From d0babb26ab341026fe227de810ed30c6c9f65cf2 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 11 Jan 2013 18:50:50 +0000 Subject: Try a separate writer thread. --- src/lib/encoder.cc | 94 ++++++++++++++++++++++++++++++++++++++++++------------ src/lib/encoder.h | 14 ++++++-- 2 files changed, 85 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 693bd5bc8..93a364fed 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -60,7 +60,9 @@ Encoder::Encoder (shared_ptr f, shared_ptr o) , _swr_context (0) #endif , _audio_frames_written (0) - , _process_end (false) + , _terminate_encoder (false) + , _writer_thread (0) + , _terminate_writer (false) { if (_film->audio_stream()) { /* Create sound output files with .tmp suffixes; we will rename @@ -85,6 +87,7 @@ Encoder::~Encoder () { close_sound_files (); terminate_worker_threads (); + terminate_writer_thread (); } void @@ -130,6 +133,8 @@ Encoder::process_begin () _worker_threads.push_back (new boost::thread (boost::bind (&Encoder::encoder_thread, this, *i))); } } + + _writer_thread = new boost::thread (boost::bind (&Encoder::writer_thread, this)); } @@ -174,11 +179,11 @@ Encoder::process_end () boost::mutex::scoped_lock lock (_worker_mutex); - _film->log()->log ("Clearing queue of " + lexical_cast (_queue.size ())); + _film->log()->log ("Clearing queue of " + lexical_cast (_encode_queue.size ())); /* Keep waking workers until the queue is empty */ - while (!_queue.empty ()) { - _film->log()->log ("Waking with " + lexical_cast (_queue.size ()), Log::VERBOSE); + while (!_encode_queue.empty ()) { + _film->log()->log ("Waking with " + lexical_cast (_encode_queue.size ()), Log::VERBOSE); _worker_condition.notify_all (); _worker_condition.wait (lock); } @@ -186,8 +191,9 @@ Encoder::process_end () lock.unlock (); terminate_worker_threads (); + terminate_writer_thread (); - _film->log()->log ("Mopping up " + lexical_cast (_queue.size())); + _film->log()->log ("Mopping up " + lexical_cast (_encode_queue.size())); /* The following sequence of events can occur in the above code: 1. a remote worker takes the last image off the queue @@ -198,7 +204,7 @@ Encoder::process_end () So just mop up anything left in the queue here. */ - for (list >::iterator i = _queue.begin(); i != _queue.end(); ++i) { + for (list >::iterator i = _encode_queue.begin(); i != _encode_queue.end(); ++i) { _film->log()->log (String::compose ("Encode left-over frame %1", (*i)->frame ())); try { shared_ptr e = (*i)->encode_locally (); @@ -209,6 +215,11 @@ Encoder::process_end () } } + /* Mop up any unwritten things in the writer's queue */ + for (list, int> >::iterator i = _write_queue.begin(); i != _write_queue.end(); ++i) { + i->first->write (_opt, i->second); + } + /* Now do links (or copies on windows) to duplicate frames */ for (list >::iterator i = _links_required.begin(); i != _links_required.end(); ++i) { link (_opt->frame_out_path (i->first, false), _opt->frame_out_path (i->second, false)); @@ -295,13 +306,13 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptr= _worker_threads.size() * 2 && !_process_end) { - TIMING ("decoder sleeps with queue of %1", _queue.size()); + while (_encode_queue.size() >= _worker_threads.size() * 2 && !_terminate_encoder) { + TIMING ("decoder sleeps with queue of %1", _encode_queue.size()); _worker_condition.wait (lock); - TIMING ("decoder wakes with queue of %1", _queue.size()); + TIMING ("decoder wakes with queue of %1", _encode_queue.size()); } - if (_process_end) { + if (_terminate_encoder) { return; } @@ -320,8 +331,8 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptr const s = Filter::ffmpeg_strings (_film->filters()); - TIMING ("adding to queue of %1", _queue.size ()); - _queue.push_back (boost::shared_ptr ( + TIMING ("adding to queue of %1", _encode_queue.size ()); + _encode_queue.push_back (boost::shared_ptr ( new DCPVideoFrame ( image, sub, _opt->out_size, _opt->padding, _film->subtitle_offset(), _film->subtitle_scale(), _film->scaler(), _video_frame, _film->frames_per_second(), s.second, @@ -434,7 +445,7 @@ void Encoder::terminate_worker_threads () { boost::mutex::scoped_lock lock (_worker_mutex); - _process_end = true; + _terminate_encoder = true; _worker_condition.notify_all (); lock.unlock (); @@ -444,6 +455,23 @@ Encoder::terminate_worker_threads () } } +void +Encoder::terminate_writer_thread () +{ + if (!_writer_thread) { + return; + } + + boost::mutex::scoped_lock lock (_writer_mutex); + _terminate_writer = true; + _writer_condition.notify_all (); + lock.unlock (); + + _writer_thread->join (); + delete _writer_thread; + _writer_thread = 0; +} + void Encoder::encoder_thread (ServerDescription* server) { @@ -457,18 +485,18 @@ Encoder::encoder_thread (ServerDescription* server) TIMING ("encoder thread %1 sleeps", boost::this_thread::get_id()); boost::mutex::scoped_lock lock (_worker_mutex); - while (_queue.empty () && !_process_end) { + while (_encode_queue.empty () && !_terminate_encoder) { _worker_condition.wait (lock); } - if (_process_end) { + if (_terminate_encoder) { return; } - TIMING ("encoder thread %1 wakes with queue of %2", boost::this_thread::get_id(), _queue.size()); - boost::shared_ptr vf = _queue.front (); + TIMING ("encoder thread %1 wakes with queue of %2", boost::this_thread::get_id(), _encode_queue.size()); + boost::shared_ptr vf = _encode_queue.front (); _film->log()->log (String::compose ("Encoder thread %1 pops frame %2 from queue", boost::this_thread::get_id(), vf->frame()), Log::VERBOSE); - _queue.pop_front (); + _encode_queue.pop_front (); lock.unlock (); @@ -508,14 +536,15 @@ Encoder::encoder_thread (ServerDescription* server) } if (encoded) { - encoded->write (_opt, vf->frame ()); - frame_done (); + boost::mutex::scoped_lock lock (_writer_mutex); + _write_queue.push_back (make_pair (encoded, vf->frame ())); + _writer_condition.notify_all (); } else { lock.lock (); _film->log()->log ( String::compose ("Encoder thread %1 pushes frame %2 back onto queue after failure", boost::this_thread::get_id(), vf->frame()) ); - _queue.push_front (vf); + _encode_queue.push_front (vf); lock.unlock (); } @@ -542,3 +571,26 @@ Encoder::link (string a, string b) const boost::filesystem::copy_file (a, b); #endif } + +void +Encoder::writer_thread () +{ + while (1) + { + boost::mutex::scoped_lock lock (_writer_mutex); + while (_write_queue.empty() && !_terminate_writer) { + _writer_condition.wait (lock); + } + + if (_terminate_writer) { + return; + } + + pair, int> encoded = _write_queue.front (); + _write_queue.pop_front (); + + lock.unlock (); + encoded.first->write (_opt, encoded.second); + lock.lock (); + } +} diff --git a/src/lib/encoder.h b/src/lib/encoder.h index 52ccfc166..fff264963 100644 --- a/src/lib/encoder.h +++ b/src/lib/encoder.h @@ -51,6 +51,7 @@ class AudioBuffers; class Film; class ServerDescription; class DCPVideoFrame; +class EncodedData; /** @class Encoder * @brief Encoder to J2K and WAV for DCP. @@ -119,6 +120,9 @@ private: void terminate_worker_threads (); void link (std::string, std::string) const; + void writer_thread (); + void terminate_writer_thread (); + #if HAVE_SWRESAMPLE SwrContext* _swr_context; #endif @@ -133,11 +137,17 @@ private: int64_t _audio_frames_written; boost::optional _last_real_frame; - bool _process_end; - std::list > _queue; + bool _terminate_encoder; + std::list > _encode_queue; std::list _worker_threads; mutable boost::mutex _worker_mutex; boost::condition _worker_condition; + + boost::thread* _writer_thread; + bool _terminate_writer; + std::list, int> > _write_queue; + mutable boost::mutex _writer_mutex; + boost::condition _writer_condition; }; #endif -- cgit v1.2.3 From ef0aa27c671f9c34b9aad79015bcc50cb10c0fc5 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 11 Jan 2013 19:20:51 +0000 Subject: Encoded data must be copied; disambiguate second lock in encoder_thread. --- src/lib/dcp_video_frame.cc | 26 ++++++++++++++++++++------ src/lib/dcp_video_frame.h | 21 +++++++++------------ src/lib/encoder.cc | 2 +- 3 files changed, 30 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/lib/dcp_video_frame.cc b/src/lib/dcp_video_frame.cc index 8b70b0aa4..f84fa8a3f 100644 --- a/src/lib/dcp_video_frame.cc +++ b/src/lib/dcp_video_frame.cc @@ -59,6 +59,7 @@ using std::string; using std::stringstream; using std::ofstream; +using std::cout; using boost::shared_ptr; /** Construct a DCP video frame. @@ -371,6 +372,18 @@ DCPVideoFrame::encode_remotely (ServerDescription const * serv) return e; } +EncodedData::EncodedData (int s) + : _data (new uint8_t[s]) + , _size (s) +{ + +} + +EncodedData::~EncodedData () +{ + delete[] _data; +} + /** Write this data to a J2K file. * @param opt Options. * @param frame Frame index. @@ -413,14 +426,15 @@ EncodedData::send (shared_ptr socket) socket->write (_data, _size, 30); } -/** @param s Size of data in bytes */ -RemotelyEncodedData::RemotelyEncodedData (int s) - : EncodedData (new uint8_t[s], s) +LocallyEncodedData::LocallyEncodedData (uint8_t* d, int s) + : EncodedData (s) { - + memcpy (_data, d, s); } -RemotelyEncodedData::~RemotelyEncodedData () +/** @param s Size of data in bytes */ +RemotelyEncodedData::RemotelyEncodedData (int s) + : EncodedData (s) { - delete[] _data; + } diff --git a/src/lib/dcp_video_frame.h b/src/lib/dcp_video_frame.h index 57e7e6203..f5ffa467e 100644 --- a/src/lib/dcp_video_frame.h +++ b/src/lib/dcp_video_frame.h @@ -39,15 +39,11 @@ class Subtitle; class EncodedData { public: - /** @param d Data (will not be freed by this class, but may be by subclasses) - * @param s Size of data, in bytes. + /** @param s Size of data, in bytes. */ - EncodedData (uint8_t* d, int s) - : _data (d) - , _size (s) - {} + EncodedData (int s); - virtual ~EncodedData () {} + virtual ~EncodedData (); void send (boost::shared_ptr socket); void write (boost::shared_ptr, SourceFrame); @@ -65,6 +61,10 @@ public: protected: uint8_t* _data; ///< data int _size; ///< data size in bytes + +private: + /* No copy construction */ + EncodedData (EncodedData const &); }; /** @class LocallyEncodedData @@ -75,12 +75,10 @@ protected: class LocallyEncodedData : public EncodedData { public: - /** @param d Data (which will not be freed by this class) + /** @param d Data (which will be copied by this class) * @param s Size of data, in bytes. */ - LocallyEncodedData (uint8_t* d, int s) - : EncodedData (d, s) - {} + LocallyEncodedData (uint8_t* d, int s); }; /** @class RemotelyEncodedData @@ -91,7 +89,6 @@ class RemotelyEncodedData : public EncodedData { public: RemotelyEncodedData (int s); - ~RemotelyEncodedData (); }; /** @class DCPVideoFrame diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 93a364fed..f6d0cc40e 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -536,7 +536,7 @@ Encoder::encoder_thread (ServerDescription* server) } if (encoded) { - boost::mutex::scoped_lock lock (_writer_mutex); + boost::mutex::scoped_lock lock2 (_writer_mutex); _write_queue.push_back (make_pair (encoded, vf->frame ())); _writer_condition.notify_all (); } else { -- cgit v1.2.3 From 7b81eb3b0b4e173404c30d754796c7339034c3c5 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 11 Jan 2013 19:29:03 +0000 Subject: Add writer thread timing. --- src/lib/encoder.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index f6d0cc40e..ef8866897 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -577,10 +577,12 @@ Encoder::writer_thread () { while (1) { + TIMING ("writer sleeps"); boost::mutex::scoped_lock lock (_writer_mutex); while (_write_queue.empty() && !_terminate_writer) { _writer_condition.wait (lock); } + TIMING ("writer wakes with a queue of %1", _write_queue.size()); if (_terminate_writer) { return; -- cgit v1.2.3 From 72494dd766159e9bdac5d80479b43eb1b3ca15b2 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 11 Jan 2013 19:30:44 +0000 Subject: Make the previous compile. --- src/lib/encoder.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index ef8866897..731a39042 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -577,8 +577,8 @@ Encoder::writer_thread () { while (1) { - TIMING ("writer sleeps"); boost::mutex::scoped_lock lock (_writer_mutex); + TIMING ("writer sleeps with a queue of %1", _write_queue.size()); while (_write_queue.empty() && !_terminate_writer) { _writer_condition.wait (lock); } -- cgit v1.2.3 From c7292767fe4935da750423461a41224b3e0a8e37 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 16 Jan 2013 21:45:41 +0000 Subject: Give DCPFrameRate a constructor. Add repeat member and cleverer dcp frame rate calculations. --- src/lib/check_hashes_job.cc | 6 +++-- src/lib/dcp_video_frame.cc | 6 ++--- src/lib/encoder.cc | 2 +- src/lib/film.cc | 13 +++++---- src/lib/make_dcp_job.cc | 11 +++++--- src/lib/options.h | 8 +++--- src/lib/util.cc | 66 ++++++++++++++++++++++++++++++++------------- src/lib/util.h | 19 ++++++++----- 8 files changed, 88 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/src/lib/check_hashes_job.cc b/src/lib/check_hashes_job.cc index 701584c74..6f6591396 100644 --- a/src/lib/check_hashes_job.cc +++ b/src/lib/check_hashes_job.cc @@ -59,9 +59,11 @@ CheckHashesJob::run () } SourceFrame const N = _film->dcp_trim_start() + _film->dcp_length().get(); - DCPFrameRate const dfr = dcp_frame_rate (_film->frames_per_second ()); + DCPFrameRate const dfr (_film->frames_per_second ()); + + int const inc = dfr.skip ? 2 : 1; - for (SourceFrame i = _film->dcp_trim_start(); i < N; i += dfr.skip) { + for (SourceFrame i = _film->dcp_trim_start(); i < N; i += inc) { string const j2k_file = _encode_opt->frame_out_path (i, false); string const hash_file = _encode_opt->hash_out_path (i, false); diff --git a/src/lib/dcp_video_frame.cc b/src/lib/dcp_video_frame.cc index c6b29ba41..f6fb8fe2e 100644 --- a/src/lib/dcp_video_frame.cc +++ b/src/lib/dcp_video_frame.cc @@ -66,8 +66,8 @@ using boost::shared_ptr; * @param out Required size of output, in pixels (including any padding). * @param s Scaler to use. * @param p Number of pixels of padding either side of the image. - * @param f Index of the frame within the Film. - * @param fps Frames per second of the Film. + * @param f Index of the frame within the Film's source. + * @param fps Frames per second of the Film's source. * @param pp FFmpeg post-processing string to use. * @param clut Colour look-up table to use (see Config::colour_lut_index ()) * @param bw J2K bandwidth to use (see Config::j2k_bandwidth ()) @@ -86,7 +86,7 @@ DCPVideoFrame::DCPVideoFrame ( , _subtitle_scale (subtitle_scale) , _scaler (s) , _frame (f) - , _frames_per_second (dcp_frame_rate(fps).frames_per_second) + , _frames_per_second (DCPFrameRate(fps).frames_per_second) , _post_process (pp) , _colour_lut (clut) , _j2k_bandwidth (bw) diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index efedfcfef..afa636150 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -279,7 +279,7 @@ Encoder::frame_skipped () void Encoder::process_video (shared_ptr image, bool same, boost::shared_ptr sub) { - if (_opt->video_skip != 0 && (_video_frame % _opt->video_skip) != 0) { + if (_opt->video_skip && (_video_frame % 2)) { ++_video_frame; return; } diff --git a/src/lib/film.cc b/src/lib/film.cc index f0441c9e0..17e14e544 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -294,25 +294,26 @@ Film::make_dcp (bool transcode) if (dcp_length ()) { oe->video_range = make_pair (dcp_trim_start(), dcp_trim_start() + dcp_length().get()); if (audio_stream()) { + DCPFrameRate dfr (frames_per_second ()); oe->audio_range = make_pair ( video_frames_to_audio_frames ( oe->video_range.get().first, dcp_audio_sample_rate (audio_stream()->sample_rate()), - dcp_frame_rate (frames_per_second()).frames_per_second + dfr.frames_per_second ), video_frames_to_audio_frames ( oe->video_range.get().second, dcp_audio_sample_rate (audio_stream()->sample_rate()), - dcp_frame_rate (frames_per_second()).frames_per_second + dfr.frames_per_second ) ); } } - oe->video_skip = dcp_frame_rate (frames_per_second()).skip; + oe->video_skip = DCPFrameRate (frames_per_second()).skip; shared_ptr od (new DecodeOptions); od->decode_subtitles = with_subtitles (); @@ -704,13 +705,15 @@ Film::target_audio_sample_rate () const /* Resample to a DCI-approved sample rate */ double t = dcp_audio_sample_rate (audio_stream()->sample_rate()); - DCPFrameRate dfr = dcp_frame_rate (frames_per_second ()); + DCPFrameRate dfr (frames_per_second ()); /* Compensate for the fact that video will be rounded to the nearest integer number of frames per second. */ + + int const mult = dfr.skip ? 2 : 1; if (dfr.run_fast) { - t *= _frames_per_second * dfr.skip / dfr.frames_per_second; + t *= _frames_per_second * mult / dfr.frames_per_second; } return rint (t); diff --git a/src/lib/make_dcp_job.cc b/src/lib/make_dcp_job.cc index b9f0cacf3..67a2d8b13 100644 --- a/src/lib/make_dcp_job.cc +++ b/src/lib/make_dcp_job.cc @@ -61,7 +61,9 @@ MakeDCPJob::name () const string MakeDCPJob::j2c_path (int f, int offset) const { - SourceFrame const s = ((f + offset) * dcp_frame_rate(_film->frames_per_second()).skip) + _film->dcp_trim_start(); + DCPFrameRate dfr (_film->frames_per_second()); + int const mult = dfr.skip ? 2 : 1; + SourceFrame const s = ((f + offset) * mult) + _film->dcp_trim_start(); return _opt->frame_out_path (s, false); } @@ -85,13 +87,16 @@ MakeDCPJob::run () /* Remove any old DCP */ boost::filesystem::remove_all (dcp_path); - DCPFrameRate const dfr = dcp_frame_rate (_film->frames_per_second ()); + DCPFrameRate const dfr (_film->frames_per_second ()); int frames = 0; switch (_film->content_type ()) { case VIDEO: /* Source frames -> DCP frames */ - frames = _film->dcp_length().get() / dfr.skip; + frames = _film->dcp_length().get(); + if (dfr.skip) { + frames /= 2; + } break; case STILL: frames = _film->still_duration() * 24; diff --git a/src/lib/options.h b/src/lib/options.h index 55b066a2d..d1fc1d54e 100644 --- a/src/lib/options.h +++ b/src/lib/options.h @@ -39,7 +39,7 @@ public: EncodeOptions (std::string f, std::string e, std::string m) : padding (0) - , video_skip (0) + , video_skip (false) , _frame_out_path (f) , _frame_out_extension (e) , _multichannel_audio_out_path (m) @@ -98,10 +98,8 @@ public: /** Range of audio frames to decode (in the DCP's sampling rate) */ boost::optional > audio_range; - /** Skip frames such that we don't decode any frame where (index % decode_video_skip) != 0; e.g. - * 1 for every frame, 2 for every other frame, etc. - */ - SourceFrame video_skip; + /** true to skip every other frame */ + SourceFrame video_skip; private: /** Path of the directory to write video frames to */ diff --git a/src/lib/util.cc b/src/lib/util.cc index 0fced638c..4228ce6cf 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -330,25 +330,55 @@ md5_digest (string file) return s.str (); } -/** @param fps Arbitrary frames-per-second value. - * @return DCPFrameRate for this frames-per-second. - */ -DCPFrameRate -dcp_frame_rate (float fps) -{ - DCPFrameRate dfr; - - dfr.run_fast = (fps != rint (fps)); - dfr.frames_per_second = rint (fps); - dfr.skip = 1; - - /* XXX: somewhat arbitrary */ - if (fps == 50) { - dfr.frames_per_second = 25; - dfr.skip = 2; +static bool about_equal (float a, float b) +{ + /* A film of F seconds at f FPS will be Ff frames; + Consider some delta FPS d, so if we run the same + film at (f + d) FPS it will last F(f + d) seconds. + + Hence the difference in length over the length of the film will + be F(f + d) - Ff frames + = Ff + Fd - Ff frames + = Fd frames + = Fd/f seconds + + So if we accept a difference of 1 frame, ie 1/f seconds, we can + say that + + 1/f = Fd/f + ie 1 = Fd + ie d = 1/F + + So for a 3hr film, ie F = 3 * 60 * 60 = 10800, the acceptable + FPS error is 1/F ~= 0.0001 ~= 10-e4 + */ + + return (fabs (a - b) < 1e-4); +} + +/** @param fps Arbitrary source frames-per-second value */ +DCPFrameRate::DCPFrameRate (float fps) + : frames_per_second (rint (fps)) + , skip (false) + , repeat (false) + , run_fast (false) +{ + if (about_equal (fps, 50)) { + /* XXX: not sure about this; just run at 50? + Ring Peter Jackson. + */ + frames_per_second = 25; + skip = true; + } else if (fps >= (27.5 / 2) && fps <= (32.5 / 2)) { + frames_per_second = 30; + repeat = true; + } else if (fps >= (24.5 / 2) && fps <= (27.5 / 2)) { + frames_per_second = 25; + repeat = true; + } else if (fps >= (20 / 2) && fps <= (24.5 / 2)) { + frames_per_second = 24; + repeat = true; } - - return dfr; } /** @param An arbitrary sampling rate. diff --git a/src/lib/util.h b/src/lib/util.h index 024c40fb5..50e7410d6 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -61,14 +61,22 @@ typedef int SourceFrame; struct DCPFrameRate { + DCPFrameRate (float); + /** frames per second for the DCP */ int frames_per_second; - /** Skip every `skip' frames. e.g. if this is 1, we skip nothing; - * if it's 2, we skip every other frame. - */ - int skip; + /** true to skip every other frame */ + bool skip; + /** true to repeat every frame once */ + bool repeat; /** true if this DCP will run its video faster than the source - * (e.g. if the source is 29.97fps and we will run the DCP at 30fps) + * without taking into account `skip' and `repeat'. + * (i.e. run_fast will be true if + * source is 29.97fps, DCP is 30fps + * source is 14.50fps, DCP is 30fps + * but not if + * source is 15.00fps, DCP is 30fps + * source is 12.50fps, DCP is 25fps) */ bool run_fast; }; @@ -183,7 +191,6 @@ struct Rect extern std::string crop_string (Position, Size); extern int dcp_audio_sample_rate (int); -extern DCPFrameRate dcp_frame_rate (float); extern int dcp_audio_channels (int); extern std::string colour_lut_index_to_name (int index); extern int stride_round_up (int, int const *, int); -- cgit v1.2.3 From e9ee53e42d7f8bbcd2a454ee9de5f3e66ec06b03 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 16 Jan 2013 23:36:16 +0000 Subject: Add some tests and hopefully clarify the DCPFrameRate class. --- src/lib/config.cc | 4 +++ src/lib/config.h | 11 +++++- src/lib/film.cc | 15 ++++---- src/lib/util.cc | 89 ++++++++++++++++++++++++++++++++++----------- src/lib/util.h | 21 ++++++++--- test/test.cc | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 213 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/lib/config.cc b/src/lib/config.cc index 65d01bf00..307b96844 100644 --- a/src/lib/config.cc +++ b/src/lib/config.cc @@ -44,6 +44,10 @@ Config::Config () , _tms_path (".") , _sound_processor (SoundProcessor::from_id ("dolby_cp750")) { + _allowed_dcp_frame_rates.push_back (24); + _allowed_dcp_frame_rates.push_back (25); + _allowed_dcp_frame_rates.push_back (30); + ifstream f (file().c_str ()); string line; while (getline (f, line)) { diff --git a/src/lib/config.h b/src/lib/config.h index c84ce76b5..c41437efb 100644 --- a/src/lib/config.h +++ b/src/lib/config.h @@ -94,6 +94,10 @@ public: return _sound_processor; } + std::list allowed_dcp_frame_rates () const { + return _allowed_dcp_frame_rates; + } + /** @param n New number of local encoding threads */ void set_num_local_encoding_threads (int n) { _num_local_encoding_threads = n; @@ -140,7 +144,11 @@ public: void set_tms_password (std::string p) { _tms_password = p; } - + + void set_allowed_dcp_frame_rates (std::list const & r) { + _allowed_dcp_frame_rates = r; + } + void write () const; static Config* instance (); @@ -172,6 +180,7 @@ private: std::string _tms_password; /** Our sound processor */ SoundProcessor const * _sound_processor; + std::list _allowed_dcp_frame_rates; /** Singleton instance, or 0 */ static Config* _instance; diff --git a/src/lib/film.cc b/src/lib/film.cc index 17e14e544..83c60a5f5 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -255,7 +255,9 @@ Film::make_dcp (bool transcode) } log()->log (String::compose ("Content is %1; type %2", content_path(), (content_type() == STILL ? "still" : "video"))); - log()->log (String::compose ("Content length %1", length().get())); + if (length()) { + log()->log (String::compose ("Content length %1", length().get())); + } log()->log (String::compose ("Content digest %1", content_digest())); log()->log (String::compose ("%1 threads", Config::instance()->num_local_encoding_threads())); log()->log (String::compose ("J2K bandwidth %1", j2k_bandwidth())); @@ -707,13 +709,14 @@ Film::target_audio_sample_rate () const DCPFrameRate dfr (frames_per_second ()); - /* Compensate for the fact that video will be rounded to the - nearest integer number of frames per second. + /* Compensate if the DCP is being run at a different frame rate + to the source; that is, if the video is run such that it will + look different in the DCP compared to the source (slower or faster). + skip/repeat doesn't come into effect here. */ - int const mult = dfr.skip ? 2 : 1; - if (dfr.run_fast) { - t *= _frames_per_second * mult / dfr.frames_per_second; + if (dfr.change_speed) { + t *= _frames_per_second * dfr.factor() / dfr.frames_per_second; } return rint (t); diff --git a/src/lib/util.cc b/src/lib/util.cc index 4228ce6cf..b500ddc2f 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -26,6 +26,7 @@ #include #include #include +#include #ifdef DVDOMATIC_POSIX #include #include @@ -58,6 +59,7 @@ extern "C" { #include "dcp_content_type.h" #include "filter.h" #include "sound_processor.h" +#include "config.h" using namespace std; using namespace boost; @@ -356,29 +358,74 @@ static bool about_equal (float a, float b) return (fabs (a - b) < 1e-4); } +class FrameRateCandidate +{ +public: + FrameRateCandidate (float source_, int dcp_) + : source (source_) + , dcp (dcp_) + {} + + bool skip () const { + return !about_equal (source, dcp) && source > dcp; + } + + bool repeat () const { + return !about_equal (source, dcp) && source < dcp; + } + + float source; + int dcp; +}; + /** @param fps Arbitrary source frames-per-second value */ -DCPFrameRate::DCPFrameRate (float fps) - : frames_per_second (rint (fps)) - , skip (false) - , repeat (false) - , run_fast (false) -{ - if (about_equal (fps, 50)) { - /* XXX: not sure about this; just run at 50? - Ring Peter Jackson. - */ - frames_per_second = 25; - skip = true; - } else if (fps >= (27.5 / 2) && fps <= (32.5 / 2)) { - frames_per_second = 30; - repeat = true; - } else if (fps >= (24.5 / 2) && fps <= (27.5 / 2)) { - frames_per_second = 25; - repeat = true; - } else if (fps >= (20 / 2) && fps <= (24.5 / 2)) { - frames_per_second = 24; - repeat = true; +/** XXX: this could be slow-ish */ +DCPFrameRate::DCPFrameRate (float source_fps) +{ + list const allowed_dcp_frame_rates = Config::instance()->allowed_dcp_frame_rates (); + + /* Work out what rates we could manage, including those achieved by using skip / repeat. */ + list candidates; + + /* Start with the ones without skip / repeat so they will get matched in preference to skipped/repeated ones */ + for (list::const_iterator i = allowed_dcp_frame_rates.begin(); i != allowed_dcp_frame_rates.end(); ++i) { + candidates.push_back (FrameRateCandidate (*i, *i)); } + + /* Then the skip/repeat ones */ + for (list::const_iterator i = allowed_dcp_frame_rates.begin(); i != allowed_dcp_frame_rates.end(); ++i) { + candidates.push_back (FrameRateCandidate (float (*i) / 2, *i)); + candidates.push_back (FrameRateCandidate (float (*i) * 2, *i)); + } + + /* Pick the best one, bailing early if we hit an exact match */ + float error = numeric_limits::max (); + boost::optional best; + list::iterator i = candidates.begin(); + while (i != candidates.end()) { + + if (about_equal (i->source, source_fps)) { + best = *i; + break; + } + + float const e = fabs (i->source - source_fps); + if (e < error) { + error = e; + best = *i; + } + + ++i; + } + + if (!best) { + throw EncodeError ("cannot find a suitable DCP frame rate for this source"); + } + + frames_per_second = best->dcp; + skip = best->skip (); + repeat = best->repeat (); + change_speed = !about_equal (source_fps * factor(), frames_per_second); } /** @param An arbitrary sampling rate. diff --git a/src/lib/util.h b/src/lib/util.h index 50e7410d6..1fd2c0150 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -62,6 +62,19 @@ typedef int SourceFrame; struct DCPFrameRate { DCPFrameRate (float); + + /** @return factor by which to multiply a source frame rate + to get the effective rate after any skip or repeat has happened. + */ + float factor () const { + if (skip) { + return 0.5; + } else if (repeat) { + return 2; + } + + return 1; + } /** frames per second for the DCP */ int frames_per_second; @@ -69,16 +82,16 @@ struct DCPFrameRate bool skip; /** true to repeat every frame once */ bool repeat; - /** true if this DCP will run its video faster than the source - * without taking into account `skip' and `repeat'. - * (i.e. run_fast will be true if + /** true if this DCP will run its video faster or slower than the source + * without taking into account `repeat'. + * (e.g. change_speed will be true if * source is 29.97fps, DCP is 30fps * source is 14.50fps, DCP is 30fps * but not if * source is 15.00fps, DCP is 30fps * source is 12.50fps, DCP is 25fps) */ - bool run_fast; + bool change_speed; }; enum ContentType { diff --git a/test/test.cc b/test/test.cc index c393aac5e..45a80f024 100644 --- a/test/test.cc +++ b/test/test.cc @@ -429,6 +429,111 @@ BOOST_AUTO_TEST_CASE (make_dcp_with_range_test) BOOST_CHECK_EQUAL (JobManager::instance()->errors(), false); } +/* Test the constructor of DCPFrameRate */ +BOOST_AUTO_TEST_CASE (dcp_frame_rate_test) +{ + /* Run some tests with a limited range of allowed rates */ + + std::list afr; + afr.push_back (24); + afr.push_back (25); + afr.push_back (30); + Config::instance()->set_allowed_dcp_frame_rates (afr); + + DCPFrameRate dfr = DCPFrameRate (60); + BOOST_CHECK_EQUAL (dfr.frames_per_second, 30); + BOOST_CHECK_EQUAL (dfr.skip, true); + BOOST_CHECK_EQUAL (dfr.repeat, false); + BOOST_CHECK_EQUAL (dfr.change_speed, false); + + dfr = DCPFrameRate (50); + BOOST_CHECK_EQUAL (dfr.frames_per_second, 25); + BOOST_CHECK_EQUAL (dfr.skip, true); + BOOST_CHECK_EQUAL (dfr.repeat, false); + BOOST_CHECK_EQUAL (dfr.change_speed, false); + + dfr = DCPFrameRate (48); + BOOST_CHECK_EQUAL (dfr.frames_per_second, 24); + BOOST_CHECK_EQUAL (dfr.skip, true); + BOOST_CHECK_EQUAL (dfr.repeat, false); + BOOST_CHECK_EQUAL (dfr.change_speed, false); + + dfr = DCPFrameRate (30); + BOOST_CHECK_EQUAL (dfr.skip, false); + BOOST_CHECK_EQUAL (dfr.frames_per_second, 30); + BOOST_CHECK_EQUAL (dfr.repeat, false); + BOOST_CHECK_EQUAL (dfr.change_speed, false); + + dfr = DCPFrameRate (29.97); + BOOST_CHECK_EQUAL (dfr.skip, false); + BOOST_CHECK_EQUAL (dfr.frames_per_second, 30); + BOOST_CHECK_EQUAL (dfr.repeat, false); + BOOST_CHECK_EQUAL (dfr.change_speed, true); + + dfr = DCPFrameRate (25); + BOOST_CHECK_EQUAL (dfr.skip, false); + BOOST_CHECK_EQUAL (dfr.frames_per_second, 25); + BOOST_CHECK_EQUAL (dfr.repeat, false); + BOOST_CHECK_EQUAL (dfr.change_speed, false); + + dfr = DCPFrameRate (24); + BOOST_CHECK_EQUAL (dfr.skip, false); + BOOST_CHECK_EQUAL (dfr.frames_per_second, 24); + BOOST_CHECK_EQUAL (dfr.repeat, false); + BOOST_CHECK_EQUAL (dfr.change_speed, false); + + dfr = DCPFrameRate (14.5); + BOOST_CHECK_EQUAL (dfr.skip, false); + BOOST_CHECK_EQUAL (dfr.frames_per_second, 30); + BOOST_CHECK_EQUAL (dfr.repeat, true); + BOOST_CHECK_EQUAL (dfr.change_speed, true); + + dfr = DCPFrameRate (12.6); + BOOST_CHECK_EQUAL (dfr.skip, false); + BOOST_CHECK_EQUAL (dfr.frames_per_second, 25); + BOOST_CHECK_EQUAL (dfr.repeat, true); + BOOST_CHECK_EQUAL (dfr.change_speed, true); + + dfr = DCPFrameRate (12.4); + BOOST_CHECK_EQUAL (dfr.skip, false); + BOOST_CHECK_EQUAL (dfr.frames_per_second, 25); + BOOST_CHECK_EQUAL (dfr.repeat, true); + BOOST_CHECK_EQUAL (dfr.change_speed, true); + + dfr = DCPFrameRate (12); + BOOST_CHECK_EQUAL (dfr.skip, false); + BOOST_CHECK_EQUAL (dfr.frames_per_second, 24); + BOOST_CHECK_EQUAL (dfr.repeat, true); + BOOST_CHECK_EQUAL (dfr.change_speed, false); + + /* Now add some more rates and see if it will use them + in preference to skip/repeat. + */ + + afr.push_back (48); + afr.push_back (50); + afr.push_back (60); + Config::instance()->set_allowed_dcp_frame_rates (afr); + + dfr = DCPFrameRate (60); + BOOST_CHECK_EQUAL (dfr.frames_per_second, 60); + BOOST_CHECK_EQUAL (dfr.skip, false); + BOOST_CHECK_EQUAL (dfr.repeat, false); + BOOST_CHECK_EQUAL (dfr.change_speed, false); + + dfr = DCPFrameRate (50); + BOOST_CHECK_EQUAL (dfr.frames_per_second, 50); + BOOST_CHECK_EQUAL (dfr.skip, false); + BOOST_CHECK_EQUAL (dfr.repeat, false); + BOOST_CHECK_EQUAL (dfr.change_speed, false); + + dfr = DCPFrameRate (48); + BOOST_CHECK_EQUAL (dfr.frames_per_second, 48); + BOOST_CHECK_EQUAL (dfr.skip, false); + BOOST_CHECK_EQUAL (dfr.repeat, false); + BOOST_CHECK_EQUAL (dfr.change_speed, false); +} + BOOST_AUTO_TEST_CASE (audio_sampling_rate_test) { shared_ptr f = new_test_film ("audio_sampling_rate_test"); -- cgit v1.2.3 From d87ea0504297c0bb6bd3bd192588d0f3e927fee9 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 16 Jan 2013 23:41:52 +0000 Subject: More of Encoder can be private. --- src/lib/encoder.h | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/lib/encoder.h b/src/lib/encoder.h index 52ccfc166..bd38dc6bd 100644 --- a/src/lib/encoder.h +++ b/src/lib/encoder.h @@ -85,11 +85,18 @@ public: bool skipping () const; SourceFrame video_frame () const; -protected: +private: void frame_done (); void frame_skipped (); + void close_sound_files (); + void write_audio (boost::shared_ptr audio); + + void encoder_thread (ServerDescription *); + void terminate_worker_threads (); + void link (std::string, std::string) const; + /** Film that we are encoding */ boost::shared_ptr _film; /** Options */ @@ -111,14 +118,6 @@ protected: /** Number of audio frames received so far */ int64_t _audio_frame; -private: - void close_sound_files (); - void write_audio (boost::shared_ptr audio); - - void encoder_thread (ServerDescription *); - void terminate_worker_threads (); - void link (std::string, std::string) const; - #if HAVE_SWRESAMPLE SwrContext* _swr_context; #endif -- cgit v1.2.3 From f35b2a637ba82e39eb81e030c2e112185349cac5 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 17 Jan 2013 00:10:12 +0000 Subject: EncodeOptions can go. --- src/lib/ab_transcode_job.cc | 5 +- src/lib/ab_transcode_job.h | 3 -- src/lib/check_hashes_job.cc | 13 +++--- src/lib/check_hashes_job.h | 3 -- src/lib/dcp_video_frame.cc | 8 ++-- src/lib/dcp_video_frame.h | 4 +- src/lib/encoder.cc | 39 +++++++++------- src/lib/encoder.h | 5 +- src/lib/film.cc | 111 +++++++++++++++++++++++++++++++------------- src/lib/film.h | 6 +++ src/lib/make_dcp_job.cc | 12 ++--- src/lib/make_dcp_job.h | 6 +-- src/lib/options.h | 84 --------------------------------- src/lib/transcode_job.cc | 5 +- src/lib/transcode_job.h | 4 +- src/lib/transcoder.h | 1 - 16 files changed, 132 insertions(+), 177 deletions(-) (limited to 'src') diff --git a/src/lib/ab_transcode_job.cc b/src/lib/ab_transcode_job.cc index a6233c185..2dd8f95ad 100644 --- a/src/lib/ab_transcode_job.cc +++ b/src/lib/ab_transcode_job.cc @@ -32,10 +32,9 @@ using boost::shared_ptr; /** @param f Film to compare. * @param o Options. */ -ABTranscodeJob::ABTranscodeJob (shared_ptr f, shared_ptr od, shared_ptr oe, shared_ptr req) +ABTranscodeJob::ABTranscodeJob (shared_ptr f, shared_ptr od, shared_ptr req) : Job (f, req) , _decode_opt (od) - , _encode_opt (oe) { _film_b.reset (new Film (*_film)); _film_b->set_scaler (Config::instance()->reference_scaler ()); @@ -53,7 +52,7 @@ ABTranscodeJob::run () { try { /* _film_b is the one with reference filters */ - ABTranscoder w (_film_b, _film, _decode_opt, this, shared_ptr (new Encoder (_film, _encode_opt))); + ABTranscoder w (_film_b, _film, _decode_opt, this, shared_ptr (new Encoder (_film))); w.go (); set_progress (1); set_state (FINISHED_OK); diff --git a/src/lib/ab_transcode_job.h b/src/lib/ab_transcode_job.h index 86a2a81b8..69c157651 100644 --- a/src/lib/ab_transcode_job.h +++ b/src/lib/ab_transcode_job.h @@ -26,7 +26,6 @@ class Film; class DecodeOptions; -class EncodeOptions; /** @class ABTranscodeJob * @brief Job to run a transcoder which produces output for A/B comparison of various settings. @@ -41,7 +40,6 @@ public: ABTranscodeJob ( boost::shared_ptr f, boost::shared_ptr od, - boost::shared_ptr oe, boost::shared_ptr req ); @@ -50,7 +48,6 @@ public: private: boost::shared_ptr _decode_opt; - boost::shared_ptr _encode_opt; /** Copy of our Film using the reference filters and scaler */ boost::shared_ptr _film_b; diff --git a/src/lib/check_hashes_job.cc b/src/lib/check_hashes_job.cc index 6f6591396..099845d8c 100644 --- a/src/lib/check_hashes_job.cc +++ b/src/lib/check_hashes_job.cc @@ -34,10 +34,9 @@ using std::stringstream; using std::ifstream; using boost::shared_ptr; -CheckHashesJob::CheckHashesJob (shared_ptr f, shared_ptr od, shared_ptr oe, shared_ptr req) +CheckHashesJob::CheckHashesJob (shared_ptr f, shared_ptr od, shared_ptr req) : Job (f, req) , _decode_opt (od) - , _encode_opt (oe) , _bad (0) { @@ -64,8 +63,8 @@ CheckHashesJob::run () int const inc = dfr.skip ? 2 : 1; for (SourceFrame i = _film->dcp_trim_start(); i < N; i += inc) { - string const j2k_file = _encode_opt->frame_out_path (i, false); - string const hash_file = _encode_opt->hash_out_path (i, false); + string const j2k_file = _film->frame_out_path (i, false); + string const hash_file = _film->hash_out_path (i, false); if (!boost::filesystem::exists (j2k_file)) { _film->log()->log (String::compose ("Frame %1 has a missing J2K file.", i)); @@ -94,13 +93,13 @@ CheckHashesJob::run () shared_ptr tc; if (_film->dcp_ab()) { - tc.reset (new ABTranscodeJob (_film, _decode_opt, _encode_opt, shared_from_this())); + tc.reset (new ABTranscodeJob (_film, _decode_opt, shared_from_this())); } else { - tc.reset (new TranscodeJob (_film, _decode_opt, _encode_opt, shared_from_this())); + tc.reset (new TranscodeJob (_film, _decode_opt, shared_from_this())); } JobManager::instance()->add_after (shared_from_this(), tc); - JobManager::instance()->add_after (tc, shared_ptr (new CheckHashesJob (_film, _decode_opt, _encode_opt, tc))); + JobManager::instance()->add_after (tc, shared_ptr (new CheckHashesJob (_film, _decode_opt, tc))); } set_progress (1); diff --git a/src/lib/check_hashes_job.h b/src/lib/check_hashes_job.h index c41af9d3f..7e62b0e7a 100644 --- a/src/lib/check_hashes_job.h +++ b/src/lib/check_hashes_job.h @@ -20,7 +20,6 @@ #include "job.h" class DecodeOptions; -class EncodeOptions; class CheckHashesJob : public Job { @@ -28,7 +27,6 @@ public: CheckHashesJob ( boost::shared_ptr f, boost::shared_ptr od, - boost::shared_ptr oe, boost::shared_ptr req ); @@ -38,6 +36,5 @@ public: private: boost::shared_ptr _decode_opt; - boost::shared_ptr _encode_opt; int _bad; }; diff --git a/src/lib/dcp_video_frame.cc b/src/lib/dcp_video_frame.cc index f6fb8fe2e..c00ed9b88 100644 --- a/src/lib/dcp_video_frame.cc +++ b/src/lib/dcp_video_frame.cc @@ -376,9 +376,9 @@ DCPVideoFrame::encode_remotely (ServerDescription const * serv) * @param frame Frame index. */ void -EncodedData::write (shared_ptr opt, SourceFrame frame) +EncodedData::write (shared_ptr film, SourceFrame frame) { - string const tmp_j2k = opt->frame_out_path (frame, true); + string const tmp_j2k = film->frame_out_path (frame, true); FILE* f = fopen (tmp_j2k.c_str (), "wb"); @@ -389,13 +389,13 @@ EncodedData::write (shared_ptr opt, SourceFrame frame) fwrite (_data, 1, _size, f); fclose (f); - string const real_j2k = opt->frame_out_path (frame, false); + string const real_j2k = film->frame_out_path (frame, false); /* Rename the file from foo.j2c.tmp to foo.j2c now that it is complete */ boost::filesystem::rename (tmp_j2k, real_j2k); /* Write a file containing the hash */ - string const hash = opt->hash_out_path (frame, false); + string const hash = film->hash_out_path (frame, false); ofstream h (hash.c_str()); h << md5_digest (_data, _size) << "\n"; h.close (); diff --git a/src/lib/dcp_video_frame.h b/src/lib/dcp_video_frame.h index 134720da8..1b75cb207 100644 --- a/src/lib/dcp_video_frame.h +++ b/src/lib/dcp_video_frame.h @@ -26,7 +26,7 @@ */ class FilmState; -class EncodeOptions; +class Film; class ServerDescription; class Scaler; class Image; @@ -50,7 +50,7 @@ public: virtual ~EncodedData () {} void send (boost::shared_ptr socket); - void write (boost::shared_ptr, SourceFrame); + void write (boost::shared_ptr, SourceFrame); /** @return data */ uint8_t* data () const { diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index afa636150..35b43e334 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -34,6 +34,7 @@ #include "config.h" #include "dcp_video_frame.h" #include "server.h" +#include "format.h" #include "cross.h" using std::pair; @@ -50,9 +51,8 @@ int const Encoder::_history_size = 25; /** @param f Film that we are encoding. * @param o Options. */ -Encoder::Encoder (shared_ptr f, shared_ptr o) +Encoder::Encoder (shared_ptr f) : _film (f) - , _opt (o) , _just_skipped (false) , _video_frame (0) , _audio_frame (0) @@ -72,9 +72,9 @@ Encoder::Encoder (shared_ptr f, shared_ptr o) /* We write mono files */ sf_info.channels = 1; sf_info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_24; - SNDFILE* f = sf_open (_opt->multichannel_audio_out_path (i, true).c_str (), SFM_WRITE, &sf_info); + SNDFILE* f = sf_open (_film->multichannel_audio_out_path (i, true).c_str (), SFM_WRITE, &sf_info); if (f == 0) { - throw CreateFileError (_opt->multichannel_audio_out_path (i, true)); + throw CreateFileError (_film->multichannel_audio_out_path (i, true)); } _sound_files.push_back (f); } @@ -165,10 +165,10 @@ Encoder::process_end () /* Rename .wav.tmp files to .wav */ for (int i = 0; i < dcp_audio_channels (_film->audio_channels()); ++i) { - if (boost::filesystem::exists (_opt->multichannel_audio_out_path (i, false))) { - boost::filesystem::remove (_opt->multichannel_audio_out_path (i, false)); + if (boost::filesystem::exists (_film->multichannel_audio_out_path (i, false))) { + boost::filesystem::remove (_film->multichannel_audio_out_path (i, false)); } - boost::filesystem::rename (_opt->multichannel_audio_out_path (i, true), _opt->multichannel_audio_out_path (i, false)); + boost::filesystem::rename (_film->multichannel_audio_out_path (i, true), _film->multichannel_audio_out_path (i, false)); } } @@ -202,7 +202,7 @@ Encoder::process_end () _film->log()->log (String::compose ("Encode left-over frame %1", (*i)->frame ())); try { shared_ptr e = (*i)->encode_locally (); - e->write (_opt, (*i)->frame ()); + e->write (_film, (*i)->frame ()); frame_done (); } catch (std::exception& e) { _film->log()->log (String::compose ("Local encode failed (%1)", e.what ())); @@ -211,8 +211,8 @@ Encoder::process_end () /* Now do links (or copies on windows) to duplicate frames */ for (list >::iterator i = _links_required.begin(); i != _links_required.end(); ++i) { - link (_opt->frame_out_path (i->first, false), _opt->frame_out_path (i->second, false)); - link (_opt->hash_out_path (i->first, false), _opt->hash_out_path (i->second, false)); + link (_film->frame_out_path (i->first, false), _film->frame_out_path (i->second, false)); + link (_film->hash_out_path (i->first, false), _film->hash_out_path (i->second, false)); } } @@ -279,13 +279,15 @@ Encoder::frame_skipped () void Encoder::process_video (shared_ptr image, bool same, boost::shared_ptr sub) { - if (_opt->video_skip && (_video_frame % 2)) { + DCPFrameRate dfr (_film->frames_per_second ()); + + if (dfr.skip && (_video_frame % 2)) { ++_video_frame; return; } - if (_opt->video_range) { - pair const r = _opt->video_range.get(); + if (_film->video_range ()) { + pair const r = _film->video_range().get(); if (_video_frame < r.first || _video_frame >= r.second) { ++_video_frame; return; @@ -306,7 +308,7 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptrframe_out_path (_video_frame, false))) { + if (boost::filesystem::exists (_film->frame_out_path (_video_frame, false))) { frame_skipped (); return; } @@ -323,7 +325,8 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptr ( new DCPVideoFrame ( - image, sub, _opt->out_size, _opt->padding, _film->subtitle_offset(), _film->subtitle_scale(), + image, sub, _film->format()->dcp_size(), _film->format()->dcp_padding (_film), + _film->subtitle_offset(), _film->subtitle_scale(), _film->scaler(), _video_frame, _film->frames_per_second(), s.second, _film->colour_lut(), _film->j2k_bandwidth(), _film->log() @@ -340,11 +343,11 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptr data) { - if (_opt->audio_range) { + if (_film->audio_range ()) { shared_ptr trimmed (new AudioBuffers (*data.get ())); /* Range that we are encoding */ - pair required_range = _opt->audio_range.get(); + pair required_range = _film->audio_range().get(); /* Range of this block of data */ pair this_range (_audio_frame, _audio_frame + trimmed->frames()); @@ -508,7 +511,7 @@ Encoder::encoder_thread (ServerDescription* server) } if (encoded) { - encoded->write (_opt, vf->frame ()); + encoded->write (_film, vf->frame ()); frame_done (); } else { lock.lock (); diff --git a/src/lib/encoder.h b/src/lib/encoder.h index bd38dc6bd..d8edf9b26 100644 --- a/src/lib/encoder.h +++ b/src/lib/encoder.h @@ -44,7 +44,6 @@ extern "C" { #include "video_sink.h" #include "audio_sink.h" -class EncodeOptions; class Image; class Subtitle; class AudioBuffers; @@ -62,7 +61,7 @@ class DCPVideoFrame; class Encoder : public VideoSink, public AudioSink { public: - Encoder (boost::shared_ptr f, boost::shared_ptr o); + Encoder (boost::shared_ptr f); virtual ~Encoder (); /** Called to indicate that a processing run is about to begin */ @@ -99,8 +98,6 @@ private: /** Film that we are encoding */ boost::shared_ptr _film; - /** Options */ - boost::shared_ptr _opt; /** Mutex for _time_history, _just_skipped and _last_frame */ mutable boost::mutex _history_mutex; diff --git a/src/lib/film.cc b/src/lib/film.cc index 83c60a5f5..4bf6606a9 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -290,33 +290,6 @@ Film::make_dcp (bool transcode) throw MissingSettingError ("name"); } - shared_ptr oe (new EncodeOptions (j2k_dir(), ".j2c", dir ("wavs"))); - oe->out_size = format()->dcp_size (); - oe->padding = format()->dcp_padding (shared_from_this ()); - if (dcp_length ()) { - oe->video_range = make_pair (dcp_trim_start(), dcp_trim_start() + dcp_length().get()); - if (audio_stream()) { - DCPFrameRate dfr (frames_per_second ()); - oe->audio_range = make_pair ( - - video_frames_to_audio_frames ( - oe->video_range.get().first, - dcp_audio_sample_rate (audio_stream()->sample_rate()), - dfr.frames_per_second - ), - - video_frames_to_audio_frames ( - oe->video_range.get().second, - dcp_audio_sample_rate (audio_stream()->sample_rate()), - dfr.frames_per_second - ) - ); - } - - } - - oe->video_skip = DCPFrameRate (frames_per_second()).skip; - shared_ptr od (new DecodeOptions); od->decode_subtitles = with_subtitles (); @@ -324,14 +297,14 @@ Film::make_dcp (bool transcode) if (transcode) { if (dcp_ab()) { - r = JobManager::instance()->add (shared_ptr (new ABTranscodeJob (shared_from_this(), od, oe, shared_ptr ()))); + r = JobManager::instance()->add (shared_ptr (new ABTranscodeJob (shared_from_this(), od, shared_ptr ()))); } else { - r = JobManager::instance()->add (shared_ptr (new TranscodeJob (shared_from_this(), od, oe, shared_ptr ()))); + r = JobManager::instance()->add (shared_ptr (new TranscodeJob (shared_from_this(), od, shared_ptr ()))); } } - r = JobManager::instance()->add (shared_ptr (new CheckHashesJob (shared_from_this(), od, oe, r))); - JobManager::instance()->add (shared_ptr (new MakeDCPJob (shared_from_this(), oe, r))); + r = JobManager::instance()->add (shared_ptr (new CheckHashesJob (shared_from_this(), od, r))); + JobManager::instance()->add (shared_ptr (new MakeDCPJob (shared_from_this(), r))); } /** Start a job to examine our content file */ @@ -1437,3 +1410,79 @@ Film::audio_stream () const return _external_audio_stream; } + +/** @param f Source frame index. + * @param t true to return a temporary file path, otherwise a permanent one. + * @return The path to write this video frame to. + */ +string +Film::frame_out_path (SourceFrame f, bool t) const +{ + stringstream s; + s << j2k_dir() << "/"; + s.width (8); + s << std::setfill('0') << f << ".j2c"; + + if (t) { + s << ".tmp"; + } + + return s.str (); +} + +string +Film::hash_out_path (SourceFrame f, bool t) const +{ + return frame_out_path (f, t) + ".md5"; +} + +/** @param c Audio channel index. + * @param t true to return a temporary file path, otherwise a permanent one. + * @return The path to write this audio file to. + */ +string +Film::multichannel_audio_out_path (int c, bool t) const +{ + stringstream s; + s << dir ("wavs") << "/" << (c + 1) << ".wav"; + if (t) { + s << ".tmp"; + } + + return s.str (); +} + +boost::optional > +Film::video_range () const +{ + if (!dcp_length()) { + return boost::optional > (); + } + + return make_pair (dcp_trim_start(), dcp_trim_start() + dcp_length().get()); +} + +boost::optional > +Film::audio_range () const +{ + boost::optional > vr = video_range (); + if (!vr || !audio_stream()) { + return boost::optional > (); + } + + DCPFrameRate dfr (frames_per_second ()); + return make_pair ( + + video_frames_to_audio_frames ( + vr.get().first, + dcp_audio_sample_rate (audio_stream()->sample_rate()), + dfr.frames_per_second + ), + + video_frames_to_audio_frames ( + vr.get().second, + dcp_audio_sample_rate (audio_stream()->sample_rate()), + dfr.frames_per_second + ) + ); +} diff --git a/src/lib/film.h b/src/lib/film.h index 3485dfaae..6c27af3ab 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -78,6 +78,10 @@ public: std::string file (std::string f) const; std::string dir (std::string d) const; + std::string frame_out_path (SourceFrame f, bool t) const; + std::string hash_out_path (SourceFrame f, bool t) const; + std::string multichannel_audio_out_path (int c, bool t) const; + std::string content_path () const; ContentType content_type () const; @@ -97,6 +101,8 @@ public: } int audio_channels () const; + boost::optional > video_range () const; + boost::optional > audio_range () const; void set_dci_date_today (); diff --git a/src/lib/make_dcp_job.cc b/src/lib/make_dcp_job.cc index 67a2d8b13..efc2f05d5 100644 --- a/src/lib/make_dcp_job.cc +++ b/src/lib/make_dcp_job.cc @@ -36,6 +36,7 @@ extern "C" { #include "options.h" #include "imagemagick_decoder.h" #include "film.h" +#include "format.h" using std::string; using std::cout; @@ -44,9 +45,8 @@ using boost::shared_ptr; /** @param f Film we are making the DCP for. * @param o Options. */ -MakeDCPJob::MakeDCPJob (shared_ptr f, shared_ptr o, shared_ptr req) +MakeDCPJob::MakeDCPJob (shared_ptr f, shared_ptr req) : Job (f, req) - , _opt (o) { } @@ -64,13 +64,13 @@ MakeDCPJob::j2c_path (int f, int offset) const DCPFrameRate dfr (_film->frames_per_second()); int const mult = dfr.skip ? 2 : 1; SourceFrame const s = ((f + offset) * mult) + _film->dcp_trim_start(); - return _opt->frame_out_path (s, false); + return _film->frame_out_path (s, false); } string MakeDCPJob::wav_path (libdcp::Channel c) const { - return _opt->multichannel_audio_out_path (int (c), false); + return _film->multichannel_audio_out_path (int (c), false); } void @@ -138,8 +138,8 @@ MakeDCPJob::run () &dcp.Progress, dfr.frames_per_second, this_time, - _opt->out_size.width, - _opt->out_size.height + _film->format()->dcp_size().width, + _film->format()->dcp_size().height ) ); diff --git a/src/lib/make_dcp_job.h b/src/lib/make_dcp_job.h index 5e4f78a25..481382248 100644 --- a/src/lib/make_dcp_job.h +++ b/src/lib/make_dcp_job.h @@ -23,15 +23,13 @@ #include "job.h" -class EncodeOptions; - /** @class MakeDCPJob * @brief A job to create DCPs */ class MakeDCPJob : public Job { public: - MakeDCPJob (boost::shared_ptr, boost::shared_ptr, boost::shared_ptr req); + MakeDCPJob (boost::shared_ptr, boost::shared_ptr req); std::string name () const; void run (); @@ -40,7 +38,5 @@ private: void dcp_progress (float); std::string j2c_path (int, int) const; std::string wav_path (libdcp::Channel) const; - - boost::shared_ptr _opt; }; diff --git a/src/lib/options.h b/src/lib/options.h index d1fc1d54e..2f8733507 100644 --- a/src/lib/options.h +++ b/src/lib/options.h @@ -27,90 +27,6 @@ #include #include "util.h" -/** @class EncodeOptions - * @brief EncodeOptions for an encoding operation. - * - * These are settings which may be different, in different circumstances, for - * the same film; ie they are options for a particular operation. - */ -class EncodeOptions -{ -public: - - EncodeOptions (std::string f, std::string e, std::string m) - : padding (0) - , video_skip (false) - , _frame_out_path (f) - , _frame_out_extension (e) - , _multichannel_audio_out_path (m) - {} - - /** @return The path to write video frames to */ - std::string frame_out_path () const { - return _frame_out_path; - } - - /** @param f Source frame index. - * @param t true to return a temporary file path, otherwise a permanent one. - * @return The path to write this video frame to. - */ - std::string frame_out_path (SourceFrame f, bool t) const { - std::stringstream s; - s << _frame_out_path << "/"; - s.width (8); - s << std::setfill('0') << f << _frame_out_extension; - - if (t) { - s << ".tmp"; - } - - return s.str (); - } - - std::string hash_out_path (SourceFrame f, bool t) const { - return frame_out_path (f, t) + ".md5"; - } - - /** @return Path to write multichannel audio data to */ - std::string multichannel_audio_out_path () const { - return _multichannel_audio_out_path; - } - - /** @param c Audio channel index. - * @param t true to return a temporary file path, otherwise a permanent one. - * @return The path to write this audio file to. - */ - std::string multichannel_audio_out_path (int c, bool t) const { - std::stringstream s; - s << _multichannel_audio_out_path << "/" << (c + 1) << ".wav"; - if (t) { - s << ".tmp"; - } - - return s.str (); - } - - Size out_size; ///< size of output images - int padding; ///< number of pixels of padding (in terms of the output size) each side of the image - - /** Range of video frames to encode (in DCP frames) */ - boost::optional > video_range; - /** Range of audio frames to decode (in the DCP's sampling rate) */ - boost::optional > audio_range; - - /** true to skip every other frame */ - SourceFrame video_skip; - -private: - /** Path of the directory to write video frames to */ - std::string _frame_out_path; - /** Extension to use for video frame files (including the leading .) */ - std::string _frame_out_extension; - /** Path of the directory to write audio files to */ - std::string _multichannel_audio_out_path; -}; - - class DecodeOptions { public: diff --git a/src/lib/transcode_job.cc b/src/lib/transcode_job.cc index dfb9b1071..db5c33641 100644 --- a/src/lib/transcode_job.cc +++ b/src/lib/transcode_job.cc @@ -40,10 +40,9 @@ using boost::shared_ptr; * @param o Options. * @param req Job that must be completed before this job is run. */ -TranscodeJob::TranscodeJob (shared_ptr f, shared_ptr od, shared_ptr oe, shared_ptr req) +TranscodeJob::TranscodeJob (shared_ptr f, shared_ptr od, shared_ptr req) : Job (f, req) , _decode_opt (od) - , _encode_opt (oe) { } @@ -62,7 +61,7 @@ TranscodeJob::run () _film->log()->log ("Transcode job starting"); _film->log()->log (String::compose ("Audio delay is %1ms", _film->audio_delay())); - _encoder.reset (new Encoder (_film, _encode_opt)); + _encoder.reset (new Encoder (_film)); Transcoder w (_film, _decode_opt, this, _encoder); w.go (); set_progress (1); diff --git a/src/lib/transcode_job.h b/src/lib/transcode_job.h index 97f655e15..aef190a64 100644 --- a/src/lib/transcode_job.h +++ b/src/lib/transcode_job.h @@ -26,7 +26,6 @@ class Encoder; class DecodeOptions; -class EncodeOptions; /** @class TranscodeJob * @brief A job which transcodes from one format to another. @@ -34,7 +33,7 @@ class EncodeOptions; class TranscodeJob : public Job { public: - TranscodeJob (boost::shared_ptr f, boost::shared_ptr od, boost::shared_ptr oe, boost::shared_ptr req); + TranscodeJob (boost::shared_ptr f, boost::shared_ptr od, boost::shared_ptr req); std::string name () const; void run (); @@ -45,6 +44,5 @@ protected: private: boost::shared_ptr _decode_opt; - boost::shared_ptr _encode_opt; boost::shared_ptr _encoder; }; diff --git a/src/lib/transcoder.h b/src/lib/transcoder.h index b50113742..ef6a438c8 100644 --- a/src/lib/transcoder.h +++ b/src/lib/transcoder.h @@ -36,7 +36,6 @@ class Gain; class VideoDecoder; class AudioDecoder; class DelayLine; -class EncodeOptions; class DecodeOptions; /** @class Transcoder -- cgit v1.2.3 From 9db7ed5f6499de903313a85d59bb70302e97e7ff Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 17 Jan 2013 00:24:13 +0000 Subject: shared_ptr is a bit excessive for DecodeOptions. --- src/lib/ab_transcode_job.cc | 6 +++--- src/lib/ab_transcode_job.h | 6 +++--- src/lib/ab_transcoder.cc | 2 +- src/lib/ab_transcoder.h | 3 +-- src/lib/audio_decoder.cc | 2 +- src/lib/audio_decoder.h | 2 +- src/lib/check_hashes_job.cc | 4 ++-- src/lib/check_hashes_job.h | 7 +++---- src/lib/decoder.cc | 4 ++-- src/lib/decoder.h | 8 ++++---- src/lib/decoder_factory.cc | 2 +- src/lib/decoder_factory.h | 5 +++-- src/lib/examine_content_job.cc | 7 +++---- src/lib/external_audio_decoder.cc | 2 +- src/lib/external_audio_decoder.h | 2 +- src/lib/ffmpeg_decoder.cc | 12 ++++++------ src/lib/ffmpeg_decoder.h | 2 +- src/lib/film.cc | 10 ++++------ src/lib/imagemagick_decoder.cc | 2 +- src/lib/imagemagick_decoder.h | 2 +- src/lib/options.h | 13 ++++++------- src/lib/transcode_job.cc | 6 +++--- src/lib/transcode_job.h | 6 +++--- src/lib/transcoder.cc | 2 +- src/lib/transcoder.h | 3 +-- src/lib/video_decoder.cc | 2 +- src/lib/video_decoder.h | 2 +- src/wx/film_viewer.cc | 8 ++++---- 28 files changed, 63 insertions(+), 69 deletions(-) (limited to 'src') diff --git a/src/lib/ab_transcode_job.cc b/src/lib/ab_transcode_job.cc index 2dd8f95ad..0efd277bb 100644 --- a/src/lib/ab_transcode_job.cc +++ b/src/lib/ab_transcode_job.cc @@ -30,11 +30,11 @@ using std::string; using boost::shared_ptr; /** @param f Film to compare. - * @param o Options. + * @param o Decode options. */ -ABTranscodeJob::ABTranscodeJob (shared_ptr f, shared_ptr od, shared_ptr req) +ABTranscodeJob::ABTranscodeJob (shared_ptr f, DecodeOptions o, shared_ptr req) : Job (f, req) - , _decode_opt (od) + , _decode_opt (o) { _film_b.reset (new Film (*_film)); _film_b->set_scaler (Config::instance()->reference_scaler ()); diff --git a/src/lib/ab_transcode_job.h b/src/lib/ab_transcode_job.h index 69c157651..983842038 100644 --- a/src/lib/ab_transcode_job.h +++ b/src/lib/ab_transcode_job.h @@ -23,9 +23,9 @@ #include #include "job.h" +#include "options.h" class Film; -class DecodeOptions; /** @class ABTranscodeJob * @brief Job to run a transcoder which produces output for A/B comparison of various settings. @@ -39,7 +39,7 @@ class ABTranscodeJob : public Job public: ABTranscodeJob ( boost::shared_ptr f, - boost::shared_ptr od, + DecodeOptions o, boost::shared_ptr req ); @@ -47,7 +47,7 @@ public: void run (); private: - boost::shared_ptr _decode_opt; + DecodeOptions _decode_opt; /** Copy of our Film using the reference filters and scaler */ boost::shared_ptr _film_b; diff --git a/src/lib/ab_transcoder.cc b/src/lib/ab_transcoder.cc index 53af43b5d..fc4fb8daa 100644 --- a/src/lib/ab_transcoder.cc +++ b/src/lib/ab_transcoder.cc @@ -49,7 +49,7 @@ using boost::shared_ptr; */ ABTranscoder::ABTranscoder ( - shared_ptr a, shared_ptr b, shared_ptr o, Job* j, shared_ptr e) + shared_ptr a, shared_ptr b, DecodeOptions o, Job* j, shared_ptr e) : _film_a (a) , _film_b (b) , _job (j) diff --git a/src/lib/ab_transcoder.h b/src/lib/ab_transcoder.h index 7bfcb393c..58a08af04 100644 --- a/src/lib/ab_transcoder.h +++ b/src/lib/ab_transcoder.h @@ -31,7 +31,6 @@ class Job; class Encoder; class VideoDecoder; class AudioDecoder; -class DecodeOptions; class Image; class Log; class Subtitle; @@ -51,7 +50,7 @@ public: ABTranscoder ( boost::shared_ptr a, boost::shared_ptr b, - boost::shared_ptr o, + DecodeOptions o, Job* j, boost::shared_ptr e ); diff --git a/src/lib/audio_decoder.cc b/src/lib/audio_decoder.cc index 9d8de971c..a038dd2bb 100644 --- a/src/lib/audio_decoder.cc +++ b/src/lib/audio_decoder.cc @@ -23,7 +23,7 @@ using boost::optional; using boost::shared_ptr; -AudioDecoder::AudioDecoder (shared_ptr f, shared_ptr o, Job* j) +AudioDecoder::AudioDecoder (shared_ptr f, DecodeOptions o, Job* j) : Decoder (f, o, j) { diff --git a/src/lib/audio_decoder.h b/src/lib/audio_decoder.h index 013a6327f..3bf585f4d 100644 --- a/src/lib/audio_decoder.h +++ b/src/lib/audio_decoder.h @@ -34,7 +34,7 @@ class AudioDecoder : public AudioSource, public virtual Decoder { public: - AudioDecoder (boost::shared_ptr, boost::shared_ptr, Job *); + AudioDecoder (boost::shared_ptr, DecodeOptions, Job *); virtual void set_audio_stream (boost::shared_ptr); diff --git a/src/lib/check_hashes_job.cc b/src/lib/check_hashes_job.cc index 099845d8c..2ad97c382 100644 --- a/src/lib/check_hashes_job.cc +++ b/src/lib/check_hashes_job.cc @@ -34,9 +34,9 @@ using std::stringstream; using std::ifstream; using boost::shared_ptr; -CheckHashesJob::CheckHashesJob (shared_ptr f, shared_ptr od, shared_ptr req) +CheckHashesJob::CheckHashesJob (shared_ptr f, DecodeOptions o, shared_ptr req) : Job (f, req) - , _decode_opt (od) + , _decode_opt (o) , _bad (0) { diff --git a/src/lib/check_hashes_job.h b/src/lib/check_hashes_job.h index 7e62b0e7a..5fa17382d 100644 --- a/src/lib/check_hashes_job.h +++ b/src/lib/check_hashes_job.h @@ -18,15 +18,14 @@ */ #include "job.h" - -class DecodeOptions; +#include "options.h" class CheckHashesJob : public Job { public: CheckHashesJob ( boost::shared_ptr f, - boost::shared_ptr od, + DecodeOptions od, boost::shared_ptr req ); @@ -35,6 +34,6 @@ public: std::string status () const; private: - boost::shared_ptr _decode_opt; + DecodeOptions _decode_opt; int _bad; }; diff --git a/src/lib/decoder.cc b/src/lib/decoder.cc index 7066b488e..fd0abee41 100644 --- a/src/lib/decoder.cc +++ b/src/lib/decoder.cc @@ -46,10 +46,10 @@ using boost::shared_ptr; using boost::optional; /** @param f Film. - * @param o Options. + * @param o Decode options. * @param j Job that we are running within, or 0 */ -Decoder::Decoder (boost::shared_ptr f, boost::shared_ptr o, Job* j) +Decoder::Decoder (boost::shared_ptr f, DecodeOptions o, Job* j) : _film (f) , _opt (o) , _job (j) diff --git a/src/lib/decoder.h b/src/lib/decoder.h index 3908afa2f..cc4c87373 100644 --- a/src/lib/decoder.h +++ b/src/lib/decoder.h @@ -34,9 +34,9 @@ #include "video_source.h" #include "audio_source.h" #include "film.h" +#include "options.h" class Job; -class DecodeOptions; class Image; class Log; class DelayLine; @@ -54,7 +54,7 @@ class FilterGraph; class Decoder { public: - Decoder (boost::shared_ptr, boost::shared_ptr, Job *); + Decoder (boost::shared_ptr, DecodeOptions, Job *); virtual ~Decoder () {} virtual bool pass () = 0; @@ -66,8 +66,8 @@ public: protected: /** our Film */ boost::shared_ptr _film; - /** our options */ - boost::shared_ptr _opt; + /** our decode options */ + DecodeOptions _opt; /** associated Job, or 0 */ Job* _job; diff --git a/src/lib/decoder_factory.cc b/src/lib/decoder_factory.cc index 2a0d828e2..c4d818f49 100644 --- a/src/lib/decoder_factory.cc +++ b/src/lib/decoder_factory.cc @@ -36,7 +36,7 @@ using boost::dynamic_pointer_cast; Decoders decoder_factory ( - shared_ptr f, shared_ptr o, Job* j + shared_ptr f, DecodeOptions o, Job* j ) { if (boost::filesystem::is_directory (f->content_path()) || f->content_type() == STILL) { diff --git a/src/lib/decoder_factory.h b/src/lib/decoder_factory.h index 47d977ce7..445a1c8a2 100644 --- a/src/lib/decoder_factory.h +++ b/src/lib/decoder_factory.h @@ -24,8 +24,9 @@ * @brief A method to create appropriate decoders for some content. */ +#include "options.h" + class Film; -class DecodeOptions; class Job; class VideoDecoder; class AudioDecoder; @@ -43,7 +44,7 @@ struct Decoders { }; extern Decoders decoder_factory ( - boost::shared_ptr, boost::shared_ptr, Job * + boost::shared_ptr, DecodeOptions, Job * ); #endif diff --git a/src/lib/examine_content_job.cc b/src/lib/examine_content_job.cc index a783cde33..69a757e2b 100644 --- a/src/lib/examine_content_job.cc +++ b/src/lib/examine_content_job.cc @@ -78,8 +78,8 @@ ExamineContentJob::run () _film->unset_length (); _film->set_crop (Crop ()); - shared_ptr o (new DecodeOptions); - o->decode_audio = false; + DecodeOptions o; + o.decode_audio = false; Decoders decoders = decoder_factory (_film, o, this); @@ -96,8 +96,7 @@ ExamineContentJob::run () /* Get a quick decoder to get the content's length from its header */ - shared_ptr o (new DecodeOptions); - Decoders d = decoder_factory (_film, o, 0); + Decoders d = decoder_factory (_film, DecodeOptions(), 0); _film->set_length (d.video->length()); _film->log()->log (String::compose ("Video length obtained from header as %1 frames", _film->length().get())); diff --git a/src/lib/external_audio_decoder.cc b/src/lib/external_audio_decoder.cc index 25c8068b6..366051418 100644 --- a/src/lib/external_audio_decoder.cc +++ b/src/lib/external_audio_decoder.cc @@ -31,7 +31,7 @@ using std::cout; using boost::shared_ptr; using boost::optional; -ExternalAudioDecoder::ExternalAudioDecoder (shared_ptr f, shared_ptr o, Job* j) +ExternalAudioDecoder::ExternalAudioDecoder (shared_ptr f, DecodeOptions o, Job* j) : Decoder (f, o, j) , AudioDecoder (f, o, j) { diff --git a/src/lib/external_audio_decoder.h b/src/lib/external_audio_decoder.h index 2558955eb..37e53bca7 100644 --- a/src/lib/external_audio_decoder.h +++ b/src/lib/external_audio_decoder.h @@ -44,7 +44,7 @@ private: class ExternalAudioDecoder : public AudioDecoder { public: - ExternalAudioDecoder (boost::shared_ptr, boost::shared_ptr, Job *); + ExternalAudioDecoder (boost::shared_ptr, DecodeOptions, Job *); bool pass (); diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index a19f26ad7..9e5cda889 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -59,7 +59,7 @@ using boost::shared_ptr; using boost::optional; using boost::dynamic_pointer_cast; -FFmpegDecoder::FFmpegDecoder (shared_ptr f, shared_ptr o, Job* j) +FFmpegDecoder::FFmpegDecoder (shared_ptr f, DecodeOptions o, Job* j) : Decoder (f, o, j) , VideoDecoder (f, o, j) , AudioDecoder (f, o, j) @@ -78,7 +78,7 @@ FFmpegDecoder::FFmpegDecoder (shared_ptr f, shared_ptrvideo_sync) { + if (!o.video_sync) { _first_video = 0; } } @@ -239,7 +239,7 @@ FFmpegDecoder::pass () filter_and_emit_video (_frame); } - if (_audio_stream && _opt->decode_audio) { + if (_audio_stream && _opt.decode_audio) { while (avcodec_decode_audio4 (_audio_codec_context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) { int const data_size = av_samples_get_buffer_size ( 0, _audio_codec_context->channels, _frame->nb_samples, audio_sample_format (), 1 @@ -267,14 +267,14 @@ FFmpegDecoder::pass () _film->log()->log (String::compose ("Used only %1 bytes of %2 in packet", r, _packet.size)); } - if (_opt->video_sync) { + if (_opt.video_sync) { out_with_sync (); } else { filter_and_emit_video (_frame); } } - } else if (ffa && _packet.stream_index == ffa->id() && _opt->decode_audio) { + } else if (ffa && _packet.stream_index == ffa->id() && _opt.decode_audio) { int frame_finished; if (avcodec_decode_audio4 (_audio_codec_context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) { @@ -323,7 +323,7 @@ FFmpegDecoder::pass () } } - } else if (_subtitle_stream && _packet.stream_index == _subtitle_stream->id() && _opt->decode_subtitles && _first_video) { + } else if (_subtitle_stream && _packet.stream_index == _subtitle_stream->id() && _opt.decode_subtitles && _first_video) { int got_subtitle; AVSubtitle sub; diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h index 2fb8675f9..51b88a24a 100644 --- a/src/lib/ffmpeg_decoder.h +++ b/src/lib/ffmpeg_decoder.h @@ -86,7 +86,7 @@ private: class FFmpegDecoder : public VideoDecoder, public AudioDecoder { public: - FFmpegDecoder (boost::shared_ptr, boost::shared_ptr, Job *); + FFmpegDecoder (boost::shared_ptr, DecodeOptions, Job *); ~FFmpegDecoder (); float frames_per_second () const; diff --git a/src/lib/film.cc b/src/lib/film.cc index 4bf6606a9..2934595ab 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -290,8 +290,8 @@ Film::make_dcp (bool transcode) throw MissingSettingError ("name"); } - shared_ptr od (new DecodeOptions); - od->decode_subtitles = with_subtitles (); + DecodeOptions od; + od.decode_subtitles = with_subtitles (); shared_ptr r; @@ -878,8 +878,7 @@ Film::set_content (string c) */ try { - shared_ptr o (new DecodeOptions); - Decoders d = decoder_factory (shared_from_this(), o, 0); + Decoders d = decoder_factory (shared_from_this(), DecodeOptions(), 0); set_size (d.video->native_size ()); set_frames_per_second (d.video->frames_per_second ()); @@ -1121,8 +1120,7 @@ Film::set_external_audio (vector a) _external_audio = a; } - shared_ptr o (new DecodeOptions); - shared_ptr decoder (new ExternalAudioDecoder (shared_from_this(), o, 0)); + shared_ptr decoder (new ExternalAudioDecoder (shared_from_this(), DecodeOptions(), 0)); if (decoder->audio_stream()) { _external_audio_stream = decoder->audio_stream (); } diff --git a/src/lib/imagemagick_decoder.cc b/src/lib/imagemagick_decoder.cc index bad1fb813..063730540 100644 --- a/src/lib/imagemagick_decoder.cc +++ b/src/lib/imagemagick_decoder.cc @@ -29,7 +29,7 @@ using std::cout; using boost::shared_ptr; ImageMagickDecoder::ImageMagickDecoder ( - boost::shared_ptr f, boost::shared_ptr o, Job* j) + boost::shared_ptr f, DecodeOptions o, Job* j) : Decoder (f, o, j) , VideoDecoder (f, o, j) { diff --git a/src/lib/imagemagick_decoder.h b/src/lib/imagemagick_decoder.h index 6f426f308..5dfcab6f0 100644 --- a/src/lib/imagemagick_decoder.h +++ b/src/lib/imagemagick_decoder.h @@ -26,7 +26,7 @@ namespace Magick { class ImageMagickDecoder : public VideoDecoder { public: - ImageMagickDecoder (boost::shared_ptr, boost::shared_ptr, Job *); + ImageMagickDecoder (boost::shared_ptr, DecodeOptions, Job *); float frames_per_second () const { /* We don't know */ diff --git a/src/lib/options.h b/src/lib/options.h index 2f8733507..2cd7dffde 100644 --- a/src/lib/options.h +++ b/src/lib/options.h @@ -17,16 +17,13 @@ */ +#ifndef DVDOMATIC_OPTIONS_H +#define DVDOMATIC_OPTIONS_H + /** @file src/options.h - * @brief Options for a transcoding operation. + * @brief Options for a decoding operation. */ -#include -#include -#include -#include -#include "util.h" - class DecodeOptions { public: @@ -40,3 +37,5 @@ public: bool decode_subtitles; bool video_sync; }; + +#endif diff --git a/src/lib/transcode_job.cc b/src/lib/transcode_job.cc index db5c33641..23a3d9fe8 100644 --- a/src/lib/transcode_job.cc +++ b/src/lib/transcode_job.cc @@ -37,12 +37,12 @@ using std::setprecision; using boost::shared_ptr; /** @param s Film to use. - * @param o Options. + * @param o Decode options. * @param req Job that must be completed before this job is run. */ -TranscodeJob::TranscodeJob (shared_ptr f, shared_ptr od, shared_ptr req) +TranscodeJob::TranscodeJob (shared_ptr f, DecodeOptions o, shared_ptr req) : Job (f, req) - , _decode_opt (od) + , _decode_opt (o) { } diff --git a/src/lib/transcode_job.h b/src/lib/transcode_job.h index aef190a64..8f78e7f6a 100644 --- a/src/lib/transcode_job.h +++ b/src/lib/transcode_job.h @@ -23,9 +23,9 @@ #include #include "job.h" +#include "options.h" class Encoder; -class DecodeOptions; /** @class TranscodeJob * @brief A job which transcodes from one format to another. @@ -33,7 +33,7 @@ class DecodeOptions; class TranscodeJob : public Job { public: - TranscodeJob (boost::shared_ptr f, boost::shared_ptr od, boost::shared_ptr req); + TranscodeJob (boost::shared_ptr f, DecodeOptions od, boost::shared_ptr req); std::string name () const; void run (); @@ -43,6 +43,6 @@ protected: int remaining_time () const; private: - boost::shared_ptr _decode_opt; + DecodeOptions _decode_opt; boost::shared_ptr _encoder; }; diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc index 87a1fb3f2..93963761e 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -48,7 +48,7 @@ using boost::dynamic_pointer_cast; * @param j Job that we are running under, or 0. * @param e Encoder to use. */ -Transcoder::Transcoder (shared_ptr f, shared_ptr o, Job* j, shared_ptr e) +Transcoder::Transcoder (shared_ptr f, DecodeOptions o, Job* j, shared_ptr e) : _job (j) , _encoder (e) , _decoders (decoder_factory (f, o, j)) diff --git a/src/lib/transcoder.h b/src/lib/transcoder.h index ef6a438c8..786010869 100644 --- a/src/lib/transcoder.h +++ b/src/lib/transcoder.h @@ -36,7 +36,6 @@ class Gain; class VideoDecoder; class AudioDecoder; class DelayLine; -class DecodeOptions; /** @class Transcoder * @brief A class which takes a FilmState and some Options, then uses those to transcode a Film. @@ -49,7 +48,7 @@ class Transcoder public: Transcoder ( boost::shared_ptr f, - boost::shared_ptr o, + DecodeOptions o, Job* j, boost::shared_ptr e ); diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc index e0a7576ee..3a803a863 100644 --- a/src/lib/video_decoder.cc +++ b/src/lib/video_decoder.cc @@ -28,7 +28,7 @@ using boost::shared_ptr; using boost::optional; -VideoDecoder::VideoDecoder (shared_ptr f, shared_ptr o, Job* j) +VideoDecoder::VideoDecoder (shared_ptr f, DecodeOptions o, Job* j) : Decoder (f, o, j) , _video_frame (0) , _last_source_time (0) diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h index 7726d2057..c0eab2140 100644 --- a/src/lib/video_decoder.h +++ b/src/lib/video_decoder.h @@ -27,7 +27,7 @@ class VideoDecoder : public VideoSource, public virtual Decoder { public: - VideoDecoder (boost::shared_ptr, boost::shared_ptr, Job *); + VideoDecoder (boost::shared_ptr, DecodeOptions, Job *); /** @return video frames per second, or 0 if unknown */ virtual float frames_per_second () const = 0; diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 3d8198457..347531cc2 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -98,10 +98,10 @@ FilmViewer::film_changed (Film::Property p) break; case Film::CONTENT: { - shared_ptr o (new DecodeOptions); - o->decode_audio = false; - o->decode_subtitles = true; - o->video_sync = false; + DecodeOptions o; + o.decode_audio = false; + o.decode_subtitles = true; + o.video_sync = false; _decoders = decoder_factory (_film, o, 0); _decoders.video->Video.connect (bind (&FilmViewer::process_video, this, _1, _2, _3)); _decoders.video->OutputChanged.connect (boost::bind (&FilmViewer::decoder_changed, this)); -- cgit v1.2.3 From 4870ce43dd314d557f7b14938456138c746fd617 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 17 Jan 2013 00:33:16 +0000 Subject: dcp_trim -> trim --- src/lib/check_hashes_job.cc | 4 ++-- src/lib/film.cc | 38 +++++++++++++++++++------------------- src/lib/film.h | 20 ++++++++++---------- src/lib/make_dcp_job.cc | 2 +- src/lib/transcode_job.cc | 2 +- src/wx/film_editor.cc | 44 ++++++++++++++++++++++---------------------- src/wx/film_editor.h | 8 ++++---- src/wx/properties_dialog.cc | 2 +- test/metadata.ref | 6 +++--- test/test.cc | 10 +++++----- 10 files changed, 68 insertions(+), 68 deletions(-) (limited to 'src') diff --git a/src/lib/check_hashes_job.cc b/src/lib/check_hashes_job.cc index 2ad97c382..cf4e86b79 100644 --- a/src/lib/check_hashes_job.cc +++ b/src/lib/check_hashes_job.cc @@ -57,12 +57,12 @@ CheckHashesJob::run () throw EncodeError ("cannot check hashes of a DCP with unknown length"); } - SourceFrame const N = _film->dcp_trim_start() + _film->dcp_length().get(); + SourceFrame const N = _film->trim_start() + _film->dcp_length().get(); DCPFrameRate const dfr (_film->frames_per_second ()); int const inc = dfr.skip ? 2 : 1; - for (SourceFrame i = _film->dcp_trim_start(); i < N; i += inc) { + for (SourceFrame i = _film->trim_start(); i < N; i += inc) { string const j2k_file = _film->frame_out_path (i, false); string const hash_file = _film->hash_out_path (i, false); diff --git a/src/lib/film.cc b/src/lib/film.cc index 2934595ab..8fe03184d 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -73,7 +73,7 @@ using boost::ends_with; using boost::starts_with; using boost::optional; -int const Film::state_version = 1; +int const Film::state_version = 2; /** Construct a Film object in a given directory, reading any metadata * file that exists in that directory. An exception will be thrown if @@ -89,8 +89,8 @@ Film::Film (string d, bool must_exist) , _dcp_content_type (0) , _format (0) , _scaler (Scaler::from_id ("bicubic")) - , _dcp_trim_start (0) - , _dcp_trim_end (0) + , _trim_start (0) + , _trim_end (0) , _dcp_ab (false) , _use_content_audio (true) , _audio_gain (0) @@ -155,8 +155,8 @@ Film::Film (Film const & o) , _crop (o._crop) , _filters (o._filters) , _scaler (o._scaler) - , _dcp_trim_start (o._dcp_trim_start) - , _dcp_trim_end (o._dcp_trim_end) + , _trim_start (o._trim_start) + , _trim_end (o._trim_end) , _reel_size (o._reel_size) , _dcp_ab (o._dcp_ab) , _content_audio_stream (o._content_audio_stream) @@ -388,8 +388,8 @@ Film::write_metadata () const f << "filter " << (*i)->id () << "\n"; } f << "scaler " << _scaler->id () << "\n"; - f << "dcp_trim_start " << _dcp_trim_start << "\n"; - f << "dcp_trim_end " << _dcp_trim_end << "\n"; + f << "trim_start " << _trim_start << "\n"; + f << "trim_end " << _trim_end << "\n"; if (_reel_size) { f << "reel_size " << _reel_size.get() << "\n"; } @@ -503,10 +503,10 @@ Film::read_metadata () _filters.push_back (Filter::from_id (v)); } else if (k == "scaler") { _scaler = Scaler::from_id (v); - } else if (k == "dcp_trim_start") { - _dcp_trim_start = atoi (v.c_str ()); - } else if (k == "dcp_trim_end") { - _dcp_trim_end = atoi (v.c_str ()); + } else if ( ((!version || version < 2) && k == "trim_start") || k == "trim_start") { + _trim_start = atoi (v.c_str ()); + } else if ( ((!version || version < 2) && k == "trim_end") || k == "trim_end") { + _trim_end = atoi (v.c_str ()); } else if (k == "reel_size") { _reel_size = boost::lexical_cast (v); } else if (k == "dcp_ab") { @@ -706,7 +706,7 @@ Film::dcp_length () const return boost::optional (); } - return length().get() - dcp_trim_start() - dcp_trim_end(); + return length().get() - trim_start() - trim_end(); } /** @return a DCI-compliant name for a DCP of this film */ @@ -1053,23 +1053,23 @@ Film::set_scaler (Scaler const * s) } void -Film::set_dcp_trim_start (int t) +Film::set_trim_start (int t) { { boost::mutex::scoped_lock lm (_state_mutex); - _dcp_trim_start = t; + _trim_start = t; } - signal_changed (DCP_TRIM_START); + signal_changed (TRIM_START); } void -Film::set_dcp_trim_end (int t) +Film::set_trim_end (int t) { { boost::mutex::scoped_lock lm (_state_mutex); - _dcp_trim_end = t; + _trim_end = t; } - signal_changed (DCP_TRIM_END); + signal_changed (TRIM_END); } void @@ -1457,7 +1457,7 @@ Film::video_range () const return boost::optional > (); } - return make_pair (dcp_trim_start(), dcp_trim_start() + dcp_length().get()); + return make_pair (trim_start(), trim_start() + dcp_length().get()); } boost::optional > diff --git a/src/lib/film.h b/src/lib/film.h index 6c27af3ab..4cecf663c 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -120,8 +120,8 @@ public: CROP, FILTERS, SCALER, - DCP_TRIM_START, - DCP_TRIM_END, + TRIM_START, + TRIM_END, REEL_SIZE, DCP_AB, CONTENT_AUDIO_STREAM, @@ -197,14 +197,14 @@ public: return _scaler; } - SourceFrame dcp_trim_start () const { + SourceFrame trim_start () const { boost::mutex::scoped_lock lm (_state_mutex); - return _dcp_trim_start; + return _trim_start; } - SourceFrame dcp_trim_end () const { + SourceFrame trim_end () const { boost::mutex::scoped_lock lm (_state_mutex); - return _dcp_trim_end; + return _trim_end; } boost::optional reel_size () const { @@ -365,8 +365,8 @@ public: void set_bottom_crop (int); void set_filters (std::vector); void set_scaler (Scaler const *); - void set_dcp_trim_start (int); - void set_dcp_trim_end (int); + void set_trim_start (int); + void set_trim_end (int); void set_reel_size (uint64_t); void unset_reel_size (); void set_dcp_ab (bool); @@ -448,9 +448,9 @@ private: /** Scaler algorithm to use */ Scaler const * _scaler; /** Frames to trim off the start of the DCP */ - int _dcp_trim_start; + int _trim_start; /** Frames to trim off the end of the DCP */ - int _dcp_trim_end; + int _trim_end; /** Approximate target reel size in bytes; if not set, use a single reel */ boost::optional _reel_size; /** true to create an A/B comparison DCP, where the left half of the image diff --git a/src/lib/make_dcp_job.cc b/src/lib/make_dcp_job.cc index efc2f05d5..fcb10069d 100644 --- a/src/lib/make_dcp_job.cc +++ b/src/lib/make_dcp_job.cc @@ -63,7 +63,7 @@ MakeDCPJob::j2c_path (int f, int offset) const { DCPFrameRate dfr (_film->frames_per_second()); int const mult = dfr.skip ? 2 : 1; - SourceFrame const s = ((f + offset) * mult) + _film->dcp_trim_start(); + SourceFrame const s = ((f + offset) * mult) + _film->trim_start(); return _film->frame_out_path (s, false); } diff --git a/src/lib/transcode_job.cc b/src/lib/transcode_job.cc index 23a3d9fe8..c9792ed2e 100644 --- a/src/lib/transcode_job.cc +++ b/src/lib/transcode_job.cc @@ -120,6 +120,6 @@ TranscodeJob::remaining_time () const } /* We assume that dcp_length() is valid, if it is set */ - SourceFrame const left = _film->dcp_trim_start() + _film->dcp_length().get() - _encoder->video_frame(); + SourceFrame const left = _film->trim_start() + _film->dcp_length().get() - _encoder->video_frame(); return left / fps; } diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 17c40c83d..f83518b88 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -140,11 +140,11 @@ FilmEditor::make_film_panel () video_control (add_label_to_sizer (_film_sizer, _film_panel, "Trim frames")); wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); video_control (add_label_to_sizer (s, _film_panel, "Start")); - _dcp_trim_start = new wxSpinCtrl (_film_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)); - s->Add (video_control (_dcp_trim_start)); + _trim_start = new wxSpinCtrl (_film_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)); + s->Add (video_control (_trim_start)); video_control (add_label_to_sizer (s, _film_panel, "End")); - _dcp_trim_end = new wxSpinCtrl (_film_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)); - s->Add (video_control (_dcp_trim_end)); + _trim_end = new wxSpinCtrl (_film_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)); + s->Add (video_control (_trim_end)); _film_sizer->Add (s); } @@ -202,8 +202,8 @@ FilmEditor::connect_to_widgets () _dcp_content_type->Connect (wxID_ANY, wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler (FilmEditor::dcp_content_type_changed), 0, this); _dcp_ab->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::dcp_ab_toggled), 0, this); _still_duration->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::still_duration_changed), 0, this); - _dcp_trim_start->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::dcp_trim_start_changed), 0, this); - _dcp_trim_end->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::dcp_trim_end_changed), 0, this); + _trim_start->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::trim_start_changed), 0, this); + _trim_end->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::trim_end_changed), 0, this); _multiple_reels->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::multiple_reels_toggled), 0, this); _reel_size->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::reel_size_changed), 0, this); _with_subtitles->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::with_subtitles_toggled), 0, this); @@ -304,8 +304,8 @@ FilmEditor::make_video_panel () _right_crop->SetRange (0, 1024); _bottom_crop->SetRange (0, 1024); _still_duration->SetRange (1, 60 * 60); - _dcp_trim_start->SetRange (0, 100); - _dcp_trim_end->SetRange (0, 100); + _trim_start->SetRange (0, 100); + _trim_end->SetRange (0, 100); _j2k_bandwidth->SetRange (50, 250); } @@ -661,8 +661,8 @@ FilmEditor::film_changed (Film::Property p) } _length->SetLabel (std_to_wx (s.str ())); if (_film->length()) { - _dcp_trim_start->SetRange (0, _film->length().get()); - _dcp_trim_end->SetRange (0, _film->length().get()); + _trim_start->SetRange (0, _film->length().get()); + _trim_end->SetRange (0, _film->length().get()); } break; case Film::DCP_CONTENT_TYPE: @@ -675,11 +675,11 @@ FilmEditor::film_changed (Film::Property p) case Film::SCALER: checked_set (_scaler, Scaler::as_index (_film->scaler ())); break; - case Film::DCP_TRIM_START: - checked_set (_dcp_trim_start, _film->dcp_trim_start()); + case Film::TRIM_START: + checked_set (_trim_start, _film->trim_start()); break; - case Film::DCP_TRIM_END: - checked_set (_dcp_trim_end, _film->dcp_trim_end()); + case Film::TRIM_END: + checked_set (_trim_end, _film->trim_end()); break; case Film::REEL_SIZE: if (_film->reel_size()) { @@ -811,8 +811,8 @@ FilmEditor::set_film (shared_ptr f) film_changed (Film::CROP); film_changed (Film::FILTERS); film_changed (Film::SCALER); - film_changed (Film::DCP_TRIM_START); - film_changed (Film::DCP_TRIM_END); + film_changed (Film::TRIM_START); + film_changed (Film::TRIM_END); film_changed (Film::REEL_SIZE); film_changed (Film::DCP_AB); film_changed (Film::CONTENT_AUDIO_STREAM); @@ -856,8 +856,8 @@ FilmEditor::set_things_sensitive (bool s) _scaler->Enable (s); _audio_stream->Enable (s); _dcp_content_type->Enable (s); - _dcp_trim_start->Enable (s); - _dcp_trim_end->Enable (s); + _trim_start->Enable (s); + _trim_end->Enable (s); _multiple_reels->Enable (s); _reel_size->Enable (s); _dcp_ab->Enable (s); @@ -974,23 +974,23 @@ FilmEditor::still_duration_changed (wxCommandEvent &) } void -FilmEditor::dcp_trim_start_changed (wxCommandEvent &) +FilmEditor::trim_start_changed (wxCommandEvent &) { if (!_film) { return; } - _film->set_dcp_trim_start (_dcp_trim_start->GetValue ()); + _film->set_trim_start (_trim_start->GetValue ()); } void -FilmEditor::dcp_trim_end_changed (wxCommandEvent &) +FilmEditor::trim_end_changed (wxCommandEvent &) { if (!_film) { return; } - _film->set_dcp_trim_end (_dcp_trim_end->GetValue ()); + _film->set_trim_end (_trim_end->GetValue ()); } void diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index 34e67eef1..323aead95 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -63,8 +63,8 @@ private: void content_changed (wxCommandEvent &); void trust_content_header_changed (wxCommandEvent &); void format_changed (wxCommandEvent &); - void dcp_trim_start_changed (wxCommandEvent &); - void dcp_trim_end_changed (wxCommandEvent &); + void trim_start_changed (wxCommandEvent &); + void trim_end_changed (wxCommandEvent &); void multiple_reels_toggled (wxCommandEvent &); void reel_size_changed (wxCommandEvent &); void dcp_content_type_changed (wxCommandEvent &); @@ -168,8 +168,8 @@ private: /** The Film's duration for still sources */ wxSpinCtrl* _still_duration; - wxSpinCtrl* _dcp_trim_start; - wxSpinCtrl* _dcp_trim_end; + wxSpinCtrl* _trim_start; + wxSpinCtrl* _trim_end; wxCheckBox* _multiple_reels; wxSpinCtrl* _reel_size; /** Selector to generate an A/B comparison DCP */ diff --git a/src/wx/properties_dialog.cc b/src/wx/properties_dialog.cc index b03c6b32c..c34922ec4 100644 --- a/src/wx/properties_dialog.cc +++ b/src/wx/properties_dialog.cc @@ -93,7 +93,7 @@ PropertiesDialog::frames_already_encoded () const if (_film->dcp_length()) { /* XXX: encoded_frames() should check which frames have been encoded */ - u << " (" << ((_film->encoded_frames() - _film->dcp_trim_start()) * 100 / _film->dcp_length().get()) << "%)"; + u << " (" << ((_film->encoded_frames() - _film->trim_start()) * 100 / _film->dcp_length().get()) << "%)"; } return u.str (); } diff --git a/test/metadata.ref b/test/metadata.ref index 3aea4bcba..90255e916 100644 --- a/test/metadata.ref +++ b/test/metadata.ref @@ -1,4 +1,4 @@ -version 1 +version 2 name fred use_dci_name 1 content @@ -12,8 +12,8 @@ bottom_crop 4 filter pphb filter unsharp scaler bicubic -dcp_trim_start 42 -dcp_trim_end 99 +trim_start 42 +trim_end 99 dcp_ab 1 use_content_audio 1 audio_gain 0 diff --git a/test/test.cc b/test/test.cc index 45a80f024..9143b87d5 100644 --- a/test/test.cc +++ b/test/test.cc @@ -99,8 +99,8 @@ BOOST_AUTO_TEST_CASE (film_metadata_test) f_filters.push_back (Filter::from_id ("pphb")); f_filters.push_back (Filter::from_id ("unsharp")); f->set_filters (f_filters); - f->set_dcp_trim_start (42); - f->set_dcp_trim_end (99); + f->set_trim_start (42); + f->set_trim_end (99); f->set_dcp_ab (true); f->write_metadata (); @@ -121,8 +121,8 @@ BOOST_AUTO_TEST_CASE (film_metadata_test) BOOST_CHECK_EQUAL (g_filters.size(), 2); BOOST_CHECK_EQUAL (g_filters.front(), Filter::from_id ("pphb")); BOOST_CHECK_EQUAL (g_filters.back(), Filter::from_id ("unsharp")); - BOOST_CHECK_EQUAL (g->dcp_trim_start(), 42); - BOOST_CHECK_EQUAL (g->dcp_trim_end(), 99); + BOOST_CHECK_EQUAL (g->trim_start(), 42); + BOOST_CHECK_EQUAL (g->trim_end(), 99); BOOST_CHECK_EQUAL (g->dcp_ab(), true); g->write_metadata (); @@ -419,7 +419,7 @@ BOOST_AUTO_TEST_CASE (make_dcp_with_range_test) film->examine_content (); film->set_format (Format::from_nickname ("Flat")); film->set_dcp_content_type (DCPContentType::from_pretty_name ("Test")); - film->set_dcp_trim_end (42); + film->set_trim_end (42); film->make_dcp (true); while (JobManager::instance()->work_to_do() && !JobManager::instance()->errors()) { -- cgit v1.2.3 From 3882d34aed9dee417ceed93bf0bf5372b3970ff6 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 17 Jan 2013 20:49:09 +0000 Subject: Basics of doing trim using asset entry point / duration. --- src/lib/encoder.cc | 32 -------------------------------- src/lib/film.cc | 34 ---------------------------------- src/lib/film.h | 2 -- src/lib/make_dcp_job.cc | 7 +++++++ 4 files changed, 7 insertions(+), 68 deletions(-) (limited to 'src') diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 35b43e334..c32d68834 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -286,14 +286,6 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptrvideo_range ()) { - pair const r = _film->video_range().get(); - if (_video_frame < r.first || _video_frame >= r.second) { - ++_video_frame; - return; - } - } - boost::mutex::scoped_lock lock (_worker_mutex); /* Wait until the queue has gone down a bit */ @@ -343,30 +335,6 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptr data) { - if (_film->audio_range ()) { - shared_ptr trimmed (new AudioBuffers (*data.get ())); - - /* Range that we are encoding */ - pair required_range = _film->audio_range().get(); - /* Range of this block of data */ - pair this_range (_audio_frame, _audio_frame + trimmed->frames()); - - if (this_range.second < required_range.first || required_range.second < this_range.first) { - /* No part of this audio is within the required range */ - return; - } else if (required_range.first >= this_range.first && required_range.first < this_range.second) { - /* Trim start */ - int64_t const shift = required_range.first - this_range.first; - trimmed->move (shift, 0, trimmed->frames() - shift); - trimmed->set_frames (trimmed->frames() - shift); - } else if (required_range.second >= this_range.first && required_range.second < this_range.second) { - /* Trim end */ - trimmed->set_frames (required_range.second - this_range.first); - } - - data = trimmed; - } - #if HAVE_SWRESAMPLE /* Maybe sample-rate convert */ if (_swr_context) { diff --git a/src/lib/film.cc b/src/lib/film.cc index 8fe03184d..2af8d3c14 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -1450,37 +1450,3 @@ Film::multichannel_audio_out_path (int c, bool t) const return s.str (); } -boost::optional > -Film::video_range () const -{ - if (!dcp_length()) { - return boost::optional > (); - } - - return make_pair (trim_start(), trim_start() + dcp_length().get()); -} - -boost::optional > -Film::audio_range () const -{ - boost::optional > vr = video_range (); - if (!vr || !audio_stream()) { - return boost::optional > (); - } - - DCPFrameRate dfr (frames_per_second ()); - return make_pair ( - - video_frames_to_audio_frames ( - vr.get().first, - dcp_audio_sample_rate (audio_stream()->sample_rate()), - dfr.frames_per_second - ), - - video_frames_to_audio_frames ( - vr.get().second, - dcp_audio_sample_rate (audio_stream()->sample_rate()), - dfr.frames_per_second - ) - ); -} diff --git a/src/lib/film.h b/src/lib/film.h index 4cecf663c..b03d84920 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -101,8 +101,6 @@ public: } int audio_channels () const; - boost::optional > video_range () const; - boost::optional > audio_range () const; void set_dci_date_today (); diff --git a/src/lib/make_dcp_job.cc b/src/lib/make_dcp_job.cc index fcb10069d..3603298d9 100644 --- a/src/lib/make_dcp_job.cc +++ b/src/lib/make_dcp_job.cc @@ -142,6 +142,9 @@ MakeDCPJob::run () _film->format()->dcp_size().height ) ); + + pa->set_entry_point (_film->trim_start ()); + pa->set_duration (_film->duration ()); ascend (); @@ -161,6 +164,10 @@ MakeDCPJob::run () dcp_audio_channels (_film->audio_channels()) ) ); + + sa->set_entry_point (_film->trim_start ()); + sa->set_duration (_film->duration ()); + ascend (); } -- cgit v1.2.3 From 39c65e47432c76a4e34aaea5317bd7362409aed0 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 17 Jan 2013 21:30:16 +0000 Subject: Try to tidy up frame indexing; use DCP length obtained from the transcode to make the DCP. --- src/lib/check_hashes_job.cc | 12 ++++-------- src/lib/dcp_video_frame.cc | 9 +++++---- src/lib/dcp_video_frame.h | 12 ++++++------ src/lib/encoder.cc | 39 +++++++++++++++++++++++---------------- src/lib/encoder.h | 12 ++++++++---- src/lib/ffmpeg_decoder.cc | 1 + src/lib/ffmpeg_decoder.h | 2 +- src/lib/film.cc | 40 +++++++++++++++++++++++++--------------- src/lib/film.h | 26 +++++++++++++++++--------- src/lib/filter_graph.cc | 1 + src/lib/filter_graph.h | 6 +++--- src/lib/format.cc | 1 + src/lib/format.h | 10 +++++----- src/lib/image.cc | 1 + src/lib/image.h | 14 +++++++------- src/lib/imagemagick_decoder.cc | 3 ++- src/lib/imagemagick_decoder.h | 2 +- src/lib/make_dcp_job.cc | 32 ++++++++------------------------ src/lib/matcher.h | 2 +- src/lib/server.cc | 1 + src/lib/subtitle.cc | 1 + src/lib/transcode_job.cc | 15 +++++++++++++-- src/lib/util.cc | 11 +---------- src/lib/util.h | 34 ++++------------------------------ src/lib/video_decoder.h | 2 +- src/wx/film_editor.cc | 2 ++ src/wx/film_viewer.cc | 1 + src/wx/properties_dialog.cc | 4 ++-- test/metadata.ref | 1 + test/test.cc | 14 +++++++------- 30 files changed, 154 insertions(+), 157 deletions(-) (limited to 'src') diff --git a/src/lib/check_hashes_job.cc b/src/lib/check_hashes_job.cc index cf4e86b79..55a744552 100644 --- a/src/lib/check_hashes_job.cc +++ b/src/lib/check_hashes_job.cc @@ -53,16 +53,12 @@ CheckHashesJob::run () { _bad = 0; - if (!_film->dcp_length()) { - throw EncodeError ("cannot check hashes of a DCP with unknown length"); + if (!_film->dcp_intrinsic_duration()) { + throw EncodeError ("cannot check hashes of a DCP with unknown intrinsic duration"); } - SourceFrame const N = _film->trim_start() + _film->dcp_length().get(); - DCPFrameRate const dfr (_film->frames_per_second ()); - - int const inc = dfr.skip ? 2 : 1; - - for (SourceFrame i = _film->trim_start(); i < N; i += inc) { + int const N = _film->dcp_intrinsic_duration().get(); + for (int i = 0; i < N; ++i) { string const j2k_file = _film->frame_out_path (i, false); string const hash_file = _film->hash_out_path (i, false); diff --git a/src/lib/dcp_video_frame.cc b/src/lib/dcp_video_frame.cc index c00ed9b88..427d447ef 100644 --- a/src/lib/dcp_video_frame.cc +++ b/src/lib/dcp_video_frame.cc @@ -60,13 +60,14 @@ using std::string; using std::stringstream; using std::ofstream; using boost::shared_ptr; +using libdcp::Size; /** Construct a DCP video frame. * @param input Input image. * @param out Required size of output, in pixels (including any padding). * @param s Scaler to use. * @param p Number of pixels of padding either side of the image. - * @param f Index of the frame within the Film's source. + * @param f Index of the frame within the DCP's intrinsic duration. * @param fps Frames per second of the Film's source. * @param pp FFmpeg post-processing string to use. * @param clut Colour look-up table to use (see Config::colour_lut_index ()) @@ -76,7 +77,7 @@ using boost::shared_ptr; DCPVideoFrame::DCPVideoFrame ( shared_ptr yuv, shared_ptr sub, Size out, int p, int subtitle_offset, float subtitle_scale, - Scaler const * s, SourceFrame f, float fps, string pp, int clut, int bw, Log* l + Scaler const * s, int f, float fps, string pp, int clut, int bw, Log* l ) : _input (yuv) , _subtitle (sub) @@ -373,10 +374,10 @@ DCPVideoFrame::encode_remotely (ServerDescription const * serv) /** Write this data to a J2K file. * @param opt Options. - * @param frame Frame index. + * @param frame DCP Frame index. */ void -EncodedData::write (shared_ptr film, SourceFrame frame) +EncodedData::write (shared_ptr film, int frame) { string const tmp_j2k = film->frame_out_path (frame, true); diff --git a/src/lib/dcp_video_frame.h b/src/lib/dcp_video_frame.h index 1b75cb207..4271ebb28 100644 --- a/src/lib/dcp_video_frame.h +++ b/src/lib/dcp_video_frame.h @@ -50,7 +50,7 @@ public: virtual ~EncodedData () {} void send (boost::shared_ptr socket); - void write (boost::shared_ptr, SourceFrame); + void write (boost::shared_ptr, int); /** @return data */ uint8_t* data () const { @@ -107,8 +107,8 @@ class DCPVideoFrame { public: DCPVideoFrame ( - boost::shared_ptr, boost::shared_ptr, Size, - int, int, float, Scaler const *, SourceFrame, float, std::string, int, int, Log * + boost::shared_ptr, boost::shared_ptr, libdcp::Size, + int, int, float, Scaler const *, int, float, std::string, int, int, Log * ); virtual ~DCPVideoFrame (); @@ -116,7 +116,7 @@ public: boost::shared_ptr encode_locally (); boost::shared_ptr encode_remotely (ServerDescription const *); - SourceFrame frame () const { + int frame () const { return _frame; } @@ -125,12 +125,12 @@ private: boost::shared_ptr _input; ///< the input image boost::shared_ptr _subtitle; ///< any subtitle that should be on the image - Size _out_size; ///< the required size of the output, in pixels + libdcp::Size _out_size; ///< the required size of the output, in pixels int _padding; int _subtitle_offset; float _subtitle_scale; Scaler const * _scaler; ///< scaler to use - SourceFrame _frame; ///< frame index within the Film's source + int _frame; ///< frame index within the DCP's intrinsic duration int _frames_per_second; ///< Frames per second that we will use for the DCP (rounded) std::string _post_process; ///< FFmpeg post-processing string to use int _colour_lut; ///< Colour look-up table to use diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index c32d68834..6df7c85a1 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -54,12 +54,13 @@ int const Encoder::_history_size = 25; Encoder::Encoder (shared_ptr f) : _film (f) , _just_skipped (false) - , _video_frame (0) - , _audio_frame (0) + , _video_frames_in (0) + , _audio_frames_in (0) + , _video_frames_out (0) + , _audio_frames_out (0) #ifdef HAVE_SWRESAMPLE , _swr_context (0) #endif - , _audio_frames_written (0) , _process_end (false) { if (_film->audio_stream()) { @@ -241,12 +242,12 @@ Encoder::skipping () const return _just_skipped; } -/** @return Number of video frames that have been received */ -SourceFrame -Encoder::video_frame () const +/** @return Number of video frames that have been sent out */ +int +Encoder::video_frames_out () const { boost::mutex::scoped_lock (_history_mutex); - return _video_frame; + return _video_frames_out; } /** Should be called when a frame has been encoded successfully. @@ -281,8 +282,8 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptrframes_per_second ()); - if (dfr.skip && (_video_frame % 2)) { - ++_video_frame; + if (dfr.skip && (_video_frames_in % 2)) { + ++_video_frames_in; return; } @@ -300,7 +301,7 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptrframe_out_path (_video_frame, false))) { + if (boost::filesystem::exists (_film->frame_out_path (_video_frames_out, false))) { frame_skipped (); return; } @@ -310,7 +311,7 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptr const s = Filter::ffmpeg_strings (_film->filters()); @@ -319,17 +320,23 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptrformat()->dcp_size(), _film->format()->dcp_padding (_film), _film->subtitle_offset(), _film->subtitle_scale(), - _film->scaler(), _video_frame, _film->frames_per_second(), s.second, + _film->scaler(), _video_frames_out, _film->frames_per_second(), s.second, _film->colour_lut(), _film->j2k_bandwidth(), _film->log() ) )); _worker_condition.notify_all (); - _last_real_frame = _video_frame; + _last_real_frame = _video_frames_out; } - ++_video_frame; + ++_video_frames_in; + ++_video_frames_out; + + if (dfr.repeat) { + _links_required.push_back (make_pair (_video_frames_out, _video_frames_out - 1)); + ++_video_frames_out; + } } void @@ -378,7 +385,7 @@ Encoder::process_audio (shared_ptr data) write_audio (data); - _audio_frame += data->frames (); + _audio_frames_in += data->frames (); } void @@ -388,7 +395,7 @@ Encoder::write_audio (shared_ptr audio) sf_write_float (_sound_files[i], audio->data(i), audio->frames()); } - _audio_frames_written += audio->frames (); + _audio_frames_out += audio->frames (); } void diff --git a/src/lib/encoder.h b/src/lib/encoder.h index d8edf9b26..20255cca9 100644 --- a/src/lib/encoder.h +++ b/src/lib/encoder.h @@ -82,7 +82,7 @@ public: float current_frames_per_second () const; bool skipping () const; - SourceFrame video_frame () const; + int video_frames_out () const; private: @@ -111,9 +111,13 @@ private: bool _just_skipped; /** Number of video frames received so far */ - SourceFrame _video_frame; + SourceFrame _video_frames_in; /** Number of audio frames received so far */ - int64_t _audio_frame; + int64_t _audio_frames_in; + /** Number of video frames written for the DCP so far */ + int _video_frames_out; + /** Number of audio frames written for the DCP so far */ + int64_t _audio_frames_out; #if HAVE_SWRESAMPLE SwrContext* _swr_context; @@ -122,11 +126,11 @@ private: /** List of links that we need to create when all frames have been processed; * such that we need to call link (first, second) for each member of this list. * In other words, `first' is a `real' frame and `second' should be a link to `first'. + * Frames are DCP frames. */ std::list > _links_required; std::vector _sound_files; - int64_t _audio_frames_written; boost::optional _last_real_frame; bool _process_end; diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 9e5cda889..e7dfc206b 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -58,6 +58,7 @@ using std::list; using boost::shared_ptr; using boost::optional; using boost::dynamic_pointer_cast; +using libdcp::Size; FFmpegDecoder::FFmpegDecoder (shared_ptr f, DecodeOptions o, Job* j) : Decoder (f, o, j) diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h index 51b88a24a..9a4e65ebc 100644 --- a/src/lib/ffmpeg_decoder.h +++ b/src/lib/ffmpeg_decoder.h @@ -90,7 +90,7 @@ public: ~FFmpegDecoder (); float frames_per_second () const; - Size native_size () const; + libdcp::Size native_size () const; SourceFrame length () const; int time_base_numerator () const; int time_base_denominator () const; diff --git a/src/lib/film.cc b/src/lib/film.cc index 2af8d3c14..1741d49e6 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -72,6 +72,7 @@ using boost::to_upper_copy; using boost::ends_with; using boost::starts_with; using boost::optional; +using libdcp::Size; int const Film::state_version = 2; @@ -180,6 +181,7 @@ Film::Film (Film const & o) , _package_type (o._package_type) , _size (o._size) , _length (o._length) + , _dcp_intrinsic_duration (o._dcp_intrinsic_duration) , _content_digest (o._content_digest) , _content_audio_streams (o._content_audio_streams) , _external_audio_stream (o._external_audio_stream) @@ -423,6 +425,7 @@ Film::write_metadata () const f << "width " << _size.width << "\n"; f << "height " << _size.height << "\n"; f << "length " << _length.get_value_or(0) << "\n"; + f << "dcp_intrinsic_duration " << _dcp_intrinsic_duration.get_value_or(0) << "\n"; f << "content_digest " << _content_digest << "\n"; for (vector >::const_iterator i = _content_audio_streams.begin(); i != _content_audio_streams.end(); ++i) { @@ -569,6 +572,11 @@ Film::read_metadata () if (vv) { _length = vv; } + } else if (k == "dcp_intrinsic_duration") { + int const vv = atoi (v.c_str ()); + if (vv) { + _dcp_intrinsic_duration = vv; + } } else if (k == "content_digest") { _content_digest = v; } else if (k == "content_audio_stream" || (!version && k == "audio_stream")) { @@ -695,18 +703,10 @@ Film::target_audio_sample_rate () const return rint (t); } -boost::optional -Film::dcp_length () const +int +Film::still_duration_in_frames () const { - if (content_type() == STILL) { - return _still_duration * frames_per_second(); - } - - if (!length()) { - return boost::optional (); - } - - return length().get() - trim_start() - trim_end(); + return still_duration() * frames_per_second(); } /** @return a DCI-compliant name for a DCP of this film */ @@ -1327,7 +1327,17 @@ Film::unset_length () _length = boost::none; } signal_changed (LENGTH); -} +} + +void +Film::set_dcp_intrinsic_duration (int d) +{ + { + boost::mutex::scoped_lock lm (_state_mutex); + _dcp_intrinsic_duration = d; + } + signal_changed (DCP_INTRINSIC_DURATION); +} void Film::set_content_digest (string d) @@ -1409,12 +1419,12 @@ Film::audio_stream () const return _external_audio_stream; } -/** @param f Source frame index. +/** @param f DCP frame index. * @param t true to return a temporary file path, otherwise a permanent one. * @return The path to write this video frame to. */ string -Film::frame_out_path (SourceFrame f, bool t) const +Film::frame_out_path (int f, bool t) const { stringstream s; s << j2k_dir() << "/"; @@ -1429,7 +1439,7 @@ Film::frame_out_path (SourceFrame f, bool t) const } string -Film::hash_out_path (SourceFrame f, bool t) const +Film::hash_out_path (int f, bool t) const { return frame_out_path (f, t) + ".md5"; } diff --git a/src/lib/film.h b/src/lib/film.h index b03d84920..e10abfa4b 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -78,8 +78,8 @@ public: std::string file (std::string f) const; std::string dir (std::string d) const; - std::string frame_out_path (SourceFrame f, bool t) const; - std::string hash_out_path (SourceFrame f, bool t) const; + std::string frame_out_path (int f, bool t) const; + std::string hash_out_path (int f, bool t) const; std::string multichannel_audio_out_path (int c, bool t) const; std::string content_path () const; @@ -90,11 +90,14 @@ public: void write_metadata () const; void read_metadata (); - Size cropped_size (Size) const; - boost::optional dcp_length () const; + libdcp::Size cropped_size (libdcp::Size) const; std::string dci_name () const; std::string dcp_name () const; + boost::optional dcp_intrinsic_duration () const { + return _dcp_intrinsic_duration; + } + /** @return true if our state has changed since we last saved it */ bool dirty () const { return _dirty; @@ -137,6 +140,7 @@ public: DCI_METADATA, SIZE, LENGTH, + DCP_INTRINSIC_DURATION, CONTENT_AUDIO_STREAMS, SUBTITLE_STREAMS, FRAMES_PER_SECOND, @@ -195,12 +199,12 @@ public: return _scaler; } - SourceFrame trim_start () const { + int trim_start () const { boost::mutex::scoped_lock lm (_state_mutex); return _trim_start; } - SourceFrame trim_end () const { + int trim_end () const { boost::mutex::scoped_lock lm (_state_mutex); return _trim_end; } @@ -245,6 +249,8 @@ public: return _still_duration; } + int still_duration_in_frames () const; + boost::shared_ptr subtitle_stream () const { boost::mutex::scoped_lock lm (_state_mutex); return _subtitle_stream; @@ -310,7 +316,7 @@ public: return _package_type; } - Size size () const { + libdcp::Size size () const { boost::mutex::scoped_lock lm (_state_mutex); return _size; } @@ -387,9 +393,10 @@ public: void set_studio (std::string); void set_facility (std::string); void set_package_type (std::string); - void set_size (Size); + void set_size (libdcp::Size); void set_length (SourceFrame); void unset_length (); + void set_dcp_intrinsic_duration (int); void set_content_digest (std::string); void set_content_audio_streams (std::vector >); void set_subtitle_streams (std::vector >); @@ -499,9 +506,10 @@ private: /* Data which are cached to speed things up */ /** Size, in pixels, of the source (ignoring cropping) */ - Size _size; + libdcp::Size _size; /** The length of the source, in video frames (as far as we know) */ boost::optional _length; + boost::optional _dcp_intrinsic_duration; /** MD5 digest of our content file */ std::string _content_digest; /** The audio streams in our content */ diff --git a/src/lib/filter_graph.cc b/src/lib/filter_graph.cc index 376ab404f..86864a762 100644 --- a/src/lib/filter_graph.cc +++ b/src/lib/filter_graph.cc @@ -47,6 +47,7 @@ using std::stringstream; using std::string; using std::list; using boost::shared_ptr; +using libdcp::Size; /** Construct a FilterGraph for the settings in a film. * @param film Film. diff --git a/src/lib/filter_graph.h b/src/lib/filter_graph.h index 9e6ac6252..7e4e8422b 100644 --- a/src/lib/filter_graph.h +++ b/src/lib/filter_graph.h @@ -37,15 +37,15 @@ class FFmpegDecoder; class FilterGraph { public: - FilterGraph (boost::shared_ptr film, FFmpegDecoder* decoder, Size s, AVPixelFormat p); + FilterGraph (boost::shared_ptr film, FFmpegDecoder* decoder, libdcp::Size s, AVPixelFormat p); - bool can_process (Size s, AVPixelFormat p) const; + bool can_process (libdcp::Size s, AVPixelFormat p) const; std::list > process (AVFrame const * frame); private: AVFilterContext* _buffer_src_context; AVFilterContext* _buffer_sink_context; - Size _size; ///< size of the images that this chain can process + libdcp::Size _size; ///< size of the images that this chain can process AVPixelFormat _pixel_format; ///< pixel format of the images that this chain can process }; diff --git a/src/lib/format.cc b/src/lib/format.cc index 975862411..a80fab619 100644 --- a/src/lib/format.cc +++ b/src/lib/format.cc @@ -35,6 +35,7 @@ using std::setprecision; using std::stringstream; using std::vector; using boost::shared_ptr; +using libdcp::Size; vector Format::_formats; diff --git a/src/lib/format.h b/src/lib/format.h index 2118237a4..48a000480 100644 --- a/src/lib/format.h +++ b/src/lib/format.h @@ -31,7 +31,7 @@ class Film; class Format { public: - Format (Size dcp, std::string id, std::string n, std::string d) + Format (libdcp::Size dcp, std::string id, std::string n, std::string d) : _dcp_size (dcp) , _id (id) , _nickname (n) @@ -52,7 +52,7 @@ public: * put in a DCP for this ratio. This size will not correspond * to the ratio when we are doing things like 16:9 in a Flat frame. */ - Size dcp_size () const { + libdcp::Size dcp_size () const { return _dcp_size; } @@ -85,7 +85,7 @@ protected: * put in a DCP for this ratio. This size will not correspond * to the ratio when we are doing things like 16:9 in a Flat frame. */ - Size _dcp_size; + libdcp::Size _dcp_size; /** id for use in metadata */ std::string _id; /** nickname (e.g. Flat, Scope) */ @@ -104,7 +104,7 @@ private: class FixedFormat : public Format { public: - FixedFormat (int, Size, std::string, std::string, std::string); + FixedFormat (int, libdcp::Size, std::string, std::string, std::string); int ratio_as_integer (boost::shared_ptr) const { return _ratio; @@ -125,7 +125,7 @@ private: class VariableFormat : public Format { public: - VariableFormat (Size, std::string, std::string, std::string); + VariableFormat (libdcp::Size, std::string, std::string, std::string); int ratio_as_integer (boost::shared_ptr f) const; float ratio_as_float (boost::shared_ptr f) const; diff --git a/src/lib/image.cc b/src/lib/image.cc index f774f476f..c41558f02 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -42,6 +42,7 @@ extern "C" { using namespace std; using namespace boost; +using libdcp::Size; void Image::swap (Image& other) diff --git a/src/lib/image.h b/src/lib/image.h index e19c6f54b..5ca3f337c 100644 --- a/src/lib/image.h +++ b/src/lib/image.h @@ -66,13 +66,13 @@ public: virtual int * stride () const = 0; /** @return Size of the image, in pixels */ - virtual Size size () const = 0; + virtual libdcp::Size size () const = 0; int components () const; int lines (int) const; - boost::shared_ptr scale_and_convert_to_rgb (Size out_size, int padding, Scaler const * scaler, bool aligned) const; - boost::shared_ptr scale (Size, Scaler const *, bool aligned) const; + boost::shared_ptr scale_and_convert_to_rgb (libdcp::Size out_size, int padding, Scaler const * scaler, bool aligned) const; + boost::shared_ptr scale (libdcp::Size, Scaler const *, bool aligned) const; boost::shared_ptr post_process (std::string, bool aligned) const; void alpha_blend (boost::shared_ptr image, Position pos); boost::shared_ptr crop (Crop c, bool aligned) const; @@ -106,7 +106,7 @@ public: uint8_t ** data () const; int * line_size () const; int * stride () const; - Size size () const; + libdcp::Size size () const; private: /* Not allowed */ @@ -122,7 +122,7 @@ private: class SimpleImage : public Image { public: - SimpleImage (AVPixelFormat, Size, bool); + SimpleImage (AVPixelFormat, libdcp::Size, bool); SimpleImage (SimpleImage const &); SimpleImage& operator= (SimpleImage const &); ~SimpleImage (); @@ -130,14 +130,14 @@ public: uint8_t ** data () const; int * line_size () const; int * stride () const; - Size size () const; + libdcp::Size size () const; protected: void allocate (); void swap (SimpleImage &); private: - Size _size; ///< size in pixels + libdcp::Size _size; ///< size in pixels uint8_t** _data; ///< array of pointers to components int* _line_size; ///< array of sizes of the data in each line, in pixels (without any alignment padding bytes) int* _stride; ///< array of strides for each line (including any alignment padding bytes) diff --git a/src/lib/imagemagick_decoder.cc b/src/lib/imagemagick_decoder.cc index 063730540..bab4f2f07 100644 --- a/src/lib/imagemagick_decoder.cc +++ b/src/lib/imagemagick_decoder.cc @@ -27,6 +27,7 @@ using std::cout; using boost::shared_ptr; +using libdcp::Size; ImageMagickDecoder::ImageMagickDecoder ( boost::shared_ptr f, DecodeOptions o, Job* j) @@ -70,7 +71,7 @@ bool ImageMagickDecoder::pass () { if (_iter == _files.end()) { - if (!_film->dcp_length() || video_frame() >= _film->dcp_length().get()) { + if (video_frame() >= _film->still_duration_in_frames()) { return true; } diff --git a/src/lib/imagemagick_decoder.h b/src/lib/imagemagick_decoder.h index 5dfcab6f0..84a6f15f9 100644 --- a/src/lib/imagemagick_decoder.h +++ b/src/lib/imagemagick_decoder.h @@ -33,7 +33,7 @@ public: return 0; } - Size native_size () const; + libdcp::Size native_size () const; SourceFrame length () const { /* We don't know */ diff --git a/src/lib/make_dcp_job.cc b/src/lib/make_dcp_job.cc index 3603298d9..6877e5e88 100644 --- a/src/lib/make_dcp_job.cc +++ b/src/lib/make_dcp_job.cc @@ -61,10 +61,7 @@ MakeDCPJob::name () const string MakeDCPJob::j2c_path (int f, int offset) const { - DCPFrameRate dfr (_film->frames_per_second()); - int const mult = dfr.skip ? 2 : 1; - SourceFrame const s = ((f + offset) * mult) + _film->trim_start(); - return _film->frame_out_path (s, false); + return _film->frame_out_path (f, false); } string @@ -76,8 +73,8 @@ MakeDCPJob::wav_path (libdcp::Channel c) const void MakeDCPJob::run () { - if (!_film->dcp_length()) { - throw EncodeError ("cannot make a DCP when the source length is not known"); + if (!_film->dcp_intrinsic_duration()) { + throw EncodeError ("cannot make a DCP when its intrinsic duration is not known"); } descend (0.9); @@ -87,22 +84,10 @@ MakeDCPJob::run () /* Remove any old DCP */ boost::filesystem::remove_all (dcp_path); + int const frames = _film->dcp_intrinsic_duration().get(); + int const duration = frames - _film->trim_start() - _film->trim_end(); DCPFrameRate const dfr (_film->frames_per_second ()); - int frames = 0; - switch (_film->content_type ()) { - case VIDEO: - /* Source frames -> DCP frames */ - frames = _film->dcp_length().get(); - if (dfr.skip) { - frames /= 2; - } - break; - case STILL: - frames = _film->still_duration() * 24; - break; - } - libdcp::DCP dcp (_film->dir (_film->dcp_name())); dcp.Progress.connect (boost::bind (&MakeDCPJob::dcp_progress, this, _1)); @@ -138,13 +123,12 @@ MakeDCPJob::run () &dcp.Progress, dfr.frames_per_second, this_time, - _film->format()->dcp_size().width, - _film->format()->dcp_size().height + _film->format()->dcp_size() ) ); pa->set_entry_point (_film->trim_start ()); - pa->set_duration (_film->duration ()); + pa->set_duration (duration); ascend (); @@ -166,7 +150,7 @@ MakeDCPJob::run () ); sa->set_entry_point (_film->trim_start ()); - sa->set_duration (_film->duration ()); + sa->set_duration (duration); ascend (); } diff --git a/src/lib/matcher.h b/src/lib/matcher.h index b94c28446..60bb87432 100644 --- a/src/lib/matcher.h +++ b/src/lib/matcher.h @@ -35,6 +35,6 @@ private: int _video_frames; int64_t _audio_frames; boost::optional _pixel_format; - boost::optional _size; + boost::optional _size; boost::optional _channels; }; diff --git a/src/lib/server.cc b/src/lib/server.cc index bea75cff8..134cb65a0 100644 --- a/src/lib/server.cc +++ b/src/lib/server.cc @@ -45,6 +45,7 @@ using boost::algorithm::is_any_of; using boost::algorithm::split; using boost::thread; using boost::bind; +using libdcp::Size; /** Create a server description from a string of metadata returned from as_metadata(). * @param v Metadata. diff --git a/src/lib/subtitle.cc b/src/lib/subtitle.cc index c52d3ac66..a7aa7cd21 100644 --- a/src/lib/subtitle.cc +++ b/src/lib/subtitle.cc @@ -27,6 +27,7 @@ using namespace std; using namespace boost; +using libdcp::Size; /** Construct a TimedSubtitle. This is a subtitle image, position, * and a range of time over which it should be shown. diff --git a/src/lib/transcode_job.cc b/src/lib/transcode_job.cc index c9792ed2e..6dd74c36c 100644 --- a/src/lib/transcode_job.cc +++ b/src/lib/transcode_job.cc @@ -67,7 +67,10 @@ TranscodeJob::run () set_progress (1); set_state (FINISHED_OK); + _film->set_dcp_intrinsic_duration (_encoder->video_frames_out ()); + _film->log()->log ("Transcode job completed successfully"); + _film->log()->log (String::compose ("DCP intrinsic duration is %1", _encoder->video_frames_out())); } catch (std::exception& e) { @@ -115,11 +118,19 @@ TranscodeJob::remaining_time () const return 0; } - if (!_film->dcp_length()) { + if (!_film->length()) { return 0; } + /* Compute approximate proposed length here, as it's only here that we need it */ + int length = _film->length().get(); + DCPFrameRate const dfr (_film->frames_per_second ()); + if (dfr.skip) { + length /= 2; + } + /* If we are repeating it shouldn't affect transcode time, so don't take it into account */ + /* We assume that dcp_length() is valid, if it is set */ - SourceFrame const left = _film->trim_start() + _film->dcp_length().get() - _encoder->video_frame(); + int const left = length - _encoder->video_frames_out(); return left / fps; } diff --git a/src/lib/util.cc b/src/lib/util.cc index b500ddc2f..0e250bb08 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -63,6 +63,7 @@ extern "C" { using namespace std; using namespace boost; +using libdcp::Size; thread::id ui_thread; @@ -455,16 +456,6 @@ dcp_audio_channels (int f) } -bool operator== (Size const & a, Size const & b) -{ - return (a.width == b.width && a.height == b.height); -} - -bool operator!= (Size const & a, Size const & b) -{ - return !(a == b); -} - bool operator== (Crop const & a, Crop const & b) { return (a.left == b.left && a.right == b.right && a.top == b.top && a.bottom == b.bottom); diff --git a/src/lib/util.h b/src/lib/util.h index 1fd2c0150..c4940a5d7 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -29,6 +29,7 @@ #include #include #include +#include extern "C" { #include #include @@ -99,33 +100,6 @@ enum ContentType { VIDEO ///< content is a video }; -/** @class Size - * @brief Representation of the size of something */ -struct Size -{ - /** Construct a zero Size */ - Size () - : width (0) - , height (0) - {} - - /** @param w Width. - * @param h Height. - */ - Size (int w, int h) - : width (w) - , height (h) - {} - - /** width */ - int width; - /** height */ - int height; -}; - -extern bool operator== (Size const & a, Size const & b); -extern bool operator!= (Size const & a, Size const & b); - /** @struct Crop * @brief A description of the crop of an image or video. */ @@ -195,14 +169,14 @@ struct Rect return Position (x, y); } - Size size () const { - return Size (width, height); + libdcp::Size size () const { + return libdcp::Size (width, height); } Rect intersection (Rect const & other) const; }; -extern std::string crop_string (Position, Size); +extern std::string crop_string (Position, libdcp::Size); extern int dcp_audio_sample_rate (int); extern int dcp_audio_channels (int); extern std::string colour_lut_index_to_name (int index); diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h index c0eab2140..ef1ab041a 100644 --- a/src/lib/video_decoder.h +++ b/src/lib/video_decoder.h @@ -32,7 +32,7 @@ public: /** @return video frames per second, or 0 if unknown */ virtual float frames_per_second () const = 0; /** @return native size in pixels */ - virtual Size native_size () const = 0; + virtual libdcp::Size native_size () const = 0; /** @return length (in source video frames), according to our content's header */ virtual SourceFrame length () const = 0; diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index f83518b88..bbaeb17c4 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -665,6 +665,8 @@ FilmEditor::film_changed (Film::Property p) _trim_end->SetRange (0, _film->length().get()); } break; + case Film::DCP_INTRINSIC_DURATION: + break; case Film::DCP_CONTENT_TYPE: checked_set (_dcp_content_type, DCPContentType::as_index (_film->dcp_content_type ())); _dcp_name->SetLabel (std_to_wx (_film->dcp_name ())); diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 347531cc2..e5da41d5e 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -44,6 +44,7 @@ using std::max; using std::cout; using std::list; using boost::shared_ptr; +using libdcp::Size; FilmViewer::FilmViewer (shared_ptr f, wxWindow* p) : wxPanel (p) diff --git a/src/wx/properties_dialog.cc b/src/wx/properties_dialog.cc index c34922ec4..0cf75cf51 100644 --- a/src/wx/properties_dialog.cc +++ b/src/wx/properties_dialog.cc @@ -91,9 +91,9 @@ PropertiesDialog::frames_already_encoded () const return ""; } - if (_film->dcp_length()) { + if (_film->length()) { /* XXX: encoded_frames() should check which frames have been encoded */ - u << " (" << ((_film->encoded_frames() - _film->trim_start()) * 100 / _film->dcp_length().get()) << "%)"; + u << " (" << (_film->encoded_frames() * 100 / _film->length().get()) << "%)"; } return u.str (); } diff --git a/test/metadata.ref b/test/metadata.ref index 90255e916..ff0c25118 100644 --- a/test/metadata.ref +++ b/test/metadata.ref @@ -34,6 +34,7 @@ package_type width 0 height 0 length 0 +dcp_intrinsic_duration 0 content_digest external_audio_stream external 0 0 frames_per_second 0 diff --git a/test/test.cc b/test/test.cc index 9143b87d5..7e1d92e06 100644 --- a/test/test.cc +++ b/test/test.cc @@ -325,7 +325,7 @@ do_remote_encode (shared_ptr frame, ServerDescription* descriptio BOOST_AUTO_TEST_CASE (client_server_test) { - shared_ptr image (new SimpleImage (PIX_FMT_RGB24, Size (1998, 1080), false)); + shared_ptr image (new SimpleImage (PIX_FMT_RGB24, libdcp::Size (1998, 1080), false)); uint8_t* p = image->data()[0]; for (int y = 0; y < 1080; ++y) { @@ -336,7 +336,7 @@ BOOST_AUTO_TEST_CASE (client_server_test) } } - shared_ptr sub_image (new SimpleImage (PIX_FMT_RGBA, Size (100, 200), false)); + shared_ptr sub_image (new SimpleImage (PIX_FMT_RGBA, libdcp::Size (100, 200), false)); p = sub_image->data()[0]; for (int y = 0; y < 200; ++y) { for (int x = 0; x < 100; ++x) { @@ -355,7 +355,7 @@ BOOST_AUTO_TEST_CASE (client_server_test) new DCPVideoFrame ( image, subtitle, - Size (1998, 1080), + libdcp::Size (1998, 1080), 0, 0, 1, @@ -636,7 +636,7 @@ BOOST_AUTO_TEST_CASE (job_manager_test) BOOST_AUTO_TEST_CASE (compact_image_test) { - SimpleImage* s = new SimpleImage (PIX_FMT_RGB24, Size (50, 50), false); + SimpleImage* s = new SimpleImage (PIX_FMT_RGB24, libdcp::Size (50, 50), false); BOOST_CHECK_EQUAL (s->components(), 1); BOOST_CHECK_EQUAL (s->stride()[0], 50 * 3); BOOST_CHECK_EQUAL (s->line_size()[0], 50 * 3); @@ -662,7 +662,7 @@ BOOST_AUTO_TEST_CASE (compact_image_test) BOOST_CHECK (t->stride()[0] == s->stride()[0]); /* assignment operator */ - SimpleImage* u = new SimpleImage (PIX_FMT_YUV422P, Size (150, 150), true); + SimpleImage* u = new SimpleImage (PIX_FMT_YUV422P, libdcp::Size (150, 150), true); *u = *s; BOOST_CHECK_EQUAL (u->components(), 1); BOOST_CHECK_EQUAL (u->stride()[0], 50 * 3); @@ -685,7 +685,7 @@ BOOST_AUTO_TEST_CASE (compact_image_test) BOOST_AUTO_TEST_CASE (aligned_image_test) { - SimpleImage* s = new SimpleImage (PIX_FMT_RGB24, Size (50, 50), true); + SimpleImage* s = new SimpleImage (PIX_FMT_RGB24, libdcp::Size (50, 50), true); BOOST_CHECK_EQUAL (s->components(), 1); /* 160 is 150 aligned to the nearest 32 bytes */ BOOST_CHECK_EQUAL (s->stride()[0], 160); @@ -712,7 +712,7 @@ BOOST_AUTO_TEST_CASE (aligned_image_test) BOOST_CHECK (t->stride()[0] == s->stride()[0]); /* assignment operator */ - SimpleImage* u = new SimpleImage (PIX_FMT_YUV422P, Size (150, 150), false); + SimpleImage* u = new SimpleImage (PIX_FMT_YUV422P, libdcp::Size (150, 150), false); *u = *s; BOOST_CHECK_EQUAL (u->components(), 1); BOOST_CHECK_EQUAL (u->stride()[0], 160); -- cgit v1.2.3 From d42989d447bc9199b670d8e99fbb8b93f06ddb71 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 17 Jan 2013 21:34:24 +0000 Subject: Missed offset for multi-reel. --- src/lib/make_dcp_job.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/make_dcp_job.cc b/src/lib/make_dcp_job.cc index 6877e5e88..fb24fedb3 100644 --- a/src/lib/make_dcp_job.cc +++ b/src/lib/make_dcp_job.cc @@ -61,7 +61,7 @@ MakeDCPJob::name () const string MakeDCPJob::j2c_path (int f, int offset) const { - return _film->frame_out_path (f, false); + return _film->frame_out_path (f + offset, false); } string -- cgit v1.2.3 From cadd50fe2609a1ad9963389d65d8e91f85226752 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 17 Jan 2013 23:42:59 +0000 Subject: Sort of works to a first-order approximation. --- src/lib/dcp_video_frame.cc | 15 +++++ src/lib/dcp_video_frame.h | 2 + src/lib/encoder.cc | 148 ++++++++++++++++++++++++++++++++++----------- src/lib/encoder.h | 25 +++++--- 4 files changed, 146 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/lib/dcp_video_frame.cc b/src/lib/dcp_video_frame.cc index 1c408270e..da864ad9f 100644 --- a/src/lib/dcp_video_frame.cc +++ b/src/lib/dcp_video_frame.cc @@ -380,6 +380,21 @@ EncodedData::EncodedData (int s) } +EncodedData::EncodedData (string file) +{ + _size = boost::filesystem::file_size (file); + _data = new uint8_t[_size]; + + FILE* f = fopen (file.c_str(), "rb"); + if (!f) { + throw FileError ("could not open file for reading", file); + } + + fread (_data, 1, _size, f); + fclose (f); +} + + EncodedData::~EncodedData () { delete[] _data; diff --git a/src/lib/dcp_video_frame.h b/src/lib/dcp_video_frame.h index e311724d8..b446352c7 100644 --- a/src/lib/dcp_video_frame.h +++ b/src/lib/dcp_video_frame.h @@ -43,6 +43,8 @@ public: */ EncodedData (int s); + EncodedData (std::string f); + virtual ~EncodedData (); void send (boost::shared_ptr socket); diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 0f48310ef..c6960d0d1 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -24,6 +24,7 @@ #include #include #include +#include #include "encoder.h" #include "util.h" #include "options.h" @@ -47,6 +48,7 @@ using std::make_pair; using namespace boost; int const Encoder::_history_size = 25; +unsigned int const Encoder::_maximum_frames_in_memory = 8; /** @param f Film that we are encoding. * @param o Options. @@ -60,10 +62,12 @@ Encoder::Encoder (shared_ptr f) , _audio_frames_out (0) #ifdef HAVE_SWRESAMPLE , _swr_context (0) -#endif +#endif + , _have_a_real_frame (false) , _terminate_encoder (false) , _writer_thread (0) - , _terminate_writer (false) + , _finish_writer (false) + , _last_written_frame (-1) { if (_film->audio_stream()) { /* Create sound output files with .tmp suffixes; we will rename @@ -88,7 +92,7 @@ Encoder::~Encoder () { close_sound_files (); terminate_worker_threads (); - terminate_writer_thread (); + finish_writer_thread (); } void @@ -135,6 +139,17 @@ Encoder::process_begin () } } + /* XXX! */ + _picture_asset.reset ( + new libdcp::MonoPictureAsset ( + _film->dir (_film->dcp_name()), + String::compose ("video_%1.mxf", 0), + DCPFrameRate (_film->frames_per_second()).frames_per_second, + _film->format()->dcp_size() + ) + ); + + _picture_asset_writer = _picture_asset->start_write (); _writer_thread = new boost::thread (boost::bind (&Encoder::writer_thread, this)); } @@ -192,7 +207,6 @@ Encoder::process_end () lock.unlock (); terminate_worker_threads (); - terminate_writer_thread (); _film->log()->log ("Mopping up " + lexical_cast (_encode_queue.size())); @@ -209,23 +223,19 @@ Encoder::process_end () _film->log()->log (String::compose ("Encode left-over frame %1", (*i)->frame ())); try { shared_ptr e = (*i)->encode_locally (); - e->write (_film, (*i)->frame ()); + { + boost::mutex::scoped_lock lock2 (_writer_mutex); + _write_queue.push_back (make_pair (e, (*i)->frame ())); + _writer_condition.notify_all (); + } frame_done (); } catch (std::exception& e) { _film->log()->log (String::compose ("Local encode failed (%1)", e.what ())); } } - /* Mop up any unwritten things in the writer's queue */ - for (list, int> >::iterator i = _write_queue.begin(); i != _write_queue.end(); ++i) { - i->first->write (_opt, i->second); - } - - /* Now do links (or copies on windows) to duplicate frames */ - for (list >::iterator i = _links_required.begin(); i != _links_required.end(); ++i) { - link (_film->frame_out_path (i->first, false), _film->frame_out_path (i->second, false)); - link (_film->hash_out_path (i->first, false), _film->hash_out_path (i->second, false)); - } + finish_writer_thread (); + _picture_asset_writer->finalize (); } /** @return an estimate of the current number of frames we are encoding per second, @@ -317,12 +327,13 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptr (), _video_frames_out)); } else { /* Queue this new frame for encoding */ pair const s = Filter::ffmpeg_strings (_film->filters()); @@ -338,14 +349,15 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptr (), _video_frames_out)); ++_video_frames_out; } } @@ -434,14 +446,14 @@ Encoder::terminate_worker_threads () } void -Encoder::terminate_writer_thread () +Encoder::finish_writer_thread () { if (!_writer_thread) { return; } boost::mutex::scoped_lock lock (_writer_mutex); - _terminate_writer = true; + _finish_writer = true; _writer_condition.notify_all (); lock.unlock (); @@ -550,27 +562,95 @@ Encoder::link (string a, string b) const #endif } +struct WriteQueueSorter +{ + bool operator() (pair, int> const & a, pair, int> const & b) { + return a.second < b.second; + } +}; + void Encoder::writer_thread () { while (1) { boost::mutex::scoped_lock lock (_writer_mutex); - TIMING ("writer sleeps with a queue of %1", _write_queue.size()); - while (_write_queue.empty() && !_terminate_writer) { - _writer_condition.wait (lock); + + while (1) { + if (_finish_writer || + _write_queue.size() > _maximum_frames_in_memory || + (!_write_queue.empty() && _write_queue.front().second == (_last_written_frame + 1))) { + + break; + } + + TIMING ("writer sleeps with a queue of %1; %2 pending", _write_queue.size(), _pending.size()); + _writer_condition.wait (lock); + TIMING ("writer wakes with a queue of %1", _write_queue.size()); + + _write_queue.sort (WriteQueueSorter ()); } - TIMING ("writer wakes with a queue of %1", _write_queue.size()); - if (_terminate_writer) { + if (_finish_writer && _write_queue.empty() && _pending.empty()) { return; } - pair, int> encoded = _write_queue.front (); - _write_queue.pop_front (); + /* Write any frames that we can write; i.e. those that are in sequence */ + while (!_write_queue.empty() && _write_queue.front().second == (_last_written_frame + 1)) { + pair, int> encoded = _write_queue.front (); + _write_queue.pop_front (); - lock.unlock (); - encoded.first->write (_opt, encoded.second); - lock.lock (); + lock.unlock (); + /* XXX: write to mxf */ + _film->log()->log (String::compose ("Writer writes %1 to MXF", encoded.second)); + if (encoded.first) { + _picture_asset_writer->write (encoded.first->data(), encoded.first->size()); + _last_written = encoded.first; + } else { + _picture_asset_writer->write (_last_written->data(), _last_written->size()); + } + lock.lock (); + + ++_last_written_frame; + } + + while (_write_queue.size() > _maximum_frames_in_memory) { + /* Too many frames in memory which can't yet be written to the stream. + Put some to disk. + */ + + pair, int> encoded = _write_queue.front (); + _write_queue.pop_back (); + if (!encoded.first) { + /* This is a `repeat-last' frame, so no need to write it to disk */ + continue; + } + + lock.unlock (); + _film->log()->log (String::compose ("Writer full; pushes %1 to disk", encoded.second)); + encoded.first->write (_film, encoded.second); + lock.lock (); + + _pending.push_back (encoded.second); + } + + while (_write_queue.size() < _maximum_frames_in_memory && !_pending.empty()) { + /* We have some space in memory. Fetch some frames back off disk. */ + + _pending.sort (); + int const fetch = _pending.front (); + + lock.unlock (); + _film->log()->log (String::compose ("Writer pulls %1 back from disk", fetch)); + shared_ptr encoded; + if (boost::filesystem::exists (_film->frame_out_path (fetch, false))) { + /* It's an actual frame (not a repeat-last); load it in */ + encoded.reset (new EncodedData (_film->frame_out_path (fetch, false))); + } + lock.lock (); + + _write_queue.push_back (make_pair (encoded, fetch)); + _pending.remove (fetch); + } } } diff --git a/src/lib/encoder.h b/src/lib/encoder.h index 96e7a1d25..3e2b5d957 100644 --- a/src/lib/encoder.h +++ b/src/lib/encoder.h @@ -52,6 +52,11 @@ class ServerDescription; class DCPVideoFrame; class EncodedData; +namespace libdcp { + class MonoPictureAsset; + class MonoPictureAssetWriter; +} + /** @class Encoder * @brief Encoder to J2K and WAV for DCP. * @@ -121,22 +126,15 @@ private: int64_t _audio_frames_out; void writer_thread (); - void terminate_writer_thread (); + void finish_writer_thread (); #if HAVE_SWRESAMPLE SwrContext* _swr_context; #endif - /** List of links that we need to create when all frames have been processed; - * such that we need to call link (first, second) for each member of this list. - * In other words, `first' is a `real' frame and `second' should be a link to `first'. - * Frames are DCP frames. - */ - std::list > _links_required; - std::vector _sound_files; - boost::optional _last_real_frame; + bool _have_a_real_frame; bool _terminate_encoder; std::list > _encode_queue; std::list _worker_threads; @@ -144,10 +142,17 @@ private: boost::condition _worker_condition; boost::thread* _writer_thread; - bool _terminate_writer; + bool _finish_writer; std::list, int> > _write_queue; mutable boost::mutex _writer_mutex; boost::condition _writer_condition; + boost::shared_ptr _last_written; + std::list _pending; + int _last_written_frame; + static const unsigned int _maximum_frames_in_memory; + + boost::shared_ptr _picture_asset; + boost::shared_ptr _picture_asset_writer; }; #endif -- cgit v1.2.3 From a93bbd88eaa67a1e24471789335a2790b6cfbc78 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 17 Jan 2013 23:56:49 +0000 Subject: Some fixes and logs. --- src/lib/encoder.cc | 5 ++--- src/lib/log.cc | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index c6960d0d1..0d5fc1c6e 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -601,7 +601,6 @@ Encoder::writer_thread () _write_queue.pop_front (); lock.unlock (); - /* XXX: write to mxf */ _film->log()->log (String::compose ("Writer writes %1 to MXF", encoded.second)); if (encoded.first) { _picture_asset_writer->write (encoded.first->data(), encoded.first->size()); @@ -619,7 +618,7 @@ Encoder::writer_thread () Put some to disk. */ - pair, int> encoded = _write_queue.front (); + pair, int> encoded = _write_queue.back (); _write_queue.pop_back (); if (!encoded.first) { /* This is a `repeat-last' frame, so no need to write it to disk */ @@ -627,7 +626,7 @@ Encoder::writer_thread () } lock.unlock (); - _film->log()->log (String::compose ("Writer full; pushes %1 to disk", encoded.second)); + _film->log()->log (String::compose ("Writer full (awaiting %1); pushes %2 to disk", _last_written_frame + 1, encoded.second)); encoded.first->write (_film, encoded.second); lock.lock (); diff --git a/src/lib/log.cc b/src/lib/log.cc index 06cff0495..7459700ea 100644 --- a/src/lib/log.cc +++ b/src/lib/log.cc @@ -28,7 +28,7 @@ using namespace std; Log::Log () - : _level (VERBOSE) + : _level (STANDARD) { } -- cgit v1.2.3 From d4024b9f794823a2808724ae9fae74195f1a0824 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 18 Jan 2013 00:19:21 +0000 Subject: Some missing frame_done()s. --- src/lib/encoder.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 0d5fc1c6e..b37a3c098 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -334,6 +334,7 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptr (), _video_frames_out)); + frame_done (); } else { /* Queue this new frame for encoding */ pair const s = Filter::ffmpeg_strings (_film->filters()); @@ -359,6 +360,7 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptr (), _video_frames_out)); ++_video_frames_out; + frame_done (); } } @@ -529,6 +531,7 @@ Encoder::encoder_thread (ServerDescription* server) boost::mutex::scoped_lock lock2 (_writer_mutex); _write_queue.push_back (make_pair (encoded, vf->frame ())); _writer_condition.notify_all (); + frame_done (); } else { lock.lock (); _film->log()->log ( -- cgit v1.2.3 From 479b67ec506289a4763b2dd4f07e72d1dd676483 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 18 Jan 2013 00:40:49 +0000 Subject: Add writer class to pull some stuff out of Encoder. --- NOTES | 6 ++ src/lib/encoder.cc | 172 ++++---------------------------------------------- src/lib/encoder.h | 23 +------ src/lib/writer.cc | 180 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/writer.h | 60 ++++++++++++++++++ src/lib/wscript | 1 + 6 files changed, 261 insertions(+), 181 deletions(-) create mode 100644 NOTES create mode 100644 src/lib/writer.cc create mode 100644 src/lib/writer.h (limited to 'src') diff --git a/NOTES b/NOTES new file mode 100644 index 000000000..5be074c90 --- /dev/null +++ b/NOTES @@ -0,0 +1,6 @@ + +Encoder to write audio mxf; and sort out creation of those mxfs +DCP job still to write XML; presumably. +Write hashes of frames after successful write. +Make check of hashes optional + diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index b37a3c098..bad420f35 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -37,6 +37,7 @@ #include "server.h" #include "format.h" #include "cross.h" +#include "writer.h" using std::pair; using std::string; @@ -48,7 +49,6 @@ using std::make_pair; using namespace boost; int const Encoder::_history_size = 25; -unsigned int const Encoder::_maximum_frames_in_memory = 8; /** @param f Film that we are encoding. * @param o Options. @@ -65,9 +65,6 @@ Encoder::Encoder (shared_ptr f) #endif , _have_a_real_frame (false) , _terminate_encoder (false) - , _writer_thread (0) - , _finish_writer (false) - , _last_written_frame (-1) { if (_film->audio_stream()) { /* Create sound output files with .tmp suffixes; we will rename @@ -92,7 +89,9 @@ Encoder::~Encoder () { close_sound_files (); terminate_worker_threads (); - finish_writer_thread (); + if (_writer) { + _writer->finish (); + } } void @@ -139,18 +138,7 @@ Encoder::process_begin () } } - /* XXX! */ - _picture_asset.reset ( - new libdcp::MonoPictureAsset ( - _film->dir (_film->dcp_name()), - String::compose ("video_%1.mxf", 0), - DCPFrameRate (_film->frames_per_second()).frames_per_second, - _film->format()->dcp_size() - ) - ); - - _picture_asset_writer = _picture_asset->start_write (); - _writer_thread = new boost::thread (boost::bind (&Encoder::writer_thread, this)); + _writer.reset (new Writer (_film)); } @@ -222,20 +210,15 @@ Encoder::process_end () for (list >::iterator i = _encode_queue.begin(); i != _encode_queue.end(); ++i) { _film->log()->log (String::compose ("Encode left-over frame %1", (*i)->frame ())); try { - shared_ptr e = (*i)->encode_locally (); - { - boost::mutex::scoped_lock lock2 (_writer_mutex); - _write_queue.push_back (make_pair (e, (*i)->frame ())); - _writer_condition.notify_all (); - } + _writer->write ((*i)->encode_locally(), (*i)->frame ()); frame_done (); } catch (std::exception& e) { _film->log()->log (String::compose ("Local encode failed (%1)", e.what ())); } } - finish_writer_thread (); - _picture_asset_writer->finalize (); + _writer->finish (); + _writer.reset (); } /** @return an estimate of the current number of frames we are encoding per second, @@ -328,12 +311,8 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptr (), _video_frames_out)); + /* Use the last frame that we encoded. */ + _writer->repeat (_video_frames_out); frame_done (); } else { /* Queue this new frame for encoding */ @@ -357,8 +336,7 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptr (), _video_frames_out)); + _writer->repeat (_video_frames_out); ++_video_frames_out; frame_done (); } @@ -447,23 +425,6 @@ Encoder::terminate_worker_threads () } } -void -Encoder::finish_writer_thread () -{ - if (!_writer_thread) { - return; - } - - boost::mutex::scoped_lock lock (_writer_mutex); - _finish_writer = true; - _writer_condition.notify_all (); - lock.unlock (); - - _writer_thread->join (); - delete _writer_thread; - _writer_thread = 0; -} - void Encoder::encoder_thread (ServerDescription* server) { @@ -528,9 +489,7 @@ Encoder::encoder_thread (ServerDescription* server) } if (encoded) { - boost::mutex::scoped_lock lock2 (_writer_mutex); - _write_queue.push_back (make_pair (encoded, vf->frame ())); - _writer_condition.notify_all (); + _writer->write (encoded, vf->frame ()); frame_done (); } else { lock.lock (); @@ -549,110 +508,3 @@ Encoder::encoder_thread (ServerDescription* server) _worker_condition.notify_all (); } } - -void -Encoder::link (string a, string b) const -{ -#ifdef DVDOMATIC_POSIX - int const r = symlink (a.c_str(), b.c_str()); - if (r) { - throw EncodeError (String::compose ("could not create symlink from %1 to %2", a, b)); - } -#endif - -#ifdef DVDOMATIC_WINDOWS - boost::filesystem::copy_file (a, b); -#endif -} - -struct WriteQueueSorter -{ - bool operator() (pair, int> const & a, pair, int> const & b) { - return a.second < b.second; - } -}; - -void -Encoder::writer_thread () -{ - while (1) - { - boost::mutex::scoped_lock lock (_writer_mutex); - - while (1) { - if (_finish_writer || - _write_queue.size() > _maximum_frames_in_memory || - (!_write_queue.empty() && _write_queue.front().second == (_last_written_frame + 1))) { - - break; - } - - TIMING ("writer sleeps with a queue of %1; %2 pending", _write_queue.size(), _pending.size()); - _writer_condition.wait (lock); - TIMING ("writer wakes with a queue of %1", _write_queue.size()); - - _write_queue.sort (WriteQueueSorter ()); - } - - if (_finish_writer && _write_queue.empty() && _pending.empty()) { - return; - } - - /* Write any frames that we can write; i.e. those that are in sequence */ - while (!_write_queue.empty() && _write_queue.front().second == (_last_written_frame + 1)) { - pair, int> encoded = _write_queue.front (); - _write_queue.pop_front (); - - lock.unlock (); - _film->log()->log (String::compose ("Writer writes %1 to MXF", encoded.second)); - if (encoded.first) { - _picture_asset_writer->write (encoded.first->data(), encoded.first->size()); - _last_written = encoded.first; - } else { - _picture_asset_writer->write (_last_written->data(), _last_written->size()); - } - lock.lock (); - - ++_last_written_frame; - } - - while (_write_queue.size() > _maximum_frames_in_memory) { - /* Too many frames in memory which can't yet be written to the stream. - Put some to disk. - */ - - pair, int> encoded = _write_queue.back (); - _write_queue.pop_back (); - if (!encoded.first) { - /* This is a `repeat-last' frame, so no need to write it to disk */ - continue; - } - - lock.unlock (); - _film->log()->log (String::compose ("Writer full (awaiting %1); pushes %2 to disk", _last_written_frame + 1, encoded.second)); - encoded.first->write (_film, encoded.second); - lock.lock (); - - _pending.push_back (encoded.second); - } - - while (_write_queue.size() < _maximum_frames_in_memory && !_pending.empty()) { - /* We have some space in memory. Fetch some frames back off disk. */ - - _pending.sort (); - int const fetch = _pending.front (); - - lock.unlock (); - _film->log()->log (String::compose ("Writer pulls %1 back from disk", fetch)); - shared_ptr encoded; - if (boost::filesystem::exists (_film->frame_out_path (fetch, false))) { - /* It's an actual frame (not a repeat-last); load it in */ - encoded.reset (new EncodedData (_film->frame_out_path (fetch, false))); - } - lock.lock (); - - _write_queue.push_back (make_pair (encoded, fetch)); - _pending.remove (fetch); - } - } -} diff --git a/src/lib/encoder.h b/src/lib/encoder.h index 3e2b5d957..a277aca51 100644 --- a/src/lib/encoder.h +++ b/src/lib/encoder.h @@ -51,11 +51,7 @@ class Film; class ServerDescription; class DCPVideoFrame; class EncodedData; - -namespace libdcp { - class MonoPictureAsset; - class MonoPictureAssetWriter; -} +class Writer; /** @class Encoder * @brief Encoder to J2K and WAV for DCP. @@ -100,7 +96,6 @@ private: void encoder_thread (ServerDescription *); void terminate_worker_threads (); - void link (std::string, std::string) const; /** Film that we are encoding */ boost::shared_ptr _film; @@ -125,9 +120,6 @@ private: /** Number of audio frames written for the DCP so far */ int64_t _audio_frames_out; - void writer_thread (); - void finish_writer_thread (); - #if HAVE_SWRESAMPLE SwrContext* _swr_context; #endif @@ -141,18 +133,7 @@ private: mutable boost::mutex _worker_mutex; boost::condition _worker_condition; - boost::thread* _writer_thread; - bool _finish_writer; - std::list, int> > _write_queue; - mutable boost::mutex _writer_mutex; - boost::condition _writer_condition; - boost::shared_ptr _last_written; - std::list _pending; - int _last_written_frame; - static const unsigned int _maximum_frames_in_memory; - - boost::shared_ptr _picture_asset; - boost::shared_ptr _picture_asset_writer; + boost::shared_ptr _writer; }; #endif diff --git a/src/lib/writer.cc b/src/lib/writer.cc new file mode 100644 index 000000000..0381ee378 --- /dev/null +++ b/src/lib/writer.cc @@ -0,0 +1,180 @@ +/* + Copyright (C) 2012 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include "writer.h" +#include "compose.hpp" +#include "film.h" +#include "format.h" +#include "log.h" +#include "dcp_video_frame.h" + +using std::make_pair; +using std::pair; +using boost::shared_ptr; + +unsigned int const Writer::_maximum_frames_in_memory = 8; + +Writer::Writer (shared_ptr f) + : _film (f) + , _thread (0) + , _finish (false) + , _last_written_frame (-1) +{ + _picture_asset.reset ( + new libdcp::MonoPictureAsset ( + _film->dir (_film->dcp_name()), + String::compose ("video_%1.mxf", 0), + DCPFrameRate (_film->frames_per_second()).frames_per_second, + _film->format()->dcp_size() + ) + ); + + _picture_asset_writer = _picture_asset->start_write (); + + _thread = new boost::thread (boost::bind (&Writer::thread, this)); +} + +void +Writer::write (shared_ptr encoded, int frame) +{ + boost::mutex::scoped_lock lock (_mutex); + _queue.push_back (make_pair (encoded, frame)); + _condition.notify_all (); +} + +struct QueueSorter +{ + bool operator() (pair, int> const & a, pair, int> const & b) { + return a.second < b.second; + } +}; + +void +Writer::thread () +{ + while (1) + { + boost::mutex::scoped_lock lock (_mutex); + + while (1) { + if (_finish || + _queue.size() > _maximum_frames_in_memory || + (!_queue.empty() && _queue.front().second == (_last_written_frame + 1))) { + + break; + } + + TIMING ("writer sleeps with a queue of %1; %2 pending", _queue.size(), _pending.size()); + _condition.wait (lock); + TIMING ("writer wakes with a queue of %1", _queue.size()); + + _queue.sort (QueueSorter ()); + } + + if (_finish && _queue.empty() && _pending.empty()) { + return; + } + + /* Write any frames that we can write; i.e. those that are in sequence */ + while (!_queue.empty() && _queue.front().second == (_last_written_frame + 1)) { + pair, int> encoded = _queue.front (); + _queue.pop_front (); + + lock.unlock (); + _film->log()->log (String::compose ("Writer writes %1 to MXF", encoded.second)); + if (encoded.first) { + _picture_asset_writer->write (encoded.first->data(), encoded.first->size()); + _last_written = encoded.first; + } else { + _picture_asset_writer->write (_last_written->data(), _last_written->size()); + } + lock.lock (); + + ++_last_written_frame; + } + + while (_queue.size() > _maximum_frames_in_memory) { + /* Too many frames in memory which can't yet be written to the stream. + Put some to disk. + */ + + pair, int> encoded = _queue.back (); + _queue.pop_back (); + if (!encoded.first) { + /* This is a `repeat-last' frame, so no need to write it to disk */ + continue; + } + + lock.unlock (); + _film->log()->log (String::compose ("Writer full (awaiting %1); pushes %2 to disk", _last_written_frame + 1, encoded.second)); + encoded.first->write (_film, encoded.second); + lock.lock (); + + _pending.push_back (encoded.second); + } + + while (_queue.size() < _maximum_frames_in_memory && !_pending.empty()) { + /* We have some space in memory. Fetch some frames back off disk. */ + + _pending.sort (); + int const fetch = _pending.front (); + + lock.unlock (); + _film->log()->log (String::compose ("Writer pulls %1 back from disk", fetch)); + shared_ptr encoded; + if (boost::filesystem::exists (_film->frame_out_path (fetch, false))) { + /* It's an actual frame (not a repeat-last); load it in */ + encoded.reset (new EncodedData (_film->frame_out_path (fetch, false))); + } + lock.lock (); + + _queue.push_back (make_pair (encoded, fetch)); + _pending.remove (fetch); + } + } + +} + +void +Writer::finish () +{ + if (!_thread) { + return; + } + + boost::mutex::scoped_lock lock (_mutex); + _finish = true; + _condition.notify_all (); + lock.unlock (); + + _thread->join (); + delete _thread; + _thread = 0; + + _picture_asset_writer->finalize (); +} + +/** Tell the writer that frame `f' should be a repeat of the frame before it */ +void +Writer::repeat (int f) +{ + boost::mutex::scoped_lock lock (_mutex); + _queue.push_back (make_pair (shared_ptr (), f)); +} diff --git a/src/lib/writer.h b/src/lib/writer.h new file mode 100644 index 000000000..8156308a6 --- /dev/null +++ b/src/lib/writer.h @@ -0,0 +1,60 @@ +/* + Copyright (C) 2012 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include +#include +#include + +class Film; +class EncodedData; + +namespace libdcp { + class MonoPictureAsset; + class MonoPictureAssetWriter; +} + +class Writer +{ +public: + Writer (boost::shared_ptr); + + void write (boost::shared_ptr, int); + void repeat (int f); + void finish (); + +private: + + void thread (); + + boost::shared_ptr _film; + + boost::thread* _thread; + bool _finish; + std::list, int> > _queue; + mutable boost::mutex _mutex; + boost::condition _condition; + boost::shared_ptr _last_written; + std::list _pending; + int _last_written_frame; + static const unsigned int _maximum_frames_in_memory; + + boost::shared_ptr _picture_asset; + boost::shared_ptr _picture_asset_writer; +}; diff --git a/src/lib/wscript b/src/lib/wscript index b2b639f06..6d72f6480 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -56,6 +56,7 @@ def build(bld): version.cc video_decoder.cc video_source.cc + writer.cc """ obj.target = 'dvdomatic' -- cgit v1.2.3 From 5e4ab7ebd9a6b62b64fbaf91d7aa1a2a9d4bdec4 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 18 Jan 2013 21:49:49 +0000 Subject: Untested direct write of audio to MXF. --- NOTES | 2 +- src/lib/dcp_video_frame.cc | 2 +- src/lib/dcp_video_frame.h | 2 +- src/lib/encoder.cc | 59 +++------------------------------------------- src/lib/encoder.h | 8 ------- src/lib/writer.cc | 35 ++++++++++++++++++++++----- src/lib/writer.h | 12 +++++++--- 7 files changed, 44 insertions(+), 76 deletions(-) (limited to 'src') diff --git a/NOTES b/NOTES index a771e9bfd..b384cb6c0 100644 --- a/NOTES +++ b/NOTES @@ -4,4 +4,4 @@ Get rid of DCP job entirely and make encoder write XML (since it has the *Asset ... perhaps generate the CPL hash on the fly Write hashes of frames after successful write. Make check of hashes optional; recovery in general - +Fix multi-reel or remove it \ No newline at end of file diff --git a/src/lib/dcp_video_frame.cc b/src/lib/dcp_video_frame.cc index da864ad9f..89db5761a 100644 --- a/src/lib/dcp_video_frame.cc +++ b/src/lib/dcp_video_frame.cc @@ -405,7 +405,7 @@ EncodedData::~EncodedData () * @param frame DCP Frame index. */ void -EncodedData::write (shared_ptr film, int frame) +EncodedData::write (shared_ptr film, int frame) const { string const tmp_j2k = film->frame_out_path (frame, true); diff --git a/src/lib/dcp_video_frame.h b/src/lib/dcp_video_frame.h index b446352c7..2ad2b0d44 100644 --- a/src/lib/dcp_video_frame.h +++ b/src/lib/dcp_video_frame.h @@ -48,7 +48,7 @@ public: virtual ~EncodedData (); void send (boost::shared_ptr socket); - void write (boost::shared_ptr, int); + void write (boost::shared_ptr, int) const; /** @return data */ uint8_t* data () const { diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index bad420f35..c2416b87e 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -57,37 +57,18 @@ Encoder::Encoder (shared_ptr f) : _film (f) , _just_skipped (false) , _video_frames_in (0) - , _audio_frames_in (0) , _video_frames_out (0) - , _audio_frames_out (0) #ifdef HAVE_SWRESAMPLE , _swr_context (0) #endif , _have_a_real_frame (false) , _terminate_encoder (false) { - if (_film->audio_stream()) { - /* Create sound output files with .tmp suffixes; we will rename - them if and when we complete. - */ - for (int i = 0; i < dcp_audio_channels (_film->audio_channels()); ++i) { - SF_INFO sf_info; - sf_info.samplerate = dcp_audio_sample_rate (_film->audio_stream()->sample_rate()); - /* We write mono files */ - sf_info.channels = 1; - sf_info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_24; - SNDFILE* f = sf_open (_film->multichannel_audio_out_path (i, true).c_str (), SFM_WRITE, &sf_info); - if (f == 0) { - throw CreateFileError (_film->multichannel_audio_out_path (i, true)); - } - _sound_files.push_back (f); - } - } + } Encoder::~Encoder () { - close_sound_files (); terminate_worker_threads (); if (_writer) { _writer->finish (); @@ -162,25 +143,13 @@ Encoder::process_end () } out->set_frames (frames); - write_audio (out); + _writer->write (out); } swr_free (&_swr_context); } #endif - if (_film->audio_stream()) { - close_sound_files (); - - /* Rename .wav.tmp files to .wav */ - for (int i = 0; i < dcp_audio_channels (_film->audio_channels()); ++i) { - if (boost::filesystem::exists (_film->multichannel_audio_out_path (i, false))) { - boost::filesystem::remove (_film->multichannel_audio_out_path (i, false)); - } - boost::filesystem::rename (_film->multichannel_audio_out_path (i, true), _film->multichannel_audio_out_path (i, false)); - } - } - boost::mutex::scoped_lock lock (_worker_mutex); _film->log()->log ("Clearing queue of " + lexical_cast (_encode_queue.size ())); @@ -386,31 +355,9 @@ Encoder::process_audio (shared_ptr data) data = b; } - write_audio (data); - - _audio_frames_in += data->frames (); + _writer->write (data); } -void -Encoder::write_audio (shared_ptr audio) -{ - for (int i = 0; i < audio->channels(); ++i) { - sf_write_float (_sound_files[i], audio->data(i), audio->frames()); - } - - _audio_frames_out += audio->frames (); -} - -void -Encoder::close_sound_files () -{ - for (vector::iterator i = _sound_files.begin(); i != _sound_files.end(); ++i) { - sf_close (*i); - } - - _sound_files.clear (); -} - void Encoder::terminate_worker_threads () { diff --git a/src/lib/encoder.h b/src/lib/encoder.h index a277aca51..fc89d674a 100644 --- a/src/lib/encoder.h +++ b/src/lib/encoder.h @@ -39,7 +39,6 @@ extern "C" { #include } #endif -#include #include "util.h" #include "video_sink.h" #include "audio_sink.h" @@ -91,7 +90,6 @@ private: void frame_done (); void frame_skipped (); - void close_sound_files (); void write_audio (boost::shared_ptr audio); void encoder_thread (ServerDescription *); @@ -113,19 +111,13 @@ private: /** Number of video frames received so far */ SourceFrame _video_frames_in; - /** Number of audio frames received so far */ - int64_t _audio_frames_in; /** Number of video frames written for the DCP so far */ int _video_frames_out; - /** Number of audio frames written for the DCP so far */ - int64_t _audio_frames_out; #if HAVE_SWRESAMPLE SwrContext* _swr_context; #endif - std::vector _sound_files; - bool _have_a_real_frame; bool _terminate_encoder; std::list > _encode_queue; diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 0381ee378..fbd371550 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -18,6 +18,7 @@ */ #include +#include #include "writer.h" #include "compose.hpp" #include "film.h" @@ -48,20 +49,41 @@ Writer::Writer (shared_ptr f) _picture_asset_writer = _picture_asset->start_write (); + if (_film->audio_channels() > 0) { + _sound_asset.reset ( + new libdcp::SoundAsset ( + _film->dir (_film->dcp_name()), + String::compose ("audio_%1.mxf", 0), + DCPFrameRate (_film->frames_per_second()).frames_per_second, + _film->audio_channels(), + _film->audio_stream()->sample_rate() + ) + ); + + _sound_asset_writer = _sound_asset->start_write (); + } + _thread = new boost::thread (boost::bind (&Writer::thread, this)); } void -Writer::write (shared_ptr encoded, int frame) +Writer::write (shared_ptr encoded, int frame) { boost::mutex::scoped_lock lock (_mutex); _queue.push_back (make_pair (encoded, frame)); _condition.notify_all (); } +/** This method is not thread safe */ +void +Writer::write (shared_ptr audio) +{ + _sound_asset_writer->write (audio->data(), audio->frames()); +} + struct QueueSorter { - bool operator() (pair, int> const & a, pair, int> const & b) { + bool operator() (pair, int> const & a, pair, int> const & b) { return a.second < b.second; } }; @@ -94,7 +116,7 @@ Writer::thread () /* Write any frames that we can write; i.e. those that are in sequence */ while (!_queue.empty() && _queue.front().second == (_last_written_frame + 1)) { - pair, int> encoded = _queue.front (); + pair, int> encoded = _queue.front (); _queue.pop_front (); lock.unlock (); @@ -115,7 +137,7 @@ Writer::thread () Put some to disk. */ - pair, int> encoded = _queue.back (); + pair, int> encoded = _queue.back (); _queue.pop_back (); if (!encoded.first) { /* This is a `repeat-last' frame, so no need to write it to disk */ @@ -138,7 +160,7 @@ Writer::thread () lock.unlock (); _film->log()->log (String::compose ("Writer pulls %1 back from disk", fetch)); - shared_ptr encoded; + shared_ptr encoded; if (boost::filesystem::exists (_film->frame_out_path (fetch, false))) { /* It's an actual frame (not a repeat-last); load it in */ encoded.reset (new EncodedData (_film->frame_out_path (fetch, false))); @@ -169,6 +191,7 @@ Writer::finish () _thread = 0; _picture_asset_writer->finalize (); + _sound_asset_writer->finalize (); } /** Tell the writer that frame `f' should be a repeat of the frame before it */ @@ -176,5 +199,5 @@ void Writer::repeat (int f) { boost::mutex::scoped_lock lock (_mutex); - _queue.push_back (make_pair (shared_ptr (), f)); + _queue.push_back (make_pair (shared_ptr (), f)); } diff --git a/src/lib/writer.h b/src/lib/writer.h index 8156308a6..77f98f160 100644 --- a/src/lib/writer.h +++ b/src/lib/writer.h @@ -24,10 +24,13 @@ class Film; class EncodedData; +class AudioBuffers; namespace libdcp { class MonoPictureAsset; class MonoPictureAssetWriter; + class SoundAsset; + class SoundAssetWriter; } class Writer @@ -35,7 +38,8 @@ class Writer public: Writer (boost::shared_ptr); - void write (boost::shared_ptr, int); + void write (boost::shared_ptr, int); + void write (boost::shared_ptr); void repeat (int f); void finish (); @@ -47,14 +51,16 @@ private: boost::thread* _thread; bool _finish; - std::list, int> > _queue; + std::list, int> > _queue; mutable boost::mutex _mutex; boost::condition _condition; - boost::shared_ptr _last_written; + boost::shared_ptr _last_written; std::list _pending; int _last_written_frame; static const unsigned int _maximum_frames_in_memory; boost::shared_ptr _picture_asset; boost::shared_ptr _picture_asset_writer; + boost::shared_ptr _sound_asset; + boost::shared_ptr _sound_asset_writer; }; -- cgit v1.2.3 From 51325470f2d8d2f9abdbe4170c146c90383dbfb4 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 18 Jan 2013 21:56:12 +0000 Subject: Remove make dcp job. --- src/lib/film.cc | 4 +- src/lib/make_dcp_job.cc | 182 ------------------------------------------------ src/lib/make_dcp_job.h | 42 ----------- src/lib/writer.cc | 28 ++++++++ src/lib/wscript | 1 - src/tools/makedcp.cc | 1 - 6 files changed, 29 insertions(+), 229 deletions(-) delete mode 100644 src/lib/make_dcp_job.cc delete mode 100644 src/lib/make_dcp_job.h (limited to 'src') diff --git a/src/lib/film.cc b/src/lib/film.cc index 1741d49e6..c91a80471 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -39,7 +39,6 @@ #include "ab_transcode_job.h" #include "transcode_job.h" #include "scp_dcp_job.h" -#include "make_dcp_job.h" #include "log.h" #include "options.h" #include "exceptions.h" @@ -305,8 +304,7 @@ Film::make_dcp (bool transcode) } } - r = JobManager::instance()->add (shared_ptr (new CheckHashesJob (shared_from_this(), od, r))); - JobManager::instance()->add (shared_ptr (new MakeDCPJob (shared_from_this(), r))); + // r = JobManager::instance()->add (shared_ptr (new CheckHashesJob (shared_from_this(), od, r))); } /** Start a job to examine our content file */ diff --git a/src/lib/make_dcp_job.cc b/src/lib/make_dcp_job.cc deleted file mode 100644 index fb24fedb3..000000000 --- a/src/lib/make_dcp_job.cc +++ /dev/null @@ -1,182 +0,0 @@ -/* - Copyright (C) 2012 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -/** @file src/make_dcp_job.cc - * @brief A job to create DCPs. - */ - -#include -#include -#include -#include -#include -#include -extern "C" { -#include -} -#include "make_dcp_job.h" -#include "dcp_content_type.h" -#include "exceptions.h" -#include "options.h" -#include "imagemagick_decoder.h" -#include "film.h" -#include "format.h" - -using std::string; -using std::cout; -using boost::shared_ptr; - -/** @param f Film we are making the DCP for. - * @param o Options. - */ -MakeDCPJob::MakeDCPJob (shared_ptr f, shared_ptr req) - : Job (f, req) -{ - -} - -string -MakeDCPJob::name () const -{ - return String::compose ("Make DCP for %1", _film->name()); -} - -/** @param f DCP frame index */ -string -MakeDCPJob::j2c_path (int f, int offset) const -{ - return _film->frame_out_path (f + offset, false); -} - -string -MakeDCPJob::wav_path (libdcp::Channel c) const -{ - return _film->multichannel_audio_out_path (int (c), false); -} - -void -MakeDCPJob::run () -{ - if (!_film->dcp_intrinsic_duration()) { - throw EncodeError ("cannot make a DCP when its intrinsic duration is not known"); - } - - descend (0.9); - - string const dcp_path = _film->dir (_film->dcp_name()); - - /* Remove any old DCP */ - boost::filesystem::remove_all (dcp_path); - - int const frames = _film->dcp_intrinsic_duration().get(); - int const duration = frames - _film->trim_start() - _film->trim_end(); - DCPFrameRate const dfr (_film->frames_per_second ()); - - libdcp::DCP dcp (_film->dir (_film->dcp_name())); - dcp.Progress.connect (boost::bind (&MakeDCPJob::dcp_progress, this, _1)); - - shared_ptr cpl ( - new libdcp::CPL (_film->dir (_film->dcp_name()), _film->dcp_name(), _film->dcp_content_type()->libdcp_kind (), frames, dfr.frames_per_second) - ); - - dcp.add_cpl (cpl); - - int frames_per_reel = 0; - if (_film->reel_size()) { - frames_per_reel = (_film->reel_size().get() / (_film->j2k_bandwidth() / 8)) * dfr.frames_per_second; - } else { - frames_per_reel = frames; - } - - int frames_done = 0; - int reel = 0; - - while (frames_done < frames) { - - descend (float (frames_per_reel) / frames); - - int this_time = std::min (frames_per_reel, (frames - frames_done)); - - descend (0.8); - - shared_ptr pa ( - new libdcp::MonoPictureAsset ( - boost::bind (&MakeDCPJob::j2c_path, this, _1, frames_done), - _film->dir (_film->dcp_name()), - String::compose ("video_%1.mxf", reel), - &dcp.Progress, - dfr.frames_per_second, - this_time, - _film->format()->dcp_size() - ) - ); - - pa->set_entry_point (_film->trim_start ()); - pa->set_duration (duration); - - ascend (); - - shared_ptr sa; - - if (_film->audio_channels() > 0) { - descend (0.1); - sa.reset ( - new libdcp::SoundAsset ( - boost::bind (&MakeDCPJob::wav_path, this, _1), - _film->dir (_film->dcp_name()), - String::compose ("audio_%1.mxf", reel), - &dcp.Progress, - dfr.frames_per_second, - this_time, - frames_done, - dcp_audio_channels (_film->audio_channels()) - ) - ); - - sa->set_entry_point (_film->trim_start ()); - sa->set_duration (duration); - - ascend (); - } - - descend (0.1); - cpl->add_reel (shared_ptr (new libdcp::Reel (pa, sa, shared_ptr ()))); - ascend (); - - frames_done += frames_per_reel; - ++reel; - - ascend (); - } - - ascend (); - - descend (0.1); - dcp.write_xml (); - ascend (); - - set_progress (1); - set_state (FINISHED_OK); -} - -void -MakeDCPJob::dcp_progress (float p) -{ - set_progress (p); -} diff --git a/src/lib/make_dcp_job.h b/src/lib/make_dcp_job.h deleted file mode 100644 index 481382248..000000000 --- a/src/lib/make_dcp_job.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - Copyright (C) 2012 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -/** @file src/make_dcp_job.h - * @brief A job to create DCPs. - */ - -#include "job.h" - -/** @class MakeDCPJob - * @brief A job to create DCPs - */ -class MakeDCPJob : public Job -{ -public: - MakeDCPJob (boost::shared_ptr, boost::shared_ptr req); - - std::string name () const; - void run (); - -private: - void dcp_progress (float); - std::string j2c_path (int, int) const; - std::string wav_path (libdcp::Channel) const; -}; - diff --git a/src/lib/writer.cc b/src/lib/writer.cc index fbd371550..2cefd32fb 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -19,6 +19,7 @@ #include #include +#include #include "writer.h" #include "compose.hpp" #include "film.h" @@ -192,6 +193,33 @@ Writer::finish () _picture_asset_writer->finalize (); _sound_asset_writer->finalize (); + + + int const frames = _film->dcp_intrinsic_duration().get(); + int const duration = frames - _film->trim_start() - _film->trim_end(); + + _picture_asset->set_entry_point (_film->trim_start ()); + _picture_asset->set_duration (duration); + _sound_asset->set_entry_point (_film->trim_start ()); + _sound_asset->set_duration (duration); + + libdcp::DCP dcp (_film->dir (_film->dcp_name())); + DCPFrameRate dfr (_film->frames_per_second ()); + + shared_ptr cpl ( + new libdcp::CPL (_film->dir (_film->dcp_name()), _film->dcp_name(), _film->dcp_content_type()->libdcp_kind (), frames, dfr.frames_per_second) + ); + + dcp.add_cpl (cpl); + + cpl->add_reel (shared_ptr (new libdcp::Reel ( + _picture_asset, + _sound_asset, + shared_ptr () + ) + )); + + dcp.write_xml (); } /** Tell the writer that frame `f' should be a repeat of the frame before it */ diff --git a/src/lib/wscript b/src/lib/wscript index 6d72f6480..02c426373 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -40,7 +40,6 @@ def build(bld): job_manager.cc log.cc lut.cc - make_dcp_job.cc matcher.cc scp_dcp_job.cc scaler.cc diff --git a/src/tools/makedcp.cc b/src/tools/makedcp.cc index 900c31bfc..447b0ddc0 100644 --- a/src/tools/makedcp.cc +++ b/src/tools/makedcp.cc @@ -26,7 +26,6 @@ #include "film.h" #include "filter.h" #include "transcode_job.h" -#include "make_dcp_job.h" #include "job_manager.h" #include "ab_transcode_job.h" #include "util.h" -- cgit v1.2.3 From 5e7de85ce53a42b90023a2160d3450a7af4a4b61 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 20 Jan 2013 23:11:18 +0000 Subject: Write hashes of encoded frames. --- src/lib/dcp_video_frame.cc | 10 ++++++---- src/lib/dcp_video_frame.h | 1 + src/lib/writer.cc | 2 ++ 3 files changed, 9 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/lib/dcp_video_frame.cc b/src/lib/dcp_video_frame.cc index 89db5761a..c3f0fed03 100644 --- a/src/lib/dcp_video_frame.cc +++ b/src/lib/dcp_video_frame.cc @@ -401,8 +401,8 @@ EncodedData::~EncodedData () } /** Write this data to a J2K file. - * @param opt Options. - * @param frame DCP Frame index. + * @param Film Film. + * @param frame DCP frame index. */ void EncodedData::write (shared_ptr film, int frame) const @@ -422,12 +422,14 @@ EncodedData::write (shared_ptr film, int frame) const /* Rename the file from foo.j2c.tmp to foo.j2c now that it is complete */ boost::filesystem::rename (tmp_j2k, real_j2k); +} - /* Write a file containing the hash */ +void +EncodedData::write_hash (shared_ptr film, int frame) const +{ string const hash = film->hash_out_path (frame, false); ofstream h (hash.c_str()); h << md5_digest (_data, _size) << "\n"; - h.close (); } /** Send this data to a socket. diff --git a/src/lib/dcp_video_frame.h b/src/lib/dcp_video_frame.h index 2ad2b0d44..1d434505a 100644 --- a/src/lib/dcp_video_frame.h +++ b/src/lib/dcp_video_frame.h @@ -49,6 +49,7 @@ public: void send (boost::shared_ptr socket); void write (boost::shared_ptr, int) const; + void write_hash (boost::shared_ptr, int) const; /** @return data */ uint8_t* data () const { diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 2cefd32fb..b94ff3c24 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -124,9 +124,11 @@ Writer::thread () _film->log()->log (String::compose ("Writer writes %1 to MXF", encoded.second)); if (encoded.first) { _picture_asset_writer->write (encoded.first->data(), encoded.first->size()); + encoded.first->write_hash (_film, encoded.second); _last_written = encoded.first; } else { _picture_asset_writer->write (_last_written->data(), _last_written->size()); + _last_written->write_hash (_film, encoded.second); } lock.lock (); -- cgit v1.2.3 From 00e09ae4af02a5c54d8eaba9316f2902b9539c38 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 21 Jan 2013 20:20:38 +0000 Subject: A couple of bug fixes. --- NOTES | 1 - src/lib/writer.cc | 7 ++++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/NOTES b/NOTES index 365db34de..245017e0d 100644 --- a/NOTES +++ b/NOTES @@ -1,5 +1,4 @@ ... perhaps generate the CPL hash on the fly -Write hashes of frames after successful write. Make check of hashes optional; recovery in general Fix multi-reel or remove it \ No newline at end of file diff --git a/src/lib/writer.cc b/src/lib/writer.cc index b94ff3c24..df6f20791 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -57,7 +57,7 @@ Writer::Writer (shared_ptr f) String::compose ("audio_%1.mxf", 0), DCPFrameRate (_film->frames_per_second()).frames_per_second, _film->audio_channels(), - _film->audio_stream()->sample_rate() + dcp_audio_sample_rate (_film->audio_stream()->sample_rate()) ) ); @@ -196,10 +196,11 @@ Writer::finish () _picture_asset_writer->finalize (); _sound_asset_writer->finalize (); - - int const frames = _film->dcp_intrinsic_duration().get(); + int const frames = _last_written_frame + 1; int const duration = frames - _film->trim_start() - _film->trim_end(); + _film->set_intrinsic_duration (frames); + _picture_asset->set_entry_point (_film->trim_start ()); _picture_asset->set_duration (duration); _sound_asset->set_entry_point (_film->trim_start ()); -- cgit v1.2.3 From 657f735160fd8b0abc67d6e5f519da5786ed26f0 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 21 Jan 2013 20:35:00 +0000 Subject: Fix a couple of things; go back to un-numbered MXF file names for a bit. --- src/lib/encoder.cc | 2 +- src/lib/encoder.h | 4 ++-- src/lib/writer.cc | 8 ++++---- src/lib/writer.h | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index c2416b87e..6b14b2698 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -53,7 +53,7 @@ int const Encoder::_history_size = 25; /** @param f Film that we are encoding. * @param o Options. */ -Encoder::Encoder (shared_ptr f) +Encoder::Encoder (shared_ptr f) : _film (f) , _just_skipped (false) , _video_frames_in (0) diff --git a/src/lib/encoder.h b/src/lib/encoder.h index fc89d674a..429b46a18 100644 --- a/src/lib/encoder.h +++ b/src/lib/encoder.h @@ -62,7 +62,7 @@ class Writer; class Encoder : public VideoSink, public AudioSink { public: - Encoder (boost::shared_ptr f); + Encoder (boost::shared_ptr f); virtual ~Encoder (); /** Called to indicate that a processing run is about to begin */ @@ -96,7 +96,7 @@ private: void terminate_worker_threads (); /** Film that we are encoding */ - boost::shared_ptr _film; + boost::shared_ptr _film; /** Mutex for _time_history, _just_skipped and _last_frame */ mutable boost::mutex _history_mutex; diff --git a/src/lib/writer.cc b/src/lib/writer.cc index df6f20791..56cfa43a7 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -33,7 +33,7 @@ using boost::shared_ptr; unsigned int const Writer::_maximum_frames_in_memory = 8; -Writer::Writer (shared_ptr f) +Writer::Writer (shared_ptr f) : _film (f) , _thread (0) , _finish (false) @@ -42,7 +42,7 @@ Writer::Writer (shared_ptr f) _picture_asset.reset ( new libdcp::MonoPictureAsset ( _film->dir (_film->dcp_name()), - String::compose ("video_%1.mxf", 0), + "video.mxf", DCPFrameRate (_film->frames_per_second()).frames_per_second, _film->format()->dcp_size() ) @@ -54,7 +54,7 @@ Writer::Writer (shared_ptr f) _sound_asset.reset ( new libdcp::SoundAsset ( _film->dir (_film->dcp_name()), - String::compose ("audio_%1.mxf", 0), + "audio.mxf", DCPFrameRate (_film->frames_per_second()).frames_per_second, _film->audio_channels(), dcp_audio_sample_rate (_film->audio_stream()->sample_rate()) @@ -199,7 +199,7 @@ Writer::finish () int const frames = _last_written_frame + 1; int const duration = frames - _film->trim_start() - _film->trim_end(); - _film->set_intrinsic_duration (frames); + _film->set_dcp_intrinsic_duration (frames); _picture_asset->set_entry_point (_film->trim_start ()); _picture_asset->set_duration (duration); diff --git a/src/lib/writer.h b/src/lib/writer.h index 77f98f160..1aaea4d9d 100644 --- a/src/lib/writer.h +++ b/src/lib/writer.h @@ -36,7 +36,7 @@ namespace libdcp { class Writer { public: - Writer (boost::shared_ptr); + Writer (boost::shared_ptr); void write (boost::shared_ptr, int); void write (boost::shared_ptr); @@ -47,7 +47,7 @@ private: void thread (); - boost::shared_ptr _film; + boost::shared_ptr _film; boost::thread* _thread; bool _finish; -- cgit v1.2.3 From 001dcc94aaba89a5fed1a328496bf83dba5bfb79 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 22 Jan 2013 20:24:19 +0000 Subject: Speculative fix to bytes_per_pixel(). --- src/lib/image.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/image.cc b/src/lib/image.cc index c41558f02..4eed0e5b4 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -350,7 +350,7 @@ Image::bytes_per_pixel (int c) const return 0.5; } case PIX_FMT_YUV422P10LE: - if (c == 1) { + if (c == 0) { return 2; } else { return 1; -- cgit v1.2.3 From 3886847e2dafdaec4ad780dac606802356beb31d Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 23 Jan 2013 14:42:45 +0000 Subject: Cope with no sound. --- src/lib/writer.cc | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 56cfa43a7..a434db0ec 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -194,7 +194,10 @@ Writer::finish () _thread = 0; _picture_asset_writer->finalize (); - _sound_asset_writer->finalize (); + + if (_sound_asset_writer) { + _sound_asset_writer->finalize (); + } int const frames = _last_written_frame + 1; int const duration = frames - _film->trim_start() - _film->trim_end(); @@ -203,8 +206,11 @@ Writer::finish () _picture_asset->set_entry_point (_film->trim_start ()); _picture_asset->set_duration (duration); - _sound_asset->set_entry_point (_film->trim_start ()); - _sound_asset->set_duration (duration); + + if (_sound_asset) { + _sound_asset->set_entry_point (_film->trim_start ()); + _sound_asset->set_duration (duration); + } libdcp::DCP dcp (_film->dir (_film->dcp_name())); DCPFrameRate dfr (_film->frames_per_second ()); -- cgit v1.2.3 From d58f9adc515ac0c0193a4998fed3605f4e2c6e11 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 23 Jan 2013 14:42:56 +0000 Subject: Fix and test Image::make_black(). --- src/lib/image.cc | 18 +++++++++++++--- test/test.cc | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 76 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/lib/image.cc b/src/lib/image.cc index 4eed0e5b4..3afb6205e 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -245,13 +245,25 @@ Image::make_black () { switch (_pixel_format) { case PIX_FMT_YUV420P: - case PIX_FMT_YUV422P10LE: case PIX_FMT_YUV422P: memset (data()[0], 0, lines(0) * stride()[0]); - memset (data()[1], 0x80, lines(1) * stride()[1]); - memset (data()[2], 0x80, lines(2) * stride()[2]); + memset (data()[1], 0x7f, lines(1) * stride()[1]); + memset (data()[2], 0x7f, lines(2) * stride()[2]); break; + case PIX_FMT_YUV422P10LE: + memset (data()[0], 0, lines(0) * stride()[0]); + for (int i = 1; i < 3; ++i) { + int16_t* p = reinterpret_cast (data()[i]); + for (int y = 0; y < size().height; ++y) { + for (int x = 0; x < line_size()[i] / 2; ++x) { + p[x] = (1 << 9) - 1; + } + p += stride()[i] / 2; + } + } + break; + case PIX_FMT_RGB24: memset (data()[0], 0, lines(0) * stride()[0]); break; diff --git a/test/test.cc b/test/test.cc index 7e1d92e06..13eb1f17f 100644 --- a/test/test.cc +++ b/test/test.cc @@ -69,9 +69,69 @@ new_test_film (string name) return shared_ptr (new Film (d, false)); } -BOOST_AUTO_TEST_CASE (film_metadata_test) + +/* Check that Image::make_black works, and doesn't use values which crash + sws_scale(). +*/ +BOOST_AUTO_TEST_CASE (make_black_test) { + /* This needs to happen in the first test */ dvdomatic_setup (); + + libdcp::Size in_size (512, 512); + libdcp::Size out_size (1024, 1024); + + { + /* Plain RGB input */ + boost::shared_ptr foo (new SimpleImage (AV_PIX_FMT_RGB24, in_size, true)); + foo->make_black (); + boost::shared_ptr bar = foo->scale_and_convert_to_rgb (out_size, 0, Scaler::from_id ("bicubic"), true); + + uint8_t* p = bar->data()[0]; + for (int y = 0; y < bar->size().height; ++y) { + uint8_t* q = p; + for (int x = 0; x < bar->line_size()[0]; ++x) { + BOOST_CHECK_EQUAL (*q++, 0); + } + p += bar->stride()[0]; + } + } + + { + /* YUV420P input */ + boost::shared_ptr foo (new SimpleImage (AV_PIX_FMT_YUV420P, in_size, true)); + foo->make_black (); + boost::shared_ptr bar = foo->scale_and_convert_to_rgb (out_size, 0, Scaler::from_id ("bicubic"), true); + + uint8_t* p = bar->data()[0]; + for (int y = 0; y < bar->size().height; ++y) { + uint8_t* q = p; + for (int x = 0; x < bar->line_size()[0]; ++x) { + BOOST_CHECK_EQUAL (*q++, 0); + } + p += bar->stride()[0]; + } + } + + { + /* YUV422P10LE input */ + boost::shared_ptr foo (new SimpleImage (AV_PIX_FMT_YUV422P10LE, in_size, true)); + foo->make_black (); + boost::shared_ptr bar = foo->scale_and_convert_to_rgb (out_size, 0, Scaler::from_id ("bicubic"), true); + + uint8_t* p = bar->data()[0]; + for (int y = 0; y < bar->size().height; ++y) { + uint8_t* q = p; + for (int x = 0; x < bar->line_size()[0]; ++x) { + BOOST_CHECK_EQUAL (*q++, 0); + } + p += bar->stride()[0]; + } + } +} + +BOOST_AUTO_TEST_CASE (film_metadata_test) +{ setup_test_config (); string const test_film = "build/test/film_metadata_test"; -- cgit v1.2.3 From 52821965206bce3e5d47200d838e54996857d212 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 23 Jan 2013 15:04:54 +0000 Subject: Make sure inputs to sws_scale are aligned, as I think they must be. --- src/lib/image.cc | 31 ++++++++++++++++++++++++++----- src/lib/image.h | 4 ++++ test/test.cc | 22 +++++++++++++--------- 3 files changed, 43 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/lib/image.cc b/src/lib/image.cc index 3afb6205e..0a51add00 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -96,11 +96,15 @@ Image::components () const } shared_ptr -Image::scale (Size out_size, Scaler const * scaler, bool aligned) const +Image::scale (Size out_size, Scaler const * scaler, bool result_aligned) const { assert (scaler); + /* Empirical testing suggests that sws_scale() will crash if + the input image is not aligned. + */ + assert (aligned ()); - shared_ptr scaled (new SimpleImage (pixel_format(), out_size, aligned)); + shared_ptr scaled (new SimpleImage (pixel_format(), out_size, result_aligned)); struct SwsContext* scale_context = sws_getContext ( size().width, size().height, pixel_format(), @@ -125,14 +129,18 @@ Image::scale (Size out_size, Scaler const * scaler, bool aligned) const * @param scaler Scaler to use. */ shared_ptr -Image::scale_and_convert_to_rgb (Size out_size, int padding, Scaler const * scaler, bool aligned) const +Image::scale_and_convert_to_rgb (Size out_size, int padding, Scaler const * scaler, bool result_aligned) const { assert (scaler); + /* Empirical testing suggests that sws_scale() will crash if + the input image is not aligned. + */ + assert (aligned ()); Size content_size = out_size; content_size.width -= (padding * 2); - shared_ptr rgb (new SimpleImage (PIX_FMT_RGB24, content_size, aligned)); + shared_ptr rgb (new SimpleImage (PIX_FMT_RGB24, content_size, result_aligned)); struct SwsContext* scale_context = sws_getContext ( size().width, size().height, pixel_format(), @@ -153,7 +161,7 @@ Image::scale_and_convert_to_rgb (Size out_size, int padding, Scaler const * scal scheme of things. */ if (padding > 0) { - shared_ptr padded_rgb (new SimpleImage (PIX_FMT_RGB24, out_size, aligned)); + shared_ptr padded_rgb (new SimpleImage (PIX_FMT_RGB24, out_size, result_aligned)); padded_rgb->make_black (); /* XXX: we are cheating a bit here; we know the frame is RGB so we can @@ -485,6 +493,12 @@ SimpleImage::size () const return _size; } +bool +SimpleImage::aligned () const +{ + return _aligned; +} + FilterBufferImage::FilterBufferImage (AVPixelFormat p, AVFilterBufferRef* b) : Image (p) , _buffer (b) @@ -522,6 +536,13 @@ FilterBufferImage::size () const return Size (_buffer->video->w, _buffer->video->h); } +bool +FilterBufferImage::aligned () const +{ + /* XXX? */ + return true; +} + RGBPlusAlphaImage::RGBPlusAlphaImage (shared_ptr im) : SimpleImage (im->pixel_format(), im->size(), false) { diff --git a/src/lib/image.h b/src/lib/image.h index 5ca3f337c..23f13a648 100644 --- a/src/lib/image.h +++ b/src/lib/image.h @@ -68,6 +68,8 @@ public: /** @return Size of the image, in pixels */ virtual libdcp::Size size () const = 0; + virtual bool aligned () const = 0; + int components () const; int lines (int) const; @@ -107,6 +109,7 @@ public: int * line_size () const; int * stride () const; libdcp::Size size () const; + bool aligned () const; private: /* Not allowed */ @@ -131,6 +134,7 @@ public: int * line_size () const; int * stride () const; libdcp::Size size () const; + bool aligned () const; protected: void allocate (); diff --git a/test/test.cc b/test/test.cc index 13eb1f17f..9f1248f29 100644 --- a/test/test.cc +++ b/test/test.cc @@ -385,26 +385,30 @@ do_remote_encode (shared_ptr frame, ServerDescription* descriptio BOOST_AUTO_TEST_CASE (client_server_test) { - shared_ptr image (new SimpleImage (PIX_FMT_RGB24, libdcp::Size (1998, 1080), false)); + shared_ptr image (new SimpleImage (PIX_FMT_RGB24, libdcp::Size (1998, 1080), true)); uint8_t* p = image->data()[0]; for (int y = 0; y < 1080; ++y) { + uint8_t* q = p; for (int x = 0; x < 1998; ++x) { - *p++ = x % 256; - *p++ = y % 256; - *p++ = (x + y) % 256; + *q++ = x % 256; + *q++ = y % 256; + *q++ = (x + y) % 256; } + p += image->stride()[0]; } - shared_ptr sub_image (new SimpleImage (PIX_FMT_RGBA, libdcp::Size (100, 200), false)); + shared_ptr sub_image (new SimpleImage (PIX_FMT_RGBA, libdcp::Size (100, 200), true)); p = sub_image->data()[0]; for (int y = 0; y < 200; ++y) { + uint8_t* q = p; for (int x = 0; x < 100; ++x) { - *p++ = y % 256; - *p++ = x % 256; - *p++ = (x + y) % 256; - *p++ = 1; + *q++ = y % 256; + *q++ = x % 256; + *q++ = (x + y) % 256; + *q++ = 1; } + p += sub_image->stride()[0]; } shared_ptr subtitle (new Subtitle (Position (50, 60), sub_image)); -- cgit v1.2.3 From 4233db111cc4b1ca8a1a82b8aac96805a866ffa0 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 23 Jan 2013 19:04:32 +0000 Subject: Fix some unaligned images. --- src/lib/imagemagick_decoder.cc | 2 +- src/lib/matcher.cc | 2 +- src/lib/video_decoder.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/lib/imagemagick_decoder.cc b/src/lib/imagemagick_decoder.cc index bab4f2f07..a623fd226 100644 --- a/src/lib/imagemagick_decoder.cc +++ b/src/lib/imagemagick_decoder.cc @@ -98,7 +98,7 @@ ImageMagickDecoder::pass () delete magick_image; - image = image->crop (_film->crop(), false); + image = image->crop (_film->crop(), true); emit_video (image, 0); diff --git a/src/lib/matcher.cc b/src/lib/matcher.cc index 2b7a080fc..182fb306c 100644 --- a/src/lib/matcher.cc +++ b/src/lib/matcher.cc @@ -81,7 +81,7 @@ Matcher::process_end () _log->log (String::compose ("Emitting %1 frames of black video", black_video_frames)); - shared_ptr black (new SimpleImage (_pixel_format.get(), _size.get(), false)); + shared_ptr black (new SimpleImage (_pixel_format.get(), _size.get(), true)); black->make_black (); for (int i = 0; i < black_video_frames; ++i) { Video (black, i != 0, shared_ptr()); diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc index 3a803a863..0fa16bc32 100644 --- a/src/lib/video_decoder.cc +++ b/src/lib/video_decoder.cc @@ -57,7 +57,7 @@ void VideoDecoder::repeat_last_video () { if (!_last_image) { - _last_image.reset (new SimpleImage (pixel_format(), native_size(), false)); + _last_image.reset (new SimpleImage (pixel_format(), native_size(), true)); _last_image->make_black (); } -- cgit v1.2.3 From d1b20374b1bd02b2929c9c3080c006874b525ef5 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 23 Jan 2013 20:06:37 +0000 Subject: Remove multi-reel, for now, and sort out Size vs libdcp::Size. --- src/lib/dcp_video_frame.cc | 2 +- src/lib/dcp_video_frame.h | 8 ++-- src/lib/ffmpeg_decoder.cc | 8 ++-- src/lib/ffmpeg_decoder.h | 2 +- src/lib/film.cc | 32 ++------------- src/lib/film.h | 20 +++------- src/lib/filter_graph.cc | 4 +- src/lib/filter_graph.h | 6 +-- src/lib/format.cc | 30 +++++++------- src/lib/format.h | 12 +++--- src/lib/image.cc | 16 ++++---- src/lib/image.h | 16 ++++---- src/lib/imagemagick_decoder.cc | 6 +-- src/lib/imagemagick_decoder.h | 2 +- src/lib/make_dcp_job.cc | 90 +++++++++++++++--------------------------- src/lib/make_dcp_job.h | 2 +- src/lib/matcher.h | 2 +- src/lib/options.h | 2 +- src/lib/server.cc | 6 +-- src/lib/subtitle.cc | 2 +- src/lib/util.cc | 13 +----- src/lib/util.h | 34 ++-------------- src/lib/video_decoder.h | 2 +- src/wx/film_editor.cc | 60 ---------------------------- src/wx/film_editor.h | 5 --- src/wx/film_viewer.cc | 4 +- src/wx/film_viewer.h | 2 +- test/test.cc | 14 +++---- 28 files changed, 119 insertions(+), 283 deletions(-) (limited to 'src') diff --git a/src/lib/dcp_video_frame.cc b/src/lib/dcp_video_frame.cc index c6b29ba41..921a1876b 100644 --- a/src/lib/dcp_video_frame.cc +++ b/src/lib/dcp_video_frame.cc @@ -75,7 +75,7 @@ using boost::shared_ptr; */ DCPVideoFrame::DCPVideoFrame ( shared_ptr yuv, shared_ptr sub, - Size out, int p, int subtitle_offset, float subtitle_scale, + libdcp::Size out, int p, int subtitle_offset, float subtitle_scale, Scaler const * s, SourceFrame f, float fps, string pp, int clut, int bw, Log* l ) : _input (yuv) diff --git a/src/lib/dcp_video_frame.h b/src/lib/dcp_video_frame.h index 134720da8..c0eff3f35 100644 --- a/src/lib/dcp_video_frame.h +++ b/src/lib/dcp_video_frame.h @@ -40,7 +40,7 @@ class EncodedData { public: /** @param d Data (will not be freed by this class, but may be by subclasses) - * @param s Size of data, in bytes. + * @param s libdcp::Size of data, in bytes. */ EncodedData (uint8_t* d, int s) : _data (d) @@ -76,7 +76,7 @@ class LocallyEncodedData : public EncodedData { public: /** @param d Data (which will not be freed by this class) - * @param s Size of data, in bytes. + * @param s libdcp::Size of data, in bytes. */ LocallyEncodedData (uint8_t* d, int s) : EncodedData (d, s) @@ -107,7 +107,7 @@ class DCPVideoFrame { public: DCPVideoFrame ( - boost::shared_ptr, boost::shared_ptr, Size, + boost::shared_ptr, boost::shared_ptr, libdcp::Size, int, int, float, Scaler const *, SourceFrame, float, std::string, int, int, Log * ); @@ -125,7 +125,7 @@ private: boost::shared_ptr _input; ///< the input image boost::shared_ptr _subtitle; ///< any subtitle that should be on the image - Size _out_size; ///< the required size of the output, in pixels + libdcp::Size _out_size; ///< the required size of the output, in pixels int _padding; int _subtitle_offset; float _subtitle_scale; diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index a19f26ad7..aff3ff666 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -468,10 +468,10 @@ FFmpegDecoder::audio_sample_format () const return _audio_codec_context->sample_fmt; } -Size +libdcp::Size FFmpegDecoder::native_size () const { - return Size (_video_codec_context->width, _video_codec_context->height); + return libdcp::Size (_video_codec_context->width, _video_codec_context->height); } PixelFormat @@ -558,12 +558,12 @@ FFmpegDecoder::filter_and_emit_video (AVFrame* frame) shared_ptr graph; list >::iterator i = _filter_graphs.begin(); - while (i != _filter_graphs.end() && !(*i)->can_process (Size (frame->width, frame->height), (AVPixelFormat) frame->format)) { + while (i != _filter_graphs.end() && !(*i)->can_process (libdcp::Size (frame->width, frame->height), (AVPixelFormat) frame->format)) { ++i; } if (i == _filter_graphs.end ()) { - graph.reset (new FilterGraph (_film, this, Size (frame->width, frame->height), (AVPixelFormat) frame->format)); + graph.reset (new FilterGraph (_film, this, libdcp::Size (frame->width, frame->height), (AVPixelFormat) frame->format)); _filter_graphs.push_back (graph); _film->log()->log (String::compose ("New graph for %1x%2, pixel format %3", frame->width, frame->height, frame->format)); } else { diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h index 2fb8675f9..3b564b826 100644 --- a/src/lib/ffmpeg_decoder.h +++ b/src/lib/ffmpeg_decoder.h @@ -90,7 +90,7 @@ public: ~FFmpegDecoder (); float frames_per_second () const; - Size native_size () const; + libdcp::Size native_size () const; SourceFrame length () const; int time_base_numerator () const; int time_base_denominator () const; diff --git a/src/lib/film.cc b/src/lib/film.cc index f0441c9e0..5a11b0ca9 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -157,7 +157,6 @@ Film::Film (Film const & o) , _scaler (o._scaler) , _dcp_trim_start (o._dcp_trim_start) , _dcp_trim_end (o._dcp_trim_end) - , _reel_size (o._reel_size) , _dcp_ab (o._dcp_ab) , _content_audio_stream (o._content_audio_stream) , _external_audio (o._external_audio) @@ -414,9 +413,6 @@ Film::write_metadata () const f << "scaler " << _scaler->id () << "\n"; f << "dcp_trim_start " << _dcp_trim_start << "\n"; f << "dcp_trim_end " << _dcp_trim_end << "\n"; - if (_reel_size) { - f << "reel_size " << _reel_size.get() << "\n"; - } f << "dcp_ab " << (_dcp_ab ? "1" : "0") << "\n"; if (_content_audio_stream) { f << "selected_content_audio_stream " << _content_audio_stream->to_string() << "\n"; @@ -531,8 +527,6 @@ Film::read_metadata () _dcp_trim_start = atoi (v.c_str ()); } else if (k == "dcp_trim_end") { _dcp_trim_end = atoi (v.c_str ()); - } else if (k == "reel_size") { - _reel_size = boost::lexical_cast (v); } else if (k == "dcp_ab") { _dcp_ab = (v == "1"); } else if (k == "selected_content_audio_stream" || (!version && k == "selected_audio_stream")) { @@ -628,8 +622,8 @@ Film::read_metadata () _dirty = false; } -Size -Film::cropped_size (Size s) const +libdcp::Size +Film::cropped_size (libdcp::Size s) const { boost::mutex::scoped_lock lm (_state_mutex); s.width -= _crop.left + _crop.right; @@ -1094,26 +1088,6 @@ Film::set_dcp_trim_end (int t) signal_changed (DCP_TRIM_END); } -void -Film::set_reel_size (uint64_t s) -{ - { - boost::mutex::scoped_lock lm (_state_mutex); - _reel_size = s; - } - signal_changed (REEL_SIZE); -} - -void -Film::unset_reel_size () -{ - { - boost::mutex::scoped_lock lm (_state_mutex); - _reel_size = boost::optional (); - } - signal_changed (REEL_SIZE); -} - void Film::set_dcp_ab (bool a) { @@ -1323,7 +1297,7 @@ Film::set_package_type (string p) } void -Film::set_size (Size s) +Film::set_size (libdcp::Size s) { { boost::mutex::scoped_lock lm (_state_mutex); diff --git a/src/lib/film.h b/src/lib/film.h index 3485dfaae..d3530b817 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -86,7 +86,7 @@ public: void write_metadata () const; void read_metadata (); - Size cropped_size (Size) const; + libdcp::Size cropped_size (libdcp::Size) const; boost::optional dcp_length () const; std::string dci_name () const; std::string dcp_name () const; @@ -116,7 +116,6 @@ public: SCALER, DCP_TRIM_START, DCP_TRIM_END, - REEL_SIZE, DCP_AB, CONTENT_AUDIO_STREAM, EXTERNAL_AUDIO, @@ -201,11 +200,6 @@ public: return _dcp_trim_end; } - boost::optional reel_size () const { - boost::mutex::scoped_lock lm (_state_mutex); - return _reel_size; - } - bool dcp_ab () const { boost::mutex::scoped_lock lm (_state_mutex); return _dcp_ab; @@ -306,7 +300,7 @@ public: return _package_type; } - Size size () const { + libdcp::Size size () const { boost::mutex::scoped_lock lm (_state_mutex); return _size; } @@ -361,8 +355,6 @@ public: void set_scaler (Scaler const *); void set_dcp_trim_start (int); void set_dcp_trim_end (int); - void set_reel_size (uint64_t); - void unset_reel_size (); void set_dcp_ab (bool); void set_content_audio_stream (boost::shared_ptr); void set_external_audio (std::vector); @@ -383,7 +375,7 @@ public: void set_studio (std::string); void set_facility (std::string); void set_package_type (std::string); - void set_size (Size); + void set_size (libdcp::Size); void set_length (SourceFrame); void unset_length (); void set_content_digest (std::string); @@ -445,8 +437,6 @@ private: int _dcp_trim_start; /** Frames to trim off the end of the DCP */ int _dcp_trim_end; - /** Approximate target reel size in bytes; if not set, use a single reel */ - boost::optional _reel_size; /** true to create an A/B comparison DCP, where the left half of the image is the video without any filters or post-processing, and the right half has the specified filters and post-processing. @@ -494,8 +484,8 @@ private: /* Data which are cached to speed things up */ - /** Size, in pixels, of the source (ignoring cropping) */ - Size _size; + /** libdcp::Size, in pixels, of the source (ignoring cropping) */ + libdcp::Size _size; /** The length of the source, in video frames (as far as we know) */ boost::optional _length; /** MD5 digest of our content file */ diff --git a/src/lib/filter_graph.cc b/src/lib/filter_graph.cc index 376ab404f..6cd7dc2cb 100644 --- a/src/lib/filter_graph.cc +++ b/src/lib/filter_graph.cc @@ -54,7 +54,7 @@ using boost::shared_ptr; * @param s Size of the images to process. * @param p Pixel format of the images to process. */ -FilterGraph::FilterGraph (shared_ptr film, FFmpegDecoder* decoder, Size s, AVPixelFormat p) +FilterGraph::FilterGraph (shared_ptr film, FFmpegDecoder* decoder, libdcp::Size s, AVPixelFormat p) : _buffer_src_context (0) , _buffer_sink_context (0) , _size (s) @@ -205,7 +205,7 @@ FilterGraph::process (AVFrame const * frame) * @return true if this chain can process images with `s' and `p', otherwise false. */ bool -FilterGraph::can_process (Size s, AVPixelFormat p) const +FilterGraph::can_process (libdcp::Size s, AVPixelFormat p) const { return (_size == s && _pixel_format == p); } diff --git a/src/lib/filter_graph.h b/src/lib/filter_graph.h index 9e6ac6252..7e4e8422b 100644 --- a/src/lib/filter_graph.h +++ b/src/lib/filter_graph.h @@ -37,15 +37,15 @@ class FFmpegDecoder; class FilterGraph { public: - FilterGraph (boost::shared_ptr film, FFmpegDecoder* decoder, Size s, AVPixelFormat p); + FilterGraph (boost::shared_ptr film, FFmpegDecoder* decoder, libdcp::Size s, AVPixelFormat p); - bool can_process (Size s, AVPixelFormat p) const; + bool can_process (libdcp::Size s, AVPixelFormat p) const; std::list > process (AVFrame const * frame); private: AVFilterContext* _buffer_src_context; AVFilterContext* _buffer_sink_context; - Size _size; ///< size of the images that this chain can process + libdcp::Size _size; ///< size of the images that this chain can process AVPixelFormat _pixel_format; ///< pixel format of the images that this chain can process }; diff --git a/src/lib/format.cc b/src/lib/format.cc index 975862411..088a16059 100644 --- a/src/lib/format.cc +++ b/src/lib/format.cc @@ -67,19 +67,19 @@ Format::as_metadata () const void Format::setup_formats () { - _formats.push_back (new FixedFormat (119, Size (1285, 1080), "119", "1.19", "F")); - _formats.push_back (new FixedFormat (133, Size (1436, 1080), "133", "1.33", "F")); - _formats.push_back (new FixedFormat (138, Size (1485, 1080), "138", "1.375", "F")); - _formats.push_back (new FixedFormat (133, Size (1998, 1080), "133-in-flat", "4:3 within Flat", "F")); - _formats.push_back (new FixedFormat (137, Size (1480, 1080), "137", "Academy", "F")); - _formats.push_back (new FixedFormat (166, Size (1793, 1080), "166", "1.66", "F")); - _formats.push_back (new FixedFormat (166, Size (1998, 1080), "166-in-flat", "1.66 within Flat", "F")); - _formats.push_back (new FixedFormat (178, Size (1998, 1080), "178-in-flat", "16:9 within Flat", "F")); - _formats.push_back (new FixedFormat (178, Size (1920, 1080), "178", "16:9", "F")); - _formats.push_back (new FixedFormat (185, Size (1998, 1080), "185", "Flat", "F")); - _formats.push_back (new FixedFormat (239, Size (2048, 858), "239", "Scope", "S")); - _formats.push_back (new VariableFormat (Size (1998, 1080), "var-185", "Flat", "F")); - _formats.push_back (new VariableFormat (Size (2048, 858), "var-239", "Scope", "S")); + _formats.push_back (new FixedFormat (119, libdcp::Size (1285, 1080), "119", "1.19", "F")); + _formats.push_back (new FixedFormat (133, libdcp::Size (1436, 1080), "133", "1.33", "F")); + _formats.push_back (new FixedFormat (138, libdcp::Size (1485, 1080), "138", "1.375", "F")); + _formats.push_back (new FixedFormat (133, libdcp::Size (1998, 1080), "133-in-flat", "4:3 within Flat", "F")); + _formats.push_back (new FixedFormat (137, libdcp::Size (1480, 1080), "137", "Academy", "F")); + _formats.push_back (new FixedFormat (166, libdcp::Size (1793, 1080), "166", "1.66", "F")); + _formats.push_back (new FixedFormat (166, libdcp::Size (1998, 1080), "166-in-flat", "1.66 within Flat", "F")); + _formats.push_back (new FixedFormat (178, libdcp::Size (1998, 1080), "178-in-flat", "16:9 within Flat", "F")); + _formats.push_back (new FixedFormat (178, libdcp::Size (1920, 1080), "178", "16:9", "F")); + _formats.push_back (new FixedFormat (185, libdcp::Size (1998, 1080), "185", "Flat", "F")); + _formats.push_back (new FixedFormat (239, libdcp::Size (2048, 858), "239", "Scope", "S")); + _formats.push_back (new VariableFormat (libdcp::Size (1998, 1080), "var-185", "Flat", "F")); + _formats.push_back (new VariableFormat (libdcp::Size (2048, 858), "var-239", "Scope", "S")); } /** @param n Nickname. @@ -140,7 +140,7 @@ Format::all () * @param id ID (e.g. 185) * @param n Nick name (e.g. Flat) */ -FixedFormat::FixedFormat (int r, Size dcp, string id, string n, string d) +FixedFormat::FixedFormat (int r, libdcp::Size dcp, string id, string n, string d) : Format (dcp, id, n, d) , _ratio (r) { @@ -160,7 +160,7 @@ Format::dcp_padding (shared_ptr f) const return p; } -VariableFormat::VariableFormat (Size dcp, string id, string n, string d) +VariableFormat::VariableFormat (libdcp::Size dcp, string id, string n, string d) : Format (dcp, id, n, d) { diff --git a/src/lib/format.h b/src/lib/format.h index 2118237a4..b4c691e56 100644 --- a/src/lib/format.h +++ b/src/lib/format.h @@ -31,7 +31,7 @@ class Film; class Format { public: - Format (Size dcp, std::string id, std::string n, std::string d) + Format (libdcp::Size dcp, std::string id, std::string n, std::string d) : _dcp_size (dcp) , _id (id) , _nickname (n) @@ -52,7 +52,7 @@ public: * put in a DCP for this ratio. This size will not correspond * to the ratio when we are doing things like 16:9 in a Flat frame. */ - Size dcp_size () const { + libdcp::Size dcp_size () const { return _dcp_size; } @@ -81,11 +81,11 @@ public: static void setup_formats (); protected: - /** Size in pixels of the images that we should + /** libdcp::Size in pixels of the images that we should * put in a DCP for this ratio. This size will not correspond * to the ratio when we are doing things like 16:9 in a Flat frame. */ - Size _dcp_size; + libdcp::Size _dcp_size; /** id for use in metadata */ std::string _id; /** nickname (e.g. Flat, Scope) */ @@ -104,7 +104,7 @@ private: class FixedFormat : public Format { public: - FixedFormat (int, Size, std::string, std::string, std::string); + FixedFormat (int, libdcp::Size, std::string, std::string, std::string); int ratio_as_integer (boost::shared_ptr) const { return _ratio; @@ -125,7 +125,7 @@ private: class VariableFormat : public Format { public: - VariableFormat (Size, std::string, std::string, std::string); + VariableFormat (libdcp::Size, std::string, std::string, std::string); int ratio_as_integer (boost::shared_ptr f) const; float ratio_as_float (boost::shared_ptr f) const; diff --git a/src/lib/image.cc b/src/lib/image.cc index f774f476f..feda09ec5 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -95,7 +95,7 @@ Image::components () const } shared_ptr -Image::scale (Size out_size, Scaler const * scaler, bool aligned) const +Image::scale (libdcp::Size out_size, Scaler const * scaler, bool aligned) const { assert (scaler); @@ -124,11 +124,11 @@ Image::scale (Size out_size, Scaler const * scaler, bool aligned) const * @param scaler Scaler to use. */ shared_ptr -Image::scale_and_convert_to_rgb (Size out_size, int padding, Scaler const * scaler, bool aligned) const +Image::scale_and_convert_to_rgb (libdcp::Size out_size, int padding, Scaler const * scaler, bool aligned) const { assert (scaler); - Size content_size = out_size; + libdcp::Size content_size = out_size; content_size.width -= (padding * 2); shared_ptr rgb (new SimpleImage (PIX_FMT_RGB24, content_size, aligned)); @@ -215,7 +215,7 @@ Image::post_process (string pp, bool aligned) const shared_ptr Image::crop (Crop crop, bool aligned) const { - Size cropped_size = size (); + libdcp::Size cropped_size = size (); cropped_size.width -= crop.left + crop.right; cropped_size.height -= crop.top + crop.bottom; @@ -368,7 +368,7 @@ Image::bytes_per_pixel (int c) const * @param p Pixel format. * @param s Size in pixels. */ -SimpleImage::SimpleImage (AVPixelFormat p, Size s, bool aligned) +SimpleImage::SimpleImage (AVPixelFormat p, libdcp::Size s, bool aligned) : Image (p) , _size (s) , _aligned (aligned) @@ -466,7 +466,7 @@ SimpleImage::stride () const return _stride; } -Size +libdcp::Size SimpleImage::size () const { return _size; @@ -503,10 +503,10 @@ FilterBufferImage::stride () const return _buffer->linesize; } -Size +libdcp::Size FilterBufferImage::size () const { - return Size (_buffer->video->w, _buffer->video->h); + return libdcp::Size (_buffer->video->w, _buffer->video->h); } RGBPlusAlphaImage::RGBPlusAlphaImage (shared_ptr im) diff --git a/src/lib/image.h b/src/lib/image.h index e19c6f54b..adee8bc4d 100644 --- a/src/lib/image.h +++ b/src/lib/image.h @@ -65,14 +65,14 @@ public: /** @return Array of strides for each line (including any alignment padding bytes) */ virtual int * stride () const = 0; - /** @return Size of the image, in pixels */ - virtual Size size () const = 0; + /** @return libdcp::Size of the image, in pixels */ + virtual libdcp::Size size () const = 0; int components () const; int lines (int) const; - boost::shared_ptr scale_and_convert_to_rgb (Size out_size, int padding, Scaler const * scaler, bool aligned) const; - boost::shared_ptr scale (Size, Scaler const *, bool aligned) const; + boost::shared_ptr scale_and_convert_to_rgb (libdcp::Size out_size, int padding, Scaler const * scaler, bool aligned) const; + boost::shared_ptr scale (libdcp::Size, Scaler const *, bool aligned) const; boost::shared_ptr post_process (std::string, bool aligned) const; void alpha_blend (boost::shared_ptr image, Position pos); boost::shared_ptr crop (Crop c, bool aligned) const; @@ -106,7 +106,7 @@ public: uint8_t ** data () const; int * line_size () const; int * stride () const; - Size size () const; + libdcp::Size size () const; private: /* Not allowed */ @@ -122,7 +122,7 @@ private: class SimpleImage : public Image { public: - SimpleImage (AVPixelFormat, Size, bool); + SimpleImage (AVPixelFormat, libdcp::Size, bool); SimpleImage (SimpleImage const &); SimpleImage& operator= (SimpleImage const &); ~SimpleImage (); @@ -130,14 +130,14 @@ public: uint8_t ** data () const; int * line_size () const; int * stride () const; - Size size () const; + libdcp::Size size () const; protected: void allocate (); void swap (SimpleImage &); private: - Size _size; ///< size in pixels + libdcp::Size _size; ///< size in pixels uint8_t** _data; ///< array of pointers to components int* _line_size; ///< array of sizes of the data in each line, in pixels (without any alignment padding bytes) int* _stride; ///< array of strides for each line (including any alignment padding bytes) diff --git a/src/lib/imagemagick_decoder.cc b/src/lib/imagemagick_decoder.cc index bad1fb813..5ebd6c8e1 100644 --- a/src/lib/imagemagick_decoder.cc +++ b/src/lib/imagemagick_decoder.cc @@ -50,7 +50,7 @@ ImageMagickDecoder::ImageMagickDecoder ( _iter = _files.begin (); } -Size +libdcp::Size ImageMagickDecoder::native_size () const { if (_files.empty ()) { @@ -60,7 +60,7 @@ ImageMagickDecoder::native_size () const /* Look at the first file and assume its size holds for all */ using namespace MagickCore; Magick::Image* image = new Magick::Image (_film->content_path ()); - Size const s = Size (image->columns(), image->rows()); + libdcp::Size const s = libdcp::Size (image->columns(), image->rows()); delete image; return s; @@ -80,7 +80,7 @@ ImageMagickDecoder::pass () Magick::Image* magick_image = new Magick::Image (_film->content_path ()); - Size size = native_size (); + libdcp::Size size = native_size (); shared_ptr image (new SimpleImage (PIX_FMT_RGB24, size, false)); using namespace MagickCore; diff --git a/src/lib/imagemagick_decoder.h b/src/lib/imagemagick_decoder.h index 6f426f308..c4795b003 100644 --- a/src/lib/imagemagick_decoder.h +++ b/src/lib/imagemagick_decoder.h @@ -33,7 +33,7 @@ public: return 0; } - Size native_size () const; + libdcp::Size native_size () const; SourceFrame length () const { /* We don't know */ diff --git a/src/lib/make_dcp_job.cc b/src/lib/make_dcp_job.cc index b9f0cacf3..705521626 100644 --- a/src/lib/make_dcp_job.cc +++ b/src/lib/make_dcp_job.cc @@ -59,9 +59,9 @@ MakeDCPJob::name () const /** @param f DCP frame index */ string -MakeDCPJob::j2c_path (int f, int offset) const +MakeDCPJob::j2c_path (int f) const { - SourceFrame const s = ((f + offset) * dcp_frame_rate(_film->frames_per_second()).skip) + _film->dcp_trim_start(); + SourceFrame const s = (f * dcp_frame_rate(_film->frames_per_second()).skip) + _film->dcp_trim_start(); return _opt->frame_out_path (s, false); } @@ -107,71 +107,45 @@ MakeDCPJob::run () dcp.add_cpl (cpl); - int frames_per_reel = 0; - if (_film->reel_size()) { - frames_per_reel = (_film->reel_size().get() / (_film->j2k_bandwidth() / 8)) * dfr.frames_per_second; - } else { - frames_per_reel = frames; - } - - int frames_done = 0; - int reel = 0; - - while (frames_done < frames) { - - descend (float (frames_per_reel) / frames); - - int this_time = std::min (frames_per_reel, (frames - frames_done)); - - descend (0.8); - - shared_ptr pa ( - new libdcp::MonoPictureAsset ( - boost::bind (&MakeDCPJob::j2c_path, this, _1, frames_done), + descend (0.8); + + shared_ptr pa ( + new libdcp::MonoPictureAsset ( + boost::bind (&MakeDCPJob::j2c_path, this, _1), + _film->dir (_film->dcp_name()), + "video.mxf", + &dcp.Progress, + dfr.frames_per_second, + frames, + _opt->out_size + ) + ); + + ascend (); + + shared_ptr sa; + + if (_film->audio_channels() > 0) { + descend (0.1); + sa.reset ( + new libdcp::SoundAsset ( + boost::bind (&MakeDCPJob::wav_path, this, _1), _film->dir (_film->dcp_name()), - String::compose ("video_%1.mxf", reel), + "audio.mxf", &dcp.Progress, dfr.frames_per_second, - this_time, - _opt->out_size.width, - _opt->out_size.height + frames, + dcp_audio_channels (_film->audio_channels()) ) ); - - ascend (); - - shared_ptr sa; - - if (_film->audio_channels() > 0) { - descend (0.1); - sa.reset ( - new libdcp::SoundAsset ( - boost::bind (&MakeDCPJob::wav_path, this, _1), - _film->dir (_film->dcp_name()), - String::compose ("audio_%1.mxf", reel), - &dcp.Progress, - dfr.frames_per_second, - this_time, - frames_done, - dcp_audio_channels (_film->audio_channels()) - ) - ); - ascend (); - } - - descend (0.1); - cpl->add_reel (shared_ptr (new libdcp::Reel (pa, sa, shared_ptr ()))); - ascend (); - - frames_done += frames_per_reel; - ++reel; - ascend (); } + descend (0.05); + cpl->add_reel (shared_ptr (new libdcp::Reel (pa, sa, shared_ptr ()))); ascend (); - - descend (0.1); + + descend (0.05); dcp.write_xml (); ascend (); diff --git a/src/lib/make_dcp_job.h b/src/lib/make_dcp_job.h index 5e4f78a25..1aa906b0a 100644 --- a/src/lib/make_dcp_job.h +++ b/src/lib/make_dcp_job.h @@ -38,7 +38,7 @@ public: private: void dcp_progress (float); - std::string j2c_path (int, int) const; + std::string j2c_path (int) const; std::string wav_path (libdcp::Channel) const; boost::shared_ptr _opt; diff --git a/src/lib/matcher.h b/src/lib/matcher.h index b94c28446..60bb87432 100644 --- a/src/lib/matcher.h +++ b/src/lib/matcher.h @@ -35,6 +35,6 @@ private: int _video_frames; int64_t _audio_frames; boost::optional _pixel_format; - boost::optional _size; + boost::optional _size; boost::optional _channels; }; diff --git a/src/lib/options.h b/src/lib/options.h index 55b066a2d..2f2f44b64 100644 --- a/src/lib/options.h +++ b/src/lib/options.h @@ -90,7 +90,7 @@ public: return s.str (); } - Size out_size; ///< size of output images + libdcp::Size out_size; ///< size of output images int padding; ///< number of pixels of padding (in terms of the output size) each side of the image /** Range of video frames to encode (in DCP frames) */ diff --git a/src/lib/server.cc b/src/lib/server.cc index bea75cff8..1bb8f205e 100644 --- a/src/lib/server.cc +++ b/src/lib/server.cc @@ -92,9 +92,9 @@ Server::process (shared_ptr socket) return -1; } - Size in_size (get_required_int (kv, "input_width"), get_required_int (kv, "input_height")); + libdcp::Size in_size (get_required_int (kv, "input_width"), get_required_int (kv, "input_height")); int pixel_format_int = get_required_int (kv, "input_pixel_format"); - Size out_size (get_required_int (kv, "output_width"), get_required_int (kv, "output_height")); + libdcp::Size out_size (get_required_int (kv, "output_width"), get_required_int (kv, "output_height")); int padding = get_required_int (kv, "padding"); int subtitle_offset = get_required_int (kv, "subtitle_offset"); float subtitle_scale = get_required_float (kv, "subtitle_scale"); @@ -105,7 +105,7 @@ Server::process (shared_ptr socket) int colour_lut_index = get_required_int (kv, "colour_lut"); int j2k_bandwidth = get_required_int (kv, "j2k_bandwidth"); Position subtitle_position (get_optional_int (kv, "subtitle_x"), get_optional_int (kv, "subtitle_y")); - Size subtitle_size (get_optional_int (kv, "subtitle_width"), get_optional_int (kv, "subtitle_height")); + libdcp::Size subtitle_size (get_optional_int (kv, "subtitle_width"), get_optional_int (kv, "subtitle_height")); /* This checks that colour_lut_index is within range */ colour_lut_index_to_name (colour_lut_index); diff --git a/src/lib/subtitle.cc b/src/lib/subtitle.cc index c52d3ac66..8a9998d6a 100644 --- a/src/lib/subtitle.cc +++ b/src/lib/subtitle.cc @@ -55,7 +55,7 @@ TimedSubtitle::TimedSubtitle (AVSubtitle const & sub) throw DecodeError ("non-bitmap subtitles not yet supported"); } - shared_ptr image (new SimpleImage (PIX_FMT_RGBA, Size (rect->w, rect->h), true)); + shared_ptr image (new SimpleImage (PIX_FMT_RGBA, libdcp::Size (rect->w, rect->h), true)); /* Start of the first line in the subtitle */ uint8_t* sub_p = rect->pict.data[0]; diff --git a/src/lib/util.cc b/src/lib/util.cc index 0fced638c..7f370b896 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -244,7 +244,7 @@ dvdomatic_setup () * @return FFmpeg crop filter string. */ string -crop_string (Position start, Size size) +crop_string (Position start, libdcp::Size size) { stringstream s; s << "crop=" << size.width << ":" << size.height << ":" << start.x << ":" << start.y; @@ -377,17 +377,6 @@ dcp_audio_channels (int f) return f; } - -bool operator== (Size const & a, Size const & b) -{ - return (a.width == b.width && a.height == b.height); -} - -bool operator!= (Size const & a, Size const & b) -{ - return !(a == b); -} - bool operator== (Crop const & a, Crop const & b) { return (a.left == b.left && a.right == b.right && a.top == b.top && a.bottom == b.bottom); diff --git a/src/lib/util.h b/src/lib/util.h index 024c40fb5..77fb943e0 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -29,6 +29,7 @@ #include #include #include +#include extern "C" { #include #include @@ -78,33 +79,6 @@ enum ContentType { VIDEO ///< content is a video }; -/** @class Size - * @brief Representation of the size of something */ -struct Size -{ - /** Construct a zero Size */ - Size () - : width (0) - , height (0) - {} - - /** @param w Width. - * @param h Height. - */ - Size (int w, int h) - : width (w) - , height (h) - {} - - /** width */ - int width; - /** height */ - int height; -}; - -extern bool operator== (Size const & a, Size const & b); -extern bool operator!= (Size const & a, Size const & b); - /** @struct Crop * @brief A description of the crop of an image or video. */ @@ -174,14 +148,14 @@ struct Rect return Position (x, y); } - Size size () const { - return Size (width, height); + libdcp::Size size () const { + return libdcp::Size (width, height); } Rect intersection (Rect const & other) const; }; -extern std::string crop_string (Position, Size); +extern std::string crop_string (Position, libdcp::Size); extern int dcp_audio_sample_rate (int); extern DCPFrameRate dcp_frame_rate (float); extern int dcp_audio_channels (int); diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h index 7726d2057..b18082c69 100644 --- a/src/lib/video_decoder.h +++ b/src/lib/video_decoder.h @@ -32,7 +32,7 @@ public: /** @return video frames per second, or 0 if unknown */ virtual float frames_per_second () const = 0; /** @return native size in pixels */ - virtual Size native_size () const = 0; + virtual libdcp::Size native_size () const = 0; /** @return length (in source video frames), according to our content's header */ virtual SourceFrame length () const = 0; diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 17c40c83d..72f2d4807 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -149,17 +149,6 @@ FilmEditor::make_film_panel () _film_sizer->Add (s); } - _multiple_reels = new wxCheckBox (_film_panel, wxID_ANY, wxT ("Make multiple reels")); - _film_sizer->Add (_multiple_reels); - - { - wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); - _reel_size = new wxSpinCtrl (_film_panel, wxID_ANY); - s->Add (_reel_size); - add_label_to_sizer (s, _film_panel, "Gb each"); - _film_sizer->Add (s); - } - _dcp_ab = new wxCheckBox (_film_panel, wxID_ANY, wxT ("A/B")); video_control (_dcp_ab); _film_sizer->Add (_dcp_ab, 1); @@ -180,8 +169,6 @@ FilmEditor::make_film_panel () for (vector::const_iterator i = ct.begin(); i != ct.end(); ++i) { _dcp_content_type->Append (std_to_wx ((*i)->pretty_name ())); } - - _reel_size->SetRange(1, 1000); } void @@ -204,8 +191,6 @@ FilmEditor::connect_to_widgets () _still_duration->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::still_duration_changed), 0, this); _dcp_trim_start->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::dcp_trim_start_changed), 0, this); _dcp_trim_end->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::dcp_trim_end_changed), 0, this); - _multiple_reels->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::multiple_reels_toggled), 0, this); - _reel_size->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::reel_size_changed), 0, this); _with_subtitles->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::with_subtitles_toggled), 0, this); _subtitle_offset->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::subtitle_offset_changed), 0, this); _subtitle_scale->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::subtitle_scale_changed), 0, this); @@ -478,32 +463,6 @@ FilmEditor::trust_content_header_changed (wxCommandEvent &) _film->set_trust_content_header (_trust_content_header->GetValue ()); } -void -FilmEditor::multiple_reels_toggled (wxCommandEvent &) -{ - if (!_film) { - return; - } - - if (_multiple_reels->GetValue()) { - _film->set_reel_size (_reel_size->GetValue() * 1e9); - } else { - _film->unset_reel_size (); - } - - setup_reel_control_sensitivity (); -} - -void -FilmEditor::reel_size_changed (wxCommandEvent &) -{ - if (!_film) { - return; - } - - _film->set_reel_size (static_cast (_reel_size->GetValue()) * 1e9); -} - /** Called when the DCP A/B switch has been toggled */ void FilmEditor::dcp_ab_toggled (wxCommandEvent &) @@ -681,15 +640,6 @@ FilmEditor::film_changed (Film::Property p) case Film::DCP_TRIM_END: checked_set (_dcp_trim_end, _film->dcp_trim_end()); break; - case Film::REEL_SIZE: - if (_film->reel_size()) { - checked_set (_multiple_reels, true); - checked_set (_reel_size, _film->reel_size().get() / 1e9); - } else { - checked_set (_multiple_reels, false); - } - setup_reel_control_sensitivity (); - break; case Film::AUDIO_GAIN: checked_set (_audio_gain, _film->audio_gain ()); break; @@ -813,7 +763,6 @@ FilmEditor::set_film (shared_ptr f) film_changed (Film::SCALER); film_changed (Film::DCP_TRIM_START); film_changed (Film::DCP_TRIM_END); - film_changed (Film::REEL_SIZE); film_changed (Film::DCP_AB); film_changed (Film::CONTENT_AUDIO_STREAM); film_changed (Film::EXTERNAL_AUDIO); @@ -858,8 +807,6 @@ FilmEditor::set_things_sensitive (bool s) _dcp_content_type->Enable (s); _dcp_trim_start->Enable (s); _dcp_trim_end->Enable (s); - _multiple_reels->Enable (s); - _reel_size->Enable (s); _dcp_ab->Enable (s); _colour_lut->Enable (s); _j2k_bandwidth->Enable (s); @@ -870,7 +817,6 @@ FilmEditor::set_things_sensitive (bool s) setup_subtitle_control_sensitivity (); setup_audio_control_sensitivity (); - setup_reel_control_sensitivity (); } /** Called when the `Edit filters' button has been clicked */ @@ -1211,9 +1157,3 @@ FilmEditor::external_audio_changed (wxCommandEvent &) _film->set_external_audio (a); } - -void -FilmEditor::setup_reel_control_sensitivity () -{ - _reel_size->Enable (_multiple_reels->GetValue ()); -} diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index 34e67eef1..8a900f1e4 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -65,8 +65,6 @@ private: void format_changed (wxCommandEvent &); void dcp_trim_start_changed (wxCommandEvent &); void dcp_trim_end_changed (wxCommandEvent &); - void multiple_reels_toggled (wxCommandEvent &); - void reel_size_changed (wxCommandEvent &); void dcp_content_type_changed (wxCommandEvent &); void dcp_ab_toggled (wxCommandEvent &); void scaler_changed (wxCommandEvent &); @@ -94,7 +92,6 @@ private: void setup_formats (); void setup_subtitle_control_sensitivity (); void setup_audio_control_sensitivity (); - void setup_reel_control_sensitivity (); void setup_streams (); void setup_audio_details (); @@ -170,8 +167,6 @@ private: wxSpinCtrl* _dcp_trim_start; wxSpinCtrl* _dcp_trim_end; - wxCheckBox* _multiple_reels; - wxSpinCtrl* _reel_size; /** Selector to generate an A/B comparison DCP */ wxCheckBox* _dcp_ab; diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 3d8198457..e014a8731 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -257,13 +257,13 @@ FilmViewer::raw_to_display () return; } - Size old_size; + libdcp::Size old_size; if (_display_frame) { old_size = _display_frame->size(); } /* Get a compacted image as we have to feed it to wxWidgets */ - _display_frame = _raw_frame->scale_and_convert_to_rgb (Size (_out_width, _out_height), 0, _film->scaler(), false); + _display_frame = _raw_frame->scale_and_convert_to_rgb (libdcp::Size (_out_width, _out_height), 0, _film->scaler(), false); if (old_size != _display_frame->size()) { _clear_required = true; diff --git a/src/wx/film_viewer.h b/src/wx/film_viewer.h index 6029c04f3..c6b5e7c0c 100644 --- a/src/wx/film_viewer.h +++ b/src/wx/film_viewer.h @@ -59,7 +59,7 @@ private: boost::shared_ptr _film; - wxBoxSizer* _v_sizer; + wxSizer* _v_sizer; wxPanel* _panel; wxSlider* _slider; wxToggleButton* _play_button; diff --git a/test/test.cc b/test/test.cc index c393aac5e..5f6d687ac 100644 --- a/test/test.cc +++ b/test/test.cc @@ -325,7 +325,7 @@ do_remote_encode (shared_ptr frame, ServerDescription* descriptio BOOST_AUTO_TEST_CASE (client_server_test) { - shared_ptr image (new SimpleImage (PIX_FMT_RGB24, Size (1998, 1080), false)); + shared_ptr image (new SimpleImage (PIX_FMT_RGB24, libdcp::Size (1998, 1080), false)); uint8_t* p = image->data()[0]; for (int y = 0; y < 1080; ++y) { @@ -336,7 +336,7 @@ BOOST_AUTO_TEST_CASE (client_server_test) } } - shared_ptr sub_image (new SimpleImage (PIX_FMT_RGBA, Size (100, 200), false)); + shared_ptr sub_image (new SimpleImage (PIX_FMT_RGBA, libdcp::Size (100, 200), false)); p = sub_image->data()[0]; for (int y = 0; y < 200; ++y) { for (int x = 0; x < 100; ++x) { @@ -355,7 +355,7 @@ BOOST_AUTO_TEST_CASE (client_server_test) new DCPVideoFrame ( image, subtitle, - Size (1998, 1080), + libdcp::Size (1998, 1080), 0, 0, 1, @@ -531,7 +531,7 @@ BOOST_AUTO_TEST_CASE (job_manager_test) BOOST_AUTO_TEST_CASE (compact_image_test) { - SimpleImage* s = new SimpleImage (PIX_FMT_RGB24, Size (50, 50), false); + SimpleImage* s = new SimpleImage (PIX_FMT_RGB24, libdcp::Size (50, 50), false); BOOST_CHECK_EQUAL (s->components(), 1); BOOST_CHECK_EQUAL (s->stride()[0], 50 * 3); BOOST_CHECK_EQUAL (s->line_size()[0], 50 * 3); @@ -557,7 +557,7 @@ BOOST_AUTO_TEST_CASE (compact_image_test) BOOST_CHECK (t->stride()[0] == s->stride()[0]); /* assignment operator */ - SimpleImage* u = new SimpleImage (PIX_FMT_YUV422P, Size (150, 150), true); + SimpleImage* u = new SimpleImage (PIX_FMT_YUV422P, libdcp::Size (150, 150), true); *u = *s; BOOST_CHECK_EQUAL (u->components(), 1); BOOST_CHECK_EQUAL (u->stride()[0], 50 * 3); @@ -580,7 +580,7 @@ BOOST_AUTO_TEST_CASE (compact_image_test) BOOST_AUTO_TEST_CASE (aligned_image_test) { - SimpleImage* s = new SimpleImage (PIX_FMT_RGB24, Size (50, 50), true); + SimpleImage* s = new SimpleImage (PIX_FMT_RGB24, libdcp::Size (50, 50), true); BOOST_CHECK_EQUAL (s->components(), 1); /* 160 is 150 aligned to the nearest 32 bytes */ BOOST_CHECK_EQUAL (s->stride()[0], 160); @@ -607,7 +607,7 @@ BOOST_AUTO_TEST_CASE (aligned_image_test) BOOST_CHECK (t->stride()[0] == s->stride()[0]); /* assignment operator */ - SimpleImage* u = new SimpleImage (PIX_FMT_YUV422P, Size (150, 150), false); + SimpleImage* u = new SimpleImage (PIX_FMT_YUV422P, libdcp::Size (150, 150), false); *u = *s; BOOST_CHECK_EQUAL (u->components(), 1); BOOST_CHECK_EQUAL (u->stride()[0], 160); -- cgit v1.2.3 From 0b760c0526b0b9d13def519ab8afba1e511d8111 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 23 Jan 2013 20:49:26 +0000 Subject: Try to fix up paths for video MXFs, hashes and temporarily-stored frames. --- .gitignore | 5 +- src/lib/check_hashes_job.cc | 120 -------------------------------------------- src/lib/check_hashes_job.h | 39 -------------- src/lib/dcp_video_frame.cc | 12 ++--- src/lib/encoder.cc | 26 ---------- src/lib/encoder.h | 6 +-- src/lib/film.cc | 90 ++++++++++++++++----------------- src/lib/film.h | 10 ++-- src/lib/transcode_job.cc | 5 -- src/lib/writer.cc | 6 +-- src/lib/wscript | 1 - 11 files changed, 61 insertions(+), 259 deletions(-) delete mode 100644 src/lib/check_hashes_job.cc delete mode 100644 src/lib/check_hashes_job.h (limited to 'src') diff --git a/.gitignore b/.gitignore index 4c0c1926d..cc3351558 100644 --- a/.gitignore +++ b/.gitignore @@ -17,4 +17,7 @@ doc/manual/pdf doc/manual/extensions.ent .be/id-cache *.pyc - +GPATH +GRTAGS +GSYMS +GTAGS diff --git a/src/lib/check_hashes_job.cc b/src/lib/check_hashes_job.cc deleted file mode 100644 index 55a744552..000000000 --- a/src/lib/check_hashes_job.cc +++ /dev/null @@ -1,120 +0,0 @@ -/* - Copyright (C) 2012 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include -#include -#include -#include "check_hashes_job.h" -#include "options.h" -#include "log.h" -#include "job_manager.h" -#include "ab_transcode_job.h" -#include "transcode_job.h" -#include "film.h" -#include "exceptions.h" - -using std::string; -using std::stringstream; -using std::ifstream; -using boost::shared_ptr; - -CheckHashesJob::CheckHashesJob (shared_ptr f, DecodeOptions o, shared_ptr req) - : Job (f, req) - , _decode_opt (o) - , _bad (0) -{ - -} - -string -CheckHashesJob::name () const -{ - return String::compose ("Check hashes of %1", _film->name()); -} - -void -CheckHashesJob::run () -{ - _bad = 0; - - if (!_film->dcp_intrinsic_duration()) { - throw EncodeError ("cannot check hashes of a DCP with unknown intrinsic duration"); - } - - int const N = _film->dcp_intrinsic_duration().get(); - for (int i = 0; i < N; ++i) { - string const j2k_file = _film->frame_out_path (i, false); - string const hash_file = _film->hash_out_path (i, false); - - if (!boost::filesystem::exists (j2k_file)) { - _film->log()->log (String::compose ("Frame %1 has a missing J2K file.", i)); - boost::filesystem::remove (hash_file); - ++_bad; - } else if (!boost::filesystem::exists (hash_file)) { - _film->log()->log (String::compose ("Frame %1 has a missing hash file.", i)); - boost::filesystem::remove (j2k_file); - ++_bad; - } else { - ifstream ref (hash_file.c_str ()); - string hash; - ref >> hash; - if (hash != md5_digest (j2k_file)) { - _film->log()->log (String::compose ("Frame %1 has wrong hash; deleting.", i)); - boost::filesystem::remove (j2k_file); - boost::filesystem::remove (hash_file); - ++_bad; - } - } - - set_progress (float (i) / N); - } - - if (_bad) { - shared_ptr tc; - - if (_film->dcp_ab()) { - tc.reset (new ABTranscodeJob (_film, _decode_opt, shared_from_this())); - } else { - tc.reset (new TranscodeJob (_film, _decode_opt, shared_from_this())); - } - - JobManager::instance()->add_after (shared_from_this(), tc); - JobManager::instance()->add_after (tc, shared_ptr (new CheckHashesJob (_film, _decode_opt, tc))); - } - - set_progress (1); - set_state (FINISHED_OK); -} - -string -CheckHashesJob::status () const -{ - stringstream s; - s << Job::status (); - if (overall_progress() > 0) { - if (_bad == 0) { - s << "; no bad frames found"; - } else if (_bad == 1) { - s << "; 1 bad frame found"; - } else { - s << "; " << _bad << " bad frames found"; - } - } - return s.str (); -} diff --git a/src/lib/check_hashes_job.h b/src/lib/check_hashes_job.h deleted file mode 100644 index 5fa17382d..000000000 --- a/src/lib/check_hashes_job.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright (C) 2012 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include "job.h" -#include "options.h" - -class CheckHashesJob : public Job -{ -public: - CheckHashesJob ( - boost::shared_ptr f, - DecodeOptions od, - boost::shared_ptr req - ); - - std::string name () const; - void run (); - std::string status () const; - -private: - DecodeOptions _decode_opt; - int _bad; -}; diff --git a/src/lib/dcp_video_frame.cc b/src/lib/dcp_video_frame.cc index c3f0fed03..5df2d7a46 100644 --- a/src/lib/dcp_video_frame.cc +++ b/src/lib/dcp_video_frame.cc @@ -407,27 +407,27 @@ EncodedData::~EncodedData () void EncodedData::write (shared_ptr film, int frame) const { - string const tmp_j2k = film->frame_out_path (frame, true); + string const tmp_j2c = film->j2c_path (frame, true); - FILE* f = fopen (tmp_j2k.c_str (), "wb"); + FILE* f = fopen (tmp_j2c.c_str (), "wb"); if (!f) { - throw WriteFileError (tmp_j2k, errno); + throw WriteFileError (tmp_j2c, errno); } fwrite (_data, 1, _size, f); fclose (f); - string const real_j2k = film->frame_out_path (frame, false); + string const real_j2c = film->j2c_path (frame, false); /* Rename the file from foo.j2c.tmp to foo.j2c now that it is complete */ - boost::filesystem::rename (tmp_j2k, real_j2k); + boost::filesystem::rename (tmp_j2c, real_j2c); } void EncodedData::write_hash (shared_ptr film, int frame) const { - string const hash = film->hash_out_path (frame, false); + string const hash = film->hash_path (frame); ofstream h (hash.c_str()); h << md5_digest (_data, _size) << "\n"; } diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 6b14b2698..978d787e8 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -55,7 +55,6 @@ int const Encoder::_history_size = 25; */ Encoder::Encoder (shared_ptr f) : _film (f) - , _just_skipped (false) , _video_frames_in (0) , _video_frames_out (0) #ifdef HAVE_SWRESAMPLE @@ -207,14 +206,6 @@ Encoder::current_frames_per_second () const return _history_size / (seconds (now) - seconds (_time_history.back ())); } -/** @return true if the last frame to be processed was skipped as it already existed */ -bool -Encoder::skipping () const -{ - boost::mutex::scoped_lock (_history_mutex); - return _just_skipped; -} - /** @return Number of video frames that have been sent out */ int Encoder::video_frames_out () const @@ -230,7 +221,6 @@ void Encoder::frame_done () { boost::mutex::scoped_lock lock (_history_mutex); - _just_skipped = false; struct timeval tv; gettimeofday (&tv, 0); @@ -240,16 +230,6 @@ Encoder::frame_done () } } -/** Called by a subclass when it has just skipped the processing - of a frame because it has already been done. -*/ -void -Encoder::frame_skipped () -{ - boost::mutex::scoped_lock lock (_history_mutex); - _just_skipped = true; -} - void Encoder::process_video (shared_ptr image, bool same, boost::shared_ptr sub) { @@ -273,12 +253,6 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptrframe_out_path (_video_frames_out, false))) { - frame_skipped (); - return; - } - if (same && _have_a_real_frame) { /* Use the last frame that we encoded. */ _writer->repeat (_video_frames_out); diff --git a/src/lib/encoder.h b/src/lib/encoder.h index 429b46a18..8b02f7004 100644 --- a/src/lib/encoder.h +++ b/src/lib/encoder.h @@ -82,13 +82,11 @@ public: virtual void process_end (); float current_frames_per_second () const; - bool skipping () const; int video_frames_out () const; private: void frame_done (); - void frame_skipped (); void write_audio (boost::shared_ptr audio); @@ -98,7 +96,7 @@ private: /** Film that we are encoding */ boost::shared_ptr _film; - /** Mutex for _time_history, _just_skipped and _last_frame */ + /** Mutex for _time_history and _last_frame */ mutable boost::mutex _history_mutex; /** List of the times of completion of the last _history_size frames; first is the most recently completed. @@ -106,8 +104,6 @@ private: std::list _time_history; /** Number of frames that we should keep history for */ static int const _history_size; - /** true if the last frame we processed was skipped (because it was already done) */ - bool _just_skipped; /** Number of video frames received so far */ SourceFrame _video_frames_in; diff --git a/src/lib/film.cc b/src/lib/film.cc index ae9edbfdb..dc308078c 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -46,7 +46,6 @@ #include "scaler.h" #include "decoder_factory.h" #include "config.h" -#include "check_hashes_job.h" #include "version.h" #include "ui_signaller.h" #include "video_decoder.h" @@ -194,24 +193,14 @@ Film::~Film () { delete _log; } - -/** @return The path to the directory to write JPEG2000 files to */ + string -Film::j2k_dir () const +Film::video_state_identifier () const { - assert (format()); - - boost::filesystem::path p; - - /* Start with j2c */ - p /= "j2c"; + assert (format ()); pair f = Filter::ffmpeg_strings (filters()); - /* Write stuff to specify the filter / post-processing settings that are in use, - so that we don't get confused about J2K files generated using different - settings. - */ stringstream s; s << format()->id() << "_" << content_digest() @@ -221,19 +210,33 @@ Film::j2k_dir () const << "_" << j2k_bandwidth() << "_" << boost::lexical_cast (colour_lut()); - p /= s.str (); - - /* Similarly for the A/B case */ if (dcp_ab()) { - stringstream s; pair fa = Filter::ffmpeg_strings (Config::instance()->reference_filters()); s << "ab_" << Config::instance()->reference_scaler()->id() << "_" << fa.first << "_" << fa.second; - p /= s.str (); } - + + return s.str (); +} + +/** @return The path to the directory to write video frame hash files to */ +string +Film::hash_dir () const +{ + boost::filesystem::path p; + p /= "hash"; + p /= video_state_identifier (); return dir (p.string()); } +string +Film::video_mxf_path () const +{ + boost::filesystem::path p; + p /= "video"; + p /= video_state_identifier (); + return file (p.string()); +} + /** Add suitable Jobs to the JobManager to create a DCP for this Film. * @param true to transcode, false to use the WAV and J2K files that are already there. */ @@ -302,8 +305,6 @@ Film::make_dcp (bool transcode) r = JobManager::instance()->add (shared_ptr (new TranscodeJob (shared_from_this(), od, shared_ptr ()))); } } - - // r = JobManager::instance()->add (shared_ptr (new CheckHashesJob (shared_from_this(), od, r))); } /** Start a job to examine our content file */ @@ -344,7 +345,7 @@ Film::encoded_frames () const } int N = 0; - for (boost::filesystem::directory_iterator i = boost::filesystem::directory_iterator (j2k_dir ()); i != boost::filesystem::directory_iterator(); ++i) { + for (boost::filesystem::directory_iterator i = boost::filesystem::directory_iterator (hash_dir ()); i != boost::filesystem::directory_iterator(); ++i) { ++N; boost::this_thread::interruption_point (); } @@ -1391,44 +1392,37 @@ Film::audio_stream () const return _external_audio_stream; } -/** @param f DCP frame index. - * @param t true to return a temporary file path, otherwise a permanent one. - * @return The path to write this video frame to. - */ string -Film::frame_out_path (int f, bool t) const +Film::hash_path (int f) const { + boost::filesystem::path p; + p /= hash_dir (); + stringstream s; - s << j2k_dir() << "/"; s.width (8); - s << std::setfill('0') << f << ".j2c"; + s << setfill('0') << f << ".md5"; - if (t) { - s << ".tmp"; - } - - return s.str (); + p /= s.str(); + return p.string (); } string -Film::hash_out_path (int f, bool t) const +Film::j2c_path (int f, bool t) const { - return frame_out_path (f, t) + ".md5"; -} + boost::filesystem::path p; + p /= "j2c"; + p /= video_state_identifier (); -/** @param c Audio channel index. - * @param t true to return a temporary file path, otherwise a permanent one. - * @return The path to write this audio file to. - */ -string -Film::multichannel_audio_out_path (int c, bool t) const -{ stringstream s; - s << dir ("wavs") << "/" << (c + 1) << ".wav"; + s.width (8); + s << setfill('0') << f << ".j2c"; + if (t) { s << ".tmp"; } - - return s.str (); + + p /= s.str(); + return p.string (); } + diff --git a/src/lib/film.h b/src/lib/film.h index 60646b0c8..4d2819be3 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -59,7 +59,10 @@ public: Film (Film const &); ~Film (); - std::string j2k_dir () const; + std::string hash_dir () const; + std::string j2c_path (int f, bool t) const; + std::string hash_path (int f) const; + std::string video_mxf_path () const; void examine_content (); void send_dcp_to_tms (); @@ -78,10 +81,6 @@ public: std::string file (std::string f) const; std::string dir (std::string d) const; - std::string frame_out_path (int f, bool t) const; - std::string hash_out_path (int f, bool t) const; - std::string multichannel_audio_out_path (int c, bool t) const; - std::string content_path () const; ContentType content_type () const; @@ -413,6 +412,7 @@ private: void signal_changed (Property); void examine_content_finished (); + std::string video_state_identifier () const; /** Complete path to directory containing the film metadata; * must not be relative. diff --git a/src/lib/transcode_job.cc b/src/lib/transcode_job.cc index 6dd74c36c..e9a59c743 100644 --- a/src/lib/transcode_job.cc +++ b/src/lib/transcode_job.cc @@ -89,11 +89,6 @@ TranscodeJob::status () const return "0%"; } - if (_encoder->skipping () && !finished ()) { - return "skipping already-encoded frames"; - } - - float const fps = _encoder->current_frames_per_second (); if (fps == 0) { return Job::status (); diff --git a/src/lib/writer.cc b/src/lib/writer.cc index a434db0ec..16ed5c349 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -42,7 +42,7 @@ Writer::Writer (shared_ptr f) _picture_asset.reset ( new libdcp::MonoPictureAsset ( _film->dir (_film->dcp_name()), - "video.mxf", + _film->video_mxf_path(), DCPFrameRate (_film->frames_per_second()).frames_per_second, _film->format()->dcp_size() ) @@ -164,9 +164,9 @@ Writer::thread () lock.unlock (); _film->log()->log (String::compose ("Writer pulls %1 back from disk", fetch)); shared_ptr encoded; - if (boost::filesystem::exists (_film->frame_out_path (fetch, false))) { + if (boost::filesystem::exists (_film->j2c_path (fetch, false))) { /* It's an actual frame (not a repeat-last); load it in */ - encoded.reset (new EncodedData (_film->frame_out_path (fetch, false))); + encoded.reset (new EncodedData (_film->j2c_path (fetch, false))); } lock.lock (); diff --git a/src/lib/wscript b/src/lib/wscript index 02c426373..5d676f249 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -14,7 +14,6 @@ def build(bld): ab_transcoder.cc audio_decoder.cc audio_source.cc - check_hashes_job.cc config.cc combiner.cc cross.cc -- cgit v1.2.3 From c1da77c1eac00998617cf3c50b6997251e8bd40e Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 24 Jan 2013 11:31:57 +0000 Subject: Fix lack of audio with trimmed DCPs. --- ChangeLog | 4 ++++ src/lib/encoder.cc | 1 + 2 files changed, 5 insertions(+) (limited to 'src') diff --git a/ChangeLog b/ChangeLog index 9d30cea9b..c60a09208 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-01-24 Carl Hetherington + + * Fix lack of audio with trimmed DCPs. + 2013-01-07 Carl Hetherington * Version 0.70 released. diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 693bd5bc8..f396e3cf2 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -350,6 +350,7 @@ Encoder::process_audio (shared_ptr data) if (this_range.second < required_range.first || required_range.second < this_range.first) { /* No part of this audio is within the required range */ + _audio_frame += data->frames(); return; } else if (required_range.first >= this_range.first && required_range.first < this_range.second) { /* Trim start */ -- cgit v1.2.3 From feea01f6109e00fddaacc9ae23f4cf6f55b4cabf Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 24 Jan 2013 15:15:16 +0000 Subject: Fix incorrect assert(). --- src/lib/subtitle.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/subtitle.cc b/src/lib/subtitle.cc index 8a9998d6a..b4ac14285 100644 --- a/src/lib/subtitle.cc +++ b/src/lib/subtitle.cc @@ -34,7 +34,7 @@ using namespace boost; */ TimedSubtitle::TimedSubtitle (AVSubtitle const & sub) { - assert (sub.rects > 0); + assert (sub.num_rects > 0); /* Subtitle PTS in seconds (within the source, not taking into account any of the source that we may have chopped off for the DCP) -- cgit v1.2.3 From cd21997cc5d7e6bc16c6c6e767e61cddfc7f6add Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 24 Jan 2013 20:00:12 +0000 Subject: Possibly-working basic DCP creation. --- src/lib/film.cc | 12 ++++++++---- src/lib/film.h | 3 ++- src/lib/writer.cc | 26 ++++++++++++++++++++++++-- 3 files changed, 34 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/lib/film.cc b/src/lib/film.cc index dc308078c..f6eb032fd 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -229,12 +229,16 @@ Film::hash_dir () const } string -Film::video_mxf_path () const +Film::video_mxf_dir () const { boost::filesystem::path p; - p /= "video"; - p /= video_state_identifier (); - return file (p.string()); + return dir ("video"); +} + +string +Film::video_mxf_filename () const +{ + return video_state_identifier() + ".mxf"; } /** Add suitable Jobs to the JobManager to create a DCP for this Film. diff --git a/src/lib/film.h b/src/lib/film.h index 4d2819be3..07764dac8 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -62,7 +62,8 @@ public: std::string hash_dir () const; std::string j2c_path (int f, bool t) const; std::string hash_path (int f) const; - std::string video_mxf_path () const; + std::string video_mxf_dir () const; + std::string video_mxf_filename () const; void examine_content (); void send_dcp_to_tms (); diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 16ed5c349..33a7f42af 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -39,10 +39,15 @@ Writer::Writer (shared_ptr f) , _finish (false) , _last_written_frame (-1) { + /* Create our picture asset in a subdirectory, named according to the + film's parameters which affect the video output. We will hard-link + it into the DCP later. + */ + _picture_asset.reset ( new libdcp::MonoPictureAsset ( - _film->dir (_film->dcp_name()), - _film->video_mxf_path(), + _film->video_mxf_dir (), + _film->video_mxf_filename (), DCPFrameRate (_film->frames_per_second()).frames_per_second, _film->format()->dcp_size() ) @@ -207,6 +212,23 @@ Writer::finish () _picture_asset->set_entry_point (_film->trim_start ()); _picture_asset->set_duration (duration); + /* Hard-link the video MXF into the DCP */ + + boost::filesystem::path from; + from /= _film->video_mxf_dir(); + from /= _film->video_mxf_filename(); + + boost::filesystem::path to; + to /= _film->dir (_film->dcp_name()); + to /= "video.mxf"; + + boost::filesystem::create_hard_link (from, to); + + /* And update the asset */ + + _picture_asset->set_directory (_film->dir (_film->dcp_name ())); + _picture_asset->set_file_name ("video.mxf"); + if (_sound_asset) { _sound_asset->set_entry_point (_film->trim_start ()); _sound_asset->set_duration (duration); -- cgit v1.2.3 From 494b6ee180e531358bab39e72f6123e90f9314e5 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 25 Jan 2013 01:21:17 +0000 Subject: Basics of checking video MXFs. --- src/lib/writer.cc | 40 ++++++++++++++++++++++++++++++++++++++++ src/lib/writer.h | 2 ++ 2 files changed, 42 insertions(+) (limited to 'src') diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 33a7f42af..3ec88860a 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -17,8 +17,10 @@ */ +#include #include #include +#include #include #include "writer.h" #include "compose.hpp" @@ -29,16 +31,22 @@ using std::make_pair; using std::pair; +using std::string; +using std::ifstream; +using std::cout; using boost::shared_ptr; unsigned int const Writer::_maximum_frames_in_memory = 8; Writer::Writer (shared_ptr f) : _film (f) + , _first_nonexistant_frame (0) , _thread (0) , _finish (false) , _last_written_frame (-1) { + check_existing_picture_mxf (); + /* Create our picture asset in a subdirectory, named according to the film's parameters which affect the video output. We will hard-link it into the DCP later. @@ -260,3 +268,35 @@ Writer::repeat (int f) boost::mutex::scoped_lock lock (_mutex); _queue.push_back (make_pair (shared_ptr (), f)); } + +void +Writer::check_existing_picture_mxf () +{ + boost::filesystem::path p; + p /= _film->video_mxf_dir (); + p /= _film->video_mxf_filename (); + if (!boost::filesystem::exists (p)) { + return; + } + + libdcp::MonoPictureAsset existing (_film->video_mxf_dir(), _film->video_mxf_filename()); + + while (_first_nonexistant_frame < existing.intrinsic_duration()) { + + shared_ptr f = existing.get_frame (_first_nonexistant_frame); + string const existing_hash = md5_digest (f->j2k_data(), f->j2k_size()); + + ifstream hf (_film->hash_path (_first_nonexistant_frame).c_str ()); + string reference_hash; + hf >> reference_hash; + + if (existing_hash != reference_hash) { + cout << "frame " << _first_nonexistant_frame << " failed hash check.\n"; + break; + } + + cout << "frame " << _first_nonexistant_frame << " ok.\n"; + ++_first_nonexistant_frame; + } +} + diff --git a/src/lib/writer.h b/src/lib/writer.h index 1aaea4d9d..768d63448 100644 --- a/src/lib/writer.h +++ b/src/lib/writer.h @@ -46,8 +46,10 @@ public: private: void thread (); + void check_existing_picture_mxf (); boost::shared_ptr _film; + int _first_nonexistant_frame; boost::thread* _thread; bool _finish; -- cgit v1.2.3 From 8657b4ad0776366f58fe4e7fba07bab78fa749a1 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 25 Jan 2013 12:48:47 +0000 Subject: Check for liblzma during configure (#7). --- src/lib/wscript | 2 +- wscript | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/wscript b/src/lib/wscript index b2b639f06..4d93a31aa 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -6,7 +6,7 @@ def build(bld): obj.name = 'libdvdomatic' obj.export_includes = ['.'] - obj.uselib = 'AVCODEC AVUTIL AVFORMAT AVFILTER SWSCALE SWRESAMPLE SNDFILE BOOST_FILESYSTEM BOOST_THREAD BOOST_DATETIME BOOST_SIGNALS2 OPENJPEG POSTPROC TIFF MAGICK SSH DCP GLIB' + obj.uselib = 'AVCODEC AVUTIL AVFORMAT AVFILTER SWSCALE SWRESAMPLE SNDFILE BOOST_FILESYSTEM BOOST_THREAD BOOST_DATETIME BOOST_SIGNALS2 OPENJPEG POSTPROC TIFF MAGICK SSH DCP GLIB LZMA' if bld.env.TARGET_WINDOWS: obj.uselib += ' WINSOCK2' obj.source = """ diff --git a/wscript b/wscript index 9acb61262..bf5cf1daa 100644 --- a/wscript +++ b/wscript @@ -89,6 +89,7 @@ def configure(conf): conf.check_cfg(package = 'sndfile', args = '--cflags --libs', uselib_store = 'SNDFILE', mandatory = True) conf.check_cfg(package = 'glib-2.0', args = '--cflags --libs', uselib_store = 'GLIB', mandatory = True) + conf.check_cfg(package = 'liblzma', args = '--cflags --libs', uselib_store = 'LZMA', mandatory = True) conf.check_cfg(package = '', path = 'Magick++-config', args = '--cppflags --cxxflags --libs', uselib_store = 'MAGICK', mandatory = True) if conf.options.static: -- cgit v1.2.3 From be1b34275e14d2584e233ac2a81d3dc44a97c208 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 25 Jan 2013 17:16:13 +0000 Subject: Make DCIMetadata class and use it. --- src/lib/dci_metadata.cc | 55 ++++++++++++++++++++ src/lib/dci_metadata.h | 40 +++++++++++++++ src/lib/film.cc | 127 ++++++++-------------------------------------- src/lib/film.h | 55 +++----------------- src/lib/wscript | 1 + src/wx/dci_name_dialog.cc | 76 ++++++++++----------------- src/wx/dci_name_dialog.h | 8 +-- 7 files changed, 152 insertions(+), 210 deletions(-) create mode 100644 src/lib/dci_metadata.cc create mode 100644 src/lib/dci_metadata.h (limited to 'src') diff --git a/src/lib/dci_metadata.cc b/src/lib/dci_metadata.cc new file mode 100644 index 000000000..2b4cc3ae7 --- /dev/null +++ b/src/lib/dci_metadata.cc @@ -0,0 +1,55 @@ +/* + Copyright (C) 2012 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include "dci_metadata.h" + +using namespace std; + +void +DCIMetadata::write (ostream& f) const +{ + f << "audio_language " << audio_language << "\n"; + f << "subtitle_language " << subtitle_language << "\n"; + f << "territory " << territory << "\n"; + f << "rating " << rating << "\n"; + f << "studio " << studio << "\n"; + f << "facility " << facility << "\n"; + f << "package_type " << package_type << "\n"; +} + +void +DCIMetadata::read (string k, string v) +{ + if (k == "audio_language") { + audio_language = v; + } else if (k == "subtitle_language") { + subtitle_language = v; + } else if (k == "territory") { + territory = v; + } else if (k == "rating") { + rating = v; + } else if (k == "studio") { + studio = v; + } else if (k == "facility") { + facility = v; + } else if (k == "package_type") { + package_type = v; + } +} diff --git a/src/lib/dci_metadata.h b/src/lib/dci_metadata.h new file mode 100644 index 000000000..eecdc7655 --- /dev/null +++ b/src/lib/dci_metadata.h @@ -0,0 +1,40 @@ +/* + Copyright (C) 2012 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef DVDOMATIC_DCI_METADATA_H +#define DVDOMATIC_DCI_METADATA_H + +#include + +class DCIMetadata +{ +public: + void read (std::string, std::string); + void write (std::ostream &) const; + + std::string audio_language; + std::string subtitle_language; + std::string territory; + std::string rating; + std::string studio; + std::string facility; + std::string package_type; +}; + +#endif diff --git a/src/lib/film.cc b/src/lib/film.cc index 5a11b0ca9..df89a2552 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -170,13 +170,7 @@ Film::Film (Film const & o) , _subtitle_scale (o._subtitle_scale) , _colour_lut (o._colour_lut) , _j2k_bandwidth (o._j2k_bandwidth) - , _audio_language (o._audio_language) - , _subtitle_language (o._subtitle_language) - , _territory (o._territory) - , _rating (o._rating) - , _studio (o._studio) - , _facility (o._facility) - , _package_type (o._package_type) + , _dci_metadata (o._dci_metadata) , _size (o._size) , _length (o._length) , _content_digest (o._content_digest) @@ -432,14 +426,7 @@ Film::write_metadata () const f << "subtitle_scale " << _subtitle_scale << "\n"; f << "colour_lut " << _colour_lut << "\n"; f << "j2k_bandwidth " << _j2k_bandwidth << "\n"; - f << "audio_language " << _audio_language << "\n"; - f << "subtitle_language " << _subtitle_language << "\n"; - f << "territory " << _territory << "\n"; - f << "rating " << _rating << "\n"; - f << "studio " << _studio << "\n"; - f << "facility " << _facility << "\n"; - f << "package_type " << _package_type << "\n"; - + _dci_metadata.write (f); f << "width " << _size.width << "\n"; f << "height " << _size.height << "\n"; f << "length " << _length.get_value_or(0) << "\n"; @@ -561,21 +548,9 @@ Film::read_metadata () _colour_lut = atoi (v.c_str ()); } else if (k == "j2k_bandwidth") { _j2k_bandwidth = atoi (v.c_str ()); - } else if (k == "audio_language") { - _audio_language = v; - } else if (k == "subtitle_language") { - _subtitle_language = v; - } else if (k == "territory") { - _territory = v; - } else if (k == "rating") { - _rating = v; - } else if (k == "studio") { - _studio = v; - } else if (k == "facility") { - _facility = v; - } else if (k == "package_type") { - _package_type = v; } + + _dci_metadata.read (k, v); /* Cached stuff */ if (k == "width") { @@ -752,10 +727,12 @@ Film::dci_name () const d << format()->dci_name() << "_"; } - if (!audio_language().empty ()) { - d << audio_language(); - if (!subtitle_language().empty() && with_subtitles()) { - d << "-" << subtitle_language(); + DCIMetadata const dm = dci_metadata (); + + if (!dm.audio_language.empty ()) { + d << dm.audio_language; + if (!dm.subtitle_language.empty() && with_subtitles()) { + d << "-" << dm.subtitle_language; } else { d << "-XX"; } @@ -763,10 +740,10 @@ Film::dci_name () const d << "_"; } - if (!territory().empty ()) { - d << territory(); - if (!rating().empty ()) { - d << "-" << rating(); + if (!dm.territory.empty ()) { + d << dm.territory; + if (!dm.rating.empty ()) { + d << "-" << dm.rating; } d << "_"; } @@ -788,18 +765,18 @@ Film::dci_name () const d << "2K_"; - if (!studio().empty ()) { - d << studio() << "_"; + if (!dm.studio.empty ()) { + d << dm.studio << "_"; } d << boost::gregorian::to_iso_string (_dci_date) << "_"; - if (!facility().empty ()) { - d << facility() << "_"; + if (!dm.facility.empty ()) { + d << dm.facility << "_"; } - if (!package_type().empty ()) { - d << package_type(); + if (!dm.package_type.empty ()) { + d << dm.package_type; } return d.str (); @@ -1227,71 +1204,11 @@ Film::set_j2k_bandwidth (int b) } void -Film::set_audio_language (string l) -{ - { - boost::mutex::scoped_lock lm (_state_mutex); - _audio_language = l; - } - signal_changed (DCI_METADATA); -} - -void -Film::set_subtitle_language (string l) -{ - { - boost::mutex::scoped_lock lm (_state_mutex); - _subtitle_language = l; - } - signal_changed (DCI_METADATA); -} - -void -Film::set_territory (string t) -{ - { - boost::mutex::scoped_lock lm (_state_mutex); - _territory = t; - } - signal_changed (DCI_METADATA); -} - -void -Film::set_rating (string r) -{ - { - boost::mutex::scoped_lock lm (_state_mutex); - _rating = r; - } - signal_changed (DCI_METADATA); -} - -void -Film::set_studio (string s) -{ - { - boost::mutex::scoped_lock lm (_state_mutex); - _studio = s; - } - signal_changed (DCI_METADATA); -} - -void -Film::set_facility (string f) -{ - { - boost::mutex::scoped_lock lm (_state_mutex); - _facility = f; - } - signal_changed (DCI_METADATA); -} - -void -Film::set_package_type (string p) +Film::set_dci_metadata (DCIMetadata m) { { boost::mutex::scoped_lock lm (_state_mutex); - _package_type = p; + _dci_metadata = m; } signal_changed (DCI_METADATA); } diff --git a/src/lib/film.h b/src/lib/film.h index d3530b817..af7ec6701 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -38,6 +38,7 @@ extern "C" { #include "dcp_content_type.h" #include "util.h" #include "stream.h" +#include "dci_metadata.h" class Format; class Job; @@ -265,41 +266,11 @@ public: return _j2k_bandwidth; } - std::string audio_language () const { + DCIMetadata dci_metadata () const { boost::mutex::scoped_lock lm (_state_mutex); - return _audio_language; + return _dci_metadata; } - std::string subtitle_language () const { - boost::mutex::scoped_lock lm (_state_mutex); - return _subtitle_language; - } - - std::string territory () const { - boost::mutex::scoped_lock lm (_state_mutex); - return _territory; - } - - std::string rating () const { - boost::mutex::scoped_lock lm (_state_mutex); - return _rating; - } - - std::string studio () const { - boost::mutex::scoped_lock lm (_state_mutex); - return _studio; - } - - std::string facility () const { - boost::mutex::scoped_lock lm (_state_mutex); - return _facility; - } - - std::string package_type () const { - boost::mutex::scoped_lock lm (_state_mutex); - return _package_type; - } - libdcp::Size size () const { boost::mutex::scoped_lock lm (_state_mutex); return _size; @@ -368,13 +339,7 @@ public: void set_subtitle_scale (float); void set_colour_lut (int); void set_j2k_bandwidth (int); - void set_audio_language (std::string); - void set_subtitle_language (std::string); - void set_territory (std::string); - void set_rating (std::string); - void set_studio (std::string); - void set_facility (std::string); - void set_package_type (std::string); + void set_dci_metadata (DCIMetadata); void set_size (libdcp::Size); void set_length (SourceFrame); void unset_length (); @@ -472,15 +437,9 @@ private: int _colour_lut; /** bandwidth for J2K files in bits per second */ int _j2k_bandwidth; - - /* DCI naming stuff */ - std::string _audio_language; - std::string _subtitle_language; - std::string _territory; - std::string _rating; - std::string _studio; - std::string _facility; - std::string _package_type; + + /** DCI naming stuff */ + DCIMetadata _dci_metadata; /* Data which are cached to speed things up */ diff --git a/src/lib/wscript b/src/lib/wscript index 4d93a31aa..cada2b0c3 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -18,6 +18,7 @@ def build(bld): config.cc combiner.cc cross.cc + dci_metadata.cc dcp_content_type.cc dcp_video_frame.cc decoder.cc diff --git a/src/wx/dci_name_dialog.cc b/src/wx/dci_name_dialog.cc index 6927d6c9e..41d93576f 100644 --- a/src/wx/dci_name_dialog.cc +++ b/src/wx/dci_name_dialog.cc @@ -59,21 +59,23 @@ DCINameDialog::DCINameDialog (wxWindow* parent, shared_ptr film) _package_type = new wxTextCtrl (this, wxID_ANY); table->Add (_package_type, 1, wxEXPAND); - _audio_language->SetValue (std_to_wx (_film->audio_language ())); - _subtitle_language->SetValue (std_to_wx (_film->subtitle_language ())); - _territory->SetValue (std_to_wx (_film->territory ())); - _rating->SetValue (std_to_wx (_film->rating ())); - _studio->SetValue (std_to_wx (_film->studio ())); - _facility->SetValue (std_to_wx (_film->facility ())); - _package_type->SetValue (std_to_wx (_film->package_type ())); + DCIMetadata dm = _film->dci_metadata (); + + _audio_language->SetValue (std_to_wx (dm.audio_language)); + _subtitle_language->SetValue (std_to_wx (dm.subtitle_language)); + _territory->SetValue (std_to_wx (dm.territory)); + _rating->SetValue (std_to_wx (dm.rating)); + _studio->SetValue (std_to_wx (dm.studio)); + _facility->SetValue (std_to_wx (dm.facility)); + _package_type->SetValue (std_to_wx (dm.package_type)); - _audio_language->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (DCINameDialog::audio_language_changed), 0, this); - _subtitle_language->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (DCINameDialog::subtitle_language_changed), 0, this); - _territory->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (DCINameDialog::territory_changed), 0, this); - _rating->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (DCINameDialog::rating_changed), 0, this); - _studio->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (DCINameDialog::studio_changed), 0, this); - _facility->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (DCINameDialog::facility_changed), 0, this); - _package_type->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (DCINameDialog::package_type_changed), 0, this); + _audio_language->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (DCINameDialog::changed), 0, this); + _subtitle_language->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (DCINameDialog::changed), 0, this); + _territory->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (DCINameDialog::changed), 0, this); + _rating->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (DCINameDialog::changed), 0, this); + _studio->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (DCINameDialog::changed), 0, this); + _facility->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (DCINameDialog::changed), 0, this); + _package_type->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (DCINameDialog::changed), 0, this); wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL); overall_sizer->Add (table, 1, wxEXPAND | wxALL, 6); @@ -89,43 +91,17 @@ DCINameDialog::DCINameDialog (wxWindow* parent, shared_ptr film) } void -DCINameDialog::audio_language_changed (wxCommandEvent &) +DCINameDialog::changed (wxCommandEvent &) { - _film->set_audio_language (wx_to_std (_audio_language->GetValue ())); -} - -void -DCINameDialog::subtitle_language_changed (wxCommandEvent &) -{ - _film->set_subtitle_language (wx_to_std (_subtitle_language->GetValue ())); -} - -void -DCINameDialog::territory_changed (wxCommandEvent &) -{ - _film->set_territory (wx_to_std (_territory->GetValue ())); -} - -void -DCINameDialog::rating_changed (wxCommandEvent &) -{ - _film->set_rating (wx_to_std (_rating->GetValue ())); -} + DCIMetadata dm; -void -DCINameDialog::studio_changed (wxCommandEvent &) -{ - _film->set_studio (wx_to_std (_studio->GetValue ())); -} + dm.audio_language = wx_to_std (_audio_language->GetValue ()); + dm.subtitle_language = wx_to_std (_subtitle_language->GetValue ()); + dm.territory = wx_to_std (_territory->GetValue ()); + dm.rating = wx_to_std (_rating->GetValue ()); + dm.studio = wx_to_std (_studio->GetValue ()); + dm.facility = wx_to_std (_facility->GetValue ()); + dm.package_type = wx_to_std (_package_type->GetValue ()); -void -DCINameDialog::facility_changed (wxCommandEvent &) -{ - _film->set_facility (wx_to_std (_facility->GetValue ())); -} - -void -DCINameDialog::package_type_changed (wxCommandEvent &) -{ - _film->set_package_type (wx_to_std (_package_type->GetValue ())); + _film->set_dci_metadata (dm); } diff --git a/src/wx/dci_name_dialog.h b/src/wx/dci_name_dialog.h index 1fd5436b8..dc96deed6 100644 --- a/src/wx/dci_name_dialog.h +++ b/src/wx/dci_name_dialog.h @@ -29,13 +29,7 @@ public: DCINameDialog (wxWindow *, boost::shared_ptr); private: - void audio_language_changed (wxCommandEvent &); - void subtitle_language_changed (wxCommandEvent &); - void territory_changed (wxCommandEvent &); - void rating_changed (wxCommandEvent &); - void studio_changed (wxCommandEvent &); - void facility_changed (wxCommandEvent &); - void package_type_changed (wxCommandEvent &); + void changed (wxCommandEvent &); wxTextCtrl* _audio_language; wxTextCtrl* _subtitle_language; -- cgit v1.2.3 From 57202d20733638d979fcc7976ed725ded23c5515 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 25 Jan 2013 17:20:05 +0000 Subject: Remove film-specifity of dci name dialog and rename its source file. --- src/wx/dci_metadata_dialog.cc | 96 +++++++++++++++++++++++++++++++++++++ src/wx/dci_metadata_dialog.h | 42 +++++++++++++++++ src/wx/dci_name_dialog.cc | 107 ------------------------------------------ src/wx/dci_name_dialog.h | 43 ----------------- src/wx/film_editor.cc | 5 +- src/wx/wscript | 2 +- 6 files changed, 142 insertions(+), 153 deletions(-) create mode 100644 src/wx/dci_metadata_dialog.cc create mode 100644 src/wx/dci_metadata_dialog.h delete mode 100644 src/wx/dci_name_dialog.cc delete mode 100644 src/wx/dci_name_dialog.h (limited to 'src') diff --git a/src/wx/dci_metadata_dialog.cc b/src/wx/dci_metadata_dialog.cc new file mode 100644 index 000000000..c5682e19e --- /dev/null +++ b/src/wx/dci_metadata_dialog.cc @@ -0,0 +1,96 @@ +/* + Copyright (C) 2012 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include "dci_metadata_dialog.h" +#include "wx_util.h" +#include "film.h" + +using boost::shared_ptr; + +DCIMetadataDialog::DCIMetadataDialog (wxWindow* parent, DCIMetadata dm) + : wxDialog (parent, wxID_ANY, _("DCI name"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) +{ + wxFlexGridSizer* table = new wxFlexGridSizer (2, 6, 6); + table->AddGrowableCol (1, 1); + + add_label_to_sizer (table, this, "Audio Language (e.g. EN)"); + _audio_language = new wxTextCtrl (this, wxID_ANY); + table->Add (_audio_language, 1, wxEXPAND); + + add_label_to_sizer (table, this, "Subtitle Language (e.g. FR)"); + _subtitle_language = new wxTextCtrl (this, wxID_ANY); + table->Add (_subtitle_language, 1, wxEXPAND); + + add_label_to_sizer (table, this, "Territory (e.g. UK)"); + _territory = new wxTextCtrl (this, wxID_ANY); + table->Add (_territory, 1, wxEXPAND); + + add_label_to_sizer (table, this, "Rating (e.g. 15)"); + _rating = new wxTextCtrl (this, wxID_ANY); + table->Add (_rating, 1, wxEXPAND); + + add_label_to_sizer (table, this, "Studio (e.g. TCF)"); + _studio = new wxTextCtrl (this, wxID_ANY); + table->Add (_studio, 1, wxEXPAND); + + add_label_to_sizer (table, this, "Facility (e.g. DLA)"); + _facility = new wxTextCtrl (this, wxID_ANY); + table->Add (_facility, 1, wxEXPAND); + + add_label_to_sizer (table, this, "Package Type (e.g. OV)"); + _package_type = new wxTextCtrl (this, wxID_ANY); + table->Add (_package_type, 1, wxEXPAND); + + _audio_language->SetValue (std_to_wx (dm.audio_language)); + _subtitle_language->SetValue (std_to_wx (dm.subtitle_language)); + _territory->SetValue (std_to_wx (dm.territory)); + _rating->SetValue (std_to_wx (dm.rating)); + _studio->SetValue (std_to_wx (dm.studio)); + _facility->SetValue (std_to_wx (dm.facility)); + _package_type->SetValue (std_to_wx (dm.package_type)); + + wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL); + overall_sizer->Add (table, 1, wxEXPAND | wxALL, 6); + + wxSizer* buttons = CreateSeparatedButtonSizer (wxOK); + if (buttons) { + overall_sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder()); + } + + SetSizer (overall_sizer); + overall_sizer->Layout (); + overall_sizer->SetSizeHints (this); +} + +DCIMetadata +DCIMetadataDialog::dci_metadata () const +{ + DCIMetadata dm; + + dm.audio_language = wx_to_std (_audio_language->GetValue ()); + dm.subtitle_language = wx_to_std (_subtitle_language->GetValue ()); + dm.territory = wx_to_std (_territory->GetValue ()); + dm.rating = wx_to_std (_rating->GetValue ()); + dm.studio = wx_to_std (_studio->GetValue ()); + dm.facility = wx_to_std (_facility->GetValue ()); + dm.package_type = wx_to_std (_package_type->GetValue ()); + + return dm; +} diff --git a/src/wx/dci_metadata_dialog.h b/src/wx/dci_metadata_dialog.h new file mode 100644 index 000000000..fbc5e3b86 --- /dev/null +++ b/src/wx/dci_metadata_dialog.h @@ -0,0 +1,42 @@ +/* + Copyright (C) 2012 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include +#include +#include "dci_metadata.h" + +class Film; + +class DCIMetadataDialog : public wxDialog +{ +public: + DCIMetadataDialog (wxWindow *, DCIMetadata); + + DCIMetadata dci_metadata () const; + +private: + wxTextCtrl* _audio_language; + wxTextCtrl* _subtitle_language; + wxTextCtrl* _territory; + wxTextCtrl* _rating; + wxTextCtrl* _studio; + wxTextCtrl* _facility; + wxTextCtrl* _package_type; +}; diff --git a/src/wx/dci_name_dialog.cc b/src/wx/dci_name_dialog.cc deleted file mode 100644 index 41d93576f..000000000 --- a/src/wx/dci_name_dialog.cc +++ /dev/null @@ -1,107 +0,0 @@ -/* - Copyright (C) 2012 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include -#include "dci_name_dialog.h" -#include "wx_util.h" -#include "film.h" - -using boost::shared_ptr; - -DCINameDialog::DCINameDialog (wxWindow* parent, shared_ptr film) - : wxDialog (parent, wxID_ANY, _("DCI name"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) - , _film (film) -{ - wxFlexGridSizer* table = new wxFlexGridSizer (2, 6, 6); - table->AddGrowableCol (1, 1); - - add_label_to_sizer (table, this, "Audio Language (e.g. EN)"); - _audio_language = new wxTextCtrl (this, wxID_ANY); - table->Add (_audio_language, 1, wxEXPAND); - - add_label_to_sizer (table, this, "Subtitle Language (e.g. FR)"); - _subtitle_language = new wxTextCtrl (this, wxID_ANY); - table->Add (_subtitle_language, 1, wxEXPAND); - - add_label_to_sizer (table, this, "Territory (e.g. UK)"); - _territory = new wxTextCtrl (this, wxID_ANY); - table->Add (_territory, 1, wxEXPAND); - - add_label_to_sizer (table, this, "Rating (e.g. 15)"); - _rating = new wxTextCtrl (this, wxID_ANY); - table->Add (_rating, 1, wxEXPAND); - - add_label_to_sizer (table, this, "Studio (e.g. TCF)"); - _studio = new wxTextCtrl (this, wxID_ANY); - table->Add (_studio, 1, wxEXPAND); - - add_label_to_sizer (table, this, "Facility (e.g. DLA)"); - _facility = new wxTextCtrl (this, wxID_ANY); - table->Add (_facility, 1, wxEXPAND); - - add_label_to_sizer (table, this, "Package Type (e.g. OV)"); - _package_type = new wxTextCtrl (this, wxID_ANY); - table->Add (_package_type, 1, wxEXPAND); - - DCIMetadata dm = _film->dci_metadata (); - - _audio_language->SetValue (std_to_wx (dm.audio_language)); - _subtitle_language->SetValue (std_to_wx (dm.subtitle_language)); - _territory->SetValue (std_to_wx (dm.territory)); - _rating->SetValue (std_to_wx (dm.rating)); - _studio->SetValue (std_to_wx (dm.studio)); - _facility->SetValue (std_to_wx (dm.facility)); - _package_type->SetValue (std_to_wx (dm.package_type)); - - _audio_language->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (DCINameDialog::changed), 0, this); - _subtitle_language->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (DCINameDialog::changed), 0, this); - _territory->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (DCINameDialog::changed), 0, this); - _rating->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (DCINameDialog::changed), 0, this); - _studio->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (DCINameDialog::changed), 0, this); - _facility->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (DCINameDialog::changed), 0, this); - _package_type->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (DCINameDialog::changed), 0, this); - - wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL); - overall_sizer->Add (table, 1, wxEXPAND | wxALL, 6); - - wxSizer* buttons = CreateSeparatedButtonSizer (wxOK); - if (buttons) { - overall_sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder()); - } - - SetSizer (overall_sizer); - overall_sizer->Layout (); - overall_sizer->SetSizeHints (this); -} - -void -DCINameDialog::changed (wxCommandEvent &) -{ - DCIMetadata dm; - - dm.audio_language = wx_to_std (_audio_language->GetValue ()); - dm.subtitle_language = wx_to_std (_subtitle_language->GetValue ()); - dm.territory = wx_to_std (_territory->GetValue ()); - dm.rating = wx_to_std (_rating->GetValue ()); - dm.studio = wx_to_std (_studio->GetValue ()); - dm.facility = wx_to_std (_facility->GetValue ()); - dm.package_type = wx_to_std (_package_type->GetValue ()); - - _film->set_dci_metadata (dm); -} diff --git a/src/wx/dci_name_dialog.h b/src/wx/dci_name_dialog.h deleted file mode 100644 index dc96deed6..000000000 --- a/src/wx/dci_name_dialog.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - Copyright (C) 2012 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include -#include -#include - -class Film; - -class DCINameDialog : public wxDialog -{ -public: - DCINameDialog (wxWindow *, boost::shared_ptr); - -private: - void changed (wxCommandEvent &); - - wxTextCtrl* _audio_language; - wxTextCtrl* _subtitle_language; - wxTextCtrl* _territory; - wxTextCtrl* _rating; - wxTextCtrl* _studio; - wxTextCtrl* _facility; - wxTextCtrl* _package_type; - - boost::shared_ptr _film; -}; diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 72f2d4807..aa32585df 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -43,7 +43,7 @@ #include "film_editor.h" #include "gain_calculator_dialog.h" #include "sound_processor.h" -#include "dci_name_dialog.h" +#include "dci_metadata_dialog.h" #include "scaler.h" using std::string; @@ -1056,8 +1056,9 @@ FilmEditor::edit_dci_button_clicked (wxCommandEvent &) return; } - DCINameDialog* d = new DCINameDialog (this, _film); + DCIMetadataDialog* d = new DCIMetadataDialog (this, _film->dci_metadata ()); d->ShowModal (); + _film->set_dci_metadata (d->dci_metadata ()); d->Destroy (); } diff --git a/src/wx/wscript b/src/wx/wscript index 4dbb04eea..47272f697 100644 --- a/src/wx/wscript +++ b/src/wx/wscript @@ -14,7 +14,7 @@ def build(bld): obj.use = 'libdvdomatic' obj.source = """ config_dialog.cc - dci_name_dialog.cc + dci_metadata_dialog.cc dir_picker_ctrl.cc film_editor.cc film_viewer.cc -- cgit v1.2.3 From 7101dd05ddcde66600bded064e28b491d79e3ebc Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 25 Jan 2013 19:29:50 +0000 Subject: Provide option of default DCI name details (#42). --- ChangeLog | 6 ++++++ src/lib/config.cc | 6 +++++- src/lib/config.h | 11 +++++++++++ src/lib/film.cc | 1 + src/wx/config_dialog.cc | 17 +++++++++++++++++ src/wx/config_dialog.h | 4 +++- 6 files changed, 43 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/ChangeLog b/ChangeLog index 73e7eb85f..96813f774 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2013-01-25 Carl Hetherington + + * Add option to specify default details + for the DCI name details dialog in new + Films (#42). + 2013-01-24 Carl Hetherington * Version 0.72 released. diff --git a/src/lib/config.cc b/src/lib/config.cc index 65d01bf00..c4659eecf 100644 --- a/src/lib/config.cc +++ b/src/lib/config.cc @@ -86,6 +86,8 @@ Config::Config () } else if (k == "sound_processor") { _sound_processor = SoundProcessor::from_id (v); } + + _default_dci_metadata.read (k, v); } } @@ -132,7 +134,9 @@ Config::write () const f << "tms_path " << _tms_path << "\n"; f << "tms_user " << _tms_user << "\n"; f << "tms_password " << _tms_password << "\n"; - f << "sound_processor " << _sound_processor->id (); + f << "sound_processor " << _sound_processor->id () << "\n"; + + _default_dci_metadata.write (f); } string diff --git a/src/lib/config.h b/src/lib/config.h index c84ce76b5..98cbf67e5 100644 --- a/src/lib/config.h +++ b/src/lib/config.h @@ -27,6 +27,7 @@ #include #include #include +#include "dci_metadata.h" class ServerDescription; class Scaler; @@ -94,6 +95,10 @@ public: return _sound_processor; } + DCIMetadata default_dci_metadata () const { + return _default_dci_metadata; + } + /** @param n New number of local encoding threads */ void set_num_local_encoding_threads (int n) { _num_local_encoding_threads = n; @@ -140,6 +145,10 @@ public: void set_tms_password (std::string p) { _tms_password = p; } + + void set_default_dci_metadata (DCIMetadata d) { + _default_dci_metadata = d; + } void write () const; @@ -172,6 +181,8 @@ private: std::string _tms_password; /** Our sound processor */ SoundProcessor const * _sound_processor; + /** Default DCI metadata for newly-created Films */ + DCIMetadata _default_dci_metadata; /** Singleton instance, or 0 */ static Config* _instance; diff --git a/src/lib/film.cc b/src/lib/film.cc index df89a2552..f5522b74a 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -101,6 +101,7 @@ Film::Film (string d, bool must_exist) , _subtitle_scale (1) , _colour_lut (0) , _j2k_bandwidth (200000000) + , _dci_metadata (Config::instance()->default_dci_metadata ()) , _frames_per_second (0) , _dirty (false) { diff --git a/src/wx/config_dialog.cc b/src/wx/config_dialog.cc index 9de8e7001..8886fa160 100644 --- a/src/wx/config_dialog.cc +++ b/src/wx/config_dialog.cc @@ -35,6 +35,7 @@ #include "filter_dialog.h" #include "server_dialog.h" #include "dir_picker_ctrl.h" +#include "dci_metadata_dialog.h" using namespace std; using boost::bind; @@ -79,6 +80,11 @@ ConfigDialog::ConfigDialog (wxWindow* parent) table->Add (_default_directory, 1, wxEXPAND); table->AddSpacer (0); + add_label_to_sizer (table, this, "Default DCI name details"); + _default_dci_metadata_button = new wxButton (this, wxID_ANY, _("Edit...")); + table->Add (_default_dci_metadata_button); + table->AddSpacer (1); + add_label_to_sizer (table, this, "Reference scaler for A/B"); _reference_scaler = new wxComboBox (this, wxID_ANY); vector const sc = Scaler::all (); @@ -142,6 +148,8 @@ ConfigDialog::ConfigDialog (wxWindow* parent) _default_directory->SetPath (std_to_wx (config->default_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())))); _default_directory->Connect (wxID_ANY, wxEVT_COMMAND_DIRPICKER_CHANGED, wxCommandEventHandler (ConfigDialog::default_directory_changed), 0, this); + _default_dci_metadata_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (ConfigDialog::edit_default_dci_metadata_clicked), 0, this); + _reference_scaler->SetSelection (Scaler::as_index (config->reference_scaler ())); _reference_scaler->Connect (wxID_ANY, wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler (ConfigDialog::reference_scaler_changed), 0, this); @@ -307,3 +315,12 @@ ConfigDialog::reference_filters_changed (vector f) pair p = Filter::ffmpeg_strings (Config::instance()->reference_filters ()); _reference_filters->SetLabel (std_to_wx (p.first + " " + p.second)); } + +void +ConfigDialog::edit_default_dci_metadata_clicked (wxCommandEvent &) +{ + DCIMetadataDialog* d = new DCIMetadataDialog (this, Config::instance()->default_dci_metadata ()); + d->ShowModal (); + Config::instance()->set_default_dci_metadata (d->dci_metadata ()); + d->Destroy (); +} diff --git a/src/wx/config_dialog.h b/src/wx/config_dialog.h index 32123a0d7..fdbe99a4c 100644 --- a/src/wx/config_dialog.h +++ b/src/wx/config_dialog.h @@ -45,6 +45,7 @@ private: void tms_password_changed (wxCommandEvent &); void num_local_encoding_threads_changed (wxCommandEvent &); void default_directory_changed (wxCommandEvent &); + void edit_default_dci_metadata_clicked (wxCommandEvent &); void reference_scaler_changed (wxCommandEvent &); void edit_reference_filters_clicked (wxCommandEvent &); void reference_filters_changed (std::vector); @@ -64,7 +65,8 @@ private: DirPickerCtrl* _default_directory; #else wxDirPickerCtrl* _default_directory; -#endif +#endif + wxButton* _default_dci_metadata_button; wxComboBox* _reference_scaler; wxStaticText* _reference_filters; wxButton* _reference_filters_button; -- cgit v1.2.3 From a7130995cf5f13396746932511ba133e8ad4ca9d Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 25 Jan 2013 19:55:37 +0000 Subject: Use wxChoice instead of wxComboBox throughout. Fixes dcp content type hanging over on new film. --- src/wx/config_dialog.cc | 2 +- src/wx/config_dialog.h | 2 +- src/wx/film_editor.cc | 16 ++++++++-------- src/wx/film_editor.h | 12 ++++++------ src/wx/wx_util.cc | 13 +++---------- src/wx/wx_util.h | 4 ++-- 6 files changed, 21 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/wx/config_dialog.cc b/src/wx/config_dialog.cc index 8886fa160..99527ffe7 100644 --- a/src/wx/config_dialog.cc +++ b/src/wx/config_dialog.cc @@ -86,7 +86,7 @@ ConfigDialog::ConfigDialog (wxWindow* parent) table->AddSpacer (1); add_label_to_sizer (table, this, "Reference scaler for A/B"); - _reference_scaler = new wxComboBox (this, wxID_ANY); + _reference_scaler = new wxChoice (this, wxID_ANY); vector const sc = Scaler::all (); for (vector::const_iterator i = sc.begin(); i != sc.end(); ++i) { _reference_scaler->Append (std_to_wx ((*i)->name ())); diff --git a/src/wx/config_dialog.h b/src/wx/config_dialog.h index fdbe99a4c..948bf0571 100644 --- a/src/wx/config_dialog.h +++ b/src/wx/config_dialog.h @@ -67,7 +67,7 @@ private: wxDirPickerCtrl* _default_directory; #endif wxButton* _default_dci_metadata_button; - wxComboBox* _reference_scaler; + wxChoice* _reference_scaler; wxStaticText* _reference_filters; wxButton* _reference_filters_button; wxListCtrl* _servers; diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index aa32585df..1e5765ae8 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -120,7 +120,7 @@ FilmEditor::make_film_panel () _film_sizer->AddSpacer (0); add_label_to_sizer (_film_sizer, _film_panel, "Content Type"); - _dcp_content_type = new wxComboBox (_film_panel, wxID_ANY, wxT (""), wxDefaultPosition, wxDefaultSize, 0, 0, wxCB_READONLY); + _dcp_content_type = new wxChoice (_film_panel, wxID_ANY); _film_sizer->Add (_dcp_content_type); video_control (add_label_to_sizer (_film_sizer, _film_panel, "Frames Per Second")); @@ -186,7 +186,7 @@ FilmEditor::connect_to_widgets () _bottom_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::bottom_crop_changed), 0, this); _filters_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::edit_filters_clicked), 0, this); _scaler->Connect (wxID_ANY, wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler (FilmEditor::scaler_changed), 0, this); - _dcp_content_type->Connect (wxID_ANY, wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler (FilmEditor::dcp_content_type_changed), 0, this); + _dcp_content_type->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::dcp_content_type_changed), 0, this); _dcp_ab->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::dcp_ab_toggled), 0, this); _still_duration->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::still_duration_changed), 0, this); _dcp_trim_start->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::dcp_trim_start_changed), 0, this); @@ -222,7 +222,7 @@ FilmEditor::make_video_panel () _video_panel->SetSizer (pad); add_label_to_sizer (_video_sizer, _video_panel, "Format"); - _format = new wxComboBox (_video_panel, wxID_ANY, wxT (""), wxDefaultPosition, wxDefaultSize, 0, 0, wxCB_READONLY); + _format = new wxChoice (_video_panel, wxID_ANY); _video_sizer->Add (_format); { @@ -259,7 +259,7 @@ FilmEditor::make_video_panel () } video_control (add_label_to_sizer (_video_sizer, _video_panel, "Scaler")); - _scaler = new wxComboBox (_video_panel, wxID_ANY, wxT (""), wxDefaultPosition, wxDefaultSize, 0, 0, wxCB_READONLY); + _scaler = new wxChoice (_video_panel, wxID_ANY); _video_sizer->Add (video_control (_scaler), 1); vector const sc = Scaler::all (); @@ -268,7 +268,7 @@ FilmEditor::make_video_panel () } add_label_to_sizer (_video_sizer, _video_panel, "Colour look-up table"); - _colour_lut = new wxComboBox (_video_panel, wxID_ANY); + _colour_lut = new wxChoice (_video_panel, wxID_ANY); for (int i = 0; i < 2; ++i) { _colour_lut->Append (std_to_wx (colour_lut_index_to_name (i))); } @@ -328,7 +328,7 @@ FilmEditor::make_audio_panel () _use_content_audio = new wxRadioButton (_audio_panel, wxID_ANY, _("Use content's audio"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP); _audio_sizer->Add (video_control (_use_content_audio)); wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); - _audio_stream = new wxComboBox (_audio_panel, wxID_ANY, wxT (""), wxDefaultPosition, wxDefaultSize, 0, 0, wxCB_READONLY); + _audio_stream = new wxChoice (_audio_panel, wxID_ANY); s->Add (video_control (_audio_stream), 1); _audio = new wxStaticText (_audio_panel, wxID_ANY, wxT ("")); s->Add (video_control (_audio), 1, wxALIGN_CENTER_VERTICAL | wxLEFT, 8); @@ -373,7 +373,7 @@ FilmEditor::make_subtitle_panel () video_control (_with_subtitles); _subtitle_sizer->Add (_with_subtitles, 1); - _subtitle_stream = new wxComboBox (_subtitle_panel, wxID_ANY, wxT (""), wxDefaultPosition, wxDefaultSize, 0, 0, wxCB_READONLY); + _subtitle_stream = new wxChoice (_subtitle_panel, wxID_ANY); _subtitle_sizer->Add (video_control (_subtitle_stream)); video_control (add_label_to_sizer (_subtitle_sizer, _subtitle_panel, "Subtitle Offset")); @@ -1085,7 +1085,7 @@ FilmEditor::setup_streams () if (_film->subtitle_stream()) { checked_set (_subtitle_stream, _film->subtitle_stream()->to_string()); } else { - _subtitle_stream->SetValue (wxT ("")); + _subtitle_stream->SetSelection (wxNOT_FOUND); } } diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index 8a900f1e4..581ae3f69 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -118,7 +118,7 @@ private: wxCheckBox* _use_dci_name; wxButton* _edit_dci_button; /** The Film's format */ - wxComboBox* _format; + wxChoice* _format; /** The Film's content file */ wxFilePickerCtrl* _content; wxCheckBox* _trust_content_header; @@ -135,9 +135,9 @@ private: /** Button to open the filters dialogue */ wxButton* _filters_button; /** The Film's scaler */ - wxComboBox* _scaler; + wxChoice* _scaler; wxRadioButton* _use_content_audio; - wxComboBox* _audio_stream; + wxChoice* _audio_stream; wxRadioButton* _use_external_audio; wxFilePickerCtrl* _external_audio[MAX_AUDIO_CHANNELS]; /** The Film's audio gain */ @@ -147,13 +147,13 @@ private: /** The Film's audio delay */ wxSpinCtrl* _audio_delay; wxCheckBox* _with_subtitles; - wxComboBox* _subtitle_stream; + wxChoice* _subtitle_stream; wxSpinCtrl* _subtitle_offset; wxSpinCtrl* _subtitle_scale; - wxComboBox* _colour_lut; + wxChoice* _colour_lut; wxSpinCtrl* _j2k_bandwidth; /** The Film's DCP content type */ - wxComboBox* _dcp_content_type; + wxChoice* _dcp_content_type; /** The Film's frames per second */ wxStaticText* _frames_per_second; /** The Film's original size */ diff --git a/src/wx/wx_util.cc b/src/wx/wx_util.cc index bc444e4bc..413071ea6 100644 --- a/src/wx/wx_util.cc +++ b/src/wx/wx_util.cc @@ -138,22 +138,15 @@ checked_set (wxSpinCtrl* widget, int value) } void -checked_set (wxComboBox* widget, int value) +checked_set (wxChoice* widget, int value) { if (widget->GetSelection() != value) { - if (value == wxNOT_FOUND) { - /* Work around an apparent wxWidgets bug; SetSelection (wxNOT_FOUND) - appears not to work sometimes. - */ - widget->SetValue (wxT ("")); - } else { - widget->SetSelection (value); - } + widget->SetSelection (value); } } void -checked_set (wxComboBox* widget, string value) +checked_set (wxChoice* widget, string value) { wxClientData* o = 0; if (widget->GetSelection() != -1) { diff --git a/src/wx/wx_util.h b/src/wx/wx_util.h index 6cb7fd002..0c77735eb 100644 --- a/src/wx/wx_util.h +++ b/src/wx/wx_util.h @@ -58,8 +58,8 @@ extern std::string string_client_data (wxClientData* o); extern void checked_set (wxFilePickerCtrl* widget, std::string value); extern void checked_set (wxSpinCtrl* widget, int value); -extern void checked_set (wxComboBox* widget, int value); -extern void checked_set (wxComboBox* widget, std::string value); +extern void checked_set (wxChoice* widget, int value); +extern void checked_set (wxChoice* widget, std::string value); extern void checked_set (wxTextCtrl* widget, std::string value); extern void checked_set (wxCheckBox* widget, bool value); extern void checked_set (wxRadioButton* widget, bool value); -- cgit v1.2.3 From 9e92f4742708e8b1516623647ee458211fdd68c1 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 25 Jan 2013 20:54:29 +0000 Subject: Fix signalling of wxChoices that used to be ComboBoxes. Use Size a little more. Show any padding of films into larger frames in the preview (#33). --- src/lib/format.cc | 9 +++++++ src/lib/format.h | 3 +++ src/wx/config_dialog.cc | 2 +- src/wx/film_editor.cc | 10 ++++---- src/wx/film_viewer.cc | 64 +++++++++++++++++++++++++++++++++---------------- src/wx/film_viewer.h | 11 +++++---- 6 files changed, 69 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/lib/format.cc b/src/lib/format.cc index 088a16059..6615e16e0 100644 --- a/src/lib/format.cc +++ b/src/lib/format.cc @@ -147,6 +147,9 @@ FixedFormat::FixedFormat (int r, libdcp::Size dcp, string id, string n, string d } +/** @return Number of pixels (int the DCP image) to pad either side of the film + * (so there are dcp_padding() pixels on the left and dcp_padding() on the right) + */ int Format::dcp_padding (shared_ptr f) const { @@ -160,6 +163,12 @@ Format::dcp_padding (shared_ptr f) const return p; } +float +Format::container_ratio_as_float () const +{ + return static_cast (_dcp_size.width) / _dcp_size.height; +} + VariableFormat::VariableFormat (libdcp::Size dcp, string id, string n, string d) : Format (dcp, id, n, d) { diff --git a/src/lib/format.h b/src/lib/format.h index b4c691e56..783ff25ce 100644 --- a/src/lib/format.h +++ b/src/lib/format.h @@ -46,6 +46,9 @@ public: /** @return the ratio as a floating point number */ virtual float ratio_as_float (boost::shared_ptr f) const = 0; + /** @return the ratio of the container (including any padding) as a floating point number */ + float container_ratio_as_float () const; + int dcp_padding (boost::shared_ptr f) const; /** @return size in pixels of the images that we should diff --git a/src/wx/config_dialog.cc b/src/wx/config_dialog.cc index 99527ffe7..b656a5278 100644 --- a/src/wx/config_dialog.cc +++ b/src/wx/config_dialog.cc @@ -151,7 +151,7 @@ ConfigDialog::ConfigDialog (wxWindow* parent) _default_dci_metadata_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (ConfigDialog::edit_default_dci_metadata_clicked), 0, this); _reference_scaler->SetSelection (Scaler::as_index (config->reference_scaler ())); - _reference_scaler->Connect (wxID_ANY, wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler (ConfigDialog::reference_scaler_changed), 0, this); + _reference_scaler->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (ConfigDialog::reference_scaler_changed), 0, this); pair p = Filter::ffmpeg_strings (config->reference_filters ()); _reference_filters->SetLabel (std_to_wx (p.first + " " + p.second)); diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 1e5765ae8..f058afa54 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -177,7 +177,7 @@ FilmEditor::connect_to_widgets () _name->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (FilmEditor::name_changed), 0, this); _use_dci_name->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::use_dci_name_toggled), 0, this); _edit_dci_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::edit_dci_button_clicked), 0, this); - _format->Connect (wxID_ANY, wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler (FilmEditor::format_changed), 0, this); + _format->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::format_changed), 0, this); _content->Connect (wxID_ANY, wxEVT_COMMAND_FILEPICKER_CHANGED, wxCommandEventHandler (FilmEditor::content_changed), 0, this); _trust_content_header->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::trust_content_header_changed), 0, this); _left_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::left_crop_changed), 0, this); @@ -185,7 +185,7 @@ FilmEditor::connect_to_widgets () _top_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::top_crop_changed), 0, this); _bottom_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::bottom_crop_changed), 0, this); _filters_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::edit_filters_clicked), 0, this); - _scaler->Connect (wxID_ANY, wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler (FilmEditor::scaler_changed), 0, this); + _scaler->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::scaler_changed), 0, this); _dcp_content_type->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::dcp_content_type_changed), 0, this); _dcp_ab->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::dcp_ab_toggled), 0, this); _still_duration->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::still_duration_changed), 0, this); @@ -194,10 +194,10 @@ FilmEditor::connect_to_widgets () _with_subtitles->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::with_subtitles_toggled), 0, this); _subtitle_offset->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::subtitle_offset_changed), 0, this); _subtitle_scale->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::subtitle_scale_changed), 0, this); - _colour_lut->Connect (wxID_ANY, wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler (FilmEditor::colour_lut_changed), 0, this); + _colour_lut->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::colour_lut_changed), 0, this); _j2k_bandwidth->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::j2k_bandwidth_changed), 0, this); - _subtitle_stream->Connect (wxID_ANY, wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler (FilmEditor::subtitle_stream_changed), 0, this); - _audio_stream->Connect (wxID_ANY, wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler (FilmEditor::audio_stream_changed), 0, this); + _subtitle_stream->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::subtitle_stream_changed), 0, this); + _audio_stream->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::audio_stream_changed), 0, this); _audio_gain->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::audio_gain_changed), 0, this); _audio_gain_calculate_button->Connect ( wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::audio_gain_calculate_button_clicked), 0, this diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index e014a8731..16b3ccd9a 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -50,11 +50,8 @@ FilmViewer::FilmViewer (shared_ptr f, wxWindow* p) , _panel (new wxPanel (this)) , _slider (new wxSlider (this, wxID_ANY, 0, 0, 4096)) , _play_button (new wxToggleButton (this, wxID_ANY, wxT ("Play"))) + , _display_frame_x (0) , _got_frame (false) - , _out_width (0) - , _out_height (0) - , _panel_width (0) - , _panel_height (0) , _clear_required (false) { _panel->SetDoubleBuffered (true); @@ -195,14 +192,21 @@ FilmViewer::paint_panel (wxPaintEvent &) _clear_required = false; } - if (!_display_frame || !_film || !_out_width || !_out_height) { + if (!_display_frame || !_film || !_out_size.width || !_out_size.height) { dc.Clear (); return; } - wxImage frame (_out_width, _out_height, _display_frame->data()[0], true); + if (_display_frame_x) { + dc.SetPen(*wxBLACK_PEN); + dc.SetBrush(*wxBLACK_BRUSH); + dc.DrawRectangle (0, 0, _display_frame_x, _film_size.height); + dc.DrawRectangle (_display_frame_x + _film_size.width, 0, _display_frame_x * 2 + _film_size.width, _film_size.height); + } + + wxImage frame (_film_size.width, _film_size.height, _display_frame->data()[0], true); wxBitmap frame_bitmap (frame); - dc.DrawBitmap (frame_bitmap, 0, 0); + dc.DrawBitmap (frame_bitmap, _display_frame_x, 0); if (_film->with_subtitles() && _display_sub) { wxImage sub (_display_sub->size().width, _display_sub->size().height, _display_sub->data()[0], _display_sub->alpha(), true); @@ -231,8 +235,8 @@ FilmViewer::slider_moved (wxScrollEvent &) void FilmViewer::panel_sized (wxSizeEvent& ev) { - _panel_width = ev.GetSize().GetWidth(); - _panel_height = ev.GetSize().GetHeight(); + _panel_size.width = ev.GetSize().GetWidth(); + _panel_size.height = ev.GetSize().GetHeight(); calculate_sizes (); update_from_raw (); } @@ -253,7 +257,7 @@ FilmViewer::update_from_raw () void FilmViewer::raw_to_display () { - if (!_raw_frame || _out_width < 64 || _out_height < 64 || !_film) { + if (!_raw_frame || _out_size.width < 64 || _out_size.height < 64 || !_film) { return; } @@ -263,7 +267,7 @@ FilmViewer::raw_to_display () } /* Get a compacted image as we have to feed it to wxWidgets */ - _display_frame = _raw_frame->scale_and_convert_to_rgb (libdcp::Size (_out_width, _out_height), 0, _film->scaler(), false); + _display_frame = _raw_frame->scale_and_convert_to_rgb (_film_size, 0, _film->scaler(), false); if (old_size != _display_frame->size()) { _clear_required = true; @@ -271,13 +275,14 @@ FilmViewer::raw_to_display () if (_raw_sub) { Rect tx = subtitle_transformed_area ( - float (_out_width) / _film->size().width, - float (_out_height) / _film->size().height, + float (_film_size.width) / _film->size().width, + float (_film_size.height) / _film->size().height, _raw_sub->area(), _film->subtitle_offset(), _film->subtitle_scale() ); _display_sub.reset (new RGBPlusAlphaImage (_raw_sub->image()->scale (tx.size(), _film->scaler(), false))); _display_sub_position = tx.position(); + _display_sub_position.x += _display_frame_x; } else { _display_sub.reset (); } @@ -289,17 +294,36 @@ FilmViewer::calculate_sizes () if (!_film) { return; } + + Format const * format = _film->format (); - float const panel_ratio = static_cast (_panel_width) / _panel_height; - float const film_ratio = _film->format() ? _film->format()->ratio_as_float(_film) : 1.78; + float const panel_ratio = static_cast (_panel_size.width) / _panel_size.height; + float const film_ratio = format ? format->container_ratio_as_float () : 1.78; + if (panel_ratio < film_ratio) { /* panel is less widscreen than the film; clamp width */ - _out_width = _panel_width; - _out_height = _out_width / film_ratio; + _out_size.width = _panel_size.width; + _out_size.height = _out_size.width / film_ratio; } else { - /* panel is more widescreen than the film; clamp heignt */ - _out_height = _panel_height; - _out_width = _out_height * film_ratio; + /* panel is more widescreen than the film; clamp height */ + _out_size.height = _panel_size.height; + _out_size.width = _out_size.height * film_ratio; + } + + /* Work out how much padding there is in terms of our display; this will be the x position + of our _display_frame. + */ + _display_frame_x = 0; + if (format) { + _display_frame_x = static_cast (format->dcp_padding (_film)) * _out_size.width / format->dcp_size().width; + } + + _film_size = _out_size; + _film_size.width -= _display_frame_x * 2; + + /* Catch silly values */ + if (_out_size.width < 64) { + _out_size.width = 64; } } diff --git a/src/wx/film_viewer.h b/src/wx/film_viewer.h index c6b5e7c0c..456301eb4 100644 --- a/src/wx/film_viewer.h +++ b/src/wx/film_viewer.h @@ -69,14 +69,17 @@ private: boost::shared_ptr _raw_frame; boost::shared_ptr _raw_sub; boost::shared_ptr _display_frame; + int _display_frame_x; boost::shared_ptr _display_sub; Position _display_sub_position; bool _got_frame; - int _out_width; - int _out_height; - int _panel_width; - int _panel_height; + /** Size of our output (including padding if we have any) */ + libdcp::Size _out_size; + /** Size that we will make our film (equal to _out_size unless we have padding) */ + libdcp::Size _film_size; + /** Size of the panel that we have available */ + libdcp::Size _panel_size; bool _clear_required; }; -- cgit v1.2.3 From 8e7d91ac8b945d66a65fc7b20249cd1c7796c7fa Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 28 Jan 2013 18:43:27 +0000 Subject: Write more extensive information about frames, and hash the MXF packet rather than the J2K data. --- src/lib/dcp_video_frame.cc | 8 ++++---- src/lib/dcp_video_frame.h | 3 ++- src/lib/film.cc | 12 ++++++------ src/lib/film.h | 4 ++-- src/lib/writer.cc | 36 +++++++++++++++++++++++------------- 5 files changed, 37 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/lib/dcp_video_frame.cc b/src/lib/dcp_video_frame.cc index 5df2d7a46..4f3fda44a 100644 --- a/src/lib/dcp_video_frame.cc +++ b/src/lib/dcp_video_frame.cc @@ -425,11 +425,11 @@ EncodedData::write (shared_ptr film, int frame) const } void -EncodedData::write_hash (shared_ptr film, int frame) const +EncodedData::write_info (shared_ptr film, int frame, libdcp::FrameInfo fin) const { - string const hash = film->hash_path (frame); - ofstream h (hash.c_str()); - h << md5_digest (_data, _size) << "\n"; + string const info = film->info_path (frame); + ofstream h (info.c_str()); + fin.write (h); } /** Send this data to a socket. diff --git a/src/lib/dcp_video_frame.h b/src/lib/dcp_video_frame.h index e988b663a..be8a559b2 100644 --- a/src/lib/dcp_video_frame.h +++ b/src/lib/dcp_video_frame.h @@ -19,6 +19,7 @@ */ #include +#include #include "util.h" /** @file src/dcp_video_frame.h @@ -48,7 +49,7 @@ public: void send (boost::shared_ptr socket); void write (boost::shared_ptr, int) const; - void write_hash (boost::shared_ptr, int) const; + void write_info (boost::shared_ptr, int, libdcp::FrameInfo) const; /** @return data */ uint8_t* data () const { diff --git a/src/lib/film.cc b/src/lib/film.cc index bdc4cca73..e7ea77023 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -213,12 +213,12 @@ Film::video_state_identifier () const return s.str (); } -/** @return The path to the directory to write video frame hash files to */ +/** @return The path to the directory to write video frame info files to */ string -Film::hash_dir () const +Film::info_dir () const { boost::filesystem::path p; - p /= "hash"; + p /= "info"; p /= video_state_identifier (); return dir (p.string()); } @@ -344,7 +344,7 @@ Film::encoded_frames () const } int N = 0; - for (boost::filesystem::directory_iterator i = boost::filesystem::directory_iterator (hash_dir ()); i != boost::filesystem::directory_iterator(); ++i) { + for (boost::filesystem::directory_iterator i = boost::filesystem::directory_iterator (info_dir ()); i != boost::filesystem::directory_iterator(); ++i) { ++N; boost::this_thread::interruption_point (); } @@ -1315,10 +1315,10 @@ Film::audio_stream () const } string -Film::hash_path (int f) const +Film::info_path (int f) const { boost::filesystem::path p; - p /= hash_dir (); + p /= info_dir (); stringstream s; s.width (8); diff --git a/src/lib/film.h b/src/lib/film.h index 7c4c72f7b..5b65a099d 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -60,9 +60,9 @@ public: Film (Film const &); ~Film (); - std::string hash_dir () const; + std::string info_dir () const; std::string j2c_path (int f, bool t) const; - std::string hash_path (int f) const; + std::string info_path (int f) const; std::string video_mxf_dir () const; std::string video_mxf_filename () const; diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 3ec88860a..7f338e238 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -136,12 +136,12 @@ Writer::thread () lock.unlock (); _film->log()->log (String::compose ("Writer writes %1 to MXF", encoded.second)); if (encoded.first) { - _picture_asset_writer->write (encoded.first->data(), encoded.first->size()); - encoded.first->write_hash (_film, encoded.second); + libdcp::FrameInfo const fin = _picture_asset_writer->write (encoded.first->data(), encoded.first->size()); + encoded.first->write_info (_film, encoded.second, fin); _last_written = encoded.first; } else { - _picture_asset_writer->write (_last_written->data(), _last_written->size()); - _last_written->write_hash (_film, encoded.second); + libdcp::FrameInfo const fin = _picture_asset_writer->write (_last_written->data(), _last_written->size()); + _last_written->write_info (_film, encoded.second, fin); } lock.lock (); @@ -279,18 +279,26 @@ Writer::check_existing_picture_mxf () return; } - libdcp::MonoPictureAsset existing (_film->video_mxf_dir(), _film->video_mxf_filename()); + /* Try to open the picture MXF */ + FILE* mxf = fopen (p.string().c_str(), "rb"); + if (!mxf) { + return; + } - while (_first_nonexistant_frame < existing.intrinsic_duration()) { + while (_first_nonexistant_frame < _film->dcp_intrinsic_duration ()) { - shared_ptr f = existing.get_frame (_first_nonexistant_frame); - string const existing_hash = md5_digest (f->j2k_data(), f->j2k_size()); - - ifstream hf (_film->hash_path (_first_nonexistant_frame).c_str ()); - string reference_hash; - hf >> reference_hash; + /* Read the frame info as written */ + ifstream ifi (_film->info_path (_first_nonexistant_frame).c_str()); + libdcp::FrameInfo info (ifi); - if (existing_hash != reference_hash) { + /* Read the data from the MXF and hash it */ + fseek (mxf, info.offset, SEEK_SET); + uint8_t* data = new uint8_t[info.length]; + fread (data, 1, info.length, mxf); + string const existing_hash = md5_digest (data, info.length); + delete[] data; + + if (existing_hash != info.hash) { cout << "frame " << _first_nonexistant_frame << " failed hash check.\n"; break; } @@ -298,5 +306,7 @@ Writer::check_existing_picture_mxf () cout << "frame " << _first_nonexistant_frame << " ok.\n"; ++_first_nonexistant_frame; } + + fclose (mxf); } -- cgit v1.2.3 From aeb20874df252fd8d36f5d3742ed8e34f2215367 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 2 Feb 2013 13:46:20 +0000 Subject: First try at doing fake writes. --- src/lib/encoder.cc | 5 +- src/lib/writer.cc | 161 ++++++++++++++++++++++++++++++++++------------------- src/lib/writer.h | 27 ++++++++- 3 files changed, 134 insertions(+), 59 deletions(-) (limited to 'src') diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 978d787e8..b92be84a8 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -253,7 +253,10 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptrcan_fake_write (_video_frames_out)) { + _writer->fake_write (_video_frames_out); + _have_a_real_frame = false; + } else if (same && _have_a_real_frame) { /* Use the last frame that we encoded. */ _writer->repeat (_video_frames_out); frame_done (); diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 7f338e238..a444efad8 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -47,7 +47,7 @@ Writer::Writer (shared_ptr f) { check_existing_picture_mxf (); - /* Create our picture asset in a subdirectory, named according to the + /* Create our picture asset in a subdirectory, named according to those film's parameters which affect the video output. We will hard-link it into the DCP later. */ @@ -60,8 +60,8 @@ Writer::Writer (shared_ptr f) _film->format()->dcp_size() ) ); - - _picture_asset_writer = _picture_asset->start_write (); + + _picture_asset_writer = _picture_asset->start_write (_first_nonexistant_frame > 0); if (_film->audio_channels() > 0) { _sound_asset.reset ( @@ -84,7 +84,30 @@ void Writer::write (shared_ptr encoded, int frame) { boost::mutex::scoped_lock lock (_mutex); - _queue.push_back (make_pair (encoded, frame)); + + QueueItem qi; + qi.type = QueueItem::FULL; + qi.encoded = encoded; + qi.frame = frame; + _queue.push_back (qi); + + _condition.notify_all (); +} + +void +Writer::fake_write (int frame) +{ + boost::mutex::scoped_lock lock (_mutex); + + ifstream ifi (_film->info_path (frame).c_str()); + libdcp::FrameInfo info (ifi); + + QueueItem qi; + qi.type = QueueItem::FAKE; + qi.size = info.size; + qi.frame = frame; + _queue.push_back (qi); + _condition.notify_all (); } @@ -95,13 +118,6 @@ Writer::write (shared_ptr audio) _sound_asset_writer->write (audio->data(), audio->frames()); } -struct QueueSorter -{ - bool operator() (pair, int> const & a, pair, int> const & b) { - return a.second < b.second; - } -}; - void Writer::thread () { @@ -112,7 +128,7 @@ Writer::thread () while (1) { if (_finish || _queue.size() > _maximum_frames_in_memory || - (!_queue.empty() && _queue.front().second == (_last_written_frame + 1))) { + (!_queue.empty() && _queue.front().frame == (_last_written_frame + 1))) { break; } @@ -121,7 +137,7 @@ Writer::thread () _condition.wait (lock); TIMING ("writer wakes with a queue of %1", _queue.size()); - _queue.sort (QueueSorter ()); + _queue.sort (); } if (_finish && _queue.empty() && _pending.empty()) { @@ -129,19 +145,32 @@ Writer::thread () } /* Write any frames that we can write; i.e. those that are in sequence */ - while (!_queue.empty() && _queue.front().second == (_last_written_frame + 1)) { - pair, int> encoded = _queue.front (); + while (!_queue.empty() && _queue.front().frame == (_last_written_frame + 1)) { + QueueItem qi = _queue.front (); _queue.pop_front (); lock.unlock (); - _film->log()->log (String::compose ("Writer writes %1 to MXF", encoded.second)); - if (encoded.first) { - libdcp::FrameInfo const fin = _picture_asset_writer->write (encoded.first->data(), encoded.first->size()); - encoded.first->write_info (_film, encoded.second, fin); - _last_written = encoded.first; - } else { + switch (qi.type) { + case QueueItem::FULL: + { + _film->log()->log (String::compose ("Writer FULL-writes %1 to MXF", qi.frame)); + libdcp::FrameInfo const fin = _picture_asset_writer->write (qi.encoded->data(), qi.encoded->size()); + qi.encoded->write_info (_film, qi.frame, fin); + _last_written = qi.encoded; + break; + } + case QueueItem::FAKE: + _film->log()->log (String::compose ("Writer FAKE-writes %1 to MXF", qi.frame)); + _picture_asset_writer->fake_write (qi.size); + _last_written.reset (); + break; + case QueueItem::REPEAT: + { + _film->log()->log (String::compose ("Writer REPEAT-writes %1 to MXF", qi.frame)); libdcp::FrameInfo const fin = _picture_asset_writer->write (_last_written->data(), _last_written->size()); - _last_written->write_info (_film, encoded.second, fin); + _last_written->write_info (_film, qi.frame, fin); + break; + } } lock.lock (); @@ -150,41 +179,39 @@ Writer::thread () while (_queue.size() > _maximum_frames_in_memory) { /* Too many frames in memory which can't yet be written to the stream. - Put some to disk. + Put some in our pending list (and write FULL queue items' data to disk) */ - pair, int> encoded = _queue.back (); + QueueItem qi = _queue.back (); _queue.pop_back (); - if (!encoded.first) { - /* This is a `repeat-last' frame, so no need to write it to disk */ - continue; - } - lock.unlock (); - _film->log()->log (String::compose ("Writer full (awaiting %1); pushes %2 to disk", _last_written_frame + 1, encoded.second)); - encoded.first->write (_film, encoded.second); - lock.lock (); + if (qi.type == QueueItem::FULL) { + lock.unlock (); + _film->log()->log (String::compose ("Writer full (awaiting %1); pushes %2 to disk", _last_written_frame + 1, qi.frame)); + qi.encoded->write (_film, qi.frame); + lock.lock (); + qi.encoded.reset (); + } - _pending.push_back (encoded.second); + _pending.push_back (qi); } while (_queue.size() < _maximum_frames_in_memory && !_pending.empty()) { /* We have some space in memory. Fetch some frames back off disk. */ _pending.sort (); - int const fetch = _pending.front (); - - lock.unlock (); - _film->log()->log (String::compose ("Writer pulls %1 back from disk", fetch)); - shared_ptr encoded; - if (boost::filesystem::exists (_film->j2c_path (fetch, false))) { - /* It's an actual frame (not a repeat-last); load it in */ - encoded.reset (new EncodedData (_film->j2c_path (fetch, false))); + QueueItem qi = _pending.front (); + + if (qi.type == QueueItem::FULL) { + lock.unlock (); + _film->log()->log (String::compose ("Writer pulls %1 back from disk", qi.frame)); + shared_ptr encoded; + qi.encoded.reset (new EncodedData (_film->j2c_path (qi.frame, false))); + lock.lock (); } - lock.lock (); - _queue.push_back (make_pair (encoded, fetch)); - _pending.remove (fetch); + _queue.push_back (qi); + _pending.remove (qi); } } @@ -266,20 +293,24 @@ void Writer::repeat (int f) { boost::mutex::scoped_lock lock (_mutex); - _queue.push_back (make_pair (shared_ptr (), f)); + + QueueItem qi; + qi.type = QueueItem::REPEAT; + qi.frame = f; + + _queue.push_back (qi); + + _condition.notify_all (); } + void Writer::check_existing_picture_mxf () { + /* Try to open the existing MXF */ boost::filesystem::path p; p /= _film->video_mxf_dir (); p /= _film->video_mxf_filename (); - if (!boost::filesystem::exists (p)) { - return; - } - - /* Try to open the picture MXF */ FILE* mxf = fopen (p.string().c_str(), "rb"); if (!mxf) { return; @@ -293,20 +324,38 @@ Writer::check_existing_picture_mxf () /* Read the data from the MXF and hash it */ fseek (mxf, info.offset, SEEK_SET); - uint8_t* data = new uint8_t[info.length]; - fread (data, 1, info.length, mxf); - string const existing_hash = md5_digest (data, info.length); - delete[] data; + EncodedData data (info.size); + fread (data.data(), 1, data.size(), mxf); + string const existing_hash = md5_digest (data.data(), data.size()); if (existing_hash != info.hash) { - cout << "frame " << _first_nonexistant_frame << " failed hash check.\n"; + _film->log()->log (String::compose ("Existing frame %1 failed hash check", _first_nonexistant_frame)); break; } - cout << "frame " << _first_nonexistant_frame << " ok.\n"; + _film->log()->log (String::compose ("Have existing frame %1", _first_nonexistant_frame)); ++_first_nonexistant_frame; } fclose (mxf); } +/** @return true if the fake write succeeded, otherwise false */ +bool +Writer::can_fake_write (int frame) const +{ + return (frame != 0 && frame < _first_nonexistant_frame); +} + + +bool +operator< (QueueItem const & a, QueueItem const & b) +{ + return a.frame < b.frame; +} + +bool +operator== (QueueItem const & a, QueueItem const & b) +{ + return a.frame == b.frame; +} diff --git a/src/lib/writer.h b/src/lib/writer.h index 768d63448..57609825d 100644 --- a/src/lib/writer.h +++ b/src/lib/writer.h @@ -33,12 +33,35 @@ namespace libdcp { class SoundAssetWriter; } +struct QueueItem +{ +public: + enum Type { + FULL, + FAKE, + REPEAT + } type; + + /** encoded data for FULL */ + boost::shared_ptr encoded; + /** size of data for FAKE */ + int size; + /** frame index */ + int frame; +}; + +bool operator< (QueueItem const & a, QueueItem const & b); +bool operator== (QueueItem const & a, QueueItem const & b); + class Writer { public: Writer (boost::shared_ptr); + + bool can_fake_write (int) const; void write (boost::shared_ptr, int); + void fake_write (int); void write (boost::shared_ptr); void repeat (int f); void finish (); @@ -53,11 +76,11 @@ private: boost::thread* _thread; bool _finish; - std::list, int> > _queue; + std::list _queue; mutable boost::mutex _mutex; boost::condition _condition; boost::shared_ptr _last_written; - std::list _pending; + std::list _pending; int _last_written_frame; static const unsigned int _maximum_frames_in_memory; -- cgit v1.2.3 From 8b4aa224882d2451f81c0a3ad07ec2d4ea098d5a Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 2 Feb 2013 14:16:12 +0000 Subject: Stop playback if there is a problem with decoding (#39). --- src/wx/film_viewer.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 7b8f02220..0b3fb0fd2 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -377,6 +377,8 @@ FilmViewer::get_frame () } } } catch (DecodeError& e) { + _play_button->SetValue (false); + check_play_state (); error_dialog (this, String::compose ("Could not decode video for view (%1)", e.what())); } } -- cgit v1.2.3 From 98bbaf1e907e927dbd26131cbdef243a82fdc2d1 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 2 Feb 2013 14:27:54 +0000 Subject: Only offer filters and postproc that exist. --- ChangeLog | 3 +++ src/lib/filter.cc | 68 ++++++++++++++++++++++++++++++++----------------- src/lib/filter.h | 1 + src/lib/filter_graph.cc | 2 -- src/lib/util.cc | 2 ++ 5 files changed, 50 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/ChangeLog b/ChangeLog index 8845dc78d..a6f3009a6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2013-02-02 Carl Hetherington + * Fix infinite loop of error messages when + `playing back' using a non-existant filter (#39). + * Encode data straight to MXFs, rather than going via .j2c files. Should roughly halve required disk space and reduce time diff --git a/src/lib/filter.cc b/src/lib/filter.cc index 446cc111d..c23882726 100644 --- a/src/lib/filter.cc +++ b/src/lib/filter.cc @@ -22,6 +22,10 @@ */ #include "filter.h" +extern "C" { +#include +#include +} using namespace std; @@ -57,30 +61,46 @@ Filter::setup_filters () { /* Note: "none" is a magic id name, so don't use it here */ - _filters.push_back (new Filter ("pphb", "Horizontal deblocking filter", "", "hb")); - _filters.push_back (new Filter ("ppvb", "Vertical deblocking filter", "", "vb")); - _filters.push_back (new Filter ("ppha", "Horizontal deblocking filter A", "", "ha")); - _filters.push_back (new Filter ("ppva", "Vertical deblocking filter A", "", "va")); - _filters.push_back (new Filter ("pph1", "Experimental horizontal deblocking filter 1", "", "h1")); - _filters.push_back (new Filter ("pphv", "Experimental vertical deblocking filter 1", "", "v1")); - _filters.push_back (new Filter ("ppdr", "Deringing filter", "", "dr")); - _filters.push_back (new Filter ("pplb", "Linear blend deinterlacer", "", "lb")); - _filters.push_back (new Filter ("ppli", "Linear interpolating deinterlacer", "", "li")); - _filters.push_back (new Filter ("ppci", "Cubic interpolating deinterlacer", "", "ci")); - _filters.push_back (new Filter ("ppmd", "Median deinterlacer", "", "md")); - _filters.push_back (new Filter ("ppfd", "FFMPEG deinterlacer", "", "fd")); - _filters.push_back (new Filter ("ppl5", "FIR low-pass deinterlacer", "", "l5")); - _filters.push_back (new Filter ("mcdeint", "Motion compensating deinterlacer", "mcdeint", "")); - _filters.push_back (new Filter ("kerndeint", "Kernel deinterlacer", "kerndeint", "")); - _filters.push_back (new Filter ("yadif", "Yet Another Deinterlacing Filter", "yadif", "")); - _filters.push_back (new Filter ("pptn", "Temporal noise reducer", "", "tn")); - _filters.push_back (new Filter ("ppfq", "Force quantizer", "", "fq")); - _filters.push_back (new Filter ("gradfun", "Gradient debander", "gradfun", "")); - _filters.push_back (new Filter ("unsharp", "Unsharp mask and Gaussian blur", "unsharp", "")); - _filters.push_back (new Filter ("denoise3d", "3D denoiser", "denoise3d", "")); - _filters.push_back (new Filter ("hqdn3d", "High quality 3D denoiser", "hqdn3d", "")); - _filters.push_back (new Filter ("telecine", "Telecine filter", "telecine", "")); - _filters.push_back (new Filter ("ow", "Overcomplete wavelet denoiser", "mp=ow", "")); + maybe_add ("pphb", "Horizontal deblocking filter", "", "hb"); + maybe_add ("ppvb", "Vertical deblocking filter", "", "vb"); + maybe_add ("ppha", "Horizontal deblocking filter A", "", "ha"); + maybe_add ("ppva", "Vertical deblocking filter A", "", "va"); + maybe_add ("pph1", "Experimental horizontal deblocking filter 1", "", "h1"); + maybe_add ("pphv", "Experimental vertical deblocking filter 1", "", "v1"); + maybe_add ("ppdr", "Deringing filter", "", "dr"); + maybe_add ("pplb", "Linear blend deinterlacer", "", "lb"); + maybe_add ("ppli", "Linear interpolating deinterlacer", "", "li"); + maybe_add ("ppci", "Cubic interpolating deinterlacer", "", "ci"); + maybe_add ("ppmd", "Median deinterlacer", "", "md"); + maybe_add ("ppfd", "FFMPEG deinterlacer", "", "fd"); + maybe_add ("ppl5", "FIR low-pass deinterlacer", "", "l5"); + maybe_add ("mcdeint", "Motion compensating deinterlacer", "mcdeint", ""); + maybe_add ("kerndeint", "Kernel deinterlacer", "kerndeint", ""); + maybe_add ("yadif", "Yet Another Deinterlacing Filter", "yadif", ""); + maybe_add ("pptn", "Temporal noise reducer", "", "tn"); + maybe_add ("ppfq", "Force quantizer", "", "fq"); + maybe_add ("gradfun", "Gradient debander", "gradfun", ""); + maybe_add ("unsharp", "Unsharp mask and Gaussian blur", "unsharp", ""); + maybe_add ("denoise3d", "3D denoiser", "denoise3d", ""); + maybe_add ("hqdn3d", "High quality 3D denoiser", "hqdn3d", ""); + maybe_add ("telecine", "Telecine filter", "telecine", ""); + maybe_add ("ow", "Overcomplete wavelet denoiser", "mp=ow", ""); +} + +void +Filter::maybe_add (string i, string n, string v, string p) +{ + if (!v.empty ()) { + if (avfilter_get_by_name (i.c_str())) { + _filters.push_back (new Filter (i, n, v, p)); + } + } else if (!p.empty ()) { + pp_mode* m = pp_get_mode_by_name_and_quality (p.c_str(), PP_QUALITY_MAX); + if (m) { + _filters.push_back (new Filter (i, n, v, p)); + pp_free_mode (m); + } + } } /** @param filters Set of filters. diff --git a/src/lib/filter.h b/src/lib/filter.h index 20c55049c..e7e8b389f 100644 --- a/src/lib/filter.h +++ b/src/lib/filter.h @@ -73,6 +73,7 @@ private: /** all available filters */ static std::vector _filters; + static void maybe_add (std::string, std::string, std::string, std::string); }; #endif diff --git a/src/lib/filter_graph.cc b/src/lib/filter_graph.cc index 3a13d93d0..b0991a2da 100644 --- a/src/lib/filter_graph.cc +++ b/src/lib/filter_graph.cc @@ -68,8 +68,6 @@ FilterGraph::FilterGraph (shared_ptr film, FFmpegDecoder* decoder, libdcp: filters += crop_string (Position (film->crop().left, film->crop().top), film->cropped_size (decoder->native_size())); - avfilter_register_all (); - AVFilterGraph* graph = avfilter_graph_alloc(); if (graph == 0) { throw DecodeError ("Could not create filter graph."); diff --git a/src/lib/util.cc b/src/lib/util.cc index 872985024..ce89d5355 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -233,6 +233,8 @@ seconds (struct timeval t) void dvdomatic_setup () { + avfilter_register_all (); + Format::setup_formats (); DCPContentType::setup_dcp_content_types (); Scaler::setup_scalers (); -- cgit v1.2.3 From de4d3d0fdda0f20ccab06877444fc1e5ff362f93 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 2 Feb 2013 14:49:02 +0000 Subject: Tidy up filters dialog; don't show non-existant ones, and categorise them. --- ChangeLog | 4 ++++ src/lib/filter.cc | 58 ++++++++++++++++++++++++++------------------------- src/lib/filter.h | 9 ++++++-- src/wx/filter_view.cc | 37 ++++++++++++++++++++++++++------ 4 files changed, 72 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/ChangeLog b/ChangeLog index a6f3009a6..fc623d7c5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2013-02-02 Carl Hetherington + * Tidy up filters dialog by not showing those + that are not configured in FFmpeg, and by splitting + them up into categories. + * Fix infinite loop of error messages when `playing back' using a non-existant filter (#39). diff --git a/src/lib/filter.cc b/src/lib/filter.cc index c23882726..9a662f90f 100644 --- a/src/lib/filter.cc +++ b/src/lib/filter.cc @@ -33,12 +33,14 @@ vector Filter::_filters; /** @param i Our id. * @param n User-visible name. + * @param c User-visible category. * @param v String for a FFmpeg video filter descriptor, or "". * @param p String for a FFmpeg post-processing descriptor, or "". */ -Filter::Filter (string i, string n, string v, string p) +Filter::Filter (string i, string n, string c, string v, string p) : _id (i) , _name (n) + , _category (c) , _vf (v) , _pp (p) { @@ -61,43 +63,43 @@ Filter::setup_filters () { /* Note: "none" is a magic id name, so don't use it here */ - maybe_add ("pphb", "Horizontal deblocking filter", "", "hb"); - maybe_add ("ppvb", "Vertical deblocking filter", "", "vb"); - maybe_add ("ppha", "Horizontal deblocking filter A", "", "ha"); - maybe_add ("ppva", "Vertical deblocking filter A", "", "va"); - maybe_add ("pph1", "Experimental horizontal deblocking filter 1", "", "h1"); - maybe_add ("pphv", "Experimental vertical deblocking filter 1", "", "v1"); - maybe_add ("ppdr", "Deringing filter", "", "dr"); - maybe_add ("pplb", "Linear blend deinterlacer", "", "lb"); - maybe_add ("ppli", "Linear interpolating deinterlacer", "", "li"); - maybe_add ("ppci", "Cubic interpolating deinterlacer", "", "ci"); - maybe_add ("ppmd", "Median deinterlacer", "", "md"); - maybe_add ("ppfd", "FFMPEG deinterlacer", "", "fd"); - maybe_add ("ppl5", "FIR low-pass deinterlacer", "", "l5"); - maybe_add ("mcdeint", "Motion compensating deinterlacer", "mcdeint", ""); - maybe_add ("kerndeint", "Kernel deinterlacer", "kerndeint", ""); - maybe_add ("yadif", "Yet Another Deinterlacing Filter", "yadif", ""); - maybe_add ("pptn", "Temporal noise reducer", "", "tn"); - maybe_add ("ppfq", "Force quantizer", "", "fq"); - maybe_add ("gradfun", "Gradient debander", "gradfun", ""); - maybe_add ("unsharp", "Unsharp mask and Gaussian blur", "unsharp", ""); - maybe_add ("denoise3d", "3D denoiser", "denoise3d", ""); - maybe_add ("hqdn3d", "High quality 3D denoiser", "hqdn3d", ""); - maybe_add ("telecine", "Telecine filter", "telecine", ""); - maybe_add ("ow", "Overcomplete wavelet denoiser", "mp=ow", ""); + maybe_add ("pphb", "Horizontal deblocking filter", "De-blocking", "", "hb"); + maybe_add ("ppvb", "Vertical deblocking filter", "De-blocking", "", "vb"); + maybe_add ("ppha", "Horizontal deblocking filter A", "De-blocking", "", "ha"); + maybe_add ("ppva", "Vertical deblocking filter A", "De-blocking", "", "va"); + maybe_add ("pph1", "Experimental horizontal deblocking filter 1", "De-blocking", "", "h1"); + maybe_add ("pphv", "Experimental vertical deblocking filter 1", "De-blocking", "", "v1"); + maybe_add ("ppdr", "Deringing filter", "Misc", "", "dr"); + maybe_add ("pplb", "Linear blend deinterlacer", "De-interlacing", "", "lb"); + maybe_add ("ppli", "Linear interpolating deinterlacer", "De-interlacing", "", "li"); + maybe_add ("ppci", "Cubic interpolating deinterlacer", "De-interlacing", "", "ci"); + maybe_add ("ppmd", "Median deinterlacer", "De-interlacing", "", "md"); + maybe_add ("ppfd", "FFMPEG deinterlacer", "De-interlacing", "", "fd"); + maybe_add ("ppl5", "FIR low-pass deinterlacer", "De-interlacing", "", "l5"); + maybe_add ("mcdeint", "Motion compensating deinterlacer", "De-interlacing", "mcdeint", ""); + maybe_add ("kerndeint", "Kernel deinterlacer", "De-interlacing", "kerndeint", ""); + maybe_add ("yadif", "Yet Another Deinterlacing Filter", "De-interlacing", "yadif", ""); + maybe_add ("pptn", "Temporal noise reducer", "Noise reduction", "", "tn"); + maybe_add ("ppfq", "Force quantizer", "Misc", "", "fq"); + maybe_add ("gradfun", "Gradient debander", "Misc", "gradfun", ""); + maybe_add ("unsharp", "Unsharp mask and Gaussian blur", "Misc", "unsharp", ""); + maybe_add ("denoise3d", "3D denoiser", "Noise reduction", "denoise3d", ""); + maybe_add ("hqdn3d", "High quality 3D denoiser", "Noise reduction", "hqdn3d", ""); + maybe_add ("telecine", "Telecine filter", "Misc", "telecine", ""); + maybe_add ("ow", "Overcomplete wavelet denoiser", "Noise reduction", "mp=ow", ""); } void -Filter::maybe_add (string i, string n, string v, string p) +Filter::maybe_add (string i, string n, string c, string v, string p) { if (!v.empty ()) { if (avfilter_get_by_name (i.c_str())) { - _filters.push_back (new Filter (i, n, v, p)); + _filters.push_back (new Filter (i, n, c, v, p)); } } else if (!p.empty ()) { pp_mode* m = pp_get_mode_by_name_and_quality (p.c_str(), PP_QUALITY_MAX); if (m) { - _filters.push_back (new Filter (i, n, v, p)); + _filters.push_back (new Filter (i, n, c, v, p)); pp_free_mode (m); } } diff --git a/src/lib/filter.h b/src/lib/filter.h index e7e8b389f..205d92482 100644 --- a/src/lib/filter.h +++ b/src/lib/filter.h @@ -33,7 +33,7 @@ class Filter { public: - Filter (std::string, std::string, std::string, std::string); + Filter (std::string, std::string, std::string, std::string, std::string); /** @return our id */ std::string id () const { @@ -54,6 +54,10 @@ public: std::string pp () const { return _pp; } + + std::string category () const { + return _category; + } static std::vector all (); static Filter const * from_id (std::string); @@ -66,6 +70,7 @@ private: std::string _id; /** user-visible name */ std::string _name; + std::string _category; /** string for a FFmpeg video filter descriptor */ std::string _vf; /** string for a FFmpeg post-processing descriptor */ @@ -73,7 +78,7 @@ private: /** all available filters */ static std::vector _filters; - static void maybe_add (std::string, std::string, std::string, std::string); + static void maybe_add (std::string, std::string, std::string, std::string, std::string); }; #endif diff --git a/src/wx/filter_view.cc b/src/wx/filter_view.cc index 8d9535d81..db6728ba5 100644 --- a/src/wx/filter_view.cc +++ b/src/wx/filter_view.cc @@ -37,13 +37,38 @@ FilterView::FilterView (wxWindow* parent, vector const & active) vector filters = Filter::all (); + typedef map > CategoryMap; + CategoryMap categories; + for (vector::iterator i = filters.begin(); i != filters.end(); ++i) { - wxCheckBox* b = new wxCheckBox (this, wxID_ANY, std_to_wx ((*i)->name ())); - bool const a = find (active.begin(), active.end(), *i) != active.end (); - b->SetValue (a); - _filters[*i] = b; - b->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilterView::filter_toggled), 0, this); - sizer->Add (b); + CategoryMap::iterator j = categories.find ((*i)->category ()); + if (j == categories.end ()) { + list c; + c.push_back (*i); + categories[(*i)->category()] = c; + } else { + j->second.push_back (*i); + } + } + + for (CategoryMap::iterator i = categories.begin(); i != categories.end(); ++i) { + + wxStaticText* c = new wxStaticText (this, wxID_ANY, std_to_wx (i->first)); + wxFont font = c->GetFont(); + font.SetWeight(wxFONTWEIGHT_BOLD); + c->SetFont(font); + sizer->Add (c); + + for (list::iterator j = i->second.begin(); j != i->second.end(); ++j) { + wxCheckBox* b = new wxCheckBox (this, wxID_ANY, std_to_wx ((*j)->name ())); + bool const a = find (active.begin(), active.end(), *j) != active.end (); + b->SetValue (a); + _filters[*j] = b; + b->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilterView::filter_toggled), 0, this); + sizer->Add (b); + } + + sizer->AddSpacer (6); } } -- cgit v1.2.3 From 6664ce3a91a51593821fa23755a05e08868dc788 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 2 Feb 2013 17:49:53 +0000 Subject: Post-process viewer images. --- src/wx/film_viewer.cc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 0b3fb0fd2..e103df776 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -34,6 +34,7 @@ #include "lib/scaler.h" #include "lib/exceptions.h" #include "lib/examine_content_job.h" +#include "lib/filter.h" #include "film_viewer.h" #include "wx_util.h" #include "video_decoder.h" @@ -116,6 +117,7 @@ FilmViewer::film_changed (Film::Property p) case Film::SUBTITLE_OFFSET: case Film::SUBTITLE_SCALE: case Film::SCALER: + case Film::FILTERS: update_from_raw (); break; case Film::SUBTITLE_STREAM: @@ -267,8 +269,15 @@ FilmViewer::raw_to_display () old_size = _display_frame->size(); } + boost::shared_ptr input = _raw_frame; + + pair const s = Filter::ffmpeg_strings (_film->filters()); + if (!s.second.empty ()) { + input = input->post_process (s.second, true); + } + /* Get a compacted image as we have to feed it to wxWidgets */ - _display_frame = _raw_frame->scale_and_convert_to_rgb (_film_size, 0, _film->scaler(), false); + _display_frame = input->scale_and_convert_to_rgb (_film_size, 0, _film->scaler(), false); if (old_size != _display_frame->size()) { _clear_required = true; -- cgit v1.2.3 From 55e5d61e68d9ee95594562f911c9db0397246fbe Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 2 Feb 2013 19:09:51 +0000 Subject: Insist on boost 1.45 and hence filesystem v3 now that libdcp requires it. --- src/lib/film.cc | 8 -------- src/lib/scp_dcp_job.cc | 5 ----- src/lib/util.cc | 4 ---- src/tools/dvdomatic.cc | 4 ---- src/wx/dir_picker_ctrl.cc | 4 ---- wscript | 13 +++++++++++++ 6 files changed, 13 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/lib/film.cc b/src/lib/film.cc index e7ea77023..8720e79e4 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -810,16 +810,8 @@ Film::set_content (string c) { string check = directory (); -#if BOOST_FILESYSTEM_VERSION == 3 boost::filesystem::path slash ("/"); string platform_slash = slash.make_preferred().string (); -#else -#ifdef DVDOMATIC_WINDOWS - string platform_slash = "\\"; -#else - string platform_slash = "/"; -#endif -#endif if (!ends_with (check, platform_slash)) { check += platform_slash; diff --git a/src/lib/scp_dcp_job.cc b/src/lib/scp_dcp_job.cc index 22129f56c..3d941888e 100644 --- a/src/lib/scp_dcp_job.cc +++ b/src/lib/scp_dcp_job.cc @@ -161,12 +161,7 @@ SCPDCPJob::run () for (boost::filesystem::directory_iterator i = boost::filesystem::directory_iterator (dcp_dir); i != boost::filesystem::directory_iterator(); ++i) { - /* Aah, the sweet smell of progress */ -#if BOOST_FILESYSTEM_VERSION == 3 string const leaf = boost::filesystem::path(*i).leaf().generic_string (); -#else - string const leaf = i->leaf (); -#endif set_status ("copying " + leaf); diff --git a/src/lib/util.cc b/src/lib/util.cc index ce89d5355..328be066a 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -934,11 +934,7 @@ video_frames_to_audio_frames (SourceFrame v, float audio_sample_rate, float fram bool still_image_file (string f) { -#if BOOST_FILESYSTEM_VERSION == 3 string ext = boost::filesystem::path(f).extension().string(); -#else - string ext = boost::filesystem::path(f).extension(); -#endif transform (ext.begin(), ext.end(), ext.begin(), ::tolower); diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index d5dca2ab4..9a1db3fed 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -270,11 +270,7 @@ public: maybe_save_then_delete_film (); film.reset (new Film (d->get_path (), false)); film->log()->set_level (log_level); -#if BOOST_FILESYSTEM_VERSION == 3 film->set_name (boost::filesystem::path (d->get_path()).filename().generic_string()); -#else - film->set_name (boost::filesystem::path (d->get_path()).filename()); -#endif set_film (); } diff --git a/src/wx/dir_picker_ctrl.cc b/src/wx/dir_picker_ctrl.cc index cb811fc10..b6558a881 100644 --- a/src/wx/dir_picker_ctrl.cc +++ b/src/wx/dir_picker_ctrl.cc @@ -50,11 +50,7 @@ DirPickerCtrl::SetPath (wxString p) if (_path == wxStandardPaths::Get().GetDocumentsDir()) { _folder->SetLabel (_("My Documents")); } else { -#if BOOST_FILESYSTEM_VERSION == 3 _folder->SetLabel (std_to_wx (filesystem::path (wx_to_std (_path)).leaf().string())); -#else - _folder->SetLabel (std_to_wx (filesystem::path (wx_to_std (_path)).leaf())); -#endif } } diff --git a/wscript b/wscript index bf5cf1daa..ed45b278d 100644 --- a/wscript +++ b/wscript @@ -106,6 +106,18 @@ def configure(conf): conf.check_cfg(package = 'libopenjpeg', args = '--cflags --libs', atleast_version = '1.5.0', uselib_store = 'OPENJPEG', mandatory = True) conf.check_cfg(package = 'libopenjpeg', args = '--cflags --libs', max_version = '1.5.1', mandatory = True) + conf.check_cxx(fragment = """ + #include \n + #if BOOST_VERSION < 104500\n + #error boost too old\n + #endif\n + int main(void) { return 0; }\n + """, + mandatory = True, + msg = 'Checking for boost library >= 1.45', + okmsg = 'yes', + errmsg = 'too old\nPlease install boost version 1.45 or higher.') + conf.check_cc(fragment = """ #include \n int main () {\n @@ -118,6 +130,7 @@ def configure(conf): #include \n int main() { boost::thread t (); }\n """, msg = 'Checking for boost threading library', + libpath = '/usr/local/lib', lib = [boost_thread, 'boost_system%s' % boost_lib_suffix], uselib_store = 'BOOST_THREAD') -- cgit v1.2.3 From dea922bbc1fa2b643140a6b5275e58a1fb0225c9 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 2 Feb 2013 19:40:55 +0000 Subject: Fix erroneous check wrt intrinsic duration. --- src/lib/writer.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/writer.cc b/src/lib/writer.cc index a444efad8..5bd32147a 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -316,7 +316,7 @@ Writer::check_existing_picture_mxf () return; } - while (_first_nonexistant_frame < _film->dcp_intrinsic_duration ()) { + while (1) { /* Read the frame info as written */ ifstream ifi (_film->info_path (_first_nonexistant_frame).c_str()); -- cgit v1.2.3 From 7ddcba57c47cf771695765977cc57384bea71e7a Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 2 Feb 2013 23:49:31 +0000 Subject: Remove crashing and thought-to-be-unnecessary process_end from DelayLine. --- src/lib/delay_line.cc | 9 --------- src/lib/delay_line.h | 1 - 2 files changed, 10 deletions(-) (limited to 'src') diff --git a/src/lib/delay_line.cc b/src/lib/delay_line.cc index 45d8e9d9d..4ad172781 100644 --- a/src/lib/delay_line.cc +++ b/src/lib/delay_line.cc @@ -91,12 +91,3 @@ DelayLine::process_audio (shared_ptr data) Audio (data); } - -void -DelayLine::process_end () -{ - if (_frames < 0) { - _buffers->make_silent (); - Audio (_buffers); - } -} diff --git a/src/lib/delay_line.h b/src/lib/delay_line.h index fa2870ae7..4d6f1313b 100644 --- a/src/lib/delay_line.h +++ b/src/lib/delay_line.h @@ -29,7 +29,6 @@ public: DelayLine (Log* log, int channels, int frames); void process_audio (boost::shared_ptr); - void process_end (); private: boost::shared_ptr _buffers; -- cgit v1.2.3 From d3af3c9c9e1c0272986b41f9ffa323e46a79cd75 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 3 Feb 2013 17:47:00 +0000 Subject: Fix crop on aligned images, which affected still image DCP generation. --- src/lib/image.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/lib/image.cc b/src/lib/image.cc index 9223fdc5d..0ec6bd26c 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -240,8 +240,8 @@ Image::crop (Crop crop, bool aligned) const for (int y = 0; y < cropped_size.height; ++y) { memcpy (out_p, in_p + crop_left_in_bytes, cropped_width_in_bytes); - in_p += line_size()[c]; - out_p += out->line_size()[c]; + in_p += stride()[c]; + out_p += out->stride()[c]; } } -- cgit v1.2.3 From 90550787a8b00329170a6a1d0e9bb58aeb92ac6f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 3 Feb 2013 21:36:03 +0000 Subject: FIXME comment. --- src/lib/util.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/lib/util.cc b/src/lib/util.cc index 328be066a..340b76b57 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -622,6 +622,9 @@ Socket::read_definite_and_consume (uint8_t* data, int size, int timeout) /** Read as much data as is available, up to some limit. * @param data Where to put the data. * @param size Maximum amount of data to read. + * + * XXX This method assumes that there is always lots of data to read(); + * if there isn't, it will hang waiting for data that will never arrive. */ void Socket::read_indefinite (uint8_t* data, int size, int timeout) -- cgit v1.2.3 From 6b4527e671bc3fdb4e1a687b066c44ca90a25377 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 4 Feb 2013 20:46:37 +0000 Subject: Try to return an error code if things go wrong. --- src/tools/makedcp.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/tools/makedcp.cc b/src/tools/makedcp.cc index 447b0ddc0..892bed3b8 100644 --- a/src/tools/makedcp.cc +++ b/src/tools/makedcp.cc @@ -159,6 +159,7 @@ main (int argc, char* argv[]) bool should_stop = false; bool first = true; + bool error = false; while (!should_stop) { dvdomatic_sleep (5); @@ -194,6 +195,7 @@ main (int argc, char* argv[]) if ((*i)->finished_in_error ()) { ++finished_in_error; + error = true; } if (!progress && (*i)->finished_in_error ()) { @@ -209,7 +211,7 @@ main (int argc, char* argv[]) } } - return 0; + return error ? EXIT_FAILURE : EXIT_SUCCESS; } -- cgit v1.2.3 From 3b6af76dc7a9089a35d2d2815d4fb8fb55876d1b Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 6 Feb 2013 12:59:52 +0000 Subject: Try to improve i18n a bit. --- src/tools/dvdomatic.cc | 10 ++-- src/wx/config_dialog.cc | 20 ++++---- src/wx/dci_metadata_dialog.cc | 14 +++--- src/wx/film_editor.cc | 102 +++++++++++++++++++++------------------ src/wx/film_viewer.cc | 2 +- src/wx/gain_calculator_dialog.cc | 4 +- src/wx/job_manager_view.cc | 2 +- src/wx/job_wrapper.cc | 4 +- src/wx/new_film_dialog.cc | 6 +-- src/wx/properties_dialog.cc | 16 +++--- src/wx/server_dialog.cc | 6 +-- src/wx/wx_util.cc | 12 ++--- src/wx/wx_util.h | 6 +-- wscript | 3 +- 14 files changed, 109 insertions(+), 98 deletions(-) (limited to 'src') diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 9a1db3fed..0565d3a1c 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -64,7 +64,7 @@ public: { stringstream s; s << "Save changes to film \"" << film->name() << "\" before closing?"; - _dialog = new wxMessageDialog (0, std_to_wx (s.str()), wxT ("Film changed"), wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION); + _dialog = new wxMessageDialog (0, std_to_wx (s.str()), _("Film changed"), wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION); } ~FilmChangedDialog () @@ -263,7 +263,7 @@ public: if (r == wxID_OK) { if (boost::filesystem::exists (d->get_path())) { - error_dialog (this, String::compose ("The directory %1 already exists.", d->get_path())); + error_dialog (this, wxString::Format (_("The directory %s already exists"), d->get_path().c_str())); return; } @@ -279,7 +279,7 @@ public: void file_open (wxCommandEvent &) { - wxDirDialog* c = new wxDirDialog (this, wxT ("Select film to open"), wxStandardPaths::Get().GetDocumentsDir(), wxDEFAULT_DIALOG_STYLE | wxDD_DIR_MUST_EXIST); + wxDirDialog* c = new wxDirDialog (this, _("Select film to open"), wxStandardPaths::Get().GetDocumentsDir(), wxDEFAULT_DIALOG_STYLE | wxDD_DIR_MUST_EXIST); int const r = c->ShowModal (); if (r == wxID_OK) { @@ -289,7 +289,9 @@ public: film->log()->set_level (log_level); set_film (); } catch (std::exception& e) { - error_dialog (this, String::compose ("Could not open film at %1 (%2)", wx_to_std (c->GetPath()), e.what())); + wxString p = c->GetPath (); + wxCharBuffer b = p.ToUTF8 (); + error_dialog (this, wxString::Format (_("Could not open film at %s (%s)"), p.data(), e.what())); } } diff --git a/src/wx/config_dialog.cc b/src/wx/config_dialog.cc index b656a5278..07e32a457 100644 --- a/src/wx/config_dialog.cc +++ b/src/wx/config_dialog.cc @@ -46,32 +46,32 @@ ConfigDialog::ConfigDialog (wxWindow* parent) wxFlexGridSizer* table = new wxFlexGridSizer (3, 6, 6); table->AddGrowableCol (1, 1); - add_label_to_sizer (table, this, "TMS IP address"); + add_label_to_sizer (table, this, _("TMS IP address")); _tms_ip = new wxTextCtrl (this, wxID_ANY); table->Add (_tms_ip, 1, wxEXPAND); table->AddSpacer (0); - add_label_to_sizer (table, this, "TMS target path"); + add_label_to_sizer (table, this, _("TMS target path")); _tms_path = new wxTextCtrl (this, wxID_ANY); table->Add (_tms_path, 1, wxEXPAND); table->AddSpacer (0); - add_label_to_sizer (table, this, "TMS user name"); + add_label_to_sizer (table, this, _("TMS user name")); _tms_user = new wxTextCtrl (this, wxID_ANY); table->Add (_tms_user, 1, wxEXPAND); table->AddSpacer (0); - add_label_to_sizer (table, this, "TMS password"); + add_label_to_sizer (table, this, _("TMS password")); _tms_password = new wxTextCtrl (this, wxID_ANY); table->Add (_tms_password, 1, wxEXPAND); table->AddSpacer (0); - add_label_to_sizer (table, this, "Threads to use for encoding on this host"); + add_label_to_sizer (table, this, _("Threads to use for encoding on this host")); _num_local_encoding_threads = new wxSpinCtrl (this); table->Add (_num_local_encoding_threads, 1, wxEXPAND); table->AddSpacer (0); - add_label_to_sizer (table, this, "Default directory for new films"); + add_label_to_sizer (table, this, _("Default directory for new films")); #ifdef __WXMSW__ _default_directory = new DirPickerCtrl (this); #else @@ -80,12 +80,12 @@ ConfigDialog::ConfigDialog (wxWindow* parent) table->Add (_default_directory, 1, wxEXPAND); table->AddSpacer (0); - add_label_to_sizer (table, this, "Default DCI name details"); + add_label_to_sizer (table, this, _("Default DCI name details")); _default_dci_metadata_button = new wxButton (this, wxID_ANY, _("Edit...")); table->Add (_default_dci_metadata_button); table->AddSpacer (1); - add_label_to_sizer (table, this, "Reference scaler for A/B"); + add_label_to_sizer (table, this, _("Reference scaler for A/B")); _reference_scaler = new wxChoice (this, wxID_ANY); vector const sc = Scaler::all (); for (vector::const_iterator i = sc.begin(); i != sc.end(); ++i) { @@ -96,7 +96,7 @@ ConfigDialog::ConfigDialog (wxWindow* parent) table->AddSpacer (0); { - add_label_to_sizer (table, this, "Reference filters for A/B"); + add_label_to_sizer (table, this, _("Reference filters for A/B")); wxSizer* s = new wxBoxSizer (wxHORIZONTAL); _reference_filters = new wxStaticText (this, wxID_ANY, wxT ("")); s->Add (_reference_filters, 1, wxEXPAND); @@ -106,7 +106,7 @@ ConfigDialog::ConfigDialog (wxWindow* parent) table->AddSpacer (0); } - add_label_to_sizer (table, this, "Encoding Servers"); + add_label_to_sizer (table, this, _("Encoding Servers")); _servers = new wxListCtrl (this, wxID_ANY, wxDefaultPosition, wxSize (220, 100), wxLC_REPORT | wxLC_SINGLE_SEL); wxListItem ip; ip.SetId (0); diff --git a/src/wx/dci_metadata_dialog.cc b/src/wx/dci_metadata_dialog.cc index c5682e19e..c08c58ed4 100644 --- a/src/wx/dci_metadata_dialog.cc +++ b/src/wx/dci_metadata_dialog.cc @@ -30,31 +30,31 @@ DCIMetadataDialog::DCIMetadataDialog (wxWindow* parent, DCIMetadata dm) wxFlexGridSizer* table = new wxFlexGridSizer (2, 6, 6); table->AddGrowableCol (1, 1); - add_label_to_sizer (table, this, "Audio Language (e.g. EN)"); + add_label_to_sizer (table, this, _("Audio Language (e.g. EN)")); _audio_language = new wxTextCtrl (this, wxID_ANY); table->Add (_audio_language, 1, wxEXPAND); - add_label_to_sizer (table, this, "Subtitle Language (e.g. FR)"); + add_label_to_sizer (table, this, _("Subtitle Language (e.g. FR)")); _subtitle_language = new wxTextCtrl (this, wxID_ANY); table->Add (_subtitle_language, 1, wxEXPAND); - add_label_to_sizer (table, this, "Territory (e.g. UK)"); + add_label_to_sizer (table, this, _("Territory (e.g. UK)")); _territory = new wxTextCtrl (this, wxID_ANY); table->Add (_territory, 1, wxEXPAND); - add_label_to_sizer (table, this, "Rating (e.g. 15)"); + add_label_to_sizer (table, this, _("Rating (e.g. 15)")); _rating = new wxTextCtrl (this, wxID_ANY); table->Add (_rating, 1, wxEXPAND); - add_label_to_sizer (table, this, "Studio (e.g. TCF)"); + add_label_to_sizer (table, this, _("Studio (e.g. TCF)")); _studio = new wxTextCtrl (this, wxID_ANY); table->Add (_studio, 1, wxEXPAND); - add_label_to_sizer (table, this, "Facility (e.g. DLA)"); + add_label_to_sizer (table, this, _("Facility (e.g. DLA)")); _facility = new wxTextCtrl (this, wxID_ANY); table->Add (_facility, 1, wxEXPAND); - add_label_to_sizer (table, this, "Package Type (e.g. OV)"); + add_label_to_sizer (table, this, _("Package Type (e.g. OV)")); _package_type = new wxTextCtrl (this, wxID_ANY); table->Add (_package_type, 1, wxEXPAND); diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index f274416fb..4b8f6ee33 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -97,71 +97,72 @@ FilmEditor::make_film_panel () pad->Add (_film_sizer, 0, wxALL, 8); _film_panel->SetSizer (pad); - add_label_to_sizer (_film_sizer, _film_panel, "Name"); + add_label_to_sizer (_film_sizer, _film_panel, _("Name")); _name = new wxTextCtrl (_film_panel, wxID_ANY); _film_sizer->Add (_name, 1, wxEXPAND); - add_label_to_sizer (_film_sizer, _film_panel, "DCP Name"); + add_label_to_sizer (_film_sizer, _film_panel, _("DCP Name")); _dcp_name = new wxStaticText (_film_panel, wxID_ANY, wxT ("")); _film_sizer->Add (_dcp_name, 0, wxALIGN_CENTER_VERTICAL | wxSHRINK); - _use_dci_name = new wxCheckBox (_film_panel, wxID_ANY, wxT ("Use DCI name")); + _use_dci_name = new wxCheckBox (_film_panel, wxID_ANY, _("Use DCI name")); _film_sizer->Add (_use_dci_name, 1, wxEXPAND); - _edit_dci_button = new wxButton (_film_panel, wxID_ANY, wxT ("Details...")); + _edit_dci_button = new wxButton (_film_panel, wxID_ANY, _("Details...")); _film_sizer->Add (_edit_dci_button, 0); - add_label_to_sizer (_film_sizer, _film_panel, "Content"); - _content = new wxFilePickerCtrl (_film_panel, wxID_ANY, wxT (""), wxT ("Select Content File"), wxT("*.*")); + add_label_to_sizer (_film_sizer, _film_panel, _("Content")); + _content = new wxFilePickerCtrl (_film_panel, wxID_ANY, wxT (""), _("Select Content File"), wxT("*.*")); _film_sizer->Add (_content, 1, wxEXPAND); - _trust_content_header = new wxCheckBox (_film_panel, wxID_ANY, wxT ("Trust content's header")); + _trust_content_header = new wxCheckBox (_film_panel, wxID_ANY, _("Trust content's header")); video_control (_trust_content_header); _film_sizer->Add (_trust_content_header, 1); _film_sizer->AddSpacer (0); - add_label_to_sizer (_film_sizer, _film_panel, "Content Type"); + add_label_to_sizer (_film_sizer, _film_panel, _("Content Type")); _dcp_content_type = new wxChoice (_film_panel, wxID_ANY); _film_sizer->Add (_dcp_content_type); - video_control (add_label_to_sizer (_film_sizer, _film_panel, "Frames Per Second")); + video_control (add_label_to_sizer (_film_sizer, _film_panel, _("Frames Per Second"))); _frames_per_second = new wxStaticText (_film_panel, wxID_ANY, wxT ("")); _film_sizer->Add (video_control (_frames_per_second), 1, wxALIGN_CENTER_VERTICAL); - video_control (add_label_to_sizer (_film_sizer, _film_panel, "Original Size")); + video_control (add_label_to_sizer (_film_sizer, _film_panel, _("Original Size"))); _original_size = new wxStaticText (_film_panel, wxID_ANY, wxT ("")); _film_sizer->Add (video_control (_original_size), 1, wxALIGN_CENTER_VERTICAL); - video_control (add_label_to_sizer (_film_sizer, _film_panel, "Length")); + video_control (add_label_to_sizer (_film_sizer, _film_panel, _("Length"))); _length = new wxStaticText (_film_panel, wxID_ANY, wxT ("")); _film_sizer->Add (video_control (_length), 1, wxALIGN_CENTER_VERTICAL); { - video_control (add_label_to_sizer (_film_sizer, _film_panel, "Trim frames")); + video_control (add_label_to_sizer (_film_sizer, _film_panel, _("Trim frames"))); wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); - video_control (add_label_to_sizer (s, _film_panel, "Start")); + video_control (add_label_to_sizer (s, _film_panel, _("Start"))); _trim_start = new wxSpinCtrl (_film_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)); s->Add (video_control (_trim_start)); - video_control (add_label_to_sizer (s, _film_panel, "End")); + video_control (add_label_to_sizer (s, _film_panel, _("End"))); _trim_end = new wxSpinCtrl (_film_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)); s->Add (video_control (_trim_end)); _film_sizer->Add (s); } - _dcp_ab = new wxCheckBox (_film_panel, wxID_ANY, wxT ("A/B")); + _dcp_ab = new wxCheckBox (_film_panel, wxID_ANY, _("A/B")); video_control (_dcp_ab); _film_sizer->Add (_dcp_ab, 1); _film_sizer->AddSpacer (0); /* STILL-only stuff */ { - still_control (add_label_to_sizer (_film_sizer, _film_panel, "Duration")); + still_control (add_label_to_sizer (_film_sizer, _film_panel, _("Duration"))); wxSizer* s = new wxBoxSizer (wxHORIZONTAL); _still_duration = new wxSpinCtrl (_film_panel); still_control (_still_duration); s->Add (_still_duration, 1, wxEXPAND); - still_control (add_label_to_sizer (s, _film_panel, "s")); + /* TRANSLATORS: `s' here is an abbreviation for seconds, the unit of time */ + still_control (add_label_to_sizer (s, _film_panel, _("s"))); _film_sizer->Add (s); } @@ -221,24 +222,27 @@ FilmEditor::make_video_panel () pad->Add (_video_sizer, 0, wxALL, 8); _video_panel->SetSizer (pad); - add_label_to_sizer (_video_sizer, _video_panel, "Format"); + add_label_to_sizer (_video_sizer, _video_panel, _("Format")); _format = new wxChoice (_video_panel, wxID_ANY); _video_sizer->Add (_format); { - add_label_to_sizer (_video_sizer, _video_panel, "Crop"); + add_label_to_sizer (_video_sizer, _video_panel, _("Crop")); wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); - add_label_to_sizer (s, _video_panel, "L"); + /* TRANSLATORS: L, R, T and B are abbreviations for Left, Right, Top, Bottom, the four edges + of the picture frame. + */ + add_label_to_sizer (s, _video_panel, _("L")); _left_crop = new wxSpinCtrl (_video_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)); s->Add (_left_crop, 0); - add_label_to_sizer (s, _video_panel, "R"); + add_label_to_sizer (s, _video_panel, _("R")); _right_crop = new wxSpinCtrl (_video_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)); s->Add (_right_crop, 0); - add_label_to_sizer (s, _video_panel, "T"); + add_label_to_sizer (s, _video_panel, _("T")); _top_crop = new wxSpinCtrl (_video_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)); s->Add (_top_crop, 0); - add_label_to_sizer (s, _video_panel, "B"); + add_label_to_sizer (s, _video_panel, _("B")); _bottom_crop = new wxSpinCtrl (_video_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)); s->Add (_bottom_crop, 0); @@ -247,18 +251,18 @@ FilmEditor::make_video_panel () /* VIDEO-only stuff */ { - video_control (add_label_to_sizer (_video_sizer, _video_panel, "Filters")); + video_control (add_label_to_sizer (_video_sizer, _video_panel, _("Filters"))); wxSizer* s = new wxBoxSizer (wxHORIZONTAL); - _filters = new wxStaticText (_video_panel, wxID_ANY, wxT ("None")); + _filters = new wxStaticText (_video_panel, wxID_ANY, _("None")); video_control (_filters); s->Add (_filters, 1, wxEXPAND | wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM | wxRIGHT, 6); - _filters_button = new wxButton (_video_panel, wxID_ANY, wxT ("Edit...")); + _filters_button = new wxButton (_video_panel, wxID_ANY, _("Edit...")); video_control (_filters_button); s->Add (_filters_button, 0); _video_sizer->Add (s, 1); } - video_control (add_label_to_sizer (_video_sizer, _video_panel, "Scaler")); + video_control (add_label_to_sizer (_video_sizer, _video_panel, _("Scaler"))); _scaler = new wxChoice (_video_panel, wxID_ANY); _video_sizer->Add (video_control (_scaler), 1); @@ -267,7 +271,7 @@ FilmEditor::make_video_panel () _scaler->Append (std_to_wx ((*i)->name())); } - add_label_to_sizer (_video_sizer, _video_panel, "Colour look-up table"); + add_label_to_sizer (_video_sizer, _video_panel, _("Colour look-up table")); _colour_lut = new wxChoice (_video_panel, wxID_ANY); for (int i = 0; i < 2; ++i) { _colour_lut->Append (std_to_wx (colour_lut_index_to_name (i))); @@ -276,11 +280,11 @@ FilmEditor::make_video_panel () _video_sizer->Add (_colour_lut, 1, wxEXPAND); { - add_label_to_sizer (_video_sizer, _video_panel, "JPEG2000 bandwidth"); + add_label_to_sizer (_video_sizer, _video_panel, _("JPEG2000 bandwidth")); wxSizer* s = new wxBoxSizer (wxHORIZONTAL); _j2k_bandwidth = new wxSpinCtrl (_video_panel, wxID_ANY); s->Add (_j2k_bandwidth, 1); - add_label_to_sizer (s, _video_panel, "MBps"); + add_label_to_sizer (s, _video_panel, _("MBps")); _video_sizer->Add (s, 1); } @@ -304,11 +308,11 @@ FilmEditor::make_audio_panel () _audio_panel->SetSizer (pad); { - video_control (add_label_to_sizer (_audio_sizer, _audio_panel, "Audio Gain")); + video_control (add_label_to_sizer (_audio_sizer, _audio_panel, _("Audio Gain"))); wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); _audio_gain = new wxSpinCtrl (_audio_panel); s->Add (video_control (_audio_gain), 1); - video_control (add_label_to_sizer (s, _audio_panel, "dB")); + video_control (add_label_to_sizer (s, _audio_panel, _("dB"))); _audio_gain_calculate_button = new wxButton (_audio_panel, wxID_ANY, _("Calculate...")); video_control (_audio_gain_calculate_button); s->Add (_audio_gain_calculate_button, 1, wxEXPAND); @@ -316,11 +320,12 @@ FilmEditor::make_audio_panel () } { - video_control (add_label_to_sizer (_audio_sizer, _audio_panel, "Audio Delay")); + video_control (add_label_to_sizer (_audio_sizer, _audio_panel, _("Audio Delay"))); wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); _audio_delay = new wxSpinCtrl (_audio_panel); s->Add (video_control (_audio_delay), 1); - video_control (add_label_to_sizer (s, _audio_panel, "ms")); + /* TRANSLATORS: this is an abbreviation for milliseconds, the unit of time */ + video_control (add_label_to_sizer (s, _audio_panel, _("ms"))); _audio_sizer->Add (s); } @@ -341,18 +346,21 @@ FilmEditor::make_audio_panel () assert (MAX_AUDIO_CHANNELS == 6); - char const * channels[] = { - "Left", - "Right", - "Centre", - "Lfe (sub)", - "Left surround", - "Right surround" + /* TRANSLATORS: these are the names of audio channels; Lfe (sub) is the low-frequency + enhancement channel (sub-woofer)./ + */ + wxString const channels[] = { + _("Left"), + _("Right"), + _("Centre"), + _("Lfe (sub)"), + _("Left surround"), + _("Right surround"), }; for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) { add_label_to_sizer (_audio_sizer, _audio_panel, channels[i]); - _external_audio[i] = new wxFilePickerCtrl (_audio_panel, wxID_ANY, wxT (""), wxT ("Select Audio File"), wxT ("*.wav")); + _external_audio[i] = new wxFilePickerCtrl (_audio_panel, wxID_ANY, wxT (""), _("Select Audio File"), wxT ("*.wav")); _audio_sizer->Add (_external_audio[i], 1, wxEXPAND); } @@ -369,23 +377,23 @@ FilmEditor::make_subtitle_panel () pad->Add (_subtitle_sizer, 0, wxALL, 8); _subtitle_panel->SetSizer (pad); - _with_subtitles = new wxCheckBox (_subtitle_panel, wxID_ANY, wxT("With Subtitles")); + _with_subtitles = new wxCheckBox (_subtitle_panel, wxID_ANY, _("With Subtitles")); video_control (_with_subtitles); _subtitle_sizer->Add (_with_subtitles, 1); _subtitle_stream = new wxChoice (_subtitle_panel, wxID_ANY); _subtitle_sizer->Add (video_control (_subtitle_stream)); - video_control (add_label_to_sizer (_subtitle_sizer, _subtitle_panel, "Subtitle Offset")); + video_control (add_label_to_sizer (_subtitle_sizer, _subtitle_panel, _("Subtitle Offset"))); _subtitle_offset = new wxSpinCtrl (_subtitle_panel); _subtitle_sizer->Add (video_control (_subtitle_offset), 1); { - video_control (add_label_to_sizer (_subtitle_sizer, _subtitle_panel, "Subtitle Scale")); + video_control (add_label_to_sizer (_subtitle_sizer, _subtitle_panel, _("Subtitle Scale"))); wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); _subtitle_scale = new wxSpinCtrl (_subtitle_panel); s->Add (video_control (_subtitle_scale)); - video_control (add_label_to_sizer (s, _subtitle_panel, "%")); + video_control (add_label_to_sizer (s, _subtitle_panel, _("%"))); _subtitle_sizer->Add (s); } @@ -449,7 +457,7 @@ FilmEditor::content_changed (wxCommandEvent &) _film->set_content (wx_to_std (_content->GetPath ())); } catch (std::exception& e) { _content->SetPath (std_to_wx (_film->directory ())); - error_dialog (this, String::compose ("Could not set content: %1", e.what ())); + error_dialog (this, wxString::Format (_("Could not set content: %s"), e.what ())); } } diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index e103df776..4e5f38300 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -388,7 +388,7 @@ FilmViewer::get_frame () } catch (DecodeError& e) { _play_button->SetValue (false); check_play_state (); - error_dialog (this, String::compose ("Could not decode video for view (%1)", e.what())); + error_dialog (this, wxString::Format (_("Could not decode video for view (%s)"), e.what())); } } diff --git a/src/wx/gain_calculator_dialog.cc b/src/wx/gain_calculator_dialog.cc index 3f07faf06..7f4b774c0 100644 --- a/src/wx/gain_calculator_dialog.cc +++ b/src/wx/gain_calculator_dialog.cc @@ -29,11 +29,11 @@ GainCalculatorDialog::GainCalculatorDialog (wxWindow* parent) wxFlexGridSizer* table = new wxFlexGridSizer (2, 6, 6); table->AddGrowableCol (1, 1); - add_label_to_sizer (table, this, "I want to play this back at fader"); + add_label_to_sizer (table, this, _("I want to play this back at fader")); _wanted = new wxTextCtrl (this, wxID_ANY, wxT (""), wxDefaultPosition, wxDefaultSize, 0, wxTextValidator (wxFILTER_NUMERIC)); table->Add (_wanted, 1, wxEXPAND); - add_label_to_sizer (table, this, "But I have to use fader"); + add_label_to_sizer (table, this, _("But I have to use fader")); _actual = new wxTextCtrl (this, wxID_ANY, wxT (""), wxDefaultPosition, wxDefaultSize, 0, wxTextValidator (wxFILTER_NUMERIC)); table->Add (_actual, 1, wxEXPAND); diff --git a/src/wx/job_manager_view.cc b/src/wx/job_manager_view.cc index 9c7040584..a5c02b163 100644 --- a/src/wx/job_manager_view.cc +++ b/src/wx/job_manager_view.cc @@ -95,7 +95,7 @@ JobManagerView::update () _job_records[*i].message->SetLabel (std_to_wx (st)); _job_records[*i].gauge->SetValue (p * 100); } else { - _job_records[*i].message->SetLabel (wxT ("Running")); + _job_records[*i].message->SetLabel (_("Running")); _job_records[*i].gauge->Pulse (); } } diff --git a/src/wx/job_wrapper.cc b/src/wx/job_wrapper.cc index f2056cf49..cb02ecd02 100644 --- a/src/wx/job_wrapper.cc +++ b/src/wx/job_wrapper.cc @@ -35,8 +35,8 @@ JobWrapper::make_dcp (wxWindow* parent, shared_ptr film, bool transcode) try { film->make_dcp (transcode); } catch (BadSettingError& e) { - error_dialog (parent, String::compose ("Bad setting for %1 (%2)", e.setting(), e.what ())); + error_dialog (parent, wxString::Format (_("Bad setting for %s (%s)"), e.setting().c_str(), e.what())); } catch (std::exception& e) { - error_dialog (parent, String::compose ("Could not make DCP: %1", e.what ())); + error_dialog (parent, wxString::Format (_("Could not make DCP: %s"), e.what ())); } } diff --git a/src/wx/new_film_dialog.cc b/src/wx/new_film_dialog.cc index eb6f2849b..90c2d727e 100644 --- a/src/wx/new_film_dialog.cc +++ b/src/wx/new_film_dialog.cc @@ -30,7 +30,7 @@ using namespace std; using namespace boost; NewFilmDialog::NewFilmDialog (wxWindow* parent) - : wxDialog (parent, wxID_ANY, wxString (_("New Film"))) + : wxDialog (parent, wxID_ANY, _("New Film")) { wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL); SetSizer (overall_sizer); @@ -39,11 +39,11 @@ NewFilmDialog::NewFilmDialog (wxWindow* parent) table->AddGrowableCol (1, 1); overall_sizer->Add (table, 1, wxEXPAND | wxALL, 6); - add_label_to_sizer (table, this, "Film name"); + add_label_to_sizer (table, this, _("Film name")); _name = new wxTextCtrl (this, wxID_ANY); table->Add (_name, 1, wxEXPAND); - add_label_to_sizer (table, this, "Create in folder"); + add_label_to_sizer (table, this, _("Create in folder")); #ifdef __WXMSW__ _folder = new DirPickerCtrl (this); #else diff --git a/src/wx/properties_dialog.cc b/src/wx/properties_dialog.cc index 0cf75cf51..338d0f972 100644 --- a/src/wx/properties_dialog.cc +++ b/src/wx/properties_dialog.cc @@ -38,20 +38,20 @@ PropertiesDialog::PropertiesDialog (wxWindow* parent, shared_ptr film) { wxFlexGridSizer* table = new wxFlexGridSizer (2, 3, 6); - add_label_to_sizer (table, this, "Frames"); - _frames = new wxStaticText (this, wxID_ANY, std_to_wx ("")); + add_label_to_sizer (table, this, _("Frames")); + _frames = new wxStaticText (this, wxID_ANY, wxT ("")); table->Add (_frames, 1, wxALIGN_CENTER_VERTICAL); - add_label_to_sizer (table, this, "Disk space required for frames"); - _disk_for_frames = new wxStaticText (this, wxID_ANY, std_to_wx ("")); + add_label_to_sizer (table, this, _("Disk space required for frames")); + _disk_for_frames = new wxStaticText (this, wxID_ANY, wxT ("")); table->Add (_disk_for_frames, 1, wxALIGN_CENTER_VERTICAL); - add_label_to_sizer (table, this, "Total disk space required"); - _total_disk = new wxStaticText (this, wxID_ANY, std_to_wx ("")); + add_label_to_sizer (table, this, _("Total disk space required")); + _total_disk = new wxStaticText (this, wxID_ANY, wxT ("")); table->Add (_total_disk, 1, wxALIGN_CENTER_VERTICAL); - add_label_to_sizer (table, this, "Frames already encoded"); - _encoded = new ThreadedStaticText (this, "counting...", boost::bind (&PropertiesDialog::frames_already_encoded, this)); + add_label_to_sizer (table, this, _("Frames already encoded")); + _encoded = new ThreadedStaticText (this, _("counting..."), boost::bind (&PropertiesDialog::frames_already_encoded, this)); table->Add (_encoded, 1, wxALIGN_CENTER_VERTICAL); if (_film->length()) { diff --git a/src/wx/server_dialog.cc b/src/wx/server_dialog.cc index 7b394a484..1b5b71dc9 100644 --- a/src/wx/server_dialog.cc +++ b/src/wx/server_dialog.cc @@ -22,7 +22,7 @@ #include "wx_util.h" ServerDialog::ServerDialog (wxWindow* parent, ServerDescription* server) - : wxDialog (parent, wxID_ANY, wxString (_("Server"))) + : wxDialog (parent, wxID_ANY, _("Server")) { if (server) { _server = server; @@ -33,11 +33,11 @@ ServerDialog::ServerDialog (wxWindow* parent, ServerDescription* server) wxFlexGridSizer* table = new wxFlexGridSizer (2, 4, 4); table->AddGrowableCol (1, 1); - add_label_to_sizer (table, this, "Host name or IP address"); + add_label_to_sizer (table, this, _("Host name or IP address")); _host = new wxTextCtrl (this, wxID_ANY); table->Add (_host, 1, wxEXPAND); - add_label_to_sizer (table, this, "Threads to use"); + add_label_to_sizer (table, this, _("Threads to use")); _threads = new wxSpinCtrl (this, wxID_ANY); table->Add (_threads, 1, wxEXPAND); diff --git a/src/wx/wx_util.cc b/src/wx/wx_util.cc index 413071ea6..632dbc32e 100644 --- a/src/wx/wx_util.cc +++ b/src/wx/wx_util.cc @@ -36,9 +36,9 @@ using namespace boost; * @param prop Proportion to pass when calling Add() on the wxSizer. */ wxStaticText * -add_label_to_sizer (wxSizer* s, wxWindow* p, string t, int prop) +add_label_to_sizer (wxSizer* s, wxWindow* p, wxString t, int prop) { - wxStaticText* m = new wxStaticText (p, wxID_ANY, std_to_wx (t)); + wxStaticText* m = new wxStaticText (p, wxID_ANY, t); s->Add (m, prop, wxALIGN_CENTER_VERTICAL | wxALL, 6); return m; } @@ -48,9 +48,9 @@ add_label_to_sizer (wxSizer* s, wxWindow* p, string t, int prop) * @param m Message. */ void -error_dialog (wxWindow* parent, string m) +error_dialog (wxWindow* parent, wxString m) { - wxMessageDialog* d = new wxMessageDialog (parent, std_to_wx (m), wxT ("DVD-o-matic"), wxOK); + wxMessageDialog* d = new wxMessageDialog (parent, m, _("DVD-o-matic"), wxOK); d->ShowModal (); d->Destroy (); } @@ -79,8 +79,8 @@ int const ThreadedStaticText::_update_event_id = 10000; * @param initial Initial text for the wxStaticText while the computation is being run. * @param fn Function which works out what the wxStaticText content should be and returns it. */ -ThreadedStaticText::ThreadedStaticText (wxWindow* parent, string initial, function fn) - : wxStaticText (parent, wxID_ANY, std_to_wx (initial)) +ThreadedStaticText::ThreadedStaticText (wxWindow* parent, wxString initial, function fn) + : wxStaticText (parent, wxID_ANY, initial) { Connect (_update_event_id, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (ThreadedStaticText::thread_finished), 0, this); _thread = new thread (bind (&ThreadedStaticText::run, this, fn)); diff --git a/src/wx/wx_util.h b/src/wx/wx_util.h index 0c77735eb..dd069a9d7 100644 --- a/src/wx/wx_util.h +++ b/src/wx/wx_util.h @@ -28,8 +28,8 @@ class wxSpinCtrl; * @brief Some utility functions and classes. */ -extern void error_dialog (wxWindow *, std::string); -extern wxStaticText* add_label_to_sizer (wxSizer *, wxWindow *, std::string, int prop = 0); +extern void error_dialog (wxWindow *, wxString); +extern wxStaticText* add_label_to_sizer (wxSizer *, wxWindow *, wxString, int prop = 0); extern std::string wx_to_std (wxString); extern wxString std_to_wx (std::string); @@ -41,7 +41,7 @@ extern wxString std_to_wx (std::string); class ThreadedStaticText : public wxStaticText { public: - ThreadedStaticText (wxWindow* parent, std::string initial, boost::function fn); + ThreadedStaticText (wxWindow* parent, wxString initial, boost::function fn); ~ThreadedStaticText (); private: diff --git a/wscript b/wscript index f84f9d13b..1dba6bb67 100644 --- a/wscript +++ b/wscript @@ -89,7 +89,8 @@ def configure(conf): conf.check_cfg(package = 'sndfile', args = '--cflags --libs', uselib_store = 'SNDFILE', mandatory = True) conf.check_cfg(package = 'glib-2.0', args = '--cflags --libs', uselib_store = 'GLIB', mandatory = True) - conf.check_cfg(package = 'liblzma', args = '--cflags --libs', uselib_store = 'LZMA', mandatory = True) + if conf.options.target_windows is False: + conf.check_cfg(package = 'liblzma', args = '--cflags --libs', uselib_store = 'LZMA', mandatory = True) conf.check_cfg(package = '', path = 'Magick++-config', args = '--cppflags --cxxflags --libs', uselib_store = 'MAGICK', mandatory = True) if conf.options.static: -- cgit v1.2.3 From 7fd57a4523af7f59037d03f78aee727987932094 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 6 Feb 2013 22:10:16 +0000 Subject: Fix redraw problems at the borders on Windows (#45). --- src/wx/film_editor.cc | 139 ++++++++++++++++++++++++++------------------------ 1 file changed, 71 insertions(+), 68 deletions(-) (limited to 'src') diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 4b8f6ee33..634e417df 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -92,52 +92,53 @@ void FilmEditor::make_film_panel () { _film_panel = new wxPanel (_notebook); - _film_sizer = new wxFlexGridSizer (2, 4, 4); - wxBoxSizer* pad = new wxBoxSizer (wxVERTICAL); - pad->Add (_film_sizer, 0, wxALL, 8); - _film_panel->SetSizer (pad); + _film_sizer = new wxBoxSizer (wxVERTICAL); + _film_panel->SetSizer (_film_sizer); - add_label_to_sizer (_film_sizer, _film_panel, _("Name")); + wxFlexGridSizer* grid = new wxFlexGridSizer (2, 4, 4); + _film_sizer->Add (grid, 0, wxALL, 8); + + add_label_to_sizer (grid, _film_panel, _("Name")); _name = new wxTextCtrl (_film_panel, wxID_ANY); - _film_sizer->Add (_name, 1, wxEXPAND); + grid->Add (_name, 1, wxEXPAND); - add_label_to_sizer (_film_sizer, _film_panel, _("DCP Name")); + add_label_to_sizer (grid, _film_panel, _("DCP Name")); _dcp_name = new wxStaticText (_film_panel, wxID_ANY, wxT ("")); - _film_sizer->Add (_dcp_name, 0, wxALIGN_CENTER_VERTICAL | wxSHRINK); + grid->Add (_dcp_name, 0, wxALIGN_CENTER_VERTICAL | wxSHRINK); _use_dci_name = new wxCheckBox (_film_panel, wxID_ANY, _("Use DCI name")); - _film_sizer->Add (_use_dci_name, 1, wxEXPAND); + grid->Add (_use_dci_name, 1, wxEXPAND); _edit_dci_button = new wxButton (_film_panel, wxID_ANY, _("Details...")); - _film_sizer->Add (_edit_dci_button, 0); + grid->Add (_edit_dci_button, 0); - add_label_to_sizer (_film_sizer, _film_panel, _("Content")); + add_label_to_sizer (grid, _film_panel, _("Content")); _content = new wxFilePickerCtrl (_film_panel, wxID_ANY, wxT (""), _("Select Content File"), wxT("*.*")); - _film_sizer->Add (_content, 1, wxEXPAND); + grid->Add (_content, 1, wxEXPAND); _trust_content_header = new wxCheckBox (_film_panel, wxID_ANY, _("Trust content's header")); video_control (_trust_content_header); - _film_sizer->Add (_trust_content_header, 1); - _film_sizer->AddSpacer (0); + grid->Add (_trust_content_header, 1); + grid->AddSpacer (0); - add_label_to_sizer (_film_sizer, _film_panel, _("Content Type")); + add_label_to_sizer (grid, _film_panel, _("Content Type")); _dcp_content_type = new wxChoice (_film_panel, wxID_ANY); - _film_sizer->Add (_dcp_content_type); + grid->Add (_dcp_content_type); - video_control (add_label_to_sizer (_film_sizer, _film_panel, _("Frames Per Second"))); + video_control (add_label_to_sizer (grid, _film_panel, _("Frames Per Second"))); _frames_per_second = new wxStaticText (_film_panel, wxID_ANY, wxT ("")); - _film_sizer->Add (video_control (_frames_per_second), 1, wxALIGN_CENTER_VERTICAL); + grid->Add (video_control (_frames_per_second), 1, wxALIGN_CENTER_VERTICAL); - video_control (add_label_to_sizer (_film_sizer, _film_panel, _("Original Size"))); + video_control (add_label_to_sizer (grid, _film_panel, _("Original Size"))); _original_size = new wxStaticText (_film_panel, wxID_ANY, wxT ("")); - _film_sizer->Add (video_control (_original_size), 1, wxALIGN_CENTER_VERTICAL); + grid->Add (video_control (_original_size), 1, wxALIGN_CENTER_VERTICAL); - video_control (add_label_to_sizer (_film_sizer, _film_panel, _("Length"))); + video_control (add_label_to_sizer (grid, _film_panel, _("Length"))); _length = new wxStaticText (_film_panel, wxID_ANY, wxT ("")); - _film_sizer->Add (video_control (_length), 1, wxALIGN_CENTER_VERTICAL); + grid->Add (video_control (_length), 1, wxALIGN_CENTER_VERTICAL); { - video_control (add_label_to_sizer (_film_sizer, _film_panel, _("Trim frames"))); + video_control (add_label_to_sizer (grid, _film_panel, _("Trim frames"))); wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); video_control (add_label_to_sizer (s, _film_panel, _("Start"))); _trim_start = new wxSpinCtrl (_film_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)); @@ -146,24 +147,24 @@ FilmEditor::make_film_panel () _trim_end = new wxSpinCtrl (_film_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)); s->Add (video_control (_trim_end)); - _film_sizer->Add (s); + grid->Add (s); } _dcp_ab = new wxCheckBox (_film_panel, wxID_ANY, _("A/B")); video_control (_dcp_ab); - _film_sizer->Add (_dcp_ab, 1); - _film_sizer->AddSpacer (0); + grid->Add (_dcp_ab, 1); + grid->AddSpacer (0); /* STILL-only stuff */ { - still_control (add_label_to_sizer (_film_sizer, _film_panel, _("Duration"))); + still_control (add_label_to_sizer (grid, _film_panel, _("Duration"))); wxSizer* s = new wxBoxSizer (wxHORIZONTAL); _still_duration = new wxSpinCtrl (_film_panel); still_control (_still_duration); s->Add (_still_duration, 1, wxEXPAND); /* TRANSLATORS: `s' here is an abbreviation for seconds, the unit of time */ still_control (add_label_to_sizer (s, _film_panel, _("s"))); - _film_sizer->Add (s); + grid->Add (s); } vector const ct = DCPContentType::all (); @@ -217,17 +218,18 @@ void FilmEditor::make_video_panel () { _video_panel = new wxPanel (_notebook); - _video_sizer = new wxFlexGridSizer (2, 4, 4); - wxBoxSizer* pad = new wxBoxSizer (wxVERTICAL); - pad->Add (_video_sizer, 0, wxALL, 8); - _video_panel->SetSizer (pad); + _video_sizer = new wxBoxSizer (wxVERTICAL); + _video_panel->SetSizer (_video_sizer); + + wxFlexGridSizer* grid = new wxFlexGridSizer (2, 4, 4); + _video_sizer->Add (grid, 0, wxALL, 8); - add_label_to_sizer (_video_sizer, _video_panel, _("Format")); + add_label_to_sizer (grid, _video_panel, _("Format")); _format = new wxChoice (_video_panel, wxID_ANY); - _video_sizer->Add (_format); + grid->Add (_format); { - add_label_to_sizer (_video_sizer, _video_panel, _("Crop")); + add_label_to_sizer (grid, _video_panel, _("Crop")); wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); /* TRANSLATORS: L, R, T and B are abbreviations for Left, Right, Top, Bottom, the four edges @@ -246,12 +248,12 @@ FilmEditor::make_video_panel () _bottom_crop = new wxSpinCtrl (_video_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)); s->Add (_bottom_crop, 0); - _video_sizer->Add (s); + grid->Add (s); } /* VIDEO-only stuff */ { - video_control (add_label_to_sizer (_video_sizer, _video_panel, _("Filters"))); + video_control (add_label_to_sizer (grid, _video_panel, _("Filters"))); wxSizer* s = new wxBoxSizer (wxHORIZONTAL); _filters = new wxStaticText (_video_panel, wxID_ANY, _("None")); video_control (_filters); @@ -259,33 +261,33 @@ FilmEditor::make_video_panel () _filters_button = new wxButton (_video_panel, wxID_ANY, _("Edit...")); video_control (_filters_button); s->Add (_filters_button, 0); - _video_sizer->Add (s, 1); + grid->Add (s, 1); } - video_control (add_label_to_sizer (_video_sizer, _video_panel, _("Scaler"))); + video_control (add_label_to_sizer (grid, _video_panel, _("Scaler"))); _scaler = new wxChoice (_video_panel, wxID_ANY); - _video_sizer->Add (video_control (_scaler), 1); + grid->Add (video_control (_scaler), 1); vector const sc = Scaler::all (); for (vector::const_iterator i = sc.begin(); i != sc.end(); ++i) { _scaler->Append (std_to_wx ((*i)->name())); } - add_label_to_sizer (_video_sizer, _video_panel, _("Colour look-up table")); + add_label_to_sizer (grid, _video_panel, _("Colour look-up table")); _colour_lut = new wxChoice (_video_panel, wxID_ANY); for (int i = 0; i < 2; ++i) { _colour_lut->Append (std_to_wx (colour_lut_index_to_name (i))); } _colour_lut->SetSelection (0); - _video_sizer->Add (_colour_lut, 1, wxEXPAND); + grid->Add (_colour_lut, 1, wxEXPAND); { - add_label_to_sizer (_video_sizer, _video_panel, _("JPEG2000 bandwidth")); + add_label_to_sizer (grid, _video_panel, _("JPEG2000 bandwidth")); wxSizer* s = new wxBoxSizer (wxHORIZONTAL); _j2k_bandwidth = new wxSpinCtrl (_video_panel, wxID_ANY); s->Add (_j2k_bandwidth, 1); add_label_to_sizer (s, _video_panel, _("MBps")); - _video_sizer->Add (s, 1); + grid->Add (s, 1); } _left_crop->SetRange (0, 1024); @@ -302,13 +304,14 @@ void FilmEditor::make_audio_panel () { _audio_panel = new wxPanel (_notebook); - _audio_sizer = new wxFlexGridSizer (2, 4, 4); - wxBoxSizer* pad = new wxBoxSizer (wxVERTICAL); - pad->Add (_audio_sizer, 0, wxALL, 8); - _audio_panel->SetSizer (pad); + _audio_sizer = new wxBoxSizer (wxVERTICAL); + _audio_panel->SetSizer (_audio_sizer); + + wxFlexGridSizer* grid = new wxFlexGridSizer (2, 4, 4); + _audio_sizer->Add (grid, 0, wxALL, 8); { - video_control (add_label_to_sizer (_audio_sizer, _audio_panel, _("Audio Gain"))); + video_control (add_label_to_sizer (grid, _audio_panel, _("Audio Gain"))); wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); _audio_gain = new wxSpinCtrl (_audio_panel); s->Add (video_control (_audio_gain), 1); @@ -316,33 +319,33 @@ FilmEditor::make_audio_panel () _audio_gain_calculate_button = new wxButton (_audio_panel, wxID_ANY, _("Calculate...")); video_control (_audio_gain_calculate_button); s->Add (_audio_gain_calculate_button, 1, wxEXPAND); - _audio_sizer->Add (s); + grid->Add (s); } { - video_control (add_label_to_sizer (_audio_sizer, _audio_panel, _("Audio Delay"))); + video_control (add_label_to_sizer (grid, _audio_panel, _("Audio Delay"))); wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); _audio_delay = new wxSpinCtrl (_audio_panel); s->Add (video_control (_audio_delay), 1); /* TRANSLATORS: this is an abbreviation for milliseconds, the unit of time */ video_control (add_label_to_sizer (s, _audio_panel, _("ms"))); - _audio_sizer->Add (s); + grid->Add (s); } { _use_content_audio = new wxRadioButton (_audio_panel, wxID_ANY, _("Use content's audio"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP); - _audio_sizer->Add (video_control (_use_content_audio)); + grid->Add (video_control (_use_content_audio)); wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); _audio_stream = new wxChoice (_audio_panel, wxID_ANY); s->Add (video_control (_audio_stream), 1); _audio = new wxStaticText (_audio_panel, wxID_ANY, wxT ("")); s->Add (video_control (_audio), 1, wxALIGN_CENTER_VERTICAL | wxLEFT, 8); - _audio_sizer->Add (s, 1, wxEXPAND); + grid->Add (s, 1, wxEXPAND); } _use_external_audio = new wxRadioButton (_audio_panel, wxID_ANY, _("Use external audio")); - _audio_sizer->Add (_use_external_audio); - _audio_sizer->AddSpacer (0); + grid->Add (_use_external_audio); + grid->AddSpacer (0); assert (MAX_AUDIO_CHANNELS == 6); @@ -359,9 +362,9 @@ FilmEditor::make_audio_panel () }; for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) { - add_label_to_sizer (_audio_sizer, _audio_panel, channels[i]); + add_label_to_sizer (grid, _audio_panel, channels[i]); _external_audio[i] = new wxFilePickerCtrl (_audio_panel, wxID_ANY, wxT (""), _("Select Audio File"), wxT ("*.wav")); - _audio_sizer->Add (_external_audio[i], 1, wxEXPAND); + grid->Add (_external_audio[i], 1, wxEXPAND); } _audio_gain->SetRange (-60, 60); @@ -372,29 +375,29 @@ void FilmEditor::make_subtitle_panel () { _subtitle_panel = new wxPanel (_notebook); - _subtitle_sizer = new wxFlexGridSizer (2, 4, 4); - wxBoxSizer* pad = new wxBoxSizer (wxVERTICAL); - pad->Add (_subtitle_sizer, 0, wxALL, 8); - _subtitle_panel->SetSizer (pad); + _subtitle_sizer = new wxBoxSizer (wxVERTICAL); + _subtitle_panel->SetSizer (_subtitle_sizer); + wxFlexGridSizer* grid = new wxFlexGridSizer (2, 4, 4); + _subtitle_sizer->Add (grid, 0, wxALL, 8); _with_subtitles = new wxCheckBox (_subtitle_panel, wxID_ANY, _("With Subtitles")); video_control (_with_subtitles); - _subtitle_sizer->Add (_with_subtitles, 1); + grid->Add (_with_subtitles, 1); _subtitle_stream = new wxChoice (_subtitle_panel, wxID_ANY); - _subtitle_sizer->Add (video_control (_subtitle_stream)); + grid->Add (video_control (_subtitle_stream)); - video_control (add_label_to_sizer (_subtitle_sizer, _subtitle_panel, _("Subtitle Offset"))); + video_control (add_label_to_sizer (grid, _subtitle_panel, _("Subtitle Offset"))); _subtitle_offset = new wxSpinCtrl (_subtitle_panel); - _subtitle_sizer->Add (video_control (_subtitle_offset), 1); + grid->Add (video_control (_subtitle_offset), 1); { - video_control (add_label_to_sizer (_subtitle_sizer, _subtitle_panel, _("Subtitle Scale"))); + video_control (add_label_to_sizer (grid, _subtitle_panel, _("Subtitle Scale"))); wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); _subtitle_scale = new wxSpinCtrl (_subtitle_panel); s->Add (video_control (_subtitle_scale)); video_control (add_label_to_sizer (s, _subtitle_panel, _("%"))); - _subtitle_sizer->Add (s); + grid->Add (s); } _subtitle_offset->SetRange (-1024, 1024); -- cgit v1.2.3 From 7deb94e3cb9048891664f74d9c8a534ca6a24748 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 7 Feb 2013 00:00:41 +0000 Subject: Remove x264 dependency; add options to help building on mageia. --- src/wx/wscript | 2 +- wscript | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/wx/wscript b/src/wx/wscript index 47272f697..d844b1f1b 100644 --- a/src/wx/wscript +++ b/src/wx/wscript @@ -1,5 +1,5 @@ def configure(conf): - conf.check_cfg(package = '', path = 'wx-config', args = '--cppflags --cxxflags --libs', uselib_store = 'WXWIDGETS', mandatory = True) + conf.check_cfg(package = '', path = conf.options.wx_config, args = '--cppflags --cxxflags --libs', uselib_store = 'WXWIDGETS', mandatory = True) def build(bld): if bld.env.STATIC: diff --git a/wscript b/wscript index bf5cf1daa..43ac63548 100644 --- a/wscript +++ b/wscript @@ -13,6 +13,8 @@ def options(opt): opt.add_option('--disable-gui', action='store_true', default = False, help = 'disable building of GUI tools') opt.add_option('--target-windows', action='store_true', default = False, help = 'set up to do a cross-compile to Windows') opt.add_option('--static', action='store_true', default = False, help = 'build statically, and link statically to libdcp and FFmpeg') + opt.add_option('--magickpp-config', action='store', default='Magick++-config', help = 'path to Magick++-config') + opt.add_option('--wx-config', action='store', default='wx-config', help = 'path to wx-config') def configure(conf): conf.load('compiler_cxx') @@ -73,7 +75,7 @@ def configure(conf): conf.env.STLIB_AVFILTER = ['avfilter', 'swresample'] conf.env.HAVE_AVCODEC = 1 conf.env.STLIB_AVCODEC = ['avcodec'] - conf.env.LIB_AVCODEC = ['x264', 'z'] + conf.env.LIB_AVCODEC = ['z'] conf.env.HAVE_AVUTIL = 1 conf.env.STLIB_AVUTIL = ['avutil'] conf.env.HAVE_SWSCALE = 1 @@ -90,7 +92,7 @@ def configure(conf): conf.check_cfg(package = 'sndfile', args = '--cflags --libs', uselib_store = 'SNDFILE', mandatory = True) conf.check_cfg(package = 'glib-2.0', args = '--cflags --libs', uselib_store = 'GLIB', mandatory = True) conf.check_cfg(package = 'liblzma', args = '--cflags --libs', uselib_store = 'LZMA', mandatory = True) - conf.check_cfg(package = '', path = 'Magick++-config', args = '--cppflags --cxxflags --libs', uselib_store = 'MAGICK', mandatory = True) + conf.check_cfg(package = '', path = conf.options.magickpp_config, args = '--cppflags --cxxflags --libs', uselib_store = 'MAGICK', mandatory = True) if conf.options.static: conf.check_cc(fragment = """ -- cgit v1.2.3 From a70021afdc1e1fa026d8274f1bd2c905a7ced384 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 7 Feb 2013 00:57:09 +0000 Subject: Hopefully fix crash on trying to create a j2c file for the first time. --- src/lib/film.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/lib/film.cc b/src/lib/film.cc index 8720e79e4..0a989201b 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -1317,7 +1317,7 @@ Film::info_path (int f) const s << setfill('0') << f << ".md5"; p /= s.str(); - return p.string (); + return file (p.string ()); } string @@ -1336,7 +1336,7 @@ Film::j2c_path (int f, bool t) const } p /= s.str(); - return p.string (); + return file (p.string ()); } -- cgit v1.2.3 From dc096ebf9c5b793756f680c269e5ac7411da6978 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 7 Feb 2013 12:47:28 +0000 Subject: Remove old DCP before creating new one (#47). --- src/lib/writer.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 5bd32147a..94072e6e8 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -45,6 +45,9 @@ Writer::Writer (shared_ptr f) , _finish (false) , _last_written_frame (-1) { + /* Remove any old DCP */ + boost::filesystem::remove_all (_film->dir (_film->dcp_name ())); + check_existing_picture_mxf (); /* Create our picture asset in a subdirectory, named according to those -- cgit v1.2.3 From d238c04f7fb4d07e1c374ba884da8528692a9228 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 7 Feb 2013 12:48:24 +0000 Subject: Fix inadvertant breakage of hash file creation. --- src/lib/film.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/film.cc b/src/lib/film.cc index 0a989201b..34289e65f 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -1317,7 +1317,11 @@ Film::info_path (int f) const s << setfill('0') << f << ".md5"; p /= s.str(); - return file (p.string ()); + + /* info_dir() will already have added any initial bit of the path, + so don't call file() on this. + */ + return p.string (); } string -- cgit v1.2.3 From 76c5bf73c05a407ff0ceada320b821e0ca4868f9 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 7 Feb 2013 12:48:46 +0000 Subject: Remove make_dcp_job files. --- src/lib/make_dcp_job.cc | 160 ------------------------------------------------ src/lib/make_dcp_job.h | 46 -------------- 2 files changed, 206 deletions(-) delete mode 100644 src/lib/make_dcp_job.cc delete mode 100644 src/lib/make_dcp_job.h (limited to 'src') diff --git a/src/lib/make_dcp_job.cc b/src/lib/make_dcp_job.cc deleted file mode 100644 index 705521626..000000000 --- a/src/lib/make_dcp_job.cc +++ /dev/null @@ -1,160 +0,0 @@ -/* - Copyright (C) 2012 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -/** @file src/make_dcp_job.cc - * @brief A job to create DCPs. - */ - -#include -#include -#include -#include -#include -#include -extern "C" { -#include -} -#include "make_dcp_job.h" -#include "dcp_content_type.h" -#include "exceptions.h" -#include "options.h" -#include "imagemagick_decoder.h" -#include "film.h" - -using std::string; -using std::cout; -using boost::shared_ptr; - -/** @param f Film we are making the DCP for. - * @param o Options. - */ -MakeDCPJob::MakeDCPJob (shared_ptr f, shared_ptr o, shared_ptr req) - : Job (f, req) - , _opt (o) -{ - -} - -string -MakeDCPJob::name () const -{ - return String::compose ("Make DCP for %1", _film->name()); -} - -/** @param f DCP frame index */ -string -MakeDCPJob::j2c_path (int f) const -{ - SourceFrame const s = (f * dcp_frame_rate(_film->frames_per_second()).skip) + _film->dcp_trim_start(); - return _opt->frame_out_path (s, false); -} - -string -MakeDCPJob::wav_path (libdcp::Channel c) const -{ - return _opt->multichannel_audio_out_path (int (c), false); -} - -void -MakeDCPJob::run () -{ - if (!_film->dcp_length()) { - throw EncodeError ("cannot make a DCP when the source length is not known"); - } - - descend (0.9); - - string const dcp_path = _film->dir (_film->dcp_name()); - - /* Remove any old DCP */ - boost::filesystem::remove_all (dcp_path); - - DCPFrameRate const dfr = dcp_frame_rate (_film->frames_per_second ()); - - int frames = 0; - switch (_film->content_type ()) { - case VIDEO: - /* Source frames -> DCP frames */ - frames = _film->dcp_length().get() / dfr.skip; - break; - case STILL: - frames = _film->still_duration() * 24; - break; - } - - libdcp::DCP dcp (_film->dir (_film->dcp_name())); - dcp.Progress.connect (boost::bind (&MakeDCPJob::dcp_progress, this, _1)); - - shared_ptr cpl ( - new libdcp::CPL (_film->dir (_film->dcp_name()), _film->dcp_name(), _film->dcp_content_type()->libdcp_kind (), frames, dfr.frames_per_second) - ); - - dcp.add_cpl (cpl); - - descend (0.8); - - shared_ptr pa ( - new libdcp::MonoPictureAsset ( - boost::bind (&MakeDCPJob::j2c_path, this, _1), - _film->dir (_film->dcp_name()), - "video.mxf", - &dcp.Progress, - dfr.frames_per_second, - frames, - _opt->out_size - ) - ); - - ascend (); - - shared_ptr sa; - - if (_film->audio_channels() > 0) { - descend (0.1); - sa.reset ( - new libdcp::SoundAsset ( - boost::bind (&MakeDCPJob::wav_path, this, _1), - _film->dir (_film->dcp_name()), - "audio.mxf", - &dcp.Progress, - dfr.frames_per_second, - frames, - dcp_audio_channels (_film->audio_channels()) - ) - ); - ascend (); - } - - descend (0.05); - cpl->add_reel (shared_ptr (new libdcp::Reel (pa, sa, shared_ptr ()))); - ascend (); - - descend (0.05); - dcp.write_xml (); - ascend (); - - set_progress (1); - set_state (FINISHED_OK); -} - -void -MakeDCPJob::dcp_progress (float p) -{ - set_progress (p); -} diff --git a/src/lib/make_dcp_job.h b/src/lib/make_dcp_job.h deleted file mode 100644 index 1aa906b0a..000000000 --- a/src/lib/make_dcp_job.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - Copyright (C) 2012 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -/** @file src/make_dcp_job.h - * @brief A job to create DCPs. - */ - -#include "job.h" - -class EncodeOptions; - -/** @class MakeDCPJob - * @brief A job to create DCPs - */ -class MakeDCPJob : public Job -{ -public: - MakeDCPJob (boost::shared_ptr, boost::shared_ptr, boost::shared_ptr req); - - std::string name () const; - void run (); - -private: - void dcp_progress (float); - std::string j2c_path (int) const; - std::string wav_path (libdcp::Channel) const; - - boost::shared_ptr _opt; -}; - -- cgit v1.2.3 From 9298f5a03786be14cfe3c37871e76f749617e6ca Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 7 Feb 2013 14:53:14 +0000 Subject: Add believed missing frame done. --- src/lib/encoder.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index b92be84a8..ccca719a3 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -256,6 +256,7 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptrcan_fake_write (_video_frames_out)) { _writer->fake_write (_video_frames_out); _have_a_real_frame = false; + frame_done (); } else if (same && _have_a_real_frame) { /* Use the last frame that we encoded. */ _writer->repeat (_video_frames_out); -- cgit v1.2.3 From f5c77f7acdcdd1cc178f172dd49b48c9648b8c8b Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 7 Feb 2013 15:30:30 +0000 Subject: Create parent directories on file() as well as dir(). --- src/lib/film.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/film.cc b/src/lib/film.cc index 34289e65f..e759b761c 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -449,7 +449,7 @@ Film::read_metadata () ifstream f (file ("metadata").c_str()); if (!f.good()) { - throw OpenFileError (file("metadata")); + throw OpenFileError (file ("metadata")); } multimap kv = read_key_value (f); @@ -601,23 +601,31 @@ string Film::dir (string d) const { boost::mutex::scoped_lock lm (_directory_mutex); + boost::filesystem::path p; p /= _directory; p /= d; + boost::filesystem::create_directories (p); + return p.string (); } /** Given a file or directory name, return its full path within the Film's directory. * _directory_mutex must not be locked on entry. + * Any required parent directories will be created. */ string Film::file (string f) const { boost::mutex::scoped_lock lm (_directory_mutex); + boost::filesystem::path p; p /= _directory; p /= f; + + boost::filesystem::create_directories (p.parent_path ()); + return p.string (); } -- cgit v1.2.3 From 82c4d63241354fa392428a6c752f34bbf676069a Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 7 Feb 2013 20:33:46 +0000 Subject: Simplify writer a bit and fix it when frames are arriving quickly. --- src/lib/writer.cc | 77 ++++++++++++++++++++++++++----------------------------- src/lib/writer.h | 4 +-- 2 files changed, 38 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 94072e6e8..91a692ba0 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -33,16 +33,18 @@ using std::make_pair; using std::pair; using std::string; using std::ifstream; +using std::list; using std::cout; using boost::shared_ptr; -unsigned int const Writer::_maximum_frames_in_memory = 8; +int const Writer::_maximum_frames_in_memory = 8; Writer::Writer (shared_ptr f) : _film (f) , _first_nonexistant_frame (0) , _thread (0) , _finish (false) + , _queued_full_in_memory (0) , _last_written_frame (-1) { /* Remove any old DCP */ @@ -93,6 +95,7 @@ Writer::write (shared_ptr encoded, int frame) qi.encoded = encoded; qi.frame = frame; _queue.push_back (qi); + ++_queued_full_in_memory; _condition.notify_all (); } @@ -129,21 +132,22 @@ Writer::thread () boost::mutex::scoped_lock lock (_mutex); while (1) { + + _queue.sort (); + if (_finish || - _queue.size() > _maximum_frames_in_memory || + _queued_full_in_memory > _maximum_frames_in_memory || (!_queue.empty() && _queue.front().frame == (_last_written_frame + 1))) { - - break; - } - - TIMING ("writer sleeps with a queue of %1; %2 pending", _queue.size(), _pending.size()); - _condition.wait (lock); - TIMING ("writer wakes with a queue of %1", _queue.size()); - - _queue.sort (); + + break; + } + + TIMING ("writer sleeps with a queue of %1", _queue.size()); + _condition.wait (lock); + TIMING ("writer wakes with a queue of %1", _queue.size()); } - if (_finish && _queue.empty() && _pending.empty()) { + if (_finish && _queue.empty()) { return; } @@ -151,12 +155,18 @@ Writer::thread () while (!_queue.empty() && _queue.front().frame == (_last_written_frame + 1)) { QueueItem qi = _queue.front (); _queue.pop_front (); + if (qi.type == QueueItem::FULL && qi.encoded) { + --_queued_full_in_memory; + } lock.unlock (); switch (qi.type) { case QueueItem::FULL: { _film->log()->log (String::compose ("Writer FULL-writes %1 to MXF", qi.frame)); + if (!qi.encoded) { + qi.encoded.reset (new EncodedData (_film->j2c_path (qi.frame, false))); + } libdcp::FrameInfo const fin = _picture_asset_writer->write (qi.encoded->data(), qi.encoded->size()); qi.encoded->write_info (_film, qi.frame, fin); _last_written = qi.encoded; @@ -180,41 +190,26 @@ Writer::thread () ++_last_written_frame; } - while (_queue.size() > _maximum_frames_in_memory) { + while (_queued_full_in_memory > _maximum_frames_in_memory) { /* Too many frames in memory which can't yet be written to the stream. - Put some in our pending list (and write FULL queue items' data to disk) + Write some FULL frames to disk. */ - QueueItem qi = _queue.back (); - _queue.pop_back (); - - if (qi.type == QueueItem::FULL) { - lock.unlock (); - _film->log()->log (String::compose ("Writer full (awaiting %1); pushes %2 to disk", _last_written_frame + 1, qi.frame)); - qi.encoded->write (_film, qi.frame); - lock.lock (); - qi.encoded.reset (); + /* Find one */ + list::reverse_iterator i = _queue.rbegin (); + while (i != _queue.rend() && (i->type != QueueItem::FULL || !i->encoded)) { + ++i; } - _pending.push_back (qi); - } + assert (i != _queue.rend()); + QueueItem qi = *i; - while (_queue.size() < _maximum_frames_in_memory && !_pending.empty()) { - /* We have some space in memory. Fetch some frames back off disk. */ - - _pending.sort (); - QueueItem qi = _pending.front (); - - if (qi.type == QueueItem::FULL) { - lock.unlock (); - _film->log()->log (String::compose ("Writer pulls %1 back from disk", qi.frame)); - shared_ptr encoded; - qi.encoded.reset (new EncodedData (_film->j2c_path (qi.frame, false))); - lock.lock (); - } - - _queue.push_back (qi); - _pending.remove (qi); + lock.unlock (); + _film->log()->log (String::compose ("Writer full (awaiting %1); pushes %2 to disk", _last_written_frame + 1, qi.frame)); + qi.encoded->write (_film, qi.frame); + lock.lock (); + qi.encoded.reset (); + --_queued_full_in_memory; } } diff --git a/src/lib/writer.h b/src/lib/writer.h index 57609825d..68e422a50 100644 --- a/src/lib/writer.h +++ b/src/lib/writer.h @@ -77,12 +77,12 @@ private: boost::thread* _thread; bool _finish; std::list _queue; + int _queued_full_in_memory; mutable boost::mutex _mutex; boost::condition _condition; boost::shared_ptr _last_written; - std::list _pending; int _last_written_frame; - static const unsigned int _maximum_frames_in_memory; + static const int _maximum_frames_in_memory; boost::shared_ptr _picture_asset; boost::shared_ptr _picture_asset_writer; -- cgit v1.2.3 From 67ac2b512788c5c331ff57b2d8bf571fd58d0ebf Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 7 Feb 2013 22:02:16 +0000 Subject: Possibly fix legacy dcp_trim_start tags; use DCI name for content type to be a little more i18n friendly. --- src/lib/dcp_content_type.cc | 12 ++++++++++++ src/lib/dcp_content_type.h | 1 + src/lib/film.cc | 14 +++++++++----- 3 files changed, 22 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/lib/dcp_content_type.cc b/src/lib/dcp_content_type.cc index aae805308..1c96979e4 100644 --- a/src/lib/dcp_content_type.cc +++ b/src/lib/dcp_content_type.cc @@ -63,6 +63,18 @@ DCPContentType::from_pretty_name (string n) return 0; } +DCPContentType const * +DCPContentType::from_dci_name (string n) +{ + for (vector::const_iterator i = _dcp_content_types.begin(); i != _dcp_content_types.end(); ++i) { + if ((*i)->dci_name() == n) { + return *i; + } + } + + return 0; +} + DCPContentType const * DCPContentType::from_index (int n) { diff --git a/src/lib/dcp_content_type.h b/src/lib/dcp_content_type.h index 2b6e60a19..960bb0129 100644 --- a/src/lib/dcp_content_type.h +++ b/src/lib/dcp_content_type.h @@ -50,6 +50,7 @@ public: } static DCPContentType const * from_pretty_name (std::string); + static DCPContentType const * from_dci_name (std::string); static DCPContentType const * from_index (int); static int as_index (DCPContentType const *); static std::vector all (); diff --git a/src/lib/film.cc b/src/lib/film.cc index e759b761c..59f79e666 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -72,7 +72,7 @@ using boost::starts_with; using boost::optional; using libdcp::Size; -int const Film::state_version = 2; +int const Film::state_version = 3; /** Construct a Film object in a given directory, reading any metadata * file that exists in that directory. An exception will be thrown if @@ -374,7 +374,7 @@ Film::write_metadata () const f << "content " << _content << "\n"; f << "trust_content_header " << (_trust_content_header ? "1" : "0") << "\n"; if (_dcp_content_type) { - f << "dcp_content_type " << _dcp_content_type->pretty_name () << "\n"; + f << "dcp_content_type " << _dcp_content_type->dci_name () << "\n"; } if (_format) { f << "format " << _format->as_metadata () << "\n"; @@ -478,7 +478,11 @@ Film::read_metadata () } else if (k == "trust_content_header") { _trust_content_header = (v == "1"); } else if (k == "dcp_content_type") { - _dcp_content_type = DCPContentType::from_pretty_name (v); + if (version < 3) { + _dcp_content_type = DCPContentType::from_pretty_name (v); + } else { + _dcp_content_type = DCPContentType::from_dci_name (v); + } } else if (k == "format") { _format = Format::from_metadata (v); } else if (k == "left_crop") { @@ -493,9 +497,9 @@ Film::read_metadata () _filters.push_back (Filter::from_id (v)); } else if (k == "scaler") { _scaler = Scaler::from_id (v); - } else if ( ((!version || version < 2) && k == "trim_start") || k == "trim_start") { + } else if ( ((!version || version < 2) && k == "dcp_trim_start") || k == "trim_start") { _trim_start = atoi (v.c_str ()); - } else if ( ((!version || version < 2) && k == "trim_end") || k == "trim_end") { + } else if ( ((!version || version < 2) && k == "dcp_trim_end") || k == "trim_end") { _trim_end = atoi (v.c_str ()); } else if (k == "dcp_ab") { _dcp_ab = (v == "1"); -- cgit v1.2.3 From c8e32123f94a9bb7c3bd13611053bcf6ce08b760 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 8 Feb 2013 12:19:51 +0000 Subject: Log some stats from the writer. --- src/lib/writer.cc | 20 ++++++++++++++++++++ src/lib/writer.h | 5 +++++ 2 files changed, 25 insertions(+) (limited to 'src') diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 91a692ba0..563acc02d 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -46,6 +46,10 @@ Writer::Writer (shared_ptr f) , _finish (false) , _queued_full_in_memory (0) , _last_written_frame (-1) + , _full_written (0) + , _fake_written (0) + , _repeat_written (0) + , _pushed_to_disk (0) { /* Remove any old DCP */ boost::filesystem::remove_all (_film->dir (_film->dcp_name ())); @@ -159,6 +163,18 @@ Writer::thread () --_queued_full_in_memory; } + switch (qi.type) { + case QueueItem::FULL: + ++_full_written; + break; + case QueueItem::FAKE: + ++_fake_written; + break; + case QueueItem::REPEAT: + ++_repeat_written; + break; + } + lock.unlock (); switch (qi.type) { case QueueItem::FULL: @@ -204,6 +220,8 @@ Writer::thread () assert (i != _queue.rend()); QueueItem qi = *i; + ++_pushed_to_disk; + lock.unlock (); _film->log()->log (String::compose ("Writer full (awaiting %1); pushes %2 to disk", _last_written_frame + 1, qi.frame)); qi.encoded->write (_film, qi.frame); @@ -284,6 +302,8 @@ Writer::finish () )); dcp.write_xml (); + + _film->log()->log (String::compose ("Wrote %1 FULL, %2 FAKE, %3 REPEAT; %4 pushed to disk", _full_written, _fake_written, _repeat_written, _pushed_to_disk)); } /** Tell the writer that frame `f' should be a repeat of the frame before it */ diff --git a/src/lib/writer.h b/src/lib/writer.h index 68e422a50..ba989b022 100644 --- a/src/lib/writer.h +++ b/src/lib/writer.h @@ -84,6 +84,11 @@ private: int _last_written_frame; static const int _maximum_frames_in_memory; + int _full_written; + int _fake_written; + int _repeat_written; + int _pushed_to_disk; + boost::shared_ptr _picture_asset; boost::shared_ptr _picture_asset_writer; boost::shared_ptr _sound_asset; -- cgit v1.2.3 From c188b321ccda7972021b64017a3655be5f19f21e Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 8 Feb 2013 12:30:23 +0000 Subject: A couple of comments; tidy up logging. --- src/lib/writer.cc | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 563acc02d..1df8a4301 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -163,18 +163,6 @@ Writer::thread () --_queued_full_in_memory; } - switch (qi.type) { - case QueueItem::FULL: - ++_full_written; - break; - case QueueItem::FAKE: - ++_fake_written; - break; - case QueueItem::REPEAT: - ++_repeat_written; - break; - } - lock.unlock (); switch (qi.type) { case QueueItem::FULL: @@ -186,18 +174,21 @@ Writer::thread () libdcp::FrameInfo const fin = _picture_asset_writer->write (qi.encoded->data(), qi.encoded->size()); qi.encoded->write_info (_film, qi.frame, fin); _last_written = qi.encoded; + ++_full_written; break; } case QueueItem::FAKE: _film->log()->log (String::compose ("Writer FAKE-writes %1 to MXF", qi.frame)); _picture_asset_writer->fake_write (qi.size); _last_written.reset (); + ++_fake_written; break; case QueueItem::REPEAT: { _film->log()->log (String::compose ("Writer REPEAT-writes %1 to MXF", qi.frame)); libdcp::FrameInfo const fin = _picture_asset_writer->write (_last_written->data(), _last_written->size()); _last_written->write_info (_film, qi.frame, fin); + ++_repeat_written; break; } } @@ -358,10 +349,15 @@ Writer::check_existing_picture_mxf () fclose (mxf); } -/** @return true if the fake write succeeded, otherwise false */ +/** @param frame Frame index. + * @return true if we can fake-write this frame. + */ bool Writer::can_fake_write (int frame) const { + /* We have to do a proper write of the first frame so that we can set up the JPEG2000 + parameters in the MXF writer. + */ return (frame != 0 && frame < _first_nonexistant_frame); } -- cgit v1.2.3 From bfd87f274b440b3c10bde8e6cdc45bedbadd9a9b Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 8 Feb 2013 12:38:04 +0000 Subject: Some comments. --- src/lib/writer.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'src') diff --git a/src/lib/writer.h b/src/lib/writer.h index ba989b022..cee20acb9 100644 --- a/src/lib/writer.h +++ b/src/lib/writer.h @@ -37,8 +37,14 @@ struct QueueItem { public: enum Type { + /** a normal frame with some JPEG200 data */ FULL, + /** a frame whose data already exists in the MXF, + and we fake-write it; i.e. we update the writer's + state but we use the data that is already on disk. + */ FAKE, + /** this is a repeat of the last frame to be written */ REPEAT } type; @@ -71,22 +77,41 @@ private: void thread (); void check_existing_picture_mxf (); + /** our Film */ boost::shared_ptr _film; + /** the first frame index that does not already exist in our MXF */ int _first_nonexistant_frame; + /** our thread, or 0 */ boost::thread* _thread; + /** true if our thread should finish */ bool _finish; + /** queue of things to write to disk */ std::list _queue; + /** number of FULL frames whose JPEG200 data is currently held in RAM */ int _queued_full_in_memory; + /** mutex for thread state */ mutable boost::mutex _mutex; + /** condition to manage thread wakeups */ boost::condition _condition; + /** the data of the last written frame, or 0 if there isn't one */ boost::shared_ptr _last_written; + /** the index of the last written frame */ int _last_written_frame; + /** maximum number of frames to hold in memory, for when we are managing + ordering + */ static const int _maximum_frames_in_memory; + /** number of FULL written frames */ int _full_written; + /** number of FAKE written frames */ int _fake_written; + /** number of REPEAT written frames */ int _repeat_written; + /** number of frames pushed to disk and then recovered + due to the limit of frames to be held in memory. + */ int _pushed_to_disk; boost::shared_ptr _picture_asset; -- cgit v1.2.3 From 748995a13c2a6758ef867b2b78b945342768bae7 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 8 Feb 2013 12:47:51 +0000 Subject: Rename some things. --- src/lib/encoder.cc | 74 +++++++++++++++++++++++++++--------------------------- src/lib/encoder.h | 14 +++++------ 2 files changed, 44 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index ccca719a3..8d8e8c0e4 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -61,14 +61,14 @@ Encoder::Encoder (shared_ptr f) , _swr_context (0) #endif , _have_a_real_frame (false) - , _terminate_encoder (false) + , _terminate (false) { } Encoder::~Encoder () { - terminate_worker_threads (); + terminate_threads (); if (_writer) { _writer->finish (); } @@ -107,14 +107,14 @@ Encoder::process_begin () } for (int i = 0; i < Config::instance()->num_local_encoding_threads (); ++i) { - _worker_threads.push_back (new boost::thread (boost::bind (&Encoder::encoder_thread, this, (ServerDescription *) 0))); + _threads.push_back (new boost::thread (boost::bind (&Encoder::encoder_thread, this, (ServerDescription *) 0))); } vector servers = Config::instance()->servers (); for (vector::iterator i = servers.begin(); i != servers.end(); ++i) { for (int j = 0; j < (*i)->threads (); ++j) { - _worker_threads.push_back (new boost::thread (boost::bind (&Encoder::encoder_thread, this, *i))); + _threads.push_back (new boost::thread (boost::bind (&Encoder::encoder_thread, this, *i))); } } @@ -149,33 +149,33 @@ Encoder::process_end () } #endif - boost::mutex::scoped_lock lock (_worker_mutex); + boost::mutex::scoped_lock lock (_mutex); - _film->log()->log ("Clearing queue of " + lexical_cast (_encode_queue.size ())); + _film->log()->log ("Clearing queue of " + lexical_cast (_queue.size ())); /* Keep waking workers until the queue is empty */ - while (!_encode_queue.empty ()) { - _film->log()->log ("Waking with " + lexical_cast (_encode_queue.size ()), Log::VERBOSE); - _worker_condition.notify_all (); - _worker_condition.wait (lock); + while (!_queue.empty ()) { + _film->log()->log ("Waking with " + lexical_cast (_queue.size ()), Log::VERBOSE); + _condition.notify_all (); + _condition.wait (lock); } lock.unlock (); - terminate_worker_threads (); + terminate_threads (); - _film->log()->log ("Mopping up " + lexical_cast (_encode_queue.size())); + _film->log()->log ("Mopping up " + lexical_cast (_queue.size())); /* The following sequence of events can occur in the above code: 1. a remote worker takes the last image off the queue 2. the loop above terminates 3. the remote worker fails to encode the image and puts it back on the queue - 4. the remote worker is then terminated by terminate_worker_threads + 4. the remote worker is then terminated by terminate_threads So just mop up anything left in the queue here. */ - for (list >::iterator i = _encode_queue.begin(); i != _encode_queue.end(); ++i) { + for (list >::iterator i = _queue.begin(); i != _queue.end(); ++i) { _film->log()->log (String::compose ("Encode left-over frame %1", (*i)->frame ())); try { _writer->write ((*i)->encode_locally(), (*i)->frame ()); @@ -240,16 +240,16 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptr= _worker_threads.size() * 2 && !_terminate_encoder) { - TIMING ("decoder sleeps with queue of %1", _encode_queue.size()); - _worker_condition.wait (lock); - TIMING ("decoder wakes with queue of %1", _encode_queue.size()); + while (_queue.size() >= _threads.size() * 2 && !_terminate) { + TIMING ("decoder sleeps with queue of %1", _queue.size()); + _condition.wait (lock); + TIMING ("decoder wakes with queue of %1", _queue.size()); } - if (_terminate_encoder) { + if (_terminate) { return; } @@ -264,8 +264,8 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptr const s = Filter::ffmpeg_strings (_film->filters()); - TIMING ("adding to queue of %1", _encode_queue.size ()); - _encode_queue.push_back (boost::shared_ptr ( + TIMING ("adding to queue of %1", _queue.size ()); + _queue.push_back (boost::shared_ptr ( new DCPVideoFrame ( image, sub, _film->format()->dcp_size(), _film->format()->dcp_padding (_film), _film->subtitle_offset(), _film->subtitle_scale(), @@ -275,7 +275,7 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptr data) } void -Encoder::terminate_worker_threads () +Encoder::terminate_threads () { - boost::mutex::scoped_lock lock (_worker_mutex); - _terminate_encoder = true; - _worker_condition.notify_all (); + boost::mutex::scoped_lock lock (_mutex); + _terminate = true; + _condition.notify_all (); lock.unlock (); - for (list::iterator i = _worker_threads.begin(); i != _worker_threads.end(); ++i) { + for (list::iterator i = _threads.begin(); i != _threads.end(); ++i) { (*i)->join (); delete *i; } @@ -362,19 +362,19 @@ Encoder::encoder_thread (ServerDescription* server) while (1) { TIMING ("encoder thread %1 sleeps", boost::this_thread::get_id()); - boost::mutex::scoped_lock lock (_worker_mutex); - while (_encode_queue.empty () && !_terminate_encoder) { - _worker_condition.wait (lock); + boost::mutex::scoped_lock lock (_mutex); + while (_queue.empty () && !_terminate) { + _condition.wait (lock); } - if (_terminate_encoder) { + if (_terminate) { return; } - TIMING ("encoder thread %1 wakes with queue of %2", boost::this_thread::get_id(), _encode_queue.size()); - boost::shared_ptr vf = _encode_queue.front (); + TIMING ("encoder thread %1 wakes with queue of %2", boost::this_thread::get_id(), _queue.size()); + boost::shared_ptr vf = _queue.front (); _film->log()->log (String::compose ("Encoder thread %1 pops frame %2 from queue", boost::this_thread::get_id(), vf->frame()), Log::VERBOSE); - _encode_queue.pop_front (); + _queue.pop_front (); lock.unlock (); @@ -421,7 +421,7 @@ Encoder::encoder_thread (ServerDescription* server) _film->log()->log ( String::compose ("Encoder thread %1 pushes frame %2 back onto queue after failure", boost::this_thread::get_id(), vf->frame()) ); - _encode_queue.push_front (vf); + _queue.push_front (vf); lock.unlock (); } @@ -430,6 +430,6 @@ Encoder::encoder_thread (ServerDescription* server) } lock.lock (); - _worker_condition.notify_all (); + _condition.notify_all (); } } diff --git a/src/lib/encoder.h b/src/lib/encoder.h index 8b02f7004..69a5c5a23 100644 --- a/src/lib/encoder.h +++ b/src/lib/encoder.h @@ -21,7 +21,7 @@ #define DVDOMATIC_ENCODER_H /** @file src/encoder.h - * @brief Parent class for classes which can encode video and audio frames. + * @brief Encoder to J2K and WAV for DCP. */ #include @@ -91,7 +91,7 @@ private: void write_audio (boost::shared_ptr audio); void encoder_thread (ServerDescription *); - void terminate_worker_threads (); + void terminate_threads (); /** Film that we are encoding */ boost::shared_ptr _film; @@ -115,11 +115,11 @@ private: #endif bool _have_a_real_frame; - bool _terminate_encoder; - std::list > _encode_queue; - std::list _worker_threads; - mutable boost::mutex _worker_mutex; - boost::condition _worker_condition; + bool _terminate; + std::list > _queue; + std::list _threads; + mutable boost::mutex _mutex; + boost::condition _condition; boost::shared_ptr _writer; }; -- cgit v1.2.3 From 567abac0d7824f27b8fdcd6fb7da7e5ddae62a0f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 8 Feb 2013 12:54:15 +0000 Subject: Some comments. --- src/lib/encoder.cc | 4 +--- src/lib/video_decoder.cc | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 8d8e8c0e4..0c810d12c 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -50,9 +50,7 @@ using namespace boost; int const Encoder::_history_size = 25; -/** @param f Film that we are encoding. - * @param o Options. - */ +/** @param f Film that we are encoding */ Encoder::Encoder (shared_ptr f) : _film (f) , _video_frames_in (0) diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc index 0fa16bc32..c11b752ae 100644 --- a/src/lib/video_decoder.cc +++ b/src/lib/video_decoder.cc @@ -53,6 +53,10 @@ VideoDecoder::emit_video (shared_ptr image, double t) _last_source_time = t; } +/** Called by subclasses to repeat the last video frame that we + * passed to emit_video(). If emit_video hasn't yet been called, + * we will generate a black frame. + */ void VideoDecoder::repeat_last_video () { @@ -64,6 +68,11 @@ VideoDecoder::repeat_last_video () signal_video (_last_image, true, _last_subtitle); } +/** Emit our signal to say that some video data is ready. + * @param image Video frame. + * @param same true if `image' is the same as the last one we emitted. + * @param sub Subtitle for this frame, or 0. + */ void VideoDecoder::signal_video (shared_ptr image, bool same, shared_ptr sub) { @@ -75,6 +84,11 @@ VideoDecoder::signal_video (shared_ptr image, bool same, shared_ptr s) { @@ -86,6 +100,9 @@ VideoDecoder::emit_subtitle (shared_ptr s) } } +/** Set which stream of subtitles we should use from our source. + * @param s Stream to use. + */ void VideoDecoder::set_subtitle_stream (shared_ptr s) { -- cgit v1.2.3 From 2e536ef0971edefea23810b99f7706881072783b Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 8 Feb 2013 13:07:16 +0000 Subject: Shuffle Job pointers around slightly. --- src/lib/ab_transcoder.cc | 8 +++++--- src/lib/audio_decoder.cc | 4 ++-- src/lib/audio_decoder.h | 2 +- src/lib/decoder.cc | 5 +---- src/lib/decoder.h | 5 +---- src/lib/decoder_factory.cc | 10 +++++----- src/lib/decoder_factory.h | 3 +-- src/lib/examine_content_job.cc | 4 ++-- src/lib/external_audio_decoder.cc | 6 +++--- src/lib/external_audio_decoder.h | 2 +- src/lib/ffmpeg_decoder.cc | 8 ++++---- src/lib/ffmpeg_decoder.h | 2 +- src/lib/film.cc | 4 ++-- src/lib/imagemagick_decoder.cc | 6 +++--- src/lib/imagemagick_decoder.h | 2 +- src/lib/transcoder.cc | 6 ++++-- src/lib/video_decoder.cc | 12 +++++++----- src/lib/video_decoder.h | 4 ++-- src/wx/film_viewer.cc | 2 +- 19 files changed, 47 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/lib/ab_transcoder.cc b/src/lib/ab_transcoder.cc index fc4fb8daa..f47a99fda 100644 --- a/src/lib/ab_transcoder.cc +++ b/src/lib/ab_transcoder.cc @@ -55,8 +55,8 @@ ABTranscoder::ABTranscoder ( , _job (j) , _encoder (e) { - _da = decoder_factory (_film_a, o, j); - _db = decoder_factory (_film_b, o, j); + _da = decoder_factory (_film_a, o); + _db = decoder_factory (_film_b, o); if (_film_a->audio_stream()) { shared_ptr st = _film_a->audio_stream(); @@ -98,7 +98,9 @@ ABTranscoder::go () bool const vb = _db.video->pass (); bool const a = _da.audio->pass (); - _da.video->set_progress (); + if (_job) { + _da.video->set_progress (_job); + } if (va && vb && a) { break; diff --git a/src/lib/audio_decoder.cc b/src/lib/audio_decoder.cc index a038dd2bb..a54c14843 100644 --- a/src/lib/audio_decoder.cc +++ b/src/lib/audio_decoder.cc @@ -23,8 +23,8 @@ using boost::optional; using boost::shared_ptr; -AudioDecoder::AudioDecoder (shared_ptr f, DecodeOptions o, Job* j) - : Decoder (f, o, j) +AudioDecoder::AudioDecoder (shared_ptr f, DecodeOptions o) + : Decoder (f, o) { } diff --git a/src/lib/audio_decoder.h b/src/lib/audio_decoder.h index 3bf585f4d..9bef8e0e7 100644 --- a/src/lib/audio_decoder.h +++ b/src/lib/audio_decoder.h @@ -34,7 +34,7 @@ class AudioDecoder : public AudioSource, public virtual Decoder { public: - AudioDecoder (boost::shared_ptr, DecodeOptions, Job *); + AudioDecoder (boost::shared_ptr, DecodeOptions); virtual void set_audio_stream (boost::shared_ptr); diff --git a/src/lib/decoder.cc b/src/lib/decoder.cc index fd0abee41..30009460f 100644 --- a/src/lib/decoder.cc +++ b/src/lib/decoder.cc @@ -26,7 +26,6 @@ #include #include "film.h" #include "format.h" -#include "job.h" #include "options.h" #include "exceptions.h" #include "image.h" @@ -47,12 +46,10 @@ using boost::optional; /** @param f Film. * @param o Decode options. - * @param j Job that we are running within, or 0 */ -Decoder::Decoder (boost::shared_ptr f, DecodeOptions o, Job* j) +Decoder::Decoder (boost::shared_ptr f, DecodeOptions o) : _film (f) , _opt (o) - , _job (j) { _film_connection = f->Changed.connect (bind (&Decoder::film_changed, this, _1)); } diff --git a/src/lib/decoder.h b/src/lib/decoder.h index cc4c87373..f2f523516 100644 --- a/src/lib/decoder.h +++ b/src/lib/decoder.h @@ -36,7 +36,6 @@ #include "film.h" #include "options.h" -class Job; class Image; class Log; class DelayLine; @@ -54,7 +53,7 @@ class FilterGraph; class Decoder { public: - Decoder (boost::shared_ptr, DecodeOptions, Job *); + Decoder (boost::shared_ptr, DecodeOptions); virtual ~Decoder () {} virtual bool pass () = 0; @@ -68,8 +67,6 @@ protected: boost::shared_ptr _film; /** our decode options */ DecodeOptions _opt; - /** associated Job, or 0 */ - Job* _job; private: virtual void film_changed (Film::Property) {} diff --git a/src/lib/decoder_factory.cc b/src/lib/decoder_factory.cc index c4d818f49..59e15722d 100644 --- a/src/lib/decoder_factory.cc +++ b/src/lib/decoder_factory.cc @@ -36,21 +36,21 @@ using boost::dynamic_pointer_cast; Decoders decoder_factory ( - shared_ptr f, DecodeOptions o, Job* j + shared_ptr f, DecodeOptions o ) { if (boost::filesystem::is_directory (f->content_path()) || f->content_type() == STILL) { /* A single image file, or a directory of them */ return Decoders ( - shared_ptr (new ImageMagickDecoder (f, o, j)), - shared_ptr (new ExternalAudioDecoder (f, o, j)) + shared_ptr (new ImageMagickDecoder (f, o)), + shared_ptr (new ExternalAudioDecoder (f, o)) ); } - shared_ptr fd (new FFmpegDecoder (f, o, j)); + shared_ptr fd (new FFmpegDecoder (f, o)); if (f->use_content_audio()) { return Decoders (fd, fd); } - return Decoders (fd, shared_ptr (new ExternalAudioDecoder (f, o, j))); + return Decoders (fd, shared_ptr (new ExternalAudioDecoder (f, o))); } diff --git a/src/lib/decoder_factory.h b/src/lib/decoder_factory.h index 445a1c8a2..8076b01c7 100644 --- a/src/lib/decoder_factory.h +++ b/src/lib/decoder_factory.h @@ -27,7 +27,6 @@ #include "options.h" class Film; -class Job; class VideoDecoder; class AudioDecoder; @@ -44,7 +43,7 @@ struct Decoders { }; extern Decoders decoder_factory ( - boost::shared_ptr, DecodeOptions, Job * + boost::shared_ptr, DecodeOptions ); #endif diff --git a/src/lib/examine_content_job.cc b/src/lib/examine_content_job.cc index 69a757e2b..94e5320fe 100644 --- a/src/lib/examine_content_job.cc +++ b/src/lib/examine_content_job.cc @@ -81,7 +81,7 @@ ExamineContentJob::run () DecodeOptions o; o.decode_audio = false; - Decoders decoders = decoder_factory (_film, o, this); + Decoders decoders = decoder_factory (_film, o); set_progress_unknown (); while (!decoders.video->pass()) { @@ -96,7 +96,7 @@ ExamineContentJob::run () /* Get a quick decoder to get the content's length from its header */ - Decoders d = decoder_factory (_film, DecodeOptions(), 0); + Decoders d = decoder_factory (_film, DecodeOptions()); _film->set_length (d.video->length()); _film->log()->log (String::compose ("Video length obtained from header as %1 frames", _film->length().get())); diff --git a/src/lib/external_audio_decoder.cc b/src/lib/external_audio_decoder.cc index 366051418..9c01bfb34 100644 --- a/src/lib/external_audio_decoder.cc +++ b/src/lib/external_audio_decoder.cc @@ -31,9 +31,9 @@ using std::cout; using boost::shared_ptr; using boost::optional; -ExternalAudioDecoder::ExternalAudioDecoder (shared_ptr f, DecodeOptions o, Job* j) - : Decoder (f, o, j) - , AudioDecoder (f, o, j) +ExternalAudioDecoder::ExternalAudioDecoder (shared_ptr f, DecodeOptions o) + : Decoder (f, o) + , AudioDecoder (f, o) { sf_count_t frames; vector sf = open_files (frames); diff --git a/src/lib/external_audio_decoder.h b/src/lib/external_audio_decoder.h index 37e53bca7..6f010abb1 100644 --- a/src/lib/external_audio_decoder.h +++ b/src/lib/external_audio_decoder.h @@ -44,7 +44,7 @@ private: class ExternalAudioDecoder : public AudioDecoder { public: - ExternalAudioDecoder (boost::shared_ptr, DecodeOptions, Job *); + ExternalAudioDecoder (boost::shared_ptr, DecodeOptions); bool pass (); diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 81f405644..1f11f70a0 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -60,10 +60,10 @@ using boost::optional; using boost::dynamic_pointer_cast; using libdcp::Size; -FFmpegDecoder::FFmpegDecoder (shared_ptr f, DecodeOptions o, Job* j) - : Decoder (f, o, j) - , VideoDecoder (f, o, j) - , AudioDecoder (f, o, j) +FFmpegDecoder::FFmpegDecoder (shared_ptr f, DecodeOptions o) + : Decoder (f, o) + , VideoDecoder (f, o) + , AudioDecoder (f, o) , _format_context (0) , _video_stream (-1) , _frame (0) diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h index 9a4e65ebc..17308eb56 100644 --- a/src/lib/ffmpeg_decoder.h +++ b/src/lib/ffmpeg_decoder.h @@ -86,7 +86,7 @@ private: class FFmpegDecoder : public VideoDecoder, public AudioDecoder { public: - FFmpegDecoder (boost::shared_ptr, DecodeOptions, Job *); + FFmpegDecoder (boost::shared_ptr, DecodeOptions); ~FFmpegDecoder (); float frames_per_second () const; diff --git a/src/lib/film.cc b/src/lib/film.cc index 59f79e666..ff4d3b8f5 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -857,7 +857,7 @@ Film::set_content (string c) */ try { - Decoders d = decoder_factory (shared_from_this(), DecodeOptions(), 0); + Decoders d = decoder_factory (shared_from_this(), DecodeOptions()); set_size (d.video->native_size ()); set_frames_per_second (d.video->frames_per_second ()); @@ -1079,7 +1079,7 @@ Film::set_external_audio (vector a) _external_audio = a; } - shared_ptr decoder (new ExternalAudioDecoder (shared_from_this(), DecodeOptions(), 0)); + shared_ptr decoder (new ExternalAudioDecoder (shared_from_this(), DecodeOptions())); if (decoder->audio_stream()) { _external_audio_stream = decoder->audio_stream (); } diff --git a/src/lib/imagemagick_decoder.cc b/src/lib/imagemagick_decoder.cc index 99b9e1d34..42fe699d7 100644 --- a/src/lib/imagemagick_decoder.cc +++ b/src/lib/imagemagick_decoder.cc @@ -30,9 +30,9 @@ using boost::shared_ptr; using libdcp::Size; ImageMagickDecoder::ImageMagickDecoder ( - boost::shared_ptr f, DecodeOptions o, Job* j) - : Decoder (f, o, j) - , VideoDecoder (f, o, j) + boost::shared_ptr f, DecodeOptions o) + : Decoder (f, o) + , VideoDecoder (f, o) { if (boost::filesystem::is_directory (_film->content_path())) { for ( diff --git a/src/lib/imagemagick_decoder.h b/src/lib/imagemagick_decoder.h index 84a6f15f9..0e375f6e9 100644 --- a/src/lib/imagemagick_decoder.h +++ b/src/lib/imagemagick_decoder.h @@ -26,7 +26,7 @@ namespace Magick { class ImageMagickDecoder : public VideoDecoder { public: - ImageMagickDecoder (boost::shared_ptr, DecodeOptions, Job *); + ImageMagickDecoder (boost::shared_ptr, DecodeOptions); float frames_per_second () const { /* We don't know */ diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc index 93963761e..959fac857 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -51,7 +51,7 @@ using boost::dynamic_pointer_cast; Transcoder::Transcoder (shared_ptr f, DecodeOptions o, Job* j, shared_ptr e) : _job (j) , _encoder (e) - , _decoders (decoder_factory (f, o, j)) + , _decoders (decoder_factory (f, o)) { assert (_encoder); @@ -96,7 +96,9 @@ Transcoder::go () while (1) { if (!done[0]) { done[0] = _decoders.video->pass (); - _decoders.video->set_progress (); + if (_job) { + _decoders.video->set_progress (_job); + } } if (!done[1] && _decoders.audio && dynamic_pointer_cast (_decoders.audio) != dynamic_pointer_cast (_decoders.video)) { diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc index c11b752ae..c1f48cb5e 100644 --- a/src/lib/video_decoder.cc +++ b/src/lib/video_decoder.cc @@ -28,8 +28,8 @@ using boost::shared_ptr; using boost::optional; -VideoDecoder::VideoDecoder (shared_ptr f, DecodeOptions o, Job* j) - : Decoder (f, o, j) +VideoDecoder::VideoDecoder (shared_ptr f, DecodeOptions o) + : Decoder (f, o) , _video_frame (0) , _last_source_time (0) { @@ -110,9 +110,11 @@ VideoDecoder::set_subtitle_stream (shared_ptr s) } void -VideoDecoder::set_progress () const +VideoDecoder::set_progress (Job* j) const { - if (_job && _film->length()) { - _job->set_progress (float (_video_frame) / _film->length().get()); + assert (j); + + if (_film->length()) { + j->set_progress (float (_video_frame) / _film->length().get()); } } diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h index ef1ab041a..283ab5d88 100644 --- a/src/lib/video_decoder.h +++ b/src/lib/video_decoder.h @@ -27,7 +27,7 @@ class VideoDecoder : public VideoSource, public virtual Decoder { public: - VideoDecoder (boost::shared_ptr, DecodeOptions, Job *); + VideoDecoder (boost::shared_ptr, DecodeOptions); /** @return video frames per second, or 0 if unknown */ virtual float frames_per_second () const = 0; @@ -43,7 +43,7 @@ public: virtual void set_subtitle_stream (boost::shared_ptr); - void set_progress () const; + void set_progress (Job *) const; int video_frame () const { return _video_frame; diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 4e5f38300..4e779a693 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -101,7 +101,7 @@ FilmViewer::film_changed (Film::Property p) o.decode_audio = false; o.decode_subtitles = true; o.video_sync = false; - _decoders = decoder_factory (_film, o, 0); + _decoders = decoder_factory (_film, o); _decoders.video->Video.connect (bind (&FilmViewer::process_video, this, _1, _2, _3)); _decoders.video->OutputChanged.connect (boost::bind (&FilmViewer::decoder_changed, this)); _decoders.video->set_subtitle_stream (_film->subtitle_stream()); -- cgit v1.2.3 From 31450fc1ec394e091afd9f373b03d92d822ff7c4 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 11 Feb 2013 00:13:05 +0000 Subject: Add copyright year. --- src/tools/dvdomatic.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 0565d3a1c..4572678e3 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -354,7 +354,7 @@ public: info.SetVersion (std_to_wx (String::compose ("version %1 git %2", dvdomatic_version, dvdomatic_git_commit))); } info.SetDescription (_("Free, open-source DCP generation from almost anything.")); - info.SetCopyright (_("(C) Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen")); + info.SetCopyright (_("(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen")); wxArrayString authors; authors.Add (wxT ("Carl Hetherington")); authors.Add (wxT ("Terrence Meiczinger")); -- cgit v1.2.3 From b45f90d8d504c15b60d2ae3a3344e8beb2947f8a Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 11 Feb 2013 00:13:18 +0000 Subject: Reformatting. --- src/lib/wscript | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/wscript b/src/lib/wscript index 454565cdc..eee04190c 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -6,7 +6,11 @@ def build(bld): obj.name = 'libdvdomatic' obj.export_includes = ['.'] - obj.uselib = 'AVCODEC AVUTIL AVFORMAT AVFILTER SWSCALE SWRESAMPLE SNDFILE BOOST_FILESYSTEM BOOST_THREAD BOOST_DATETIME BOOST_SIGNALS2 OPENJPEG POSTPROC TIFF MAGICK SSH DCP GLIB LZMA' + obj.uselib = """ + AVCODEC AVUTIL AVFORMAT AVFILTER SWSCALE SWRESAMPLE + BOOST_FILESYSTEM BOOST_THREAD BOOST_DATETIME BOOST_SIGNALS2 + SNDFILE OPENJPEG POSTPROC TIFF MAGICK SSH DCP GLIB LZMA + """ if bld.env.TARGET_WINDOWS: obj.uselib += ' WINSOCK2' obj.source = """ -- cgit v1.2.3 From beea3beacba34c11b6b73323f4c3c8590a9aa73e Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 11 Feb 2013 00:18:40 +0000 Subject: Basic attempt to catch exceptions in the writer thread and pass them safely back to the GUI. --- src/lib/encoder.cc | 4 ++++ src/lib/exceptions.h | 32 ++++++++++++++++++++++++++++++++ src/lib/writer.cc | 13 ++++++++++--- src/lib/writer.h | 5 +++-- 4 files changed, 49 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 0c810d12c..d64622cba 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -251,6 +251,10 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptrthrown ()) { + _writer->rethrow (); + } + if (_writer->can_fake_write (_video_frames_out)) { _writer->fake_write (_video_frames_out); _have_a_real_frame = false; diff --git a/src/lib/exceptions.h b/src/lib/exceptions.h index bf8e85f0b..e757d2506 100644 --- a/src/lib/exceptions.h +++ b/src/lib/exceptions.h @@ -17,6 +17,9 @@ */ +#ifndef DVDOMATIC_EXCEPTIONS_H +#define DVDOMATIC_EXCEPTIONS_H + /** @file src/exceptions.h * @brief Our exceptions. */ @@ -24,6 +27,8 @@ #include #include #include +#include +#include /** @class StringError * @brief A parent class for exceptions using messages held in a std::string @@ -224,3 +229,30 @@ public: : StringError (s) {} }; + +class ExceptionStore +{ +public: + bool thrown () const { + boost::mutex::scoped_lock lm (_mutex); + return _exception; + } + + void rethrow () { + boost::mutex::scoped_lock lm (_mutex); + boost::rethrow_exception (_exception); + } + +protected: + + void store_current () { + boost::mutex::scoped_lock lm (_mutex); + _exception = boost::current_exception (); + } + +private: + boost::exception_ptr _exception; + mutable boost::mutex _mutex; +}; + +#endif diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 1df8a4301..8a09f254b 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -85,7 +85,7 @@ Writer::Writer (shared_ptr f) _sound_asset_writer = _sound_asset->start_write (); } - + _thread = new boost::thread (boost::bind (&Writer::thread, this)); } @@ -130,6 +130,7 @@ Writer::write (shared_ptr audio) void Writer::thread () +try { while (1) { @@ -221,7 +222,10 @@ Writer::thread () --_queued_full_in_memory; } } - +} +catch (...) +{ + store_current (); } void @@ -237,6 +241,10 @@ Writer::finish () lock.unlock (); _thread->join (); + if (thrown ()) { + rethrow (); + } + delete _thread; _thread = 0; @@ -361,7 +369,6 @@ Writer::can_fake_write (int frame) const return (frame != 0 && frame < _first_nonexistant_frame); } - bool operator< (QueueItem const & a, QueueItem const & b) { diff --git a/src/lib/writer.h b/src/lib/writer.h index cee20acb9..beb16c7b9 100644 --- a/src/lib/writer.h +++ b/src/lib/writer.h @@ -21,6 +21,7 @@ #include #include #include +#include "exceptions.h" class Film; class EncodedData; @@ -59,7 +60,7 @@ public: bool operator< (QueueItem const & a, QueueItem const & b); bool operator== (QueueItem const & a, QueueItem const & b); -class Writer +class Writer : public ExceptionStore { public: Writer (boost::shared_ptr); @@ -113,7 +114,7 @@ private: due to the limit of frames to be held in memory. */ int _pushed_to_disk; - + boost::shared_ptr _picture_asset; boost::shared_ptr _picture_asset_writer; boost::shared_ptr _sound_asset; -- cgit v1.2.3 From 8e0242d7edcea2944aef3382f70e4e2fab7d12d9 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 11 Feb 2013 00:36:42 +0000 Subject: Adapt properties dialog for direct MXF write. --- src/wx/properties_dialog.cc | 18 +++++------------- src/wx/properties_dialog.h | 3 +-- 2 files changed, 6 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/wx/properties_dialog.cc b/src/wx/properties_dialog.cc index 338d0f972..a57aaf5b9 100644 --- a/src/wx/properties_dialog.cc +++ b/src/wx/properties_dialog.cc @@ -42,13 +42,9 @@ PropertiesDialog::PropertiesDialog (wxWindow* parent, shared_ptr film) _frames = new wxStaticText (this, wxID_ANY, wxT ("")); table->Add (_frames, 1, wxALIGN_CENTER_VERTICAL); - add_label_to_sizer (table, this, _("Disk space required for frames")); - _disk_for_frames = new wxStaticText (this, wxID_ANY, wxT ("")); - table->Add (_disk_for_frames, 1, wxALIGN_CENTER_VERTICAL); - - add_label_to_sizer (table, this, _("Total disk space required")); - _total_disk = new wxStaticText (this, wxID_ANY, wxT ("")); - table->Add (_total_disk, 1, wxALIGN_CENTER_VERTICAL); + add_label_to_sizer (table, this, _("Disk space required")); + _disk = new wxStaticText (this, wxID_ANY, wxT ("")); + table->Add (_disk, 1, wxALIGN_CENTER_VERTICAL); add_label_to_sizer (table, this, _("Frames already encoded")); _encoded = new ThreadedStaticText (this, _("counting..."), boost::bind (&PropertiesDialog::frames_already_encoded, this)); @@ -59,14 +55,10 @@ PropertiesDialog::PropertiesDialog (wxWindow* parent, shared_ptr film) double const disk = ((double) _film->j2k_bandwidth() / 8) * _film->length().get() / (_film->frames_per_second () * 1073741824); stringstream s; s << fixed << setprecision (1) << disk << "Gb"; - _disk_for_frames->SetLabel (std_to_wx (s.str ())); - stringstream t; - t << fixed << setprecision (1) << (disk * 2) << "Gb"; - _total_disk->SetLabel (std_to_wx (t.str ())); + _disk->SetLabel (std_to_wx (s.str ())); } else { _frames->SetLabel (_("unknown")); - _disk_for_frames->SetLabel (_("unknown")); - _total_disk->SetLabel (_("unknown")); + _disk->SetLabel (_("unknown")); } wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL); diff --git a/src/wx/properties_dialog.h b/src/wx/properties_dialog.h index 308c0f7b3..cae929e18 100644 --- a/src/wx/properties_dialog.h +++ b/src/wx/properties_dialog.h @@ -32,8 +32,7 @@ private: boost::shared_ptr _film; wxStaticText* _frames; - wxStaticText* _disk_for_frames; - wxStaticText* _total_disk; + wxStaticText* _disk; ThreadedStaticText* _encoded; }; -- cgit v1.2.3 From e650b7b674d2739b932b3429415e5d785e5f0246 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 11 Feb 2013 20:21:22 +0000 Subject: Fix default directory for film's setup on Windows (#49). --- src/wx/dir_picker_ctrl.cc | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/wx/dir_picker_ctrl.cc b/src/wx/dir_picker_ctrl.cc index b6558a881..ec7854764 100644 --- a/src/wx/dir_picker_ctrl.cc +++ b/src/wx/dir_picker_ctrl.cc @@ -19,6 +19,7 @@ #include #include +#include #include #include "dir_picker_ctrl.h" #include "wx_util.h" @@ -52,6 +53,9 @@ DirPickerCtrl::SetPath (wxString p) } else { _folder->SetLabel (std_to_wx (filesystem::path (wx_to_std (_path)).leaf().string())); } + + wxCommandEvent ev (wxEVT_COMMAND_DIRPICKER_CHANGED, wxID_ANY); + GetEventHandler()->ProcessEvent (ev); } wxString -- cgit v1.2.3 From 106c8fb2d471cb0b01da3b6b09e743304a869f4b Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 11 Feb 2013 23:56:33 +0000 Subject: Check for a DCP before offering to copy it to a TMS. --- src/lib/film.cc | 36 ++++++++++++++++++++++++++++++------ src/lib/film.h | 12 +++++++----- src/tools/dvdomatic.cc | 29 ++++++++++++++++++++++------- src/wx/film_editor.cc | 23 ++++++++++++++--------- src/wx/film_editor.h | 1 + test/metadata.ref | 1 + test/test.cc | 35 +++++++++++++++++++++++++++++++---- 7 files changed, 106 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/lib/film.cc b/src/lib/film.cc index ff4d3b8f5..36ebe7199 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -63,7 +63,6 @@ using std::ofstream; using std::setfill; using std::min; using std::make_pair; -using std::cout; using boost::shared_ptr; using boost::lexical_cast; using boost::to_upper_copy; @@ -104,6 +103,8 @@ Film::Film (string d, bool must_exist) , _frames_per_second (0) , _dirty (false) { + set_dci_date_today (); + /* Make state.directory a complete path without ..s (where possible) (Code swiped from Adam Bowen on stackoverflow) */ @@ -139,7 +140,6 @@ Film::Film (string d, bool must_exist) } _log = new FileLog (file ("log")); - set_dci_date_today (); } Film::Film (Film const & o) @@ -171,6 +171,7 @@ Film::Film (Film const & o) , _colour_lut (o._colour_lut) , _j2k_bandwidth (o._j2k_bandwidth) , _dci_metadata (o._dci_metadata) + , _dci_date (o._dci_date) , _size (o._size) , _length (o._length) , _dcp_intrinsic_duration (o._dcp_intrinsic_duration) @@ -409,6 +410,7 @@ Film::write_metadata () const f << "colour_lut " << _colour_lut << "\n"; f << "j2k_bandwidth " << _j2k_bandwidth << "\n"; _dci_metadata.write (f); + f << "dci_date " << boost::gregorian::to_iso_string (_dci_date) << "\n"; f << "width " << _size.width << "\n"; f << "height " << _size.height << "\n"; f << "length " << _length.get_value_or(0) << "\n"; @@ -535,6 +537,8 @@ Film::read_metadata () _colour_lut = atoi (v.c_str ()); } else if (k == "j2k_bandwidth") { _j2k_bandwidth = atoi (v.c_str ()); + } else if (k == "dci_date") { + _dci_date = boost::gregorian::from_undelimited_string (v); } _dci_metadata.read (k, v); @@ -696,7 +700,7 @@ Film::still_duration_in_frames () const /** @return a DCI-compliant name for a DCP of this film */ string -Film::dci_name () const +Film::dci_name (bool if_created_now) const { stringstream d; @@ -764,7 +768,11 @@ Film::dci_name () const d << dm.studio << "_"; } - d << boost::gregorian::to_iso_string (_dci_date) << "_"; + if (if_created_now) { + d << boost::gregorian::to_iso_string (boost::gregorian::day_clock::local_day ()) << "_"; + } else { + d << boost::gregorian::to_iso_string (_dci_date) << "_"; + } if (!dm.facility.empty ()) { d << dm.facility << "_"; @@ -779,10 +787,10 @@ Film::dci_name () const /** @return name to give the DCP */ string -Film::dcp_name () const +Film::dcp_name (bool if_created_now) const { if (use_dci_name()) { - return dci_name (); + return dci_name (if_created_now); } return name(); @@ -1355,4 +1363,20 @@ Film::j2c_path (int f, bool t) const return file (p.string ()); } +/** Make an educated guess as to whether we have a complete DCP + * or not. + * @return true if we do. + */ +bool +Film::have_dcp () const +{ + try { + libdcp::DCP dcp (dir (dcp_name())); + dcp.read (); + } catch (...) { + return false; + } + + return true; +} diff --git a/src/lib/film.h b/src/lib/film.h index 5b65a099d..cc77460db 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -92,8 +92,8 @@ public: void read_metadata (); libdcp::Size cropped_size (libdcp::Size) const; - std::string dci_name () const; - std::string dcp_name () const; + std::string dci_name (bool if_created_now) const; + std::string dcp_name (bool if_created_now = false) const; boost::optional dcp_intrinsic_duration () const { return _dcp_intrinsic_duration; @@ -108,6 +108,8 @@ public: void set_dci_date_today (); + bool have_dcp () const; + /** Identifiers for the parts of our state; used for signalling changes. */ @@ -373,9 +375,6 @@ private: /** Any running ExamineContentJob, or 0 */ boost::shared_ptr _examine_content_job; - /** The date that we should use in a DCI name */ - boost::gregorian::date _dci_date; - void signal_changed (Property); void examine_content_finished (); std::string video_state_identifier () const; @@ -452,6 +451,8 @@ private: /** DCI naming stuff */ DCIMetadata _dci_metadata; + /** The date that we should use in a DCI name */ + boost::gregorian::date _dci_date; /* Data which are cached to speed things up */ @@ -478,6 +479,7 @@ private: mutable boost::mutex _state_mutex; friend class paths_test; + friend class film_metadata_test; }; #endif diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 4572678e3..b90f3b07f 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -54,6 +54,7 @@ static FilmViewer* film_viewer = 0; static shared_ptr film; static std::string log_level; static std::string film_to_load; +static wxMenu* jobs_menu = 0; static void set_menu_sensitivity (); @@ -159,19 +160,19 @@ setup_menu (wxMenuBar* m) wxMenu* edit = new wxMenu; add_item (edit, "&Preferences...", ID_edit_preferences, ALWAYS); - wxMenu* jobs = new wxMenu; - add_item (jobs, "&Make DCP", ID_jobs_make_dcp, NEEDS_FILM); - add_item (jobs, "&Send DCP to TMS", ID_jobs_send_dcp_to_tms, NEEDS_FILM); - jobs->AppendSeparator (); - add_item (jobs, "&Examine content", ID_jobs_examine_content, NEEDS_FILM); - add_item (jobs, "Make DCP from existing &transcode", ID_jobs_make_dcp_from_existing_transcode, NEEDS_FILM); + jobs_menu = new wxMenu; + add_item (jobs_menu, "&Make DCP", ID_jobs_make_dcp, NEEDS_FILM); + add_item (jobs_menu, "&Send DCP to TMS", ID_jobs_send_dcp_to_tms, NEEDS_FILM); + jobs_menu->AppendSeparator (); + add_item (jobs_menu, "&Examine content", ID_jobs_examine_content, NEEDS_FILM); + add_item (jobs_menu, "Make DCP from existing &transcode", ID_jobs_make_dcp_from_existing_transcode, NEEDS_FILM); wxMenu* help = new wxMenu; add_item (help, "About", ID_help_about, ALWAYS); m->Append (file, _("&File")); m->Append (edit, _("&Edit")); - m->Append (jobs, _("&Jobs")); + m->Append (jobs_menu, _("&Jobs")); m->Append (help, _("&Help")); } @@ -204,6 +205,8 @@ public: Connect (ID_jobs_make_dcp_from_existing_transcode, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::jobs_make_dcp_from_existing_transcode)); Connect (ID_help_about, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::help_about)); + Connect (wxID_ANY, wxEVT_MENU_OPEN, wxMenuEventHandler (Frame::menu_opened)); + wxPanel* panel = new wxPanel (this); wxSizer* s = new wxBoxSizer (wxHORIZONTAL); s->Add (panel, 1, wxEXPAND); @@ -237,6 +240,18 @@ public: set_film (); } +private: + + void menu_opened (wxMenuEvent& ev) + { + if (ev.GetMenu() != jobs_menu) { + return; + } + + bool const have_dcp = film && film->have_dcp(); + jobs_menu->Enable (ID_jobs_send_dcp_to_tms, have_dcp); + } + void set_film () { film_viewer->set_film (film); diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 634e417df..956084261 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -585,7 +585,7 @@ FilmEditor::film_changed (Film::Property p) } else { checked_set (_format, n); } - _dcp_name->SetLabel (std_to_wx (_film->dcp_name ())); + setup_dcp_name (); break; } case Film::CROP: @@ -608,8 +608,7 @@ FilmEditor::film_changed (Film::Property p) } case Film::NAME: checked_set (_name, _film->name()); - _film->set_dci_date_today (); - _dcp_name->SetLabel (std_to_wx (_film->dcp_name ())); + setup_dcp_name (); break; case Film::FRAMES_PER_SECOND: s << fixed << setprecision(2) << _film->frames_per_second(); @@ -639,7 +638,7 @@ FilmEditor::film_changed (Film::Property p) break; case Film::DCP_CONTENT_TYPE: checked_set (_dcp_content_type, DCPContentType::as_index (_film->dcp_content_type ())); - _dcp_name->SetLabel (std_to_wx (_film->dcp_name ())); + setup_dcp_name (); break; case Film::DCP_AB: checked_set (_dcp_ab, _film->dcp_ab ()); @@ -665,7 +664,7 @@ FilmEditor::film_changed (Film::Property p) case Film::WITH_SUBTITLES: checked_set (_with_subtitles, _film->with_subtitles ()); setup_subtitle_control_sensitivity (); - _dcp_name->SetLabel (std_to_wx (_film->dcp_name ())); + setup_dcp_name (); break; case Film::SUBTITLE_OFFSET: checked_set (_subtitle_offset, _film->subtitle_offset ()); @@ -681,23 +680,23 @@ FilmEditor::film_changed (Film::Property p) break; case Film::USE_DCI_NAME: checked_set (_use_dci_name, _film->use_dci_name ()); - _dcp_name->SetLabel (std_to_wx (_film->dcp_name ())); + setup_dcp_name (); break; case Film::DCI_METADATA: - _dcp_name->SetLabel (std_to_wx (_film->dcp_name ())); + setup_dcp_name (); break; case Film::CONTENT_AUDIO_STREAM: if (_film->content_audio_stream()) { checked_set (_audio_stream, _film->content_audio_stream()->to_string()); } - _dcp_name->SetLabel (std_to_wx (_film->dcp_name ())); + setup_dcp_name (); setup_audio_details (); setup_audio_control_sensitivity (); break; case Film::USE_CONTENT_AUDIO: checked_set (_use_content_audio, _film->use_content_audio()); checked_set (_use_external_audio, !_film->use_content_audio()); - _dcp_name->SetLabel (std_to_wx (_film->dcp_name ())); + setup_dcp_name (); setup_audio_details (); setup_audio_control_sensitivity (); break; @@ -1171,3 +1170,9 @@ FilmEditor::external_audio_changed (wxCommandEvent &) _film->set_external_audio (a); } + +void +FilmEditor::setup_dcp_name () +{ + _dcp_name->SetLabel (std_to_wx (_film->dcp_name (true))); +} diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index 90be752d8..8cb90b481 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -94,6 +94,7 @@ private: void setup_audio_control_sensitivity (); void setup_streams (); void setup_audio_details (); + void setup_dcp_name (); wxControl* video_control (wxControl *); wxControl* still_control (wxControl *); diff --git a/test/metadata.ref b/test/metadata.ref index 4250bdf23..ab40dfe8d 100644 --- a/test/metadata.ref +++ b/test/metadata.ref @@ -31,6 +31,7 @@ rating studio facility package_type +dci_date 20130211 width 0 height 0 length 0 diff --git a/test/test.cc b/test/test.cc index 771ef9992..75199fac7 100644 --- a/test/test.cc +++ b/test/test.cc @@ -21,6 +21,7 @@ #include #include #include +#include #include "format.h" #include "film.h" #include "filter.h" @@ -60,14 +61,25 @@ setup_test_config () Config::instance()->set_default_dci_metadata (DCIMetadata ()); } +boost::filesystem::path +test_film_dir (string name) +{ + boost::filesystem::path p; + p /= "build"; + p /= "test"; + p /= name; + return p; +} + shared_ptr new_test_film (string name) { - string const d = String::compose ("build/test/%1", name); - if (boost::filesystem::exists (d)) { - boost::filesystem::remove_all (d); + boost::filesystem::path p = test_film_dir (name); + if (boost::filesystem::exists (p)) { + boost::filesystem::remove_all (p); } - return shared_ptr (new Film (d, false)); + + return shared_ptr (new Film (p.string(), false)); } @@ -144,6 +156,7 @@ BOOST_AUTO_TEST_CASE (film_metadata_test) BOOST_CHECK_THROW (new Film (test_film, true), OpenFileError); shared_ptr f (new Film (test_film, false)); + f->_dci_date = boost::gregorian::from_undelimited_string ("20130211"); BOOST_CHECK (f->format() == 0); BOOST_CHECK (f->dcp_content_type() == 0); BOOST_CHECK (f->filters ().empty()); @@ -468,6 +481,7 @@ BOOST_AUTO_TEST_CASE (make_dcp_test) film->set_format (Format::from_nickname ("Flat")); film->set_dcp_content_type (DCPContentType::from_pretty_name ("Test")); film->make_dcp (true); + film->write_metadata (); while (JobManager::instance()->work_to_do ()) { dvdomatic_sleep (1); @@ -476,6 +490,19 @@ BOOST_AUTO_TEST_CASE (make_dcp_test) BOOST_CHECK_EQUAL (JobManager::instance()->errors(), false); } +/** Test Film::have_dcp(). Requires the output from make_dcp_test above */ +BOOST_AUTO_TEST_CASE (have_dcp_test) +{ + boost::filesystem::path p = test_film_dir ("make_dcp_test"); + Film f (p.string ()); + BOOST_CHECK (f.have_dcp()); + + p /= f.dcp_name(); + p /= "video.mxf"; + boost::filesystem::remove (p); + BOOST_CHECK (!f.have_dcp ()); +} + BOOST_AUTO_TEST_CASE (make_dcp_with_range_test) { shared_ptr film = new_test_film ("make_dcp_with_range_test"); -- cgit v1.2.3 From e118ae9353cc3a3052cad2d07b43ec40e56f0074 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 12 Feb 2013 19:37:05 +0000 Subject: Don't try to make decoders when there is no content. --- src/lib/decoder_factory.cc | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/lib/decoder_factory.cc b/src/lib/decoder_factory.cc index 59e15722d..478ccd1c1 100644 --- a/src/lib/decoder_factory.cc +++ b/src/lib/decoder_factory.cc @@ -39,6 +39,10 @@ decoder_factory ( shared_ptr f, DecodeOptions o ) { + if (f->content().empty()) { + return Decoders (); + } + if (boost::filesystem::is_directory (f->content_path()) || f->content_type() == STILL) { /* A single image file, or a directory of them */ return Decoders ( -- cgit v1.2.3 From e22b479faa80d20ae6c5749b2334e5f3c21ef599 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 12 Feb 2013 19:37:15 +0000 Subject: Cope better with having no decoders. --- src/wx/film_viewer.cc | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 4e779a693..a619edf7c 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -102,6 +102,9 @@ FilmViewer::film_changed (Film::Property p) o.decode_subtitles = true; o.video_sync = false; _decoders = decoder_factory (_film, o); + if (_decoders.video == 0) { + break; + } _decoders.video->Video.connect (bind (&FilmViewer::process_video, this, _1, _2, _3)); _decoders.video->OutputChanged.connect (boost::bind (&FilmViewer::decoder_changed, this)); _decoders.video->set_subtitle_stream (_film->subtitle_stream()); @@ -121,7 +124,9 @@ FilmViewer::film_changed (Film::Property p) update_from_raw (); break; case Film::SUBTITLE_STREAM: - _decoders.video->set_subtitle_stream (_film->subtitle_stream ()); + if (_decoders.video) { + _decoders.video->set_subtitle_stream (_film->subtitle_stream ()); + } break; default: break; @@ -155,7 +160,7 @@ FilmViewer::set_film (shared_ptr f) void FilmViewer::decoder_changed () { - if (_decoders.video->seek_to_last ()) { + if (_decoders.video == 0 || _decoders.video->seek_to_last ()) { return; } @@ -167,7 +172,7 @@ FilmViewer::decoder_changed () void FilmViewer::timer (wxTimerEvent &) { - if (!_film) { + if (!_film || !_decoders.video) { return; } @@ -222,7 +227,7 @@ FilmViewer::paint_panel (wxPaintEvent &) void FilmViewer::slider_moved (wxScrollEvent &) { - if (!_film || !_film->length()) { + if (!_film || !_film->length() || !_decoders.video) { return; } @@ -373,6 +378,11 @@ FilmViewer::get_frame () { /* Clear our raw frame in case we don't get a new one */ _raw_frame.reset (); + + if (_decoders.video == 0) { + _display_frame.reset (); + return; + } try { _got_frame = false; -- cgit v1.2.3 From 1d938d62dae5a21a87b0f416302d51f154f89663 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 12 Feb 2013 19:37:31 +0000 Subject: Primitive opening of DCP's containing folder (#51). --- src/tools/dvdomatic.cc | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'src') diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index b90f3b07f..3281fc113 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -19,6 +19,9 @@ #include #include +#ifdef __WXMSW__ +#include +#endif #include #include #include @@ -44,6 +47,7 @@ using std::cout; using std::string; +using std::wstring; using std::stringstream; using std::map; using std::make_pair; @@ -139,6 +143,7 @@ enum { ID_edit_preferences, ID_jobs_make_dcp, ID_jobs_send_dcp_to_tms, + ID_jobs_show_dcp, ID_jobs_examine_content, ID_jobs_make_dcp_from_existing_transcode, ID_help_about @@ -163,6 +168,7 @@ setup_menu (wxMenuBar* m) jobs_menu = new wxMenu; add_item (jobs_menu, "&Make DCP", ID_jobs_make_dcp, NEEDS_FILM); add_item (jobs_menu, "&Send DCP to TMS", ID_jobs_send_dcp_to_tms, NEEDS_FILM); + add_item (jobs_menu, "S&how DCP", ID_jobs_show_dcp, NEEDS_FILM); jobs_menu->AppendSeparator (); add_item (jobs_menu, "&Examine content", ID_jobs_examine_content, NEEDS_FILM); add_item (jobs_menu, "Make DCP from existing &transcode", ID_jobs_make_dcp_from_existing_transcode, NEEDS_FILM); @@ -201,6 +207,7 @@ public: Connect (ID_edit_preferences, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::edit_preferences)); Connect (ID_jobs_make_dcp, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::jobs_make_dcp)); Connect (ID_jobs_send_dcp_to_tms, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::jobs_send_dcp_to_tms)); + Connect (ID_jobs_show_dcp, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::jobs_show_dcp)); Connect (ID_jobs_examine_content, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::jobs_examine_content)); Connect (ID_jobs_make_dcp_from_existing_transcode, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::jobs_make_dcp_from_existing_transcode)); Connect (ID_help_about, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::help_about)); @@ -250,6 +257,7 @@ private: bool const have_dcp = film && film->have_dcp(); jobs_menu->Enable (ID_jobs_send_dcp_to_tms, have_dcp); + jobs_menu->Enable (ID_jobs_show_dcp, have_dcp); } void set_film () @@ -353,6 +361,26 @@ private: { film->send_dcp_to_tms (); } + + void jobs_show_dcp (wxCommandEvent &) + { +#ifdef __WXMSW__ + string d = film->directory(); + wstring w; + w.assign (d.begin(), d.end()); + ShellExecute (0, L"open", w.c_str(), 0, 0, SW_SHOWDEFAULT); +#else + int r = system ("which nautilus"); + if (WEXITSTATUS (r) == 0) { + system (string ("nautilus " + film->directory()).c_str ()); + } else { + int r = system ("which konqueror"); + if (WEXITSTATUS (r) == 0) { + system (string ("konqueror " + film->directory()).c_str ()); + } + } +#endif + } void jobs_examine_content (wxCommandEvent &) { -- cgit v1.2.3 From b77dd4f1ef4d6a1c0c36499f82835e0457469dbd Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 12 Feb 2013 19:59:13 +0000 Subject: Tolerate inability to open film metadata. --- src/tools/dvdomatic.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 3281fc113..be47b4fe6 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -51,6 +51,7 @@ using std::wstring; using std::stringstream; using std::map; using std::make_pair; +using std::exception; using boost::shared_ptr; static FilmEditor* film_editor = 0; @@ -440,8 +441,12 @@ class App : public wxApp dvdomatic_setup (); if (!film_to_load.empty() && boost::filesystem::is_directory (film_to_load)) { - film.reset (new Film (film_to_load)); - film->log()->set_level (log_level); + try { + film.reset (new Film (film_to_load)); + film->log()->set_level (log_level); + } catch (exception& e) { + error_dialog (0, String::compose ("Could not load film %1 (%2)", film_to_load, e.what())); + } } Frame* f = new Frame (_("DVD-o-matic")); -- cgit v1.2.3 From 9b78074e1487ac263f84fd1132735fba83045719 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 12 Feb 2013 21:48:06 +0000 Subject: Add details button to job manager; stretch jobs across the whole of the bottom of the frame; give a better error on low disc space conditions (#48). --- src/lib/job.cc | 40 +++++++++++++++++++++++++++++++--------- src/lib/job.h | 10 ++++++---- src/tools/dvdomatic.cc | 12 ++++++------ src/wx/film_viewer.cc | 2 +- src/wx/job_manager_view.cc | 25 ++++++++++++++++++++++++- src/wx/job_manager_view.h | 2 ++ 6 files changed, 70 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/lib/job.cc b/src/lib/job.cc index 896862d14..2ddcf5335 100644 --- a/src/lib/job.cc +++ b/src/lib/job.cc @@ -67,19 +67,33 @@ Job::run_wrapper () set_progress (1); set_state (FINISHED_ERROR); - set_error (String::compose ("%1 (%2)", e.what(), boost::filesystem::path (e.filename()).leaf())); + string m = String::compose ("An error occurred whilst handling the file %1.", boost::filesystem::path (e.filename()).leaf()); + + boost::filesystem::space_info const s = boost::filesystem::space (e.filename()); + if (s.available < pow (1024, 3)) { + m += "\n\nThe drive that the film is stored on is low in disc space. Free some more space and try again."; + } + + set_error (e.what(), m); + } catch (std::exception& e) { set_progress (1); set_state (FINISHED_ERROR); - set_error (e.what ()); + set_error ( + e.what (), + "It is not known what caused this error. The best idea is to report the problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" + ); } catch (...) { set_progress (1); set_state (FINISHED_ERROR); - set_error ("unknown exception"); + set_error ( + "Unknown error", + "It is not known what caused this error. The best idea is to report the problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" + ); } } @@ -211,22 +225,30 @@ Job::descend (float a) _stack.push_back (Level (a)); } -/** @return Any error string that the job has generated */ string -Job::error () const +Job::error_details () const +{ + boost::mutex::scoped_lock lm (_state_mutex); + return _error_details; +} + +/** @return A summary of any error that the job has generated */ +string +Job::error_summary () const { boost::mutex::scoped_lock lm (_state_mutex); - return _error; + return _error_summary; } /** Set the current error string. * @param e New error string. */ void -Job::set_error (string e) +Job::set_error (string s, string d) { boost::mutex::scoped_lock lm (_state_mutex); - _error = e; + _error_summary = s; + _error_details = d; } /** Say that this job's progress will be unknown until further notice */ @@ -253,7 +275,7 @@ Job::status () const } else if (finished_ok ()) { s << "OK (ran for " << seconds_to_hms (_ran_for) << ")"; } else if (finished_in_error ()) { - s << "Error (" << error() << ")"; + s << "Error (" << error_summary() << ")"; } return s.str (); diff --git a/src/lib/job.h b/src/lib/job.h index f32cfa811..1ea0a9b17 100644 --- a/src/lib/job.h +++ b/src/lib/job.h @@ -53,7 +53,8 @@ public: bool finished_ok () const; bool finished_in_error () const; - std::string error () const; + std::string error_summary () const; + std::string error_details () const; int elapsed_time () const; virtual std::string status () const; @@ -83,7 +84,7 @@ protected: }; void set_state (State); - void set_error (std::string e); + void set_error (std::string s, std::string d); /** Film for this job */ boost::shared_ptr _film; @@ -98,8 +99,9 @@ private: mutable boost::mutex _state_mutex; /** current state of the job */ State _state; - /** message for an error that has occurred (when state == FINISHED_ERROR) */ - std::string _error; + /** summary of an error that has occurred (when state == FINISHED_ERROR) */ + std::string _error_summary; + std::string _error_details; /** time that this job was started */ time_t _start_time; diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index be47b4fe6..bab49c2dc 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -224,13 +224,13 @@ public: film_viewer = new FilmViewer (film, panel); JobManagerView* job_manager_view = new JobManagerView (panel); - wxSizer* rhs_sizer = new wxBoxSizer (wxVERTICAL); - rhs_sizer->Add (film_viewer, 3, wxEXPAND | wxALL); - rhs_sizer->Add (job_manager_view, 1, wxEXPAND | wxALL); + wxSizer* top_sizer = new wxBoxSizer (wxHORIZONTAL); + top_sizer->Add (film_editor, 0, wxALL, 6); + top_sizer->Add (film_viewer, 1, wxEXPAND | wxALL, 6); - wxBoxSizer* main_sizer = new wxBoxSizer (wxHORIZONTAL); - main_sizer->Add (film_editor, 0, wxALL, 6); - main_sizer->Add (rhs_sizer, 1, wxEXPAND | wxALL, 6); + wxBoxSizer* main_sizer = new wxBoxSizer (wxVERTICAL); + main_sizer->Add (top_sizer, 2, wxEXPAND | wxALL, 6); + main_sizer->Add (job_manager_view, 1, wxEXPAND | wxALL, 6); panel->SetSizer (main_sizer); set_menu_sensitivity (); diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index a619edf7c..e685b7b35 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -70,7 +70,7 @@ FilmViewer::FilmViewer (shared_ptr f, wxWindow* p) h_sizer->Add (_play_button, 0, wxEXPAND); h_sizer->Add (_slider, 1, wxEXPAND); - _v_sizer->Add (h_sizer, 0, wxEXPAND); + _v_sizer->Add (h_sizer, 0, wxEXPAND | wxALL, 6); _panel->Connect (wxID_ANY, wxEVT_PAINT, wxPaintEventHandler (FilmViewer::paint_panel), 0, this); _panel->Connect (wxID_ANY, wxEVT_SIZE, wxSizeEventHandler (FilmViewer::panel_sized), 0, this); diff --git a/src/wx/job_manager_view.cc b/src/wx/job_manager_view.cc index a5c02b163..75842a8d4 100644 --- a/src/wx/job_manager_view.cc +++ b/src/wx/job_manager_view.cc @@ -30,6 +30,7 @@ using std::string; using std::list; +using std::map; using boost::shared_ptr; /** Must be called in the GUI thread */ @@ -41,7 +42,7 @@ JobManagerView::JobManagerView (wxWindow* parent) sizer->Add (_panel, 1, wxEXPAND); SetSizer (sizer); - _table = new wxFlexGridSizer (3, 6, 6); + _table = new wxFlexGridSizer (4, 6, 6); _table->AddGrowableCol (1, 1); _panel->SetSizer (_table); @@ -83,6 +84,11 @@ JobManagerView::update () r.message = new wxStaticText (_panel, wxID_ANY, std_to_wx ("")); _table->Insert (index + 2, r.message, 1, wxALIGN_CENTER_VERTICAL | wxALL, 6); + + r.details = new wxButton (_panel, wxID_ANY, _("Details...")); + r.details->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (JobManagerView::details_clicked), 0, this); + r.details->Enable (false); + _table->Insert (index + 3, r.details, 1, wxALIGN_CENTER_VERTICAL | wxALL, 6); _job_records[*i] = r; } @@ -104,6 +110,9 @@ JobManagerView::update () _job_records[*i].gauge->SetValue (100); _job_records[*i].message->SetLabel (std_to_wx (st)); _job_records[*i].finalised = true; + if (!(*i)->error_details().empty ()) { + _job_records[*i].details->Enable (true); + } } index += 3; @@ -112,3 +121,17 @@ JobManagerView::update () _table->Layout (); FitInside (); } + +void +JobManagerView::details_clicked (wxCommandEvent& ev) +{ + wxObject* o = ev.GetEventObject (); + + for (map, JobRecord>::iterator i = _job_records.begin(); i != _job_records.end(); ++i) { + if (i->second.details == o) { + string s = i->first->error_summary(); + s[0] = toupper (s[0]); + error_dialog (this, String::compose ("%1.\n\n%2", s, i->first->error_details())); + } + } +} diff --git a/src/wx/job_manager_view.h b/src/wx/job_manager_view.h index 5c10890ef..d43e795ea 100644 --- a/src/wx/job_manager_view.h +++ b/src/wx/job_manager_view.h @@ -39,6 +39,7 @@ public: private: void periodic (wxTimerEvent &); + void details_clicked (wxCommandEvent &); boost::shared_ptr _timer; wxPanel* _panel; @@ -46,6 +47,7 @@ private: struct JobRecord { wxGauge* gauge; wxStaticText* message; + wxButton* details; bool finalised; }; -- cgit v1.2.3 From d8c3cdf82816acdecab1d13e364fd120b69b4498 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 12 Feb 2013 22:11:52 +0000 Subject: Remove unused files. --- src/wx/film_list.cc | 65 ----------------------------------------------------- src/wx/film_list.h | 41 --------------------------------- 2 files changed, 106 deletions(-) delete mode 100644 src/wx/film_list.cc delete mode 100644 src/wx/film_list.h (limited to 'src') diff --git a/src/wx/film_list.cc b/src/wx/film_list.cc deleted file mode 100644 index 05d9734f6..000000000 --- a/src/wx/film_list.cc +++ /dev/null @@ -1,65 +0,0 @@ -/* - Copyright (C) 2012 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include -#include "lib/film.h" -#include "film_list.h" - -using namespace std; -using namespace boost; - -FilmList::FilmList (string d) - : _directory (d) - , _list (1) -{ - for (filesystem::directory_iterator i = filesystem::directory_iterator (_directory); i != filesystem::directory_iterator(); ++i) { - if (is_directory (*i)) { - filesystem::path m = filesystem::path (*i) / filesystem::path ("metadata"); - if (is_regular_file (m)) { - Film* f = new Film (i->path().string()); - _films.push_back (f); - } - } - } - - for (vector::iterator i = _films.begin(); i != _films.end(); ++i) { - _list.append_text ((*i)->name ()); - } - - _list.set_headers_visible (false); - _list.get_selection()->signal_changed().connect (bind (&FilmList::selection_changed, this)); -} - -Gtk::Widget& -FilmList::widget () -{ - return _list; -} - -void -FilmList::selection_changed () -{ - Gtk::ListViewText::SelectionList s = _list.get_selected (); - if (s.empty ()) { - return; - } - - assert (s[0] < int (_films.size ())); - SelectionChanged (_films[s[0]]); -} diff --git a/src/wx/film_list.h b/src/wx/film_list.h deleted file mode 100644 index 5a4ac3cc1..000000000 --- a/src/wx/film_list.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - Copyright (C) 2012 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include -#include -#include - -class Film; - -class FilmList -{ -public: - FilmList (std::string); - - Gtk::Widget& widget (); - - sigc::signal SelectionChanged; - -private: - void selection_changed (); - - std::string _directory; - std::vector _films; - Gtk::ListViewText _list; -}; -- cgit v1.2.3 From e7e200bdbc071ed3116905cc81c0d3e226de0298 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 12 Feb 2013 22:32:08 +0000 Subject: Small use of String::compose. --- src/lib/exceptions.h | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/lib/exceptions.h b/src/lib/exceptions.h index e757d2506..6de8806e4 100644 --- a/src/lib/exceptions.h +++ b/src/lib/exceptions.h @@ -25,10 +25,10 @@ */ #include -#include #include #include #include +#include "compose.hpp" /** @class StringError * @brief A parent class for exceptions using messages held in a std::string @@ -140,12 +140,7 @@ public: ReadFileError (std::string f, int e = 0) : FileError ("", f) { - std::stringstream s; - s << "could not read from file " << f; - if (e) { - s << " (" << strerror (e) << ")"; - } - _what = s.str (); + _what = String::compose ("could not read from file %1 (%2)", f, strerror (e)); } }; @@ -161,12 +156,7 @@ public: WriteFileError (std::string f, int e) : FileError ("", f) { - std::stringstream s; - s << "could not write to file " << f; - if (e) { - s << " (" << strerror (e) << ")"; - } - _what = s.str (); + _what = String::compose ("could not write to file %1 (%2)", f, strerror (e)); } }; -- cgit v1.2.3 From 229a746ceba3949144eaede0ddcc9394b6a4c065 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 12 Feb 2013 23:26:59 +0000 Subject: Formatting. --- src/lib/util.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/util.cc b/src/lib/util.cc index 340b76b57..483d12d45 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -335,7 +335,8 @@ md5_digest (string file) return s.str (); } -static bool about_equal (float a, float b) +static bool +about_equal (float a, float b) { /* A film of F seconds at f FPS will be Ff frames; Consider some delta FPS d, so if we run the same -- cgit v1.2.3 From ba079aaab20805d743c49f7a43bf6ce0170db231 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 12 Feb 2013 23:27:32 +0000 Subject: Never say 100% when not finished (part of #44). --- src/lib/job.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/lib/job.cc b/src/lib/job.cc index 2ddcf5335..dd034bf0c 100644 --- a/src/lib/job.cc +++ b/src/lib/job.cc @@ -267,11 +267,17 @@ Job::status () const int const t = elapsed_time (); int const r = remaining_time (); + int pc = rint (p * 100); + if (pc == 100) { + /* 100% makes it sound like we've finished when we haven't */ + pc = 99; + } + stringstream s; if (!finished () && p >= 0 && t > 10 && r > 0) { - s << rint (p * 100) << "%; " << seconds_to_approximate_hms (r) << " remaining"; + s << pc << "%; " << seconds_to_approximate_hms (r) << " remaining"; } else if (!finished () && (t <= 10 || r == 0)) { - s << rint (p * 100) << "%"; + s << pc << "%"; } else if (finished_ok ()) { s << "OK (ran for " << seconds_to_hms (_ran_for) << ")"; } else if (finished_in_error ()) { -- cgit v1.2.3 From 5b4861e0e255ecf411542cf32865fb90317f9c62 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 13 Feb 2013 00:34:29 +0000 Subject: Use a tooltip for long DCP names (#50). --- src/wx/film_editor.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 956084261..3ccdac713 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -1174,5 +1174,11 @@ FilmEditor::external_audio_changed (wxCommandEvent &) void FilmEditor::setup_dcp_name () { - _dcp_name->SetLabel (std_to_wx (_film->dcp_name (true))); + string s = _film->dcp_name (true); + if (s.length() > 28) { + _dcp_name->SetLabel (std_to_wx (s.substr (0, 28) + "...")); + _dcp_name->SetToolTip (std_to_wx (s)); + } else { + _dcp_name->SetLabel (std_to_wx (s)); + } } -- cgit v1.2.3 From 019e44f1a19e366b1771b3a0fb1dbec2d343597f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 13 Feb 2013 22:53:08 +0000 Subject: Tweak crop widgets. --- src/wx/film_editor.cc | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 3ccdac713..54eccb4f1 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -228,28 +228,21 @@ FilmEditor::make_video_panel () _format = new wxChoice (_video_panel, wxID_ANY); grid->Add (_format); - { - add_label_to_sizer (grid, _video_panel, _("Crop")); - wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); + add_label_to_sizer (grid, _video_panel, _("Left crop")); + _left_crop = new wxSpinCtrl (_video_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)); + grid->Add (_left_crop); - /* TRANSLATORS: L, R, T and B are abbreviations for Left, Right, Top, Bottom, the four edges - of the picture frame. - */ - add_label_to_sizer (s, _video_panel, _("L")); - _left_crop = new wxSpinCtrl (_video_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)); - s->Add (_left_crop, 0); - add_label_to_sizer (s, _video_panel, _("R")); - _right_crop = new wxSpinCtrl (_video_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)); - s->Add (_right_crop, 0); - add_label_to_sizer (s, _video_panel, _("T")); - _top_crop = new wxSpinCtrl (_video_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)); - s->Add (_top_crop, 0); - add_label_to_sizer (s, _video_panel, _("B")); - _bottom_crop = new wxSpinCtrl (_video_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)); - s->Add (_bottom_crop, 0); - - grid->Add (s); - } + add_label_to_sizer (grid, _video_panel, _("Right crop")); + _right_crop = new wxSpinCtrl (_video_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)); + grid->Add (_right_crop); + + add_label_to_sizer (grid, _video_panel, _("Top crop")); + _top_crop = new wxSpinCtrl (_video_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)); + grid->Add (_top_crop); + + add_label_to_sizer (grid, _video_panel, _("Bottom crop")); + _bottom_crop = new wxSpinCtrl (_video_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)); + grid->Add (_bottom_crop); /* VIDEO-only stuff */ { -- cgit v1.2.3 From 4b7ef6b5d477ef116b9c29877a0ca99e5625248c Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 13 Feb 2013 23:05:20 +0000 Subject: Fix erroneous padding of view using -in-flat formats (#52). --- src/wx/film_viewer.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index e685b7b35..e9992a11f 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -57,7 +57,7 @@ FilmViewer::FilmViewer (shared_ptr f, wxWindow* p) , _clear_required (false) { _panel->SetDoubleBuffered (true); -#if wxMAJOR_VERSION == 2 && wxMINOR_VERSION >= 9 +#if wxMAJOR_VERSION == 2 && wxMINOR_VERSION >= 9 _panel->SetBackgroundStyle (wxBG_STYLE_PAINT); #endif @@ -209,7 +209,7 @@ FilmViewer::paint_panel (wxPaintEvent &) dc.SetPen(*wxBLACK_PEN); dc.SetBrush(*wxBLACK_BRUSH); dc.DrawRectangle (0, 0, _display_frame_x, _film_size.height); - dc.DrawRectangle (_display_frame_x + _film_size.width, 0, _display_frame_x * 2 + _film_size.width, _film_size.height); + dc.DrawRectangle (_display_frame_x + _film_size.width, 0, _display_frame_x, _film_size.height); } wxImage frame (_film_size.width, _film_size.height, _display_frame->data()[0], true); -- cgit v1.2.3 From f1066609865293a9cdb7fd642a2360e3f4009a6f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 15 Feb 2013 19:37:20 +0000 Subject: Support BMP for still images (part of #55). --- src/lib/util.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/util.cc b/src/lib/util.cc index 483d12d45..c0c8be984 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -942,7 +942,7 @@ still_image_file (string f) transform (ext.begin(), ext.end(), ext.begin(), ::tolower); - return (ext == ".tif" || ext == ".tiff" || ext == ".jpg" || ext == ".jpeg" || ext == ".png"); + return (ext == ".tif" || ext == ".tiff" || ext == ".jpg" || ext == ".jpeg" || ext == ".png" || ext == ".bmp"); } /** @return A pair containing CPU model name and the number of processors */ -- cgit v1.2.3 From 1ec75763c4aafa9e3b8dcbad656b279151e9a90c Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 15 Feb 2013 19:37:37 +0000 Subject: Fix misarrangement since details button was added. --- src/wx/job_manager_view.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/wx/job_manager_view.cc b/src/wx/job_manager_view.cc index 75842a8d4..a521f5b80 100644 --- a/src/wx/job_manager_view.cc +++ b/src/wx/job_manager_view.cc @@ -115,7 +115,7 @@ JobManagerView::update () } } - index += 3; + index += 4; } _table->Layout (); -- cgit v1.2.3 From f4b2eba2ae5bda79d14e6deb199b2865ba5542c3 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 16 Feb 2013 01:58:52 +0000 Subject: Some portability fixes. --- src/tools/dvdomatic.cc | 2 +- src/wx/job_manager_view.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index bab49c2dc..5d944a934 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -445,7 +445,7 @@ class App : public wxApp film.reset (new Film (film_to_load)); film->log()->set_level (log_level); } catch (exception& e) { - error_dialog (0, String::compose ("Could not load film %1 (%2)", film_to_load, e.what())); + error_dialog (0, std_to_wx (String::compose ("Could not load film %1 (%2)", film_to_load, e.what()))); } } diff --git a/src/wx/job_manager_view.cc b/src/wx/job_manager_view.cc index a521f5b80..8bede709f 100644 --- a/src/wx/job_manager_view.cc +++ b/src/wx/job_manager_view.cc @@ -131,7 +131,7 @@ JobManagerView::details_clicked (wxCommandEvent& ev) if (i->second.details == o) { string s = i->first->error_summary(); s[0] = toupper (s[0]); - error_dialog (this, String::compose ("%1.\n\n%2", s, i->first->error_details())); + error_dialog (this, std_to_wx (String::compose ("%1.\n\n%2", s, i->first->error_details()))); } } } -- cgit v1.2.3 From 284d33037f878e6e3bc97238e0c18b0bbb92b990 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 16 Feb 2013 22:31:58 +0000 Subject: Remove now-unused job dependencies. --- src/lib/ab_transcode_job.cc | 4 ++-- src/lib/ab_transcode_job.h | 3 +-- src/lib/examine_content_job.cc | 4 ++-- src/lib/examine_content_job.h | 2 +- src/lib/film.cc | 8 ++++---- src/lib/job.cc | 4 +--- src/lib/job.h | 8 +------- src/lib/job_manager.cc | 11 ++++------- src/lib/scp_dcp_job.cc | 4 ++-- src/lib/scp_dcp_job.h | 2 +- src/lib/transcode_job.cc | 5 ++--- src/lib/transcode_job.h | 2 +- test/test.cc | 39 ++++----------------------------------- 13 files changed, 26 insertions(+), 70 deletions(-) (limited to 'src') diff --git a/src/lib/ab_transcode_job.cc b/src/lib/ab_transcode_job.cc index 0efd277bb..025c23c86 100644 --- a/src/lib/ab_transcode_job.cc +++ b/src/lib/ab_transcode_job.cc @@ -32,8 +32,8 @@ using boost::shared_ptr; /** @param f Film to compare. * @param o Decode options. */ -ABTranscodeJob::ABTranscodeJob (shared_ptr f, DecodeOptions o, shared_ptr req) - : Job (f, req) +ABTranscodeJob::ABTranscodeJob (shared_ptr f, DecodeOptions o) + : Job (f) , _decode_opt (o) { _film_b.reset (new Film (*_film)); diff --git a/src/lib/ab_transcode_job.h b/src/lib/ab_transcode_job.h index 983842038..8e3cbe2d8 100644 --- a/src/lib/ab_transcode_job.h +++ b/src/lib/ab_transcode_job.h @@ -39,8 +39,7 @@ class ABTranscodeJob : public Job public: ABTranscodeJob ( boost::shared_ptr f, - DecodeOptions o, - boost::shared_ptr req + DecodeOptions o ); std::string name () const; diff --git a/src/lib/examine_content_job.cc b/src/lib/examine_content_job.cc index 94e5320fe..31d76c4f7 100644 --- a/src/lib/examine_content_job.cc +++ b/src/lib/examine_content_job.cc @@ -36,8 +36,8 @@ using std::vector; using std::pair; using boost::shared_ptr; -ExamineContentJob::ExamineContentJob (shared_ptr f, shared_ptr req) - : Job (f, req) +ExamineContentJob::ExamineContentJob (shared_ptr f) + : Job (f) { } diff --git a/src/lib/examine_content_job.h b/src/lib/examine_content_job.h index 729c287b5..8ee4f0d60 100644 --- a/src/lib/examine_content_job.h +++ b/src/lib/examine_content_job.h @@ -29,7 +29,7 @@ class ExamineContentJob : public Job { public: - ExamineContentJob (boost::shared_ptr, boost::shared_ptr req); + ExamineContentJob (boost::shared_ptr); ~ExamineContentJob (); std::string name () const; diff --git a/src/lib/film.cc b/src/lib/film.cc index 36ebe7199..289a8c348 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -300,9 +300,9 @@ Film::make_dcp (bool transcode) if (transcode) { if (dcp_ab()) { - r = JobManager::instance()->add (shared_ptr (new ABTranscodeJob (shared_from_this(), od, shared_ptr ()))); + r = JobManager::instance()->add (shared_ptr (new ABTranscodeJob (shared_from_this(), od))); } else { - r = JobManager::instance()->add (shared_ptr (new TranscodeJob (shared_from_this(), od, shared_ptr ()))); + r = JobManager::instance()->add (shared_ptr (new TranscodeJob (shared_from_this(), od))); } } } @@ -315,7 +315,7 @@ Film::examine_content () return; } - _examine_content_job.reset (new ExamineContentJob (shared_from_this(), shared_ptr ())); + _examine_content_job.reset (new ExamineContentJob (shared_from_this())); _examine_content_job->Finished.connect (bind (&Film::examine_content_finished, this)); JobManager::instance()->add (_examine_content_job); } @@ -330,7 +330,7 @@ Film::examine_content_finished () void Film::send_dcp_to_tms () { - shared_ptr j (new SCPDCPJob (shared_from_this(), shared_ptr ())); + shared_ptr j (new SCPDCPJob (shared_from_this())); JobManager::instance()->add (j); } diff --git a/src/lib/job.cc b/src/lib/job.cc index dd034bf0c..bde2c8cfd 100644 --- a/src/lib/job.cc +++ b/src/lib/job.cc @@ -33,11 +33,9 @@ using std::stringstream; using boost::shared_ptr; /** @param s Film that we are operating on. - * @param req Job that must be completed before this job is run. */ -Job::Job (shared_ptr f, shared_ptr req) +Job::Job (shared_ptr f) : _film (f) - , _required (req) , _state (NEW) , _start_time (0) , _progress_unknown (false) diff --git a/src/lib/job.h b/src/lib/job.h index 1ea0a9b17..1538e2779 100644 --- a/src/lib/job.h +++ b/src/lib/job.h @@ -37,7 +37,7 @@ class Film; class Job : public boost::enable_shared_from_this { public: - Job (boost::shared_ptr s, boost::shared_ptr req); + Job (boost::shared_ptr s); virtual ~Job() {} /** @return user-readable name of this job */ @@ -65,10 +65,6 @@ public: void descend (float); float overall_progress () const; - boost::shared_ptr required () const { - return _required; - } - boost::signals2::signal Finished; protected: @@ -93,8 +89,6 @@ private: void run_wrapper (); - boost::shared_ptr _required; - /** mutex for _state and _error */ mutable boost::mutex _state_mutex; /** current state of the job */ diff --git a/src/lib/job_manager.cc b/src/lib/job_manager.cc index fa02fd370..910597628 100644 --- a/src/lib/job_manager.cc +++ b/src/lib/job_manager.cc @@ -111,13 +111,10 @@ JobManager::scheduler () } if ((*i)->is_new()) { - shared_ptr r = (*i)->required (); - if (!r || r->finished_ok ()) { - (*i)->start (); - - /* Only start one job at once */ - break; - } + (*i)->start (); + + /* Only start one job at once */ + break; } } } diff --git a/src/lib/scp_dcp_job.cc b/src/lib/scp_dcp_job.cc index 3d941888e..30d02eff8 100644 --- a/src/lib/scp_dcp_job.cc +++ b/src/lib/scp_dcp_job.cc @@ -94,8 +94,8 @@ public: }; -SCPDCPJob::SCPDCPJob (shared_ptr f, shared_ptr req) - : Job (f, req) +SCPDCPJob::SCPDCPJob (shared_ptr f) + : Job (f) , _status ("Waiting") { diff --git a/src/lib/scp_dcp_job.h b/src/lib/scp_dcp_job.h index 5d0bfe7b4..08d8e2c78 100644 --- a/src/lib/scp_dcp_job.h +++ b/src/lib/scp_dcp_job.h @@ -26,7 +26,7 @@ class SCPDCPJob : public Job { public: - SCPDCPJob (boost::shared_ptr, boost::shared_ptr req); + SCPDCPJob (boost::shared_ptr); std::string name () const; void run (); diff --git a/src/lib/transcode_job.cc b/src/lib/transcode_job.cc index e9a59c743..87e9a47c4 100644 --- a/src/lib/transcode_job.cc +++ b/src/lib/transcode_job.cc @@ -38,10 +38,9 @@ using boost::shared_ptr; /** @param s Film to use. * @param o Decode options. - * @param req Job that must be completed before this job is run. */ -TranscodeJob::TranscodeJob (shared_ptr f, DecodeOptions o, shared_ptr req) - : Job (f, req) +TranscodeJob::TranscodeJob (shared_ptr f, DecodeOptions o) + : Job (f) , _decode_opt (o) { diff --git a/src/lib/transcode_job.h b/src/lib/transcode_job.h index 8f78e7f6a..9b69e4e65 100644 --- a/src/lib/transcode_job.h +++ b/src/lib/transcode_job.h @@ -33,7 +33,7 @@ class Encoder; class TranscodeJob : public Job { public: - TranscodeJob (boost::shared_ptr f, DecodeOptions od, boost::shared_ptr req); + TranscodeJob (boost::shared_ptr f, DecodeOptions od); std::string name () const; void run (); diff --git a/test/test.cc b/test/test.cc index 75199fac7..771325d29 100644 --- a/test/test.cc +++ b/test/test.cc @@ -652,8 +652,8 @@ BOOST_AUTO_TEST_CASE (audio_sampling_rate_test) class TestJob : public Job { public: - TestJob (shared_ptr f, shared_ptr req) - : Job (f, req) + TestJob (shared_ptr f) + : Job (f) { } @@ -684,8 +684,8 @@ BOOST_AUTO_TEST_CASE (job_manager_test) { shared_ptr f; - /* Single job, no dependency */ - shared_ptr a (new TestJob (f, shared_ptr ())); + /* Single job */ + shared_ptr a (new TestJob (f)); JobManager::instance()->add (a); dvdomatic_sleep (1); @@ -693,37 +693,6 @@ BOOST_AUTO_TEST_CASE (job_manager_test) a->set_finished_ok (); dvdomatic_sleep (2); BOOST_CHECK_EQUAL (a->finished_ok(), true); - - /* Two jobs, dependency */ - a.reset (new TestJob (f, shared_ptr ())); - shared_ptr b (new TestJob (f, a)); - - JobManager::instance()->add (a); - JobManager::instance()->add (b); - dvdomatic_sleep (2); - BOOST_CHECK_EQUAL (a->running(), true); - BOOST_CHECK_EQUAL (b->running(), false); - a->set_finished_ok (); - dvdomatic_sleep (2); - BOOST_CHECK_EQUAL (a->finished_ok(), true); - BOOST_CHECK_EQUAL (b->running(), true); - b->set_finished_ok (); - dvdomatic_sleep (2); - BOOST_CHECK_EQUAL (b->finished_ok(), true); - - /* Two jobs, dependency, first fails */ - a.reset (new TestJob (f, shared_ptr ())); - b.reset (new TestJob (f, a)); - - JobManager::instance()->add (a); - JobManager::instance()->add (b); - dvdomatic_sleep (2); - BOOST_CHECK_EQUAL (a->running(), true); - BOOST_CHECK_EQUAL (b->running(), false); - a->set_finished_error (); - dvdomatic_sleep (2); - BOOST_CHECK_EQUAL (a->finished_in_error(), true); - BOOST_CHECK_EQUAL (b->running(), false); } BOOST_AUTO_TEST_CASE (compact_image_test) -- cgit v1.2.3 From ab71d8d56cd85dec9aeeea55c52496dc3dc19921 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 16 Feb 2013 22:33:12 +0000 Subject: Remove some vestiges of FilmState. --- src/lib/dcp_video_frame.h | 1 - src/lib/transcoder.h | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/lib/dcp_video_frame.h b/src/lib/dcp_video_frame.h index be8a559b2..ab458b58f 100644 --- a/src/lib/dcp_video_frame.h +++ b/src/lib/dcp_video_frame.h @@ -26,7 +26,6 @@ * @brief A single frame of video destined for a DCP. */ -class FilmState; class Film; class ServerDescription; class Scaler; diff --git a/src/lib/transcoder.h b/src/lib/transcoder.h index 786010869..b0c263d07 100644 --- a/src/lib/transcoder.h +++ b/src/lib/transcoder.h @@ -18,7 +18,7 @@ */ /** @file src/transcoder.h - * @brief A class which takes a FilmState and some Options, then uses those to transcode a Film. + * @brief A class which takes a Film and some Options, then uses those to transcode the film. * * A decoder is selected according to the content type, and the encoder can be specified * as a parameter to the constructor. @@ -29,7 +29,6 @@ class Film; class Job; class Encoder; -class FilmState; class Matcher; class VideoFilter; class Gain; @@ -38,7 +37,7 @@ class AudioDecoder; class DelayLine; /** @class Transcoder - * @brief A class which takes a FilmState and some Options, then uses those to transcode a Film. + * @brief A class which takes a Film and some Options, then uses those to transcode the film. * * A decoder is selected according to the content type, and the encoder can be specified * as a parameter to the constructor. -- cgit v1.2.3 From fa6c885de512cdde0590c2bbe9ea424030a12c6b Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 17 Feb 2013 00:25:23 +0000 Subject: i18n hacks. --- src/lib/film.cc | 2 +- src/lib/transcode_job.cc | 6 ++- src/lib/wscript | 110 ++++++++++++++++++++++++++--------------------- src/wscript | 4 ++ src/wx/wscript | 48 +++++++++++++-------- wscript | 3 ++ 6 files changed, 103 insertions(+), 70 deletions(-) (limited to 'src') diff --git a/src/lib/film.cc b/src/lib/film.cc index 289a8c348..77f61cbac 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -246,7 +246,7 @@ Film::make_dcp (bool transcode) set_dci_date_today (); if (dcp_name().find ("/") != string::npos) { - throw BadSettingError ("name", "cannot contain slashes"); + throw BadSettingError ("name", _("cannot contain slashes")); } log()->log (String::compose ("DVD-o-matic %1 git %2 using %3", dvdomatic_version, dvdomatic_git_commit, dependency_version_summary())); diff --git a/src/lib/transcode_job.cc b/src/lib/transcode_job.cc index 87e9a47c4..a4279ef8b 100644 --- a/src/lib/transcode_job.cc +++ b/src/lib/transcode_job.cc @@ -30,6 +30,8 @@ #include "log.h" #include "encoder.h" +#include "i18n.h" + using std::string; using std::stringstream; using std::fixed; @@ -49,7 +51,7 @@ TranscodeJob::TranscodeJob (shared_ptr f, DecodeOptions o) string TranscodeJob::name () const { - return String::compose ("Transcode %1", _film->name()); + return String::compose (_("Transcode %1"), _film->name()); } void @@ -98,7 +100,7 @@ TranscodeJob::status () const s << Job::status (); if (!finished ()) { - s << "; " << fixed << setprecision (1) << fps << " frames per second"; + s << "; " << fixed << setprecision (1) << fps << " " << _("frames per second"); } return s.str (); diff --git a/src/lib/wscript b/src/lib/wscript index eee04190c..ee89ad085 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -1,3 +1,54 @@ +import os + +sources = """ + ab_transcode_job.cc + ab_transcoder.cc + audio_decoder.cc + audio_source.cc + config.cc + combiner.cc + cross.cc + dci_metadata.cc + dcp_content_type.cc + dcp_video_frame.cc + decoder.cc + decoder_factory.cc + delay_line.cc + dolby_cp750.cc + encoder.cc + examine_content_job.cc + external_audio_decoder.cc + filter_graph.cc + ffmpeg_compatibility.cc + ffmpeg_decoder.cc + film.cc + filter.cc + format.cc + gain.cc + image.cc + imagemagick_decoder.cc + job.cc + job_manager.cc + log.cc + lut.cc + matcher.cc + scp_dcp_job.cc + scaler.cc + server.cc + sound_processor.cc + stream.cc + subtitle.cc + timer.cc + transcode_job.cc + transcoder.cc + ui_signaller.cc + util.cc + version.cc + video_decoder.cc + video_source.cc + writer.cc + """ + def build(bld): if bld.env.STATIC: obj = bld(features = 'cxx cxxstlib') @@ -13,53 +64,14 @@ def build(bld): """ if bld.env.TARGET_WINDOWS: obj.uselib += ' WINSOCK2' - obj.source = """ - ab_transcode_job.cc - ab_transcoder.cc - audio_decoder.cc - audio_source.cc - config.cc - combiner.cc - cross.cc - dci_metadata.cc - dcp_content_type.cc - dcp_video_frame.cc - decoder.cc - decoder_factory.cc - delay_line.cc - dolby_cp750.cc - encoder.cc - examine_content_job.cc - external_audio_decoder.cc - filter_graph.cc - ffmpeg_compatibility.cc - ffmpeg_decoder.cc - film.cc - filter.cc - format.cc - gain.cc - image.cc - imagemagick_decoder.cc - job.cc - job_manager.cc - log.cc - lut.cc - matcher.cc - scp_dcp_job.cc - scaler.cc - server.cc - sound_processor.cc - stream.cc - subtitle.cc - timer.cc - transcode_job.cc - transcoder.cc - ui_signaller.cc - util.cc - version.cc - video_decoder.cc - video_source.cc - writer.cc - """ - + obj.source = sources obj.target = 'dvdomatic' + +def pot(bld): + s = "" + for f in sources.split('\n'): + t = f.strip() + if len(t) > 0: + s += (os.path.join('src', 'lib', t)) + " " + + os.system('xgettext -d libdvdomatic -s --keyword=_ -p build/src/lib -o libdvdomatic.pot %s' % s) diff --git a/src/wscript b/src/wscript index 3f17b3e6c..ed497ff0c 100644 --- a/src/wscript +++ b/src/wscript @@ -7,3 +7,7 @@ def build(bld): bld.recurse('tools') if not bld.env.DISABLE_GUI: bld.recurse('wx') + +def pot(bld): + bld.recurse('lib') + bld.recurse('wx') diff --git a/src/wx/wscript b/src/wx/wscript index d844b1f1b..ef1d1c083 100644 --- a/src/wx/wscript +++ b/src/wx/wscript @@ -1,3 +1,23 @@ +import os + +sources = """ + config_dialog.cc + dci_metadata_dialog.cc + dir_picker_ctrl.cc + film_editor.cc + film_viewer.cc + filter_dialog.cc + filter_view.cc + gain_calculator_dialog.cc + job_manager_view.cc + job_wrapper.cc + new_film_dialog.cc + properties_dialog.cc + server_dialog.cc + wx_util.cc + wx_ui_signaller.cc + """ + def configure(conf): conf.check_cfg(package = '', path = conf.options.wx_config, args = '--cppflags --cxxflags --libs', uselib_store = 'WXWIDGETS', mandatory = True) @@ -12,22 +32,14 @@ def build(bld): obj.export_includes = ['.'] obj.uselib = 'WXWIDGETS' obj.use = 'libdvdomatic' - obj.source = """ - config_dialog.cc - dci_metadata_dialog.cc - dir_picker_ctrl.cc - film_editor.cc - film_viewer.cc - filter_dialog.cc - filter_view.cc - gain_calculator_dialog.cc - job_manager_view.cc - job_wrapper.cc - new_film_dialog.cc - properties_dialog.cc - server_dialog.cc - wx_util.cc - wx_ui_signaller.cc - """ - + obj.source = sources obj.target = 'dvdomatic-wx' + +def pot(bld): + s = "" + for f in sources.split('\n'): + t = f.strip() + if len(t) > 0: + s += (os.path.join('src', 'wx', t)) + " " + + os.system('xgettext -d libdvdomatic -s --keyword=_ -p build/src/wx -o libdvdomatic-wx.pot %s' % s) diff --git a/wscript b/wscript index 06c193c4f..1a8238d1c 100644 --- a/wscript +++ b/wscript @@ -253,3 +253,6 @@ def create_version_cc(version): def post(ctx): if ctx.cmd == 'install': ctx.exec_command('/sbin/ldconfig') + +def pot(bld): + bld.recurse('src') -- cgit v1.2.3 From e120fc193547df8e0888534e87361294440dd5b7 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 17 Feb 2013 00:59:52 +0000 Subject: Tidy. --- src/tools/dvdomatic.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 5d944a934..8b531d0a6 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -287,7 +287,7 @@ private: if (r == wxID_OK) { if (boost::filesystem::exists (d->get_path())) { - error_dialog (this, wxString::Format (_("The directory %s already exists"), d->get_path().c_str())); + error_dialog (this, wxString::Format (_("The directory %s already exists."), d->get_path().c_str())); return; } -- cgit v1.2.3 From b8cb646c2fc0dda578aecc212db3dfb141ab9e55 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 17 Feb 2013 01:01:56 +0000 Subject: Remove pointless make DCP from existing transcode option. --- src/tools/dvdomatic.cc | 8 -------- 1 file changed, 8 deletions(-) (limited to 'src') diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 5d944a934..21c2ce760 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -146,7 +146,6 @@ enum { ID_jobs_send_dcp_to_tms, ID_jobs_show_dcp, ID_jobs_examine_content, - ID_jobs_make_dcp_from_existing_transcode, ID_help_about }; @@ -172,7 +171,6 @@ setup_menu (wxMenuBar* m) add_item (jobs_menu, "S&how DCP", ID_jobs_show_dcp, NEEDS_FILM); jobs_menu->AppendSeparator (); add_item (jobs_menu, "&Examine content", ID_jobs_examine_content, NEEDS_FILM); - add_item (jobs_menu, "Make DCP from existing &transcode", ID_jobs_make_dcp_from_existing_transcode, NEEDS_FILM); wxMenu* help = new wxMenu; add_item (help, "About", ID_help_about, ALWAYS); @@ -210,7 +208,6 @@ public: Connect (ID_jobs_send_dcp_to_tms, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::jobs_send_dcp_to_tms)); Connect (ID_jobs_show_dcp, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::jobs_show_dcp)); Connect (ID_jobs_examine_content, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::jobs_examine_content)); - Connect (ID_jobs_make_dcp_from_existing_transcode, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::jobs_make_dcp_from_existing_transcode)); Connect (ID_help_about, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::help_about)); Connect (wxID_ANY, wxEVT_MENU_OPEN, wxMenuEventHandler (Frame::menu_opened)); @@ -353,11 +350,6 @@ private: JobWrapper::make_dcp (this, film, true); } - void jobs_make_dcp_from_existing_transcode (wxCommandEvent &) - { - JobWrapper::make_dcp (this, film, false); - } - void jobs_send_dcp_to_tms (wxCommandEvent &) { film->send_dcp_to_tms (); -- cgit v1.2.3 From 30c2924b9f6cbe30896d2c8ff1c3505ba79f3a88 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 17 Feb 2013 01:16:11 +0000 Subject: Try to fix flickery updates (#59). --- src/wx/job_manager_view.cc | 6 +++--- src/wx/wx_util.cc | 8 ++++++++ src/wx/wx_util.h | 1 + 3 files changed, 12 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/wx/job_manager_view.cc b/src/wx/job_manager_view.cc index 8bede709f..7537da287 100644 --- a/src/wx/job_manager_view.cc +++ b/src/wx/job_manager_view.cc @@ -98,17 +98,17 @@ JobManagerView::update () if (!(*i)->finished ()) { float const p = (*i)->overall_progress (); if (p >= 0) { - _job_records[*i].message->SetLabel (std_to_wx (st)); + checked_set (_job_records[*i].message, st); _job_records[*i].gauge->SetValue (p * 100); } else { - _job_records[*i].message->SetLabel (_("Running")); + checked_set (_job_records[*i].message, wx_to_std (_("Running"))); _job_records[*i].gauge->Pulse (); } } if ((*i)->finished() && !_job_records[*i].finalised) { _job_records[*i].gauge->SetValue (100); - _job_records[*i].message->SetLabel (std_to_wx (st)); + checked_set (_job_records[*i].message, st); _job_records[*i].finalised = true; if (!(*i)->error_details().empty ()) { _job_records[*i].details->Enable (true); diff --git a/src/wx/wx_util.cc b/src/wx/wx_util.cc index 632dbc32e..bf78ff4d7 100644 --- a/src/wx/wx_util.cc +++ b/src/wx/wx_util.cc @@ -170,6 +170,14 @@ checked_set (wxTextCtrl* widget, string value) } } +void +checked_set (wxStaticText* widget, string value) +{ + if (widget->GetLabel() != std_to_wx (value)) { + widget->SetLabel (std_to_wx (value)); + } +} + void checked_set (wxCheckBox* widget, bool value) { diff --git a/src/wx/wx_util.h b/src/wx/wx_util.h index dd069a9d7..6cde08a90 100644 --- a/src/wx/wx_util.h +++ b/src/wx/wx_util.h @@ -63,3 +63,4 @@ extern void checked_set (wxChoice* widget, std::string value); extern void checked_set (wxTextCtrl* widget, std::string value); extern void checked_set (wxCheckBox* widget, bool value); extern void checked_set (wxRadioButton* widget, bool value); +extern void checked_set (wxStaticText* widget, std::string value); -- cgit v1.2.3 From b6d16feca5b7b28927cba193a1b3b6b73acd2c8f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 17 Feb 2013 20:55:36 +0000 Subject: Fix nasty misreading of planar audio data. --- src/lib/ffmpeg_decoder.cc | 26 ++++++++++++++------------ src/lib/ffmpeg_decoder.h | 2 +- 2 files changed, 15 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 1f11f70a0..d4ed76e37 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -127,7 +127,7 @@ FFmpegDecoder::setup_general () /* This is a hack; sometimes it seems that _audio_codec_context->channel_layout isn't set up, so bodge it here. No idea why we should have to do this. */ - + if (s->codec->channel_layout == 0) { s->codec->channel_layout = av_get_default_channel_layout (s->codec->channels); } @@ -247,7 +247,7 @@ FFmpegDecoder::pass () ); assert (_audio_codec_context->channels == _film->audio_channels()); - Audio (deinterleave_audio (_frame->data[0], data_size)); + Audio (deinterleave_audio (_frame->data, data_size)); } } @@ -320,7 +320,7 @@ FFmpegDecoder::pass () ); assert (_audio_codec_context->channels == _film->audio_channels()); - Audio (deinterleave_audio (_frame->data[0], data_size)); + Audio (deinterleave_audio (_frame->data, data_size)); } } @@ -350,8 +350,11 @@ FFmpegDecoder::pass () return false; } +/** @param data pointer to array of pointers to buffers. + * Only the first buffer will be used for non-planar data, otherwise there will be one per channel. + */ shared_ptr -FFmpegDecoder::deinterleave_audio (uint8_t* data, int size) +FFmpegDecoder::deinterleave_audio (uint8_t** data, int size) { assert (_film->audio_channels()); assert (bytes_per_audio_sample()); @@ -370,7 +373,7 @@ FFmpegDecoder::deinterleave_audio (uint8_t* data, int size) switch (audio_sample_format()) { case AV_SAMPLE_FMT_S16: { - int16_t* p = reinterpret_cast (data); + int16_t* p = reinterpret_cast (data[0]); int sample = 0; int channel = 0; for (int i = 0; i < total_samples; ++i) { @@ -387,10 +390,10 @@ FFmpegDecoder::deinterleave_audio (uint8_t* data, int size) case AV_SAMPLE_FMT_S16P: { - int16_t* p = reinterpret_cast (data); + int16_t** p = reinterpret_cast (data); for (int i = 0; i < _film->audio_channels(); ++i) { for (int j = 0; j < frames; ++j) { - audio->data(i)[j] = static_cast(*p++) / (1 << 15); + audio->data(i)[j] = static_cast(p[i][j]) / (1 << 15); } } } @@ -398,7 +401,7 @@ FFmpegDecoder::deinterleave_audio (uint8_t* data, int size) case AV_SAMPLE_FMT_S32: { - int32_t* p = reinterpret_cast (data); + int32_t* p = reinterpret_cast (data[0]); int sample = 0; int channel = 0; for (int i = 0; i < total_samples; ++i) { @@ -415,7 +418,7 @@ FFmpegDecoder::deinterleave_audio (uint8_t* data, int size) case AV_SAMPLE_FMT_FLT: { - float* p = reinterpret_cast (data); + float* p = reinterpret_cast (data[0]); int sample = 0; int channel = 0; for (int i = 0; i < total_samples; ++i) { @@ -432,10 +435,9 @@ FFmpegDecoder::deinterleave_audio (uint8_t* data, int size) case AV_SAMPLE_FMT_FLTP: { - float* p = reinterpret_cast (data); + float** p = reinterpret_cast (data); for (int i = 0; i < _film->audio_channels(); ++i) { - memcpy (audio->data(i), p, frames * sizeof(float)); - p += frames; + memcpy (audio->data(i), p[i], frames * sizeof(float)); } } break; diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h index 17308eb56..c383b8d13 100644 --- a/src/lib/ffmpeg_decoder.h +++ b/src/lib/ffmpeg_decoder.h @@ -121,7 +121,7 @@ private: void setup_subtitle (); void maybe_add_subtitle (); - boost::shared_ptr deinterleave_audio (uint8_t* data, int size); + boost::shared_ptr deinterleave_audio (uint8_t** data, int size); void film_changed (Film::Property); -- cgit v1.2.3 From fb5ec7f03c1dd93211125681bcb13c1a2526faf6 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 17 Feb 2013 21:03:18 +0000 Subject: Fix audio channel count when bumping mono up to 5.1. --- src/lib/writer.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 8a09f254b..c2cc00328 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -72,13 +72,13 @@ Writer::Writer (shared_ptr f) _picture_asset_writer = _picture_asset->start_write (_first_nonexistant_frame > 0); - if (_film->audio_channels() > 0) { + if (dcp_audio_channels (_film->audio_channels()) > 0) { _sound_asset.reset ( new libdcp::SoundAsset ( _film->dir (_film->dcp_name()), "audio.mxf", DCPFrameRate (_film->frames_per_second()).frames_per_second, - _film->audio_channels(), + dcp_audio_channels (_film->audio_channels()), dcp_audio_sample_rate (_film->audio_stream()->sample_rate()) ) ); -- cgit v1.2.3 From 68f6efd164b0db1588513a8b8d3402eedb7bb86b Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 17 Feb 2013 21:19:20 +0000 Subject: Remove some vestigial stuff. --- src/lib/film.cc | 16 ++++++---------- src/lib/film.h | 2 +- src/tools/dvdomatic.cc | 2 +- src/tools/makedcp.cc | 2 +- src/wx/job_wrapper.cc | 4 ++-- src/wx/job_wrapper.h | 2 +- test/test.cc | 4 ++-- 7 files changed, 14 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/lib/film.cc b/src/lib/film.cc index 289a8c348..1cf161259 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -237,11 +237,9 @@ Film::video_mxf_filename () const return video_state_identifier() + ".mxf"; } -/** Add suitable Jobs to the JobManager to create a DCP for this Film. - * @param true to transcode, false to use the WAV and J2K files that are already there. - */ +/** Add suitable Jobs to the JobManager to create a DCP for this Film */ void -Film::make_dcp (bool transcode) +Film::make_dcp () { set_dci_date_today (); @@ -298,12 +296,10 @@ Film::make_dcp (bool transcode) shared_ptr r; - if (transcode) { - if (dcp_ab()) { - r = JobManager::instance()->add (shared_ptr (new ABTranscodeJob (shared_from_this(), od))); - } else { - r = JobManager::instance()->add (shared_ptr (new TranscodeJob (shared_from_this(), od))); - } + if (dcp_ab()) { + r = JobManager::instance()->add (shared_ptr (new ABTranscodeJob (shared_from_this(), od))); + } else { + r = JobManager::instance()->add (shared_ptr (new TranscodeJob (shared_from_this(), od))); } } diff --git a/src/lib/film.h b/src/lib/film.h index cc77460db..04a483998 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -69,7 +69,7 @@ public: void examine_content (); void send_dcp_to_tms (); - void make_dcp (bool); + void make_dcp (); /** @return Logger. * It is safe to call this from any thread. diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index e4f582472..9efe3f545 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -347,7 +347,7 @@ private: void jobs_make_dcp (wxCommandEvent &) { - JobWrapper::make_dcp (this, film, true); + JobWrapper::make_dcp (this, film); } void jobs_send_dcp_to_tms (wxCommandEvent &) diff --git a/src/tools/makedcp.cc b/src/tools/makedcp.cc index 892bed3b8..0c6390771 100644 --- a/src/tools/makedcp.cc +++ b/src/tools/makedcp.cc @@ -155,7 +155,7 @@ main (int argc, char* argv[]) pair const f = Filter::ffmpeg_strings (film->filters ()); cout << "Filters: " << f.first << " " << f.second << "\n"; - film->make_dcp (true); + film->make_dcp (); bool should_stop = false; bool first = true; diff --git a/src/wx/job_wrapper.cc b/src/wx/job_wrapper.cc index cb02ecd02..8ddd3a348 100644 --- a/src/wx/job_wrapper.cc +++ b/src/wx/job_wrapper.cc @@ -26,14 +26,14 @@ using boost::shared_ptr; void -JobWrapper::make_dcp (wxWindow* parent, shared_ptr film, bool transcode) +JobWrapper::make_dcp (wxWindow* parent, shared_ptr film) { if (!film) { return; } try { - film->make_dcp (transcode); + film->make_dcp (); } catch (BadSettingError& e) { error_dialog (parent, wxString::Format (_("Bad setting for %s (%s)"), e.setting().c_str(), e.what())); } catch (std::exception& e) { diff --git a/src/wx/job_wrapper.h b/src/wx/job_wrapper.h index 7120e9f10..b0a4693dd 100644 --- a/src/wx/job_wrapper.h +++ b/src/wx/job_wrapper.h @@ -24,6 +24,6 @@ class Film; namespace JobWrapper { -void make_dcp (wxWindow *, boost::shared_ptr, bool); +void make_dcp (wxWindow *, boost::shared_ptr); } diff --git a/test/test.cc b/test/test.cc index 771325d29..386aead2e 100644 --- a/test/test.cc +++ b/test/test.cc @@ -480,7 +480,7 @@ BOOST_AUTO_TEST_CASE (make_dcp_test) film->set_content ("../../../test/test.mp4"); film->set_format (Format::from_nickname ("Flat")); film->set_dcp_content_type (DCPContentType::from_pretty_name ("Test")); - film->make_dcp (true); + film->make_dcp (); film->write_metadata (); while (JobManager::instance()->work_to_do ()) { @@ -512,7 +512,7 @@ BOOST_AUTO_TEST_CASE (make_dcp_with_range_test) film->set_format (Format::from_nickname ("Flat")); film->set_dcp_content_type (DCPContentType::from_pretty_name ("Test")); film->set_trim_end (42); - film->make_dcp (true); + film->make_dcp (); while (JobManager::instance()->work_to_do() && !JobManager::instance()->errors()) { dvdomatic_sleep (1); -- cgit v1.2.3 From c9831a8704aeae286be6c39bfbdc4b48cff1f087 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 18 Feb 2013 09:55:07 +0000 Subject: Try to fix crash on finishing off DCPs with mono -> 5.1 conversions. --- src/lib/encoder.cc | 42 ++++++++++++++++++++++++------------------ src/lib/encoder.h | 2 +- 2 files changed, 25 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index d64622cba..f25256379 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -140,7 +140,7 @@ Encoder::process_end () } out->set_frames (frames); - _writer->write (out); + write_audio (out); } swr_free (&_swr_context); @@ -319,23 +319,7 @@ Encoder::process_audio (shared_ptr data) } #endif - if (_film->audio_channels() == 1) { - /* We need to switch things around so that the mono channel is on - the centre channel of a 5.1 set (with other channels silent). - */ - - shared_ptr b (new AudioBuffers (6, data->frames ())); - b->make_silent (libdcp::LEFT); - b->make_silent (libdcp::RIGHT); - memcpy (b->data()[libdcp::CENTRE], data->data()[0], data->frames() * sizeof(float)); - b->make_silent (libdcp::LFE); - b->make_silent (libdcp::LS); - b->make_silent (libdcp::RS); - - data = b; - } - - _writer->write (data); + write_audio (data); } void @@ -435,3 +419,25 @@ Encoder::encoder_thread (ServerDescription* server) _condition.notify_all (); } } + +void +Encoder::write_audio (shared_ptr data) +{ + if (_film->audio_channels() == 1) { + /* We need to switch things around so that the mono channel is on + the centre channel of a 5.1 set (with other channels silent). + */ + + shared_ptr b (new AudioBuffers (6, data->frames ())); + b->make_silent (libdcp::LEFT); + b->make_silent (libdcp::RIGHT); + memcpy (b->data()[libdcp::CENTRE], data->data()[0], data->frames() * sizeof(float)); + b->make_silent (libdcp::LFE); + b->make_silent (libdcp::LS); + b->make_silent (libdcp::RS); + + data = b; + } + + _writer->write (data); +} diff --git a/src/lib/encoder.h b/src/lib/encoder.h index 69a5c5a23..86880bc34 100644 --- a/src/lib/encoder.h +++ b/src/lib/encoder.h @@ -88,7 +88,7 @@ private: void frame_done (); - void write_audio (boost::shared_ptr audio); + void write_audio (boost::shared_ptr data); void encoder_thread (ServerDescription *); void terminate_threads (); -- cgit v1.2.3 From 78ef2afb8e64fd0093b2f94b3f8246dba0a8058f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 18 Feb 2013 19:39:23 +0000 Subject: Fix subtitle positioning in the view, I think (#60). --- src/lib/subtitle.cc | 4 ++-- src/wx/film_viewer.cc | 12 +++++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/lib/subtitle.cc b/src/lib/subtitle.cc index bd5f0c879..5bb91af63 100644 --- a/src/lib/subtitle.cc +++ b/src/lib/subtitle.cc @@ -134,8 +134,8 @@ subtitle_transformed_area ( * Combining these two translations gives these expressions. */ - tx.x = target_x_scale * (sub_area.x + (sub_area.width * (1 - subtitle_scale) / 2)); - tx.y = target_y_scale * (sub_area.y + (sub_area.height * (1 - subtitle_scale) / 2)); + tx.x = rint (target_x_scale * (sub_area.x + (sub_area.width * (1 - subtitle_scale) / 2))); + tx.y = rint (target_y_scale * (sub_area.y + (sub_area.height * (1 - subtitle_scale) / 2))); return tx; } diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index e9992a11f..96656ce09 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -149,7 +149,6 @@ FilmViewer::set_film (shared_ptr f) _film->Changed.connect (boost::bind (&FilmViewer::film_changed, this, _1)); film_changed (Film::CONTENT); - film_changed (Film::CROP); film_changed (Film::FORMAT); film_changed (Film::WITH_SUBTITLES); film_changed (Film::SUBTITLE_OFFSET); @@ -289,9 +288,16 @@ FilmViewer::raw_to_display () } if (_raw_sub) { + + /* Our output is already cropped by the decoder, so we need to account for that + when working out the scale that we are applying. + */ + + Size const cropped_size = _film->cropped_size (_film->size ()); + Rect tx = subtitle_transformed_area ( - float (_film_size.width) / _film->size().width, - float (_film_size.height) / _film->size().height, + float (_film_size.width) / cropped_size.width, + float (_film_size.height) / cropped_size.height, _raw_sub->area(), _film->subtitle_offset(), _film->subtitle_scale() ); -- cgit v1.2.3 From 23fb3c45e14ff9c4e8e77c633b216f3167c636e0 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 18 Feb 2013 22:01:43 +0000 Subject: Grotty hack to sort out the layout of the top half of the frame when the editor resizes. --- src/tools/dvdomatic.cc | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 9efe3f545..1b76132f6 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -221,12 +221,12 @@ public: film_viewer = new FilmViewer (film, panel); JobManagerView* job_manager_view = new JobManagerView (panel); - wxSizer* top_sizer = new wxBoxSizer (wxHORIZONTAL); - top_sizer->Add (film_editor, 0, wxALL, 6); - top_sizer->Add (film_viewer, 1, wxEXPAND | wxALL, 6); + _top_sizer = new wxBoxSizer (wxHORIZONTAL); + _top_sizer->Add (film_editor, 0, wxALL, 6); + _top_sizer->Add (film_viewer, 1, wxEXPAND | wxALL, 6); wxBoxSizer* main_sizer = new wxBoxSizer (wxVERTICAL); - main_sizer->Add (top_sizer, 2, wxEXPAND | wxALL, 6); + main_sizer->Add (_top_sizer, 2, wxEXPAND | wxALL, 6); main_sizer->Add (job_manager_view, 1, wxEXPAND | wxALL, 6); panel->SetSizer (main_sizer); @@ -241,12 +241,24 @@ public: } else { file_changed (""); } - + set_film (); + + film_editor->Connect (wxID_ANY, wxEVT_SIZE, wxSizeEventHandler (Frame::film_editor_sized), 0, this); } private: + void film_editor_sized (wxSizeEvent &) + { + static bool in_layout = false; + if (!in_layout) { + in_layout = true; + _top_sizer->Layout (); + in_layout = false; + } + } + void menu_opened (wxMenuEvent& ev) { if (ev.GetMenu() != jobs_menu) { @@ -400,6 +412,8 @@ private: info.SetWebSite (wxT ("http://carlh.net/software/dvdomatic")); wxAboutBox (info); } + + wxSizer* _top_sizer; }; #if wxMINOR_VERSION == 9 -- cgit v1.2.3 From dc08d2da6bf14fd469005ea3512992c66b041da9 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 20 Feb 2013 11:51:12 +0000 Subject: Fix servomatic build. Hopefully resolve confusion wrt linesize and stride for FilterBufferImage; the linesize can apparently sometimes be (slightly) larger than the width for byte-per-pixel images (e.g. YUV420P). Remove grotty peek-style socket communication and use a hopefully more robust send of the length of data as a binary word before the data itself. Should fix #62. --- src/lib/dcp_video_frame.cc | 22 +++----- src/lib/image.cc | 19 +++++-- src/lib/image.h | 1 + src/lib/server.cc | 10 ++-- src/lib/util.cc | 128 ++++++++++---------------------------------- src/lib/util.h | 22 ++++---- src/tools/servomatictest.cc | 52 ++++++++++++------ src/tools/wscript | 2 +- 8 files changed, 104 insertions(+), 152 deletions(-) (limited to 'src') diff --git a/src/lib/dcp_video_frame.cc b/src/lib/dcp_video_frame.cc index 4f3fda44a..9b96724b0 100644 --- a/src/lib/dcp_video_frame.cc +++ b/src/lib/dcp_video_frame.cc @@ -316,7 +316,7 @@ DCPVideoFrame::encode_remotely (ServerDescription const * serv) shared_ptr socket (new Socket); - socket->connect (*endpoint_iterator, 30); + socket->connect (*endpoint_iterator); stringstream s; s << "encode please\n" @@ -352,21 +352,17 @@ DCPVideoFrame::encode_remotely (ServerDescription const * serv) _input->lines(0), _input->lines(1), _input->lines(2), _input->line_size()[0], _input->line_size()[1], _input->line_size()[2] )); - - socket->write ((uint8_t *) s.str().c_str(), s.str().length() + 1, 30); + + socket->write (s.str().length() + 1); + socket->write ((uint8_t *) s.str().c_str(), s.str().length() + 1); _input->write_to_socket (socket); if (_subtitle) { _subtitle->image()->write_to_socket (socket); } - char buffer[32]; - socket->read_indefinite ((uint8_t *) buffer, sizeof (buffer), 30); - socket->consume (strlen (buffer) + 1); - shared_ptr e (new RemotelyEncodedData (atoi (buffer))); - - /* now read the rest */ - socket->read_definite_and_consume (e->data(), e->size(), 30); + shared_ptr e (new RemotelyEncodedData (socket->read_uint32 ())); + socket->read (e->data(), e->size()); _log->log (String::compose ("Finished remotely-encoded frame %1", _frame)); @@ -438,10 +434,8 @@ EncodedData::write_info (shared_ptr film, int frame, libdcp::FrameIn void EncodedData::send (shared_ptr socket) { - stringstream s; - s << _size; - socket->write ((uint8_t *) s.str().c_str(), s.str().length() + 1, 30); - socket->write (_data, _size, 30); + socket->write (_size); + socket->write (_data, _size); } LocallyEncodedData::LocallyEncodedData (uint8_t* d, int s) diff --git a/src/lib/image.cc b/src/lib/image.cc index 0ec6bd26c..73d499fe8 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -323,7 +323,7 @@ Image::read_from_socket (shared_ptr socket) for (int i = 0; i < components(); ++i) { uint8_t* p = data()[i]; for (int y = 0; y < lines(i); ++y) { - socket->read_definite_and_consume (p, line_size()[i], 30); + socket->read (p, line_size()[i]); p += stride()[i]; } } @@ -335,7 +335,7 @@ Image::write_to_socket (shared_ptr socket) const for (int i = 0; i < components(); ++i) { uint8_t* p = data()[i]; for (int y = 0; y < lines(i); ++y) { - socket->write (p, line_size()[i], 30); + socket->write (p, line_size()[i]); p += stride()[i]; } } @@ -503,12 +503,18 @@ FilterBufferImage::FilterBufferImage (AVPixelFormat p, AVFilterBufferRef* b) : Image (p) , _buffer (b) { - + _line_size = (int *) av_malloc (4 * sizeof (int)); + _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0; + + for (int i = 0; i < components(); ++i) { + _line_size[i] = size().width * bytes_per_pixel(i); + } } FilterBufferImage::~FilterBufferImage () { avfilter_unref_buffer (_buffer); + av_free (_line_size); } uint8_t ** @@ -520,13 +526,16 @@ FilterBufferImage::data () const int * FilterBufferImage::line_size () const { - return _buffer->linesize; + return _line_size; } int * FilterBufferImage::stride () const { - /* XXX? */ + /* I've seen images where the _buffer->linesize is larger than the width + (by a small amount), suggesting that _buffer->linesize is what we call + stride. But I'm not sure. + */ return _buffer->linesize; } diff --git a/src/lib/image.h b/src/lib/image.h index 23f13a648..f40ea9280 100644 --- a/src/lib/image.h +++ b/src/lib/image.h @@ -117,6 +117,7 @@ private: FilterBufferImage& operator= (FilterBufferImage const &); AVFilterBufferRef* _buffer; + int* _line_size; }; /** @class SimpleImage diff --git a/src/lib/server.cc b/src/lib/server.cc index d75ab0fb6..3614ed9e4 100644 --- a/src/lib/server.cc +++ b/src/lib/server.cc @@ -28,6 +28,7 @@ #include #include #include +#include #include "server.h" #include "util.h" #include "scaler.h" @@ -45,6 +46,7 @@ using boost::algorithm::is_any_of; using boost::algorithm::split; using boost::thread; using boost::bind; +using boost::scoped_array; using libdcp::Size; /** Create a server description from a string of metadata returned from as_metadata(). @@ -82,11 +84,11 @@ Server::Server (Log* log) int Server::process (shared_ptr socket) { - char buffer[512]; - socket->read_indefinite ((uint8_t *) buffer, sizeof (buffer), 30); - socket->consume (strlen (buffer) + 1); + uint32_t length = socket->read_uint32 (); + scoped_array buffer (new char[length]); + socket->read (reinterpret_cast (buffer.get()), length); - stringstream s (buffer); + stringstream s (buffer.get()); multimap kv = read_key_value (s); if (get_required_string (kv, "encode") != "please") { diff --git a/src/lib/util.cc b/src/lib/util.cc index c0c8be984..4ee304600 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -485,10 +485,10 @@ colour_lut_index_to_name (int index) return ""; } -Socket::Socket () +Socket::Socket (int timeout) : _deadline (_io_service) , _socket (_io_service) - , _buffer_data (0) + , _timeout (timeout) { _deadline.expires_at (posix_time::pos_infin); check (); @@ -505,14 +505,13 @@ Socket::check () _deadline.async_wait (boost::bind (&Socket::check, this)); } -/** Blocking connect with timeout. +/** Blocking connect. * @param endpoint End-point to connect to. - * @param timeout Time-out in seconds. */ void -Socket::connect (asio::ip::basic_resolver_entry const & endpoint, int timeout) +Socket::connect (asio::ip::basic_resolver_entry const & endpoint) { - _deadline.expires_from_now (posix_time::seconds (timeout)); + _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); do { @@ -524,132 +523,61 @@ Socket::connect (asio::ip::basic_resolver_entry const & endpoint, } } -/** Blocking write with timeout. +/** Blocking write. * @param data Buffer to write. * @param size Number of bytes to write. - * @param timeout Time-out, in seconds. */ void -Socket::write (uint8_t const * data, int size, int timeout) +Socket::write (uint8_t const * data, int size) { - _deadline.expires_from_now (posix_time::seconds (timeout)); + _deadline.expires_from_now (posix_time::seconds (_timeout)); system::error_code ec = asio::error::would_block; asio::async_write (_socket, asio::buffer (data, size), lambda::var(ec) = lambda::_1); + do { _io_service.run_one (); } while (ec == asio::error::would_block); if (ec) { - throw NetworkError ("write timed out"); + throw NetworkError (ec.message ()); } } -/** Blocking read with timeout. +void +Socket::write (uint32_t v) +{ + v = htonl (v); + write (reinterpret_cast (&v), 4); +} + +/** Blocking read. * @param data Buffer to read to. * @param size Number of bytes to read. - * @param timeout Time-out, in seconds. */ -int -Socket::read (uint8_t* data, int size, int timeout) +void +Socket::read (uint8_t* data, int size) { - _deadline.expires_from_now (posix_time::seconds (timeout)); + _deadline.expires_from_now (posix_time::seconds (_timeout)); system::error_code ec = asio::error::would_block; - int amount_read = 0; - - _socket.async_read_some ( - asio::buffer (data, size), - (lambda::var(ec) = lambda::_1, lambda::var(amount_read) = lambda::_2) - ); + asio::async_read (_socket, asio::buffer (data, size), lambda::var(ec) = lambda::_1); do { _io_service.run_one (); } while (ec == asio::error::would_block); if (ec) { - amount_read = 0; - } - - return amount_read; -} - -/** Mark some data as being `consumed', so that it will not be returned - * as data again. - * @param size Amount of data to consume, in bytes. - */ -void -Socket::consume (int size) -{ - assert (_buffer_data >= size); - - _buffer_data -= size; - if (_buffer_data > 0) { - /* Shift still-valid data to the start of the buffer */ - memmove (_buffer, _buffer + size, _buffer_data); + throw NetworkError (ec.message ()); } } -/** Read a definite amount of data from our socket, and mark - * it as consumed. - * @param data Where to put the data. - * @param size Number of bytes to read. - */ -void -Socket::read_definite_and_consume (uint8_t* data, int size, int timeout) -{ - int const from_buffer = min (_buffer_data, size); - if (from_buffer > 0) { - /* Get data from our buffer */ - memcpy (data, _buffer, from_buffer); - consume (from_buffer); - /* Update our output state */ - data += from_buffer; - size -= from_buffer; - } - - /* read() the rest */ - while (size > 0) { - int const n = read (data, size, timeout); - if (n <= 0) { - throw NetworkError ("could not read"); - } - - data += n; - size -= n; - } -} - -/** Read as much data as is available, up to some limit. - * @param data Where to put the data. - * @param size Maximum amount of data to read. - * - * XXX This method assumes that there is always lots of data to read(); - * if there isn't, it will hang waiting for data that will never arrive. - */ -void -Socket::read_indefinite (uint8_t* data, int size, int timeout) +uint32_t +Socket::read_uint32 () { - assert (size < int (sizeof (_buffer))); - - /* Amount of extra data we need to read () */ - int to_read = size - _buffer_data; - while (to_read > 0) { - /* read as much of it as we can (into our buffer) */ - int const n = read (_buffer + _buffer_data, to_read, timeout); - if (n <= 0) { - throw NetworkError ("could not read"); - } - - to_read -= n; - _buffer_data += n; - } - - assert (_buffer_data >= size); - - /* copy data into the output buffer */ - assert (size >= _buffer_data); - memcpy (data, _buffer, size); + uint32_t v; + read (reinterpret_cast (&v), 4); + return ntohl (v); } /** @param other A Rect. diff --git a/src/lib/util.h b/src/lib/util.h index c4940a5d7..87735ea8e 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -194,39 +194,35 @@ extern std::string get_optional_string (std::multimap * that are useful for DVD-o-matic. * * This class wraps some things that I could not work out how to do with boost; - * most notably, sync read/write calls with timeouts, and the ability to peek into - * data being read. + * most notably, sync read/write calls with timeouts. */ class Socket { public: - Socket (); + Socket (int timeout = 30); /** @return Our underlying socket */ boost::asio::ip::tcp::socket& socket () { return _socket; } - void connect (boost::asio::ip::basic_resolver_entry const & endpoint, int timeout); - void write (uint8_t const * data, int size, int timeout); + void connect (boost::asio::ip::basic_resolver_entry const & endpoint); + + void write (uint32_t n); + void write (uint8_t const * data, int size); - void read_definite_and_consume (uint8_t* data, int size, int timeout); - void read_indefinite (uint8_t* data, int size, int timeout); - void consume (int amount); + void read (uint8_t* data, int size); + uint32_t read_uint32 (); private: void check (); - int read (uint8_t* data, int size, int timeout); Socket (Socket const &); boost::asio::io_service _io_service; boost::asio::deadline_timer _deadline; boost::asio::ip::tcp::socket _socket; - /** a buffer for small reads */ - uint8_t _buffer[1024]; - /** amount of valid data in the buffer */ - int _buffer_data; + int _timeout; }; /** @class AudioBuffers diff --git a/src/tools/servomatictest.cc b/src/tools/servomatictest.cc index 88c2a833e..91ad02120 100644 --- a/src/tools/servomatictest.cc +++ b/src/tools/servomatictest.cc @@ -34,22 +34,40 @@ #include "scaler.h" #include "log.h" #include "decoder_factory.h" +#include "video_decoder.h" -using namespace std; -using namespace boost; +using std::cout; +using std::cerr; +using std::string; +using std::pair; +using boost::shared_ptr; -static Server* server; -static Log log_ ("servomatictest.log"); +static ServerDescription* server; +static FileLog log_ ("servomatictest.log"); +static int frame = 0; void -process_video (shared_ptr image, bool, int frame) +process_video (shared_ptr image, bool, shared_ptr sub) { - shared_ptr local (new DCPVideoFrame (image, Size (1024, 1024), 0, Scaler::from_id ("bicubic"), frame, 24, "", 0, 250000000, &log_)); - shared_ptr remote (new DCPVideoFrame (image, Size (1024, 1024), 0, Scaler::from_id ("bicubic"), frame, 24, "", 0, 250000000, &log_)); + shared_ptr local ( + new DCPVideoFrame ( + image, sub, + libdcp::Size (1024, 1024), 0, 0, 0, + Scaler::from_id ("bicubic"), frame, 24, "", 0, 250000000, &log_) + ); + + shared_ptr remote ( + new DCPVideoFrame ( + image, sub, + libdcp::Size (1024, 1024), 0, 0, 0, + Scaler::from_id ("bicubic"), frame, 24, "", 0, 250000000, &log_) + ); cout << "Frame " << frame << ": "; cout.flush (); + ++frame; + shared_ptr local_encoded = local->encode_locally (); shared_ptr remote_encoded; @@ -130,17 +148,21 @@ main (int argc, char* argv[]) dvdomatic_setup (); - server = new Server (server_host, 1); - Film film (film_dir, true); + server = new ServerDescription (server_host, 1); + shared_ptr film (new Film (film_dir, true)); - shared_ptr opt (new Options ("fred", "jim", "sheila")); - opt->out_size = Size (1024, 1024); - opt->decode_audio = false; + DecodeOptions opt; + opt.decode_audio = false; + opt.decode_subtitles = true; + opt.video_sync = true; - shared_ptr decoder = decoder_factory (film.state_copy(), opt, 0, &log_); + Decoders decoders = decoder_factory (film, opt); try { - decoder->Video.connect (sigc::ptr_fun (process_video)); - decoder->go (); + decoders.video->Video.connect (boost::bind (process_video, _1, _2, _3)); + bool done = false; + while (!done) { + done = decoders.video->pass (); + } } catch (std::exception& e) { cerr << "Error: " << e.what() << "\n"; } diff --git a/src/tools/wscript b/src/tools/wscript index 5a837f845..c843c61d8 100644 --- a/src/tools/wscript +++ b/src/tools/wscript @@ -1,5 +1,5 @@ def build(bld): - for t in ['makedcp', 'servomatic_cli']: + for t in ['makedcp', 'servomatic_cli', 'servomatictest']: obj = bld(features = 'cxx cxxprogram') obj.uselib = 'BOOST_THREAD OPENJPEG DCP AVFORMAT AVFILTER AVCODEC AVUTIL SWSCALE POSTPROC' obj.includes = ['..'] -- cgit v1.2.3 From bc5df5cc9c2b11524938281f1b2043b185373020 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 22 Feb 2013 23:36:32 +0000 Subject: Some i18n stuff. --- TRANSLATORS | 13 +++++++++ i18n.py | 16 +++++++++++ src/lib/film.cc | 2 ++ src/tools/dvdomatic.cc | 75 +++++++++++++++++++++++++++++++++++--------------- src/tools/wscript | 12 ++++++++ src/wscript | 5 ++++ src/wx/wscript | 9 +++++- wscript | 12 ++++++++ 8 files changed, 121 insertions(+), 23 deletions(-) create mode 100644 TRANSLATORS create mode 100644 i18n.py (limited to 'src') diff --git a/TRANSLATORS b/TRANSLATORS new file mode 100644 index 000000000..cbfc875d4 --- /dev/null +++ b/TRANSLATORS @@ -0,0 +1,13 @@ +Translating DVD-o-matic +----------------------- + +1. Run ./waf po + +This will generate build/src/lib/dvdomatic.pot and build/src/wx/libdvdomatic-wx.pot. + +For each file: + +2. Open poEdit, "New catalogue from POT file", do translations, save as .po file. + +3. Send to me. + diff --git a/i18n.py b/i18n.py new file mode 100644 index 000000000..d5531834b --- /dev/null +++ b/i18n.py @@ -0,0 +1,16 @@ +import glob +import os +from waflib import Logs + +def po_to_mo(dir, name): + for f in glob.glob(os.path.join(dir, 'po', '*.po')): + + lang = os.path.basename(f).replace('.po', '') + out = os.path.join('build', dir, 'mo', lang, '%s.mo' % name) + try: + os.makedirs(os.path.dirname(out)) + except: + pass + + os.system('msgfmt %s -o %s' % (f, out)) + Logs.info('%s -> %s' % (f, out)) diff --git a/src/lib/film.cc b/src/lib/film.cc index 600cdfa02..addaa0852 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -52,6 +52,8 @@ #include "audio_decoder.h" #include "external_audio_decoder.h" +#include "i18n.h" + using std::string; using std::stringstream; using std::multimap; diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 1b76132f6..be61bf433 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -60,6 +60,7 @@ static shared_ptr film; static std::string log_level; static std::string film_to_load; static wxMenu* jobs_menu = 0; +static wxLocale* locale = 0; static void set_menu_sensitivity (); @@ -68,9 +69,12 @@ class FilmChangedDialog public: FilmChangedDialog () { - stringstream s; - s << "Save changes to film \"" << film->name() << "\" before closing?"; - _dialog = new wxMessageDialog (0, std_to_wx (s.str()), _("Film changed"), wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION); + _dialog = new wxMessageDialog ( + 0, + std_to_wx (String::compose ("Save changes to film \"%1\" before closing?", film->name())), + _("Film changed"), + wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION + ); } ~FilmChangedDialog () @@ -117,9 +121,9 @@ enum Sensitivity { map menu_items; void -add_item (wxMenu* menu, std::string text, int id, Sensitivity sens) +add_item (wxMenu* menu, wxString text, int id, Sensitivity sens) { - wxMenuItem* item = menu->Append (id, std_to_wx (text)); + wxMenuItem* item = menu->Append (id, text); menu_items.insert (make_pair (item, sens)); } @@ -153,32 +157,32 @@ void setup_menu (wxMenuBar* m) { wxMenu* file = new wxMenu; - add_item (file, "New...", ID_file_new, ALWAYS); - add_item (file, "&Open...", ID_file_open, ALWAYS); + add_item (file, _("New..."), ID_file_new, ALWAYS); + add_item (file, _("&Open..."), ID_file_open, ALWAYS); file->AppendSeparator (); - add_item (file, "&Save", ID_file_save, NEEDS_FILM); + add_item (file, _("&Save"), ID_file_save, NEEDS_FILM); file->AppendSeparator (); - add_item (file, "&Properties...", ID_file_properties, NEEDS_FILM); + add_item (file, _("&Properties..."), ID_file_properties, NEEDS_FILM); file->AppendSeparator (); - add_item (file, "&Quit", ID_file_quit, ALWAYS); + add_item (file, _("&Quit"), ID_file_quit, ALWAYS); wxMenu* edit = new wxMenu; - add_item (edit, "&Preferences...", ID_edit_preferences, ALWAYS); + add_item (edit, _("&Preferences..."), ID_edit_preferences, ALWAYS); jobs_menu = new wxMenu; - add_item (jobs_menu, "&Make DCP", ID_jobs_make_dcp, NEEDS_FILM); - add_item (jobs_menu, "&Send DCP to TMS", ID_jobs_send_dcp_to_tms, NEEDS_FILM); - add_item (jobs_menu, "S&how DCP", ID_jobs_show_dcp, NEEDS_FILM); + add_item (jobs_menu, _("&Make DCP"), ID_jobs_make_dcp, NEEDS_FILM); + add_item (jobs_menu, _("&Send DCP to TMS"), ID_jobs_send_dcp_to_tms, NEEDS_FILM); + add_item (jobs_menu, _("S&how DCP"), ID_jobs_show_dcp, NEEDS_FILM); jobs_menu->AppendSeparator (); - add_item (jobs_menu, "&Examine content", ID_jobs_examine_content, NEEDS_FILM); + add_item (jobs_menu, _("&Examine content"), ID_jobs_examine_content, NEEDS_FILM); wxMenu* help = new wxMenu; - add_item (help, "About", ID_help_about, ALWAYS); + add_item (help, _("About"), ID_help_about, ALWAYS); - m->Append (file, _("&File")); - m->Append (edit, _("&Edit")); - m->Append (jobs_menu, _("&Jobs")); - m->Append (help, _("&Help")); + m->Append (file, _(_("&File"))); + m->Append (edit, _(_("&Edit"))); + m->Append (jobs_menu, _(_("&Jobs"))); + m->Append (help, _(_("&Help"))); } bool @@ -280,7 +284,7 @@ private: void file_changed (string f) { stringstream s; - s << "DVD-o-matic"; + s << _("DVD-o-matic"); if (!f.empty ()) { s << " - " << f; } @@ -430,6 +434,32 @@ static const wxCmdLineEntryDesc command_line_description[] = { }; #endif +void +setup_i18n () +{ + int language = wxLANGUAGE_DEFAULT; + + if (wxLocale::IsAvailable (language)) { + locale = new wxLocale (language, wxLOCALE_LOAD_DEFAULT); + +#ifdef __WXGTK__ + locale->AddCatalogLookupPathPrefix (wxT ("/usr")); + locale->AddCatalogLookupPathPrefix (wxT ("/usr/local")); + locale->AddCatalogLookupPathPrefix (wxT ("build/src/wx/mo")); + locale->AddCatalogLookupPathPrefix (wxT ("build/src/tools/mo")); + wxStandardPaths* paths = (wxStandardPaths*) &wxStandardPaths::Get(); + wxString prefix = paths->GetInstallPrefix(); + locale->AddCatalogLookupPathPrefix (prefix); +#endif + + if (!locale->IsOk()) { + delete locale; + locale = new wxLocale (wxLANGUAGE_ENGLISH); + language = wxLANGUAGE_ENGLISH; + } + } +} + class App : public wxApp { bool OnInit () @@ -443,6 +473,7 @@ class App : public wxApp #endif wxInitAllImageHandlers (); + setup_i18n (); dvdomatic_setup (); @@ -451,7 +482,7 @@ class App : public wxApp film.reset (new Film (film_to_load)); film->log()->set_level (log_level); } catch (exception& e) { - error_dialog (0, std_to_wx (String::compose ("Could not load film %1 (%2)", film_to_load, e.what()))); + error_dialog (0, std_to_wx (String::compose (wx_to_std (_("Could not load film %1 (%2)")), film_to_load, e.what()))); } } diff --git a/src/tools/wscript b/src/tools/wscript index c843c61d8..8af3d06a5 100644 --- a/src/tools/wscript +++ b/src/tools/wscript @@ -1,3 +1,8 @@ +import os +import glob +from waflib import Logs +import i18n + def build(bld): for t in ['makedcp', 'servomatic_cli', 'servomatictest']: obj = bld(features = 'cxx cxxprogram') @@ -17,3 +22,10 @@ def build(bld): if bld.env.TARGET_WINDOWS: obj.source += ' ../../windows/dvdomatic.rc' obj.target = t + +def pot(bld): + os.system('xgettext -d dvdomatic -s --keyword=_ -p build/src/tools -o dvdomatic.pot %s' % os.path.join('src', 'tools', 'dvdomatic.cc')) + +def mo(bld): + i18n.po_to_mo(os.path.join('src', 'tools'), 'dvdomatic') + diff --git a/src/wscript b/src/wscript index ed497ff0c..abe39894d 100644 --- a/src/wscript +++ b/src/wscript @@ -11,3 +11,8 @@ def build(bld): def pot(bld): bld.recurse('lib') bld.recurse('wx') + bld.recurse('tools') + +def mo(bld): + bld.recurse('wx') + bld.recurse('tools') diff --git a/src/wx/wscript b/src/wx/wscript index ef1d1c083..95cdbc8f0 100644 --- a/src/wx/wscript +++ b/src/wx/wscript @@ -1,4 +1,7 @@ import os +import glob +from waflib import Logs +import i18n sources = """ config_dialog.cc @@ -42,4 +45,8 @@ def pot(bld): if len(t) > 0: s += (os.path.join('src', 'wx', t)) + " " - os.system('xgettext -d libdvdomatic -s --keyword=_ -p build/src/wx -o libdvdomatic-wx.pot %s' % s) + os.system('xgettext -d libdvdomatic-wx -s --keyword=_ -p build/src/wx -o libdvdomatic-wx.pot %s' % s) + +def mo(bld): + i18n.po_to_mo(os.path.join('src', 'wx'), 'libdvdomatic-wx') + diff --git a/wscript b/wscript index cce8c240e..2a5c54951 100644 --- a/wscript +++ b/wscript @@ -198,6 +198,15 @@ def configure(conf): define_name = 'HAVE_BUFFERSRC_H', mandatory = False) + conf.find_program('msgfmt', var='MSGFMT') + + datadir = conf.env.DATADIR + if not datadir: + datadir = os.path.join(conf.env.PREFIX, 'share') + + conf.define('LOCALEDIR', os.path.join(datadir, 'locale')) + conf.define('DATADIR', datadir) + conf.recurse('src') conf.recurse('test') @@ -256,3 +265,6 @@ def post(ctx): def pot(bld): bld.recurse('src') + +def mo(bld): + bld.recurse('src') -- cgit v1.2.3 From c4cf2ae86bfe3369acd13212ba8df494496b4de0 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 22 Feb 2013 23:40:12 +0000 Subject: Fix previous. --- src/tools/dvdomatic.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index be61bf433..d1760c327 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -451,6 +451,9 @@ setup_i18n () wxString prefix = paths->GetInstallPrefix(); locale->AddCatalogLookupPathPrefix (prefix); #endif + + locale->AddCatalog ("libdvdomatic-wx"); + locale->AddCatalog ("dvdomatic"); if (!locale->IsOk()) { delete locale; -- cgit v1.2.3 From 7913cba90bccb9501b63a0518c58abbd5a6b330d Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 23 Feb 2013 00:12:11 +0000 Subject: Try to centralise .pot building. --- i18n.py | 11 +++++++++++ src/lib/wscript | 9 ++------- src/tools/wscript | 2 +- src/wx/wscript | 8 +------- 4 files changed, 15 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/i18n.py b/i18n.py index d5531834b..10eaa38e9 100644 --- a/i18n.py +++ b/i18n.py @@ -2,6 +2,17 @@ import glob import os from waflib import Logs +def pot(dir, sources, name): + s = "" + for f in sources.split('\n'): + t = f.strip() + if len(t) > 0: + s += (os.path.join(dir, t)) + " " + + Logs.info('Making %s.pot' % os.path.join('build', dir, name)) + os.system('xgettext -d %s -s --keyword=_ -p %s -o %s.pot %s' % (name, os.path.join('build', dir), name, s)) + + def po_to_mo(dir, name): for f in glob.glob(os.path.join(dir, 'po', '*.po')): diff --git a/src/lib/wscript b/src/lib/wscript index ee89ad085..59047c70d 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -1,4 +1,5 @@ import os +import i18n sources = """ ab_transcode_job.cc @@ -68,10 +69,4 @@ def build(bld): obj.target = 'dvdomatic' def pot(bld): - s = "" - for f in sources.split('\n'): - t = f.strip() - if len(t) > 0: - s += (os.path.join('src', 'lib', t)) + " " - - os.system('xgettext -d libdvdomatic -s --keyword=_ -p build/src/lib -o libdvdomatic.pot %s' % s) + i18n.pot(os.path.join('src', 'lib'), sources, 'libdvdomatic') diff --git a/src/tools/wscript b/src/tools/wscript index 8af3d06a5..de130ce17 100644 --- a/src/tools/wscript +++ b/src/tools/wscript @@ -24,7 +24,7 @@ def build(bld): obj.target = t def pot(bld): - os.system('xgettext -d dvdomatic -s --keyword=_ -p build/src/tools -o dvdomatic.pot %s' % os.path.join('src', 'tools', 'dvdomatic.cc')) + i18n.pot(os.path.join('src', 'tools'), 'dvdomatic.cc', 'dvdomatic') def mo(bld): i18n.po_to_mo(os.path.join('src', 'tools'), 'dvdomatic') diff --git a/src/wx/wscript b/src/wx/wscript index 95cdbc8f0..a0a4bbe8b 100644 --- a/src/wx/wscript +++ b/src/wx/wscript @@ -39,13 +39,7 @@ def build(bld): obj.target = 'dvdomatic-wx' def pot(bld): - s = "" - for f in sources.split('\n'): - t = f.strip() - if len(t) > 0: - s += (os.path.join('src', 'wx', t)) + " " - - os.system('xgettext -d libdvdomatic-wx -s --keyword=_ -p build/src/wx -o libdvdomatic-wx.pot %s' % s) + i18n.pot(os.path.join('src', 'wx'), sources, 'libdvdomatic-wx') def mo(bld): i18n.po_to_mo(os.path.join('src', 'wx'), 'libdvdomatic-wx') -- cgit v1.2.3 From 2e5b4effbc5e7f7ac74cae541a05d3401c9170b0 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 23 Feb 2013 21:35:44 +0000 Subject: Throw an exception rather than asserting when unable to handle a pixel format (#65). --- src/lib/exceptions.h | 13 +++++++++++++ src/lib/image.cc | 6 +++--- 2 files changed, 16 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/lib/exceptions.h b/src/lib/exceptions.h index 6de8806e4..277355117 100644 --- a/src/lib/exceptions.h +++ b/src/lib/exceptions.h @@ -28,6 +28,9 @@ #include #include #include +extern "C" { +#include +} #include "compose.hpp" /** @class StringError @@ -220,6 +223,14 @@ public: {} }; +class PixelFormatError : public StringError +{ +public: + PixelFormatError (std::string o, AVPixelFormat f) + : StringError (String::compose ("Cannot handle pixel format %1 during %2", f, o)) + {} +}; + class ExceptionStore { public: @@ -245,4 +256,6 @@ private: mutable boost::mutex _mutex; }; + + #endif diff --git a/src/lib/image.cc b/src/lib/image.cc index 73d499fe8..ae87304c2 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -70,7 +70,7 @@ Image::lines (int n) const case PIX_FMT_YUV422P: return size().height; default: - assert (false); + throw PixelFormatError ("lines()", _pixel_format); } return 0; @@ -89,7 +89,7 @@ Image::components () const case PIX_FMT_RGBA: return 1; default: - assert (false); + throw PixelFormatError ("components()", _pixel_format); } return 0; @@ -202,7 +202,7 @@ Image::post_process (string pp, bool aligned) const pp_format = PP_FORMAT_422; break; default: - assert (false); + throw PixelFormatError ("post_process", pixel_format()); } pp_mode* mode = pp_get_mode_by_name_and_quality (pp.c_str (), PP_QUALITY_MAX); -- cgit v1.2.3 From c9b733ba0f05c011d6880ffe3aae2a87e292d106 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 23 Feb 2013 21:36:08 +0000 Subject: Throw an exception rather than asserting when unable to handle a pixel format (#65). --- src/lib/exceptions.h | 13 +++++++++++++ src/lib/image.cc | 6 +++--- 2 files changed, 16 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/lib/exceptions.h b/src/lib/exceptions.h index 6de8806e4..277355117 100644 --- a/src/lib/exceptions.h +++ b/src/lib/exceptions.h @@ -28,6 +28,9 @@ #include #include #include +extern "C" { +#include +} #include "compose.hpp" /** @class StringError @@ -220,6 +223,14 @@ public: {} }; +class PixelFormatError : public StringError +{ +public: + PixelFormatError (std::string o, AVPixelFormat f) + : StringError (String::compose ("Cannot handle pixel format %1 during %2", f, o)) + {} +}; + class ExceptionStore { public: @@ -245,4 +256,6 @@ private: mutable boost::mutex _mutex; }; + + #endif diff --git a/src/lib/image.cc b/src/lib/image.cc index 73d499fe8..ae87304c2 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -70,7 +70,7 @@ Image::lines (int n) const case PIX_FMT_YUV422P: return size().height; default: - assert (false); + throw PixelFormatError ("lines()", _pixel_format); } return 0; @@ -89,7 +89,7 @@ Image::components () const case PIX_FMT_RGBA: return 1; default: - assert (false); + throw PixelFormatError ("components()", _pixel_format); } return 0; @@ -202,7 +202,7 @@ Image::post_process (string pp, bool aligned) const pp_format = PP_FORMAT_422; break; default: - assert (false); + throw PixelFormatError ("post_process", pixel_format()); } pp_mode* mode = pp_get_mode_by_name_and_quality (pp.c_str (), PP_QUALITY_MAX); -- cgit v1.2.3 From f7a38b76ea50c62624972994f6a7ea9feaaf4f6b Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 23 Feb 2013 21:40:08 +0000 Subject: Support YUV444P pixels (#66). --- src/lib/image.cc | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/lib/image.cc b/src/lib/image.cc index ae87304c2..f38d44185 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -68,6 +68,7 @@ Image::lines (int n) const case PIX_FMT_RGBA: case PIX_FMT_YUV422P10LE: case PIX_FMT_YUV422P: + case PIX_FMT_YUV444P: return size().height; default: throw PixelFormatError ("lines()", _pixel_format); @@ -84,6 +85,7 @@ Image::components () const case PIX_FMT_YUV420P: case PIX_FMT_YUV422P10LE: case PIX_FMT_YUV422P: + case PIX_FMT_YUV444P: return 3; case PIX_FMT_RGB24: case PIX_FMT_RGBA: @@ -201,6 +203,8 @@ Image::post_process (string pp, bool aligned) const case PIX_FMT_YUV422P: pp_format = PP_FORMAT_422; break; + case PIX_FMT_YUV444P: + pp_format = PP_FORMAT_444; default: throw PixelFormatError ("post_process", pixel_format()); } @@ -254,6 +258,7 @@ Image::make_black () switch (_pixel_format) { case PIX_FMT_YUV420P: case PIX_FMT_YUV422P: + case PIX_FMT_YUV444P: memset (data()[0], 0, lines(0) * stride()[0]); memset (data()[1], 0x7f, lines(1) * stride()[1]); memset (data()[2], 0x7f, lines(2) * stride()[2]); @@ -375,6 +380,8 @@ Image::bytes_per_pixel (int c) const } else { return 1; } + case PIX_FMT_YUV444P: + return 3; default: assert (false); } -- cgit v1.2.3 From da0b66c3c8fc7b0813bb62ee48f24263bf4a682f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 23 Feb 2013 21:42:21 +0000 Subject: Tweak label. --- src/wx/film_editor.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 54eccb4f1..68291a812 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -124,7 +124,7 @@ FilmEditor::make_film_panel () _dcp_content_type = new wxChoice (_film_panel, wxID_ANY); grid->Add (_dcp_content_type); - video_control (add_label_to_sizer (grid, _film_panel, _("Frames Per Second"))); + video_control (add_label_to_sizer (grid, _film_panel, _("Original Frame Rate"))); _frames_per_second = new wxStaticText (_film_panel, wxID_ANY, wxT ("")); grid->Add (video_control (_frames_per_second), 1, wxALIGN_CENTER_VERTICAL); -- cgit v1.2.3 From bbd352c3a0acf312e66b8be0d8bfb475275102d6 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 24 Feb 2013 10:29:41 +0000 Subject: Tweak job progress reporting. --- src/lib/job.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/lib/job.cc b/src/lib/job.cc index bde2c8cfd..bfad65a0a 100644 --- a/src/lib/job.cc +++ b/src/lib/job.cc @@ -272,10 +272,11 @@ Job::status () const } stringstream s; - if (!finished () && p >= 0 && t > 10 && r > 0) { - s << pc << "%; " << seconds_to_approximate_hms (r) << " remaining"; - } else if (!finished () && (t <= 10 || r == 0)) { + if (!finished ()) { s << pc << "%"; + if (p >= 0 && t > 10 && r > 0) { + s << "; " << seconds_to_approximate_hms (r) << " remaining"; + } } else if (finished_ok ()) { s << "OK (ran for " << seconds_to_hms (_ran_for) << ")"; } else if (finished_in_error ()) { -- cgit v1.2.3 From cf1e212c30ec7419b96388e4f78b44cb55bf34c5 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 24 Feb 2013 22:15:50 +0000 Subject: Basic stuff to analyse audio (job). --- src/lib/analyse_audio_job.cc | 108 +++++++++++++++++++++++++++++++++++++++++++ src/lib/analyse_audio_job.h | 45 ++++++++++++++++++ src/lib/audio_analysis.cc | 69 +++++++++++++++++++++++++++ src/lib/audio_analysis.h | 59 +++++++++++++++++++++++ src/lib/ffmpeg_decoder.cc | 12 +++-- src/lib/film.cc | 29 ++++++++++++ src/lib/film.h | 6 +++ src/lib/options.h | 6 ++- src/lib/wscript | 2 + src/tools/dvdomatic.cc | 12 ++--- src/wx/film_editor.cc | 14 ++++++ src/wx/film_editor.h | 2 + src/wx/wscript | 2 + 13 files changed, 353 insertions(+), 13 deletions(-) create mode 100644 src/lib/analyse_audio_job.cc create mode 100644 src/lib/analyse_audio_job.h create mode 100644 src/lib/audio_analysis.cc create mode 100644 src/lib/audio_analysis.h (limited to 'src') diff --git a/src/lib/analyse_audio_job.cc b/src/lib/analyse_audio_job.cc new file mode 100644 index 000000000..5623fdfcc --- /dev/null +++ b/src/lib/analyse_audio_job.cc @@ -0,0 +1,108 @@ +/* + Copyright (C) 2012 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "audio_analysis.h" +#include "analyse_audio_job.h" +#include "compose.hpp" +#include "film.h" +#include "options.h" +#include "decoder_factory.h" +#include "audio_decoder.h" + +using std::string; +using std::max; +using boost::shared_ptr; + +int const AnalyseAudioJob::_num_points = 1024; + +AnalyseAudioJob::AnalyseAudioJob (shared_ptr f) + : Job (f) + , _done_for_this_point (0) + , _done (0) + , _samples_per_point (1) +{ + +} + +string +AnalyseAudioJob::name () const +{ + return String::compose ("Analyse audio of %1", _film->name()); +} + +void +AnalyseAudioJob::run () +{ + if (!_film->audio_stream () || !_film->length()) { + set_progress (1); + set_state (FINISHED_ERROR); + return; + } + + DecodeOptions options; + options.decode_video = false; + + Decoders decoders = decoder_factory (_film, options); + assert (decoders.audio); + + decoders.audio->set_audio_stream (_film->audio_stream ()); + decoders.audio->Audio.connect (bind (&AnalyseAudioJob::audio, this, _1)); + + int64_t total_audio_frames = video_frames_to_audio_frames (_film->length().get(), _film->audio_stream()->sample_rate(), _film->frames_per_second()); + _samples_per_point = total_audio_frames / _num_points; + + _current.resize (_film->audio_stream()->channels ()); + _analysis.reset (new AudioAnalysis (_film->audio_stream()->channels())); + + while (!decoders.audio->pass()) { + set_progress (float (_done) / total_audio_frames); + } + + _analysis->write (_film->audio_analysis_path ()); + + set_progress (1); + set_state (FINISHED_OK); +} + +void +AnalyseAudioJob::audio (shared_ptr b) +{ + for (int i = 0; i < b->frames(); ++i) { + for (int j = 0; j < b->channels(); ++j) { + float const s = b->data(j)[i]; + _current[j][AudioPoint::RMS] += pow (s, 2); + _current[j][AudioPoint::PEAK] = max (_current[j][AudioPoint::PEAK], fabsf (s)); + + if (_done_for_this_point == _samples_per_point) { + _current[j][AudioPoint::RMS] = 20 * log10 (sqrt (_current[j][AudioPoint::RMS] / _samples_per_point)); + _current[j][AudioPoint::PEAK] = 20 * log10 (_current[j][AudioPoint::PEAK]); + + _analysis->add_point (j, _current[j]); + + _done_for_this_point = 0; + _current[j] = AudioPoint (); + } + } + + ++_done_for_this_point; + } + + _done += b->frames (); +} + diff --git a/src/lib/analyse_audio_job.h b/src/lib/analyse_audio_job.h new file mode 100644 index 000000000..1e7229ce6 --- /dev/null +++ b/src/lib/analyse_audio_job.h @@ -0,0 +1,45 @@ +/* + Copyright (C) 2012 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "job.h" +#include "audio_analysis.h" + +class AudioBuffers; + +class AnalyseAudioJob : public Job +{ +public: + AnalyseAudioJob (boost::shared_ptr f); + + std::string name () const; + void run (); + +private: + void audio (boost::shared_ptr); + + int64_t _done_for_this_point; + int64_t _done; + int64_t _samples_per_point; + std::vector _current; + + boost::shared_ptr _analysis; + + static const int _num_points; +}; + diff --git a/src/lib/audio_analysis.cc b/src/lib/audio_analysis.cc new file mode 100644 index 000000000..4a710f4c1 --- /dev/null +++ b/src/lib/audio_analysis.cc @@ -0,0 +1,69 @@ +/* + Copyright (C) 2012 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include +#include +#include "audio_analysis.h" + +using std::ostream; +using std::string; +using std::ofstream; +using std::vector; + +AudioPoint::AudioPoint () +{ + for (int i = 0; i < COUNT; ++i) { + _data[i] = 0; + } +} + +void +AudioPoint::write (ostream& s) const +{ + for (int i = 0; i < COUNT; ++i) { + s << _data[i] << "\n"; + } +} + + +AudioAnalysis::AudioAnalysis (int channels) +{ + _data.resize (channels); +} + +void +AudioAnalysis::add_point (int c, AudioPoint const & p) +{ + assert (c < int (_data.size ())); + _data[c].push_back (p); +} + +void +AudioAnalysis::write (string filename) +{ + ofstream f (filename.c_str ()); + f << _data.size() << "\n"; + for (vector >::iterator i = _data.begin(); i != _data.end(); ++i) { + f << i->size () << "\n"; + for (vector::iterator j = i->begin(); j != i->end(); ++j) { + j->write (f); + } + } +} diff --git a/src/lib/audio_analysis.h b/src/lib/audio_analysis.h new file mode 100644 index 000000000..1c668b9c2 --- /dev/null +++ b/src/lib/audio_analysis.h @@ -0,0 +1,59 @@ +/* + Copyright (C) 2012 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef DVDOMATIC_AUDIO_ANALYSIS_H +#define DVDOMATIC_AUDIO_ANALYSIS_H + +#include +#include + +class AudioPoint +{ +public: + enum Type { + PEAK, + RMS, + COUNT + }; + + AudioPoint (); + + void write (std::ostream &) const; + + float& operator[] (Type t) { + return _data[t]; + } + +private: + float _data[COUNT]; +}; + +class AudioAnalysis +{ +public: + AudioAnalysis (int c); + + void add_point (int c, AudioPoint const & p); + void write (std::string); + +private: + std::vector > _data; +}; + +#endif diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index d4ed76e37..58c7317ac 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -236,8 +236,10 @@ FFmpegDecoder::pass () int frame_finished; - while (avcodec_decode_video2 (_video_codec_context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) { - filter_and_emit_video (_frame); + if (_opt.decode_video) { + while (avcodec_decode_video2 (_video_codec_context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) { + filter_and_emit_video (_frame); + } } if (_audio_stream && _opt.decode_audio) { @@ -258,7 +260,7 @@ FFmpegDecoder::pass () shared_ptr ffa = dynamic_pointer_cast (_audio_stream); - if (_packet.stream_index == _video_stream) { + if (_packet.stream_index == _video_stream && _opt.decode_video) { int frame_finished; int const r = avcodec_decode_video2 (_video_codec_context, _frame, &frame_finished, &_packet); @@ -288,9 +290,9 @@ FFmpegDecoder::pass () was before this packet. Until then audio is thrown away. */ - if (_first_video && _first_video.get() <= source_pts_seconds) { + if ((_first_video && _first_video.get() <= source_pts_seconds) || !_opt.decode_video) { - if (!_first_audio) { + if (!_first_audio && _opt.decode_video) { _first_audio = source_pts_seconds; /* This is our first audio frame, and if we've arrived here we must have had our diff --git a/src/lib/film.cc b/src/lib/film.cc index 1cf161259..fb3fb4cde 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -51,6 +51,7 @@ #include "video_decoder.h" #include "audio_decoder.h" #include "external_audio_decoder.h" +#include "analyse_audio_job.h" using std::string; using std::stringstream; @@ -237,6 +238,15 @@ Film::video_mxf_filename () const return video_state_identifier() + ".mxf"; } +string +Film::audio_analysis_path () const +{ + boost::filesystem::path p; + p /= "analysis"; + p /= content_digest(); + return file (p.string ()); +} + /** Add suitable Jobs to the JobManager to create a DCP for this Film */ void Film::make_dcp () @@ -303,6 +313,19 @@ Film::make_dcp () } } +/** Start a job to analyse the audio of our content file */ +void +Film::analyse_audio () +{ + if (_analyse_audio_job) { + return; + } + + _analyse_audio_job.reset (new AnalyseAudioJob (shared_from_this())); + _analyse_audio_job->Finished.connect (bind (&Film::analyse_audio_finished, this)); + JobManager::instance()->add (_analyse_audio_job); +} + /** Start a job to examine our content file */ void Film::examine_content () @@ -316,6 +339,12 @@ Film::examine_content () JobManager::instance()->add (_examine_content_job); } +void +Film::analyse_audio_finished () +{ + _analyse_audio_job.reset (); +} + void Film::examine_content_finished () { diff --git a/src/lib/film.h b/src/lib/film.h index 04a483998..c268d3eac 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -45,6 +45,7 @@ class Job; class Filter; class Log; class ExamineContentJob; +class AnalyseAudioJob; class ExternalAudioStream; /** @class Film @@ -65,8 +66,10 @@ public: std::string info_path (int f) const; std::string video_mxf_dir () const; std::string video_mxf_filename () const; + std::string audio_analysis_path () const; void examine_content (); + void analyse_audio (); void send_dcp_to_tms (); void make_dcp (); @@ -374,9 +377,12 @@ private: /** Any running ExamineContentJob, or 0 */ boost::shared_ptr _examine_content_job; + /** Any running AnalyseAudioJob, or 0 */ + boost::shared_ptr _analyse_audio_job; void signal_changed (Property); void examine_content_finished (); + void analyse_audio_finished (); std::string video_state_identifier () const; /** Complete path to directory containing the film metadata; diff --git a/src/lib/options.h b/src/lib/options.h index 2cd7dffde..0d2c07fd5 100644 --- a/src/lib/options.h +++ b/src/lib/options.h @@ -28,11 +28,13 @@ class DecodeOptions { public: DecodeOptions () - : decode_audio (true) + : decode_video (true) + , decode_audio (true) , decode_subtitles (false) , video_sync (true) {} - + + bool decode_video; bool decode_audio; bool decode_subtitles; bool video_sync; diff --git a/src/lib/wscript b/src/lib/wscript index eee04190c..c2b46112c 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -16,6 +16,8 @@ def build(bld): obj.source = """ ab_transcode_job.cc ab_transcoder.cc + analyse_audio_job.cc + audio_analysis.cc audio_decoder.cc audio_source.cc config.cc diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 1b76132f6..4f380b5ad 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -145,7 +145,7 @@ enum { ID_jobs_make_dcp, ID_jobs_send_dcp_to_tms, ID_jobs_show_dcp, - ID_jobs_examine_content, + ID_jobs_analyse_audio, ID_help_about }; @@ -170,7 +170,7 @@ setup_menu (wxMenuBar* m) add_item (jobs_menu, "&Send DCP to TMS", ID_jobs_send_dcp_to_tms, NEEDS_FILM); add_item (jobs_menu, "S&how DCP", ID_jobs_show_dcp, NEEDS_FILM); jobs_menu->AppendSeparator (); - add_item (jobs_menu, "&Examine content", ID_jobs_examine_content, NEEDS_FILM); + add_item (jobs_menu, "&Analyse audio", ID_jobs_analyse_audio, NEEDS_FILM); wxMenu* help = new wxMenu; add_item (help, "About", ID_help_about, ALWAYS); @@ -207,7 +207,7 @@ public: Connect (ID_jobs_make_dcp, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::jobs_make_dcp)); Connect (ID_jobs_send_dcp_to_tms, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::jobs_send_dcp_to_tms)); Connect (ID_jobs_show_dcp, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::jobs_show_dcp)); - Connect (ID_jobs_examine_content, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::jobs_examine_content)); + Connect (ID_jobs_analyse_audio, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::jobs_analyse_audio)); Connect (ID_help_about, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::help_about)); Connect (wxID_ANY, wxEVT_MENU_OPEN, wxMenuEventHandler (Frame::menu_opened)); @@ -386,10 +386,10 @@ private: } #endif } - - void jobs_examine_content (wxCommandEvent &) + + void jobs_analyse_audio (wxCommandEvent &) { - film->examine_content (); + film->analyse_audio (); } void help_about (wxCommandEvent &) diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 68291a812..4a67624db 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -45,6 +45,7 @@ #include "sound_processor.h" #include "dci_metadata_dialog.h" #include "scaler.h" +#include "audio_dialog.h" using std::string; using std::cout; @@ -204,6 +205,7 @@ FilmEditor::connect_to_widgets () _audio_gain_calculate_button->Connect ( wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::audio_gain_calculate_button_clicked), 0, this ); + _show_audio->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::show_audio_clicked), 0, this); _audio_delay->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::audio_delay_changed), 0, this); _use_content_audio->Connect (wxID_ANY, wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler (FilmEditor::use_audio_changed), 0, this); _use_external_audio->Connect (wxID_ANY, wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler (FilmEditor::use_audio_changed), 0, this); @@ -315,6 +317,10 @@ FilmEditor::make_audio_panel () grid->Add (s); } + _show_audio = new wxButton (_audio_panel, wxID_ANY, _("Show Audio...")); + grid->AddSpacer (0); + grid->Add (_show_audio); + { video_control (add_label_to_sizer (grid, _audio_panel, _("Audio Delay"))); wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); @@ -1175,3 +1181,11 @@ FilmEditor::setup_dcp_name () _dcp_name->SetLabel (std_to_wx (s)); } } + +void +FilmEditor::show_audio_clicked (wxCommandEvent &) +{ + AudioDialog* d = new AudioDialog (this, _film); + d->ShowModal (); + d->Destroy (); +} diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index 8cb90b481..bd0300aed 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -70,6 +70,7 @@ private: void scaler_changed (wxCommandEvent &); void audio_gain_changed (wxCommandEvent &); void audio_gain_calculate_button_clicked (wxCommandEvent &); + void show_audio_clicked (wxCommandEvent &); void audio_delay_changed (wxCommandEvent &); void with_subtitles_toggled (wxCommandEvent &); void subtitle_offset_changed (wxCommandEvent &); @@ -145,6 +146,7 @@ private: wxSpinCtrl* _audio_gain; /** A button to open the gain calculation dialogue */ wxButton* _audio_gain_calculate_button; + wxButton* _show_audio; /** The Film's audio delay */ wxSpinCtrl* _audio_delay; wxCheckBox* _with_subtitles; diff --git a/src/wx/wscript b/src/wx/wscript index d844b1f1b..3fa40f55a 100644 --- a/src/wx/wscript +++ b/src/wx/wscript @@ -13,6 +13,8 @@ def build(bld): obj.uselib = 'WXWIDGETS' obj.use = 'libdvdomatic' obj.source = """ + audio_dialog.cc + audio_plot.cc config_dialog.cc dci_metadata_dialog.cc dir_picker_ctrl.cc -- cgit v1.2.3 From dcd968d6d64d645816af0efbcd2f928128c95b9f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 24 Feb 2013 22:40:57 +0000 Subject: Basic UI. --- src/lib/analyse_audio_job.cc | 7 ++++- src/lib/audio_analysis.cc | 43 ++++++++++++++++++++++++++ src/lib/audio_analysis.h | 9 +++++- src/wx/audio_dialog.cc | 27 +++++++++++++++++ src/wx/audio_dialog.h | 14 +++++++++ src/wx/audio_plot.cc | 72 ++++++++++++++++++++++++++++++++++++++++++++ src/wx/audio_plot.h | 36 ++++++++++++++++++++++ src/wx/film_editor.cc | 8 ++--- 8 files changed, 210 insertions(+), 6 deletions(-) create mode 100644 src/wx/audio_dialog.cc create mode 100644 src/wx/audio_dialog.h create mode 100644 src/wx/audio_plot.cc create mode 100644 src/wx/audio_plot.h (limited to 'src') diff --git a/src/lib/analyse_audio_job.cc b/src/lib/analyse_audio_job.cc index 5623fdfcc..190d2a5d9 100644 --- a/src/lib/analyse_audio_job.cc +++ b/src/lib/analyse_audio_job.cc @@ -85,7 +85,12 @@ AnalyseAudioJob::audio (shared_ptr b) { for (int i = 0; i < b->frames(); ++i) { for (int j = 0; j < b->channels(); ++j) { - float const s = b->data(j)[i]; + float s = b->data(j)[i]; + if (fabsf (s) < 10e-7) { + /* stringstream can't serialise and recover inf or -inf, so prevent such + values by replacing with this (140dB down) */ + s = 10e-7; + } _current[j][AudioPoint::RMS] += pow (s, 2); _current[j][AudioPoint::PEAK] = max (_current[j][AudioPoint::PEAK], fabsf (s)); diff --git a/src/lib/audio_analysis.cc b/src/lib/audio_analysis.cc index 4a710f4c1..39c1ba226 100644 --- a/src/lib/audio_analysis.cc +++ b/src/lib/audio_analysis.cc @@ -18,14 +18,18 @@ */ #include +#include #include #include #include "audio_analysis.h" using std::ostream; +using std::istream; using std::string; using std::ofstream; +using std::ifstream; using std::vector; +using std::cout; AudioPoint::AudioPoint () { @@ -34,6 +38,13 @@ AudioPoint::AudioPoint () } } +AudioPoint::AudioPoint (istream& s) +{ + for (int i = 0; i < COUNT; ++i) { + s >> _data[i]; + } +} + void AudioPoint::write (ostream& s) const { @@ -48,6 +59,23 @@ AudioAnalysis::AudioAnalysis (int channels) _data.resize (channels); } +AudioAnalysis::AudioAnalysis (string filename) +{ + ifstream f (filename.c_str ()); + + int channels; + f >> channels; + _data.resize (channels); + + for (int i = 0; i < channels; ++i) { + int points; + f >> points; + for (int j = 0; j < points; ++j) { + _data[i].push_back (AudioPoint (f)); + } + } +} + void AudioAnalysis::add_point (int c, AudioPoint const & p) { @@ -55,6 +83,21 @@ AudioAnalysis::add_point (int c, AudioPoint const & p) _data[c].push_back (p); } +AudioPoint +AudioAnalysis::get_point (int c, int p) const +{ + assert (c < int (_data.size ())); + assert (p < int (_data[c].size ())); + return _data[c][p]; +} + +int +AudioAnalysis::points (int c) const +{ + assert (c < int (_data.size ())); + return _data[c].size (); +} + void AudioAnalysis::write (string filename) { diff --git a/src/lib/audio_analysis.h b/src/lib/audio_analysis.h index 1c668b9c2..c26c0584c 100644 --- a/src/lib/audio_analysis.h +++ b/src/lib/audio_analysis.h @@ -33,10 +33,11 @@ public: }; AudioPoint (); + AudioPoint (std::istream &); void write (std::ostream &) const; - float& operator[] (Type t) { + float& operator[] (int t) { return _data[t]; } @@ -48,10 +49,16 @@ class AudioAnalysis { public: AudioAnalysis (int c); + AudioAnalysis (std::string); void add_point (int c, AudioPoint const & p); + + AudioPoint get_point (int c, int p) const; + int points (int c) const; + void write (std::string); + private: std::vector > _data; }; diff --git a/src/wx/audio_dialog.cc b/src/wx/audio_dialog.cc new file mode 100644 index 000000000..7f87ee5fd --- /dev/null +++ b/src/wx/audio_dialog.cc @@ -0,0 +1,27 @@ +#include "audio_dialog.h" +#include "audio_plot.h" +#include "audio_analysis.h" +#include "film.h" + +using boost::shared_ptr; + +AudioDialog::AudioDialog (wxWindow* parent, boost::shared_ptr film) + : wxDialog (parent, wxID_ANY, _("Audio"), wxDefaultPosition, wxSize (640, 512), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) +{ + wxBoxSizer* sizer = new wxBoxSizer (wxVERTICAL); + + shared_ptr a; + + try { + a.reset (new AudioAnalysis (film->audio_analysis_path ())); + _plot = new AudioPlot (this, a, 0); + sizer->Add (_plot, 1); + } catch (...) { + + } + + SetSizer (sizer); + sizer->Layout (); + sizer->SetSizeHints (this); +} + diff --git a/src/wx/audio_dialog.h b/src/wx/audio_dialog.h new file mode 100644 index 000000000..324a1ec99 --- /dev/null +++ b/src/wx/audio_dialog.h @@ -0,0 +1,14 @@ +#include +#include + +class AudioPlot; +class Film; + +class AudioDialog : public wxDialog +{ +public: + AudioDialog (wxWindow *, boost::shared_ptr); + +private: + AudioPlot* _plot; +}; diff --git a/src/wx/audio_plot.cc b/src/wx/audio_plot.cc new file mode 100644 index 000000000..4fda3227d --- /dev/null +++ b/src/wx/audio_plot.cc @@ -0,0 +1,72 @@ +#include +#include +#include +#include "audio_plot.h" +#include "lib/decoder_factory.h" +#include "lib/audio_decoder.h" +#include "lib/audio_analysis.h" +#include "wx/wx_util.h" + +using std::cout; +using std::vector; +using std::max; +using std::min; +using boost::bind; +using boost::shared_ptr; + +AudioPlot::AudioPlot (wxWindow* parent, shared_ptr a, int c) + : wxPanel (parent) + , _analysis (a) + , _channel (c) +{ + Connect (wxID_ANY, wxEVT_PAINT, wxPaintEventHandler (AudioPlot::paint), 0, this); + + SetMinSize (wxSize (640, 512)); +} + +void +AudioPlot::paint (wxPaintEvent &) +{ + wxPaintDC dc (this); + wxGraphicsContext* gc = wxGraphicsContext::Create (dc); + if (!gc) { + return; + } + + int const width = GetSize().GetWidth(); + float const xs = width / float (_analysis->points (_channel)); + int const height = GetSize().GetHeight (); + float const ys = height / 60; + + wxGraphicsPath grid = gc->CreatePath (); + gc->SetFont (gc->CreateFont (*wxSMALL_FONT)); + for (int i = -60; i <= 0; i += 10) { + int const y = height - (i + 60) * ys; + grid.MoveToPoint (0, y); + grid.AddLineToPoint (width, y); + gc->DrawText (std_to_wx (String::compose ("%1dB", i)), width - 32, y - 12); + } + gc->SetPen (*wxLIGHT_GREY_PEN); + gc->StrokePath (grid); + + wxGraphicsPath path[AudioPoint::COUNT]; + + for (int i = 0; i < AudioPoint::COUNT; ++i) { + path[i] = gc->CreatePath (); + path[i].MoveToPoint (0, height - (max (_analysis->get_point(_channel, 0)[i], -60.0f) + 60) * ys); + } + + for (int i = 0; i < _analysis->points(_channel); ++i) { + for (int j = 0; j < AudioPoint::COUNT; ++j) { + path[j].AddLineToPoint (i * xs, height - (max (_analysis->get_point(_channel, i)[j], -60.0f) + 60) * ys); + } + } + + gc->SetPen (*wxBLUE_PEN); + gc->StrokePath (path[AudioPoint::RMS]); + + gc->SetPen (*wxRED_PEN); + gc->StrokePath (path[AudioPoint::PEAK]); + + delete gc; +} diff --git a/src/wx/audio_plot.h b/src/wx/audio_plot.h new file mode 100644 index 000000000..565997f7e --- /dev/null +++ b/src/wx/audio_plot.h @@ -0,0 +1,36 @@ +/* + Copyright (C) 2012 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include +#include + +class AudioAnalysis; + +class AudioPlot : public wxPanel +{ +public: + AudioPlot (wxWindow *, boost::shared_ptr, int); + +private: + void paint (wxPaintEvent &); + + boost::shared_ptr _analysis; + int _channel; +}; diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 4a67624db..0a9b6d87c 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -305,6 +305,10 @@ FilmEditor::make_audio_panel () wxFlexGridSizer* grid = new wxFlexGridSizer (2, 4, 4); _audio_sizer->Add (grid, 0, wxALL, 8); + _show_audio = new wxButton (_audio_panel, wxID_ANY, _("Show Audio...")); + grid->Add (_show_audio, 1); + grid->AddSpacer (0); + { video_control (add_label_to_sizer (grid, _audio_panel, _("Audio Gain"))); wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); @@ -317,10 +321,6 @@ FilmEditor::make_audio_panel () grid->Add (s); } - _show_audio = new wxButton (_audio_panel, wxID_ANY, _("Show Audio...")); - grid->AddSpacer (0); - grid->Add (_show_audio); - { video_control (add_label_to_sizer (grid, _audio_panel, _("Audio Delay"))); wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); -- cgit v1.2.3 From 040a227d300033f8a103dc6eb67847286131d9b7 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 25 Feb 2013 00:11:49 +0000 Subject: Some tidying up, add channel selector to Audio dialog. --- src/lib/analyse_audio_job.cc | 14 ++++----- src/lib/analyse_audio_job.h | 1 - src/lib/ffmpeg_decoder.cc | 2 +- src/lib/util.cc | 20 +++++++++++++ src/lib/util.h | 1 + src/wx/audio_dialog.cc | 68 ++++++++++++++++++++++++++++++++++++++------ src/wx/audio_dialog.h | 24 ++++++++++++++++ src/wx/audio_plot.cc | 44 ++++++++++++++++++++++++++-- src/wx/audio_plot.h | 5 +++- src/wx/film_editor.cc | 32 +++++++++------------ src/wx/film_editor.h | 3 +- 11 files changed, 172 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/lib/analyse_audio_job.cc b/src/lib/analyse_audio_job.cc index 190d2a5d9..fb5f2868f 100644 --- a/src/lib/analyse_audio_job.cc +++ b/src/lib/analyse_audio_job.cc @@ -27,13 +27,13 @@ using std::string; using std::max; +using std::cout; using boost::shared_ptr; -int const AnalyseAudioJob::_num_points = 1024; +int const AnalyseAudioJob::_num_points = 128; AnalyseAudioJob::AnalyseAudioJob (shared_ptr f) : Job (f) - , _done_for_this_point (0) , _done (0) , _samples_per_point (1) { @@ -94,20 +94,16 @@ AnalyseAudioJob::audio (shared_ptr b) _current[j][AudioPoint::RMS] += pow (s, 2); _current[j][AudioPoint::PEAK] = max (_current[j][AudioPoint::PEAK], fabsf (s)); - if (_done_for_this_point == _samples_per_point) { + if ((_done % _samples_per_point) == 0) { _current[j][AudioPoint::RMS] = 20 * log10 (sqrt (_current[j][AudioPoint::RMS] / _samples_per_point)); _current[j][AudioPoint::PEAK] = 20 * log10 (_current[j][AudioPoint::PEAK]); - _analysis->add_point (j, _current[j]); - _done_for_this_point = 0; _current[j] = AudioPoint (); } } - - ++_done_for_this_point; - } - _done += b->frames (); + ++_done; + } } diff --git a/src/lib/analyse_audio_job.h b/src/lib/analyse_audio_job.h index 1e7229ce6..dc1e073ee 100644 --- a/src/lib/analyse_audio_job.h +++ b/src/lib/analyse_audio_job.h @@ -33,7 +33,6 @@ public: private: void audio (boost::shared_ptr); - int64_t _done_for_this_point; int64_t _done; int64_t _samples_per_point; std::vector _current; diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 58c7317ac..148764162 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -197,7 +197,7 @@ FFmpegDecoder::setup_audio () void FFmpegDecoder::setup_subtitle () { - if (!_subtitle_stream) { + if (!_subtitle_stream || _subtitle_stream->id() >= _format_context->nb_streams) { return; } diff --git a/src/lib/util.cc b/src/lib/util.cc index 4ee304600..f807bf329 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -898,3 +898,23 @@ cpu_info () return info; } + +string +audio_channel_name (int c) +{ + assert (MAX_AUDIO_CHANNELS == 6); + + /* TRANSLATORS: these are the names of audio channels; Lfe (sub) is the low-frequency + enhancement channel (sub-woofer)./ + */ + string const channels[] = { + "Left", + "Right", + "Centre", + "Lfe (sub)", + "Left surround", + "Right surround", + }; + + return channels[c]; +} diff --git a/src/lib/util.h b/src/lib/util.h index 87735ea8e..b76aead41 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -57,6 +57,7 @@ extern std::vector split_at_spaces_considering_quotes (std::string) extern std::string md5_digest (std::string); extern std::string md5_digest (void const *, int); extern void ensure_ui_thread (); +extern std::string audio_channel_name (int); typedef int SourceFrame; diff --git a/src/wx/audio_dialog.cc b/src/wx/audio_dialog.cc index 7f87ee5fd..11efc153c 100644 --- a/src/wx/audio_dialog.cc +++ b/src/wx/audio_dialog.cc @@ -1,27 +1,79 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + #include "audio_dialog.h" #include "audio_plot.h" #include "audio_analysis.h" #include "film.h" +#include "wx_util.h" using boost::shared_ptr; AudioDialog::AudioDialog (wxWindow* parent, boost::shared_ptr film) : wxDialog (parent, wxID_ANY, _("Audio"), wxDefaultPosition, wxSize (640, 512), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) + , _plot (0) { - wxBoxSizer* sizer = new wxBoxSizer (wxVERTICAL); + wxBoxSizer* sizer = new wxBoxSizer (wxHORIZONTAL); + + _plot = new AudioPlot (this); + sizer->Add (_plot, 1); + + wxFlexGridSizer* table = new wxFlexGridSizer (2, 6, 6); + + add_label_to_sizer (table, this, _("Channel")); + _channel = new wxChoice (this, wxID_ANY); + table->Add (_channel, 1, wxEXPAND | wxALL, 6); + + sizer->Add (table); + + set_film (film); + + SetSizer (sizer); + sizer->Layout (); + sizer->SetSizeHints (this); + + _channel->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (AudioDialog::channel_changed), 0, this); +} +void +AudioDialog::set_film (boost::shared_ptr f) +{ shared_ptr a; - + try { - a.reset (new AudioAnalysis (film->audio_analysis_path ())); - _plot = new AudioPlot (this, a, 0); - sizer->Add (_plot, 1); + a.reset (new AudioAnalysis (f->audio_analysis_path ())); } catch (...) { + + } + _plot->set_analysis (a); + + _channel->Clear (); + for (int i = 0; i < f->audio_stream()->channels(); ++i) { + _channel->Append (audio_channel_name (i)); } - SetSizer (sizer); - sizer->Layout (); - sizer->SetSizeHints (this); + _channel->SetSelection (0); } +void +AudioDialog::channel_changed (wxCommandEvent &) +{ + _plot->set_channel (_channel->GetSelection ()); +} diff --git a/src/wx/audio_dialog.h b/src/wx/audio_dialog.h index 324a1ec99..1e4563972 100644 --- a/src/wx/audio_dialog.h +++ b/src/wx/audio_dialog.h @@ -1,3 +1,22 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + #include #include @@ -9,6 +28,11 @@ class AudioDialog : public wxDialog public: AudioDialog (wxWindow *, boost::shared_ptr); + void set_film (boost::shared_ptr); + private: + void channel_changed (wxCommandEvent &); + AudioPlot* _plot; + wxChoice* _channel; }; diff --git a/src/wx/audio_plot.cc b/src/wx/audio_plot.cc index 4fda3227d..cc2d8f6b4 100644 --- a/src/wx/audio_plot.cc +++ b/src/wx/audio_plot.cc @@ -1,3 +1,22 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + #include #include #include @@ -14,20 +33,39 @@ using std::min; using boost::bind; using boost::shared_ptr; -AudioPlot::AudioPlot (wxWindow* parent, shared_ptr a, int c) +AudioPlot::AudioPlot (wxWindow* parent) : wxPanel (parent) - , _analysis (a) - , _channel (c) + , _channel (0) { Connect (wxID_ANY, wxEVT_PAINT, wxPaintEventHandler (AudioPlot::paint), 0, this); SetMinSize (wxSize (640, 512)); } +void +AudioPlot::set_analysis (shared_ptr a) +{ + _analysis = a; + _channel = 0; + Refresh (); +} + +void +AudioPlot::set_channel (int c) +{ + _channel = c; + Refresh (); +} + void AudioPlot::paint (wxPaintEvent &) { wxPaintDC dc (this); + + if (!_analysis) { + return; + } + wxGraphicsContext* gc = wxGraphicsContext::Create (dc); if (!gc) { return; diff --git a/src/wx/audio_plot.h b/src/wx/audio_plot.h index 565997f7e..03bd79323 100644 --- a/src/wx/audio_plot.h +++ b/src/wx/audio_plot.h @@ -26,7 +26,10 @@ class AudioAnalysis; class AudioPlot : public wxPanel { public: - AudioPlot (wxWindow *, boost::shared_ptr, int); + AudioPlot (wxWindow *); + + void set_analysis (boost::shared_ptr); + void set_channel (int c); private: void paint (wxPaintEvent &); diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 0a9b6d87c..725f2d1b3 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -63,6 +63,7 @@ FilmEditor::FilmEditor (shared_ptr f, wxWindow* parent) : wxPanel (parent) , _film (f) , _generally_sensitive (true) + , _audio_dialog (0) { wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); SetSizer (s); @@ -346,22 +347,8 @@ FilmEditor::make_audio_panel () grid->Add (_use_external_audio); grid->AddSpacer (0); - assert (MAX_AUDIO_CHANNELS == 6); - - /* TRANSLATORS: these are the names of audio channels; Lfe (sub) is the low-frequency - enhancement channel (sub-woofer)./ - */ - wxString const channels[] = { - _("Left"), - _("Right"), - _("Centre"), - _("Lfe (sub)"), - _("Left surround"), - _("Right surround"), - }; - for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) { - add_label_to_sizer (grid, _audio_panel, channels[i]); + add_label_to_sizer (grid, _audio_panel, audio_channel_name (i)); _external_audio[i] = new wxFilePickerCtrl (_audio_panel, wxID_ANY, wxT (""), _("Select Audio File"), wxT ("*.wav")); grid->Add (_external_audio[i], 1, wxEXPAND); } @@ -762,6 +749,10 @@ FilmEditor::set_film (shared_ptr f) } else { FileChanged (""); } + + if (_audio_dialog) { + _audio_dialog->set_film (_film); + } film_changed (Film::NAME); film_changed (Film::USE_DCI_NAME); @@ -823,6 +814,7 @@ FilmEditor::set_things_sensitive (bool s) _j2k_bandwidth->Enable (s); _audio_gain->Enable (s); _audio_gain_calculate_button->Enable (s); + _show_audio->Enable (s); _audio_delay->Enable (s); _still_duration->Enable (s); @@ -1185,7 +1177,11 @@ FilmEditor::setup_dcp_name () void FilmEditor::show_audio_clicked (wxCommandEvent &) { - AudioDialog* d = new AudioDialog (this, _film); - d->ShowModal (); - d->Destroy (); + if (_audio_dialog) { + _audio_dialog->Destroy (); + _audio_dialog = 0; + } + + _audio_dialog = new AudioDialog (this, _film); + _audio_dialog->Show (); } diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index bd0300aed..2af747bb0 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -29,8 +29,8 @@ #include "lib/film.h" class wxNotebook; - class Film; +class AudioDialog; /** @class FilmEditor * @brief A wx widget to edit a film's metadata, and perform various functions. @@ -179,4 +179,5 @@ private: std::vector _formats; bool _generally_sensitive; + AudioDialog* _audio_dialog; }; -- cgit v1.2.3 From 32ae1f11a9d3e1530c3939190690b5a524997ccb Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 25 Feb 2013 00:19:06 +0000 Subject: Set up streams after changing content, otherwise we are anticipating things that have not happened yet. --- src/lib/film.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/lib/film.cc b/src/lib/film.cc index fb3fb4cde..f36614689 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -899,6 +899,13 @@ Film::set_content (string c) set_content_audio_streams (d.audio->audio_streams ()); } + { + boost::mutex::scoped_lock lm (_state_mutex); + _content = c; + } + + signal_changed (CONTENT); + /* Start off with the first audio and subtitle streams */ if (d.audio && !d.audio->audio_streams().empty()) { set_content_audio_stream (d.audio->audio_streams().front()); @@ -908,13 +915,6 @@ Film::set_content (string c) set_subtitle_stream (d.video->subtitle_streams().front()); } - { - boost::mutex::scoped_lock lm (_state_mutex); - _content = c; - } - - signal_changed (CONTENT); - examine_content (); } catch (...) { -- cgit v1.2.3 From 5702637ee38f0349fd0b7f17f10bda581e795a9d Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 25 Feb 2013 00:28:03 +0000 Subject: Respond to gain in the audio dialog. --- src/wx/audio_dialog.cc | 13 +++++++++++++ src/wx/audio_dialog.h | 7 ++++++- src/wx/audio_plot.cc | 12 ++++++++++-- src/wx/audio_plot.h | 3 +++ 4 files changed, 32 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/wx/audio_dialog.cc b/src/wx/audio_dialog.cc index 11efc153c..32864ca15 100644 --- a/src/wx/audio_dialog.cc +++ b/src/wx/audio_dialog.cc @@ -54,6 +54,9 @@ AudioDialog::AudioDialog (wxWindow* parent, boost::shared_ptr film) void AudioDialog::set_film (boost::shared_ptr f) { + _film_connection.disconnect (); + _film = f; + shared_ptr a; try { @@ -70,6 +73,8 @@ AudioDialog::set_film (boost::shared_ptr f) } _channel->SetSelection (0); + + _film_connection = f->Changed.connect (bind (&AudioDialog::film_changed, this, _1)); } void @@ -77,3 +82,11 @@ AudioDialog::channel_changed (wxCommandEvent &) { _plot->set_channel (_channel->GetSelection ()); } + +void +AudioDialog::film_changed (Film::Property p) +{ + if (p == Film::AUDIO_GAIN) { + _plot->set_gain (_film->audio_gain ()); + } +} diff --git a/src/wx/audio_dialog.h b/src/wx/audio_dialog.h index 1e4563972..968fd0a12 100644 --- a/src/wx/audio_dialog.h +++ b/src/wx/audio_dialog.h @@ -18,7 +18,9 @@ */ #include +#include #include +#include "lib/film.h" class AudioPlot; class Film; @@ -31,8 +33,11 @@ public: void set_film (boost::shared_ptr); private: + void film_changed (Film::Property); void channel_changed (wxCommandEvent &); - + + boost::shared_ptr _film; AudioPlot* _plot; wxChoice* _channel; + boost::signals2::scoped_connection _film_connection; }; diff --git a/src/wx/audio_plot.cc b/src/wx/audio_plot.cc index cc2d8f6b4..d438426c7 100644 --- a/src/wx/audio_plot.cc +++ b/src/wx/audio_plot.cc @@ -36,6 +36,7 @@ using boost::shared_ptr; AudioPlot::AudioPlot (wxWindow* parent) : wxPanel (parent) , _channel (0) + , _gain (0) { Connect (wxID_ANY, wxEVT_PAINT, wxPaintEventHandler (AudioPlot::paint), 0, this); @@ -91,12 +92,12 @@ AudioPlot::paint (wxPaintEvent &) for (int i = 0; i < AudioPoint::COUNT; ++i) { path[i] = gc->CreatePath (); - path[i].MoveToPoint (0, height - (max (_analysis->get_point(_channel, 0)[i], -60.0f) + 60) * ys); + path[i].MoveToPoint (0, height - (max (_analysis->get_point(_channel, 0)[i], -60.0f) + 60 + _gain) * ys); } for (int i = 0; i < _analysis->points(_channel); ++i) { for (int j = 0; j < AudioPoint::COUNT; ++j) { - path[j].AddLineToPoint (i * xs, height - (max (_analysis->get_point(_channel, i)[j], -60.0f) + 60) * ys); + path[j].AddLineToPoint (i * xs, height - (max (_analysis->get_point(_channel, i)[j], -60.0f) + 60 + _gain) * ys); } } @@ -108,3 +109,10 @@ AudioPlot::paint (wxPaintEvent &) delete gc; } + +void +AudioPlot::set_gain (float g) +{ + _gain = g; + Refresh (); +} diff --git a/src/wx/audio_plot.h b/src/wx/audio_plot.h index 03bd79323..dfc1b18ae 100644 --- a/src/wx/audio_plot.h +++ b/src/wx/audio_plot.h @@ -30,10 +30,13 @@ public: void set_analysis (boost::shared_ptr); void set_channel (int c); + void set_gain (float); private: void paint (wxPaintEvent &); boost::shared_ptr _analysis; int _channel; + /** gain to apply in dB */ + float _gain; }; -- cgit v1.2.3 From 1ae970dfd86a8c314660379fcbc9c7995778e5b5 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 25 Feb 2013 00:50:45 +0000 Subject: Make minimum gain a constant. --- src/wx/audio_plot.cc | 12 +++++++----- src/wx/audio_plot.h | 2 ++ 2 files changed, 9 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/wx/audio_plot.cc b/src/wx/audio_plot.cc index d438426c7..1ad07fcce 100644 --- a/src/wx/audio_plot.cc +++ b/src/wx/audio_plot.cc @@ -33,6 +33,8 @@ using std::min; using boost::bind; using boost::shared_ptr; +int const AudioPlot::_minimum = -90; + AudioPlot::AudioPlot (wxWindow* parent) : wxPanel (parent) , _channel (0) @@ -75,12 +77,12 @@ AudioPlot::paint (wxPaintEvent &) int const width = GetSize().GetWidth(); float const xs = width / float (_analysis->points (_channel)); int const height = GetSize().GetHeight (); - float const ys = height / 60; + float const ys = height / -_minimum; wxGraphicsPath grid = gc->CreatePath (); gc->SetFont (gc->CreateFont (*wxSMALL_FONT)); - for (int i = -60; i <= 0; i += 10) { - int const y = height - (i + 60) * ys; + for (int i = _minimum; i <= 0; i += 10) { + int const y = height - (i - _minimum) * ys; grid.MoveToPoint (0, y); grid.AddLineToPoint (width, y); gc->DrawText (std_to_wx (String::compose ("%1dB", i)), width - 32, y - 12); @@ -92,12 +94,12 @@ AudioPlot::paint (wxPaintEvent &) for (int i = 0; i < AudioPoint::COUNT; ++i) { path[i] = gc->CreatePath (); - path[i].MoveToPoint (0, height - (max (_analysis->get_point(_channel, 0)[i], -60.0f) + 60 + _gain) * ys); + path[i].MoveToPoint (0, height - (max (_analysis->get_point(_channel, 0)[i], float (_minimum)) - _minimum + _gain) * ys); } for (int i = 0; i < _analysis->points(_channel); ++i) { for (int j = 0; j < AudioPoint::COUNT; ++j) { - path[j].AddLineToPoint (i * xs, height - (max (_analysis->get_point(_channel, i)[j], -60.0f) + 60 + _gain) * ys); + path[j].AddLineToPoint (i * xs, height - (max (_analysis->get_point(_channel, i)[j], float (_minimum)) - _minimum + _gain) * ys); } } diff --git a/src/wx/audio_plot.h b/src/wx/audio_plot.h index dfc1b18ae..b2ae139d1 100644 --- a/src/wx/audio_plot.h +++ b/src/wx/audio_plot.h @@ -39,4 +39,6 @@ private: int _channel; /** gain to apply in dB */ float _gain; + + static const int _minimum; }; -- cgit v1.2.3 From d371988d26f8c9c4240dc3794df044cbe95d5d0d Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 25 Feb 2013 18:56:25 +0000 Subject: Fix warning. --- src/lib/ffmpeg_decoder.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 148764162..fa2355cc2 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -197,7 +197,7 @@ FFmpegDecoder::setup_audio () void FFmpegDecoder::setup_subtitle () { - if (!_subtitle_stream || _subtitle_stream->id() >= _format_context->nb_streams) { + if (!_subtitle_stream || _subtitle_stream->id() >= int (_format_context->nb_streams)) { return; } -- cgit v1.2.3 From 8bfb6ae0780b0bf3318c345df78518ad3fabc9fc Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 25 Feb 2013 19:27:58 +0000 Subject: Tidy up creation of analysis a bit. --- src/lib/audio_analysis.cc | 8 +++++- src/lib/film.cc | 3 +++ src/lib/film.h | 2 ++ src/lib/job.cc | 1 - src/lib/job.h | 1 + src/wx/audio_dialog.cc | 62 ++++++++++++++++++++++++++++++++++------------ src/wx/audio_dialog.h | 7 ++++-- src/wx/audio_plot.cc | 10 +++++--- src/wx/film_editor.cc | 3 ++- src/wx/job_manager_view.cc | 1 + 10 files changed, 73 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/lib/audio_analysis.cc b/src/lib/audio_analysis.cc index 39c1ba226..fffafc4d4 100644 --- a/src/lib/audio_analysis.cc +++ b/src/lib/audio_analysis.cc @@ -21,6 +21,7 @@ #include #include #include +#include #include "audio_analysis.h" using std::ostream; @@ -101,7 +102,9 @@ AudioAnalysis::points (int c) const void AudioAnalysis::write (string filename) { - ofstream f (filename.c_str ()); + string tmp = filename + ".tmp"; + + ofstream f (tmp.c_str ()); f << _data.size() << "\n"; for (vector >::iterator i = _data.begin(); i != _data.end(); ++i) { f << i->size () << "\n"; @@ -109,4 +112,7 @@ AudioAnalysis::write (string filename) j->write (f); } } + + f.close (); + boost::filesystem::rename (tmp, filename); } diff --git a/src/lib/film.cc b/src/lib/film.cc index f36614689..ab636bdfc 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -342,7 +342,10 @@ Film::examine_content () void Film::analyse_audio_finished () { + ensure_ui_thread (); _analyse_audio_job.reset (); + + AudioAnalysisFinished (); } void diff --git a/src/lib/film.h b/src/lib/film.h index c268d3eac..847ab434e 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -367,6 +367,8 @@ public: /** Emitted when some property has changed */ mutable boost::signals2::signal Changed; + boost::signals2::signal AudioAnalysisFinished; + /** Current version number of the state file */ static int const state_version; diff --git a/src/lib/job.cc b/src/lib/job.cc index bfad65a0a..6a53e629c 100644 --- a/src/lib/job.cc +++ b/src/lib/job.cc @@ -147,7 +147,6 @@ Job::set_state (State s) if (_state == FINISHED_OK || _state == FINISHED_ERROR) { _ran_for = elapsed_time (); - Finished (); } } diff --git a/src/lib/job.h b/src/lib/job.h index 1538e2779..c98dbaea1 100644 --- a/src/lib/job.h +++ b/src/lib/job.h @@ -65,6 +65,7 @@ public: void descend (float); float overall_progress () const; + /** Emitted by the JobManagerView from the UI thread */ boost::signals2::signal Finished; protected: diff --git a/src/wx/audio_dialog.cc b/src/wx/audio_dialog.cc index 32864ca15..89b04409a 100644 --- a/src/wx/audio_dialog.cc +++ b/src/wx/audio_dialog.cc @@ -17,6 +17,7 @@ */ +#include #include "audio_dialog.h" #include "audio_plot.h" #include "audio_analysis.h" @@ -24,8 +25,9 @@ #include "wx_util.h" using boost::shared_ptr; +using boost::bind; -AudioDialog::AudioDialog (wxWindow* parent, boost::shared_ptr film) +AudioDialog::AudioDialog (wxWindow* parent) : wxDialog (parent, wxID_ANY, _("Audio"), wxDefaultPosition, wxSize (640, 512), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) , _plot (0) { @@ -42,8 +44,6 @@ AudioDialog::AudioDialog (wxWindow* parent, boost::shared_ptr film) sizer->Add (table); - set_film (film); - SetSizer (sizer); sizer->Layout (); sizer->SetSizeHints (this); @@ -54,27 +54,48 @@ AudioDialog::AudioDialog (wxWindow* parent, boost::shared_ptr film) void AudioDialog::set_film (boost::shared_ptr f) { - _film_connection.disconnect (); - _film = f; + _film_changed_connection.disconnect (); + _film_audio_analysis_finished_connection.disconnect (); - shared_ptr a; + _film = f; - try { - a.reset (new AudioAnalysis (f->audio_analysis_path ())); - } catch (...) { + try_to_load_analysis (); + setup_channels (); - } - - _plot->set_analysis (a); + _channel->SetSelection (0); + _film_changed_connection = _film->Changed.connect (bind (&AudioDialog::film_changed, this, _1)); + _film_audio_analysis_finished_connection = _film->AudioAnalysisFinished.connect (bind (&AudioDialog::try_to_load_analysis, this)); +} + +void +AudioDialog::setup_channels () +{ _channel->Clear (); - for (int i = 0; i < f->audio_stream()->channels(); ++i) { + + if (!_film->audio_stream()) { + return; + } + + for (int i = 0; i < _film->audio_stream()->channels(); ++i) { _channel->Append (audio_channel_name (i)); } +} - _channel->SetSelection (0); +void +AudioDialog::try_to_load_analysis () +{ + shared_ptr a; - _film_connection = f->Changed.connect (bind (&AudioDialog::film_changed, this, _1)); + if (boost::filesystem::exists (_film->audio_analysis_path())) { + a.reset (new AudioAnalysis (_film->audio_analysis_path ())); + } else { + if (IsShown ()) { + _film->analyse_audio (); + } + } + + _plot->set_analysis (a); } void @@ -86,7 +107,16 @@ AudioDialog::channel_changed (wxCommandEvent &) void AudioDialog::film_changed (Film::Property p) { - if (p == Film::AUDIO_GAIN) { + switch (p) { + case Film::AUDIO_GAIN: _plot->set_gain (_film->audio_gain ()); + break; + case Film::CONTENT_AUDIO_STREAM: + case Film::EXTERNAL_AUDIO: + case Film::USE_CONTENT_AUDIO: + setup_channels (); + break; + default: + break; } } diff --git a/src/wx/audio_dialog.h b/src/wx/audio_dialog.h index 968fd0a12..623c9a067 100644 --- a/src/wx/audio_dialog.h +++ b/src/wx/audio_dialog.h @@ -28,16 +28,19 @@ class Film; class AudioDialog : public wxDialog { public: - AudioDialog (wxWindow *, boost::shared_ptr); + AudioDialog (wxWindow *); void set_film (boost::shared_ptr); private: void film_changed (Film::Property); void channel_changed (wxCommandEvent &); + void try_to_load_analysis (); + void setup_channels (); boost::shared_ptr _film; AudioPlot* _plot; wxChoice* _channel; - boost::signals2::scoped_connection _film_connection; + boost::signals2::scoped_connection _film_changed_connection; + boost::signals2::scoped_connection _film_audio_analysis_finished_connection; }; diff --git a/src/wx/audio_plot.cc b/src/wx/audio_plot.cc index 1ad07fcce..41d074dad 100644 --- a/src/wx/audio_plot.cc +++ b/src/wx/audio_plot.cc @@ -65,15 +65,17 @@ AudioPlot::paint (wxPaintEvent &) { wxPaintDC dc (this); - if (!_analysis) { - return; - } - wxGraphicsContext* gc = wxGraphicsContext::Create (dc); if (!gc) { return; } + if (!_analysis) { + gc->SetFont (gc->CreateFont (*wxNORMAL_FONT)); + gc->DrawText (_("Please wait; audio is being analysed..."), 32, 32); + return; + } + int const width = GetSize().GetWidth(); float const xs = width / float (_analysis->points (_channel)); int const height = GetSize().GetHeight (); diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 725f2d1b3..c9f83677c 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -1182,6 +1182,7 @@ FilmEditor::show_audio_clicked (wxCommandEvent &) _audio_dialog = 0; } - _audio_dialog = new AudioDialog (this, _film); + _audio_dialog = new AudioDialog (this); _audio_dialog->Show (); + _audio_dialog->set_film (_film); } diff --git a/src/wx/job_manager_view.cc b/src/wx/job_manager_view.cc index 7537da287..7361f29a8 100644 --- a/src/wx/job_manager_view.cc +++ b/src/wx/job_manager_view.cc @@ -109,6 +109,7 @@ JobManagerView::update () if ((*i)->finished() && !_job_records[*i].finalised) { _job_records[*i].gauge->SetValue (100); checked_set (_job_records[*i].message, st); + (*i)->Finished (); _job_records[*i].finalised = true; if (!(*i)->error_details().empty ()) { _job_records[*i].details->Enable (true); -- cgit v1.2.3 From 6e0f2a39c9deeb51f05c0c8c9bd46632c2c6483a Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 25 Feb 2013 20:21:29 +0000 Subject: Multiple simultaneous plots. --- src/lib/audio_analysis.cc | 13 ++++--- src/lib/audio_analysis.h | 1 + src/wx/audio_dialog.cc | 68 +++++++++++++++++++++++++++++------- src/wx/audio_dialog.h | 7 ++-- src/wx/audio_plot.cc | 88 +++++++++++++++++++++++++++++++++++++---------- src/wx/audio_plot.h | 12 ++++--- 6 files changed, 148 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/lib/audio_analysis.cc b/src/lib/audio_analysis.cc index fffafc4d4..b29ed1707 100644 --- a/src/lib/audio_analysis.cc +++ b/src/lib/audio_analysis.cc @@ -80,22 +80,27 @@ AudioAnalysis::AudioAnalysis (string filename) void AudioAnalysis::add_point (int c, AudioPoint const & p) { - assert (c < int (_data.size ())); + assert (c < channels ()); _data[c].push_back (p); } AudioPoint AudioAnalysis::get_point (int c, int p) const { - assert (c < int (_data.size ())); - assert (p < int (_data[c].size ())); + assert (p < points (c)); return _data[c][p]; } +int +AudioAnalysis::channels () const +{ + return _data.size (); +} + int AudioAnalysis::points (int c) const { - assert (c < int (_data.size ())); + assert (c < channels ()); return _data[c].size (); } diff --git a/src/lib/audio_analysis.h b/src/lib/audio_analysis.h index c26c0584c..c2d8db876 100644 --- a/src/lib/audio_analysis.h +++ b/src/lib/audio_analysis.h @@ -55,6 +55,7 @@ public: AudioPoint get_point (int c, int p) const; int points (int c) const; + int channels () const; void write (std::string); diff --git a/src/wx/audio_dialog.cc b/src/wx/audio_dialog.cc index 89b04409a..dc297e246 100644 --- a/src/wx/audio_dialog.cc +++ b/src/wx/audio_dialog.cc @@ -38,17 +38,33 @@ AudioDialog::AudioDialog (wxWindow* parent) wxFlexGridSizer* table = new wxFlexGridSizer (2, 6, 6); - add_label_to_sizer (table, this, _("Channel")); - _channel = new wxChoice (this, wxID_ANY); - table->Add (_channel, 1, wxEXPAND | wxALL, 6); + for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) { + _channel_checkbox[i] = new wxCheckBox (this, wxID_ANY, audio_channel_name (i)); + table->Add (_channel_checkbox[i], 1, wxEXPAND); + table->AddSpacer (0); + _channel_checkbox[i]->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (AudioDialog::channel_clicked), 0, this); + } + + table->AddSpacer (0); + table->AddSpacer (0); + + wxString const types[] = { + _("Peak"), + _("RMS") + }; + + for (int i = 0; i < AudioPoint::COUNT; ++i) { + _type_checkbox[i] = new wxCheckBox (this, wxID_ANY, types[i]); + table->Add (_type_checkbox[i], 1, wxEXPAND); + table->AddSpacer (0); + _type_checkbox[i]->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (AudioDialog::type_clicked), 0, this); + } sizer->Add (table); SetSizer (sizer); sizer->Layout (); sizer->SetSizeHints (this); - - _channel->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (AudioDialog::channel_changed), 0, this); } void @@ -61,8 +77,7 @@ AudioDialog::set_film (boost::shared_ptr f) try_to_load_analysis (); setup_channels (); - - _channel->SetSelection (0); + _plot->set_gain (_film->audio_gain ()); _film_changed_connection = _film->Changed.connect (bind (&AudioDialog::film_changed, this, _1)); _film_audio_analysis_finished_connection = _film->AudioAnalysisFinished.connect (bind (&AudioDialog::try_to_load_analysis, this)); @@ -71,14 +86,16 @@ AudioDialog::set_film (boost::shared_ptr f) void AudioDialog::setup_channels () { - _channel->Clear (); - if (!_film->audio_stream()) { return; } for (int i = 0; i < _film->audio_stream()->channels(); ++i) { - _channel->Append (audio_channel_name (i)); + _channel_checkbox[i]->Show (); + } + + for (int i = _film->audio_stream()->channels(); i < MAX_AUDIO_CHANNELS; ++i) { + _channel_checkbox[i]->Hide (); } } @@ -96,12 +113,26 @@ AudioDialog::try_to_load_analysis () } _plot->set_analysis (a); + _channel_checkbox[0]->SetValue (true); + _plot->set_channel_visible (0, true); + + for (int i = 0; i < AudioPoint::COUNT; ++i) { + _type_checkbox[i]->SetValue (true); + _plot->set_type_visible (i, true); + } } void -AudioDialog::channel_changed (wxCommandEvent &) +AudioDialog::channel_clicked (wxCommandEvent& ev) { - _plot->set_channel (_channel->GetSelection ()); + int c = 0; + while (c < MAX_AUDIO_CHANNELS && ev.GetEventObject() != _channel_checkbox[c]) { + ++c; + } + + assert (c < MAX_AUDIO_CHANNELS); + + _plot->set_channel_visible (c, _channel_checkbox[c]->GetValue ()); } void @@ -120,3 +151,16 @@ AudioDialog::film_changed (Film::Property p) break; } } + +void +AudioDialog::type_clicked (wxCommandEvent& ev) +{ + int t = 0; + while (t < AudioPoint::COUNT && ev.GetEventObject() != _type_checkbox[t]) { + ++t; + } + + assert (t < AudioPoint::COUNT); + + _plot->set_type_visible (t, _type_checkbox[t]->GetValue ()); +} diff --git a/src/wx/audio_dialog.h b/src/wx/audio_dialog.h index 623c9a067..c3875023f 100644 --- a/src/wx/audio_dialog.h +++ b/src/wx/audio_dialog.h @@ -21,6 +21,7 @@ #include #include #include "lib/film.h" +#include "lib/audio_analysis.h" class AudioPlot; class Film; @@ -34,13 +35,15 @@ public: private: void film_changed (Film::Property); - void channel_changed (wxCommandEvent &); + void channel_clicked (wxCommandEvent &); + void type_clicked (wxCommandEvent &); void try_to_load_analysis (); void setup_channels (); boost::shared_ptr _film; AudioPlot* _plot; - wxChoice* _channel; + wxCheckBox* _channel_checkbox[MAX_AUDIO_CHANNELS]; + wxCheckBox* _type_checkbox[AudioPoint::COUNT]; boost::signals2::scoped_connection _film_changed_connection; boost::signals2::scoped_connection _film_audio_analysis_finished_connection; }; diff --git a/src/wx/audio_plot.cc b/src/wx/audio_plot.cc index 41d074dad..cccdaed34 100644 --- a/src/wx/audio_plot.cc +++ b/src/wx/audio_plot.cc @@ -37,11 +37,25 @@ int const AudioPlot::_minimum = -90; AudioPlot::AudioPlot (wxWindow* parent) : wxPanel (parent) - , _channel (0) , _gain (0) { - Connect (wxID_ANY, wxEVT_PAINT, wxPaintEventHandler (AudioPlot::paint), 0, this); + for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) { + _channel_visible[i] = false; + } + for (int i = 0; i < AudioPoint::COUNT; ++i) { + _type_visible[i] = false; + } + + _colours.push_back (wxColour ( 0, 0, 0)); + _colours.push_back (wxColour (255, 0, 0)); + _colours.push_back (wxColour ( 0, 255, 0)); + _colours.push_back (wxColour (139, 0, 204)); + _colours.push_back (wxColour ( 0, 0, 255)); + _colours.push_back (wxColour (100, 100, 100)); + + Connect (wxID_ANY, wxEVT_PAINT, wxPaintEventHandler (AudioPlot::paint), 0, this); + SetMinSize (wxSize (640, 512)); } @@ -49,14 +63,29 @@ void AudioPlot::set_analysis (shared_ptr a) { _analysis = a; - _channel = 0; + + for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) { + _channel_visible[i] = false; + } + + for (int i = 0; i < AudioPoint::COUNT; ++i) { + _type_visible[i] = false; + } + Refresh (); } void -AudioPlot::set_channel (int c) +AudioPlot::set_channel_visible (int c, bool v) { - _channel = c; + _channel_visible[c] = v; + Refresh (); +} + +void +AudioPlot::set_type_visible (int t, bool v) +{ + _type_visible[t] = v; Refresh (); } @@ -77,7 +106,8 @@ AudioPlot::paint (wxPaintEvent &) } int const width = GetSize().GetWidth(); - float const xs = width / float (_analysis->points (_channel)); + /* Assume all channels have the same number of points */ + float const xs = width / float (_analysis->points (0)); int const height = GetSize().GetHeight (); float const ys = height / -_minimum; @@ -92,24 +122,44 @@ AudioPlot::paint (wxPaintEvent &) gc->SetPen (*wxLIGHT_GREY_PEN); gc->StrokePath (grid); - wxGraphicsPath path[AudioPoint::COUNT]; + for (int c = 0; c < MAX_AUDIO_CHANNELS; ++c) { + if (!_channel_visible[c] || c >= _analysis->channels()) { + continue; + } - for (int i = 0; i < AudioPoint::COUNT; ++i) { - path[i] = gc->CreatePath (); - path[i].MoveToPoint (0, height - (max (_analysis->get_point(_channel, 0)[i], float (_minimum)) - _minimum + _gain) * ys); - } + wxGraphicsPath path[AudioPoint::COUNT]; + + for (int i = 0; i < AudioPoint::COUNT; ++i) { + if (!_type_visible[i]) { + continue; + } + + path[i] = gc->CreatePath (); + path[i].MoveToPoint (0, height - (max (_analysis->get_point(c, 0)[i], float (_minimum)) - _minimum + _gain) * ys); + } - for (int i = 0; i < _analysis->points(_channel); ++i) { - for (int j = 0; j < AudioPoint::COUNT; ++j) { - path[j].AddLineToPoint (i * xs, height - (max (_analysis->get_point(_channel, i)[j], float (_minimum)) - _minimum + _gain) * ys); + for (int i = 0; i < _analysis->points(c); ++i) { + for (int j = 0; j < AudioPoint::COUNT; ++j) { + if (!_type_visible[j]) { + continue; + } + + path[j].AddLineToPoint (i * xs, height - (max (_analysis->get_point(c, i)[j], float (_minimum)) - _minimum + _gain) * ys); + } } - } - gc->SetPen (*wxBLUE_PEN); - gc->StrokePath (path[AudioPoint::RMS]); + wxColour const col = _colours[c]; - gc->SetPen (*wxRED_PEN); - gc->StrokePath (path[AudioPoint::PEAK]); + if (_type_visible[AudioPoint::RMS]) { + gc->SetPen (*wxThePenList->FindOrCreatePen (col)); + gc->StrokePath (path[AudioPoint::RMS]); + } + + if (_type_visible[AudioPoint::PEAK]) { + gc->SetPen (*wxThePenList->FindOrCreatePen (wxColour (col.Red(), col.Green(), col.Blue(), col.Alpha() / 2))); + gc->StrokePath (path[AudioPoint::PEAK]); + } + } delete gc; } diff --git a/src/wx/audio_plot.h b/src/wx/audio_plot.h index b2ae139d1..4ac7f848c 100644 --- a/src/wx/audio_plot.h +++ b/src/wx/audio_plot.h @@ -20,8 +20,8 @@ #include #include #include - -class AudioAnalysis; +#include "util.h" +#include "audio_analysis.h" class AudioPlot : public wxPanel { @@ -29,16 +29,20 @@ public: AudioPlot (wxWindow *); void set_analysis (boost::shared_ptr); - void set_channel (int c); + void set_channel_visible (int c, bool v); + void set_type_visible (int t, bool v); void set_gain (float); private: void paint (wxPaintEvent &); boost::shared_ptr _analysis; - int _channel; + bool _channel_visible[MAX_AUDIO_CHANNELS]; + bool _type_visible[AudioPoint::COUNT]; /** gain to apply in dB */ float _gain; + std::vector _colours; + static const int _minimum; }; -- cgit v1.2.3 From eac941aed6e6eed7f0329e42c7a036ed620f8df0 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 25 Feb 2013 20:52:20 +0000 Subject: Try to tidy up channel mapping a bit. --- src/lib/encoder.cc | 26 ++++++++++---------- src/lib/util.cc | 65 ++++++++++++++++++++++++++++++++++++++++---------- src/lib/util.h | 15 +++++++++++- src/lib/writer.cc | 6 +++-- src/wx/audio_dialog.cc | 32 +++++++++++++++++-------- 5 files changed, 106 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index f25256379..07139968d 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -423,18 +423,20 @@ Encoder::encoder_thread (ServerDescription* server) void Encoder::write_audio (shared_ptr data) { - if (_film->audio_channels() == 1) { - /* We need to switch things around so that the mono channel is on - the centre channel of a 5.1 set (with other channels silent). - */ - - shared_ptr b (new AudioBuffers (6, data->frames ())); - b->make_silent (libdcp::LEFT); - b->make_silent (libdcp::RIGHT); - memcpy (b->data()[libdcp::CENTRE], data->data()[0], data->frames() * sizeof(float)); - b->make_silent (libdcp::LFE); - b->make_silent (libdcp::LS); - b->make_silent (libdcp::RS); + AudioMapping m (_film->audio_channels ()); + if (m.dcp_channels() != _film->audio_channels()) { + + /* Remap (currently just for mono -> 5.1) */ + + shared_ptr b (new AudioBuffers (m.dcp_channels(), data->frames ())); + for (int i = 0; i < m.dcp_channels(); ++i) { + optional s = m.dcp_to_source (static_cast (i)); + if (!s) { + b->make_silent (i); + } else { + memcpy (b->data()[i], data->data()[s.get()], data->frames() * sizeof(float)); + } + } data = b; } diff --git a/src/lib/util.cc b/src/lib/util.cc index f807bf329..8ad980361 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -445,19 +445,6 @@ dcp_audio_sample_rate (int fs) return 96000; } -int -dcp_audio_channels (int f) -{ - if (f == 1) { - /* The source is mono, so to put the mono channel into - the centre we need to generate a 5.1 soundtrack. - */ - return 6; - } - - return f; -} - bool operator== (Crop const & a, Crop const & b) { return (a.left == b.left && a.right == b.right && a.top == b.top && a.bottom == b.bottom); @@ -918,3 +905,55 @@ audio_channel_name (int c) return channels[c]; } + +AudioMapping::AudioMapping (int c) + : _source_channels (c) +{ + +} + +optional +AudioMapping::source_to_dcp (int c) const +{ + if (c >= _source_channels) { + return optional (); + } + + if (_source_channels == 1) { + /* mono sources to centre */ + return libdcp::CENTRE; + } + + return static_cast (c); +} + +optional +AudioMapping::dcp_to_source (libdcp::Channel c) const +{ + if (_source_channels == 1) { + if (c == libdcp::CENTRE) { + return 0; + } else { + return optional (); + } + } + + if (static_cast (c) >= _source_channels) { + return optional (); + } + + return static_cast (c); +} + +int +AudioMapping::dcp_channels () const +{ + if (_source_channels == 1) { + /* The source is mono, so to put the mono channel into + the centre we need to generate a 5.1 soundtrack. + */ + return 6; + } + + return _source_channels; +} diff --git a/src/lib/util.h b/src/lib/util.h index b76aead41..22c6ea95b 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -29,6 +29,7 @@ #include #include #include +#include #include extern "C" { #include @@ -179,7 +180,6 @@ struct Rect extern std::string crop_string (Position, libdcp::Size); extern int dcp_audio_sample_rate (int); -extern int dcp_audio_channels (int); extern std::string colour_lut_index_to_name (int index); extern int stride_round_up (int, int const *, int); extern int stride_lookup (int c, int const * stride); @@ -269,6 +269,19 @@ private: float** _data; }; +class AudioMapping +{ +public: + AudioMapping (int); + + boost::optional source_to_dcp (int c) const; + boost::optional dcp_to_source (libdcp::Channel c) const; + int dcp_channels () const; + +private: + int _source_channels; +}; + extern int64_t video_frames_to_audio_frames (SourceFrame v, float audio_sample_rate, float frames_per_second); extern bool still_image_file (std::string); extern std::pair cpu_info (); diff --git a/src/lib/writer.cc b/src/lib/writer.cc index c2cc00328..1dad4357d 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -72,13 +72,15 @@ Writer::Writer (shared_ptr f) _picture_asset_writer = _picture_asset->start_write (_first_nonexistant_frame > 0); - if (dcp_audio_channels (_film->audio_channels()) > 0) { + AudioMapping m (_film->audio_channels ()); + + if (m.dcp_channels() > 0) { _sound_asset.reset ( new libdcp::SoundAsset ( _film->dir (_film->dcp_name()), "audio.mxf", DCPFrameRate (_film->frames_per_second()).frames_per_second, - dcp_audio_channels (_film->audio_channels()), + m.dcp_channels (), dcp_audio_sample_rate (_film->audio_stream()->sample_rate()) ) ); diff --git a/src/wx/audio_dialog.cc b/src/wx/audio_dialog.cc index dc297e246..a422e4e46 100644 --- a/src/wx/audio_dialog.cc +++ b/src/wx/audio_dialog.cc @@ -26,6 +26,7 @@ using boost::shared_ptr; using boost::bind; +using boost::optional; AudioDialog::AudioDialog (wxWindow* parent) : wxDialog (parent, wxID_ANY, _("Audio"), wxDefaultPosition, wxSize (640, 512), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) @@ -89,13 +90,15 @@ AudioDialog::setup_channels () if (!_film->audio_stream()) { return; } - - for (int i = 0; i < _film->audio_stream()->channels(); ++i) { - _channel_checkbox[i]->Show (); - } - for (int i = _film->audio_stream()->channels(); i < MAX_AUDIO_CHANNELS; ++i) { - _channel_checkbox[i]->Hide (); + AudioMapping m (_film->audio_stream()->channels ()); + + for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) { + if (m.dcp_to_source(static_cast(i))) { + _channel_checkbox[i]->Show (); + } else { + _channel_checkbox[i]->Hide (); + } } } @@ -113,8 +116,13 @@ AudioDialog::try_to_load_analysis () } _plot->set_analysis (a); - _channel_checkbox[0]->SetValue (true); - _plot->set_channel_visible (0, true); + + AudioMapping m (_film->audio_stream()->channels ()); + optional c = m.source_to_dcp (0); + if (c) { + _channel_checkbox[c.get()]->SetValue (true); + _plot->set_channel_visible (0, true); + } for (int i = 0; i < AudioPoint::COUNT; ++i) { _type_checkbox[i]->SetValue (true); @@ -131,8 +139,12 @@ AudioDialog::channel_clicked (wxCommandEvent& ev) } assert (c < MAX_AUDIO_CHANNELS); - - _plot->set_channel_visible (c, _channel_checkbox[c]->GetValue ()); + + AudioMapping m (_film->audio_stream()->channels ()); + optional s = m.dcp_to_source (static_cast (c)); + if (s) { + _plot->set_channel_visible (s.get(), _channel_checkbox[c]->GetValue ()); + } } void -- cgit v1.2.3 From 2eb98dd87bb359ae333247af55b650fced7f6311 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 25 Feb 2013 20:59:12 +0000 Subject: A little tidying up. --- src/wx/audio_dialog.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/wx/audio_dialog.cc b/src/wx/audio_dialog.cc index a422e4e46..701c8263a 100644 --- a/src/wx/audio_dialog.cc +++ b/src/wx/audio_dialog.cc @@ -35,7 +35,7 @@ AudioDialog::AudioDialog (wxWindow* parent) wxBoxSizer* sizer = new wxBoxSizer (wxHORIZONTAL); _plot = new AudioPlot (this); - sizer->Add (_plot, 1); + sizer->Add (_plot, 1, wxALL, 12); wxFlexGridSizer* table = new wxFlexGridSizer (2, 6, 6); @@ -61,7 +61,7 @@ AudioDialog::AudioDialog (wxWindow* parent) _type_checkbox[i]->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (AudioDialog::type_clicked), 0, this); } - sizer->Add (table); + sizer->Add (table, 0, wxALL, 12); SetSizer (sizer); sizer->Layout (); @@ -82,6 +82,8 @@ AudioDialog::set_film (boost::shared_ptr f) _film_changed_connection = _film->Changed.connect (bind (&AudioDialog::film_changed, this, _1)); _film_audio_analysis_finished_connection = _film->AudioAnalysisFinished.connect (bind (&AudioDialog::try_to_load_analysis, this)); + + SetTitle (String::compose ("DVD-o-matic audio - %1", _film->name())); } void -- cgit v1.2.3 From b2ebae40e3dbfdf535ac7326966aa00ae3738ddb Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 25 Feb 2013 21:13:49 +0000 Subject: Maybe de-flicker the audio display a bit on windows. --- src/wx/audio_plot.cc | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/wx/audio_plot.cc b/src/wx/audio_plot.cc index cccdaed34..8e7b3f9f5 100644 --- a/src/wx/audio_plot.cc +++ b/src/wx/audio_plot.cc @@ -39,6 +39,11 @@ AudioPlot::AudioPlot (wxWindow* parent) : wxPanel (parent) , _gain (0) { + SetDoubleBuffered (true); +#if wxMAJOR_VERSION == 2 && wxMINOR_VERSION >= 9 + SetBackgroundStyle (wxBG_STYLE_PAINT); +#endif + for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) { _channel_visible[i] = false; } -- cgit v1.2.3 From f6320b67fe724d9c5e22af1a2566a0700a65ab62 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 25 Feb 2013 21:20:27 +0000 Subject: Try again. --- src/wx/film_viewer.cc | 3 --- 1 file changed, 3 deletions(-) (limited to 'src') diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 96656ce09..e1e3b009d 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -57,9 +57,6 @@ FilmViewer::FilmViewer (shared_ptr f, wxWindow* p) , _clear_required (false) { _panel->SetDoubleBuffered (true); -#if wxMAJOR_VERSION == 2 && wxMINOR_VERSION >= 9 - _panel->SetBackgroundStyle (wxBG_STYLE_PAINT); -#endif _v_sizer = new wxBoxSizer (wxVERTICAL); SetSizer (_v_sizer); -- cgit v1.2.3 From b84f9f2682205881c208035fea7a7eb43811d565 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 25 Feb 2013 21:29:53 +0000 Subject: Scratch that. --- src/wx/film_viewer.cc | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index e1e3b009d..2314a7f24 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -56,8 +56,6 @@ FilmViewer::FilmViewer (shared_ptr f, wxWindow* p) , _got_frame (false) , _clear_required (false) { - _panel->SetDoubleBuffered (true); - _v_sizer = new wxBoxSizer (wxVERTICAL); SetSizer (_v_sizer); -- cgit v1.2.3 From e13fde5e5525c5feb69cae6618f484158378d116 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 25 Feb 2013 21:39:35 +0000 Subject: Fix dumb-assery. Initial axes. --- src/wx/audio_plot.cc | 11 ++++++++--- src/wx/film_viewer.cc | 5 +++++ 2 files changed, 13 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/wx/audio_plot.cc b/src/wx/audio_plot.cc index 8e7b3f9f5..0fe9fb45e 100644 --- a/src/wx/audio_plot.cc +++ b/src/wx/audio_plot.cc @@ -40,9 +40,6 @@ AudioPlot::AudioPlot (wxWindow* parent) , _gain (0) { SetDoubleBuffered (true); -#if wxMAJOR_VERSION == 2 && wxMINOR_VERSION >= 9 - SetBackgroundStyle (wxBG_STYLE_PAINT); -#endif for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) { _channel_visible[i] = false; @@ -115,6 +112,7 @@ AudioPlot::paint (wxPaintEvent &) float const xs = width / float (_analysis->points (0)); int const height = GetSize().GetHeight (); float const ys = height / -_minimum; + int const border = 8; wxGraphicsPath grid = gc->CreatePath (); gc->SetFont (gc->CreateFont (*wxSMALL_FONT)); @@ -127,6 +125,13 @@ AudioPlot::paint (wxPaintEvent &) gc->SetPen (*wxLIGHT_GREY_PEN); gc->StrokePath (grid); + wxGraphicsPath axes = gc->CreatePath (); + axes.MoveToPoint (border, border); + axes.AddLineToPoint (border, height - border); + axes.AddLineToPoint (width - border, height - border); + gc->SetPen (*wxBLACK_PEN); + gc->StrokePath (axes); + for (int c = 0; c < MAX_AUDIO_CHANNELS; ++c) { if (!_channel_visible[c] || c >= _analysis->channels()) { continue; diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 2314a7f24..96656ce09 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -56,6 +56,11 @@ FilmViewer::FilmViewer (shared_ptr f, wxWindow* p) , _got_frame (false) , _clear_required (false) { + _panel->SetDoubleBuffered (true); +#if wxMAJOR_VERSION == 2 && wxMINOR_VERSION >= 9 + _panel->SetBackgroundStyle (wxBG_STYLE_PAINT); +#endif + _v_sizer = new wxBoxSizer (wxVERTICAL); SetSizer (_v_sizer); -- cgit v1.2.3 From 00220cc5223f5b1823dd4aa91993f5257d8938fd Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 25 Feb 2013 22:00:51 +0000 Subject: Catch exception on loading film with bad content file. --- src/wx/film_viewer.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 96656ce09..6d46b2c21 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -101,7 +101,14 @@ FilmViewer::film_changed (Film::Property p) o.decode_audio = false; o.decode_subtitles = true; o.video_sync = false; - _decoders = decoder_factory (_film, o); + + try { + _decoders = decoder_factory (_film, o); + } catch (StringError& e) { + error_dialog (this, wxString::Format (_("Could not open content file (%s)"), e.what())); + return; + } + if (_decoders.video == 0) { break; } -- cgit v1.2.3 From 7705c4569818a8b798eb471bf9298873622a1e59 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 25 Feb 2013 22:01:25 +0000 Subject: Tidy axes a little. --- src/wx/audio_plot.cc | 52 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/wx/audio_plot.cc b/src/wx/audio_plot.cc index 0fe9fb45e..fb5b92ff3 100644 --- a/src/wx/audio_plot.cc +++ b/src/wx/audio_plot.cc @@ -106,32 +106,33 @@ AudioPlot::paint (wxPaintEvent &) gc->DrawText (_("Please wait; audio is being analysed..."), 32, 32); return; } + + wxGraphicsPath grid = gc->CreatePath (); + gc->SetFont (gc->CreateFont (*wxSMALL_FONT)); + wxDouble db_label_width; + wxDouble db_label_height; + wxDouble db_label_descent; + wxDouble db_label_leading; + gc->GetTextExtent (_("-80dB"), &db_label_width, &db_label_height, &db_label_descent, &db_label_leading); + + db_label_width += 8; - int const width = GetSize().GetWidth(); + int const data_width = GetSize().GetWidth() - db_label_width; /* Assume all channels have the same number of points */ - float const xs = width / float (_analysis->points (0)); + float const xs = data_width / float (_analysis->points (0)); int const height = GetSize().GetHeight (); - float const ys = height / -_minimum; - int const border = 8; + int const yo = 32; + float const ys = (height - yo) / -_minimum; - wxGraphicsPath grid = gc->CreatePath (); - gc->SetFont (gc->CreateFont (*wxSMALL_FONT)); for (int i = _minimum; i <= 0; i += 10) { - int const y = height - (i - _minimum) * ys; - grid.MoveToPoint (0, y); - grid.AddLineToPoint (width, y); - gc->DrawText (std_to_wx (String::compose ("%1dB", i)), width - 32, y - 12); + int const y = (height - (i - _minimum) * ys) - yo; + grid.MoveToPoint (db_label_width - 4, y); + grid.AddLineToPoint (db_label_width + data_width, y); + gc->DrawText (std_to_wx (String::compose ("%1dB", i)), 0, y - (db_label_height / 2)); } gc->SetPen (*wxLIGHT_GREY_PEN); gc->StrokePath (grid); - wxGraphicsPath axes = gc->CreatePath (); - axes.MoveToPoint (border, border); - axes.AddLineToPoint (border, height - border); - axes.AddLineToPoint (width - border, height - border); - gc->SetPen (*wxBLACK_PEN); - gc->StrokePath (axes); - for (int c = 0; c < MAX_AUDIO_CHANNELS; ++c) { if (!_channel_visible[c] || c >= _analysis->channels()) { continue; @@ -145,7 +146,10 @@ AudioPlot::paint (wxPaintEvent &) } path[i] = gc->CreatePath (); - path[i].MoveToPoint (0, height - (max (_analysis->get_point(c, 0)[i], float (_minimum)) - _minimum + _gain) * ys); + path[i].MoveToPoint ( + db_label_width, + height - (max (_analysis->get_point(c, 0)[i], float (_minimum)) - _minimum + _gain) * ys - yo + ); } for (int i = 0; i < _analysis->points(c); ++i) { @@ -154,7 +158,10 @@ AudioPlot::paint (wxPaintEvent &) continue; } - path[j].AddLineToPoint (i * xs, height - (max (_analysis->get_point(c, i)[j], float (_minimum)) - _minimum + _gain) * ys); + path[j].AddLineToPoint ( + i * xs + db_label_width, + height - (max (_analysis->get_point(c, i)[j], float (_minimum)) - _minimum + _gain) * ys - yo + ); } } @@ -171,6 +178,13 @@ AudioPlot::paint (wxPaintEvent &) } } + wxGraphicsPath axes = gc->CreatePath (); + axes.MoveToPoint (db_label_width, 0); + axes.AddLineToPoint (db_label_width, height - yo); + axes.AddLineToPoint (db_label_width + data_width, height - yo); + gc->SetPen (*wxBLACK_PEN); + gc->StrokePath (axes); + delete gc; } -- cgit v1.2.3 From 67ecc371385beeed9cf5e245bf44d1487d4234c6 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 25 Feb 2013 22:23:59 +0000 Subject: Fix crash on zero-channelled analysis. --- src/wx/audio_plot.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/wx/audio_plot.cc b/src/wx/audio_plot.cc index fb5b92ff3..693e11a61 100644 --- a/src/wx/audio_plot.cc +++ b/src/wx/audio_plot.cc @@ -101,7 +101,7 @@ AudioPlot::paint (wxPaintEvent &) return; } - if (!_analysis) { + if (!_analysis || _analysis->channels() == 0) { gc->SetFont (gc->CreateFont (*wxNORMAL_FONT)); gc->DrawText (_("Please wait; audio is being analysed..."), 32, 32); return; -- cgit v1.2.3 From cb4572c5c4b0a543d42b05a47c37d5db2dc44bb8 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 25 Feb 2013 22:30:13 +0000 Subject: Time label. --- src/wx/audio_plot.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/wx/audio_plot.cc b/src/wx/audio_plot.cc index 693e11a61..8d5184d48 100644 --- a/src/wx/audio_plot.cc +++ b/src/wx/audio_plot.cc @@ -130,9 +130,12 @@ AudioPlot::paint (wxPaintEvent &) grid.AddLineToPoint (db_label_width + data_width, y); gc->DrawText (std_to_wx (String::compose ("%1dB", i)), 0, y - (db_label_height / 2)); } + gc->SetPen (*wxLIGHT_GREY_PEN); gc->StrokePath (grid); + gc->DrawText (_("Time"), data_width, height - yo + db_label_height / 2); + for (int c = 0; c < MAX_AUDIO_CHANNELS; ++c) { if (!_channel_visible[c] || c >= _analysis->channels()) { continue; -- cgit v1.2.3 From 36fdb78ea9973d1a797171d762802e707577c960 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 25 Feb 2013 23:40:08 +0000 Subject: Tweak number of points and minimum dB for display. --- src/lib/analyse_audio_job.cc | 2 +- src/wx/audio_plot.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/lib/analyse_audio_job.cc b/src/lib/analyse_audio_job.cc index fb5f2868f..588e9fc3d 100644 --- a/src/lib/analyse_audio_job.cc +++ b/src/lib/analyse_audio_job.cc @@ -30,7 +30,7 @@ using std::max; using std::cout; using boost::shared_ptr; -int const AnalyseAudioJob::_num_points = 128; +int const AnalyseAudioJob::_num_points = 1024; AnalyseAudioJob::AnalyseAudioJob (shared_ptr f) : Job (f) diff --git a/src/wx/audio_plot.cc b/src/wx/audio_plot.cc index 8d5184d48..ad69b6e1d 100644 --- a/src/wx/audio_plot.cc +++ b/src/wx/audio_plot.cc @@ -33,7 +33,7 @@ using std::min; using boost::bind; using boost::shared_ptr; -int const AudioPlot::_minimum = -90; +int const AudioPlot::_minimum = -70; AudioPlot::AudioPlot (wxWindow* parent) : wxPanel (parent) -- cgit v1.2.3 From 1fadfdf60bb2c02086c2c9689ea44c73bed41571 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 26 Feb 2013 08:15:51 +0000 Subject: Pretty dumb smoothing. --- src/lib/analyse_audio_job.cc | 3 +-- src/lib/audio_analysis.cc | 28 ++++++++++++++++++++++++++++ src/lib/audio_analysis.h | 2 ++ src/wx/audio_dialog.cc | 11 +++++++++++ src/wx/audio_dialog.h | 2 ++ src/wx/audio_plot.cc | 25 +++++++++++++++++++++++-- src/wx/audio_plot.h | 2 ++ 7 files changed, 69 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/lib/analyse_audio_job.cc b/src/lib/analyse_audio_job.cc index 588e9fc3d..bcabb6c91 100644 --- a/src/lib/analyse_audio_job.cc +++ b/src/lib/analyse_audio_job.cc @@ -95,8 +95,7 @@ AnalyseAudioJob::audio (shared_ptr b) _current[j][AudioPoint::PEAK] = max (_current[j][AudioPoint::PEAK], fabsf (s)); if ((_done % _samples_per_point) == 0) { - _current[j][AudioPoint::RMS] = 20 * log10 (sqrt (_current[j][AudioPoint::RMS] / _samples_per_point)); - _current[j][AudioPoint::PEAK] = 20 * log10 (_current[j][AudioPoint::PEAK]); + _current[j][AudioPoint::RMS] = sqrt (_current[j][AudioPoint::RMS] / _samples_per_point); _analysis->add_point (j, _current[j]); _current[j] = AudioPoint (); diff --git a/src/lib/audio_analysis.cc b/src/lib/audio_analysis.cc index b29ed1707..0cf08c5bd 100644 --- a/src/lib/audio_analysis.cc +++ b/src/lib/audio_analysis.cc @@ -31,6 +31,8 @@ using std::ofstream; using std::ifstream; using std::vector; using std::cout; +using std::max; +using std::list; AudioPoint::AudioPoint () { @@ -121,3 +123,29 @@ AudioAnalysis::write (string filename) f.close (); boost::filesystem::rename (tmp, filename); } + +float +AudioAnalysis::smooth (list const & data, AudioPoint::Type t) +{ + float val; + + switch (t) { + case AudioPoint::PEAK: + /* XXX: fall-off, or something...? */ + val = -200; + for (list::const_iterator i = data.begin(); i != data.end(); ++i) { + val = max (val, *i); + } + return val; + case AudioPoint::RMS: + val = 0; + for (list::const_iterator i = data.begin(); i != data.end(); ++i) { + val += pow (*i, 2); + } + return sqrt (val / data.size()); + default: + assert (false); + } + + return 0; +} diff --git a/src/lib/audio_analysis.h b/src/lib/audio_analysis.h index c2d8db876..a8cfbdeca 100644 --- a/src/lib/audio_analysis.h +++ b/src/lib/audio_analysis.h @@ -22,6 +22,7 @@ #include #include +#include class AudioPoint { @@ -59,6 +60,7 @@ public: void write (std::string); + static float smooth (std::list const &, AudioPoint::Type); private: std::vector > _data; diff --git a/src/wx/audio_dialog.cc b/src/wx/audio_dialog.cc index 701c8263a..bcec01332 100644 --- a/src/wx/audio_dialog.cc +++ b/src/wx/audio_dialog.cc @@ -61,6 +61,11 @@ AudioDialog::AudioDialog (wxWindow* parent) _type_checkbox[i]->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (AudioDialog::type_clicked), 0, this); } + _smoothing = new wxSlider (this, wxID_ANY, 1, 1, 128); + _smoothing->Connect (wxID_ANY, wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler (AudioDialog::smoothing_changed), 0, this); + table->Add (_smoothing, 1, wxEXPAND); + table->AddSpacer (0); + sizer->Add (table, 0, wxALL, 12); SetSizer (sizer); @@ -178,3 +183,9 @@ AudioDialog::type_clicked (wxCommandEvent& ev) _plot->set_type_visible (t, _type_checkbox[t]->GetValue ()); } + +void +AudioDialog::smoothing_changed (wxScrollEvent &) +{ + _plot->set_smoothing (_smoothing->GetValue ()); +} diff --git a/src/wx/audio_dialog.h b/src/wx/audio_dialog.h index c3875023f..16cb356fe 100644 --- a/src/wx/audio_dialog.h +++ b/src/wx/audio_dialog.h @@ -37,6 +37,7 @@ private: void film_changed (Film::Property); void channel_clicked (wxCommandEvent &); void type_clicked (wxCommandEvent &); + void smoothing_changed (wxScrollEvent &); void try_to_load_analysis (); void setup_channels (); @@ -44,6 +45,7 @@ private: AudioPlot* _plot; wxCheckBox* _channel_checkbox[MAX_AUDIO_CHANNELS]; wxCheckBox* _type_checkbox[AudioPoint::COUNT]; + wxSlider* _smoothing; boost::signals2::scoped_connection _film_changed_connection; boost::signals2::scoped_connection _film_audio_analysis_finished_connection; }; diff --git a/src/wx/audio_plot.cc b/src/wx/audio_plot.cc index ad69b6e1d..d938d0c27 100644 --- a/src/wx/audio_plot.cc +++ b/src/wx/audio_plot.cc @@ -28,6 +28,7 @@ using std::cout; using std::vector; +using std::list; using std::max; using std::min; using boost::bind; @@ -38,6 +39,7 @@ int const AudioPlot::_minimum = -70; AudioPlot::AudioPlot (wxWindow* parent) : wxPanel (parent) , _gain (0) + , _smoothing (1) { SetDoubleBuffered (true); @@ -149,21 +151,33 @@ AudioPlot::paint (wxPaintEvent &) } path[i] = gc->CreatePath (); + + float const val = 20 * log10 (_analysis->get_point(c, 0)[i]); + path[i].MoveToPoint ( db_label_width, - height - (max (_analysis->get_point(c, 0)[i], float (_minimum)) - _minimum + _gain) * ys - yo + height - (max (val, float (_minimum)) - _minimum + _gain) * ys - yo ); } + list smoothing[AudioPoint::COUNT]; + for (int i = 0; i < _analysis->points(c); ++i) { for (int j = 0; j < AudioPoint::COUNT; ++j) { if (!_type_visible[j]) { continue; } + + smoothing[j].push_back (_analysis->get_point(c, i)[j]); + if (int(smoothing[j].size()) > _smoothing) { + smoothing[j].pop_front (); + } + + float const val = 20 * log10 (_analysis->smooth (smoothing[j], static_cast (j))); path[j].AddLineToPoint ( i * xs + db_label_width, - height - (max (_analysis->get_point(c, i)[j], float (_minimum)) - _minimum + _gain) * ys - yo + height - (max (val, float (_minimum)) - _minimum + _gain) * ys - yo ); } } @@ -197,3 +211,10 @@ AudioPlot::set_gain (float g) _gain = g; Refresh (); } + +void +AudioPlot::set_smoothing (int s) +{ + _smoothing = s; + Refresh (); +} diff --git a/src/wx/audio_plot.h b/src/wx/audio_plot.h index 4ac7f848c..fe8862d54 100644 --- a/src/wx/audio_plot.h +++ b/src/wx/audio_plot.h @@ -32,6 +32,7 @@ public: void set_channel_visible (int c, bool v); void set_type_visible (int t, bool v); void set_gain (float); + void set_smoothing (int); private: void paint (wxPaintEvent &); @@ -41,6 +42,7 @@ private: bool _type_visible[AudioPoint::COUNT]; /** gain to apply in dB */ float _gain; + int _smoothing; std::vector _colours; -- cgit v1.2.3 From 8cc4b5f514795a52ad13c8d6e8527061da14a0d2 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 26 Feb 2013 16:02:15 +0000 Subject: Speculative support for some new YVU444 pixel formats. --- src/lib/image.cc | 71 ++++++++++++++++++++++++++++++++++++++++++++++++-------- src/lib/image.h | 5 +++- test/test.cc | 47 +++++++++++-------------------------- 3 files changed, 78 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/src/lib/image.cc b/src/lib/image.cc index f38d44185..b7ac13ab1 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -69,6 +69,10 @@ Image::lines (int n) const case PIX_FMT_YUV422P10LE: case PIX_FMT_YUV422P: case PIX_FMT_YUV444P: + case PIX_FMT_YUV444P9BE: + case PIX_FMT_YUV444P9LE: + case PIX_FMT_YUV444P10BE: + case PIX_FMT_YUV444P10LE: return size().height; default: throw PixelFormatError ("lines()", _pixel_format); @@ -86,6 +90,10 @@ Image::components () const case PIX_FMT_YUV422P10LE: case PIX_FMT_YUV422P: case PIX_FMT_YUV444P: + case PIX_FMT_YUV444P9BE: + case PIX_FMT_YUV444P9LE: + case PIX_FMT_YUV444P10BE: + case PIX_FMT_YUV444P10LE: return 3; case PIX_FMT_RGB24: case PIX_FMT_RGBA: @@ -204,6 +212,10 @@ Image::post_process (string pp, bool aligned) const pp_format = PP_FORMAT_422; break; case PIX_FMT_YUV444P: + case PIX_FMT_YUV444P9BE: + case PIX_FMT_YUV444P9LE: + case PIX_FMT_YUV444P10BE: + case PIX_FMT_YUV444P10LE: pp_format = PP_FORMAT_444; default: throw PixelFormatError ("post_process", pixel_format()); @@ -252,9 +264,37 @@ Image::crop (Crop crop, bool aligned) const return out; } +/** Blacken a YUV image whose bits per pixel is rounded up to 16 */ +void +Image::yuv_16_black (uint16_t v) +{ + memset (data()[0], 0, lines(0) * stride()[0]); + for (int i = 1; i < 3; ++i) { + int16_t* p = reinterpret_cast (data()[i]); + for (int y = 0; y < size().height; ++y) { + for (int x = 0; x < line_size()[i] / 2; ++x) { + p[x] = v; + } + p += stride()[i] / 2; + } + } +} + +uint16_t +Image::swap_16 (uint16_t v) +{ + return ((v >> 8) & 0xff) | ((v & 0xff) << 8); +} + void Image::make_black () { + /* U/V black value for 9-bit colour */ + static uint16_t const nine_bit_uv = (1 << 8) - 1; + + /* U/V black value for 10-bit colour */ + static uint16_t const ten_bit_uv = (1 << 9) - 1; + switch (_pixel_format) { case PIX_FMT_YUV420P: case PIX_FMT_YUV422P: @@ -264,19 +304,25 @@ Image::make_black () memset (data()[2], 0x7f, lines(2) * stride()[2]); break; + case PIX_FMT_YUV422P9LE: + case PIX_FMT_YUV444P9LE: + yuv_16_black (nine_bit_uv); + break; + + case PIX_FMT_YUV422P9BE: + case PIX_FMT_YUV444P9BE: + yuv_16_black (swap_16 (nine_bit_uv)); + break; + case PIX_FMT_YUV422P10LE: - memset (data()[0], 0, lines(0) * stride()[0]); - for (int i = 1; i < 3; ++i) { - int16_t* p = reinterpret_cast (data()[i]); - for (int y = 0; y < size().height; ++y) { - for (int x = 0; x < line_size()[i] / 2; ++x) { - p[x] = (1 << 9) - 1; - } - p += stride()[i] / 2; - } - } + case PIX_FMT_YUV444P10LE: + yuv_16_black (ten_bit_uv); break; + case PIX_FMT_YUV444P10BE: + case PIX_FMT_YUV422P10BE: + yuv_16_black (swap_16 (ten_bit_uv)); + case PIX_FMT_RGB24: memset (data()[0], 0, lines(0) * stride()[0]); break; @@ -382,6 +428,11 @@ Image::bytes_per_pixel (int c) const } case PIX_FMT_YUV444P: return 3; + case PIX_FMT_YUV444P9BE: + case PIX_FMT_YUV444P9LE: + case PIX_FMT_YUV444P10LE: + case PIX_FMT_YUV444P10BE: + return 6; default: assert (false); } diff --git a/src/lib/image.h b/src/lib/image.h index f40ea9280..6b9ade99e 100644 --- a/src/lib/image.h +++ b/src/lib/image.h @@ -92,7 +92,10 @@ protected: virtual void swap (Image &); float bytes_per_pixel (int) const; -private: +private: + void yuv_16_black (uint16_t); + static uint16_t swap_16 (uint16_t); + AVPixelFormat _pixel_format; ///< FFmpeg's way of describing the pixel format of this Image }; diff --git a/test/test.cc b/test/test.cc index 386aead2e..8cfc6e467 100644 --- a/test/test.cc +++ b/test/test.cc @@ -94,25 +94,18 @@ BOOST_AUTO_TEST_CASE (make_black_test) libdcp::Size in_size (512, 512); libdcp::Size out_size (1024, 1024); - { - /* Plain RGB input */ - boost::shared_ptr foo (new SimpleImage (AV_PIX_FMT_RGB24, in_size, true)); - foo->make_black (); - boost::shared_ptr bar = foo->scale_and_convert_to_rgb (out_size, 0, Scaler::from_id ("bicubic"), true); - - uint8_t* p = bar->data()[0]; - for (int y = 0; y < bar->size().height; ++y) { - uint8_t* q = p; - for (int x = 0; x < bar->line_size()[0]; ++x) { - BOOST_CHECK_EQUAL (*q++, 0); - } - p += bar->stride()[0]; - } - } - - { - /* YUV420P input */ - boost::shared_ptr foo (new SimpleImage (AV_PIX_FMT_YUV420P, in_size, true)); + list pix_fmts; + pix_fmts.push_back (AV_PIX_FMT_RGB24); + pix_fmts.push_back (AV_PIX_FMT_YUV420P); + pix_fmts.push_back (AV_PIX_FMT_YUV422P10LE); + pix_fmts.push_back (AV_PIX_FMT_YUV444P9LE); + pix_fmts.push_back (AV_PIX_FMT_YUV444P9BE); + pix_fmts.push_back (AV_PIX_FMT_YUV444P10LE); + pix_fmts.push_back (AV_PIX_FMT_YUV444P10BE); + + int N = 0; + for (list::const_iterator i = pix_fmts.begin(); i != pix_fmts.end(); ++i) { + boost::shared_ptr foo (new SimpleImage (*i, in_size, true)); foo->make_black (); boost::shared_ptr bar = foo->scale_and_convert_to_rgb (out_size, 0, Scaler::from_id ("bicubic"), true); @@ -124,22 +117,8 @@ BOOST_AUTO_TEST_CASE (make_black_test) } p += bar->stride()[0]; } - } - { - /* YUV422P10LE input */ - boost::shared_ptr foo (new SimpleImage (AV_PIX_FMT_YUV422P10LE, in_size, true)); - foo->make_black (); - boost::shared_ptr bar = foo->scale_and_convert_to_rgb (out_size, 0, Scaler::from_id ("bicubic"), true); - - uint8_t* p = bar->data()[0]; - for (int y = 0; y < bar->size().height; ++y) { - uint8_t* q = p; - for (int x = 0; x < bar->line_size()[0]; ++x) { - BOOST_CHECK_EQUAL (*q++, 0); - } - p += bar->stride()[0]; - } + ++N; } } -- cgit v1.2.3 From ab0ef1016c94d583d00ccb734373d7d07faf0e24 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 27 Feb 2013 00:25:37 +0000 Subject: Improve smoothing behaviour. --- src/lib/audio_analysis.cc | 26 -------- src/lib/audio_analysis.h | 2 - src/wx/audio_dialog.cc | 2 +- src/wx/audio_plot.cc | 149 ++++++++++++++++++++++++++-------------------- src/wx/audio_plot.h | 13 +++- 5 files changed, 97 insertions(+), 95 deletions(-) (limited to 'src') diff --git a/src/lib/audio_analysis.cc b/src/lib/audio_analysis.cc index 0cf08c5bd..9d708bbfd 100644 --- a/src/lib/audio_analysis.cc +++ b/src/lib/audio_analysis.cc @@ -123,29 +123,3 @@ AudioAnalysis::write (string filename) f.close (); boost::filesystem::rename (tmp, filename); } - -float -AudioAnalysis::smooth (list const & data, AudioPoint::Type t) -{ - float val; - - switch (t) { - case AudioPoint::PEAK: - /* XXX: fall-off, or something...? */ - val = -200; - for (list::const_iterator i = data.begin(); i != data.end(); ++i) { - val = max (val, *i); - } - return val; - case AudioPoint::RMS: - val = 0; - for (list::const_iterator i = data.begin(); i != data.end(); ++i) { - val += pow (*i, 2); - } - return sqrt (val / data.size()); - default: - assert (false); - } - - return 0; -} diff --git a/src/lib/audio_analysis.h b/src/lib/audio_analysis.h index a8cfbdeca..6e0e2b78a 100644 --- a/src/lib/audio_analysis.h +++ b/src/lib/audio_analysis.h @@ -60,8 +60,6 @@ public: void write (std::string); - static float smooth (std::list const &, AudioPoint::Type); - private: std::vector > _data; }; diff --git a/src/wx/audio_dialog.cc b/src/wx/audio_dialog.cc index bcec01332..b7736f664 100644 --- a/src/wx/audio_dialog.cc +++ b/src/wx/audio_dialog.cc @@ -61,7 +61,7 @@ AudioDialog::AudioDialog (wxWindow* parent) _type_checkbox[i]->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (AudioDialog::type_clicked), 0, this); } - _smoothing = new wxSlider (this, wxID_ANY, 1, 1, 128); + _smoothing = new wxSlider (this, wxID_ANY, AudioPlot::max_smoothing / 2, 1, AudioPlot::max_smoothing); _smoothing->Connect (wxID_ANY, wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler (AudioDialog::smoothing_changed), 0, this); table->Add (_smoothing, 1, wxEXPAND); table->AddSpacer (0); diff --git a/src/wx/audio_plot.cc b/src/wx/audio_plot.cc index d938d0c27..23cbabcdc 100644 --- a/src/wx/audio_plot.cc +++ b/src/wx/audio_plot.cc @@ -35,11 +35,12 @@ using boost::bind; using boost::shared_ptr; int const AudioPlot::_minimum = -70; +int const AudioPlot::max_smoothing = 128; AudioPlot::AudioPlot (wxWindow* parent) : wxPanel (parent) , _gain (0) - , _smoothing (1) + , _smoothing (max_smoothing / 2) { SetDoubleBuffered (true); @@ -111,100 +112,118 @@ AudioPlot::paint (wxPaintEvent &) wxGraphicsPath grid = gc->CreatePath (); gc->SetFont (gc->CreateFont (*wxSMALL_FONT)); - wxDouble db_label_width; wxDouble db_label_height; wxDouble db_label_descent; wxDouble db_label_leading; - gc->GetTextExtent (_("-80dB"), &db_label_width, &db_label_height, &db_label_descent, &db_label_leading); + gc->GetTextExtent (_("-80dB"), &_db_label_width, &db_label_height, &db_label_descent, &db_label_leading); - db_label_width += 8; + _db_label_width += 8; - int const data_width = GetSize().GetWidth() - db_label_width; + int const data_width = GetSize().GetWidth() - _db_label_width; /* Assume all channels have the same number of points */ - float const xs = data_width / float (_analysis->points (0)); - int const height = GetSize().GetHeight (); - int const yo = 32; - float const ys = (height - yo) / -_minimum; + _x_scale = data_width / float (_analysis->points (0)); + _height = GetSize().GetHeight (); + _y_origin = 32; + _y_scale = (_height - _y_origin) / -_minimum; for (int i = _minimum; i <= 0; i += 10) { - int const y = (height - (i - _minimum) * ys) - yo; - grid.MoveToPoint (db_label_width - 4, y); - grid.AddLineToPoint (db_label_width + data_width, y); + int const y = (_height - (i - _minimum) * _y_scale) - _y_origin; + grid.MoveToPoint (_db_label_width - 4, y); + grid.AddLineToPoint (_db_label_width + data_width, y); gc->DrawText (std_to_wx (String::compose ("%1dB", i)), 0, y - (db_label_height / 2)); } gc->SetPen (*wxLIGHT_GREY_PEN); gc->StrokePath (grid); - gc->DrawText (_("Time"), data_width, height - yo + db_label_height / 2); + gc->DrawText (_("Time"), data_width, _height - _y_origin + db_label_height / 2); - for (int c = 0; c < MAX_AUDIO_CHANNELS; ++c) { - if (!_channel_visible[c] || c >= _analysis->channels()) { - continue; - } - - wxGraphicsPath path[AudioPoint::COUNT]; - - for (int i = 0; i < AudioPoint::COUNT; ++i) { - if (!_type_visible[i]) { - continue; + + if (_type_visible[AudioPoint::PEAK]) { + for (int c = 0; c < MAX_AUDIO_CHANNELS; ++c) { + wxGraphicsPath p = gc->CreatePath (); + if (_channel_visible[c] && c < _analysis->channels()) { + plot_peak (p, c); } - - path[i] = gc->CreatePath (); - - float const val = 20 * log10 (_analysis->get_point(c, 0)[i]); - - path[i].MoveToPoint ( - db_label_width, - height - (max (val, float (_minimum)) - _minimum + _gain) * ys - yo - ); + wxColour const col = _colours[c]; + gc->SetPen (*wxThePenList->FindOrCreatePen (wxColour (col.Red(), col.Green(), col.Blue(), col.Alpha() / 2))); + gc->StrokePath (p); } + } - list smoothing[AudioPoint::COUNT]; - - for (int i = 0; i < _analysis->points(c); ++i) { - for (int j = 0; j < AudioPoint::COUNT; ++j) { - if (!_type_visible[j]) { - continue; - } - - smoothing[j].push_back (_analysis->get_point(c, i)[j]); - if (int(smoothing[j].size()) > _smoothing) { - smoothing[j].pop_front (); - } - - float const val = 20 * log10 (_analysis->smooth (smoothing[j], static_cast (j))); - - path[j].AddLineToPoint ( - i * xs + db_label_width, - height - (max (val, float (_minimum)) - _minimum + _gain) * ys - yo - ); + if (_type_visible[AudioPoint::RMS]) { + for (int c = 0; c < MAX_AUDIO_CHANNELS; ++c) { + wxGraphicsPath p = gc->CreatePath (); + if (_channel_visible[c] && c < _analysis->channels()) { + plot_rms (p, c); } - } - - wxColour const col = _colours[c]; - - if (_type_visible[AudioPoint::RMS]) { + wxColour const col = _colours[c]; gc->SetPen (*wxThePenList->FindOrCreatePen (col)); - gc->StrokePath (path[AudioPoint::RMS]); - } - - if (_type_visible[AudioPoint::PEAK]) { - gc->SetPen (*wxThePenList->FindOrCreatePen (wxColour (col.Red(), col.Green(), col.Blue(), col.Alpha() / 2))); - gc->StrokePath (path[AudioPoint::PEAK]); + gc->StrokePath (p); } } wxGraphicsPath axes = gc->CreatePath (); - axes.MoveToPoint (db_label_width, 0); - axes.AddLineToPoint (db_label_width, height - yo); - axes.AddLineToPoint (db_label_width + data_width, height - yo); + axes.MoveToPoint (_db_label_width, 0); + axes.AddLineToPoint (_db_label_width, _height - _y_origin); + axes.AddLineToPoint (_db_label_width + data_width, _height - _y_origin); gc->SetPen (*wxBLACK_PEN); gc->StrokePath (axes); delete gc; } +float +AudioPlot::y_for_linear (float p) const +{ + return _height - (20 * log10(p) - _minimum + _gain) * _y_scale - _y_origin; +} + +void +AudioPlot::plot_peak (wxGraphicsPath& path, int channel) const +{ + path.MoveToPoint (_db_label_width, y_for_linear (_analysis->get_point(channel, 0)[AudioPoint::PEAK])); + + float peak = 0; + int const N = _analysis->points(channel); + for (int i = 0; i < N; ++i) { + float const p = _analysis->get_point(channel, i)[AudioPoint::PEAK]; + peak -= 0.01f * (1 - log10 (_smoothing) / log10 (max_smoothing)); + if (p > peak) { + peak = p; + } else if (peak < 0) { + peak = 0; + } + + path.AddLineToPoint (_db_label_width + i * _x_scale, y_for_linear (peak)); + } +} + +void +AudioPlot::plot_rms (wxGraphicsPath& path, int channel) const +{ + path.MoveToPoint (_db_label_width, y_for_linear (_analysis->get_point(channel, 0)[AudioPoint::RMS])); + + list smoothing; + int const N = _analysis->points(channel); + for (int i = 0; i < N; ++i) { + + smoothing.push_back (_analysis->get_point(channel, i)[AudioPoint::RMS]); + if (int(smoothing.size()) > _smoothing) { + smoothing.pop_front (); + } + + float p = 0; + for (list::const_iterator j = smoothing.begin(); j != smoothing.end(); ++j) { + p += pow (*j, 2); + } + + p = sqrt (p / smoothing.size ()); + + path.AddLineToPoint (_db_label_width + i * _x_scale, y_for_linear (p)); + } +} + void AudioPlot::set_gain (float g) { diff --git a/src/wx/audio_plot.h b/src/wx/audio_plot.h index fe8862d54..7b2955e27 100644 --- a/src/wx/audio_plot.h +++ b/src/wx/audio_plot.h @@ -34,6 +34,8 @@ public: void set_gain (float); void set_smoothing (int); + static const int max_smoothing; + private: void paint (wxPaintEvent &); @@ -43,8 +45,17 @@ private: /** gain to apply in dB */ float _gain; int _smoothing; - std::vector _colours; + void plot_peak (wxGraphicsPath &, int) const; + void plot_rms (wxGraphicsPath &, int) const; + float y_for_linear (float) const; + + double _db_label_width; + int _height; + int _y_origin; + float _x_scale; + float _y_scale; + static const int _minimum; }; -- cgit v1.2.3 From c4a67bdee0eed651e4d99689aed949902af76c45 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 27 Feb 2013 19:51:27 +0000 Subject: Fixes for wx 2.8. --- src/wx/audio_dialog.cc | 4 ++-- src/wx/audio_plot.cc | 12 ++++++++++-- src/wx/film_editor.cc | 2 +- 3 files changed, 13 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/wx/audio_dialog.cc b/src/wx/audio_dialog.cc index b7736f664..34dd268f2 100644 --- a/src/wx/audio_dialog.cc +++ b/src/wx/audio_dialog.cc @@ -40,7 +40,7 @@ AudioDialog::AudioDialog (wxWindow* parent) wxFlexGridSizer* table = new wxFlexGridSizer (2, 6, 6); for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) { - _channel_checkbox[i] = new wxCheckBox (this, wxID_ANY, audio_channel_name (i)); + _channel_checkbox[i] = new wxCheckBox (this, wxID_ANY, std_to_wx (audio_channel_name (i))); table->Add (_channel_checkbox[i], 1, wxEXPAND); table->AddSpacer (0); _channel_checkbox[i]->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (AudioDialog::channel_clicked), 0, this); @@ -88,7 +88,7 @@ AudioDialog::set_film (boost::shared_ptr f) _film_changed_connection = _film->Changed.connect (bind (&AudioDialog::film_changed, this, _1)); _film_audio_analysis_finished_connection = _film->AudioAnalysisFinished.connect (bind (&AudioDialog::try_to_load_analysis, this)); - SetTitle (String::compose ("DVD-o-matic audio - %1", _film->name())); + SetTitle (std_to_wx (String::compose ("DVD-o-matic audio - %1", _film->name()))); } void diff --git a/src/wx/audio_plot.cc b/src/wx/audio_plot.cc index 23cbabcdc..9b2e6b1b0 100644 --- a/src/wx/audio_plot.cc +++ b/src/wx/audio_plot.cc @@ -146,7 +146,11 @@ AudioPlot::paint (wxPaintEvent &) plot_peak (p, c); } wxColour const col = _colours[c]; - gc->SetPen (*wxThePenList->FindOrCreatePen (wxColour (col.Red(), col.Green(), col.Blue(), col.Alpha() / 2))); +#if wxMAJOR_VERSION == 2 && wxMINOR_VERSION >= 9 + gc->SetPen (*wxThePenList->FindOrCreatePen (wxColour (col.Red(), col.Green(), col.Blue(), col.Alpha() / 2), 1, wxPENSTYLE_SOLID)); +#else + gc->SetPen (*wxThePenList->FindOrCreatePen (wxColour (col.Red(), col.Green(), col.Blue(), col.Alpha() / 2), 1, wxSOLID)); +#endif gc->StrokePath (p); } } @@ -158,7 +162,11 @@ AudioPlot::paint (wxPaintEvent &) plot_rms (p, c); } wxColour const col = _colours[c]; - gc->SetPen (*wxThePenList->FindOrCreatePen (col)); +#if wxMAJOR_VERSION == 2 && wxMINOR_VERSION >= 9 + gc->SetPen (*wxThePenList->FindOrCreatePen (col, 1, wxPENSTYLE_SOLID)); +#else + gc->SetPen (*wxThePenList->FindOrCreatePen (col, 1, wxSOLID)); +#endif gc->StrokePath (p); } } diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index c9f83677c..499cb1a43 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -348,7 +348,7 @@ FilmEditor::make_audio_panel () grid->AddSpacer (0); for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) { - add_label_to_sizer (grid, _audio_panel, audio_channel_name (i)); + add_label_to_sizer (grid, _audio_panel, std_to_wx (audio_channel_name (i))); _external_audio[i] = new wxFilePickerCtrl (_audio_panel, wxID_ANY, wxT (""), _("Select Audio File"), wxT ("*.wav")); grid->Add (_external_audio[i], 1, wxEXPAND); } -- cgit v1.2.3 From a2eed42dec7cb76ad787eccaad6ffa800d945e24 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 27 Feb 2013 22:43:00 +0000 Subject: Fix drift in RMS smoothing; plot the centre of the window at its point, rather than the end. --- src/wx/audio_plot.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/wx/audio_plot.cc b/src/wx/audio_plot.cc index 9b2e6b1b0..2098adb40 100644 --- a/src/wx/audio_plot.cc +++ b/src/wx/audio_plot.cc @@ -227,8 +227,9 @@ AudioPlot::plot_rms (wxGraphicsPath& path, int channel) const } p = sqrt (p / smoothing.size ()); - - path.AddLineToPoint (_db_label_width + i * _x_scale, y_for_linear (p)); + + int const ind = max (0, i - int(smoothing.size() / 2)); + path.AddLineToPoint (_db_label_width + ind * _x_scale, y_for_linear (p)); } } -- cgit v1.2.3 From 10a88b600050c1606f46f1fd843c0d0ac071d32f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 28 Feb 2013 00:13:59 +0000 Subject: Tidy up audio dialog layout slightly. --- src/wx/audio_dialog.cc | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/wx/audio_dialog.cc b/src/wx/audio_dialog.cc index 34dd268f2..74586fa13 100644 --- a/src/wx/audio_dialog.cc +++ b/src/wx/audio_dialog.cc @@ -37,18 +37,25 @@ AudioDialog::AudioDialog (wxWindow* parent) _plot = new AudioPlot (this); sizer->Add (_plot, 1, wxALL, 12); - wxFlexGridSizer* table = new wxFlexGridSizer (2, 6, 6); + wxBoxSizer* side = new wxBoxSizer (wxVERTICAL); + + { + wxStaticText* m = new wxStaticText (this, wxID_ANY, _("Channels")); + side->Add (m, 1, wxALIGN_CENTER_VERTICAL | wxTOP, 16); + } + for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) { _channel_checkbox[i] = new wxCheckBox (this, wxID_ANY, std_to_wx (audio_channel_name (i))); - table->Add (_channel_checkbox[i], 1, wxEXPAND); - table->AddSpacer (0); + side->Add (_channel_checkbox[i], 1, wxEXPAND | wxALL, 3); _channel_checkbox[i]->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (AudioDialog::channel_clicked), 0, this); } - table->AddSpacer (0); - table->AddSpacer (0); - + { + wxStaticText* m = new wxStaticText (this, wxID_ANY, _("Type")); + side->Add (m, 1, wxALIGN_CENTER_VERTICAL | wxTOP, 16); + } + wxString const types[] = { _("Peak"), _("RMS") @@ -56,17 +63,20 @@ AudioDialog::AudioDialog (wxWindow* parent) for (int i = 0; i < AudioPoint::COUNT; ++i) { _type_checkbox[i] = new wxCheckBox (this, wxID_ANY, types[i]); - table->Add (_type_checkbox[i], 1, wxEXPAND); - table->AddSpacer (0); + side->Add (_type_checkbox[i], 1, wxEXPAND | wxALL, 3); _type_checkbox[i]->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (AudioDialog::type_clicked), 0, this); } + { + wxStaticText* m = new wxStaticText (this, wxID_ANY, _("Smoothing")); + side->Add (m, 1, wxALIGN_CENTER_VERTICAL | wxTOP, 16); + } + _smoothing = new wxSlider (this, wxID_ANY, AudioPlot::max_smoothing / 2, 1, AudioPlot::max_smoothing); _smoothing->Connect (wxID_ANY, wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler (AudioDialog::smoothing_changed), 0, this); - table->Add (_smoothing, 1, wxEXPAND); - table->AddSpacer (0); + side->Add (_smoothing, 1, wxEXPAND); - sizer->Add (table, 0, wxALL, 12); + sizer->Add (side, 0, wxALL, 12); SetSizer (sizer); sizer->Layout (); -- cgit v1.2.3 From 0d3f5aae5b99832b7c5d55f32f5bccb365caa3fd Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 28 Feb 2013 22:20:07 +0000 Subject: Various markup and tweaks. --- TRANSLATORS | 2 +- i18n.py | 10 +- run/dvdomatic | 3 + src/lib/ab_transcode_job.cc | 4 +- src/lib/config.cc | 54 ++++---- src/lib/dci_metadata.cc | 30 ++-- src/lib/dcp_content_type.cc | 22 +-- src/lib/dcp_video_frame.cc | 62 +++++---- src/lib/decoder.cc | 6 +- src/lib/dolby_cp750.cc | 4 +- src/lib/encoder.cc | 44 +++--- src/lib/examine_content_job.cc | 10 +- src/lib/external_audio_decoder.cc | 12 +- src/lib/ffmpeg_compatibility.cc | 10 +- src/lib/ffmpeg_decoder.cc | 50 +++---- src/lib/film.cc | 284 +++++++++++++++++++------------------- src/lib/filter.cc | 54 ++++---- src/lib/filter_graph.cc | 48 ++++--- src/lib/format.cc | 35 ++--- src/lib/image.cc | 8 +- src/lib/imagemagick_decoder.cc | 4 +- src/lib/job.cc | 23 +-- src/lib/log.cc | 12 +- src/lib/matcher.cc | 10 +- src/lib/scaler.cc | 20 +-- src/lib/scp_dcp_job.cc | 36 ++--- src/lib/server.cc | 44 +++--- src/lib/stream.cc | 4 +- src/lib/subtitle.cc | 6 +- src/lib/timer.cc | 10 +- src/lib/transcode_job.cc | 14 +- src/lib/util.cc | 80 ++++++----- src/lib/video_decoder.cc | 4 +- src/lib/writer.cc | 28 ++-- src/tools/dvdomatic.cc | 10 +- src/wx/config_dialog.cc | 4 +- src/wx/film_editor.cc | 23 ++- src/wx/film_viewer.cc | 2 +- src/wx/properties_dialog.cc | 2 +- src/wx/server_dialog.cc | 2 +- wscript | 4 +- 41 files changed, 580 insertions(+), 514 deletions(-) (limited to 'src') diff --git a/TRANSLATORS b/TRANSLATORS index cbfc875d4..625b03613 100644 --- a/TRANSLATORS +++ b/TRANSLATORS @@ -1,7 +1,7 @@ Translating DVD-o-matic ----------------------- -1. Run ./waf po +1. Run ./waf pot This will generate build/src/lib/dvdomatic.pot and build/src/wx/libdvdomatic-wx.pot. diff --git a/i18n.py b/i18n.py index 10eaa38e9..c22cbdb95 100644 --- a/i18n.py +++ b/i18n.py @@ -2,15 +2,19 @@ import glob import os from waflib import Logs -def pot(dir, sources, name): +def pot(dir, sources, name, all = False): s = "" for f in sources.split('\n'): t = f.strip() if len(t) > 0: s += (os.path.join(dir, t)) + " " - Logs.info('Making %s.pot' % os.path.join('build', dir, name)) - os.system('xgettext -d %s -s --keyword=_ -p %s -o %s.pot %s' % (name, os.path.join('build', dir), name, s)) + if all: + Logs.info('Making %s.pot (extracting all)' % os.path.join('build', dir, name)) + os.system('xgettext -d %s -s --extract-all -p %s -o %s.pot %s' % (name, os.path.join('build', dir), name, s)) + else: + Logs.info('Making %s.pot' % os.path.join('build', dir, name)) + os.system('xgettext -d %s -s --keyword=_ --add-comments=/ -p %s -o %s.pot %s' % (name, os.path.join('build', dir), name, s)) def po_to_mo(dir, name): diff --git a/run/dvdomatic b/run/dvdomatic index ff3897064..31fd09fb9 100755 --- a/run/dvdomatic +++ b/run/dvdomatic @@ -7,6 +7,9 @@ if [ "$1" == "--debug" ]; then elif [ "$1" == "--valgrind" ]; then shift valgrind --tool="memcheck" build/src/tools/dvdomatic $* +elif [ "$1" == "--i18n" ]; then + shift + LANG=fr_FR.UTF8 build/src/tools/dvdomatic "$*" else build/src/tools/dvdomatic "$*" fi diff --git a/src/lib/ab_transcode_job.cc b/src/lib/ab_transcode_job.cc index 025c23c86..4ffdd9af6 100644 --- a/src/lib/ab_transcode_job.cc +++ b/src/lib/ab_transcode_job.cc @@ -26,6 +26,8 @@ #include "config.h" #include "encoder.h" +#include "i18n.h" + using std::string; using boost::shared_ptr; @@ -44,7 +46,7 @@ ABTranscodeJob::ABTranscodeJob (shared_ptr f, DecodeOptions o) string ABTranscodeJob::name () const { - return String::compose ("A/B transcode %1", _film->name()); + return String::compose (_("A/B transcode %1"), _film->name()); } void diff --git a/src/lib/config.cc b/src/lib/config.cc index c165859b0..82a31b3cf 100644 --- a/src/lib/config.cc +++ b/src/lib/config.cc @@ -28,6 +28,8 @@ #include "filter.h" #include "sound_processor.h" +#include "i18n.h" + using std::vector; using std::ifstream; using std::string; @@ -40,9 +42,9 @@ Config* Config::_instance = 0; Config::Config () : _num_local_encoding_threads (2) , _server_port (6192) - , _reference_scaler (Scaler::from_id ("bicubic")) - , _tms_path (".") - , _sound_processor (SoundProcessor::from_id ("dolby_cp750")) + , _reference_scaler (Scaler::from_id (N_("bicubic"))) + , _tms_path (N_(".")) + , _sound_processor (SoundProcessor::from_id (N_("dolby_cp750"))) { _allowed_dcp_frame_rates.push_back (24); _allowed_dcp_frame_rates.push_back (25); @@ -67,27 +69,27 @@ Config::Config () string const k = line.substr (0, s); string const v = line.substr (s + 1); - if (k == "num_local_encoding_threads") { + if (k == N_("num_local_encoding_threads")) { _num_local_encoding_threads = atoi (v.c_str ()); - } else if (k == "default_directory") { + } else if (k == N_("default_directory")) { _default_directory = v; - } else if (k == "server_port") { + } else if (k == N_("server_port")) { _server_port = atoi (v.c_str ()); - } else if (k == "reference_scaler") { + } else if (k == N_("reference_scaler")) { _reference_scaler = Scaler::from_id (v); - } else if (k == "reference_filter") { + } else if (k == N_("reference_filter")) { _reference_filters.push_back (Filter::from_id (v)); - } else if (k == "server") { + } else if (k == N_("server")) { _servers.push_back (ServerDescription::create_from_metadata (v)); - } else if (k == "tms_ip") { + } else if (k == N_("tms_ip")) { _tms_ip = v; - } else if (k == "tms_path") { + } else if (k == N_("tms_path")) { _tms_path = v; - } else if (k == "tms_user") { + } else if (k == N_("tms_user")) { _tms_user = v; - } else if (k == "tms_password") { + } else if (k == N_("tms_password")) { _tms_password = v; - } else if (k == "sound_processor") { + } else if (k == N_("sound_processor")) { _sound_processor = SoundProcessor::from_id (v); } @@ -101,7 +103,7 @@ Config::file () const { boost::filesystem::path p; p /= g_get_user_config_dir (); - p /= ".dvdomatic"; + p /= N_(".dvdomatic"); return p.string (); } @@ -121,24 +123,24 @@ void Config::write () const { ofstream f (file().c_str ()); - f << "num_local_encoding_threads " << _num_local_encoding_threads << "\n" - << "default_directory " << _default_directory << "\n" - << "server_port " << _server_port << "\n" - << "reference_scaler " << _reference_scaler->id () << "\n"; + f << N_("num_local_encoding_threads ") << _num_local_encoding_threads << N_("\n") + << N_("default_directory ") << _default_directory << N_("\n") + << N_("server_port ") << _server_port << N_("\n") + << N_("reference_scaler ") << _reference_scaler->id () << N_("\n"); for (vector::const_iterator i = _reference_filters.begin(); i != _reference_filters.end(); ++i) { - f << "reference_filter " << (*i)->id () << "\n"; + f << N_("reference_filter ") << (*i)->id () << N_("\n"); } for (vector::const_iterator i = _servers.begin(); i != _servers.end(); ++i) { - f << "server " << (*i)->as_metadata () << "\n"; + f << N_("server ") << (*i)->as_metadata () << N_("\n"); } - f << "tms_ip " << _tms_ip << "\n"; - f << "tms_path " << _tms_path << "\n"; - f << "tms_user " << _tms_user << "\n"; - f << "tms_password " << _tms_password << "\n"; - f << "sound_processor " << _sound_processor->id () << "\n"; + f << N_("tms_ip ") << _tms_ip << N_("\n"); + f << N_("tms_path ") << _tms_path << N_("\n"); + f << N_("tms_user ") << _tms_user << N_("\n"); + f << N_("tms_password ") << _tms_password << N_("\n"); + f << N_("sound_processor ") << _sound_processor->id () << N_("\n"); _default_dci_metadata.write (f); } diff --git a/src/lib/dci_metadata.cc b/src/lib/dci_metadata.cc index 2b4cc3ae7..758886db4 100644 --- a/src/lib/dci_metadata.cc +++ b/src/lib/dci_metadata.cc @@ -20,36 +20,38 @@ #include #include "dci_metadata.h" +#include "i18n.h" + using namespace std; void DCIMetadata::write (ostream& f) const { - f << "audio_language " << audio_language << "\n"; - f << "subtitle_language " << subtitle_language << "\n"; - f << "territory " << territory << "\n"; - f << "rating " << rating << "\n"; - f << "studio " << studio << "\n"; - f << "facility " << facility << "\n"; - f << "package_type " << package_type << "\n"; + f << N_("audio_language ") << audio_language << N_("\n"); + f << N_("subtitle_language ") << subtitle_language << N_("\n"); + f << N_("territory ") << territory << N_("\n"); + f << N_("rating ") << rating << N_("\n"); + f << N_("studio ") << studio << N_("\n"); + f << N_("facility ") << facility << N_("\n"); + f << N_("package_type ") << package_type << N_("\n"); } void DCIMetadata::read (string k, string v) { - if (k == "audio_language") { + if (k == N_("audio_language")) { audio_language = v; - } else if (k == "subtitle_language") { + } else if (k == N_("subtitle_language")) { subtitle_language = v; - } else if (k == "territory") { + } else if (k == N_("territory")) { territory = v; - } else if (k == "rating") { + } else if (k == N_("rating")) { rating = v; - } else if (k == "studio") { + } else if (k == N_("studio")) { studio = v; - } else if (k == "facility") { + } else if (k == N_("facility")) { facility = v; - } else if (k == "package_type") { + } else if (k == N_("package_type")) { package_type = v; } } diff --git a/src/lib/dcp_content_type.cc b/src/lib/dcp_content_type.cc index 1c96979e4..82bd5fa01 100644 --- a/src/lib/dcp_content_type.cc +++ b/src/lib/dcp_content_type.cc @@ -24,6 +24,8 @@ #include #include "dcp_content_type.h" +#include "i18n.h" + using namespace std; vector DCPContentType::_dcp_content_types; @@ -39,16 +41,16 @@ DCPContentType::DCPContentType (string p, libdcp::ContentKind k, string d) void DCPContentType::setup_dcp_content_types () { - _dcp_content_types.push_back (new DCPContentType ("Feature", libdcp::FEATURE, "FTR")); - _dcp_content_types.push_back (new DCPContentType ("Short", libdcp::SHORT, "SHR")); - _dcp_content_types.push_back (new DCPContentType ("Trailer", libdcp::TRAILER, "TLR")); - _dcp_content_types.push_back (new DCPContentType ("Test", libdcp::TEST, "TST")); - _dcp_content_types.push_back (new DCPContentType ("Transitional", libdcp::TRANSITIONAL, "XSN")); - _dcp_content_types.push_back (new DCPContentType ("Rating", libdcp::RATING, "RTG")); - _dcp_content_types.push_back (new DCPContentType ("Teaser", libdcp::TEASER, "TSR")); - _dcp_content_types.push_back (new DCPContentType ("Policy", libdcp::POLICY, "POL")); - _dcp_content_types.push_back (new DCPContentType ("Public Service Announcement", libdcp::PUBLIC_SERVICE_ANNOUNCEMENT, "PSA")); - _dcp_content_types.push_back (new DCPContentType ("Advertisement", libdcp::ADVERTISEMENT, "ADV")); + _dcp_content_types.push_back (new DCPContentType (_("Feature"), libdcp::FEATURE, N_("FTR"))); + _dcp_content_types.push_back (new DCPContentType (_("Short"), libdcp::SHORT, N_("SHR"))); + _dcp_content_types.push_back (new DCPContentType (_("Trailer"), libdcp::TRAILER, N_("TLR"))); + _dcp_content_types.push_back (new DCPContentType (_("Test"), libdcp::TEST, N_("TST"))); + _dcp_content_types.push_back (new DCPContentType (_("Transitional"), libdcp::TRANSITIONAL, N_("XSN"))); + _dcp_content_types.push_back (new DCPContentType (_("Rating"), libdcp::RATING, N_("RTG"))); + _dcp_content_types.push_back (new DCPContentType (_("Teaser"), libdcp::TEASER, N_("TSR"))); + _dcp_content_types.push_back (new DCPContentType (_("Policy"), libdcp::POLICY, N_("POL"))); + _dcp_content_types.push_back (new DCPContentType (_("Public Service Announcement"), libdcp::PUBLIC_SERVICE_ANNOUNCEMENT, N_("PSA"))); + _dcp_content_types.push_back (new DCPContentType (_("Advertisement"), libdcp::ADVERTISEMENT, N_("ADV"))); } DCPContentType const * diff --git a/src/lib/dcp_video_frame.cc b/src/lib/dcp_video_frame.cc index 9b96724b0..098d222cd 100644 --- a/src/lib/dcp_video_frame.cc +++ b/src/lib/dcp_video_frame.cc @@ -56,6 +56,8 @@ #include "log.h" #include "subtitle.h" +#include "i18n.h" + using std::string; using std::stringstream; using std::ofstream; @@ -119,7 +121,7 @@ DCPVideoFrame::create_openjpeg_container () _image = opj_image_create (3, &_cmptparm[0], CLRSPC_SRGB); if (_image == 0) { - throw EncodeError ("could not create libopenjpeg image"); + throw EncodeError (N_("could not create libopenjpeg image")); } _image->x0 = 0; @@ -265,7 +267,7 @@ DCPVideoFrame::encode_locally () _parameters->tcp_numlayers++; _parameters->cp_disto_alloc = 1; _parameters->cp_rsiz = CINEMA2K; - _parameters->cp_comment = strdup ("DVD-o-matic"); + _parameters->cp_comment = strdup (N_("DVD-o-matic")); _parameters->cp_cinema = CINEMA2K_24; /* 3 components, so use MCT */ @@ -278,7 +280,7 @@ DCPVideoFrame::encode_locally () /* get a J2K compressor handle */ _cinfo = opj_create_compress (CODEC_J2K); if (_cinfo == 0) { - throw EncodeError ("could not create JPEG2000 encoder"); + throw EncodeError (N_("could not create JPEG2000 encoder")); } /* Set event manager to null (openjpeg 1.3 bug) */ @@ -289,15 +291,15 @@ DCPVideoFrame::encode_locally () _cio = opj_cio_open ((opj_common_ptr) _cinfo, 0, 0); if (_cio == 0) { - throw EncodeError ("could not open JPEG2000 stream"); + throw EncodeError (N_("could not open JPEG2000 stream")); } int const r = opj_encode (_cinfo, _cio, _image, 0); if (r == 0) { - throw EncodeError ("JPEG2000 encoding failed"); + throw EncodeError (N_("JPEG2000 encoding failed")); } - _log->log (String::compose ("Finished locally-encoded frame %1", _frame)); + _log->log (String::compose (N_("Finished locally-encoded frame %1"), _frame)); return shared_ptr (new LocallyEncodedData (_cio->buffer, cio_tell (_cio))); } @@ -319,35 +321,35 @@ DCPVideoFrame::encode_remotely (ServerDescription const * serv) socket->connect (*endpoint_iterator); stringstream s; - s << "encode please\n" - << "input_width " << _input->size().width << "\n" - << "input_height " << _input->size().height << "\n" - << "input_pixel_format " << _input->pixel_format() << "\n" - << "output_width " << _out_size.width << "\n" - << "output_height " << _out_size.height << "\n" - << "padding " << _padding << "\n" - << "subtitle_offset " << _subtitle_offset << "\n" - << "subtitle_scale " << _subtitle_scale << "\n" - << "scaler " << _scaler->id () << "\n" - << "frame " << _frame << "\n" - << "frames_per_second " << _frames_per_second << "\n"; + s << N_("encode please\n") + << N_("input_width ") << _input->size().width << N_("\n") + << N_("input_height ") << _input->size().height << N_("\n") + << N_("input_pixel_format ") << _input->pixel_format() << N_("\n") + << N_("output_width ") << _out_size.width << N_("\n") + << N_("output_height ") << _out_size.height << N_("\n") + << N_("padding ") << _padding << N_("\n") + << N_("subtitle_offset ") << _subtitle_offset << N_("\n") + << N_("subtitle_scale ") << _subtitle_scale << N_("\n") + << N_("scaler ") << _scaler->id () << N_("\n") + << N_("frame ") << _frame << N_("\n") + << N_("frames_per_second ") << _frames_per_second << N_("\n"); if (!_post_process.empty()) { - s << "post_process " << _post_process << "\n"; + s << N_("post_process ") << _post_process << N_("\n"); } - s << "colour_lut " << _colour_lut << "\n" - << "j2k_bandwidth " << _j2k_bandwidth << "\n"; + s << N_("colour_lut ") << _colour_lut << N_("\n") + << N_("j2k_bandwidth ") << _j2k_bandwidth << N_("\n"); if (_subtitle) { - s << "subtitle_x " << _subtitle->position().x << "\n" - << "subtitle_y " << _subtitle->position().y << "\n" - << "subtitle_width " << _subtitle->image()->size().width << "\n" - << "subtitle_height " << _subtitle->image()->size().height << "\n"; + s << N_("subtitle_x ") << _subtitle->position().x << N_("\n") + << N_("subtitle_y ") << _subtitle->position().y << N_("\n") + << N_("subtitle_width ") << _subtitle->image()->size().width << N_("\n") + << N_("subtitle_height ") << _subtitle->image()->size().height << N_("\n"); } _log->log (String::compose ( - "Sending to remote; pixel format %1, components %2, lines (%3,%4,%5), line sizes (%6,%7,%8)", + N_("Sending to remote; pixel format %1, components %2, lines (%3,%4,%5), line sizes (%6,%7,%8)"), _input->pixel_format(), _input->components(), _input->lines(0), _input->lines(1), _input->lines(2), _input->line_size()[0], _input->line_size()[1], _input->line_size()[2] @@ -364,7 +366,7 @@ DCPVideoFrame::encode_remotely (ServerDescription const * serv) shared_ptr e (new RemotelyEncodedData (socket->read_uint32 ())); socket->read (e->data(), e->size()); - _log->log (String::compose ("Finished remotely-encoded frame %1", _frame)); + _log->log (String::compose (N_("Finished remotely-encoded frame %1"), _frame)); return e; } @@ -381,9 +383,9 @@ EncodedData::EncodedData (string file) _size = boost::filesystem::file_size (file); _data = new uint8_t[_size]; - FILE* f = fopen (file.c_str(), "rb"); + FILE* f = fopen (file.c_str(), N_("rb")); if (!f) { - throw FileError ("could not open file for reading", file); + throw FileError (_("could not open file for reading"), file); } fread (_data, 1, _size, f); @@ -405,7 +407,7 @@ EncodedData::write (shared_ptr film, int frame) const { string const tmp_j2c = film->j2c_path (frame, true); - FILE* f = fopen (tmp_j2c.c_str (), "wb"); + FILE* f = fopen (tmp_j2c.c_str (), N_("wb")); if (!f) { throw WriteFileError (tmp_j2c, errno); diff --git a/src/lib/decoder.cc b/src/lib/decoder.cc index 30009460f..52b22fa06 100644 --- a/src/lib/decoder.cc +++ b/src/lib/decoder.cc @@ -36,6 +36,8 @@ #include "subtitle.h" #include "filter_graph.h" +#include "i18n.h" + using std::string; using std::stringstream; using std::min; @@ -60,7 +62,7 @@ Decoder::Decoder (boost::shared_ptr f, DecodeOptions o) bool Decoder::seek (double) { - throw DecodeError ("decoder does not support seek"); + throw DecodeError (N_("decoder does not support seek")); } /** Seek so that the next frame we will produce is the same as the last one. @@ -69,5 +71,5 @@ Decoder::seek (double) bool Decoder::seek_to_last () { - throw DecodeError ("decoder does not support seek"); + throw DecodeError (N_("decoder does not support seek")); } diff --git a/src/lib/dolby_cp750.cc b/src/lib/dolby_cp750.cc index 262e57bc7..b45e62b87 100644 --- a/src/lib/dolby_cp750.cc +++ b/src/lib/dolby_cp750.cc @@ -19,10 +19,12 @@ #include "dolby_cp750.h" +#include "i18n.h" + using namespace std; DolbyCP750::DolbyCP750 () - : SoundProcessor ("dolby_cp750", "Dolby CP750") + : SoundProcessor ("dolby_cp750", _("Dolby CP750")) { } diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index f25256379..d4a27d01b 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -39,6 +39,8 @@ #include "cross.h" #include "writer.h" +#include "i18n.h" + using std::pair; using std::string; using std::stringstream; @@ -79,7 +81,7 @@ Encoder::process_begin () #ifdef HAVE_SWRESAMPLE stringstream s; - s << "Will resample audio from " << _film->audio_stream()->sample_rate() << " to " << _film->target_audio_sample_rate(); + s << String::compose (N_("Will resample audio from %1 to %2"), _film->audio_stream()->sample_rate(), _film->target_audio_sample_rate()); _film->log()->log (s.str ()); /* We will be using planar float data when we call the resampler */ @@ -96,7 +98,7 @@ Encoder::process_begin () swr_init (_swr_context); #else - throw EncodeError ("Cannot resample audio as libswresample is not present"); + throw EncodeError (_("Cannot resample audio as libswresample is not present")); #endif } else { #ifdef HAVE_SWRESAMPLE @@ -132,7 +134,7 @@ Encoder::process_end () int const frames = swr_convert (_swr_context, (uint8_t **) out->data(), 256, 0, 0); if (frames < 0) { - throw EncodeError ("could not run sample-rate converter"); + throw EncodeError (_("could not run sample-rate converter")); } if (frames == 0) { @@ -149,11 +151,11 @@ Encoder::process_end () boost::mutex::scoped_lock lock (_mutex); - _film->log()->log ("Clearing queue of " + lexical_cast (_queue.size ())); + _film->log()->log (String::compose (N_("Clearing queue of %1"), _queue.size ())); /* Keep waking workers until the queue is empty */ while (!_queue.empty ()) { - _film->log()->log ("Waking with " + lexical_cast (_queue.size ()), Log::VERBOSE); + _film->log()->log (String::compose (N_("Waking with %1"), _queue.size ()), Log::VERBOSE); _condition.notify_all (); _condition.wait (lock); } @@ -162,7 +164,7 @@ Encoder::process_end () terminate_threads (); - _film->log()->log ("Mopping up " + lexical_cast (_queue.size())); + _film->log()->log (String::compose (N_("Mopping up %1"), _queue.size())); /* The following sequence of events can occur in the above code: 1. a remote worker takes the last image off the queue @@ -174,12 +176,12 @@ Encoder::process_end () */ for (list >::iterator i = _queue.begin(); i != _queue.end(); ++i) { - _film->log()->log (String::compose ("Encode left-over frame %1", (*i)->frame ())); + _film->log()->log (String::compose (N_("Encode left-over frame %1"), (*i)->frame ())); try { _writer->write ((*i)->encode_locally(), (*i)->frame ()); frame_done (); } catch (std::exception& e) { - _film->log()->log (String::compose ("Local encode failed (%1)", e.what ())); + _film->log()->log (String::compose (N_("Local encode failed (%1)"), e.what ())); } } @@ -242,9 +244,9 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptr= _threads.size() * 2 && !_terminate) { - TIMING ("decoder sleeps with queue of %1", _queue.size()); + TIMING (_("decoder sleeps with queue of %1"), _queue.size()); _condition.wait (lock); - TIMING ("decoder wakes with queue of %1", _queue.size()); + TIMING (_("decoder wakes with queue of %1"), _queue.size()); } if (_terminate) { @@ -266,7 +268,7 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptr const s = Filter::ffmpeg_strings (_film->filters()); - TIMING ("adding to queue of %1", _queue.size ()); + TIMING (_("adding to queue of %1"), _queue.size ()); _queue.push_back (boost::shared_ptr ( new DCPVideoFrame ( image, sub, _film->format()->dcp_size(), _film->format()->dcp_padding (_film), @@ -309,7 +311,7 @@ Encoder::process_audio (shared_ptr data) ); if (resampled_frames < 0) { - throw EncodeError ("could not run sample-rate converter"); + throw EncodeError (_("could not run sample-rate converter")); } resampled->set_frames (resampled_frames); @@ -347,7 +349,7 @@ Encoder::encoder_thread (ServerDescription* server) while (1) { - TIMING ("encoder thread %1 sleeps", boost::this_thread::get_id()); + TIMING (N_("encoder thread %1 sleeps"), boost::this_thread::get_id()); boost::mutex::scoped_lock lock (_mutex); while (_queue.empty () && !_terminate) { _condition.wait (lock); @@ -357,9 +359,9 @@ Encoder::encoder_thread (ServerDescription* server) return; } - TIMING ("encoder thread %1 wakes with queue of %2", boost::this_thread::get_id(), _queue.size()); + TIMING (N_("encoder thread %1 wakes with queue of %2"), boost::this_thread::get_id(), _queue.size()); boost::shared_ptr vf = _queue.front (); - _film->log()->log (String::compose ("Encoder thread %1 pops frame %2 from queue", boost::this_thread::get_id(), vf->frame()), Log::VERBOSE); + _film->log()->log (String::compose (N_("Encoder thread %1 pops frame %2 from queue"), boost::this_thread::get_id(), vf->frame()), Log::VERBOSE); _queue.pop_front (); lock.unlock (); @@ -371,7 +373,7 @@ Encoder::encoder_thread (ServerDescription* server) encoded = vf->encode_remotely (server); if (remote_backoff > 0) { - _film->log()->log (String::compose ("%1 was lost, but now she is found; removing backoff", server->host_name ())); + _film->log()->log (String::compose (N_("%1 was lost, but now she is found; removing backoff"), server->host_name ())); } /* This job succeeded, so remove any backoff */ @@ -384,18 +386,18 @@ Encoder::encoder_thread (ServerDescription* server) } _film->log()->log ( String::compose ( - "Remote encode of %1 on %2 failed (%3); thread sleeping for %4s", + N_("Remote encode of %1 on %2 failed (%3); thread sleeping for %4s"), vf->frame(), server->host_name(), e.what(), remote_backoff) ); } } else { try { - TIMING ("encoder thread %1 begins local encode of %2", boost::this_thread::get_id(), vf->frame()); + TIMING (N_("encoder thread %1 begins local encode of %2"), boost::this_thread::get_id(), vf->frame()); encoded = vf->encode_locally (); - TIMING ("encoder thread %1 finishes local encode of %2", boost::this_thread::get_id(), vf->frame()); + TIMING (N_("encoder thread %1 finishes local encode of %2"), boost::this_thread::get_id(), vf->frame()); } catch (std::exception& e) { - _film->log()->log (String::compose ("Local encode failed (%1)", e.what ())); + _film->log()->log (String::compose (N_("Local encode failed (%1)"), e.what ())); } } @@ -405,7 +407,7 @@ Encoder::encoder_thread (ServerDescription* server) } else { lock.lock (); _film->log()->log ( - String::compose ("Encoder thread %1 pushes frame %2 back onto queue after failure", boost::this_thread::get_id(), vf->frame()) + String::compose (N_("Encoder thread %1 pushes frame %2 back onto queue after failure"), boost::this_thread::get_id(), vf->frame()) ); _queue.push_front (vf); lock.unlock (); diff --git a/src/lib/examine_content_job.cc b/src/lib/examine_content_job.cc index 31d76c4f7..4b30c9431 100644 --- a/src/lib/examine_content_job.cc +++ b/src/lib/examine_content_job.cc @@ -31,6 +31,8 @@ #include "film.h" #include "video_decoder.h" +#include "i18n.h" + using std::string; using std::vector; using std::pair; @@ -50,10 +52,10 @@ string ExamineContentJob::name () const { if (_film->name().empty ()) { - return "Examine content"; + return _("Examine content"); } - return String::compose ("Examine content of %1", _film->name()); + return String::compose (_("Examine content of %1"), _film->name()); } void @@ -90,7 +92,7 @@ ExamineContentJob::run () _film->set_length (decoders.video->video_frame()); - _film->log()->log (String::compose ("Video length examined as %1 frames", _film->length().get())); + _film->log()->log (String::compose (N_("Video length examined as %1 frames"), _film->length().get())); } else { @@ -99,7 +101,7 @@ ExamineContentJob::run () Decoders d = decoder_factory (_film, DecodeOptions()); _film->set_length (d.video->length()); - _film->log()->log (String::compose ("Video length obtained from header as %1 frames", _film->length().get())); + _film->log()->log (String::compose (N_("Video length obtained from header as %1 frames"), _film->length().get())); } ascend (); diff --git a/src/lib/external_audio_decoder.cc b/src/lib/external_audio_decoder.cc index 9c01bfb34..1248b5a3b 100644 --- a/src/lib/external_audio_decoder.cc +++ b/src/lib/external_audio_decoder.cc @@ -23,6 +23,8 @@ #include "film.h" #include "exceptions.h" +#include "i18n.h" + using std::vector; using std::string; using std::stringstream; @@ -67,11 +69,11 @@ ExternalAudioDecoder::open_files (sf_count_t & frames) SF_INFO info; SNDFILE* s = sf_open (files[i].c_str(), SFM_READ, &info); if (!s) { - throw DecodeError ("could not open external audio file for reading"); + throw DecodeError (_("could not open external audio file for reading")); } if (info.channels != 1) { - throw DecodeError ("external audio files must be mono"); + throw DecodeError (_("external audio files must be mono")); } sndfiles.push_back (s); @@ -89,7 +91,7 @@ ExternalAudioDecoder::open_files (sf_count_t & frames) first = false; } else { if (info.frames != frames) { - throw DecodeError ("external audio files have differing lengths"); + throw DecodeError (_("external audio files have differing lengths")); } } } @@ -158,7 +160,7 @@ ExternalAudioStream::create (string t, optional v) stringstream s (t); string type; s >> type; - if (type != "external") { + if (type != N_("external")) { return shared_ptr (); } @@ -182,5 +184,5 @@ ExternalAudioStream::ExternalAudioStream () string ExternalAudioStream::to_string () const { - return String::compose ("external %1 %2", _sample_rate, _channel_layout); + return String::compose (N_("external %1 %2"), _sample_rate, _channel_layout); } diff --git a/src/lib/ffmpeg_compatibility.cc b/src/lib/ffmpeg_compatibility.cc index 09f9276ac..361fa7423 100644 --- a/src/lib/ffmpeg_compatibility.cc +++ b/src/lib/ffmpeg_compatibility.cc @@ -22,6 +22,8 @@ extern "C" { } #include "exceptions.h" +#include "i18n.h" + #if LIBAVFILTER_VERSION_MAJOR == 2 && LIBAVFILTER_VERSION_MINOR == 15 typedef struct { @@ -67,13 +69,13 @@ get_sink () #if LIBAVFILTER_VERSION_MAJOR == 2 && LIBAVFILTER_VERSION_MINOR == 15 /* XXX does this leak stuff? */ AVFilter* buffer_sink = new AVFilter; - buffer_sink->name = av_strdup ("avsink"); + buffer_sink->name = av_strdup (N_("avsink")); buffer_sink->priv_size = sizeof (AVSinkContext); buffer_sink->init = avsink_init; buffer_sink->query_formats = avsink_query_formats; buffer_sink->inputs = new AVFilterPad[2]; AVFilterPad* i0 = const_cast (&buffer_sink->inputs[0]); - i0->name = "default"; + i0->name = N_("default"); i0->type = AVMEDIA_TYPE_VIDEO; i0->min_perms = AV_PERM_READ; i0->rej_perms = 0; @@ -91,9 +93,9 @@ get_sink () const_cast (&buffer_sink->outputs[0])->name = 0; return buffer_sink; #else - AVFilter* buffer_sink = avfilter_get_by_name("buffersink"); + AVFilter* buffer_sink = avfilter_get_by_name(N_("buffersink")); if (buffer_sink == 0) { - throw DecodeError ("Could not create buffer sink filter"); + throw DecodeError (N_("Could not create buffer sink filter")); } return buffer_sink; diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index d4ed76e37..8834f28ed 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -50,6 +50,8 @@ extern "C" { #include "filter_graph.h" #include "subtitle.h" +#include "i18n.h" + using std::cout; using std::string; using std::vector; @@ -113,7 +115,7 @@ FFmpegDecoder::setup_general () } if (avformat_find_stream_info (_format_context, 0) < 0) { - throw DecodeError ("could not find stream information"); + throw DecodeError (_("could not find stream information")); } /* Find video, audio and subtitle streams and choose the first of each */ @@ -148,12 +150,12 @@ FFmpegDecoder::setup_general () } if (_video_stream < 0) { - throw DecodeError ("could not find video stream"); + throw DecodeError (N_("could not find video stream")); } _frame = avcodec_alloc_frame (); if (_frame == 0) { - throw DecodeError ("could not allocate frame"); + throw DecodeError (N_("could not allocate frame")); } } @@ -164,11 +166,11 @@ FFmpegDecoder::setup_video () _video_codec = avcodec_find_decoder (_video_codec_context->codec_id); if (_video_codec == 0) { - throw DecodeError ("could not find video decoder"); + throw DecodeError (_("could not find video decoder")); } if (avcodec_open2 (_video_codec_context, _video_codec, 0) < 0) { - throw DecodeError ("could not open video decoder"); + throw DecodeError (N_("could not open video decoder")); } } @@ -186,11 +188,11 @@ FFmpegDecoder::setup_audio () _audio_codec = avcodec_find_decoder (_audio_codec_context->codec_id); if (_audio_codec == 0) { - throw DecodeError ("could not find audio decoder"); + throw DecodeError (_("could not find audio decoder")); } if (avcodec_open2 (_audio_codec_context, _audio_codec, 0) < 0) { - throw DecodeError ("could not open audio decoder"); + throw DecodeError (N_("could not open audio decoder")); } } @@ -205,11 +207,11 @@ FFmpegDecoder::setup_subtitle () _subtitle_codec = avcodec_find_decoder (_subtitle_codec_context->codec_id); if (_subtitle_codec == 0) { - throw DecodeError ("could not find subtitle decoder"); + throw DecodeError (_("could not find subtitle decoder")); } if (avcodec_open2 (_subtitle_codec_context, _subtitle_codec, 0) < 0) { - throw DecodeError ("could not open subtitle decoder"); + throw DecodeError (N_("could not open subtitle decoder")); } } @@ -224,7 +226,7 @@ FFmpegDecoder::pass () /* Maybe we should fail here, but for now we'll just finish off instead */ char buf[256]; av_strerror (r, buf, sizeof(buf)); - _film->log()->log (String::compose ("error on av_read_frame (%1) (%2)", buf, r)); + _film->log()->log (String::compose (N_("error on av_read_frame (%1) (%2)"), buf, r)); } /* Get any remaining frames */ @@ -265,7 +267,7 @@ FFmpegDecoder::pass () if (r >= 0 && frame_finished) { if (r != _packet.size) { - _film->log()->log (String::compose ("Used only %1 bytes of %2 in packet", r, _packet.size)); + _film->log()->log (String::compose (N_("Used only %1 bytes of %2 in packet"), r, _packet.size)); } if (_opt.video_sync) { @@ -303,7 +305,7 @@ FFmpegDecoder::pass () _film->log()->log ( String::compose ( - "First video at %1, first audio at %2, pushing %3 audio frames of silence for %4 channels (%5 bytes per sample)", + N_("First video at %1, first audio at %2, pushing %3 audio frames of silence for %4 channels (%5 bytes per sample)"), _first_video.get(), _first_audio.get(), s, ffa->channels(), bytes_per_audio_sample() ) ); @@ -443,7 +445,7 @@ FFmpegDecoder::deinterleave_audio (uint8_t** data, int size) break; default: - throw DecodeError (String::compose ("Unrecognised audio sample format (%1)", static_cast (audio_sample_format()))); + throw DecodeError (String::compose (_("Unrecognised audio sample format (%1)"), static_cast (audio_sample_format()))); } return audio; @@ -512,21 +514,21 @@ FFmpegDecoder::stream_name (AVStream* s) const { stringstream n; - AVDictionaryEntry const * lang = av_dict_get (s->metadata, "language", 0, 0); + AVDictionaryEntry const * lang = av_dict_get (s->metadata, N_("language"), 0, 0); if (lang) { n << lang->value; } - AVDictionaryEntry const * title = av_dict_get (s->metadata, "title", 0, 0); + AVDictionaryEntry const * title = av_dict_get (s->metadata, N_("title"), 0, 0); if (title) { if (!n.str().empty()) { - n << " "; + n << N_(" "); } n << title->value; } if (n.str().empty()) { - n << "unknown"; + n << N_("unknown"); } return n.str (); @@ -568,7 +570,7 @@ FFmpegDecoder::filter_and_emit_video (AVFrame* frame) if (i == _filter_graphs.end ()) { graph.reset (new FilterGraph (_film, this, libdcp::Size (frame->width, frame->height), (AVPixelFormat) frame->format)); _filter_graphs.push_back (graph); - _film->log()->log (String::compose ("New graph for %1x%2, pixel format %3", frame->width, frame->height, frame->format)); + _film->log()->log (String::compose (N_("New graph for %1x%2, pixel format %3"), frame->width, frame->height, frame->format)); } else { graph = *i; } @@ -622,7 +624,7 @@ FFmpegAudioStream::create (string t, optional v) stringstream s (t); string type; s >> type; - if (type != "ffmpeg") { + if (type != N_("ffmpeg")) { return shared_ptr (); } @@ -644,7 +646,7 @@ FFmpegAudioStream::FFmpegAudioStream (string t, optional version) string type; /* Current (marked version 1) */ n >> type >> _id >> _sample_rate >> _channel_layout; - assert (type == "ffmpeg"); + assert (type == N_("ffmpeg")); } for (int i = 0; i < name_index; ++i) { @@ -660,7 +662,7 @@ FFmpegAudioStream::FFmpegAudioStream (string t, optional version) string FFmpegAudioStream::to_string () const { - return String::compose ("ffmpeg %1 %2 %3 %4", _id, _sample_rate, _channel_layout, _name); + return String::compose (N_("ffmpeg %1 %2 %3 %4"), _id, _sample_rate, _channel_layout, _name); } void @@ -674,7 +676,7 @@ FFmpegDecoder::out_with_sync () * av_frame_get_best_effort_timestamp(_frame); _film->log()->log ( - String::compose ("Source video frame ready; source at %1, output at %2", source_pts_seconds, out_pts_seconds), + String::compose (N_("Source video frame ready; source at %1, output at %2"), source_pts_seconds, out_pts_seconds), Log::VERBOSE ); @@ -693,7 +695,7 @@ FFmpegDecoder::out_with_sync () repeat_last_video (); _film->log()->log ( String::compose ( - "Extra video frame inserted at %1s; source frame %2, source PTS %3 (at %4 fps)", + N_("Extra video frame inserted at %1s; source frame %2, source PTS %3 (at %4 fps)"), out_pts_seconds, video_frame(), source_pts_seconds, frames_per_second() ) ); @@ -705,7 +707,7 @@ FFmpegDecoder::out_with_sync () filter_and_emit_video (_frame); } else { /* Otherwise we are omitting a frame to keep things right */ - _film->log()->log (String::compose ("Frame removed at %1s", out_pts_seconds)); + _film->log()->log (String::compose (N_("Frame removed at %1s"), out_pts_seconds)); } } diff --git a/src/lib/film.cc b/src/lib/film.cc index addaa0852..c119f1515 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -88,7 +88,7 @@ Film::Film (string d, bool must_exist) , _trust_content_header (true) , _dcp_content_type (0) , _format (0) - , _scaler (Scaler::from_id ("bicubic")) + , _scaler (Scaler::from_id (N_("bicubic"))) , _trim_start (0) , _trim_end (0) , _dcp_ab (false) @@ -114,13 +114,13 @@ Film::Film (string d, bool must_exist) boost::filesystem::path p (boost::filesystem::system_complete (d)); boost::filesystem::path result; for (boost::filesystem::path::iterator i = p.begin(); i != p.end(); ++i) { - if (*i == "..") { - if (boost::filesystem::is_symlink (result) || result.filename() == "..") { + if (*i == N_("..")) { + if (boost::filesystem::is_symlink (result) || result.filename() == N_("..")) { result /= *i; } else { result = result.parent_path (); } - } else if (*i != ".") { + } else if (*i != N_(".")) { result /= *i; } } @@ -141,7 +141,7 @@ Film::Film (string d, bool must_exist) read_metadata (); } - _log = new FileLog (file ("log")); + _log = new FileLog (file (N_("log"))); } Film::Film (Film const & o) @@ -201,16 +201,16 @@ Film::video_state_identifier () const stringstream s; s << format()->id() - << "_" << content_digest() - << "_" << crop().left << "_" << crop().right << "_" << crop().top << "_" << crop().bottom - << "_" << f.first << "_" << f.second - << "_" << scaler()->id() - << "_" << j2k_bandwidth() - << "_" << boost::lexical_cast (colour_lut()); + << N_("_") << content_digest() + << N_("_") << crop().left << N_("_") << crop().right << N_("_") << crop().top << N_("_") << crop().bottom + << N_("_") << f.first << N_("_") << f.second + << N_("_") << scaler()->id() + << N_("_") << j2k_bandwidth() + << N_("_") << boost::lexical_cast (colour_lut()); if (dcp_ab()) { pair fa = Filter::ffmpeg_strings (Config::instance()->reference_filters()); - s << "ab_" << Config::instance()->reference_scaler()->id() << "_" << fa.first << "_" << fa.second; + s << N_("ab_") << Config::instance()->reference_scaler()->id() << N_("_") << fa.first << N_("_") << fa.second; } return s.str (); @@ -221,7 +221,7 @@ string Film::info_dir () const { boost::filesystem::path p; - p /= "info"; + p /= N_("info"); p /= video_state_identifier (); return dir (p.string()); } @@ -230,13 +230,13 @@ string Film::video_mxf_dir () const { boost::filesystem::path p; - return dir ("video"); + return dir (N_("video")); } string Film::video_mxf_filename () const { - return video_state_identifier() + ".mxf"; + return video_state_identifier() + N_(".mxf"); } /** Add suitable Jobs to the JobManager to create a DCP for this Film */ @@ -245,52 +245,52 @@ Film::make_dcp () { set_dci_date_today (); - if (dcp_name().find ("/") != string::npos) { - throw BadSettingError ("name", _("cannot contain slashes")); + if (dcp_name().find (N_("/")) != string::npos) { + throw BadSettingError (_("name"), _("cannot contain slashes")); } - log()->log (String::compose ("DVD-o-matic %1 git %2 using %3", dvdomatic_version, dvdomatic_git_commit, dependency_version_summary())); + log()->log (String::compose (N_("DVD-o-matic %1 git %2 using %3"), dvdomatic_version, dvdomatic_git_commit, dependency_version_summary())); { char buffer[128]; gethostname (buffer, sizeof (buffer)); - log()->log (String::compose ("Starting to make DCP on %1", buffer)); + log()->log (String::compose (N_("Starting to make DCP on %1"), buffer)); } - log()->log (String::compose ("Content is %1; type %2", content_path(), (content_type() == STILL ? "still" : "video"))); + log()->log (String::compose (N_("Content is %1; type %2"), content_path(), (content_type() == STILL ? _("still") : _("video")))); if (length()) { - log()->log (String::compose ("Content length %1", length().get())); + log()->log (String::compose (N_("Content length %1"), length().get())); } - log()->log (String::compose ("Content digest %1", content_digest())); - log()->log (String::compose ("%1 threads", Config::instance()->num_local_encoding_threads())); - log()->log (String::compose ("J2K bandwidth %1", j2k_bandwidth())); + log()->log (String::compose (N_("Content digest %1"), content_digest())); + log()->log (String::compose (N_("%1 threads"), Config::instance()->num_local_encoding_threads())); + log()->log (String::compose (N_("J2K bandwidth %1"), j2k_bandwidth())); #ifdef DVDOMATIC_DEBUG - log()->log ("DVD-o-matic built in debug mode."); + log()->log (N_("DVD-o-matic built in debug mode.")); #else - log()->log ("DVD-o-matic built in optimised mode."); + log()->log (N_("DVD-o-matic built in optimised mode.")); #endif #ifdef LIBDCP_DEBUG - log()->log ("libdcp built in debug mode."); + log()->log (N_("libdcp built in debug mode.")); #else - log()->log ("libdcp built in optimised mode."); + log()->log (N_("libdcp built in optimised mode.")); #endif pair const c = cpu_info (); - log()->log (String::compose ("CPU: %1, %2 processors", c.first, c.second)); + log()->log (String::compose (N_("CPU: %1, %2 processors"), c.first, c.second)); if (format() == 0) { - throw MissingSettingError ("format"); + throw MissingSettingError (_("format")); } if (content().empty ()) { - throw MissingSettingError ("content"); + throw MissingSettingError (_("content")); } if (dcp_content_type() == 0) { - throw MissingSettingError ("content type"); + throw MissingSettingError (_("content type")); } if (name().empty()) { - throw MissingSettingError ("name"); + throw MissingSettingError (_("name")); } DecodeOptions od; @@ -359,73 +359,73 @@ Film::write_metadata () const boost::filesystem::create_directories (directory()); - string const m = file ("metadata"); + string const m = file (N_("metadata")); ofstream f (m.c_str ()); if (!f.good ()) { throw CreateFileError (m); } - f << "version " << state_version << "\n"; + f << N_("version ") << state_version << N_("\n"); /* User stuff */ - f << "name " << _name << "\n"; - f << "use_dci_name " << _use_dci_name << "\n"; - f << "content " << _content << "\n"; - f << "trust_content_header " << (_trust_content_header ? "1" : "0") << "\n"; + f << N_("name ") << _name << N_("\n"); + f << N_("use_dci_name ") << _use_dci_name << N_("\n"); + f << N_("content ") << _content << N_("\n"); + f << N_("trust_content_header ") << (_trust_content_header ? N_("1") : N_("0")) << N_("\n"); if (_dcp_content_type) { - f << "dcp_content_type " << _dcp_content_type->dci_name () << "\n"; + f << N_("dcp_content_type ") << _dcp_content_type->dci_name () << N_("\n"); } if (_format) { - f << "format " << _format->as_metadata () << "\n"; + f << N_("format ") << _format->as_metadata () << N_("\n"); } - f << "left_crop " << _crop.left << "\n"; - f << "right_crop " << _crop.right << "\n"; - f << "top_crop " << _crop.top << "\n"; - f << "bottom_crop " << _crop.bottom << "\n"; + f << N_("left_crop ") << _crop.left << N_("\n"); + f << N_("right_crop ") << _crop.right << N_("\n"); + f << N_("top_crop ") << _crop.top << N_("\n"); + f << N_("bottom_crop ") << _crop.bottom << N_("\n"); for (vector::const_iterator i = _filters.begin(); i != _filters.end(); ++i) { - f << "filter " << (*i)->id () << "\n"; + f << N_("filter ") << (*i)->id () << N_("\n"); } - f << "scaler " << _scaler->id () << "\n"; - f << "trim_start " << _trim_start << "\n"; - f << "trim_end " << _trim_end << "\n"; - f << "dcp_ab " << (_dcp_ab ? "1" : "0") << "\n"; + f << N_("scaler ") << _scaler->id () << N_("\n"); + f << N_("trim_start ") << _trim_start << N_("\n"); + f << N_("trim_end ") << _trim_end << N_("\n"); + f << N_("dcp_ab ") << (_dcp_ab ? N_("1") : N_("0")) << N_("\n"); if (_content_audio_stream) { - f << "selected_content_audio_stream " << _content_audio_stream->to_string() << "\n"; + f << N_("selected_content_audio_stream ") << _content_audio_stream->to_string() << N_("\n"); } for (vector::const_iterator i = _external_audio.begin(); i != _external_audio.end(); ++i) { - f << "external_audio " << *i << "\n"; + f << N_("external_audio ") << *i << N_("\n"); } - f << "use_content_audio " << (_use_content_audio ? "1" : "0") << "\n"; - f << "audio_gain " << _audio_gain << "\n"; - f << "audio_delay " << _audio_delay << "\n"; - f << "still_duration " << _still_duration << "\n"; + f << N_("use_content_audio ") << (_use_content_audio ? N_("1") : N_("0")) << N_("\n"); + f << N_("audio_gain ") << _audio_gain << N_("\n"); + f << N_("audio_delay ") << _audio_delay << N_("\n"); + f << N_("still_duration ") << _still_duration << N_("\n"); if (_subtitle_stream) { - f << "selected_subtitle_stream " << _subtitle_stream->to_string() << "\n"; + f << N_("selected_subtitle_stream ") << _subtitle_stream->to_string() << N_("\n"); } - f << "with_subtitles " << _with_subtitles << "\n"; - f << "subtitle_offset " << _subtitle_offset << "\n"; - f << "subtitle_scale " << _subtitle_scale << "\n"; - f << "colour_lut " << _colour_lut << "\n"; - f << "j2k_bandwidth " << _j2k_bandwidth << "\n"; + f << N_("with_subtitles ") << _with_subtitles << N_("\n"); + f << N_("subtitle_offset ") << _subtitle_offset << N_("\n"); + f << N_("subtitle_scale ") << _subtitle_scale << N_("\n"); + f << N_("colour_lut ") << _colour_lut << N_("\n"); + f << N_("j2k_bandwidth ") << _j2k_bandwidth << N_("\n"); _dci_metadata.write (f); - f << "dci_date " << boost::gregorian::to_iso_string (_dci_date) << "\n"; - f << "width " << _size.width << "\n"; - f << "height " << _size.height << "\n"; - f << "length " << _length.get_value_or(0) << "\n"; - f << "dcp_intrinsic_duration " << _dcp_intrinsic_duration.get_value_or(0) << "\n"; - f << "content_digest " << _content_digest << "\n"; + f << N_("dci_date ") << boost::gregorian::to_iso_string (_dci_date) << N_("\n"); + f << N_("width ") << _size.width << N_("\n"); + f << N_("height ") << _size.height << N_("\n"); + f << N_("length ") << _length.get_value_or(0) << N_("\n"); + f << N_("dcp_intrinsic_duration ") << _dcp_intrinsic_duration.get_value_or(0) << N_("\n"); + f << N_("content_digest ") << _content_digest << N_("\n"); for (vector >::const_iterator i = _content_audio_streams.begin(); i != _content_audio_streams.end(); ++i) { - f << "content_audio_stream " << (*i)->to_string () << "\n"; + f << N_("content_audio_stream ") << (*i)->to_string () << N_("\n"); } - f << "external_audio_stream " << _external_audio_stream->to_string() << "\n"; + f << N_("external_audio_stream ") << _external_audio_stream->to_string() << N_("\n"); for (vector >::const_iterator i = _subtitle_streams.begin(); i != _subtitle_streams.end(); ++i) { - f << "subtitle_stream " << (*i)->to_string () << "\n"; + f << N_("subtitle_stream ") << (*i)->to_string () << N_("\n"); } - f << "frames_per_second " << _frames_per_second << "\n"; + f << N_("frames_per_second ") << _frames_per_second << N_("\n"); _dirty = false; } @@ -447,15 +447,15 @@ Film::read_metadata () boost::optional audio_stream_index; boost::optional subtitle_stream_index; - ifstream f (file ("metadata").c_str()); + ifstream f (file (N_("metadata")).c_str()); if (!f.good()) { - throw OpenFileError (file ("metadata")); + throw OpenFileError (file (N_("metadata"))); } multimap kv = read_key_value (f); /* We need version before anything else */ - multimap::iterator v = kv.find ("version"); + multimap::iterator v = kv.find (N_("version")); if (v != kv.end ()) { version = atoi (v->second.c_str()); } @@ -464,107 +464,107 @@ Film::read_metadata () string const k = i->first; string const v = i->second; - if (k == "audio_sample_rate") { + if (k == N_("audio_sample_rate")) { audio_sample_rate = atoi (v.c_str()); } /* User-specified stuff */ - if (k == "name") { + if (k == N_("name")) { _name = v; - } else if (k == "use_dci_name") { - _use_dci_name = (v == "1"); - } else if (k == "content") { + } else if (k == N_("use_dci_name")) { + _use_dci_name = (v == N_("1")); + } else if (k == N_("content")) { _content = v; - } else if (k == "trust_content_header") { - _trust_content_header = (v == "1"); - } else if (k == "dcp_content_type") { + } else if (k == N_("trust_content_header")) { + _trust_content_header = (v == N_("1")); + } else if (k == N_("dcp_content_type")) { if (version < 3) { _dcp_content_type = DCPContentType::from_pretty_name (v); } else { _dcp_content_type = DCPContentType::from_dci_name (v); } - } else if (k == "format") { + } else if (k == N_("format")) { _format = Format::from_metadata (v); - } else if (k == "left_crop") { + } else if (k == N_("left_crop")) { _crop.left = atoi (v.c_str ()); - } else if (k == "right_crop") { + } else if (k == N_("right_crop")) { _crop.right = atoi (v.c_str ()); - } else if (k == "top_crop") { + } else if (k == N_("top_crop")) { _crop.top = atoi (v.c_str ()); - } else if (k == "bottom_crop") { + } else if (k == N_("bottom_crop")) { _crop.bottom = atoi (v.c_str ()); - } else if (k == "filter") { + } else if (k == N_("filter")) { _filters.push_back (Filter::from_id (v)); - } else if (k == "scaler") { + } else if (k == N_("scaler")) { _scaler = Scaler::from_id (v); - } else if ( ((!version || version < 2) && k == "dcp_trim_start") || k == "trim_start") { + } else if ( ((!version || version < 2) && k == N_("dcp_trim_start")) || k == N_("trim_start")) { _trim_start = atoi (v.c_str ()); - } else if ( ((!version || version < 2) && k == "dcp_trim_end") || k == "trim_end") { + } else if ( ((!version || version < 2) && k == N_("dcp_trim_end")) || k == N_("trim_end")) { _trim_end = atoi (v.c_str ()); - } else if (k == "dcp_ab") { - _dcp_ab = (v == "1"); - } else if (k == "selected_content_audio_stream" || (!version && k == "selected_audio_stream")) { + } else if (k == N_("dcp_ab")) { + _dcp_ab = (v == N_("1")); + } else if (k == N_("selected_content_audio_stream") || (!version && k == N_("selected_audio_stream"))) { if (!version) { audio_stream_index = atoi (v.c_str ()); } else { _content_audio_stream = audio_stream_factory (v, version); } - } else if (k == "external_audio") { + } else if (k == N_("external_audio")) { _external_audio.push_back (v); - } else if (k == "use_content_audio") { - _use_content_audio = (v == "1"); - } else if (k == "audio_gain") { + } else if (k == N_("use_content_audio")) { + _use_content_audio = (v == N_("1")); + } else if (k == N_("audio_gain")) { _audio_gain = atof (v.c_str ()); - } else if (k == "audio_delay") { + } else if (k == N_("audio_delay")) { _audio_delay = atoi (v.c_str ()); - } else if (k == "still_duration") { + } else if (k == N_("still_duration")) { _still_duration = atoi (v.c_str ()); - } else if (k == "selected_subtitle_stream") { + } else if (k == N_("selected_subtitle_stream")) { if (!version) { subtitle_stream_index = atoi (v.c_str ()); } else { _subtitle_stream = subtitle_stream_factory (v, version); } - } else if (k == "with_subtitles") { - _with_subtitles = (v == "1"); - } else if (k == "subtitle_offset") { + } else if (k == N_("with_subtitles")) { + _with_subtitles = (v == N_("1")); + } else if (k == N_("subtitle_offset")) { _subtitle_offset = atoi (v.c_str ()); - } else if (k == "subtitle_scale") { + } else if (k == N_("subtitle_scale")) { _subtitle_scale = atof (v.c_str ()); - } else if (k == "colour_lut") { + } else if (k == N_("colour_lut")) { _colour_lut = atoi (v.c_str ()); - } else if (k == "j2k_bandwidth") { + } else if (k == N_("j2k_bandwidth")) { _j2k_bandwidth = atoi (v.c_str ()); - } else if (k == "dci_date") { + } else if (k == N_("dci_date")) { _dci_date = boost::gregorian::from_undelimited_string (v); } _dci_metadata.read (k, v); /* Cached stuff */ - if (k == "width") { + if (k == N_("width")) { _size.width = atoi (v.c_str ()); - } else if (k == "height") { + } else if (k == N_("height")) { _size.height = atoi (v.c_str ()); - } else if (k == "length") { + } else if (k == N_("length")) { int const vv = atoi (v.c_str ()); if (vv) { _length = vv; } - } else if (k == "dcp_intrinsic_duration") { + } else if (k == N_("dcp_intrinsic_duration")) { int const vv = atoi (v.c_str ()); if (vv) { _dcp_intrinsic_duration = vv; } - } else if (k == "content_digest") { + } else if (k == N_("content_digest")) { _content_digest = v; - } else if (k == "content_audio_stream" || (!version && k == "audio_stream")) { + } else if (k == N_("content_audio_stream") || (!version && k == N_("audio_stream"))) { _content_audio_streams.push_back (audio_stream_factory (v, version)); - } else if (k == "external_audio_stream") { + } else if (k == N_("external_audio_stream")) { _external_audio_stream = audio_stream_factory (v, version); - } else if (k == "subtitle_stream") { + } else if (k == N_("subtitle_stream")) { _subtitle_streams.push_back (subtitle_stream_factory (v, version)); - } else if (k == "frames_per_second") { + } else if (k == N_("frames_per_second")) { _frames_per_second = atof (v.c_str ()); } } @@ -714,14 +714,14 @@ Film::dci_name (bool if_created_now) const fixed_name = fixed_name.substr (0, 14); } - d << fixed_name << "_"; + d << fixed_name << N_("_"); if (dcp_content_type()) { - d << dcp_content_type()->dci_name() << "_"; + d << dcp_content_type()->dci_name() << N_("_"); } if (format()) { - d << format()->dci_name() << "_"; + d << format()->dci_name() << N_("_"); } DCIMetadata const dm = dci_metadata (); @@ -729,51 +729,51 @@ Film::dci_name (bool if_created_now) const if (!dm.audio_language.empty ()) { d << dm.audio_language; if (!dm.subtitle_language.empty() && with_subtitles()) { - d << "-" << dm.subtitle_language; + d << N_("-") << dm.subtitle_language; } else { - d << "-XX"; + d << N_("-XX"); } - d << "_"; + d << N_("_"); } if (!dm.territory.empty ()) { d << dm.territory; if (!dm.rating.empty ()) { - d << "-" << dm.rating; + d << N_("-") << dm.rating; } - d << "_"; + d << N_("_"); } switch (audio_channels()) { case 1: - d << "10_"; + d << N_("10_"); break; case 2: - d << "20_"; + d << N_("20_"); break; case 6: - d << "51_"; + d << N_("51_"); break; case 8: - d << "71_"; + d << N_("71_"); break; } - d << "2K_"; + d << N_("2K_"); if (!dm.studio.empty ()) { - d << dm.studio << "_"; + d << dm.studio << N_("_"); } if (if_created_now) { - d << boost::gregorian::to_iso_string (boost::gregorian::day_clock::local_day ()) << "_"; + d << boost::gregorian::to_iso_string (boost::gregorian::day_clock::local_day ()) << N_("_"); } else { - d << boost::gregorian::to_iso_string (_dci_date) << "_"; + d << boost::gregorian::to_iso_string (_dci_date) << N_("_"); } if (!dm.facility.empty ()) { - d << dm.facility << "_"; + d << dm.facility << N_("_"); } if (!dm.package_type.empty ()) { @@ -828,7 +828,7 @@ Film::set_content (string c) { string check = directory (); - boost::filesystem::path slash ("/"); + boost::filesystem::path slash (N_("/")); string platform_slash = slash.make_preferred().string (); if (!ends_with (check, platform_slash)) { @@ -901,10 +901,10 @@ Film::set_content (string c) /* Default format */ switch (content_type()) { case STILL: - set_format (Format::from_id ("var-185")); + set_format (Format::from_id (N_("var-185"))); break; case VIDEO: - set_format (Format::from_id ("185")); + set_format (Format::from_id (N_("185"))); break; } @@ -1332,7 +1332,7 @@ Film::info_path (int f) const stringstream s; s.width (8); - s << setfill('0') << f << ".md5"; + s << setfill('0') << f << N_(".md5"); p /= s.str(); @@ -1346,15 +1346,15 @@ string Film::j2c_path (int f, bool t) const { boost::filesystem::path p; - p /= "j2c"; + p /= N_("j2c"); p /= video_state_identifier (); stringstream s; s.width (8); - s << setfill('0') << f << ".j2c"; + s << setfill('0') << f << N_(".j2c"); if (t) { - s << ".tmp"; + s << N_(".tmp"); } p /= s.str(); diff --git a/src/lib/filter.cc b/src/lib/filter.cc index 9a662f90f..4d429b303 100644 --- a/src/lib/filter.cc +++ b/src/lib/filter.cc @@ -27,6 +27,8 @@ extern "C" { #include } +#include "i18n.h" + using namespace std; vector Filter::_filters; @@ -63,30 +65,30 @@ Filter::setup_filters () { /* Note: "none" is a magic id name, so don't use it here */ - maybe_add ("pphb", "Horizontal deblocking filter", "De-blocking", "", "hb"); - maybe_add ("ppvb", "Vertical deblocking filter", "De-blocking", "", "vb"); - maybe_add ("ppha", "Horizontal deblocking filter A", "De-blocking", "", "ha"); - maybe_add ("ppva", "Vertical deblocking filter A", "De-blocking", "", "va"); - maybe_add ("pph1", "Experimental horizontal deblocking filter 1", "De-blocking", "", "h1"); - maybe_add ("pphv", "Experimental vertical deblocking filter 1", "De-blocking", "", "v1"); - maybe_add ("ppdr", "Deringing filter", "Misc", "", "dr"); - maybe_add ("pplb", "Linear blend deinterlacer", "De-interlacing", "", "lb"); - maybe_add ("ppli", "Linear interpolating deinterlacer", "De-interlacing", "", "li"); - maybe_add ("ppci", "Cubic interpolating deinterlacer", "De-interlacing", "", "ci"); - maybe_add ("ppmd", "Median deinterlacer", "De-interlacing", "", "md"); - maybe_add ("ppfd", "FFMPEG deinterlacer", "De-interlacing", "", "fd"); - maybe_add ("ppl5", "FIR low-pass deinterlacer", "De-interlacing", "", "l5"); - maybe_add ("mcdeint", "Motion compensating deinterlacer", "De-interlacing", "mcdeint", ""); - maybe_add ("kerndeint", "Kernel deinterlacer", "De-interlacing", "kerndeint", ""); - maybe_add ("yadif", "Yet Another Deinterlacing Filter", "De-interlacing", "yadif", ""); - maybe_add ("pptn", "Temporal noise reducer", "Noise reduction", "", "tn"); - maybe_add ("ppfq", "Force quantizer", "Misc", "", "fq"); - maybe_add ("gradfun", "Gradient debander", "Misc", "gradfun", ""); - maybe_add ("unsharp", "Unsharp mask and Gaussian blur", "Misc", "unsharp", ""); - maybe_add ("denoise3d", "3D denoiser", "Noise reduction", "denoise3d", ""); - maybe_add ("hqdn3d", "High quality 3D denoiser", "Noise reduction", "hqdn3d", ""); - maybe_add ("telecine", "Telecine filter", "Misc", "telecine", ""); - maybe_add ("ow", "Overcomplete wavelet denoiser", "Noise reduction", "mp=ow", ""); + maybe_add (N_("pphb"), _("Horizontal deblocking filter"), _("De-blocking"), N_(""), N_("hb")); + maybe_add (N_("ppvb"), _("Vertical deblocking filter"), _("De-blocking"), N_(""), N_("vb")); + maybe_add (N_("ppha"), _("Horizontal deblocking filter A"), _("De-blocking"), N_(""), N_("ha")); + maybe_add (N_("ppva"), _("Vertical deblocking filter A"), _("De-blocking"), N_(""), N_("va")); + maybe_add (N_("pph1"), _("Experimental horizontal deblocking filter 1"), _("De-blocking"), N_(""), N_("h1")); + maybe_add (N_("pphv"), _("Experimental vertical deblocking filter 1"), _("De-blocking"), N_(""), N_("v1")); + maybe_add (N_("ppdr"), _("Deringing filter"), _("Misc"), N_(""), N_("dr")); + maybe_add (N_("pplb"), _("Linear blend deinterlacer"), _("De-interlacing"), N_(""), N_("lb")); + maybe_add (N_("ppli"), _("Linear interpolating deinterlacer"), _("De-interlacing"), N_(""), N_("li")); + maybe_add (N_("ppci"), _("Cubic interpolating deinterlacer"), _("De-interlacing"), N_(""), N_("ci")); + maybe_add (N_("ppmd"), _("Median deinterlacer"), _("De-interlacing"), N_(""), N_("md")); + maybe_add (N_("ppfd"), _("FFMPEG deinterlacer"), _("De-interlacing"), N_(""), N_("fd")); + maybe_add (N_("ppl5"), _("FIR low-pass deinterlacer"), _("De-interlacing"), N_(""), N_("l5")); + maybe_add (N_("mcdeint"), _("Motion compensating deinterlacer"), _("De-interlacing"), N_("mcdeint"), N_("")); + maybe_add (N_("kerndeint"), _("Kernel deinterlacer"), _("De-interlacing"), N_("kerndeint"), N_("")); + maybe_add (N_("yadif"), _("Yet Another Deinterlacing Filter"), _("De-interlacing"), N_("yadif"), N_("")); + maybe_add (N_("pptn"), _("Temporal noise reducer"), _("Noise reduction"), N_(""), N_("tn")); + maybe_add (N_("ppfq"), _("Force quantizer"), _("Misc"), N_(""), N_("fq")); + maybe_add (N_("gradfun"), _("Gradient debander"), _("Misc"), N_("gradfun"), N_("")); + maybe_add (N_("unsharp"), _("Unsharp mask and Gaussian blur"), _("Misc"), N_("unsharp"), N_("")); + maybe_add (N_("denoise3d"), _("3D denoiser"), _("Noise reduction"), N_("denoise3d"), N_("")); + maybe_add (N_("hqdn3d"), _("High quality 3D denoiser"), _("Noise reduction"), N_("hqdn3d"), N_("")); + maybe_add (N_("telecine"), _("Telecine filter"), _("Misc"), N_("telecine"), N_("")); + maybe_add (N_("ow"), _("Overcomplete wavelet denoiser"), _("Noise reduction"), N_("mp=ow"), N_("")); } void @@ -118,14 +120,14 @@ Filter::ffmpeg_strings (vector const & filters) for (vector::const_iterator i = filters.begin(); i != filters.end(); ++i) { if (!(*i)->vf().empty ()) { if (!vf.empty ()) { - vf += ","; + vf += N_(","); } vf += (*i)->vf (); } if (!(*i)->pp().empty ()) { if (!pp.empty()) { - pp += ","; + pp += N_(","); } pp += (*i)->pp (); } diff --git a/src/lib/filter_graph.cc b/src/lib/filter_graph.cc index b0991a2da..045cbaa6a 100644 --- a/src/lib/filter_graph.cc +++ b/src/lib/filter_graph.cc @@ -43,6 +43,8 @@ extern "C" { #include "film.h" #include "ffmpeg_decoder.h" +#include "i18n.h" + using std::stringstream; using std::string; using std::list; @@ -63,36 +65,36 @@ FilterGraph::FilterGraph (shared_ptr film, FFmpegDecoder* decoder, libdcp: { string filters = Filter::ffmpeg_strings (film->filters()).first; if (!filters.empty ()) { - filters += ","; + filters += N_(","); } filters += crop_string (Position (film->crop().left, film->crop().top), film->cropped_size (decoder->native_size())); AVFilterGraph* graph = avfilter_graph_alloc(); if (graph == 0) { - throw DecodeError ("Could not create filter graph."); + throw DecodeError (N_("could not create filter graph.")); } - AVFilter* buffer_src = avfilter_get_by_name("buffer"); + AVFilter* buffer_src = avfilter_get_by_name(N_("buffer")); if (buffer_src == 0) { - throw DecodeError ("Could not find buffer src filter"); + throw DecodeError (N_("could not find buffer src filter")); } AVFilter* buffer_sink = get_sink (); stringstream a; - a << _size.width << ":" - << _size.height << ":" - << _pixel_format << ":" - << decoder->time_base_numerator() << ":" - << decoder->time_base_denominator() << ":" - << decoder->sample_aspect_ratio_numerator() << ":" + a << _size.width << N_(":") + << _size.height << N_(":") + << _pixel_format << N_(":") + << decoder->time_base_numerator() << N_(":") + << decoder->time_base_denominator() << N_(":") + << decoder->sample_aspect_ratio_numerator() << N_(":") << decoder->sample_aspect_ratio_denominator(); int r; - if ((r = avfilter_graph_create_filter (&_buffer_src_context, buffer_src, "in", a.str().c_str(), 0, graph)) < 0) { - throw DecodeError ("could not create buffer source"); + if ((r = avfilter_graph_create_filter (&_buffer_src_context, buffer_src, N_("in"), a.str().c_str(), 0, graph)) < 0) { + throw DecodeError (N_("could not create buffer source")); } AVBufferSinkParams* sink_params = av_buffersink_params_alloc (); @@ -101,34 +103,34 @@ FilterGraph::FilterGraph (shared_ptr film, FFmpegDecoder* decoder, libdcp: pixel_fmts[1] = PIX_FMT_NONE; sink_params->pixel_fmts = pixel_fmts; - if (avfilter_graph_create_filter (&_buffer_sink_context, buffer_sink, "out", 0, sink_params, graph) < 0) { - throw DecodeError ("could not create buffer sink."); + if (avfilter_graph_create_filter (&_buffer_sink_context, buffer_sink, N_("out"), 0, sink_params, graph) < 0) { + throw DecodeError (N_("could not create buffer sink.")); } AVFilterInOut* outputs = avfilter_inout_alloc (); - outputs->name = av_strdup("in"); + outputs->name = av_strdup(N_("in")); outputs->filter_ctx = _buffer_src_context; outputs->pad_idx = 0; outputs->next = 0; AVFilterInOut* inputs = avfilter_inout_alloc (); - inputs->name = av_strdup("out"); + inputs->name = av_strdup(N_("out")); inputs->filter_ctx = _buffer_sink_context; inputs->pad_idx = 0; inputs->next = 0; #if LIBAVFILTER_VERSION_MAJOR == 2 && LIBAVFILTER_VERSION_MINOR == 15 if (avfilter_graph_parse (graph, filters.c_str(), inputs, outputs, 0) < 0) { - throw DecodeError ("could not set up filter graph."); + throw DecodeError (N_("could not set up filter graph.")); } #else if (avfilter_graph_parse (graph, filters.c_str(), &inputs, &outputs, 0) < 0) { - throw DecodeError ("could not set up filter graph."); + throw DecodeError (N_("could not set up filter graph.")); } #endif if (avfilter_graph_config (graph, 0) < 0) { - throw DecodeError ("could not configure filter graph."); + throw DecodeError (N_("could not configure filter graph.")); } /* XXX: leaking `inputs' / `outputs' ? */ @@ -145,7 +147,7 @@ FilterGraph::process (AVFrame const * frame) #if LIBAVFILTER_VERSION_MAJOR == 2 && LIBAVFILTER_VERSION_MINOR >= 53 && LIBAVFILTER_VERSION_MINOR <= 61 if (av_vsrc_buffer_add_frame (_buffer_src_context, frame, 0) < 0) { - throw DecodeError ("could not push buffer into filter chain."); + throw DecodeError (N_("could not push buffer into filter chain.")); } #elif LIBAVFILTER_VERSION_MAJOR == 2 && LIBAVFILTER_VERSION_MINOR == 15 @@ -155,13 +157,13 @@ FilterGraph::process (AVFrame const * frame) par.den = sample_aspect_ratio_denominator (); if (av_vsrc_buffer_add_frame (_buffer_src_context, frame, 0, par) < 0) { - throw DecodeError ("could not push buffer into filter chain."); + throw DecodeError (N_("could not push buffer into filter chain.")); } #else if (av_buffersrc_write_frame (_buffer_src_context, frame) < 0) { - throw DecodeError ("could not push buffer into filter chain."); + throw DecodeError (N_("could not push buffer into filter chain.")); } #endif @@ -176,7 +178,7 @@ FilterGraph::process (AVFrame const * frame) int r = avfilter_request_frame (_buffer_sink_context->inputs[0]); if (r < 0) { - throw DecodeError ("could not request filtered frame"); + throw DecodeError (N_("could not request filtered frame")); } AVFilterBufferRef* filter_buffer = _buffer_sink_context->inputs[0]->cur_buf; diff --git a/src/lib/format.cc b/src/lib/format.cc index 016c21fde..0e4830cd7 100644 --- a/src/lib/format.cc +++ b/src/lib/format.cc @@ -30,6 +30,8 @@ #include "format.h" #include "film.h" +#include "i18n.h" + using std::string; using std::setprecision; using std::stringstream; @@ -45,13 +47,13 @@ FixedFormat::name () const { stringstream s; if (!_nickname.empty ()) { - s << _nickname << " ("; + s << _nickname << N_(" ("); } - s << setprecision(3) << (_ratio / 100.0) << ":1"; + s << setprecision(3) << (_ratio / 100.0) << N_(":1"); if (!_nickname.empty ()) { - s << ")"; + s << N_(")"); } return s.str (); @@ -68,19 +70,20 @@ Format::as_metadata () const void Format::setup_formats () { - _formats.push_back (new FixedFormat (119, libdcp::Size (1285, 1080), "119", "1.19", "F")); - _formats.push_back (new FixedFormat (133, libdcp::Size (1436, 1080), "133", "1.33", "F")); - _formats.push_back (new FixedFormat (138, libdcp::Size (1485, 1080), "138", "1.375", "F")); - _formats.push_back (new FixedFormat (133, libdcp::Size (1998, 1080), "133-in-flat", "4:3 within Flat", "F")); - _formats.push_back (new FixedFormat (137, libdcp::Size (1480, 1080), "137", "Academy", "F")); - _formats.push_back (new FixedFormat (166, libdcp::Size (1793, 1080), "166", "1.66", "F")); - _formats.push_back (new FixedFormat (166, libdcp::Size (1998, 1080), "166-in-flat", "1.66 within Flat", "F")); - _formats.push_back (new FixedFormat (178, libdcp::Size (1998, 1080), "178-in-flat", "16:9 within Flat", "F")); - _formats.push_back (new FixedFormat (178, libdcp::Size (1920, 1080), "178", "16:9", "F")); - _formats.push_back (new FixedFormat (185, libdcp::Size (1998, 1080), "185", "Flat", "F")); - _formats.push_back (new FixedFormat (239, libdcp::Size (2048, 858), "239", "Scope", "S")); - _formats.push_back (new VariableFormat (libdcp::Size (1998, 1080), "var-185", "Flat", "F")); - _formats.push_back (new VariableFormat (libdcp::Size (2048, 858), "var-239", "Scope", "S")); + /// TRANSLATORS: these are film picture aspect ratios; "Academy" means 1.37, "Flat" 1.85 and "Scope" 2.39. + _formats.push_back (new FixedFormat (119, libdcp::Size (1285, 1080), N_("119"), _("1.19"), N_("F"))); + _formats.push_back (new FixedFormat (133, libdcp::Size (1436, 1080), N_("133"), _("1.33"), N_("F"))); + _formats.push_back (new FixedFormat (138, libdcp::Size (1485, 1080), N_("138"), _("1.375"), N_("F"))); + _formats.push_back (new FixedFormat (133, libdcp::Size (1998, 1080), N_("133-in-flat"), _("4:3 within Flat"), N_("F"))); + _formats.push_back (new FixedFormat (137, libdcp::Size (1480, 1080), N_("137"), _("Academy"), N_("F"))); + _formats.push_back (new FixedFormat (166, libdcp::Size (1793, 1080), N_("166"), _("1.66"), N_("F"))); + _formats.push_back (new FixedFormat (166, libdcp::Size (1998, 1080), N_("166-in-flat"), _("1.66 within Flat"), N_("F"))); + _formats.push_back (new FixedFormat (178, libdcp::Size (1998, 1080), N_("178-in-flat"), _("16:9 within Flat"), N_("F"))); + _formats.push_back (new FixedFormat (178, libdcp::Size (1920, 1080), N_("178"), _("16:9"), N_("F"))); + _formats.push_back (new FixedFormat (185, libdcp::Size (1998, 1080), N_("185"), _("Flat"), N_("F"))); + _formats.push_back (new FixedFormat (239, libdcp::Size (2048, 858), N_("239"), _("Scope"), N_("S"))); + _formats.push_back (new VariableFormat (libdcp::Size (1998, 1080), N_("var-185"), _("Flat"), N_("F"))); + _formats.push_back (new VariableFormat (libdcp::Size (2048, 858), N_("var-239"), _("Scope"), N_("S"))); } /** @param n Nickname. diff --git a/src/lib/image.cc b/src/lib/image.cc index b7ac13ab1..268c08173 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -40,6 +40,8 @@ extern "C" { #include "exceptions.h" #include "scaler.h" +#include "i18n.h" + using namespace std; using namespace boost; using libdcp::Size; @@ -75,7 +77,7 @@ Image::lines (int n) const case PIX_FMT_YUV444P10LE: return size().height; default: - throw PixelFormatError ("lines()", _pixel_format); + throw PixelFormatError (N_("lines()"), _pixel_format); } return 0; @@ -99,7 +101,7 @@ Image::components () const case PIX_FMT_RGBA: return 1; default: - throw PixelFormatError ("components()", _pixel_format); + throw PixelFormatError (N_("components()"), _pixel_format); } return 0; @@ -218,7 +220,7 @@ Image::post_process (string pp, bool aligned) const case PIX_FMT_YUV444P10LE: pp_format = PP_FORMAT_444; default: - throw PixelFormatError ("post_process", pixel_format()); + throw PixelFormatError (N_("post_process"), pixel_format()); } pp_mode* mode = pp_get_mode_by_name_and_quality (pp.c_str (), PP_QUALITY_MAX); diff --git a/src/lib/imagemagick_decoder.cc b/src/lib/imagemagick_decoder.cc index 42fe699d7..5dc0b7b06 100644 --- a/src/lib/imagemagick_decoder.cc +++ b/src/lib/imagemagick_decoder.cc @@ -25,6 +25,8 @@ #include "film.h" #include "exceptions.h" +#include "i18n.h" + using std::cout; using boost::shared_ptr; using libdcp::Size; @@ -55,7 +57,7 @@ libdcp::Size ImageMagickDecoder::native_size () const { if (_files.empty ()) { - throw DecodeError ("no still image files found"); + throw DecodeError (_("no still image files found")); } /* Look at the first file and assume its size holds for all */ diff --git a/src/lib/job.cc b/src/lib/job.cc index bfad65a0a..77d367136 100644 --- a/src/lib/job.cc +++ b/src/lib/job.cc @@ -27,6 +27,8 @@ #include "job.h" #include "util.h" +#include "i18n.h" + using std::string; using std::list; using std::stringstream; @@ -66,11 +68,12 @@ Job::run_wrapper () set_progress (1); set_state (FINISHED_ERROR); - string m = String::compose ("An error occurred whilst handling the file %1.", boost::filesystem::path (e.filename()).leaf()); + string m = String::compose (_("An error occurred whilst handling the file %1."), boost::filesystem::path (e.filename()).leaf()); boost::filesystem::space_info const s = boost::filesystem::space (e.filename()); if (s.available < pow (1024, 3)) { - m += "\n\nThe drive that the film is stored on is low in disc space. Free some more space and try again."; + m += N_("\n\n"); + m += _("The drive that the film is stored on is low in disc space. Free some more space and try again."); } set_error (e.what(), m); @@ -81,7 +84,7 @@ Job::run_wrapper () set_state (FINISHED_ERROR); set_error ( e.what (), - "It is not known what caused this error. The best idea is to report the problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" + _("It is not known what caused this error. The best idea is to report the problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)") ); } catch (...) { @@ -89,8 +92,8 @@ Job::run_wrapper () set_progress (1); set_state (FINISHED_ERROR); set_error ( - "Unknown error", - "It is not known what caused this error. The best idea is to report the problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" + _("Unknown error"), + _("It is not known what caused this error. The best idea is to report the problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)") ); } @@ -273,14 +276,16 @@ Job::status () const stringstream s; if (!finished ()) { - s << pc << "%"; + s << pc << N_("%"); if (p >= 0 && t > 10 && r > 0) { - s << "; " << seconds_to_approximate_hms (r) << " remaining"; + /// TRANSLATORS: remaining here follows an amount of time that is remaining + /// on an operation. + s << "; " << seconds_to_approximate_hms (r) << " " << _("remaining"); } } else if (finished_ok ()) { - s << "OK (ran for " << seconds_to_hms (_ran_for) << ")"; + s << String::compose (_("OK (ran for %1)"), seconds_to_hms (_ran_for)); } else if (finished_in_error ()) { - s << "Error (" << error_summary() << ")"; + s << String::compose (_("Error (%1)"), error_summary()); } return s.str (); diff --git a/src/lib/log.cc b/src/lib/log.cc index 7459700ea..ef36a902c 100644 --- a/src/lib/log.cc +++ b/src/lib/log.cc @@ -25,6 +25,8 @@ #include #include "log.h" +#include "i18n.h" + using namespace std; Log::Log () @@ -48,7 +50,7 @@ Log::log (string m, Level l) string a = ctime (&t); stringstream s; - s << a.substr (0, a.length() - 1) << ": " << m; + s << a.substr (0, a.length() - 1) << N_(": ") << m; do_log (s.str ()); } @@ -65,7 +67,7 @@ Log::microsecond_log (string m, Level l) gettimeofday (&tv, 0); stringstream s; - s << tv.tv_sec << ":" << tv.tv_usec << " " << m; + s << tv.tv_sec << N_(":") << tv.tv_usec << N_(" ") << m; do_log (s.str ()); } @@ -79,10 +81,10 @@ Log::set_level (Level l) void Log::set_level (string l) { - if (l == "verbose") { + if (l == N_("verbose")) { set_level (VERBOSE); return; - } else if (l == "timing") { + } else if (l == N_("timing")) { set_level (TIMING); return; } @@ -101,6 +103,6 @@ void FileLog::do_log (string m) { ofstream f (_file.c_str(), fstream::app); - f << m << "\n"; + f << m << N_("\n"); } diff --git a/src/lib/matcher.cc b/src/lib/matcher.cc index 182fb306c..4cd264338 100644 --- a/src/lib/matcher.cc +++ b/src/lib/matcher.cc @@ -21,6 +21,8 @@ #include "image.h" #include "log.h" +#include "i18n.h" + using std::min; using boost::shared_ptr; @@ -65,7 +67,7 @@ Matcher::process_end () _log->log ( String::compose ( - "Matching processor has seen %1 video frames (which equals %2 audio frames) and %3 audio frames", + N_("Matching processor has seen %1 video frames (which equals %2 audio frames) and %3 audio frames"), _video_frames, video_frames_to_audio_frames (_video_frames, _sample_rate, _frames_per_second), _audio_frames @@ -74,12 +76,12 @@ Matcher::process_end () if (audio_short_by_frames < 0) { - _log->log (String::compose ("%1 too many audio frames", -audio_short_by_frames)); + _log->log (String::compose (N_("%1 too many audio frames"), -audio_short_by_frames)); /* We have seen more audio than video. Emit enough black video frames so that we reverse this */ int const black_video_frames = ceil (-audio_short_by_frames * _frames_per_second / _sample_rate); - _log->log (String::compose ("Emitting %1 frames of black video", black_video_frames)); + _log->log (String::compose (N_("Emitting %1 frames of black video"), black_video_frames)); shared_ptr black (new SimpleImage (_pixel_format.get(), _size.get(), true)); black->make_black (); @@ -92,7 +94,7 @@ Matcher::process_end () } if (audio_short_by_frames > 0) { - _log->log (String::compose ("Emitted %1 too few audio frames", audio_short_by_frames)); + _log->log (String::compose (N_("Emitted %1 too few audio frames"), audio_short_by_frames)); /* Do things in half second blocks as I think there may be limits to what FFmpeg (and in particular the resampler) can cope with. diff --git a/src/lib/scaler.cc b/src/lib/scaler.cc index c81456a15..40a0f05b9 100644 --- a/src/lib/scaler.cc +++ b/src/lib/scaler.cc @@ -28,6 +28,8 @@ extern "C" { } #include "scaler.h" +#include "i18n.h" + using namespace std; vector Scaler::_scalers; @@ -57,15 +59,15 @@ Scaler::all () void Scaler::setup_scalers () { - _scalers.push_back (new Scaler (SWS_BICUBIC, "bicubic", "Bicubic")); - _scalers.push_back (new Scaler (SWS_X, "x", "X")); - _scalers.push_back (new Scaler (SWS_AREA, "area", "Area")); - _scalers.push_back (new Scaler (SWS_GAUSS, "gauss", "Gaussian")); - _scalers.push_back (new Scaler (SWS_LANCZOS, "lanczos", "Lanczos")); - _scalers.push_back (new Scaler (SWS_SINC, "sinc", "Sinc")); - _scalers.push_back (new Scaler (SWS_SPLINE, "spline", "Spline")); - _scalers.push_back (new Scaler (SWS_BILINEAR, "bilinear", "Bilinear")); - _scalers.push_back (new Scaler (SWS_FAST_BILINEAR, "fastbilinear", "Fast Bilinear")); + _scalers.push_back (new Scaler (SWS_BICUBIC, N_("bicubic"), _("Bicubic"))); + _scalers.push_back (new Scaler (SWS_X, N_("x"), _("X"))); + _scalers.push_back (new Scaler (SWS_AREA, N_("area"), _("Area"))); + _scalers.push_back (new Scaler (SWS_GAUSS, N_("gauss"), _("Gaussian"))); + _scalers.push_back (new Scaler (SWS_LANCZOS, N_("lanczos"), _("Lanczos"))); + _scalers.push_back (new Scaler (SWS_SINC, N_("sinc"), _("Sinc"))); + _scalers.push_back (new Scaler (SWS_SPLINE, N_("spline"), _("Spline"))); + _scalers.push_back (new Scaler (SWS_BILINEAR, N_("bilinear"), _("Bilinear"))); + _scalers.push_back (new Scaler (SWS_FAST_BILINEAR, N_("fastbilinear"), _("Fast Bilinear"))); } /** @param id One of our ids. diff --git a/src/lib/scp_dcp_job.cc b/src/lib/scp_dcp_job.cc index 30d02eff8..a9fdfefda 100644 --- a/src/lib/scp_dcp_job.cc +++ b/src/lib/scp_dcp_job.cc @@ -34,6 +34,8 @@ #include "log.h" #include "film.h" +#include "i18n.h" + using std::string; using std::stringstream; using std::min; @@ -47,7 +49,7 @@ public: { session = ssh_new (); if (session == 0) { - throw NetworkError ("Could not start SSH session"); + throw NetworkError (_("could not start SSH session")); } } @@ -81,7 +83,7 @@ public: { scp = ssh_scp_new (s, SSH_SCP_WRITE | SSH_SCP_RECURSIVE, Config::instance()->tms_path().c_str ()); if (!scp) { - throw NetworkError (String::compose ("Could not start SCP session (%1)", ssh_get_error (s))); + throw NetworkError (String::compose (_("could not start SCP session (%1)"), ssh_get_error (s))); } } @@ -96,7 +98,7 @@ public: SCPDCPJob::SCPDCPJob (shared_ptr f) : Job (f) - , _status ("Waiting") + , _status (_("Waiting")) { } @@ -104,17 +106,17 @@ SCPDCPJob::SCPDCPJob (shared_ptr f) string SCPDCPJob::name () const { - return "Copy DCP to TMS"; + return _("Copy DCP to TMS"); } void SCPDCPJob::run () { - _film->log()->log ("SCP DCP job starting"); + _film->log()->log (N_("SCP DCP job starting")); SSHSession ss; - set_status ("connecting"); + set_status (_("connecting")); ssh_options_set (ss.session, SSH_OPTIONS_HOST, Config::instance()->tms_ip().c_str ()); ssh_options_set (ss.session, SSH_OPTIONS_USER, Config::instance()->tms_user().c_str ()); @@ -123,29 +125,29 @@ SCPDCPJob::run () int r = ss.connect (); if (r != SSH_OK) { - throw NetworkError (String::compose ("Could not connect to server %1 (%2)", Config::instance()->tms_ip(), ssh_get_error (ss.session))); + throw NetworkError (String::compose (_("Could not connect to server %1 (%2)"), Config::instance()->tms_ip(), ssh_get_error (ss.session))); } int const state = ssh_is_server_known (ss.session); if (state == SSH_SERVER_ERROR) { - throw NetworkError (String::compose ("SSH error (%1)", ssh_get_error (ss.session))); + throw NetworkError (String::compose (_("SSH error (%1)"), ssh_get_error (ss.session))); } r = ssh_userauth_password (ss.session, 0, Config::instance()->tms_password().c_str ()); if (r != SSH_AUTH_SUCCESS) { - throw NetworkError (String::compose ("Failed to authenticate with server (%1)", ssh_get_error (ss.session))); + throw NetworkError (String::compose (_("Failed to authenticate with server (%1)"), ssh_get_error (ss.session))); } SSHSCP sc (ss.session); r = ssh_scp_init (sc.scp); if (r != SSH_OK) { - throw NetworkError (String::compose ("Could not start SCP session (%1)", ssh_get_error (ss.session))); + throw NetworkError (String::compose (_("Could not start SCP session (%1)"), ssh_get_error (ss.session))); } r = ssh_scp_push_directory (sc.scp, _film->dcp_name().c_str(), S_IRWXU); if (r != SSH_OK) { - throw NetworkError (String::compose ("Could not create remote directory %1 (%2)", _film->dcp_name(), ssh_get_error (ss.session))); + throw NetworkError (String::compose (_("Could not create remote directory %1 (%2)"), _film->dcp_name(), ssh_get_error (ss.session))); } string const dcp_dir = _film->dir (_film->dcp_name()); @@ -163,14 +165,14 @@ SCPDCPJob::run () string const leaf = boost::filesystem::path(*i).leaf().generic_string (); - set_status ("copying " + leaf); + set_status (String::compose (_("copying %1"), leaf)); boost::uintmax_t to_do = boost::filesystem::file_size (*i); ssh_scp_push_file (sc.scp, leaf.c_str(), to_do, S_IRUSR | S_IWUSR); - FILE* f = fopen (boost::filesystem::path (*i).string().c_str(), "rb"); + FILE* f = fopen (boost::filesystem::path (*i).string().c_str(), N_("rb")); if (f == 0) { - throw NetworkError (String::compose ("Could not open %1 to send", *i)); + throw NetworkError (String::compose (_("Could not open %1 to send"), *i)); } while (to_do > 0) { @@ -182,7 +184,7 @@ SCPDCPJob::run () r = ssh_scp_write (sc.scp, buffer, t); if (r != SSH_OK) { - throw NetworkError (String::compose ("Could not write to remote file (%1)", ssh_get_error (ss.session))); + throw NetworkError (String::compose (_("Could not write to remote file (%1)"), ssh_get_error (ss.session))); } to_do -= t; bytes_transferred += t; @@ -194,7 +196,7 @@ SCPDCPJob::run () } set_progress (1); - set_status (""); + set_status (N_("")); set_state (FINISHED_OK); } @@ -205,7 +207,7 @@ SCPDCPJob::status () const stringstream s; s << Job::status (); if (!_status.empty ()) { - s << "; " << _status; + s << N_("; ") << _status; } return s.str (); } diff --git a/src/lib/server.cc b/src/lib/server.cc index 3614ed9e4..76a25bfbb 100644 --- a/src/lib/server.cc +++ b/src/lib/server.cc @@ -37,6 +37,8 @@ #include "config.h" #include "subtitle.h" +#include "i18n.h" + using std::string; using std::stringstream; using std::multimap; @@ -57,7 +59,7 @@ ServerDescription * ServerDescription::create_from_metadata (string v) { vector b; - split (b, v, is_any_of (" ")); + split (b, v, is_any_of (N_(" "))); if (b.size() != 2) { return 0; @@ -71,7 +73,7 @@ string ServerDescription::as_metadata () const { stringstream s; - s << _host_name << " " << _threads; + s << _host_name << N_(" ") << _threads; return s.str (); } @@ -91,24 +93,24 @@ Server::process (shared_ptr socket) stringstream s (buffer.get()); multimap kv = read_key_value (s); - if (get_required_string (kv, "encode") != "please") { + if (get_required_string (kv, N_("encode")) != N_("please")) { return -1; } - libdcp::Size in_size (get_required_int (kv, "input_width"), get_required_int (kv, "input_height")); - int pixel_format_int = get_required_int (kv, "input_pixel_format"); - libdcp::Size out_size (get_required_int (kv, "output_width"), get_required_int (kv, "output_height")); - int padding = get_required_int (kv, "padding"); - int subtitle_offset = get_required_int (kv, "subtitle_offset"); - float subtitle_scale = get_required_float (kv, "subtitle_scale"); - string scaler_id = get_required_string (kv, "scaler"); - int frame = get_required_int (kv, "frame"); - int frames_per_second = get_required_int (kv, "frames_per_second"); - string post_process = get_optional_string (kv, "post_process"); - int colour_lut_index = get_required_int (kv, "colour_lut"); - int j2k_bandwidth = get_required_int (kv, "j2k_bandwidth"); - Position subtitle_position (get_optional_int (kv, "subtitle_x"), get_optional_int (kv, "subtitle_y")); - libdcp::Size subtitle_size (get_optional_int (kv, "subtitle_width"), get_optional_int (kv, "subtitle_height")); + libdcp::Size in_size (get_required_int (kv, N_("input_width")), get_required_int (kv, N_("input_height"))); + int pixel_format_int = get_required_int (kv, N_("input_pixel_format")); + libdcp::Size out_size (get_required_int (kv, N_("output_width")), get_required_int (kv, N_("output_height"))); + int padding = get_required_int (kv, N_("padding")); + int subtitle_offset = get_required_int (kv, N_("subtitle_offset")); + float subtitle_scale = get_required_float (kv, N_("subtitle_scale")); + string scaler_id = get_required_string (kv, N_("scaler")); + int frame = get_required_int (kv, N_("frame")); + int frames_per_second = get_required_int (kv, N_("frames_per_second")); + string post_process = get_optional_string (kv, N_("post_process")); + int colour_lut_index = get_required_int (kv, N_("colour_lut")); + int j2k_bandwidth = get_required_int (kv, N_("j2k_bandwidth")); + Position subtitle_position (get_optional_int (kv, N_("subtitle_x")), get_optional_int (kv, N_("subtitle_y"))); + libdcp::Size subtitle_size (get_optional_int (kv, N_("subtitle_width")), get_optional_int (kv, N_("subtitle_height"))); /* This checks that colour_lut_index is within range */ colour_lut_index_to_name (colour_lut_index); @@ -137,7 +139,7 @@ Server::process (shared_ptr socket) encoded->send (socket); } catch (std::exception& e) { _log->log (String::compose ( - "Send failed; frame %1, data size %2, pixel format %3, image size %4x%5, %6 components", + N_("Send failed; frame %1, data size %2, pixel format %3, image size %4x%5, %6 components"), frame, encoded->size(), image->pixel_format(), image->size().width, image->size().height, image->components() ) ); @@ -169,7 +171,7 @@ Server::worker_thread () try { frame = process (socket); } catch (std::exception& e) { - _log->log (String::compose ("Error: %1", e.what())); + _log->log (String::compose (N_("Error: %1"), e.what())); } socket.reset (); @@ -179,7 +181,7 @@ Server::worker_thread () if (frame >= 0) { struct timeval end; gettimeofday (&end, 0); - _log->log (String::compose ("Encoded frame %1 in %2", frame, seconds (end) - seconds (start))); + _log->log (String::compose (N_("Encoded frame %1 in %2"), frame, seconds (end) - seconds (start))); } _worker_condition.notify_all (); @@ -189,7 +191,7 @@ Server::worker_thread () void Server::run (int num_threads) { - _log->log (String::compose ("Server starting with %1 threads", num_threads)); + _log->log (String::compose (N_("Server starting with %1 threads"), num_threads)); for (int i = 0; i < num_threads; ++i) { _worker_threads.push_back (new thread (bind (&Server::worker_thread, this))); diff --git a/src/lib/stream.cc b/src/lib/stream.cc index 4f12f41b9..e5a2bbc2b 100644 --- a/src/lib/stream.cc +++ b/src/lib/stream.cc @@ -23,6 +23,8 @@ #include "ffmpeg_decoder.h" #include "external_audio_decoder.h" +#include "i18n.h" + using std::string; using std::stringstream; using boost::shared_ptr; @@ -47,7 +49,7 @@ SubtitleStream::SubtitleStream (string t, boost::optional) string SubtitleStream::to_string () const { - return String::compose ("%1 %2", _id, _name); + return String::compose (N_("%1 %2"), _id, _name); } /** Create a SubtitleStream from a value returned from to_string(). diff --git a/src/lib/subtitle.cc b/src/lib/subtitle.cc index 5bb91af63..5c1ad9706 100644 --- a/src/lib/subtitle.cc +++ b/src/lib/subtitle.cc @@ -25,6 +25,8 @@ #include "image.h" #include "exceptions.h" +#include "i18n.h" + using namespace std; using namespace boost; using libdcp::Size; @@ -47,13 +49,13 @@ TimedSubtitle::TimedSubtitle (AVSubtitle const & sub) _to = packet_time + (double (sub.end_display_time) / 1e3); if (sub.num_rects > 1) { - throw DecodeError ("multi-part subtitles not yet supported"); + throw DecodeError (_("multi-part subtitles not yet supported")); } AVSubtitleRect const * rect = sub.rects[0]; if (rect->type != SUBTITLE_BITMAP) { - throw DecodeError ("non-bitmap subtitles not yet supported"); + throw DecodeError (_("non-bitmap subtitles not yet supported")); } shared_ptr image (new SimpleImage (PIX_FMT_RGBA, libdcp::Size (rect->w, rect->h), true)); diff --git a/src/lib/timer.cc b/src/lib/timer.cc index a45e80dcb..69a7e3aa9 100644 --- a/src/lib/timer.cc +++ b/src/lib/timer.cc @@ -26,6 +26,8 @@ #include "timer.h" #include "util.h" +#include "i18n.h" + using namespace std; /** @param n Name to use when giving output */ @@ -40,7 +42,7 @@ PeriodTimer::~PeriodTimer () { struct timeval stop; gettimeofday (&stop, 0); - cout << "T: " << _name << ": " << (seconds (stop) - seconds (_start)) << "\n"; + cout << N_("T: ") << _name << N_(": ") << (seconds (stop) - seconds (_start)) << N_("\n"); } /** @param n Name to use when giving output. @@ -80,10 +82,10 @@ StateTimer::~StateTimer () } - set_state (""); + set_state (N_("")); - cout << _name << ":\n"; + cout << _name << N_(":\n"); for (map::iterator i = _totals.begin(); i != _totals.end(); ++i) { - cout << "\t" << i->first << " " << i->second << "\n"; + cout << N_("\t") << i->first << " " << i->second << N_("\n"); } } diff --git a/src/lib/transcode_job.cc b/src/lib/transcode_job.cc index a4279ef8b..61fad2e2b 100644 --- a/src/lib/transcode_job.cc +++ b/src/lib/transcode_job.cc @@ -59,8 +59,8 @@ TranscodeJob::run () { try { - _film->log()->log ("Transcode job starting"); - _film->log()->log (String::compose ("Audio delay is %1ms", _film->audio_delay())); + _film->log()->log (N_("Transcode job starting")); + _film->log()->log (String::compose (N_("Audio delay is %1ms"), _film->audio_delay())); _encoder.reset (new Encoder (_film)); Transcoder w (_film, _decode_opt, this, _encoder); @@ -70,14 +70,14 @@ TranscodeJob::run () _film->set_dcp_intrinsic_duration (_encoder->video_frames_out ()); - _film->log()->log ("Transcode job completed successfully"); - _film->log()->log (String::compose ("DCP intrinsic duration is %1", _encoder->video_frames_out())); + _film->log()->log (N_("Transcode job completed successfully")); + _film->log()->log (String::compose (N_("DCP intrinsic duration is %1"), _encoder->video_frames_out())); } catch (std::exception& e) { set_progress (1); set_state (FINISHED_ERROR); - _film->log()->log (String::compose ("Transcode job failed (%1)", e.what())); + _film->log()->log (String::compose (N_("Transcode job failed (%1)"), e.what())); throw; } @@ -87,7 +87,7 @@ string TranscodeJob::status () const { if (!_encoder) { - return "0%"; + return _("0%"); } float const fps = _encoder->current_frames_per_second (); @@ -100,7 +100,7 @@ TranscodeJob::status () const s << Job::status (); if (!finished ()) { - s << "; " << fixed << setprecision (1) << fps << " " << _("frames per second"); + s << N_("; ") << fixed << setprecision (1) << fps << N_(" ") << _("frames per second"); } return s.str (); diff --git a/src/lib/util.cc b/src/lib/util.cc index 4ee304600..892a7fd86 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -61,6 +61,8 @@ extern "C" { #include "sound_processor.h" #include "config.h" +#include "i18n.h" + using namespace std; using namespace boost; using libdcp::Size; @@ -83,9 +85,9 @@ seconds_to_hms (int s) m -= (h * 60); stringstream hms; - hms << h << ":"; + hms << h << N_(":"); hms.width (2); - hms << setfill ('0') << m << ":"; + hms << setfill ('0') << m << N_(":"); hms.width (2); hms << setfill ('0') << s; @@ -107,22 +109,22 @@ seconds_to_approximate_hms (int s) if (h > 0) { if (m > 30) { - ap << (h + 1) << " hours"; + ap << (h + 1) << N_(" ") << _("hours"); } else { if (h == 1) { - ap << "1 hour"; + ap << N_("1 ") << _("hour"); } else { - ap << h << " hours"; + ap << h << N_(" ") << _("hours"); } } } else if (m > 0) { if (m == 1) { - ap << "1 minute"; + ap << N_("1 ") << _("minute"); } else { - ap << m << " minutes"; + ap << m << N_(" ") << _("minutes"); } } else { - ap << s << " seconds"; + ap << s << N_(" ") << _("seconds"); } return ap.str (); @@ -135,12 +137,12 @@ seconds_to_approximate_hms (int s) static string demangle (string l) { - string::size_type const b = l.find_first_of ("("); + string::size_type const b = l.find_first_of (N_("(")); if (b == string::npos) { return l; } - string::size_type const p = l.find_last_of ("+"); + string::size_type const p = l.find_last_of (N_("+")); if (p == string::npos) { return l; } @@ -183,7 +185,7 @@ stacktrace (ostream& out, int levels) if (strings) { for (i = 0; i < size && (levels == 0 || i < size_t(levels)); i++) { - out << " " << demangle (strings[i]) << endl; + out << N_(" ") << demangle (strings[i]) << endl; } free (strings); @@ -198,7 +200,7 @@ static string ffmpeg_version_to_string (int v) { stringstream s; - s << ((v & 0xff0000) >> 16) << "." << ((v & 0xff00) >> 8) << "." << (v & 0xff); + s << ((v & 0xff0000) >> 16) << N_(".") << ((v & 0xff00) >> 8) << N_(".") << (v & 0xff); return s.str (); } @@ -207,16 +209,16 @@ string dependency_version_summary () { stringstream s; - s << "libopenjpeg " << opj_version () << ", " - << "libavcodec " << ffmpeg_version_to_string (avcodec_version()) << ", " - << "libavfilter " << ffmpeg_version_to_string (avfilter_version()) << ", " - << "libavformat " << ffmpeg_version_to_string (avformat_version()) << ", " - << "libavutil " << ffmpeg_version_to_string (avutil_version()) << ", " - << "libpostproc " << ffmpeg_version_to_string (postproc_version()) << ", " - << "libswscale " << ffmpeg_version_to_string (swscale_version()) << ", " - << MagickVersion << ", " - << "libssh " << ssh_version (0) << ", " - << "libdcp " << libdcp::version << " git " << libdcp::git_commit; + s << N_("libopenjpeg ") << opj_version () << N_(", ") + << N_("libavcodec ") << ffmpeg_version_to_string (avcodec_version()) << N_(", ") + << N_("libavfilter ") << ffmpeg_version_to_string (avfilter_version()) << N_(", ") + << N_("libavformat ") << ffmpeg_version_to_string (avformat_version()) << N_(", ") + << N_("libavutil ") << ffmpeg_version_to_string (avutil_version()) << N_(", ") + << N_("libpostproc ") << ffmpeg_version_to_string (postproc_version()) << N_(", ") + << N_("libswscale ") << ffmpeg_version_to_string (swscale_version()) << N_(", ") + << MagickVersion << N_(", ") + << N_("libssh ") << ssh_version (0) << N_(", ") + << N_("libdcp ") << libdcp::version << N_(" git ") << libdcp::git_commit; return s.str (); } @@ -233,6 +235,8 @@ seconds (struct timeval t) void dvdomatic_setup () { + bindtextdomain ("libdvdomatic", LOCALE_DIR); + avfilter_register_all (); Format::setup_formats (); @@ -252,7 +256,7 @@ string crop_string (Position start, libdcp::Size size) { stringstream s; - s << "crop=" << size.width << ":" << size.height << ":" << start.x << ":" << start.y; + s << N_("crop=") << size.width << N_(":") << size.height << N_(":") << start.x << N_(":") << start.y; return s.str (); } @@ -268,7 +272,7 @@ split_at_spaces_considering_quotes (string s) for (string::size_type i = 0; i < s.length(); ++i) { if (s[i] == ' ' && !in_quotes) { out.push_back (c); - c = ""; + c = N_(""); } else if (s[i] == '"') { in_quotes = !in_quotes; } else { @@ -423,7 +427,7 @@ DCPFrameRate::DCPFrameRate (float source_fps) } if (!best) { - throw EncodeError ("cannot find a suitable DCP frame rate for this source"); + throw EncodeError (_("cannot find a suitable DCP frame rate for this source")); } frames_per_second = best->dcp; @@ -476,13 +480,13 @@ colour_lut_index_to_name (int index) { switch (index) { case 0: - return "sRGB"; + return _("sRGB"); case 1: - return "Rec 709"; + return _("Rec 709"); } assert (false); - return ""; + return N_(""); } Socket::Socket (int timeout) @@ -519,7 +523,7 @@ Socket::connect (asio::ip::basic_resolver_entry const & endpoint) } while (ec == asio::error::would_block); if (ec || !_socket.is_open ()) { - throw NetworkError ("connect timed out"); + throw NetworkError (_("connect timed out")); } } @@ -656,13 +660,13 @@ string get_required_string (multimap const & kv, string k) { if (kv.count (k) > 1) { - throw StringError ("unexpected multiple keys in key-value set"); + throw StringError (N_("unexpected multiple keys in key-value set")); } multimap::const_iterator i = kv.find (k); if (i == kv.end ()) { - throw StringError (String::compose ("missing key %1 in key-value set", k)); + throw StringError (String::compose (_("missing key %1 in key-value set"), k)); } return i->second; @@ -686,12 +690,12 @@ string get_optional_string (multimap const & kv, string k) { if (kv.count (k) > 1) { - throw StringError ("unexpected multiple keys in key-value set"); + throw StringError (N_("unexpected multiple keys in key-value set")); } multimap::const_iterator i = kv.find (k); if (i == kv.end ()) { - return ""; + return N_(""); } return i->second; @@ -701,7 +705,7 @@ int get_optional_int (multimap const & kv, string k) { if (kv.count (k) > 1) { - throw StringError ("unexpected multiple keys in key-value set"); + throw StringError (N_("unexpected multiple keys in key-value set")); } multimap::const_iterator i = kv.find (k); @@ -870,7 +874,7 @@ still_image_file (string f) transform (ext.begin(), ext.end(), ext.begin(), ::tolower); - return (ext == ".tif" || ext == ".tiff" || ext == ".jpg" || ext == ".jpeg" || ext == ".png" || ext == ".bmp"); + return (ext == N_(".tif") || ext == N_(".tiff") || ext == N_(".jpg") || ext == N_(".jpeg") || ext == N_(".png") || ext == N_(".bmp")); } /** @return A pair containing CPU model name and the number of processors */ @@ -881,16 +885,16 @@ cpu_info () info.second = 0; #ifdef DVDOMATIC_POSIX - ifstream f ("/proc/cpuinfo"); + ifstream f (N_("/proc/cpuinfo")); while (f.good ()) { string l; getline (f, l); - if (boost::algorithm::starts_with (l, "model name")) { + if (boost::algorithm::starts_with (l, N_("model name"))) { string::size_type const c = l.find (':'); if (c != string::npos) { info.first = l.substr (c + 2); } - } else if (boost::algorithm::starts_with (l, "processor")) { + } else if (boost::algorithm::starts_with (l, N_("processor"))) { ++info.second; } } diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc index c1f48cb5e..891720f6b 100644 --- a/src/lib/video_decoder.cc +++ b/src/lib/video_decoder.cc @@ -25,6 +25,8 @@ #include "options.h" #include "job.h" +#include "i18n.h" + using boost::shared_ptr; using boost::optional; @@ -76,7 +78,7 @@ VideoDecoder::repeat_last_video () void VideoDecoder::signal_video (shared_ptr image, bool same, shared_ptr sub) { - TIMING ("Decoder emits %1", _video_frame); + TIMING (N_("Decoder emits %1"), _video_frame); Video (image, same, sub); ++_video_frame; diff --git a/src/lib/writer.cc b/src/lib/writer.cc index c2cc00328..d480d502a 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -29,6 +29,8 @@ #include "log.h" #include "dcp_video_frame.h" +#include "i18n.h" + using std::make_pair; using std::pair; using std::string; @@ -76,7 +78,7 @@ Writer::Writer (shared_ptr f) _sound_asset.reset ( new libdcp::SoundAsset ( _film->dir (_film->dcp_name()), - "audio.mxf", + N_("audio.mxf"), DCPFrameRate (_film->frames_per_second()).frames_per_second, dcp_audio_channels (_film->audio_channels()), dcp_audio_sample_rate (_film->audio_stream()->sample_rate()) @@ -147,9 +149,9 @@ try break; } - TIMING ("writer sleeps with a queue of %1", _queue.size()); + TIMING (N_("writer sleeps with a queue of %1"), _queue.size()); _condition.wait (lock); - TIMING ("writer wakes with a queue of %1", _queue.size()); + TIMING (N_("writer wakes with a queue of %1"), _queue.size()); } if (_finish && _queue.empty()) { @@ -168,7 +170,7 @@ try switch (qi.type) { case QueueItem::FULL: { - _film->log()->log (String::compose ("Writer FULL-writes %1 to MXF", qi.frame)); + _film->log()->log (String::compose (N_("Writer FULL-writes %1 to MXF"), qi.frame)); if (!qi.encoded) { qi.encoded.reset (new EncodedData (_film->j2c_path (qi.frame, false))); } @@ -179,14 +181,14 @@ try break; } case QueueItem::FAKE: - _film->log()->log (String::compose ("Writer FAKE-writes %1 to MXF", qi.frame)); + _film->log()->log (String::compose (N_("Writer FAKE-writes %1 to MXF"), qi.frame)); _picture_asset_writer->fake_write (qi.size); _last_written.reset (); ++_fake_written; break; case QueueItem::REPEAT: { - _film->log()->log (String::compose ("Writer REPEAT-writes %1 to MXF", qi.frame)); + _film->log()->log (String::compose (N_("Writer REPEAT-writes %1 to MXF"), qi.frame)); libdcp::FrameInfo const fin = _picture_asset_writer->write (_last_written->data(), _last_written->size()); _last_written->write_info (_film, qi.frame, fin); ++_repeat_written; @@ -215,7 +217,7 @@ try ++_pushed_to_disk; lock.unlock (); - _film->log()->log (String::compose ("Writer full (awaiting %1); pushes %2 to disk", _last_written_frame + 1, qi.frame)); + _film->log()->log (String::compose (N_("Writer full (awaiting %1); pushes %2 to disk"), _last_written_frame + 1, qi.frame)); qi.encoded->write (_film, qi.frame); lock.lock (); qi.encoded.reset (); @@ -270,14 +272,14 @@ Writer::finish () boost::filesystem::path to; to /= _film->dir (_film->dcp_name()); - to /= "video.mxf"; + to /= N_("video.mxf"); boost::filesystem::create_hard_link (from, to); /* And update the asset */ _picture_asset->set_directory (_film->dir (_film->dcp_name ())); - _picture_asset->set_file_name ("video.mxf"); + _picture_asset->set_file_name (N_("video.mxf")); if (_sound_asset) { _sound_asset->set_entry_point (_film->trim_start ()); @@ -302,7 +304,7 @@ Writer::finish () dcp.write_xml (); - _film->log()->log (String::compose ("Wrote %1 FULL, %2 FAKE, %3 REPEAT; %4 pushed to disk", _full_written, _fake_written, _repeat_written, _pushed_to_disk)); + _film->log()->log (String::compose (N_("Wrote %1 FULL, %2 FAKE, %3 REPEAT; %4 pushed to disk"), _full_written, _fake_written, _repeat_written, _pushed_to_disk)); } /** Tell the writer that frame `f' should be a repeat of the frame before it */ @@ -328,7 +330,7 @@ Writer::check_existing_picture_mxf () boost::filesystem::path p; p /= _film->video_mxf_dir (); p /= _film->video_mxf_filename (); - FILE* mxf = fopen (p.string().c_str(), "rb"); + FILE* mxf = fopen (p.string().c_str(), N_("rb")); if (!mxf) { return; } @@ -346,11 +348,11 @@ Writer::check_existing_picture_mxf () string const existing_hash = md5_digest (data.data(), data.size()); if (existing_hash != info.hash) { - _film->log()->log (String::compose ("Existing frame %1 failed hash check", _first_nonexistant_frame)); + _film->log()->log (String::compose (N_("Existing frame %1 failed hash check"), _first_nonexistant_frame)); break; } - _film->log()->log (String::compose ("Have existing frame %1", _first_nonexistant_frame)); + _film->log()->log (String::compose (N_("Have existing frame %1"), _first_nonexistant_frame)); ++_first_nonexistant_frame; } diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index d1760c327..52e551d2a 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -441,15 +441,9 @@ setup_i18n () if (wxLocale::IsAvailable (language)) { locale = new wxLocale (language, wxLOCALE_LOAD_DEFAULT); - + #ifdef __WXGTK__ - locale->AddCatalogLookupPathPrefix (wxT ("/usr")); - locale->AddCatalogLookupPathPrefix (wxT ("/usr/local")); - locale->AddCatalogLookupPathPrefix (wxT ("build/src/wx/mo")); - locale->AddCatalogLookupPathPrefix (wxT ("build/src/tools/mo")); - wxStandardPaths* paths = (wxStandardPaths*) &wxStandardPaths::Get(); - wxString prefix = paths->GetInstallPrefix(); - locale->AddCatalogLookupPathPrefix (prefix); + locale->AddCatalogLookupPathPrefix (wxT (LOCALE_DIR)); #endif locale->AddCatalog ("libdvdomatic-wx"); diff --git a/src/wx/config_dialog.cc b/src/wx/config_dialog.cc index 07e32a457..bf97d0d3a 100644 --- a/src/wx/config_dialog.cc +++ b/src/wx/config_dialog.cc @@ -154,7 +154,7 @@ ConfigDialog::ConfigDialog (wxWindow* parent) _reference_scaler->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (ConfigDialog::reference_scaler_changed), 0, this); pair p = Filter::ffmpeg_strings (config->reference_filters ()); - _reference_filters->SetLabel (std_to_wx (p.first + " " + p.second)); + _reference_filters->SetLabel (std_to_wx (p.first + N_(" ") + p.second)); _reference_filters_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (ConfigDialog::edit_reference_filters_clicked), 0, this); vector servers = config->servers (); @@ -313,7 +313,7 @@ ConfigDialog::reference_filters_changed (vector f) { Config::instance()->set_reference_filters (f); pair p = Filter::ffmpeg_strings (Config::instance()->reference_filters ()); - _reference_filters->SetLabel (std_to_wx (p.first + " " + p.second)); + _reference_filters->SetLabel (std_to_wx (p.first + N_(" ") + p.second)); } void diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 68291a812..b328f04c9 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -162,7 +162,7 @@ FilmEditor::make_film_panel () _still_duration = new wxSpinCtrl (_film_panel); still_control (_still_duration); s->Add (_still_duration, 1, wxEXPAND); - /* TRANSLATORS: `s' here is an abbreviation for seconds, the unit of time */ + /// TRANSLATORS: `s' here is an abbreviation for seconds, the unit of time still_control (add_label_to_sizer (s, _film_panel, _("s"))); grid->Add (s); } @@ -320,7 +320,7 @@ FilmEditor::make_audio_panel () wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); _audio_delay = new wxSpinCtrl (_audio_panel); s->Add (video_control (_audio_delay), 1); - /* TRANSLATORS: this is an abbreviation for milliseconds, the unit of time */ + /// TRANSLATORS: this is an abbreviation for milliseconds, the unit of time video_control (add_label_to_sizer (s, _audio_panel, _("ms"))); grid->Add (s); } @@ -342,9 +342,8 @@ FilmEditor::make_audio_panel () assert (MAX_AUDIO_CHANNELS == 6); - /* TRANSLATORS: these are the names of audio channels; Lfe (sub) is the low-frequency - enhancement channel (sub-woofer)./ - */ + /// TRANSLATORS: these are the names of audio channels; Lfe (sub) is the low-frequency + /// enhancement channel (sub-woofer). wxString const channels[] = { _("Left"), _("Right"), @@ -617,9 +616,9 @@ FilmEditor::film_changed (Film::Property p) break; case Film::LENGTH: if (_film->frames_per_second() > 0 && _film->length()) { - s << _film->length().get() << " frames; " << seconds_to_hms (_film->length().get() / _film->frames_per_second()); + s << _film->length().get() << " " << _("frames") << "; " << seconds_to_hms (_film->length().get() / _film->frames_per_second()); } else if (_film->length()) { - s << _film->length().get() << " frames"; + s << _film->length().get() << " " << _("frames"); } _length->SetLabel (std_to_wx (s.str ())); if (_film->length()) { @@ -754,7 +753,7 @@ FilmEditor::set_film (shared_ptr f) if (_film) { FileChanged (_film->directory ()); } else { - FileChanged (""); + FileChanged (N_("")); } film_changed (Film::NAME); @@ -1132,11 +1131,11 @@ FilmEditor::setup_audio_details () } else { stringstream s; if (_film->audio_stream()->channels() == 1) { - s << "1 channel"; + s << _("1 channel"); } else { - s << _film->audio_stream()->channels () << " channels"; + s << _film->audio_stream()->channels () << " " << _("channels"); } - s << ", " << _film->audio_stream()->sample_rate() << "Hz"; + s << ", " << _film->audio_stream()->sample_rate() << _("Hz"); _audio->SetLabel (std_to_wx (s.str ())); } } @@ -1169,7 +1168,7 @@ FilmEditor::setup_dcp_name () { string s = _film->dcp_name (true); if (s.length() > 28) { - _dcp_name->SetLabel (std_to_wx (s.substr (0, 28) + "...")); + _dcp_name->SetLabel (std_to_wx (s.substr (0, 28) + N_("..."))); _dcp_name->SetToolTip (std_to_wx (s)); } else { _dcp_name->SetLabel (std_to_wx (s)); diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 96656ce09..3705f38bb 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -51,7 +51,7 @@ FilmViewer::FilmViewer (shared_ptr f, wxWindow* p) : wxPanel (p) , _panel (new wxPanel (this)) , _slider (new wxSlider (this, wxID_ANY, 0, 0, 4096)) - , _play_button (new wxToggleButton (this, wxID_ANY, wxT ("Play"))) + , _play_button (new wxToggleButton (this, wxID_ANY, _("Play"))) , _display_frame_x (0) , _got_frame (false) , _clear_required (false) diff --git a/src/wx/properties_dialog.cc b/src/wx/properties_dialog.cc index a57aaf5b9..e93d06dbe 100644 --- a/src/wx/properties_dialog.cc +++ b/src/wx/properties_dialog.cc @@ -54,7 +54,7 @@ PropertiesDialog::PropertiesDialog (wxWindow* parent, shared_ptr film) _frames->SetLabel (std_to_wx (lexical_cast (_film->length().get()))); double const disk = ((double) _film->j2k_bandwidth() / 8) * _film->length().get() / (_film->frames_per_second () * 1073741824); stringstream s; - s << fixed << setprecision (1) << disk << "Gb"; + s << fixed << setprecision (1) << disk << _("Gb"); _disk->SetLabel (std_to_wx (s.str ())); } else { _frames->SetLabel (_("unknown")); diff --git a/src/wx/server_dialog.cc b/src/wx/server_dialog.cc index 1b5b71dc9..46e3f7127 100644 --- a/src/wx/server_dialog.cc +++ b/src/wx/server_dialog.cc @@ -27,7 +27,7 @@ ServerDialog::ServerDialog (wxWindow* parent, ServerDescription* server) if (server) { _server = server; } else { - _server = new ServerDescription ("localhost", 1); + _server = new ServerDescription (N_("localhost"), 1); } wxFlexGridSizer* table = new wxFlexGridSizer (2, 4, 4); diff --git a/wscript b/wscript index edf01784b..16ef91f3b 100644 --- a/wscript +++ b/wscript @@ -21,7 +21,9 @@ def configure(conf): if conf.options.target_windows: conf.load('winres') - conf.env.append_value('CXXFLAGS', ['-D__STDC_CONSTANT_MACROS', '-msse', '-mfpmath=sse', '-ffast-math', '-fno-strict-aliasing', '-Wall', '-Wno-attributes', '-Wextra']) + conf.env.append_value('CXXFLAGS', ['-D__STDC_CONSTANT_MACROS', '-msse', '-mfpmath=sse', '-ffast-math', '-fno-strict-aliasing', + '-Wall', '-Wno-attributes', '-Wextra', + '-DLOCALE_DIR="%s/share/locale"' % conf.env.prefix]) if conf.options.target_windows: conf.env.append_value('CXXFLAGS', ['-DDVDOMATIC_WINDOWS', '-DWIN32_LEAN_AND_MEAN', '-DBOOST_USE_WINDOWS_H', '-DUNICODE']) -- cgit v1.2.3 From 3940c9ceea90f99d18792bb9ea6074ca65d7fed9 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 28 Feb 2013 23:16:13 +0000 Subject: Build and install mo files from po. --- i18n.py | 16 ++++++---------- src/lib/wscript | 2 ++ src/tools/wscript | 6 ++---- src/wscript | 4 ---- src/wx/wscript | 6 ++---- wscript | 5 +---- 6 files changed, 13 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/i18n.py b/i18n.py index c22cbdb95..ab7f6843b 100644 --- a/i18n.py +++ b/i18n.py @@ -17,15 +17,11 @@ def pot(dir, sources, name, all = False): os.system('xgettext -d %s -s --keyword=_ --add-comments=/ -p %s -o %s.pot %s' % (name, os.path.join('build', dir), name, s)) -def po_to_mo(dir, name): - for f in glob.glob(os.path.join(dir, 'po', '*.po')): - +def po_to_mo(dir, name, bld): + for f in glob.glob(os.path.join(os.getcwd(), dir, 'po', '*.po')): lang = os.path.basename(f).replace('.po', '') - out = os.path.join('build', dir, 'mo', lang, '%s.mo' % name) - try: - os.makedirs(os.path.dirname(out)) - except: - pass + po = os.path.join('po', '%s.po' % lang) + mo = os.path.join('mo', lang, '%s.mo' % name) - os.system('msgfmt %s -o %s' % (f, out)) - Logs.info('%s -> %s' % (f, out)) + bld(rule = 'msgfmt ${SRC} -o ${TGT}', source = bld.path.make_node(po), target = bld.path.get_bld().make_node(mo)) + bld.install_files(os.path.join('${PREFIX}', 'share', 'locale', lang, 'LC_MESSAGES'), mo) diff --git a/src/lib/wscript b/src/lib/wscript index 59047c70d..6ddb94851 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -68,5 +68,7 @@ def build(bld): obj.source = sources obj.target = 'dvdomatic' + i18n.po_to_mo(os.path.join('src', 'lib'), 'libdvdomatic', bld) + def pot(bld): i18n.pot(os.path.join('src', 'lib'), sources, 'libdvdomatic') diff --git a/src/tools/wscript b/src/tools/wscript index de130ce17..64d5efe56 100644 --- a/src/tools/wscript +++ b/src/tools/wscript @@ -23,9 +23,7 @@ def build(bld): obj.source += ' ../../windows/dvdomatic.rc' obj.target = t + i18n.po_to_mo(os.path.join('src', 'tools'), 'dvdomatic', bld) + def pot(bld): i18n.pot(os.path.join('src', 'tools'), 'dvdomatic.cc', 'dvdomatic') - -def mo(bld): - i18n.po_to_mo(os.path.join('src', 'tools'), 'dvdomatic') - diff --git a/src/wscript b/src/wscript index abe39894d..f7f888acd 100644 --- a/src/wscript +++ b/src/wscript @@ -12,7 +12,3 @@ def pot(bld): bld.recurse('lib') bld.recurse('wx') bld.recurse('tools') - -def mo(bld): - bld.recurse('wx') - bld.recurse('tools') diff --git a/src/wx/wscript b/src/wx/wscript index a0a4bbe8b..92ff440cd 100644 --- a/src/wx/wscript +++ b/src/wx/wscript @@ -38,9 +38,7 @@ def build(bld): obj.source = sources obj.target = 'dvdomatic-wx' + i18n.po_to_mo(os.path.join('src', 'wx'), 'libdvdomatic-wx', bld) + def pot(bld): i18n.pot(os.path.join('src', 'wx'), sources, 'libdvdomatic-wx') - -def mo(bld): - i18n.po_to_mo(os.path.join('src', 'wx'), 'libdvdomatic-wx') - diff --git a/wscript b/wscript index 16ef91f3b..f3df9cfed 100644 --- a/wscript +++ b/wscript @@ -23,7 +23,7 @@ def configure(conf): conf.env.append_value('CXXFLAGS', ['-D__STDC_CONSTANT_MACROS', '-msse', '-mfpmath=sse', '-ffast-math', '-fno-strict-aliasing', '-Wall', '-Wno-attributes', '-Wextra', - '-DLOCALE_DIR="%s/share/locale"' % conf.env.prefix]) + '-DLOCALE_DIR="%s/share/locale"' % conf.env['PREFIX']]) if conf.options.target_windows: conf.env.append_value('CXXFLAGS', ['-DDVDOMATIC_WINDOWS', '-DWIN32_LEAN_AND_MEAN', '-DBOOST_USE_WINDOWS_H', '-DUNICODE']) @@ -267,6 +267,3 @@ def post(ctx): def pot(bld): bld.recurse('src') - -def mo(bld): - bld.recurse('src') -- cgit v1.2.3 From cbc6c5863ec336f0843a87a71e9d7a25a5e59286 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 1 Mar 2013 17:10:48 +0000 Subject: Hopefully fix up gettext in both libdvdomatic and the wx code. --- run/dvdomatic | 2 +- src/lib/util.cc | 3 ++- src/tools/dvdomatic.cc | 2 +- wscript | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/run/dvdomatic b/run/dvdomatic index 31fd09fb9..147c001cd 100755 --- a/run/dvdomatic +++ b/run/dvdomatic @@ -9,7 +9,7 @@ elif [ "$1" == "--valgrind" ]; then valgrind --tool="memcheck" build/src/tools/dvdomatic $* elif [ "$1" == "--i18n" ]; then shift - LANG=fr_FR.UTF8 build/src/tools/dvdomatic "$*" + LANGUAGE=fr_FR.UTF8 LANG=fr_FR.UTF8 build/src/tools/dvdomatic "$*" else build/src/tools/dvdomatic "$*" fi diff --git a/src/lib/util.cc b/src/lib/util.cc index 892a7fd86..3d70a3122 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -235,7 +235,8 @@ seconds (struct timeval t) void dvdomatic_setup () { - bindtextdomain ("libdvdomatic", LOCALE_DIR); + bindtextdomain ("libdvdomatic", LOCALE_PREFIX); + setlocale (LC_ALL, ""); avfilter_register_all (); diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 52e551d2a..024f5a53e 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -443,7 +443,7 @@ setup_i18n () locale = new wxLocale (language, wxLOCALE_LOAD_DEFAULT); #ifdef __WXGTK__ - locale->AddCatalogLookupPathPrefix (wxT (LOCALE_DIR)); + locale->AddCatalogLookupPathPrefix (wxT (LOCALE_PREFIX "/locale")); #endif locale->AddCatalog ("libdvdomatic-wx"); diff --git a/wscript b/wscript index f3df9cfed..019858100 100644 --- a/wscript +++ b/wscript @@ -23,7 +23,7 @@ def configure(conf): conf.env.append_value('CXXFLAGS', ['-D__STDC_CONSTANT_MACROS', '-msse', '-mfpmath=sse', '-ffast-math', '-fno-strict-aliasing', '-Wall', '-Wno-attributes', '-Wextra', - '-DLOCALE_DIR="%s/share/locale"' % conf.env['PREFIX']]) + '-DLOCALE_PREFIX="%s/share/locale"' % conf.env['PREFIX']]) if conf.options.target_windows: conf.env.append_value('CXXFLAGS', ['-DDVDOMATIC_WINDOWS', '-DWIN32_LEAN_AND_MEAN', '-DBOOST_USE_WINDOWS_H', '-DUNICODE']) -- cgit v1.2.3 From 23368040ff9defb0e999259ccda41015c1c3cdaa Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 1 Mar 2013 17:30:30 +0000 Subject: Missing file. --- src/lib/i18n.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/lib/i18n.h (limited to 'src') diff --git a/src/lib/i18n.h b/src/lib/i18n.h new file mode 100644 index 000000000..46bb1d565 --- /dev/null +++ b/src/lib/i18n.h @@ -0,0 +1,23 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include + +#define _(x) dgettext ("libdvdomatic", x) +#define N_(x) x -- cgit v1.2.3 From bc83f9ba294697528cee2be41ec6aac905371f1f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 1 Mar 2013 17:42:50 +0000 Subject: Fix bad search and replace. --- src/tools/dvdomatic.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 024f5a53e..5f06b6786 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -179,10 +179,10 @@ setup_menu (wxMenuBar* m) wxMenu* help = new wxMenu; add_item (help, _("About"), ID_help_about, ALWAYS); - m->Append (file, _(_("&File"))); - m->Append (edit, _(_("&Edit"))); - m->Append (jobs_menu, _(_("&Jobs"))); - m->Append (help, _(_("&Help"))); + m->Append (file, _("&File")); + m->Append (edit, _("&Edit")); + m->Append (jobs_menu, _("&Jobs")); + m->Append (help, _("&Help")); } bool -- cgit v1.2.3 From 6ff79076d4a92dc6530a27e2a6cb3e07b6209821 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 1 Mar 2013 17:58:04 +0000 Subject: Fix for wx 2.8. --- src/tools/dvdomatic.cc | 4 ++-- src/wx/config_dialog.cc | 4 ++-- src/wx/film_editor.cc | 4 ++-- src/wx/server_dialog.cc | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 5f06b6786..ab34924aa 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -446,8 +446,8 @@ setup_i18n () locale->AddCatalogLookupPathPrefix (wxT (LOCALE_PREFIX "/locale")); #endif - locale->AddCatalog ("libdvdomatic-wx"); - locale->AddCatalog ("dvdomatic"); + locale->AddCatalog (wxT ("libdvdomatic-wx")); + locale->AddCatalog (wxT ("dvdomatic")); if (!locale->IsOk()) { delete locale; diff --git a/src/wx/config_dialog.cc b/src/wx/config_dialog.cc index bf97d0d3a..b28c350ea 100644 --- a/src/wx/config_dialog.cc +++ b/src/wx/config_dialog.cc @@ -154,7 +154,7 @@ ConfigDialog::ConfigDialog (wxWindow* parent) _reference_scaler->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (ConfigDialog::reference_scaler_changed), 0, this); pair p = Filter::ffmpeg_strings (config->reference_filters ()); - _reference_filters->SetLabel (std_to_wx (p.first + N_(" ") + p.second)); + _reference_filters->SetLabel (std_to_wx (p.first) + N_(" ") + std_to_wx (p.second)); _reference_filters_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (ConfigDialog::edit_reference_filters_clicked), 0, this); vector servers = config->servers (); @@ -313,7 +313,7 @@ ConfigDialog::reference_filters_changed (vector f) { Config::instance()->set_reference_filters (f); pair p = Filter::ffmpeg_strings (Config::instance()->reference_filters ()); - _reference_filters->SetLabel (std_to_wx (p.first + N_(" ") + p.second)); + _reference_filters->SetLabel (std_to_wx (p.first) + N_(" ") + std_to_wx (p.second)); } void diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index b328f04c9..850466445 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -753,7 +753,7 @@ FilmEditor::set_film (shared_ptr f) if (_film) { FileChanged (_film->directory ()); } else { - FileChanged (N_("")); + FileChanged (wx_to_std (N_(""))); } film_changed (Film::NAME); @@ -1168,7 +1168,7 @@ FilmEditor::setup_dcp_name () { string s = _film->dcp_name (true); if (s.length() > 28) { - _dcp_name->SetLabel (std_to_wx (s.substr (0, 28) + N_("..."))); + _dcp_name->SetLabel (std_to_wx (s.substr (0, 28)) + N_("...")); _dcp_name->SetToolTip (std_to_wx (s)); } else { _dcp_name->SetLabel (std_to_wx (s)); diff --git a/src/wx/server_dialog.cc b/src/wx/server_dialog.cc index 46e3f7127..7a9cf95c7 100644 --- a/src/wx/server_dialog.cc +++ b/src/wx/server_dialog.cc @@ -27,7 +27,7 @@ ServerDialog::ServerDialog (wxWindow* parent, ServerDescription* server) if (server) { _server = server; } else { - _server = new ServerDescription (N_("localhost"), 1); + _server = new ServerDescription (wx_to_std (N_("localhost")), 1); } wxFlexGridSizer* table = new wxFlexGridSizer (2, 4, 4); -- cgit v1.2.3 From f4c18d89c2fd68a0dbf03b4c72e25cc8214a3a5b Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 1 Mar 2013 19:51:58 +0000 Subject: Improve smoothing a little. --- src/wx/audio_plot.cc | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/wx/audio_plot.cc b/src/wx/audio_plot.cc index 2098adb40..068b74ffd 100644 --- a/src/wx/audio_plot.cc +++ b/src/wx/audio_plot.cc @@ -213,14 +213,39 @@ AudioPlot::plot_rms (wxGraphicsPath& path, int channel) const path.MoveToPoint (_db_label_width, y_for_linear (_analysis->get_point(channel, 0)[AudioPoint::RMS])); list smoothing; + int const N = _analysis->points(channel); + + float const first = _analysis->get_point(channel, 0)[AudioPoint::RMS]; + float const last = _analysis->get_point(channel, N - 1)[AudioPoint::RMS]; + + int const before = _smoothing / 2; + int const after = _smoothing - before; + + /* Pre-load the smoothing list */ + for (int i = 0; i < before; ++i) { + smoothing.push_back (first); + } + for (int i = 0; i < after; ++i) { + if (i < N) { + smoothing.push_back (_analysis->get_point(channel, i)[AudioPoint::RMS]); + } else { + smoothing.push_back (last); + } + } + for (int i = 0; i < N; ++i) { - smoothing.push_back (_analysis->get_point(channel, i)[AudioPoint::RMS]); - if (int(smoothing.size()) > _smoothing) { - smoothing.pop_front (); + int const next_for_window = i + after; + + if (next_for_window < N) { + smoothing.push_back (_analysis->get_point(channel, i)[AudioPoint::RMS]); + } else { + smoothing.push_back (last); } + smoothing.pop_front (); + float p = 0; for (list::const_iterator j = smoothing.begin(); j != smoothing.end(); ++j) { p += pow (*j, 2); @@ -228,8 +253,7 @@ AudioPlot::plot_rms (wxGraphicsPath& path, int channel) const p = sqrt (p / smoothing.size ()); - int const ind = max (0, i - int(smoothing.size() / 2)); - path.AddLineToPoint (_db_label_width + ind * _x_scale, y_for_linear (p)); + path.AddLineToPoint (_db_label_width + i * _x_scale, y_for_linear (p)); } } -- cgit v1.2.3 From 6a516da9a403ce05b2b78b3cf1376f4dfe4be3fe Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 1 Mar 2013 21:35:41 +0000 Subject: Make film hold its DCP frame rate. --- src/lib/ab_transcoder.cc | 2 +- src/lib/analyse_audio_job.cc | 2 +- src/lib/dcp_video_frame.cc | 4 +- src/lib/dcp_video_frame.h | 4 +- src/lib/encoder.cc | 8 +- src/lib/film.cc | 45 +++++++---- src/lib/film.h | 19 +++-- src/lib/transcode_job.cc | 4 +- src/lib/transcoder.cc | 2 +- src/lib/util.cc | 37 +++++---- src/lib/util.h | 10 +-- src/lib/writer.cc | 15 ++-- src/wx/film_editor.cc | 16 ++-- src/wx/film_editor.h | 4 +- src/wx/film_viewer.cc | 6 +- src/wx/properties_dialog.cc | 4 +- test/metadata.ref | 5 +- test/test.cc | 183 +++++++++++++++++++++++-------------------- 18 files changed, 210 insertions(+), 160 deletions(-) (limited to 'src') diff --git a/src/lib/ab_transcoder.cc b/src/lib/ab_transcoder.cc index f47a99fda..4ed5d02ca 100644 --- a/src/lib/ab_transcoder.cc +++ b/src/lib/ab_transcoder.cc @@ -60,7 +60,7 @@ ABTranscoder::ABTranscoder ( if (_film_a->audio_stream()) { shared_ptr st = _film_a->audio_stream(); - _matcher.reset (new Matcher (_film_a->log(), st->sample_rate(), _film_a->frames_per_second())); + _matcher.reset (new Matcher (_film_a->log(), st->sample_rate(), _film_a->source_frame_rate())); _delay_line.reset (new DelayLine (_film_a->log(), st->channels(), _film_a->audio_delay() * st->sample_rate() / 1000)); _gain.reset (new Gain (_film_a->log(), _film_a->audio_gain())); } diff --git a/src/lib/analyse_audio_job.cc b/src/lib/analyse_audio_job.cc index ca316f70e..41f918f34 100644 --- a/src/lib/analyse_audio_job.cc +++ b/src/lib/analyse_audio_job.cc @@ -66,7 +66,7 @@ AnalyseAudioJob::run () decoders.audio->set_audio_stream (_film->audio_stream ()); decoders.audio->Audio.connect (bind (&AnalyseAudioJob::audio, this, _1)); - int64_t total_audio_frames = video_frames_to_audio_frames (_film->length().get(), _film->audio_stream()->sample_rate(), _film->frames_per_second()); + int64_t total_audio_frames = video_frames_to_audio_frames (_film->length().get(), _film->audio_stream()->sample_rate(), _film->source_frame_rate()); _samples_per_point = total_audio_frames / _num_points; _current.resize (_film->audio_stream()->channels ()); diff --git a/src/lib/dcp_video_frame.cc b/src/lib/dcp_video_frame.cc index 098d222cd..67617c63c 100644 --- a/src/lib/dcp_video_frame.cc +++ b/src/lib/dcp_video_frame.cc @@ -80,7 +80,7 @@ using libdcp::Size; DCPVideoFrame::DCPVideoFrame ( shared_ptr yuv, shared_ptr sub, Size out, int p, int subtitle_offset, float subtitle_scale, - Scaler const * s, int f, float fps, string pp, int clut, int bw, Log* l + Scaler const * s, int f, int dcp_fps, string pp, int clut, int bw, Log* l ) : _input (yuv) , _subtitle (sub) @@ -90,7 +90,7 @@ DCPVideoFrame::DCPVideoFrame ( , _subtitle_scale (subtitle_scale) , _scaler (s) , _frame (f) - , _frames_per_second (DCPFrameRate(fps).frames_per_second) + , _frames_per_second (dcp_fps) , _post_process (pp) , _colour_lut (clut) , _j2k_bandwidth (bw) diff --git a/src/lib/dcp_video_frame.h b/src/lib/dcp_video_frame.h index ab458b58f..6794765ac 100644 --- a/src/lib/dcp_video_frame.h +++ b/src/lib/dcp_video_frame.h @@ -107,7 +107,7 @@ class DCPVideoFrame public: DCPVideoFrame ( boost::shared_ptr, boost::shared_ptr, libdcp::Size, - int, int, float, Scaler const *, int, float, std::string, int, int, Log * + int, int, float, Scaler const *, int, int, std::string, int, int, Log * ); virtual ~DCPVideoFrame (); @@ -130,7 +130,7 @@ private: float _subtitle_scale; Scaler const * _scaler; ///< scaler to use int _frame; ///< frame index within the DCP's intrinsic duration - int _frames_per_second; ///< Frames per second that we will use for the DCP (rounded) + int _frames_per_second; ///< Frames per second that we will use for the DCP std::string _post_process; ///< FFmpeg post-processing string to use int _colour_lut; ///< Colour look-up table to use int _j2k_bandwidth; ///< J2K bandwidth to use diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 3cc643cd6..687dfdd2b 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -233,9 +233,9 @@ Encoder::frame_done () void Encoder::process_video (shared_ptr image, bool same, boost::shared_ptr sub) { - DCPFrameRate dfr (_film->frames_per_second ()); + FrameRateConversion frc (_film->source_frame_rate(), _film->dcp_frame_rate()); - if (dfr.skip && (_video_frames_in % 2)) { + if (frc.skip && (_video_frames_in % 2)) { ++_video_frames_in; return; } @@ -273,7 +273,7 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptrformat()->dcp_size(), _film->format()->dcp_padding (_film), _film->subtitle_offset(), _film->subtitle_scale(), - _film->scaler(), _video_frames_out, _film->frames_per_second(), s.second, + _film->scaler(), _video_frames_out, _film->dcp_frame_rate(), s.second, _film->colour_lut(), _film->j2k_bandwidth(), _film->log() ) @@ -286,7 +286,7 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptrrepeat (_video_frames_out); ++_video_frames_out; frame_done (); diff --git a/src/lib/film.cc b/src/lib/film.cc index 510158e94..a661adcc6 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -74,7 +74,7 @@ using boost::starts_with; using boost::optional; using libdcp::Size; -int const Film::state_version = 3; +int const Film::state_version = 4; /** Construct a Film object in a given directory, reading any metadata * file that exists in that directory. An exception will be thrown if @@ -103,7 +103,8 @@ Film::Film (string d, bool must_exist) , _colour_lut (0) , _j2k_bandwidth (200000000) , _dci_metadata (Config::instance()->default_dci_metadata ()) - , _frames_per_second (0) + , _dcp_frame_rate (0) + , _source_frame_rate (0) , _dirty (false) { set_dci_date_today (); @@ -175,6 +176,7 @@ Film::Film (Film const & o) , _j2k_bandwidth (o._j2k_bandwidth) , _dci_metadata (o._dci_metadata) , _dci_date (o._dci_date) + , _dcp_frame_rate (o._dcp_frame_rate) , _size (o._size) , _length (o._length) , _dcp_intrinsic_duration (o._dcp_intrinsic_duration) @@ -182,7 +184,7 @@ Film::Film (Film const & o) , _content_audio_streams (o._content_audio_streams) , _external_audio_stream (o._external_audio_stream) , _subtitle_streams (o._subtitle_streams) - , _frames_per_second (o._frames_per_second) + , _source_frame_rate (o._source_frame_rate) , _dirty (o._dirty) { @@ -204,6 +206,7 @@ Film::video_state_identifier () const s << format()->id() << N_("_") << content_digest() << N_("_") << crop().left << N_("_") << crop().right << N_("_") << crop().top << N_("_") << crop().bottom + << N_("_") << _dcp_frame_rate << N_("_") << f.first << N_("_") << f.second << N_("_") << scaler()->id() << N_("_") << j2k_bandwidth() @@ -441,6 +444,7 @@ Film::write_metadata () const f << N_("j2k_bandwidth ") << _j2k_bandwidth << N_("\n"); _dci_metadata.write (f); f << N_("dci_date ") << boost::gregorian::to_iso_string (_dci_date) << N_("\n"); + f << N_("dcp_frame_rate ") << _dcp_frame_rate << "\n"; f << N_("width ") << _size.width << N_("\n"); f << N_("height ") << _size.height << N_("\n"); f << N_("length ") << _length.get_value_or(0) << N_("\n"); @@ -457,7 +461,7 @@ Film::write_metadata () const f << N_("subtitle_stream ") << (*i)->to_string () << N_("\n"); } - f << N_("frames_per_second ") << _frames_per_second << N_("\n"); + f << N_("source_frame_rate ") << _source_frame_rate << N_("\n"); _dirty = false; } @@ -569,6 +573,8 @@ Film::read_metadata () _j2k_bandwidth = atoi (v.c_str ()); } else if (k == N_("dci_date")) { _dci_date = boost::gregorian::from_undelimited_string (v); + } else if (k == "dcp_frame_rate") { + _dcp_frame_rate = atoi (v.c_str ()); } _dci_metadata.read (k, v); @@ -596,8 +602,8 @@ Film::read_metadata () _external_audio_stream = audio_stream_factory (v, version); } else if (k == N_("subtitle_stream")) { _subtitle_streams.push_back (subtitle_stream_factory (v, version)); - } else if (k == N_("frames_per_second")) { - _frames_per_second = atof (v.c_str ()); + } else if (k == N_("source_frame_rate") || (version < 4 && k == "frames_per_second")) { + _source_frame_rate = atof (v.c_str ()); } } @@ -707,7 +713,7 @@ Film::target_audio_sample_rate () const /* Resample to a DCI-approved sample rate */ double t = dcp_audio_sample_rate (audio_stream()->sample_rate()); - DCPFrameRate dfr (frames_per_second ()); + FrameRateConversion frc (source_frame_rate(), dcp_frame_rate()); /* Compensate if the DCP is being run at a different frame rate to the source; that is, if the video is run such that it will @@ -715,8 +721,8 @@ Film::target_audio_sample_rate () const skip/repeat doesn't come into effect here. */ - if (dfr.change_speed) { - t *= _frames_per_second * dfr.factor() / dfr.frames_per_second; + if (frc.change_speed) { + t *= source_frame_rate() * frc.factor() / dcp_frame_rate(); } return rint (t); @@ -725,7 +731,7 @@ Film::target_audio_sample_rate () const int Film::still_duration_in_frames () const { - return still_duration() * frames_per_second(); + return still_duration() * source_frame_rate(); } /** @return a DCI-compliant name for a DCP of this film */ @@ -898,7 +904,7 @@ Film::set_content (string c) Decoders d = decoder_factory (shared_from_this(), DecodeOptions()); set_size (d.video->native_size ()); - set_frames_per_second (d.video->frames_per_second ()); + set_source_frame_rate (d.video->frames_per_second ()); set_subtitle_streams (d.video->subtitle_streams ()); if (d.audio) { set_content_audio_streams (d.audio->audio_streams ()); @@ -1236,6 +1242,17 @@ Film::set_dci_metadata (DCIMetadata m) signal_changed (DCI_METADATA); } + +void +Film::set_dcp_frame_rate (int f) +{ + { + boost::mutex::scoped_lock lm (_state_mutex); + _dcp_frame_rate = f; + } + signal_changed (DCP_FRAME_RATE); +} + void Film::set_size (libdcp::Size s) { @@ -1307,13 +1324,13 @@ Film::set_subtitle_streams (vector > s) } void -Film::set_frames_per_second (float f) +Film::set_source_frame_rate (float f) { { boost::mutex::scoped_lock lm (_state_mutex); - _frames_per_second = f; + _source_frame_rate = f; } - signal_changed (FRAMES_PER_SECOND); + signal_changed (SOURCE_FRAME_RATE); } void diff --git a/src/lib/film.h b/src/lib/film.h index 847ab434e..9921acbb4 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -148,7 +148,8 @@ public: DCP_INTRINSIC_DURATION, CONTENT_AUDIO_STREAMS, SUBTITLE_STREAMS, - FRAMES_PER_SECOND, + SOURCE_FRAME_RATE, + DCP_FRAME_RATE }; @@ -285,6 +286,11 @@ public: boost::mutex::scoped_lock lm (_state_mutex); return _dci_metadata; } + + int dcp_frame_rate () const { + boost::mutex::scoped_lock lm (_state_mutex); + return _dcp_frame_rate; + } libdcp::Size size () const { boost::mutex::scoped_lock lm (_state_mutex); @@ -311,13 +317,13 @@ public: return _subtitle_streams; } - float frames_per_second () const { + float source_frame_rate () const { boost::mutex::scoped_lock lm (_state_mutex); if (content_type() == STILL) { return 24; } - return _frames_per_second; + return _source_frame_rate; } boost::shared_ptr audio_stream () const; @@ -355,6 +361,7 @@ public: void set_colour_lut (int); void set_j2k_bandwidth (int); void set_dci_metadata (DCIMetadata); + void set_dcp_frame_rate (int); void set_size (libdcp::Size); void set_length (SourceFrame); void unset_length (); @@ -362,7 +369,7 @@ public: void set_content_digest (std::string); void set_content_audio_streams (std::vector >); void set_subtitle_streams (std::vector >); - void set_frames_per_second (float); + void set_source_frame_rate (float); /** Emitted when some property has changed */ mutable boost::signals2::signal Changed; @@ -461,6 +468,8 @@ private: DCIMetadata _dci_metadata; /** The date that we should use in a DCI name */ boost::gregorian::date _dci_date; + /** Frames per second to run our DCP at */ + int _dcp_frame_rate; /* Data which are cached to speed things up */ @@ -478,7 +487,7 @@ private: /** the subtitle streams that we can use */ std::vector > _subtitle_streams; /** Frames per second of the source */ - float _frames_per_second; + float _source_frame_rate; /** true if our state has changed since we last saved it */ mutable bool _dirty; diff --git a/src/lib/transcode_job.cc b/src/lib/transcode_job.cc index 61fad2e2b..f7cc500fe 100644 --- a/src/lib/transcode_job.cc +++ b/src/lib/transcode_job.cc @@ -120,8 +120,8 @@ TranscodeJob::remaining_time () const /* Compute approximate proposed length here, as it's only here that we need it */ int length = _film->length().get(); - DCPFrameRate const dfr (_film->frames_per_second ()); - if (dfr.skip) { + FrameRateConversion const frc (_film->source_frame_rate(), _film->dcp_frame_rate()); + if (frc.skip) { length /= 2; } /* If we are repeating it shouldn't affect transcode time, so don't take it into account */ diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc index 959fac857..9720ca56a 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -57,7 +57,7 @@ Transcoder::Transcoder (shared_ptr f, DecodeOptions o, Job* j, shared_ptr< if (f->audio_stream()) { shared_ptr st = f->audio_stream(); - _matcher.reset (new Matcher (f->log(), st->sample_rate(), f->frames_per_second())); + _matcher.reset (new Matcher (f->log(), st->sample_rate(), f->source_frame_rate())); _delay_line.reset (new DelayLine (f->log(), st->channels(), f->audio_delay() * st->sample_rate() / 1000)); _gain.reset (new Gain (f->log(), f->audio_gain())); } diff --git a/src/lib/util.cc b/src/lib/util.cc index de69636da..85a04ed17 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -375,21 +375,12 @@ public: , dcp (dcp_) {} - bool skip () const { - return !about_equal (source, dcp) && source > dcp; - } - - bool repeat () const { - return !about_equal (source, dcp) && source < dcp; - } - float source; int dcp; }; -/** @param fps Arbitrary source frames-per-second value */ -/** XXX: this could be slow-ish */ -DCPFrameRate::DCPFrameRate (float source_fps) +int +best_dcp_frame_rate (float source_fps) { list const allowed_dcp_frame_rates = Config::instance()->allowed_dcp_frame_rates (); @@ -427,14 +418,8 @@ DCPFrameRate::DCPFrameRate (float source_fps) ++i; } - if (!best) { - throw EncodeError (_("cannot find a suitable DCP frame rate for this source")); - } - - frames_per_second = best->dcp; - skip = best->skip (); - repeat = best->repeat (); - change_speed = !about_equal (source_fps * factor(), frames_per_second); + assert (best); + return best->dcp; } /** @param An arbitrary sampling rate. @@ -962,3 +947,17 @@ AudioMapping::dcp_channels () const return _source_channels; } + +FrameRateConversion::FrameRateConversion (float source, int dcp) + : skip (false) + , repeat (false) + , change_speed (false) +{ + if (fabs (source / 2.0 - dcp) < (fabs (source - dcp))) { + skip = true; + } else if (fabs (source * 2 - dcp) < fabs (source - dcp)) { + repeat = true; + } + + change_speed = !about_equal (source * factor(), dcp); +} diff --git a/src/lib/util.h b/src/lib/util.h index 22c6ea95b..103907151 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -62,9 +62,9 @@ extern std::string audio_channel_name (int); typedef int SourceFrame; -struct DCPFrameRate +struct FrameRateConversion { - DCPFrameRate (float); + FrameRateConversion (float, int); /** @return factor by which to multiply a source frame rate to get the effective rate after any skip or repeat has happened. @@ -79,14 +79,12 @@ struct DCPFrameRate return 1; } - /** frames per second for the DCP */ - int frames_per_second; /** true to skip every other frame */ bool skip; /** true to repeat every frame once */ bool repeat; /** true if this DCP will run its video faster or slower than the source - * without taking into account `repeat'. + * without taking into account `repeat' nor `skip'. * (e.g. change_speed will be true if * source is 29.97fps, DCP is 30fps * source is 14.50fps, DCP is 30fps @@ -97,6 +95,8 @@ struct DCPFrameRate bool change_speed; }; +int best_dcp_frame_rate (float); + enum ContentType { STILL, ///< content is still images VIDEO ///< content is a video diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 334ecec65..5a2f7c9a9 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -67,8 +67,8 @@ Writer::Writer (shared_ptr f) new libdcp::MonoPictureAsset ( _film->video_mxf_dir (), _film->video_mxf_filename (), - DCPFrameRate (_film->frames_per_second()).frames_per_second, - _film->format()->dcp_size() + _film->dcp_frame_rate (), + _film->format()->dcp_size () ) ); @@ -81,7 +81,7 @@ Writer::Writer (shared_ptr f) new libdcp::SoundAsset ( _film->dir (_film->dcp_name()), N_("audio.mxf"), - DCPFrameRate (_film->frames_per_second()).frames_per_second, + _film->dcp_frame_rate (), m.dcp_channels (), dcp_audio_sample_rate (_film->audio_stream()->sample_rate()) ) @@ -289,10 +289,15 @@ Writer::finish () } libdcp::DCP dcp (_film->dir (_film->dcp_name())); - DCPFrameRate dfr (_film->frames_per_second ()); shared_ptr cpl ( - new libdcp::CPL (_film->dir (_film->dcp_name()), _film->dcp_name(), _film->dcp_content_type()->libdcp_kind (), frames, dfr.frames_per_second) + new libdcp::CPL ( + _film->dir (_film->dcp_name()), + _film->dcp_name(), + _film->dcp_content_type()->libdcp_kind (), + frames, + _film->dcp_frame_rate () + ) ); dcp.add_cpl (cpl); diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 362243ef3..0a6a35273 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -127,8 +127,8 @@ FilmEditor::make_film_panel () grid->Add (_dcp_content_type); video_control (add_label_to_sizer (grid, _film_panel, _("Original Frame Rate"))); - _frames_per_second = new wxStaticText (_film_panel, wxID_ANY, wxT ("")); - grid->Add (video_control (_frames_per_second), 1, wxALIGN_CENTER_VERTICAL); + _source_frame_rate = new wxStaticText (_film_panel, wxID_ANY, wxT ("")); + grid->Add (video_control (_source_frame_rate), 1, wxALIGN_CENTER_VERTICAL); video_control (add_label_to_sizer (grid, _film_panel, _("Original Size"))); _original_size = new wxStaticText (_film_panel, wxID_ANY, wxT ("")); @@ -596,9 +596,9 @@ FilmEditor::film_changed (Film::Property p) checked_set (_name, _film->name()); setup_dcp_name (); break; - case Film::FRAMES_PER_SECOND: - s << fixed << setprecision(2) << _film->frames_per_second(); - _frames_per_second->SetLabel (std_to_wx (s.str ())); + case Film::SOURCE_FRAME_RATE: + s << fixed << setprecision(2) << _film->source_frame_rate(); + _source_frame_rate->SetLabel (std_to_wx (s.str ())); break; case Film::SIZE: if (_film->size().width == 0 && _film->size().height == 0) { @@ -609,8 +609,8 @@ FilmEditor::film_changed (Film::Property p) } break; case Film::LENGTH: - if (_film->frames_per_second() > 0 && _film->length()) { - s << _film->length().get() << " " << _("frames") << "; " << seconds_to_hms (_film->length().get() / _film->frames_per_second()); + if (_film->source_frame_rate() > 0 && _film->length()) { + s << _film->length().get() << " " << _("frames") << "; " << seconds_to_hms (_film->length().get() / _film->source_frame_rate()); } else if (_film->length()) { s << _film->length().get() << " " << _("frames"); } @@ -782,7 +782,7 @@ FilmEditor::set_film (shared_ptr f) film_changed (Film::LENGTH); film_changed (Film::CONTENT_AUDIO_STREAMS); film_changed (Film::SUBTITLE_STREAMS); - film_changed (Film::FRAMES_PER_SECOND); + film_changed (Film::SOURCE_FRAME_RATE); } /** Updates the sensitivity of lots of widgets to a given value. diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index 2af747bb0..da9bb0301 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -157,8 +157,8 @@ private: wxSpinCtrl* _j2k_bandwidth; /** The Film's DCP content type */ wxChoice* _dcp_content_type; - /** The Film's frames per second */ - wxStaticText* _frames_per_second; + /** The Film's source frame rate */ + wxStaticText* _source_frame_rate; /** The Film's original size */ wxStaticText* _original_size; /** The Film's length */ diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 5eba7fd80..a40a3c78d 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -188,7 +188,7 @@ FilmViewer::timer (wxTimerEvent &) get_frame (); if (_film->length()) { - int const new_slider_position = 4096 * _decoders.video->last_source_time() / (_film->length().get() / _film->frames_per_second()); + int const new_slider_position = 4096 * _decoders.video->last_source_time() / (_film->length().get() / _film->source_frame_rate()); if (new_slider_position != _slider->GetValue()) { _slider->SetValue (new_slider_position); } @@ -237,7 +237,7 @@ FilmViewer::slider_moved (wxScrollEvent &) return; } - if (_decoders.video->seek (_slider->GetValue() * _film->length().get() / (4096 * _film->frames_per_second()))) { + if (_decoders.video->seek (_slider->GetValue() * _film->length().get() / (4096 * _film->source_frame_rate()))) { return; } @@ -369,7 +369,7 @@ FilmViewer::check_play_state () } if (_play_button->GetValue()) { - _timer.Start (1000 / _film->frames_per_second()); + _timer.Start (1000 / _film->source_frame_rate()); } else { _timer.Stop (); } diff --git a/src/wx/properties_dialog.cc b/src/wx/properties_dialog.cc index e93d06dbe..f4acb6b1a 100644 --- a/src/wx/properties_dialog.cc +++ b/src/wx/properties_dialog.cc @@ -52,7 +52,9 @@ PropertiesDialog::PropertiesDialog (wxWindow* parent, shared_ptr film) if (_film->length()) { _frames->SetLabel (std_to_wx (lexical_cast (_film->length().get()))); - double const disk = ((double) _film->j2k_bandwidth() / 8) * _film->length().get() / (_film->frames_per_second () * 1073741824); + FrameRateConversion frc (_film->source_frame_rate(), _film->dcp_frame_rate()); + int const dcp_length = _film->length().get() * frc.factor(); + double const disk = ((double) _film->j2k_bandwidth() / 8) * dcp_length / (_film->dcp_frame_rate() * 1073741824); stringstream s; s << fixed << setprecision (1) << disk << _("Gb"); _disk->SetLabel (std_to_wx (s.str ())); diff --git a/test/metadata.ref b/test/metadata.ref index ab40dfe8d..10702f8a0 100644 --- a/test/metadata.ref +++ b/test/metadata.ref @@ -1,4 +1,4 @@ -version 3 +version 4 name fred use_dci_name 1 content @@ -32,10 +32,11 @@ studio facility package_type dci_date 20130211 +dcp_frame_rate 0 width 0 height 0 length 0 dcp_intrinsic_duration 0 content_digest external_audio_stream external 0 0 -frames_per_second 0 +source_frame_rate 0 diff --git a/test/test.cc b/test/test.cc index 8cfc6e467..b4a459fe7 100644 --- a/test/test.cc +++ b/test/test.cc @@ -500,8 +500,8 @@ BOOST_AUTO_TEST_CASE (make_dcp_with_range_test) BOOST_CHECK_EQUAL (JobManager::instance()->errors(), false); } -/* Test the constructor of DCPFrameRate */ -BOOST_AUTO_TEST_CASE (dcp_frame_rate_test) +/* Test best_dcp_frame_rate and FrameRateConversion */ +BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test) { /* Run some tests with a limited range of allowed rates */ @@ -511,71 +511,82 @@ BOOST_AUTO_TEST_CASE (dcp_frame_rate_test) afr.push_back (30); Config::instance()->set_allowed_dcp_frame_rates (afr); - DCPFrameRate dfr = DCPFrameRate (60); - BOOST_CHECK_EQUAL (dfr.frames_per_second, 30); - BOOST_CHECK_EQUAL (dfr.skip, true); - BOOST_CHECK_EQUAL (dfr.repeat, false); - BOOST_CHECK_EQUAL (dfr.change_speed, false); + int best = best_dcp_frame_rate (60); + FrameRateConversion frc = FrameRateConversion (60, best); + BOOST_CHECK_EQUAL (best, 30); + BOOST_CHECK_EQUAL (frc.skip, true); + BOOST_CHECK_EQUAL (frc.repeat, false); + BOOST_CHECK_EQUAL (frc.change_speed, false); - dfr = DCPFrameRate (50); - BOOST_CHECK_EQUAL (dfr.frames_per_second, 25); - BOOST_CHECK_EQUAL (dfr.skip, true); - BOOST_CHECK_EQUAL (dfr.repeat, false); - BOOST_CHECK_EQUAL (dfr.change_speed, false); - - dfr = DCPFrameRate (48); - BOOST_CHECK_EQUAL (dfr.frames_per_second, 24); - BOOST_CHECK_EQUAL (dfr.skip, true); - BOOST_CHECK_EQUAL (dfr.repeat, false); - BOOST_CHECK_EQUAL (dfr.change_speed, false); + best = best_dcp_frame_rate (50); + frc = FrameRateConversion (50, best); + BOOST_CHECK_EQUAL (best, 25); + BOOST_CHECK_EQUAL (frc.skip, true); + BOOST_CHECK_EQUAL (frc.repeat, false); + BOOST_CHECK_EQUAL (frc.change_speed, false); + + best = best_dcp_frame_rate (48); + frc = FrameRateConversion (48, best); + BOOST_CHECK_EQUAL (best, 24); + BOOST_CHECK_EQUAL (frc.skip, true); + BOOST_CHECK_EQUAL (frc.repeat, false); + BOOST_CHECK_EQUAL (frc.change_speed, false); - dfr = DCPFrameRate (30); - BOOST_CHECK_EQUAL (dfr.skip, false); - BOOST_CHECK_EQUAL (dfr.frames_per_second, 30); - BOOST_CHECK_EQUAL (dfr.repeat, false); - BOOST_CHECK_EQUAL (dfr.change_speed, false); - - dfr = DCPFrameRate (29.97); - BOOST_CHECK_EQUAL (dfr.skip, false); - BOOST_CHECK_EQUAL (dfr.frames_per_second, 30); - BOOST_CHECK_EQUAL (dfr.repeat, false); - BOOST_CHECK_EQUAL (dfr.change_speed, true); + best = best_dcp_frame_rate (30); + frc = FrameRateConversion (30, best); + BOOST_CHECK_EQUAL (best, 30); + BOOST_CHECK_EQUAL (frc.skip, false); + BOOST_CHECK_EQUAL (frc.repeat, false); + BOOST_CHECK_EQUAL (frc.change_speed, false); + + best = best_dcp_frame_rate (29.97); + frc = FrameRateConversion (29.97, best); + BOOST_CHECK_EQUAL (best, 30); + BOOST_CHECK_EQUAL (frc.skip, false); + BOOST_CHECK_EQUAL (frc.repeat, false); + BOOST_CHECK_EQUAL (frc.change_speed, true); - dfr = DCPFrameRate (25); - BOOST_CHECK_EQUAL (dfr.skip, false); - BOOST_CHECK_EQUAL (dfr.frames_per_second, 25); - BOOST_CHECK_EQUAL (dfr.repeat, false); - BOOST_CHECK_EQUAL (dfr.change_speed, false); - - dfr = DCPFrameRate (24); - BOOST_CHECK_EQUAL (dfr.skip, false); - BOOST_CHECK_EQUAL (dfr.frames_per_second, 24); - BOOST_CHECK_EQUAL (dfr.repeat, false); - BOOST_CHECK_EQUAL (dfr.change_speed, false); - - dfr = DCPFrameRate (14.5); - BOOST_CHECK_EQUAL (dfr.skip, false); - BOOST_CHECK_EQUAL (dfr.frames_per_second, 30); - BOOST_CHECK_EQUAL (dfr.repeat, true); - BOOST_CHECK_EQUAL (dfr.change_speed, true); - - dfr = DCPFrameRate (12.6); - BOOST_CHECK_EQUAL (dfr.skip, false); - BOOST_CHECK_EQUAL (dfr.frames_per_second, 25); - BOOST_CHECK_EQUAL (dfr.repeat, true); - BOOST_CHECK_EQUAL (dfr.change_speed, true); - - dfr = DCPFrameRate (12.4); - BOOST_CHECK_EQUAL (dfr.skip, false); - BOOST_CHECK_EQUAL (dfr.frames_per_second, 25); - BOOST_CHECK_EQUAL (dfr.repeat, true); - BOOST_CHECK_EQUAL (dfr.change_speed, true); - - dfr = DCPFrameRate (12); - BOOST_CHECK_EQUAL (dfr.skip, false); - BOOST_CHECK_EQUAL (dfr.frames_per_second, 24); - BOOST_CHECK_EQUAL (dfr.repeat, true); - BOOST_CHECK_EQUAL (dfr.change_speed, false); + best = best_dcp_frame_rate (25); + frc = FrameRateConversion (25, best); + BOOST_CHECK_EQUAL (best, 25); + BOOST_CHECK_EQUAL (frc.skip, false); + BOOST_CHECK_EQUAL (frc.repeat, false); + BOOST_CHECK_EQUAL (frc.change_speed, false); + + best = best_dcp_frame_rate (24); + frc = FrameRateConversion (24, best); + BOOST_CHECK_EQUAL (best, 24); + BOOST_CHECK_EQUAL (frc.skip, false); + BOOST_CHECK_EQUAL (frc.repeat, false); + BOOST_CHECK_EQUAL (frc.change_speed, false); + + best = best_dcp_frame_rate (14.5); + frc = FrameRateConversion (14.5, best); + BOOST_CHECK_EQUAL (best, 30); + BOOST_CHECK_EQUAL (frc.skip, false); + BOOST_CHECK_EQUAL (frc.repeat, true); + BOOST_CHECK_EQUAL (frc.change_speed, true); + + best = best_dcp_frame_rate (12.6); + frc = FrameRateConversion (12.6, best); + BOOST_CHECK_EQUAL (best, 25); + BOOST_CHECK_EQUAL (frc.skip, false); + BOOST_CHECK_EQUAL (frc.repeat, true); + BOOST_CHECK_EQUAL (frc.change_speed, true); + + best = best_dcp_frame_rate (12.4); + frc = FrameRateConversion (12.4, best); + BOOST_CHECK_EQUAL (best, 25); + BOOST_CHECK_EQUAL (frc.skip, false); + BOOST_CHECK_EQUAL (frc.repeat, true); + BOOST_CHECK_EQUAL (frc.change_speed, true); + + best = best_dcp_frame_rate (12); + frc = FrameRateConversion (12, best); + BOOST_CHECK_EQUAL (best, 24); + BOOST_CHECK_EQUAL (frc.skip, false); + BOOST_CHECK_EQUAL (frc.repeat, true); + BOOST_CHECK_EQUAL (frc.change_speed, false); /* Now add some more rates and see if it will use them in preference to skip/repeat. @@ -586,29 +597,33 @@ BOOST_AUTO_TEST_CASE (dcp_frame_rate_test) afr.push_back (60); Config::instance()->set_allowed_dcp_frame_rates (afr); - dfr = DCPFrameRate (60); - BOOST_CHECK_EQUAL (dfr.frames_per_second, 60); - BOOST_CHECK_EQUAL (dfr.skip, false); - BOOST_CHECK_EQUAL (dfr.repeat, false); - BOOST_CHECK_EQUAL (dfr.change_speed, false); + best = best_dcp_frame_rate (60); + frc = FrameRateConversion (60, best); + BOOST_CHECK_EQUAL (best, 60); + BOOST_CHECK_EQUAL (frc.skip, false); + BOOST_CHECK_EQUAL (frc.repeat, false); + BOOST_CHECK_EQUAL (frc.change_speed, false); - dfr = DCPFrameRate (50); - BOOST_CHECK_EQUAL (dfr.frames_per_second, 50); - BOOST_CHECK_EQUAL (dfr.skip, false); - BOOST_CHECK_EQUAL (dfr.repeat, false); - BOOST_CHECK_EQUAL (dfr.change_speed, false); - - dfr = DCPFrameRate (48); - BOOST_CHECK_EQUAL (dfr.frames_per_second, 48); - BOOST_CHECK_EQUAL (dfr.skip, false); - BOOST_CHECK_EQUAL (dfr.repeat, false); - BOOST_CHECK_EQUAL (dfr.change_speed, false); + best = best_dcp_frame_rate (50); + frc = FrameRateConversion (50, best); + BOOST_CHECK_EQUAL (best, 50); + BOOST_CHECK_EQUAL (frc.skip, false); + BOOST_CHECK_EQUAL (frc.repeat, false); + BOOST_CHECK_EQUAL (frc.change_speed, false); + + best = best_dcp_frame_rate (48); + frc = FrameRateConversion (48, best); + BOOST_CHECK_EQUAL (best, 48); + BOOST_CHECK_EQUAL (frc.skip, false); + BOOST_CHECK_EQUAL (frc.repeat, false); + BOOST_CHECK_EQUAL (frc.change_speed, false); } BOOST_AUTO_TEST_CASE (audio_sampling_rate_test) { shared_ptr f = new_test_film ("audio_sampling_rate_test"); - f->set_frames_per_second (24); + f->set_source_frame_rate (24); + f->set_dcp_frame_rate (24); f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 48000, 0))); BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 48000); @@ -619,11 +634,13 @@ BOOST_AUTO_TEST_CASE (audio_sampling_rate_test) f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 80000, 0))); BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 96000); - f->set_frames_per_second (23.976); + f->set_source_frame_rate (23.976); + f->set_dcp_frame_rate (best_dcp_frame_rate (23.976)); f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 48000, 0))); BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 47952); - f->set_frames_per_second (29.97); + f->set_source_frame_rate (29.97); + f->set_dcp_frame_rate (best_dcp_frame_rate (29.97)); f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 48000, 0))); BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 47952); } -- cgit v1.2.3 From 4ac56e7419dfd85842fed4dfd9cf912c55851de3 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 1 Mar 2013 23:21:30 +0000 Subject: More choose-dcp-rate stuff. --- src/lib/config.cc | 3 +++ src/lib/film.cc | 8 +++++++- src/wx/film_editor.cc | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++- src/wx/film_editor.h | 4 ++++ test/test.cc | 47 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 114 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/lib/config.cc b/src/lib/config.cc index 82a31b3cf..f5273b875 100644 --- a/src/lib/config.cc +++ b/src/lib/config.cc @@ -49,6 +49,9 @@ Config::Config () _allowed_dcp_frame_rates.push_back (24); _allowed_dcp_frame_rates.push_back (25); _allowed_dcp_frame_rates.push_back (30); + _allowed_dcp_frame_rates.push_back (48); + _allowed_dcp_frame_rates.push_back (50); + _allowed_dcp_frame_rates.push_back (60); ifstream f (file().c_str ()); string line; diff --git a/src/lib/film.cc b/src/lib/film.cc index a661adcc6..1c4a8108d 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -275,6 +275,7 @@ Film::make_dcp () log()->log (String::compose (N_("Content length %1"), length().get())); } log()->log (String::compose (N_("Content digest %1"), content_digest())); + log()->log (String::compose ("Content at %1 fps, DCP at %2 fps", source_frame_rate(), dcp_frame_rate())); log()->log (String::compose (N_("%1 threads"), Config::instance()->num_local_encoding_threads())); log()->log (String::compose (N_("J2K bandwidth %1"), j2k_bandwidth())); #ifdef DVDOMATIC_DEBUG @@ -602,8 +603,12 @@ Film::read_metadata () _external_audio_stream = audio_stream_factory (v, version); } else if (k == N_("subtitle_stream")) { _subtitle_streams.push_back (subtitle_stream_factory (v, version)); - } else if (k == N_("source_frame_rate") || (version < 4 && k == "frames_per_second")) { + } else if (k == N_("source_frame_rate")) { _source_frame_rate = atof (v.c_str ()); + } else if (version < 4 && k == "frames_per_second") { + _source_frame_rate = atof (v.c_str ()); + /* Fill in what would have been used for DCP frame rate by the older version */ + _dcp_frame_rate = best_dcp_frame_rate (_source_frame_rate); } } @@ -905,6 +910,7 @@ Film::set_content (string c) set_size (d.video->native_size ()); set_source_frame_rate (d.video->frames_per_second ()); + set_dcp_frame_rate (best_dcp_frame_rate (source_frame_rate ())); set_subtitle_streams (d.video->subtitle_streams ()); if (d.audio) { set_content_audio_streams (d.audio->audio_streams ()); diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 0a6a35273..7453d175a 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -129,6 +129,16 @@ FilmEditor::make_film_panel () video_control (add_label_to_sizer (grid, _film_panel, _("Original Frame Rate"))); _source_frame_rate = new wxStaticText (_film_panel, wxID_ANY, wxT ("")); grid->Add (video_control (_source_frame_rate), 1, wxALIGN_CENTER_VERTICAL); + + { + add_label_to_sizer (grid, _film_panel, _("DCP Frame Rate")); + wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); + _dcp_frame_rate = new wxChoice (_film_panel, wxID_ANY); + s->Add (_dcp_frame_rate, 1, wxALIGN_CENTER_VERTICAL); + _best_dcp_frame_rate = new wxButton (_film_panel, wxID_ANY, _("Use best")); + s->Add (_best_dcp_frame_rate, 1, wxALIGN_CENTER_VERTICAL | wxALL | wxEXPAND, 6); + grid->Add (s, 1); + } video_control (add_label_to_sizer (grid, _film_panel, _("Original Size"))); _original_size = new wxStaticText (_film_panel, wxID_ANY, wxT ("")); @@ -173,6 +183,11 @@ FilmEditor::make_film_panel () for (vector::const_iterator i = ct.begin(); i != ct.end(); ++i) { _dcp_content_type->Append (std_to_wx ((*i)->pretty_name ())); } + + list const dfr = Config::instance()->allowed_dcp_frame_rates (); + for (list::const_iterator i = dfr.begin(); i != dfr.end(); ++i) { + _dcp_frame_rate->Append (std_to_wx (boost::lexical_cast (*i))); + } } void @@ -191,6 +206,8 @@ FilmEditor::connect_to_widgets () _filters_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::edit_filters_clicked), 0, this); _scaler->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::scaler_changed), 0, this); _dcp_content_type->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::dcp_content_type_changed), 0, this); + _dcp_frame_rate->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::dcp_frame_rate_changed), 0, this); + _best_dcp_frame_rate->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::best_dcp_frame_rate_clicked), 0, this); _dcp_ab->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::dcp_ab_toggled), 0, this); _still_duration->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::still_duration_changed), 0, this); _trim_start->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::trim_start_changed), 0, this); @@ -520,7 +537,21 @@ FilmEditor::j2k_bandwidth_changed (wxCommandEvent &) } _film->set_j2k_bandwidth (_j2k_bandwidth->GetValue() * 1e6); -} +} + +void +FilmEditor::dcp_frame_rate_changed (wxCommandEvent &) +{ + if (!_film) { + return; + } + + _film->set_dcp_frame_rate ( + boost::lexical_cast ( + wx_to_std (_dcp_frame_rate->GetString (_dcp_frame_rate->GetSelection ())) + ) + ); +} /** Called when the metadata stored in the Film object has changed; @@ -700,6 +731,15 @@ FilmEditor::film_changed (Film::Property p) setup_audio_details (); break; } + case Film::DCP_FRAME_RATE: + for (unsigned int i = 0; i < _dcp_frame_rate->GetCount(); ++i) { + if (wx_to_std (_dcp_frame_rate->GetString(i)) == boost::lexical_cast (_film->dcp_frame_rate())) { + if (_dcp_frame_rate->GetSelection() != int(i)) { + _dcp_frame_rate->SetSelection (i); + break; + } + } + } } } @@ -783,6 +823,7 @@ FilmEditor::set_film (shared_ptr f) film_changed (Film::CONTENT_AUDIO_STREAMS); film_changed (Film::SUBTITLE_STREAMS); film_changed (Film::SOURCE_FRAME_RATE); + film_changed (Film::DCP_FRAME_RATE); } /** Updates the sensitivity of lots of widgets to a given value. @@ -807,6 +848,7 @@ FilmEditor::set_things_sensitive (bool s) _scaler->Enable (s); _audio_stream->Enable (s); _dcp_content_type->Enable (s); + _dcp_frame_rate->Enable (s); _trim_start->Enable (s); _trim_end->Enable (s); _dcp_ab->Enable (s); @@ -1186,3 +1228,13 @@ FilmEditor::show_audio_clicked (wxCommandEvent &) _audio_dialog->Show (); _audio_dialog->set_film (_film); } + +void +FilmEditor::best_dcp_frame_rate_clicked (wxCommandEvent &) +{ + if (!_film) { + return; + } + + _film->set_dcp_frame_rate (best_dcp_frame_rate (_film->source_frame_rate ())); +} diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index da9bb0301..4adea2bc9 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -82,6 +82,8 @@ private: void subtitle_stream_changed (wxCommandEvent &); void use_audio_changed (wxCommandEvent &); void external_audio_changed (wxCommandEvent &); + void dcp_frame_rate_changed (wxCommandEvent &); + void best_dcp_frame_rate_clicked (wxCommandEvent &); /* Handle changes to the model */ void film_changed (Film::Property); @@ -159,6 +161,8 @@ private: wxChoice* _dcp_content_type; /** The Film's source frame rate */ wxStaticText* _source_frame_rate; + wxChoice* _dcp_frame_rate; + wxButton* _best_dcp_frame_rate; /** The Film's original size */ wxStaticText* _original_size; /** The Film's length */ diff --git a/test/test.cc b/test/test.cc index b4a459fe7..15c34ca78 100644 --- a/test/test.cc +++ b/test/test.cc @@ -617,10 +617,36 @@ BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test) BOOST_CHECK_EQUAL (frc.skip, false); BOOST_CHECK_EQUAL (frc.repeat, false); BOOST_CHECK_EQUAL (frc.change_speed, false); + + /* Check some out-there conversions (not the best) */ + + frc = FrameRateConversion (14.99, 24); + BOOST_CHECK_EQUAL (frc.skip, false); + BOOST_CHECK_EQUAL (frc.repeat, true); + BOOST_CHECK_EQUAL (frc.change_speed, true); + + /* Check some conversions with limited DCP targets */ + + afr.clear (); + afr.push_back (24); + Config::instance()->set_allowed_dcp_frame_rates (afr); + + best = best_dcp_frame_rate (25); + frc = FrameRateConversion (25, best); + BOOST_CHECK_EQUAL (best, 24); + BOOST_CHECK_EQUAL (frc.skip, false); + BOOST_CHECK_EQUAL (frc.repeat, false); + BOOST_CHECK_EQUAL (frc.change_speed, true); } BOOST_AUTO_TEST_CASE (audio_sampling_rate_test) { + std::list afr; + afr.push_back (24); + afr.push_back (25); + afr.push_back (30); + Config::instance()->set_allowed_dcp_frame_rates (afr); + shared_ptr f = new_test_film ("audio_sampling_rate_test"); f->set_source_frame_rate (24); f->set_dcp_frame_rate (24); @@ -641,8 +667,29 @@ BOOST_AUTO_TEST_CASE (audio_sampling_rate_test) f->set_source_frame_rate (29.97); f->set_dcp_frame_rate (best_dcp_frame_rate (29.97)); + BOOST_CHECK_EQUAL (f->dcp_frame_rate (), 30); f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 48000, 0))); BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 47952); + + f->set_source_frame_rate (25); + f->set_dcp_frame_rate (24); + f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 48000, 0))); + BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 50000); + + f->set_source_frame_rate (25); + f->set_dcp_frame_rate (24); + f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 44100, 0))); + BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 50000); + + /* Check some out-there conversions (not the best) */ + + f->set_source_frame_rate (14.99); + f->set_dcp_frame_rate (25); + f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 16000, 0))); + /* The FrameRateConversion within target_audio_sample_rate should choose to double-up + the 14.99 fps video to 30 and then run it slow at 25. + */ + BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), rint (48000 * 2 * 14.99 / 25)); } class TestJob : public Job -- cgit v1.2.3 From 5c57bfc3f39c5c7a3d4ae166e9574f2f745b0fe8 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 1 Mar 2013 23:28:24 +0000 Subject: Remove quite a lot of N_ --- src/lib/film.cc | 279 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 140 insertions(+), 139 deletions(-) (limited to 'src') diff --git a/src/lib/film.cc b/src/lib/film.cc index 1c4a8108d..8f545952b 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -66,6 +66,7 @@ using std::ofstream; using std::setfill; using std::min; using std::make_pair; +using std::endl; using boost::shared_ptr; using boost::lexical_cast; using boost::to_upper_copy; @@ -89,7 +90,7 @@ Film::Film (string d, bool must_exist) , _trust_content_header (true) , _dcp_content_type (0) , _format (0) - , _scaler (Scaler::from_id (N_("bicubic"))) + , _scaler (Scaler::from_id ("bicubic")) , _trim_start (0) , _trim_end (0) , _dcp_ab (false) @@ -116,13 +117,13 @@ Film::Film (string d, bool must_exist) boost::filesystem::path p (boost::filesystem::system_complete (d)); boost::filesystem::path result; for (boost::filesystem::path::iterator i = p.begin(); i != p.end(); ++i) { - if (*i == N_("..")) { - if (boost::filesystem::is_symlink (result) || result.filename() == N_("..")) { + if (*i == "..") { + if (boost::filesystem::is_symlink (result) || result.filename() == "..") { result /= *i; } else { result = result.parent_path (); } - } else if (*i != N_(".")) { + } else if (*i != ".") { result /= *i; } } @@ -143,7 +144,7 @@ Film::Film (string d, bool must_exist) read_metadata (); } - _log = new FileLog (file (N_("log"))); + _log = new FileLog (file ("log")); } Film::Film (Film const & o) @@ -204,17 +205,17 @@ Film::video_state_identifier () const stringstream s; s << format()->id() - << N_("_") << content_digest() - << N_("_") << crop().left << N_("_") << crop().right << N_("_") << crop().top << N_("_") << crop().bottom - << N_("_") << _dcp_frame_rate - << N_("_") << f.first << N_("_") << f.second - << N_("_") << scaler()->id() - << N_("_") << j2k_bandwidth() - << N_("_") << boost::lexical_cast (colour_lut()); + << "_" << content_digest() + << "_" << crop().left << "_" << crop().right << "_" << crop().top << "_" << crop().bottom + << "_" << _dcp_frame_rate + << "_" << f.first << "_" << f.second + << "_" << scaler()->id() + << "_" << j2k_bandwidth() + << "_" << boost::lexical_cast (colour_lut()); if (dcp_ab()) { pair fa = Filter::ffmpeg_strings (Config::instance()->reference_filters()); - s << N_("ab_") << Config::instance()->reference_scaler()->id() << N_("_") << fa.first << N_("_") << fa.second; + s << "ab_" << Config::instance()->reference_scaler()->id() << "_" << fa.first << "_" << fa.second; } return s.str (); @@ -225,7 +226,7 @@ string Film::info_dir () const { boost::filesystem::path p; - p /= N_("info"); + p /= "info"; p /= video_state_identifier (); return dir (p.string()); } @@ -234,13 +235,13 @@ string Film::video_mxf_dir () const { boost::filesystem::path p; - return dir (N_("video")); + return dir ("video"); } string Film::video_mxf_filename () const { - return video_state_identifier() + N_(".mxf"); + return video_state_identifier() + ".mxf"; } string @@ -258,38 +259,38 @@ Film::make_dcp () { set_dci_date_today (); - if (dcp_name().find (N_("/")) != string::npos) { + if (dcp_name().find ("/") != string::npos) { throw BadSettingError (_("name"), _("cannot contain slashes")); } - log()->log (String::compose (N_("DVD-o-matic %1 git %2 using %3"), dvdomatic_version, dvdomatic_git_commit, dependency_version_summary())); + log()->log (String::compose ("DVD-o-matic %1 git %2 using %3", dvdomatic_version, dvdomatic_git_commit, dependency_version_summary())); { char buffer[128]; gethostname (buffer, sizeof (buffer)); - log()->log (String::compose (N_("Starting to make DCP on %1"), buffer)); + log()->log (String::compose ("Starting to make DCP on %1", buffer)); } - log()->log (String::compose (N_("Content is %1; type %2"), content_path(), (content_type() == STILL ? _("still") : _("video")))); + log()->log (String::compose ("Content is %1; type %2", content_path(), (content_type() == STILL ? _("still") : _("video")))); if (length()) { - log()->log (String::compose (N_("Content length %1"), length().get())); + log()->log (String::compose ("Content length %1", length().get())); } - log()->log (String::compose (N_("Content digest %1"), content_digest())); + log()->log (String::compose ("Content digest %1", content_digest())); log()->log (String::compose ("Content at %1 fps, DCP at %2 fps", source_frame_rate(), dcp_frame_rate())); - log()->log (String::compose (N_("%1 threads"), Config::instance()->num_local_encoding_threads())); - log()->log (String::compose (N_("J2K bandwidth %1"), j2k_bandwidth())); + log()->log (String::compose ("%1 threads", Config::instance()->num_local_encoding_threads())); + log()->log (String::compose ("J2K bandwidth %1", j2k_bandwidth())); #ifdef DVDOMATIC_DEBUG - log()->log (N_("DVD-o-matic built in debug mode.")); + log()->log ("DVD-o-matic built in debug mode."); #else - log()->log (N_("DVD-o-matic built in optimised mode.")); + log()->log ("DVD-o-matic built in optimised mode."); #endif #ifdef LIBDCP_DEBUG - log()->log (N_("libdcp built in debug mode.")); + log()->log ("libdcp built in debug mode."); #else - log()->log (N_("libdcp built in optimised mode.")); + log()->log ("libdcp built in optimised mode."); #endif pair const c = cpu_info (); - log()->log (String::compose (N_("CPU: %1, %2 processors"), c.first, c.second)); + log()->log (String::compose ("CPU: %1, %2 processors", c.first, c.second)); if (format() == 0) { throw MissingSettingError (_("format")); @@ -395,74 +396,74 @@ Film::write_metadata () const boost::filesystem::create_directories (directory()); - string const m = file (N_("metadata")); + string const m = file ("metadata"); ofstream f (m.c_str ()); if (!f.good ()) { throw CreateFileError (m); } - f << N_("version ") << state_version << N_("\n"); + f << "version " << state_version << endl; /* User stuff */ - f << N_("name ") << _name << N_("\n"); - f << N_("use_dci_name ") << _use_dci_name << N_("\n"); - f << N_("content ") << _content << N_("\n"); - f << N_("trust_content_header ") << (_trust_content_header ? N_("1") : N_("0")) << N_("\n"); + f << "name " << _name << endl; + f << "use_dci_name " << _use_dci_name << endl; + f << "content " << _content << endl; + f << "trust_content_header " << (_trust_content_header ? "1" : "0") << endl; if (_dcp_content_type) { - f << N_("dcp_content_type ") << _dcp_content_type->dci_name () << N_("\n"); + f << "dcp_content_type " << _dcp_content_type->dci_name () << endl; } if (_format) { - f << N_("format ") << _format->as_metadata () << N_("\n"); + f << "format " << _format->as_metadata () << endl; } - f << N_("left_crop ") << _crop.left << N_("\n"); - f << N_("right_crop ") << _crop.right << N_("\n"); - f << N_("top_crop ") << _crop.top << N_("\n"); - f << N_("bottom_crop ") << _crop.bottom << N_("\n"); + f << "left_crop " << _crop.left << endl; + f << "right_crop " << _crop.right << endl; + f << "top_crop " << _crop.top << endl; + f << "bottom_crop " << _crop.bottom << endl; for (vector::const_iterator i = _filters.begin(); i != _filters.end(); ++i) { - f << N_("filter ") << (*i)->id () << N_("\n"); + f << "filter " << (*i)->id () << endl; } - f << N_("scaler ") << _scaler->id () << N_("\n"); - f << N_("trim_start ") << _trim_start << N_("\n"); - f << N_("trim_end ") << _trim_end << N_("\n"); - f << N_("dcp_ab ") << (_dcp_ab ? N_("1") : N_("0")) << N_("\n"); + f << "scaler " << _scaler->id () << endl; + f << "trim_start " << _trim_start << endl; + f << "trim_end " << _trim_end << endl; + f << "dcp_ab " << (_dcp_ab ? "1" : "0") << endl; if (_content_audio_stream) { - f << N_("selected_content_audio_stream ") << _content_audio_stream->to_string() << N_("\n"); + f << "selected_content_audio_stream " << _content_audio_stream->to_string() << endl; } for (vector::const_iterator i = _external_audio.begin(); i != _external_audio.end(); ++i) { - f << N_("external_audio ") << *i << N_("\n"); + f << "external_audio " << *i << endl; } - f << N_("use_content_audio ") << (_use_content_audio ? N_("1") : N_("0")) << N_("\n"); - f << N_("audio_gain ") << _audio_gain << N_("\n"); - f << N_("audio_delay ") << _audio_delay << N_("\n"); - f << N_("still_duration ") << _still_duration << N_("\n"); + f << "use_content_audio " << (_use_content_audio ? "1" : "0") << endl; + f << "audio_gain " << _audio_gain << endl; + f << "audio_delay " << _audio_delay << endl; + f << "still_duration " << _still_duration << endl; if (_subtitle_stream) { - f << N_("selected_subtitle_stream ") << _subtitle_stream->to_string() << N_("\n"); + f << "selected_subtitle_stream " << _subtitle_stream->to_string() << endl; } - f << N_("with_subtitles ") << _with_subtitles << N_("\n"); - f << N_("subtitle_offset ") << _subtitle_offset << N_("\n"); - f << N_("subtitle_scale ") << _subtitle_scale << N_("\n"); - f << N_("colour_lut ") << _colour_lut << N_("\n"); - f << N_("j2k_bandwidth ") << _j2k_bandwidth << N_("\n"); + f << "with_subtitles " << _with_subtitles << endl; + f << "subtitle_offset " << _subtitle_offset << endl; + f << "subtitle_scale " << _subtitle_scale << endl; + f << "colour_lut " << _colour_lut << endl; + f << "j2k_bandwidth " << _j2k_bandwidth << endl; _dci_metadata.write (f); - f << N_("dci_date ") << boost::gregorian::to_iso_string (_dci_date) << N_("\n"); - f << N_("dcp_frame_rate ") << _dcp_frame_rate << "\n"; - f << N_("width ") << _size.width << N_("\n"); - f << N_("height ") << _size.height << N_("\n"); - f << N_("length ") << _length.get_value_or(0) << N_("\n"); - f << N_("dcp_intrinsic_duration ") << _dcp_intrinsic_duration.get_value_or(0) << N_("\n"); - f << N_("content_digest ") << _content_digest << N_("\n"); + f << "dci_date " << boost::gregorian::to_iso_string (_dci_date) << endl; + f << "dcp_frame_rate " << _dcp_frame_rate << endl; + f << "width " << _size.width << endl; + f << "height " << _size.height << endl; + f << "length " << _length.get_value_or(0) << endl; + f << "dcp_intrinsic_duration " << _dcp_intrinsic_duration.get_value_or(0) << endl; + f << "content_digest " << _content_digest << endl; for (vector >::const_iterator i = _content_audio_streams.begin(); i != _content_audio_streams.end(); ++i) { - f << N_("content_audio_stream ") << (*i)->to_string () << N_("\n"); + f << "content_audio_stream " << (*i)->to_string () << endl; } - f << N_("external_audio_stream ") << _external_audio_stream->to_string() << N_("\n"); + f << "external_audio_stream " << _external_audio_stream->to_string() << endl; for (vector >::const_iterator i = _subtitle_streams.begin(); i != _subtitle_streams.end(); ++i) { - f << N_("subtitle_stream ") << (*i)->to_string () << N_("\n"); + f << "subtitle_stream " << (*i)->to_string () << endl; } - f << N_("source_frame_rate ") << _source_frame_rate << N_("\n"); + f << "source_frame_rate " << _source_frame_rate << endl; _dirty = false; } @@ -484,15 +485,15 @@ Film::read_metadata () boost::optional audio_stream_index; boost::optional subtitle_stream_index; - ifstream f (file (N_("metadata")).c_str()); + ifstream f (file ("metadata").c_str()); if (!f.good()) { - throw OpenFileError (file (N_("metadata"))); + throw OpenFileError (file ("metadata")); } multimap kv = read_key_value (f); /* We need version before anything else */ - multimap::iterator v = kv.find (N_("version")); + multimap::iterator v = kv.find ("version"); if (v != kv.end ()) { version = atoi (v->second.c_str()); } @@ -501,78 +502,78 @@ Film::read_metadata () string const k = i->first; string const v = i->second; - if (k == N_("audio_sample_rate")) { + if (k == "audio_sample_rate") { audio_sample_rate = atoi (v.c_str()); } /* User-specified stuff */ - if (k == N_("name")) { + if (k == "name") { _name = v; - } else if (k == N_("use_dci_name")) { - _use_dci_name = (v == N_("1")); - } else if (k == N_("content")) { + } else if (k == "use_dci_name") { + _use_dci_name = (v == "1"); + } else if (k == "content") { _content = v; - } else if (k == N_("trust_content_header")) { - _trust_content_header = (v == N_("1")); - } else if (k == N_("dcp_content_type")) { + } else if (k == "trust_content_header") { + _trust_content_header = (v == "1"); + } else if (k == "dcp_content_type") { if (version < 3) { _dcp_content_type = DCPContentType::from_pretty_name (v); } else { _dcp_content_type = DCPContentType::from_dci_name (v); } - } else if (k == N_("format")) { + } else if (k == "format") { _format = Format::from_metadata (v); - } else if (k == N_("left_crop")) { + } else if (k == "left_crop") { _crop.left = atoi (v.c_str ()); - } else if (k == N_("right_crop")) { + } else if (k == "right_crop") { _crop.right = atoi (v.c_str ()); - } else if (k == N_("top_crop")) { + } else if (k == "top_crop") { _crop.top = atoi (v.c_str ()); - } else if (k == N_("bottom_crop")) { + } else if (k == "bottom_crop") { _crop.bottom = atoi (v.c_str ()); - } else if (k == N_("filter")) { + } else if (k == "filter") { _filters.push_back (Filter::from_id (v)); - } else if (k == N_("scaler")) { + } else if (k == "scaler") { _scaler = Scaler::from_id (v); - } else if ( ((!version || version < 2) && k == N_("dcp_trim_start")) || k == N_("trim_start")) { + } else if ( ((!version || version < 2) && k == "dcp_trim_start") || k == "trim_start") { _trim_start = atoi (v.c_str ()); - } else if ( ((!version || version < 2) && k == N_("dcp_trim_end")) || k == N_("trim_end")) { + } else if ( ((!version || version < 2) && k == "dcp_trim_end") || k == "trim_end") { _trim_end = atoi (v.c_str ()); - } else if (k == N_("dcp_ab")) { - _dcp_ab = (v == N_("1")); - } else if (k == N_("selected_content_audio_stream") || (!version && k == N_("selected_audio_stream"))) { + } else if (k == "dcp_ab") { + _dcp_ab = (v == "1"); + } else if (k == "selected_content_audio_stream" || (!version && k == "selected_audio_stream")) { if (!version) { audio_stream_index = atoi (v.c_str ()); } else { _content_audio_stream = audio_stream_factory (v, version); } - } else if (k == N_("external_audio")) { + } else if (k == "external_audio") { _external_audio.push_back (v); - } else if (k == N_("use_content_audio")) { - _use_content_audio = (v == N_("1")); - } else if (k == N_("audio_gain")) { + } else if (k == "use_content_audio") { + _use_content_audio = (v == "1"); + } else if (k == "audio_gain") { _audio_gain = atof (v.c_str ()); - } else if (k == N_("audio_delay")) { + } else if (k == "audio_delay") { _audio_delay = atoi (v.c_str ()); - } else if (k == N_("still_duration")) { + } else if (k == "still_duration") { _still_duration = atoi (v.c_str ()); - } else if (k == N_("selected_subtitle_stream")) { + } else if (k == "selected_subtitle_stream") { if (!version) { subtitle_stream_index = atoi (v.c_str ()); } else { _subtitle_stream = subtitle_stream_factory (v, version); } - } else if (k == N_("with_subtitles")) { - _with_subtitles = (v == N_("1")); - } else if (k == N_("subtitle_offset")) { + } else if (k == "with_subtitles") { + _with_subtitles = (v == "1"); + } else if (k == "subtitle_offset") { _subtitle_offset = atoi (v.c_str ()); - } else if (k == N_("subtitle_scale")) { + } else if (k == "subtitle_scale") { _subtitle_scale = atof (v.c_str ()); - } else if (k == N_("colour_lut")) { + } else if (k == "colour_lut") { _colour_lut = atoi (v.c_str ()); - } else if (k == N_("j2k_bandwidth")) { + } else if (k == "j2k_bandwidth") { _j2k_bandwidth = atoi (v.c_str ()); - } else if (k == N_("dci_date")) { + } else if (k == "dci_date") { _dci_date = boost::gregorian::from_undelimited_string (v); } else if (k == "dcp_frame_rate") { _dcp_frame_rate = atoi (v.c_str ()); @@ -581,29 +582,29 @@ Film::read_metadata () _dci_metadata.read (k, v); /* Cached stuff */ - if (k == N_("width")) { + if (k == "width") { _size.width = atoi (v.c_str ()); - } else if (k == N_("height")) { + } else if (k == "height") { _size.height = atoi (v.c_str ()); - } else if (k == N_("length")) { + } else if (k == "length") { int const vv = atoi (v.c_str ()); if (vv) { _length = vv; } - } else if (k == N_("dcp_intrinsic_duration")) { + } else if (k == "dcp_intrinsic_duration") { int const vv = atoi (v.c_str ()); if (vv) { _dcp_intrinsic_duration = vv; } - } else if (k == N_("content_digest")) { + } else if (k == "content_digest") { _content_digest = v; - } else if (k == N_("content_audio_stream") || (!version && k == N_("audio_stream"))) { + } else if (k == "content_audio_stream" || (!version && k == "audio_stream")) { _content_audio_streams.push_back (audio_stream_factory (v, version)); - } else if (k == N_("external_audio_stream")) { + } else if (k == "external_audio_stream") { _external_audio_stream = audio_stream_factory (v, version); - } else if (k == N_("subtitle_stream")) { + } else if (k == "subtitle_stream") { _subtitle_streams.push_back (subtitle_stream_factory (v, version)); - } else if (k == N_("source_frame_rate")) { + } else if (k == "source_frame_rate") { _source_frame_rate = atof (v.c_str ()); } else if (version < 4 && k == "frames_per_second") { _source_frame_rate = atof (v.c_str ()); @@ -757,14 +758,14 @@ Film::dci_name (bool if_created_now) const fixed_name = fixed_name.substr (0, 14); } - d << fixed_name << N_("_"); + d << fixed_name << "_"; if (dcp_content_type()) { - d << dcp_content_type()->dci_name() << N_("_"); + d << dcp_content_type()->dci_name() << "_"; } if (format()) { - d << format()->dci_name() << N_("_"); + d << format()->dci_name() << "_"; } DCIMetadata const dm = dci_metadata (); @@ -772,51 +773,51 @@ Film::dci_name (bool if_created_now) const if (!dm.audio_language.empty ()) { d << dm.audio_language; if (!dm.subtitle_language.empty() && with_subtitles()) { - d << N_("-") << dm.subtitle_language; + d << "-" << dm.subtitle_language; } else { - d << N_("-XX"); + d << "-XX"; } - d << N_("_"); + d << "_"; } if (!dm.territory.empty ()) { d << dm.territory; if (!dm.rating.empty ()) { - d << N_("-") << dm.rating; + d << "-" << dm.rating; } - d << N_("_"); + d << "_"; } switch (audio_channels()) { case 1: - d << N_("10_"); + d << "10_"; break; case 2: - d << N_("20_"); + d << "20_"; break; case 6: - d << N_("51_"); + d << "51_"; break; case 8: - d << N_("71_"); + d << "71_"; break; } - d << N_("2K_"); + d << "2K_"; if (!dm.studio.empty ()) { - d << dm.studio << N_("_"); + d << dm.studio << "_"; } if (if_created_now) { - d << boost::gregorian::to_iso_string (boost::gregorian::day_clock::local_day ()) << N_("_"); + d << boost::gregorian::to_iso_string (boost::gregorian::day_clock::local_day ()) << "_"; } else { - d << boost::gregorian::to_iso_string (_dci_date) << N_("_"); + d << boost::gregorian::to_iso_string (_dci_date) << "_"; } if (!dm.facility.empty ()) { - d << dm.facility << N_("_"); + d << dm.facility << "_"; } if (!dm.package_type.empty ()) { @@ -871,7 +872,7 @@ Film::set_content (string c) { string check = directory (); - boost::filesystem::path slash (N_("/")); + boost::filesystem::path slash ("/"); string platform_slash = slash.make_preferred().string (); if (!ends_with (check, platform_slash)) { @@ -945,10 +946,10 @@ Film::set_content (string c) /* Default format */ switch (content_type()) { case STILL: - set_format (Format::from_id (N_("var-185"))); + set_format (Format::from_id ("var-185")); break; case VIDEO: - set_format (Format::from_id (N_("185"))); + set_format (Format::from_id ("185")); break; } @@ -1387,7 +1388,7 @@ Film::info_path (int f) const stringstream s; s.width (8); - s << setfill('0') << f << N_(".md5"); + s << setfill('0') << f << ".md5"; p /= s.str(); @@ -1401,15 +1402,15 @@ string Film::j2c_path (int f, bool t) const { boost::filesystem::path p; - p /= N_("j2c"); + p /= "j2c"; p /= video_state_identifier (); stringstream s; s.width (8); - s << setfill('0') << f << N_(".j2c"); + s << setfill('0') << f << ".j2c"; if (t) { - s << N_(".tmp"); + s << ".tmp"; } p /= s.str(); -- cgit v1.2.3 From 324278cc8459e4d7d907b03e0748cf1b33f294f4 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 2 Mar 2013 00:01:18 +0000 Subject: 2.8 fix. --- src/wx/audio_plot.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/wx/audio_plot.cc b/src/wx/audio_plot.cc index af8460a16..cf44eb69f 100644 --- a/src/wx/audio_plot.cc +++ b/src/wx/audio_plot.cc @@ -115,7 +115,7 @@ AudioPlot::paint (wxPaintEvent &) wxDouble db_label_height; wxDouble db_label_descent; wxDouble db_label_leading; - gc->GetTextExtent ("-80dB", &_db_label_width, &db_label_height, &db_label_descent, &db_label_leading); + gc->GetTextExtent (wxT ("-80dB"), &_db_label_width, &db_label_height, &db_label_descent, &db_label_leading); _db_label_width += 8; -- cgit v1.2.3 From 044ae60c8c0da7dc1a6b667b657d342aa770c42b Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 2 Mar 2013 12:27:49 +0000 Subject: Offer non-stretching formats with video as well as still content (#69). --- src/lib/format.cc | 4 ++-- src/wx/film_editor.cc | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/lib/format.cc b/src/lib/format.cc index 0e4830cd7..7fb73d0f9 100644 --- a/src/lib/format.cc +++ b/src/lib/format.cc @@ -82,8 +82,8 @@ Format::setup_formats () _formats.push_back (new FixedFormat (178, libdcp::Size (1920, 1080), N_("178"), _("16:9"), N_("F"))); _formats.push_back (new FixedFormat (185, libdcp::Size (1998, 1080), N_("185"), _("Flat"), N_("F"))); _formats.push_back (new FixedFormat (239, libdcp::Size (2048, 858), N_("239"), _("Scope"), N_("S"))); - _formats.push_back (new VariableFormat (libdcp::Size (1998, 1080), N_("var-185"), _("Flat"), N_("F"))); - _formats.push_back (new VariableFormat (libdcp::Size (2048, 858), N_("var-239"), _("Scope"), N_("S"))); + _formats.push_back (new VariableFormat (libdcp::Size (1998, 1080), N_("var-185"), _("Flat without stretch"), N_("F"))); + _formats.push_back (new VariableFormat (libdcp::Size (2048, 858), N_("var-239"), _("Scope without stretch"), N_("S"))); } /** @param n Nickname. diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 362243ef3..24f6c2461 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -982,9 +982,7 @@ FilmEditor::setup_formats () vector fmt = Format::all (); for (vector::iterator i = fmt.begin(); i != fmt.end(); ++i) { - if (c == VIDEO && dynamic_cast (*i)) { - _formats.push_back (*i); - } else if (c == STILL && dynamic_cast (*i)) { + if (c == VIDEO || (c == STILL && dynamic_cast (*i))) { _formats.push_back (*i); } } -- cgit v1.2.3 From 53eb16342d492236aca77e4b73c0911a5d5eec9f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 2 Mar 2013 18:22:01 +0000 Subject: Add explanation of the effect of changing frame rate. --- src/lib/util.cc | 15 ++++++++++ src/lib/util.h | 4 ++- src/wx/film_editor.cc | 78 +++++++++++++++++++++++++++++++++------------------ src/wx/film_editor.h | 1 + src/wx/wx_util.cc | 8 ++++++ src/wx/wx_util.h | 3 ++ 6 files changed, 80 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/lib/util.cc b/src/lib/util.cc index 85a04ed17..d1450ccc2 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -960,4 +960,19 @@ FrameRateConversion::FrameRateConversion (float source, int dcp) } change_speed = !about_equal (source * factor(), dcp); + + if (!skip && !repeat && !change_speed) { + explanation = _("DCP and source have the same rate.\n"); + } else { + if (skip) { + explanation = _("DCP will use every other frame of the source.\n"); + } else if (repeat) { + explanation = _("Each source frame will be doubled in the DCP.\n"); + } + + if (change_speed) { + float const pc = (source * factor()) * 100 / dcp; + explanation += String::compose (_("DCP will run at %1%% of the source speed."), pc); + } + } } diff --git a/src/lib/util.h b/src/lib/util.h index 103907151..b0f405890 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -78,7 +78,7 @@ struct FrameRateConversion return 1; } - + /** true to skip every other frame */ bool skip; /** true to repeat every frame once */ @@ -93,6 +93,8 @@ struct FrameRateConversion * source is 12.50fps, DCP is 25fps) */ bool change_speed; + + std::string explanation; }; int best_dcp_frame_rate (float); diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 7453d175a..12ba7c1bc 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -97,60 +97,79 @@ FilmEditor::make_film_panel () _film_sizer = new wxBoxSizer (wxVERTICAL); _film_panel->SetSizer (_film_sizer); - wxFlexGridSizer* grid = new wxFlexGridSizer (2, 4, 4); + wxGridBagSizer* grid = new wxGridBagSizer (6, 6); _film_sizer->Add (grid, 0, wxALL, 8); - add_label_to_sizer (grid, _film_panel, _("Name")); + int r = 0; + + add_label_to_grid_bag_sizer (grid, _film_panel, _("Name"), wxGBPosition (r, 0)); _name = new wxTextCtrl (_film_panel, wxID_ANY); - grid->Add (_name, 1, wxEXPAND); - - add_label_to_sizer (grid, _film_panel, _("DCP Name")); + grid->Add (_name, wxGBPosition(r, 1)); + ++r; + + add_label_to_grid_bag_sizer (grid, _film_panel, _("DCP Name"), wxGBPosition (r, 0)); _dcp_name = new wxStaticText (_film_panel, wxID_ANY, wxT ("")); - grid->Add (_dcp_name, 0, wxALIGN_CENTER_VERTICAL | wxSHRINK); + grid->Add (_dcp_name, wxGBPosition(r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); + ++r; _use_dci_name = new wxCheckBox (_film_panel, wxID_ANY, _("Use DCI name")); - grid->Add (_use_dci_name, 1, wxEXPAND); + grid->Add (_use_dci_name, wxGBPosition (r, 0)); _edit_dci_button = new wxButton (_film_panel, wxID_ANY, _("Details...")); - grid->Add (_edit_dci_button, 0); + grid->Add (_edit_dci_button, wxGBPosition (r, 1), wxDefaultSpan); + ++r; - add_label_to_sizer (grid, _film_panel, _("Content")); + add_label_to_grid_bag_sizer (grid, _film_panel, _("Content"), wxGBPosition (r, 0)); _content = new wxFilePickerCtrl (_film_panel, wxID_ANY, wxT (""), _("Select Content File"), wxT("*.*")); - grid->Add (_content, 1, wxEXPAND); + grid->Add (_content, wxGBPosition (r, 1), wxDefaultSpan, wxEXPAND); + ++r; _trust_content_header = new wxCheckBox (_film_panel, wxID_ANY, _("Trust content's header")); video_control (_trust_content_header); - grid->Add (_trust_content_header, 1); - grid->AddSpacer (0); + grid->Add (_trust_content_header, wxGBPosition (r, 0), wxGBSpan(1, 2)); + ++r; - add_label_to_sizer (grid, _film_panel, _("Content Type")); + add_label_to_grid_bag_sizer (grid, _film_panel, _("Content Type"), wxGBPosition (r, 0)); _dcp_content_type = new wxChoice (_film_panel, wxID_ANY); - grid->Add (_dcp_content_type); + grid->Add (_dcp_content_type, wxGBPosition (r, 1)); + ++r; - video_control (add_label_to_sizer (grid, _film_panel, _("Original Frame Rate"))); + video_control (add_label_to_grid_bag_sizer (grid, _film_panel, _("Original Frame Rate"), wxGBPosition (r, 0))); _source_frame_rate = new wxStaticText (_film_panel, wxID_ANY, wxT ("")); - grid->Add (video_control (_source_frame_rate), 1, wxALIGN_CENTER_VERTICAL); + grid->Add (video_control (_source_frame_rate), wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); + ++r; { - add_label_to_sizer (grid, _film_panel, _("DCP Frame Rate")); + add_label_to_grid_bag_sizer (grid, _film_panel, _("DCP Frame Rate"), wxGBPosition (r, 0)); wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); _dcp_frame_rate = new wxChoice (_film_panel, wxID_ANY); s->Add (_dcp_frame_rate, 1, wxALIGN_CENTER_VERTICAL); _best_dcp_frame_rate = new wxButton (_film_panel, wxID_ANY, _("Use best")); s->Add (_best_dcp_frame_rate, 1, wxALIGN_CENTER_VERTICAL | wxALL | wxEXPAND, 6); - grid->Add (s, 1); + grid->Add (s, wxGBPosition (r, 1)); } + ++r; + + _frame_rate_explanation = new wxStaticText (_film_panel, wxID_ANY, wxT (""), wxDefaultPosition, wxDefaultSize, wxST_NO_AUTORESIZE); + grid->Add (video_control (_frame_rate_explanation), wxGBPosition (r, 0), wxGBSpan (1, 2), wxEXPAND | wxALIGN_CENTER_VERTICAL); + wxFont font = _frame_rate_explanation->GetFont(); + font.SetStyle(wxFONTSTYLE_ITALIC); + font.SetPointSize(font.GetPointSize() - 1); + _frame_rate_explanation->SetFont(font); + ++r; - video_control (add_label_to_sizer (grid, _film_panel, _("Original Size"))); + video_control (add_label_to_grid_bag_sizer (grid, _film_panel, _("Original Size"), wxGBPosition (r, 0))); _original_size = new wxStaticText (_film_panel, wxID_ANY, wxT ("")); - grid->Add (video_control (_original_size), 1, wxALIGN_CENTER_VERTICAL); + grid->Add (video_control (_original_size), wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); + ++r; - video_control (add_label_to_sizer (grid, _film_panel, _("Length"))); + video_control (add_label_to_grid_bag_sizer (grid, _film_panel, _("Length"), wxGBPosition (r, 0))); _length = new wxStaticText (_film_panel, wxID_ANY, wxT ("")); - grid->Add (video_control (_length), 1, wxALIGN_CENTER_VERTICAL); + grid->Add (video_control (_length), wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); + ++r; { - video_control (add_label_to_sizer (grid, _film_panel, _("Trim frames"))); + video_control (add_label_to_grid_bag_sizer (grid, _film_panel, _("Trim frames"), wxGBPosition (r, 0))); wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); video_control (add_label_to_sizer (s, _film_panel, _("Start"))); _trim_start = new wxSpinCtrl (_film_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)); @@ -159,25 +178,27 @@ FilmEditor::make_film_panel () _trim_end = new wxSpinCtrl (_film_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)); s->Add (video_control (_trim_end)); - grid->Add (s); + grid->Add (s, wxGBPosition (r, 1)); } + ++r; _dcp_ab = new wxCheckBox (_film_panel, wxID_ANY, _("A/B")); video_control (_dcp_ab); - grid->Add (_dcp_ab, 1); - grid->AddSpacer (0); + grid->Add (_dcp_ab, wxGBPosition (r, 0)); + ++r; /* STILL-only stuff */ { - still_control (add_label_to_sizer (grid, _film_panel, _("Duration"))); + still_control (add_label_to_grid_bag_sizer (grid, _film_panel, _("Duration"), wxGBPosition (r, 0))); wxSizer* s = new wxBoxSizer (wxHORIZONTAL); _still_duration = new wxSpinCtrl (_film_panel); still_control (_still_duration); s->Add (_still_duration, 1, wxEXPAND); /// TRANSLATORS: `s' here is an abbreviation for seconds, the unit of time still_control (add_label_to_sizer (s, _film_panel, _("s"))); - grid->Add (s); + grid->Add (s, wxGBPosition (r, 1)); } + ++r; vector const ct = DCPContentType::all (); for (vector::const_iterator i = ct.begin(); i != ct.end(); ++i) { @@ -740,6 +761,7 @@ FilmEditor::film_changed (Film::Property p) } } } + _frame_rate_explanation->SetLabel (std_to_wx (FrameRateConversion (_film->source_frame_rate(), _film->dcp_frame_rate()).explanation)); } } diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index 4adea2bc9..e9e21894e 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -163,6 +163,7 @@ private: wxStaticText* _source_frame_rate; wxChoice* _dcp_frame_rate; wxButton* _best_dcp_frame_rate; + wxStaticText* _frame_rate_explanation; /** The Film's original size */ wxStaticText* _original_size; /** The Film's length */ diff --git a/src/wx/wx_util.cc b/src/wx/wx_util.cc index bf78ff4d7..720a058cb 100644 --- a/src/wx/wx_util.cc +++ b/src/wx/wx_util.cc @@ -43,6 +43,14 @@ add_label_to_sizer (wxSizer* s, wxWindow* p, wxString t, int prop) return m; } +wxStaticText * +add_label_to_grid_bag_sizer (wxGridBagSizer* s, wxWindow* p, wxString t, wxGBPosition pos, wxGBSpan span) +{ + wxStaticText* m = new wxStaticText (p, wxID_ANY, t); + s->Add (m, pos, span, wxALIGN_CENTER_VERTICAL | wxALL, 6); + return m; +} + /** Pop up an error dialogue box. * @param parent Parent. * @param m Message. diff --git a/src/wx/wx_util.h b/src/wx/wx_util.h index 6cde08a90..bff3d7982 100644 --- a/src/wx/wx_util.h +++ b/src/wx/wx_util.h @@ -18,11 +18,13 @@ */ #include +#include #include #include class wxFilePickerCtrl; class wxSpinCtrl; +class wxGridBagSizer; /** @file src/wx/wx_util.h * @brief Some utility functions and classes. @@ -30,6 +32,7 @@ class wxSpinCtrl; extern void error_dialog (wxWindow *, wxString); extern wxStaticText* add_label_to_sizer (wxSizer *, wxWindow *, wxString, int prop = 0); +extern wxStaticText* add_label_to_grid_bag_sizer (wxGridBagSizer *, wxWindow *, wxString, wxGBPosition, wxGBSpan span = wxDefaultSpan); extern std::string wx_to_std (wxString); extern wxString std_to_wx (std::string); -- cgit v1.2.3 From 99d2e172f5c7fae21e5126a063014727871e9948 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 2 Mar 2013 19:16:25 +0000 Subject: Add similar format description, --- src/lib/format.cc | 85 ++++++++++++++++++++++++++++++++++++++++----------- src/lib/format.h | 12 ++++++-- src/lib/util.cc | 8 ++--- src/lib/util.h | 2 +- src/wx/film_editor.cc | 71 +++++++++++++++++++++++++++--------------- src/wx/film_editor.h | 3 +- 6 files changed, 130 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/src/lib/format.cc b/src/lib/format.cc index 0e4830cd7..b506c7000 100644 --- a/src/lib/format.cc +++ b/src/lib/format.cc @@ -71,19 +71,70 @@ void Format::setup_formats () { /// TRANSLATORS: these are film picture aspect ratios; "Academy" means 1.37, "Flat" 1.85 and "Scope" 2.39. - _formats.push_back (new FixedFormat (119, libdcp::Size (1285, 1080), N_("119"), _("1.19"), N_("F"))); - _formats.push_back (new FixedFormat (133, libdcp::Size (1436, 1080), N_("133"), _("1.33"), N_("F"))); - _formats.push_back (new FixedFormat (138, libdcp::Size (1485, 1080), N_("138"), _("1.375"), N_("F"))); - _formats.push_back (new FixedFormat (133, libdcp::Size (1998, 1080), N_("133-in-flat"), _("4:3 within Flat"), N_("F"))); - _formats.push_back (new FixedFormat (137, libdcp::Size (1480, 1080), N_("137"), _("Academy"), N_("F"))); - _formats.push_back (new FixedFormat (166, libdcp::Size (1793, 1080), N_("166"), _("1.66"), N_("F"))); - _formats.push_back (new FixedFormat (166, libdcp::Size (1998, 1080), N_("166-in-flat"), _("1.66 within Flat"), N_("F"))); - _formats.push_back (new FixedFormat (178, libdcp::Size (1998, 1080), N_("178-in-flat"), _("16:9 within Flat"), N_("F"))); - _formats.push_back (new FixedFormat (178, libdcp::Size (1920, 1080), N_("178"), _("16:9"), N_("F"))); - _formats.push_back (new FixedFormat (185, libdcp::Size (1998, 1080), N_("185"), _("Flat"), N_("F"))); - _formats.push_back (new FixedFormat (239, libdcp::Size (2048, 858), N_("239"), _("Scope"), N_("S"))); - _formats.push_back (new VariableFormat (libdcp::Size (1998, 1080), N_("var-185"), _("Flat"), N_("F"))); - _formats.push_back (new VariableFormat (libdcp::Size (2048, 858), N_("var-239"), _("Scope"), N_("S"))); + _formats.push_back ( + new FixedFormat (119, libdcp::Size (1285, 1080), N_("119"), _("1.19"), N_("F"), + _("Source scaled to 1.19:1") + )); + + _formats.push_back ( + new FixedFormat (133, libdcp::Size (1436, 1080), N_("133"), _("1.33"), N_("F"), + _("Source scaled to 1.33:1") + )); + + _formats.push_back ( + new FixedFormat (138, libdcp::Size (1485, 1080), N_("138"), _("1.375"), N_("F"), + _("Source scaled to 1.375:1") + )); + + _formats.push_back ( + new FixedFormat (133, libdcp::Size (1998, 1080), N_("133-in-flat"), _("4:3 within Flat"), N_("F"), + _("Source scaled to 1.33:1 then pillarboxed to Flat") + )); + + _formats.push_back ( + new FixedFormat (137, libdcp::Size (1480, 1080), N_("137"), _("Academy"), N_("F"), + _("Source scaled to 1.37:1 (Academy ratio)") + )); + + _formats.push_back ( + new FixedFormat (166, libdcp::Size (1793, 1080), N_("166"), _("1.66"), N_("F"), + _("Source scaled to 1.66:1") + )); + + _formats.push_back ( + new FixedFormat (166, libdcp::Size (1998, 1080), N_("166-in-flat"), _("1.66 within Flat"), N_("F"), + _("Source scaled to 1.66:1 then pillarboxed to Flat") + )); + + _formats.push_back ( + new FixedFormat (178, libdcp::Size (1998, 1080), N_("178-in-flat"), _("16:9 within Flat"), N_("F"), + _("Source scaled to 1.78:1 then pillarboxed to Flat") + )); + + _formats.push_back ( + new FixedFormat (178, libdcp::Size (1920, 1080), N_("178"), _("16:9"), N_("F"), + _("Source scaled to 1.78:1") + )); + + _formats.push_back ( + new FixedFormat (185, libdcp::Size (1998, 1080), N_("185"), _("Flat"), N_("F"), + _("Source scaled to Flat (1.85:1)") + )); + + _formats.push_back ( + new FixedFormat (239, libdcp::Size (2048, 858), N_("239"), _("Scope"), N_("S"), + _("Source scaled to Scope (2.39:1)") + )); + + _formats.push_back ( + new VariableFormat (libdcp::Size (1998, 1080), N_("var-185"), _("Flat without stretch"), N_("F"), + _("Source scaled to fit Flat preserving its aspect ratio") + )); + + _formats.push_back ( + new VariableFormat (libdcp::Size (2048, 858), N_("var-239"), _("Scope without stretch"), N_("S"), + _("Source scaled to fit Scope preserving its aspect ratio") + )); } /** @param n Nickname. @@ -144,8 +195,8 @@ Format::all () * @param id ID (e.g. 185) * @param n Nick name (e.g. Flat) */ -FixedFormat::FixedFormat (int r, libdcp::Size dcp, string id, string n, string d) - : Format (dcp, id, n, d) +FixedFormat::FixedFormat (int r, libdcp::Size dcp, string id, string n, string d, string e) + : Format (dcp, id, n, d, e) , _ratio (r) { @@ -173,8 +224,8 @@ Format::container_ratio_as_float () const return static_cast (_dcp_size.width) / _dcp_size.height; } -VariableFormat::VariableFormat (libdcp::Size dcp, string id, string n, string d) - : Format (dcp, id, n, d) +VariableFormat::VariableFormat (libdcp::Size dcp, string id, string n, string d, string e) + : Format (dcp, id, n, d, e) { } diff --git a/src/lib/format.h b/src/lib/format.h index 783ff25ce..305524628 100644 --- a/src/lib/format.h +++ b/src/lib/format.h @@ -31,11 +31,12 @@ class Film; class Format { public: - Format (libdcp::Size dcp, std::string id, std::string n, std::string d) + Format (libdcp::Size dcp, std::string id, std::string n, std::string d, std::string e) : _dcp_size (dcp) , _id (id) , _nickname (n) , _dci_name (d) + , _description (e) {} /** @return the aspect ratio multiplied by 100 @@ -75,6 +76,10 @@ public: return _dci_name; } + std::string description () const { + return _description; + } + std::string as_metadata () const; static Format const * from_nickname (std::string n); @@ -94,6 +99,7 @@ protected: /** nickname (e.g. Flat, Scope) */ std::string _nickname; std::string _dci_name; + std::string _description; private: /** all available formats */ @@ -107,7 +113,7 @@ private: class FixedFormat : public Format { public: - FixedFormat (int, libdcp::Size, std::string, std::string, std::string); + FixedFormat (int, libdcp::Size, std::string, std::string, std::string, std::string); int ratio_as_integer (boost::shared_ptr) const { return _ratio; @@ -128,7 +134,7 @@ private: class VariableFormat : public Format { public: - VariableFormat (libdcp::Size, std::string, std::string, std::string); + VariableFormat (libdcp::Size, std::string, std::string, std::string, std::string); int ratio_as_integer (boost::shared_ptr f) const; float ratio_as_float (boost::shared_ptr f) const; diff --git a/src/lib/util.cc b/src/lib/util.cc index d1450ccc2..71e864ebd 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -962,17 +962,17 @@ FrameRateConversion::FrameRateConversion (float source, int dcp) change_speed = !about_equal (source * factor(), dcp); if (!skip && !repeat && !change_speed) { - explanation = _("DCP and source have the same rate.\n"); + description = _("DCP and source have the same rate.\n"); } else { if (skip) { - explanation = _("DCP will use every other frame of the source.\n"); + description = _("DCP will use every other frame of the source.\n"); } else if (repeat) { - explanation = _("Each source frame will be doubled in the DCP.\n"); + description = _("Each source frame will be doubled in the DCP.\n"); } if (change_speed) { float const pc = (source * factor()) * 100 / dcp; - explanation += String::compose (_("DCP will run at %1%% of the source speed."), pc); + description += String::compose (_("DCP will run at %1%% of the source speed."), pc); } } } diff --git a/src/lib/util.h b/src/lib/util.h index b0f405890..ec67469c1 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -94,7 +94,7 @@ struct FrameRateConversion */ bool change_speed; - std::string explanation; + std::string description; }; int best_dcp_frame_rate (float); diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 12ba7c1bc..a97562b98 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -97,7 +97,7 @@ FilmEditor::make_film_panel () _film_sizer = new wxBoxSizer (wxVERTICAL); _film_panel->SetSizer (_film_sizer); - wxGridBagSizer* grid = new wxGridBagSizer (6, 6); + wxGridBagSizer* grid = new wxGridBagSizer (4, 4); _film_sizer->Add (grid, 0, wxALL, 8); int r = 0; @@ -149,12 +149,12 @@ FilmEditor::make_film_panel () } ++r; - _frame_rate_explanation = new wxStaticText (_film_panel, wxID_ANY, wxT (""), wxDefaultPosition, wxDefaultSize, wxST_NO_AUTORESIZE); - grid->Add (video_control (_frame_rate_explanation), wxGBPosition (r, 0), wxGBSpan (1, 2), wxEXPAND | wxALIGN_CENTER_VERTICAL); - wxFont font = _frame_rate_explanation->GetFont(); + _frame_rate_description = new wxStaticText (_film_panel, wxID_ANY, wxT (""), wxDefaultPosition, wxDefaultSize); + grid->Add (video_control (_frame_rate_description), wxGBPosition (r, 0), wxGBSpan (1, 2), wxEXPAND | wxALIGN_CENTER_VERTICAL | wxALL, 6); + wxFont font = _frame_rate_description->GetFont(); font.SetStyle(wxFONTSTYLE_ITALIC); font.SetPointSize(font.GetPointSize() - 1); - _frame_rate_explanation->SetFont(font); + _frame_rate_description->SetFont(font); ++r; video_control (add_label_to_grid_bag_sizer (grid, _film_panel, _("Original Size"), wxGBPosition (r, 0))); @@ -262,32 +262,46 @@ FilmEditor::make_video_panel () _video_sizer = new wxBoxSizer (wxVERTICAL); _video_panel->SetSizer (_video_sizer); - wxFlexGridSizer* grid = new wxFlexGridSizer (2, 4, 4); + wxGridBagSizer* grid = new wxGridBagSizer (4, 4); _video_sizer->Add (grid, 0, wxALL, 8); - add_label_to_sizer (grid, _video_panel, _("Format")); + int r = 0; + add_label_to_grid_bag_sizer (grid, _video_panel, _("Format"), wxGBPosition (r, 0)); _format = new wxChoice (_video_panel, wxID_ANY); - grid->Add (_format); + grid->Add (_format, wxGBPosition (r, 1)); + ++r; - add_label_to_sizer (grid, _video_panel, _("Left crop")); + _format_description = new wxStaticText (_video_panel, wxID_ANY, wxT (""), wxDefaultPosition, wxDefaultSize); + grid->Add (_format_description, wxGBPosition (r, 0), wxGBSpan (1, 2), wxEXPAND | wxALIGN_CENTER_VERTICAL | wxALL, 6); + wxFont font = _format_description->GetFont(); + font.SetStyle(wxFONTSTYLE_ITALIC); + font.SetPointSize(font.GetPointSize() - 1); + _format_description->SetFont(font); + ++r; + + add_label_to_grid_bag_sizer (grid, _video_panel, _("Left crop"), wxGBPosition (r, 0)); _left_crop = new wxSpinCtrl (_video_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)); - grid->Add (_left_crop); + grid->Add (_left_crop, wxGBPosition (r, 1)); + ++r; - add_label_to_sizer (grid, _video_panel, _("Right crop")); + add_label_to_grid_bag_sizer (grid, _video_panel, _("Right crop"), wxGBPosition (r, 0)); _right_crop = new wxSpinCtrl (_video_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)); - grid->Add (_right_crop); + grid->Add (_right_crop, wxGBPosition (r, 1)); + ++r; - add_label_to_sizer (grid, _video_panel, _("Top crop")); + add_label_to_grid_bag_sizer (grid, _video_panel, _("Top crop"), wxGBPosition (r, 0)); _top_crop = new wxSpinCtrl (_video_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)); - grid->Add (_top_crop); + grid->Add (_top_crop, wxGBPosition (r, 1)); + ++r; - add_label_to_sizer (grid, _video_panel, _("Bottom crop")); + add_label_to_grid_bag_sizer (grid, _video_panel, _("Bottom crop"), wxGBPosition (r, 0)); _bottom_crop = new wxSpinCtrl (_video_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)); - grid->Add (_bottom_crop); + grid->Add (_bottom_crop, wxGBPosition (r, 1)); + ++r; /* VIDEO-only stuff */ { - video_control (add_label_to_sizer (grid, _video_panel, _("Filters"))); + video_control (add_label_to_grid_bag_sizer (grid, _video_panel, _("Filters"), wxGBPosition (r, 0))); wxSizer* s = new wxBoxSizer (wxHORIZONTAL); _filters = new wxStaticText (_video_panel, wxID_ANY, _("None")); video_control (_filters); @@ -295,34 +309,38 @@ FilmEditor::make_video_panel () _filters_button = new wxButton (_video_panel, wxID_ANY, _("Edit...")); video_control (_filters_button); s->Add (_filters_button, 0); - grid->Add (s, 1); + grid->Add (s, wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); } + ++r; - video_control (add_label_to_sizer (grid, _video_panel, _("Scaler"))); + video_control (add_label_to_grid_bag_sizer (grid, _video_panel, _("Scaler"), wxGBPosition (r, 0))); _scaler = new wxChoice (_video_panel, wxID_ANY); - grid->Add (video_control (_scaler), 1); + grid->Add (video_control (_scaler), wxGBPosition (r, 1)); + ++r; vector const sc = Scaler::all (); for (vector::const_iterator i = sc.begin(); i != sc.end(); ++i) { _scaler->Append (std_to_wx ((*i)->name())); } - add_label_to_sizer (grid, _video_panel, _("Colour look-up table")); + add_label_to_grid_bag_sizer (grid, _video_panel, _("Colour look-up table"), wxGBPosition (r, 0)); _colour_lut = new wxChoice (_video_panel, wxID_ANY); for (int i = 0; i < 2; ++i) { _colour_lut->Append (std_to_wx (colour_lut_index_to_name (i))); } _colour_lut->SetSelection (0); - grid->Add (_colour_lut, 1, wxEXPAND); + grid->Add (_colour_lut, wxGBPosition (r, 1), wxDefaultSpan, wxEXPAND); + ++r; { - add_label_to_sizer (grid, _video_panel, _("JPEG2000 bandwidth")); + add_label_to_grid_bag_sizer (grid, _video_panel, _("JPEG2000 bandwidth"), wxGBPosition (r, 0)); wxSizer* s = new wxBoxSizer (wxHORIZONTAL); _j2k_bandwidth = new wxSpinCtrl (_video_panel, wxID_ANY); s->Add (_j2k_bandwidth, 1); add_label_to_sizer (s, _video_panel, _("MBps")); - grid->Add (s, 1); + grid->Add (s, wxGBPosition (r, 1)); } + ++r; _left_crop->SetRange (0, 1024); _top_crop->SetRange (0, 1024); @@ -624,6 +642,8 @@ FilmEditor::film_changed (Film::Property p) checked_set (_format, n); } setup_dcp_name (); + + _format_description->SetLabel (std_to_wx (_film->format()->description ())); break; } case Film::CROP: @@ -761,7 +781,8 @@ FilmEditor::film_changed (Film::Property p) } } } - _frame_rate_explanation->SetLabel (std_to_wx (FrameRateConversion (_film->source_frame_rate(), _film->dcp_frame_rate()).explanation)); + _frame_rate_description->SetLabel (std_to_wx (FrameRateConversion (_film->source_frame_rate(), _film->dcp_frame_rate()).description)); + _best_dcp_frame_rate->Enable (best_dcp_frame_rate (_film->source_frame_rate ()) != _film->dcp_frame_rate ()); } } diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index e9e21894e..29b453b8b 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -123,6 +123,7 @@ private: wxButton* _edit_dci_button; /** The Film's format */ wxChoice* _format; + wxStaticText* _format_description; /** The Film's content file */ wxFilePickerCtrl* _content; wxCheckBox* _trust_content_header; @@ -163,7 +164,7 @@ private: wxStaticText* _source_frame_rate; wxChoice* _dcp_frame_rate; wxButton* _best_dcp_frame_rate; - wxStaticText* _frame_rate_explanation; + wxStaticText* _frame_rate_description; /** The Film's original size */ wxStaticText* _original_size; /** The Film's length */ -- cgit v1.2.3 From 306758719391fab2423f1ec5ea8f8a3470b6a8b6 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 4 Mar 2013 19:51:26 +0000 Subject: Fix crash and tidy up hints when there is no content. --- src/wx/film_editor.cc | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index a19d2fff1..8330e3d3e 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -643,7 +643,11 @@ FilmEditor::film_changed (Film::Property p) } setup_dcp_name (); - _format_description->SetLabel (std_to_wx (_film->format()->description ())); + if (_film->format ()) { + _format_description->SetLabel (std_to_wx (_film->format()->description ())); + } else { + _format_description->SetLabel (wxT ("")); + } break; } case Film::CROP: @@ -781,8 +785,14 @@ FilmEditor::film_changed (Film::Property p) } } } - _frame_rate_description->SetLabel (std_to_wx (FrameRateConversion (_film->source_frame_rate(), _film->dcp_frame_rate()).description)); - _best_dcp_frame_rate->Enable (best_dcp_frame_rate (_film->source_frame_rate ()) != _film->dcp_frame_rate ()); + + if (_film->source_frame_rate()) { + _frame_rate_description->SetLabel (std_to_wx (FrameRateConversion (_film->source_frame_rate(), _film->dcp_frame_rate()).description)); + _best_dcp_frame_rate->Enable (best_dcp_frame_rate (_film->source_frame_rate ()) != _film->dcp_frame_rate ()); + } else { + _frame_rate_description->SetLabel (wxT ("")); + _best_dcp_frame_rate->Disable (); + } } } -- cgit v1.2.3 From 8563df673d03e7bbdc95fc1471ee7fddea78461c Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 4 Mar 2013 20:19:01 +0000 Subject: Move audio decoding to separate method and fix incorrect decoding when there are multiple audio packets per frame (e.g. with wmapro). --- src/lib/ffmpeg_decoder.cc | 126 +++++++++++++++++++++++++--------------------- src/lib/ffmpeg_decoder.h | 2 + 2 files changed, 72 insertions(+), 56 deletions(-) (limited to 'src') diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 462db283a..ca019e06a 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -245,14 +245,7 @@ FFmpegDecoder::pass () } if (_audio_stream && _opt.decode_audio) { - while (avcodec_decode_audio4 (_audio_codec_context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) { - int const data_size = av_samples_get_buffer_size ( - 0, _audio_codec_context->channels, _frame->nb_samples, audio_sample_format (), 1 - ); - - assert (_audio_codec_context->channels == _film->audio_channels()); - Audio (deinterleave_audio (_frame->data, data_size)); - } + decode_audio_packet (); } return true; @@ -280,54 +273,7 @@ FFmpegDecoder::pass () } } else if (ffa && _packet.stream_index == ffa->id() && _opt.decode_audio) { - - int frame_finished; - if (avcodec_decode_audio4 (_audio_codec_context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) { - - /* Where we are in the source, in seconds */ - double const source_pts_seconds = av_q2d (_format_context->streams[_packet.stream_index]->time_base) - * av_frame_get_best_effort_timestamp(_frame); - - /* We only decode audio if we've had our first video packet through, and if it - was before this packet. Until then audio is thrown away. - */ - - if ((_first_video && _first_video.get() <= source_pts_seconds) || !_opt.decode_video) { - - if (!_first_audio && _opt.decode_video) { - _first_audio = source_pts_seconds; - - /* This is our first audio frame, and if we've arrived here we must have had our - first video frame. Push some silence to make up any gap between our first - video frame and our first audio. - */ - - /* frames of silence that we must push */ - int const s = rint ((_first_audio.get() - _first_video.get()) * ffa->sample_rate ()); - - _film->log()->log ( - String::compose ( - N_("First video at %1, first audio at %2, pushing %3 audio frames of silence for %4 channels (%5 bytes per sample)"), - _first_video.get(), _first_audio.get(), s, ffa->channels(), bytes_per_audio_sample() - ) - ); - - if (s) { - shared_ptr audio (new AudioBuffers (ffa->channels(), s)); - audio->make_silent (); - Audio (audio); - } - } - - int const data_size = av_samples_get_buffer_size ( - 0, _audio_codec_context->channels, _frame->nb_samples, audio_sample_format (), 1 - ); - - assert (_audio_codec_context->channels == _film->audio_channels()); - Audio (deinterleave_audio (_frame->data, data_size)); - } - } - + decode_audio_packet (); } else if (_subtitle_stream && _packet.stream_index == _subtitle_stream->id() && _opt.decode_subtitles && _first_video) { int got_subtitle; @@ -744,3 +690,71 @@ FFmpegDecoder::frame_time () const return av_frame_get_best_effort_timestamp(_frame) * av_q2d (_format_context->streams[_video_stream]->time_base); } +void +FFmpegDecoder::decode_audio_packet () +{ + shared_ptr ffa = dynamic_pointer_cast (_audio_stream); + assert (ffa); + + /* Audio packets can contain multiple frames, so we may have to call avcodec_decode_audio4 + several times. + */ + + AVPacket copy_packet = _packet; + + while (copy_packet.size > 0) { + + int frame_finished; + int const decode_result = avcodec_decode_audio4 (_audio_codec_context, _frame, &frame_finished, ©_packet); + if (decode_result >= 0 && frame_finished) { + + /* Where we are in the source, in seconds */ + double const source_pts_seconds = av_q2d (_format_context->streams[copy_packet.stream_index]->time_base) + * av_frame_get_best_effort_timestamp(_frame); + + /* We only decode audio if we've had our first video packet through, and if it + was before this packet. Until then audio is thrown away. + */ + + if ((_first_video && _first_video.get() <= source_pts_seconds) || !_opt.decode_video) { + + if (!_first_audio && _opt.decode_video) { + _first_audio = source_pts_seconds; + + /* This is our first audio frame, and if we've arrived here we must have had our + first video frame. Push some silence to make up any gap between our first + video frame and our first audio. + */ + + /* frames of silence that we must push */ + int const s = rint ((_first_audio.get() - _first_video.get()) * ffa->sample_rate ()); + + _film->log()->log ( + String::compose ( + N_("First video at %1, first audio at %2, pushing %3 audio frames of silence for %4 channels (%5 bytes per sample)"), + _first_video.get(), _first_audio.get(), s, ffa->channels(), bytes_per_audio_sample() + ) + ); + + if (s) { + shared_ptr audio (new AudioBuffers (ffa->channels(), s)); + audio->make_silent (); + Audio (audio); + } + } + + int const data_size = av_samples_get_buffer_size ( + 0, _audio_codec_context->channels, _frame->nb_samples, audio_sample_format (), 1 + ); + + assert (_audio_codec_context->channels == _film->audio_channels()); + Audio (deinterleave_audio (_frame->data, data_size)); + } + } + + if (decode_result >= 0) { + copy_packet.data += decode_result; + copy_packet.size -= decode_result; + } + } +} diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h index c383b8d13..1bb14ce9c 100644 --- a/src/lib/ffmpeg_decoder.h +++ b/src/lib/ffmpeg_decoder.h @@ -120,6 +120,8 @@ private: void setup_audio (); void setup_subtitle (); + void decode_audio_packet (); + void maybe_add_subtitle (); boost::shared_ptr deinterleave_audio (uint8_t** data, int size); -- cgit v1.2.3 From 1489f3cca423827315ddb1cc77773e7a76b65fd2 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 5 Mar 2013 10:21:25 +0000 Subject: Maybe fix sense of note about DCP speed wrt source. --- src/lib/util.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/util.cc b/src/lib/util.cc index 71e864ebd..7395bde2e 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -971,7 +971,7 @@ FrameRateConversion::FrameRateConversion (float source, int dcp) } if (change_speed) { - float const pc = (source * factor()) * 100 / dcp; + float const pc = dcp / ((source * factor()) * 100); description += String::compose (_("DCP will run at %1%% of the source speed."), pc); } } -- cgit v1.2.3 From 743a2ad663b954a7009d1417332af0e71169b35f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 5 Mar 2013 11:52:50 +0000 Subject: Try again (fix previous). --- src/lib/util.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/util.cc b/src/lib/util.cc index 7395bde2e..53bdb4c79 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -971,7 +971,7 @@ FrameRateConversion::FrameRateConversion (float source, int dcp) } if (change_speed) { - float const pc = dcp / ((source * factor()) * 100); + float const pc = dcp * 100 / (source * factor()); description += String::compose (_("DCP will run at %1%% of the source speed."), pc); } } -- cgit v1.2.3 From 397b2d7ed429f3716416d67a67a7a38d536a40d5 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 5 Mar 2013 12:46:48 +0000 Subject: Tweak alignment. --- src/wx/film_editor.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 8330e3d3e..d2caa0dea 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -113,7 +113,7 @@ FilmEditor::make_film_panel () ++r; _use_dci_name = new wxCheckBox (_film_panel, wxID_ANY, _("Use DCI name")); - grid->Add (_use_dci_name, wxGBPosition (r, 0)); + grid->Add (_use_dci_name, wxGBPosition (r, 0), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); _edit_dci_button = new wxButton (_film_panel, wxID_ANY, _("Details...")); grid->Add (_edit_dci_button, wxGBPosition (r, 1), wxDefaultSpan); ++r; -- cgit v1.2.3 From 640f77662918211f3990b2d3481c60aaf1125d18 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 5 Mar 2013 20:08:19 +0000 Subject: Couple of small layout tweaks. --- src/wx/film_editor.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index d2caa0dea..b9a4012e3 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -104,7 +104,7 @@ FilmEditor::make_film_panel () add_label_to_grid_bag_sizer (grid, _film_panel, _("Name"), wxGBPosition (r, 0)); _name = new wxTextCtrl (_film_panel, wxID_ANY); - grid->Add (_name, wxGBPosition(r, 1)); + grid->Add (_name, wxGBPosition(r, 1), wxDefaultSpan, wxEXPAND); ++r; add_label_to_grid_bag_sizer (grid, _film_panel, _("DCP Name"), wxGBPosition (r, 0)); @@ -149,7 +149,7 @@ FilmEditor::make_film_panel () } ++r; - _frame_rate_description = new wxStaticText (_film_panel, wxID_ANY, wxT (""), wxDefaultPosition, wxDefaultSize); + _frame_rate_description = new wxStaticText (_film_panel, wxID_ANY, wxT (" \n "), wxDefaultPosition, wxDefaultSize); grid->Add (video_control (_frame_rate_description), wxGBPosition (r, 0), wxGBSpan (1, 2), wxEXPAND | wxALIGN_CENTER_VERTICAL | wxALL, 6); wxFont font = _frame_rate_description->GetFont(); font.SetStyle(wxFONTSTYLE_ITALIC); -- cgit v1.2.3 From 8fa7b8c13a76bd54207156de7bb0d09316bad379 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 5 Mar 2013 20:31:24 +0000 Subject: Fix comment. --- src/lib/ffmpeg_decoder.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index ca019e06a..ac25844e3 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -696,7 +696,7 @@ FFmpegDecoder::decode_audio_packet () shared_ptr ffa = dynamic_pointer_cast (_audio_stream); assert (ffa); - /* Audio packets can contain multiple frames, so we may have to call avcodec_decode_audio4 + /* Audio packets can contain multiple frames, so we may have to call avcodec_decode_audio4 several times. */ -- cgit v1.2.3 From 18614dda0d53b713ace5ad1df57298d049dba87f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 5 Mar 2013 23:10:16 +0000 Subject: Split timed from untimed sinks / sources. Should produce same output, in theory. --- src/lib/ab_transcoder.cc | 7 ++++--- src/lib/audio_decoder.h | 2 +- src/lib/audio_sink.h | 7 +++++++ src/lib/audio_source.cc | 6 ++++++ src/lib/audio_source.h | 12 +++++++++++ src/lib/combiner.cc | 8 ++++---- src/lib/combiner.h | 6 +++--- src/lib/delay_line.cc | 7 ++++--- src/lib/delay_line.h | 4 ++-- src/lib/external_audio_decoder.cc | 4 +++- src/lib/ffmpeg_decoder.cc | 8 +++++--- src/lib/gain.cc | 2 +- src/lib/gain.h | 2 +- src/lib/imagemagick_decoder.cc | 3 ++- src/lib/matcher.cc | 6 +++--- src/lib/matcher.h | 6 +++--- src/lib/processor.h | 42 --------------------------------------- src/lib/transcoder.cc | 3 ++- src/lib/video_decoder.cc | 10 +++++----- src/lib/video_decoder.h | 6 +++--- src/lib/video_sink.h | 12 +++++++++++ src/lib/video_source.cc | 6 ++++++ src/lib/video_source.h | 23 +++++++++++++++++++-- test/test.cc | 6 ++++-- 24 files changed, 114 insertions(+), 84 deletions(-) (limited to 'src') diff --git a/src/lib/ab_transcoder.cc b/src/lib/ab_transcoder.cc index 4ed5d02ca..373549b57 100644 --- a/src/lib/ab_transcoder.cc +++ b/src/lib/ab_transcoder.cc @@ -70,14 +70,15 @@ ABTranscoder::ABTranscoder ( _db.video->set_subtitle_stream (_film_a->subtitle_stream ()); _da.audio->set_audio_stream (_film_a->audio_stream ()); - _da.video->Video.connect (bind (&Combiner::process_video, _combiner, _1, _2, _3)); - _db.video->Video.connect (bind (&Combiner::process_video_b, _combiner, _1, _2, _3)); + _da.video->Video.connect (bind (&Combiner::process_video, _combiner, _1, _2, _3, _4)); + _db.video->Video.connect (bind (&Combiner::process_video_b, _combiner, _1, _2, _3, _4)); if (_matcher) { _combiner->connect_video (_matcher); _matcher->connect_video (_encoder); } else { - _combiner->connect_video (_encoder); + /* Remove timestamp from the output of the combiner */ + _combiner->Video.connect (bind (&Encoder::process_video, _encoder, _1, _2, _3)); } if (_matcher && _delay_line) { diff --git a/src/lib/audio_decoder.h b/src/lib/audio_decoder.h index 9bef8e0e7..cfe94b528 100644 --- a/src/lib/audio_decoder.h +++ b/src/lib/audio_decoder.h @@ -31,7 +31,7 @@ /** @class AudioDecoder. * @brief Parent class for audio decoders. */ -class AudioDecoder : public AudioSource, public virtual Decoder +class AudioDecoder : public TimedAudioSource, public virtual Decoder { public: AudioDecoder (boost::shared_ptr, DecodeOptions); diff --git a/src/lib/audio_sink.h b/src/lib/audio_sink.h index 11d578a60..a222bd6a0 100644 --- a/src/lib/audio_sink.h +++ b/src/lib/audio_sink.h @@ -27,4 +27,11 @@ public: virtual void process_audio (boost::shared_ptr) = 0; }; +class TimedAudioSink +{ +public: + /** Call with some audio data */ + virtual void process_audio (boost::shared_ptr, double t) = 0; +}; + #endif diff --git a/src/lib/audio_source.cc b/src/lib/audio_source.cc index 53b0dda15..bca3562cf 100644 --- a/src/lib/audio_source.cc +++ b/src/lib/audio_source.cc @@ -28,3 +28,9 @@ AudioSource::connect_audio (shared_ptr s) { Audio.connect (bind (&AudioSink::process_audio, s, _1)); } + +void +TimedAudioSource::connect_audio (shared_ptr s) +{ + Audio.connect (bind (&TimedAudioSink::process_audio, s, _1, _2)); +} diff --git a/src/lib/audio_source.h b/src/lib/audio_source.h index 5a1510d3c..3dc998cca 100644 --- a/src/lib/audio_source.h +++ b/src/lib/audio_source.h @@ -28,6 +28,7 @@ class AudioBuffers; class AudioSink; +class TimedAudioSink; /** A class that emits audio data */ class AudioSource @@ -39,4 +40,15 @@ public: void connect_audio (boost::shared_ptr); }; + +/** A class that emits audio data with timestamps */ +class TimedAudioSource +{ +public: + /** Emitted when some audio data is ready */ + boost::signals2::signal, double)> Audio; + + void connect_audio (boost::shared_ptr); +}; + #endif diff --git a/src/lib/combiner.cc b/src/lib/combiner.cc index 68aafd2a2..e628f3a84 100644 --- a/src/lib/combiner.cc +++ b/src/lib/combiner.cc @@ -23,7 +23,7 @@ using boost::shared_ptr; Combiner::Combiner (Log* log) - : VideoProcessor (log) + : Processor (log) { } @@ -33,7 +33,7 @@ Combiner::Combiner (Log* log) * @param image Frame image. */ void -Combiner::process_video (shared_ptr image, bool, shared_ptr) +Combiner::process_video (shared_ptr image, bool, shared_ptr, double) { _image = image; } @@ -43,7 +43,7 @@ Combiner::process_video (shared_ptr image, bool, shared_ptr) * @param sub Subtitle (which will be put onto the whole frame) */ void -Combiner::process_video_b (shared_ptr image, bool, shared_ptr sub) +Combiner::process_video_b (shared_ptr image, bool, shared_ptr sub, double t) { /* Copy the right half of this image into our _image */ /* XXX: this should probably be in the Image class */ @@ -62,6 +62,6 @@ Combiner::process_video_b (shared_ptr image, bool, shared_ptr s } } - Video (_image, false, sub); + Video (_image, false, sub, t); _image.reset (); } diff --git a/src/lib/combiner.h b/src/lib/combiner.h index 7fad1aeae..c52c53ed9 100644 --- a/src/lib/combiner.h +++ b/src/lib/combiner.h @@ -28,13 +28,13 @@ * one image used for the left half of the screen and the other for * the right. */ -class Combiner : public VideoProcessor +class Combiner : public Processor, public TimedVideoSink, public TimedVideoSource { public: Combiner (Log* log); - void process_video (boost::shared_ptr i, bool, boost::shared_ptr s); - void process_video_b (boost::shared_ptr i, bool, boost::shared_ptr s); + void process_video (boost::shared_ptr i, bool, boost::shared_ptr s, double t); + void process_video_b (boost::shared_ptr i, bool, boost::shared_ptr s, double t); private: /** The image that we are currently working on */ diff --git a/src/lib/delay_line.cc b/src/lib/delay_line.cc index 4ad172781..84785cfc6 100644 --- a/src/lib/delay_line.cc +++ b/src/lib/delay_line.cc @@ -31,7 +31,7 @@ using boost::shared_ptr; * @param frames Delay in frames, +ve to move audio later. */ DelayLine::DelayLine (Log* log, int channels, int frames) - : AudioProcessor (log) + : Processor (log) , _negative_delay_remaining (0) , _frames (frames) { @@ -47,8 +47,9 @@ DelayLine::DelayLine (Log* log, int channels, int frames) } } +/* XXX: can we just get rid of all this and fiddle with the timestamp? */ void -DelayLine::process_audio (shared_ptr data) +DelayLine::process_audio (shared_ptr data, double t) { if (_buffers) { /* We have some buffers, so we are moving the audio later */ @@ -89,5 +90,5 @@ DelayLine::process_audio (shared_ptr data) } } - Audio (data); + Audio (data, t); } diff --git a/src/lib/delay_line.h b/src/lib/delay_line.h index 4d6f1313b..8c4a3953c 100644 --- a/src/lib/delay_line.h +++ b/src/lib/delay_line.h @@ -23,12 +23,12 @@ class AudioBuffers; /** A delay line for audio */ -class DelayLine : public AudioProcessor +class DelayLine : public Processor, public TimedAudioSink, public TimedAudioSource { public: DelayLine (Log* log, int channels, int frames); - void process_audio (boost::shared_ptr); + void process_audio (boost::shared_ptr, double); private: boost::shared_ptr _buffers; diff --git a/src/lib/external_audio_decoder.cc b/src/lib/external_audio_decoder.cc index 1248b5a3b..50e5852c5 100644 --- a/src/lib/external_audio_decoder.cc +++ b/src/lib/external_audio_decoder.cc @@ -115,6 +115,7 @@ ExternalAudioDecoder::pass () sf_count_t const block = _audio_stream->sample_rate() / 2; shared_ptr audio (new AudioBuffers (_audio_stream->channels(), block)); + sf_count_t done = 0; while (frames > 0) { sf_count_t const this_time = min (block, frames); for (size_t i = 0; i < sndfiles.size(); ++i) { @@ -126,7 +127,8 @@ ExternalAudioDecoder::pass () } audio->set_frames (this_time); - Audio (audio); + Audio (audio, double(done) / _audio_stream->sample_rate()); + done += this_time; frames -= this_time; } diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index ac25844e3..32c8e224a 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -640,7 +640,8 @@ FFmpegDecoder::out_with_sync () if (delta > one_frame) { int const extra = rint (delta / one_frame); for (int i = 0; i < extra; ++i) { - repeat_last_video (); + /* XXX: timestamp is wrong */ + repeat_last_video (source_pts_seconds); _film->log()->log ( String::compose ( N_("Extra video frame inserted at %1s; source frame %2, source PTS %3 (at %4 fps)"), @@ -739,7 +740,8 @@ FFmpegDecoder::decode_audio_packet () if (s) { shared_ptr audio (new AudioBuffers (ffa->channels(), s)); audio->make_silent (); - Audio (audio); + /* XXX: this time stamp is wrong */ + Audio (audio, source_pts_seconds); } } @@ -748,7 +750,7 @@ FFmpegDecoder::decode_audio_packet () ); assert (_audio_codec_context->channels == _film->audio_channels()); - Audio (deinterleave_audio (_frame->data, data_size)); + Audio (deinterleave_audio (_frame->data, data_size), source_pts_seconds ); } } diff --git a/src/lib/gain.cc b/src/lib/gain.cc index cec3b3c62..35ce27cea 100644 --- a/src/lib/gain.cc +++ b/src/lib/gain.cc @@ -23,7 +23,7 @@ using boost::shared_ptr; /** @param gain gain in dB */ Gain::Gain (Log* log, float gain) - : AudioProcessor (log) + : Processor (log) , _gain (gain) { diff --git a/src/lib/gain.h b/src/lib/gain.h index 716ee9b51..449473582 100644 --- a/src/lib/gain.h +++ b/src/lib/gain.h @@ -19,7 +19,7 @@ #include "processor.h" -class Gain : public AudioProcessor +class Gain : public Processor, public AudioSink, public AudioSource { public: Gain (Log* log, float gain); diff --git a/src/lib/imagemagick_decoder.cc b/src/lib/imagemagick_decoder.cc index 5dc0b7b06..38dace6de 100644 --- a/src/lib/imagemagick_decoder.cc +++ b/src/lib/imagemagick_decoder.cc @@ -77,7 +77,8 @@ ImageMagickDecoder::pass () return true; } - repeat_last_video (); + /* XXX: timestamp is wrong */ + repeat_last_video (0); return false; } diff --git a/src/lib/matcher.cc b/src/lib/matcher.cc index 4cd264338..3a513b24e 100644 --- a/src/lib/matcher.cc +++ b/src/lib/matcher.cc @@ -27,7 +27,7 @@ using std::min; using boost::shared_ptr; Matcher::Matcher (Log* log, int sample_rate, float frames_per_second) - : AudioVideoProcessor (log) + : Processor (log) , _sample_rate (sample_rate) , _frames_per_second (frames_per_second) , _video_frames (0) @@ -37,7 +37,7 @@ Matcher::Matcher (Log* log, int sample_rate, float frames_per_second) } void -Matcher::process_video (boost::shared_ptr i, bool same, boost::shared_ptr s) +Matcher::process_video (boost::shared_ptr i, bool same, boost::shared_ptr s, double) { Video (i, same, s); _video_frames++; @@ -47,7 +47,7 @@ Matcher::process_video (boost::shared_ptr i, bool same, boost::shared_ptr } void -Matcher::process_audio (boost::shared_ptr b) +Matcher::process_audio (boost::shared_ptr b, double) { Audio (b); _audio_frames += b->frames (); diff --git a/src/lib/matcher.h b/src/lib/matcher.h index 60bb87432..4a66f4e70 100644 --- a/src/lib/matcher.h +++ b/src/lib/matcher.h @@ -21,12 +21,12 @@ #include "processor.h" #include "ffmpeg_compatibility.h" -class Matcher : public AudioVideoProcessor +class Matcher : public Processor, public TimedVideoSink, public TimedAudioSink, public VideoSource, public AudioSource { public: Matcher (Log* log, int sample_rate, float frames_per_second); - void process_video (boost::shared_ptr i, bool, boost::shared_ptr s); - void process_audio (boost::shared_ptr); + void process_video (boost::shared_ptr i, bool, boost::shared_ptr s, double t); + void process_audio (boost::shared_ptr, double t); void process_end (); private: diff --git a/src/lib/processor.h b/src/lib/processor.h index 19d7c4b0c..863bfdbb5 100644 --- a/src/lib/processor.h +++ b/src/lib/processor.h @@ -53,46 +53,4 @@ protected: Log* _log; ///< log to write to }; -/** @class AudioVideoProcessor - * @brief A processor which handles both video and audio data. - */ -class AudioVideoProcessor : public Processor, public VideoSource, public VideoSink, public AudioSource, public AudioSink -{ -public: - /** Construct an AudioVideoProcessor. - * @param log Log to write to. - */ - AudioVideoProcessor (Log* log) - : Processor (log) - {} -}; - -/** @class AudioProcessor - * @brief A processor which handles just audio data. - */ -class AudioProcessor : public Processor, public AudioSource, public AudioSink -{ -public: - /** Construct an AudioProcessor. - * @param log Log to write to. - */ - AudioProcessor (Log* log) - : Processor (log) - {} -}; - -/** @class VideoProcessor - * @brief A processor which handles just video data. - */ -class VideoProcessor : public Processor, public VideoSource, public VideoSink -{ -public: - /** Construct an VideoProcessor. - * @param log Log to write to. - */ - VideoProcessor (Log* log) - : Processor (log) - {} -}; - #endif diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc index 9720ca56a..3beda2b8b 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -72,7 +72,8 @@ Transcoder::Transcoder (shared_ptr f, DecodeOptions o, Job* j, shared_ptr< _decoders.video->connect_video (_matcher); _matcher->connect_video (_encoder); } else { - _decoders.video->connect_video (_encoder); + /* Discard timestamps here */ + _decoders.video->Video.connect (boost::bind (&Encoder::process_video, _encoder, _1, _2, _3)); } if (_matcher && _delay_line && _decoders.audio) { diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc index 891720f6b..773688b34 100644 --- a/src/lib/video_decoder.cc +++ b/src/lib/video_decoder.cc @@ -51,7 +51,7 @@ VideoDecoder::emit_video (shared_ptr image, double t) sub = _timed_subtitle->subtitle (); } - signal_video (image, false, sub); + signal_video (image, false, sub, t); _last_source_time = t; } @@ -60,14 +60,14 @@ VideoDecoder::emit_video (shared_ptr image, double t) * we will generate a black frame. */ void -VideoDecoder::repeat_last_video () +VideoDecoder::repeat_last_video (double t) { if (!_last_image) { _last_image.reset (new SimpleImage (pixel_format(), native_size(), true)); _last_image->make_black (); } - signal_video (_last_image, true, _last_subtitle); + signal_video (_last_image, true, _last_subtitle, t); } /** Emit our signal to say that some video data is ready. @@ -76,10 +76,10 @@ VideoDecoder::repeat_last_video () * @param sub Subtitle for this frame, or 0. */ void -VideoDecoder::signal_video (shared_ptr image, bool same, shared_ptr sub) +VideoDecoder::signal_video (shared_ptr image, bool same, shared_ptr sub, double t) { TIMING (N_("Decoder emits %1"), _video_frame); - Video (image, same, sub); + Video (image, same, sub, t); ++_video_frame; _last_image = image; diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h index 283ab5d88..5e9c60d08 100644 --- a/src/lib/video_decoder.h +++ b/src/lib/video_decoder.h @@ -24,7 +24,7 @@ #include "stream.h" #include "decoder.h" -class VideoDecoder : public VideoSource, public virtual Decoder +class VideoDecoder : public TimedVideoSource, public virtual Decoder { public: VideoDecoder (boost::shared_ptr, DecodeOptions); @@ -67,7 +67,7 @@ protected: void emit_video (boost::shared_ptr, double); void emit_subtitle (boost::shared_ptr); - void repeat_last_video (); + void repeat_last_video (double t); /** Subtitle stream to use when decoding */ boost::shared_ptr _subtitle_stream; @@ -75,7 +75,7 @@ protected: std::vector > _subtitle_streams; private: - void signal_video (boost::shared_ptr, bool, boost::shared_ptr); + void signal_video (boost::shared_ptr, bool, boost::shared_ptr, double); int _video_frame; double _last_source_time; diff --git a/src/lib/video_sink.h b/src/lib/video_sink.h index 7c128cf73..32c7f3b38 100644 --- a/src/lib/video_sink.h +++ b/src/lib/video_sink.h @@ -37,4 +37,16 @@ public: virtual void process_video (boost::shared_ptr i, bool same, boost::shared_ptr s) = 0; }; +class TimedVideoSink +{ +public: + /** Call with a frame of video. + * @param i Video frame image. + * @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. + * @param t Source timestamp. + */ + virtual void process_video (boost::shared_ptr i, bool same, boost::shared_ptr s, double t) = 0; +}; + #endif diff --git a/src/lib/video_source.cc b/src/lib/video_source.cc index 56742e2b4..af6f941fd 100644 --- a/src/lib/video_source.cc +++ b/src/lib/video_source.cc @@ -28,3 +28,9 @@ VideoSource::connect_video (shared_ptr s) { Video.connect (bind (&VideoSink::process_video, s, _1, _2, _3)); } + +void +TimedVideoSource::connect_video (shared_ptr s) +{ + Video.connect (bind (&TimedVideoSink::process_video, s, _1, _2, _3, _4)); +} diff --git a/src/lib/video_source.h b/src/lib/video_source.h index 893629160..705b0023a 100644 --- a/src/lib/video_source.h +++ b/src/lib/video_source.h @@ -29,11 +29,12 @@ #include "util.h" class VideoSink; +class TimedVideoSink; class Subtitle; class Image; -/** @class VideoSink - * @param A class that emits video data. +/** @class VideoSource + * @param A class that emits video data without timestamps. */ class VideoSource { @@ -49,4 +50,22 @@ public: void connect_video (boost::shared_ptr); }; +/** @class TimedVideoSource + * @param A class that emits video data with timestamps. + */ +class TimedVideoSource +{ +public: + + /** Emitted when a video frame is ready. + * First parameter is the video image. + * 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. + * Fourth parameter is the source timestamp of this frame. + */ + boost::signals2::signal, bool, boost::shared_ptr, double)> Video; + + void connect_video (boost::shared_ptr); +}; + #endif diff --git a/test/test.cc b/test/test.cc index 15c34ca78..b2af8ab22 100644 --- a/test/test.cc +++ b/test/test.cc @@ -273,7 +273,8 @@ do_positive_delay_line_test (int delay_length, int data_length) } /* This only works because the delay line modifies the parameter */ - d.process_audio (data); + /* XXX: timestamp is wrong */ + d.process_audio (data, 0); returned += data->frames (); for (int j = 0; j < data->frames(); ++j) { @@ -316,7 +317,8 @@ do_negative_delay_line_test (int delay_length, int data_length) } /* This only works because the delay line modifies the parameter */ - d.process_audio (data); + /* XXX: timestamp is wrong */ + d.process_audio (data, 0); returned += data->frames (); for (int j = 0; j < data->frames(); ++j) { -- cgit v1.2.3 From 59de84a29b81ac32477a4b804ca8bb9ec2760e67 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 6 Mar 2013 00:46:10 +0000 Subject: First cut. --- src/lib/ffmpeg_decoder.cc | 126 +++++------------------------------ src/lib/ffmpeg_decoder.h | 7 +- src/lib/imagemagick_decoder.cc | 14 ++-- src/lib/imagemagick_decoder.h | 3 + src/lib/matcher.cc | 148 ++++++++++++++++++++++++++++++++--------- src/lib/matcher.h | 36 ++++++++++ src/lib/video_decoder.cc | 19 +----- src/lib/video_decoder.h | 4 -- 8 files changed, 182 insertions(+), 175 deletions(-) (limited to 'src') diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 32c8e224a..f801821e9 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -80,10 +80,6 @@ FFmpegDecoder::FFmpegDecoder (shared_ptr f, DecodeOptions o) setup_video (); setup_audio (); setup_subtitle (); - - if (!o.video_sync) { - _first_video = 0; - } } FFmpegDecoder::~FFmpegDecoder () @@ -240,7 +236,7 @@ FFmpegDecoder::pass () if (_opt.decode_video) { while (avcodec_decode_video2 (_video_codec_context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) { - filter_and_emit_video (_frame); + filter_and_emit_video (); } } @@ -265,16 +261,12 @@ FFmpegDecoder::pass () _film->log()->log (String::compose (N_("Used only %1 bytes of %2 in packet"), r, _packet.size)); } - if (_opt.video_sync) { - out_with_sync (); - } else { - filter_and_emit_video (_frame); - } + filter_and_emit_video (); } } else if (ffa && _packet.stream_index == ffa->id() && _opt.decode_audio) { decode_audio_packet (); - } else if (_subtitle_stream && _packet.stream_index == _subtitle_stream->id() && _opt.decode_subtitles && _first_video) { + } else if (_subtitle_stream && _packet.stream_index == _subtitle_stream->id() && _opt.decode_subtitles) { int got_subtitle; AVSubtitle sub; @@ -504,29 +496,29 @@ FFmpegDecoder::set_subtitle_stream (shared_ptr s) } void -FFmpegDecoder::filter_and_emit_video (AVFrame* frame) +FFmpegDecoder::filter_and_emit_video () { boost::mutex::scoped_lock lm (_filter_graphs_mutex); shared_ptr graph; list >::iterator i = _filter_graphs.begin(); - while (i != _filter_graphs.end() && !(*i)->can_process (libdcp::Size (frame->width, frame->height), (AVPixelFormat) frame->format)) { + while (i != _filter_graphs.end() && !(*i)->can_process (libdcp::Size (_frame->width, _frame->height), (AVPixelFormat) _frame->format)) { ++i; } if (i == _filter_graphs.end ()) { - graph.reset (new FilterGraph (_film, this, libdcp::Size (frame->width, frame->height), (AVPixelFormat) frame->format)); + graph.reset (new FilterGraph (_film, this, libdcp::Size (_frame->width, _frame->height), (AVPixelFormat) _frame->format)); _filter_graphs.push_back (graph); - _film->log()->log (String::compose (N_("New graph for %1x%2, pixel format %3"), frame->width, frame->height, frame->format)); + _film->log()->log (String::compose (N_("New graph for %1x%2, pixel format %3"), _frame->width, _frame->height, _frame->format)); } else { graph = *i; } - list > images = graph->process (frame); + list > images = graph->process (_frame); for (list >::iterator i = images.begin(); i != images.end(); ++i) { - emit_video (*i, frame_time ()); + emit_video (*i, av_frame_get_best_effort_timestamp (_frame) * av_q2d (_format_context->streams[_video_stream]->time_base)); } } @@ -613,53 +605,6 @@ FFmpegAudioStream::to_string () const return String::compose (N_("ffmpeg %1 %2 %3 %4"), _id, _sample_rate, _channel_layout, _name); } -void -FFmpegDecoder::out_with_sync () -{ - /* Where we are in the output, in seconds */ - double const out_pts_seconds = video_frame() / frames_per_second(); - - /* Where we are in the source, in seconds */ - double const source_pts_seconds = av_q2d (_format_context->streams[_packet.stream_index]->time_base) - * av_frame_get_best_effort_timestamp(_frame); - - _film->log()->log ( - String::compose (N_("Source video frame ready; source at %1, output at %2"), source_pts_seconds, out_pts_seconds), - Log::VERBOSE - ); - - if (!_first_video) { - _first_video = source_pts_seconds; - } - - /* Difference between where we are and where we should be */ - double const delta = source_pts_seconds - _first_video.get() - out_pts_seconds; - double const one_frame = 1 / frames_per_second(); - - /* Insert frames if required to get out_pts_seconds up to pts_seconds */ - if (delta > one_frame) { - int const extra = rint (delta / one_frame); - for (int i = 0; i < extra; ++i) { - /* XXX: timestamp is wrong */ - repeat_last_video (source_pts_seconds); - _film->log()->log ( - String::compose ( - N_("Extra video frame inserted at %1s; source frame %2, source PTS %3 (at %4 fps)"), - out_pts_seconds, video_frame(), source_pts_seconds, frames_per_second() - ) - ); - } - } - - if (delta > -one_frame) { - /* Process this frame */ - filter_and_emit_video (_frame); - } else { - /* Otherwise we are omitting a frame to keep things right */ - _film->log()->log (String::compose (N_("Frame removed at %1s"), out_pts_seconds)); - } -} - void FFmpegDecoder::film_changed (Film::Property p) { @@ -685,12 +630,6 @@ FFmpegDecoder::length () const return (double(_format_context->duration) / AV_TIME_BASE) * frames_per_second(); } -double -FFmpegDecoder::frame_time () const -{ - return av_frame_get_best_effort_timestamp(_frame) * av_q2d (_format_context->streams[_video_stream]->time_base); -} - void FFmpegDecoder::decode_audio_packet () { @@ -707,54 +646,21 @@ FFmpegDecoder::decode_audio_packet () int frame_finished; int const decode_result = avcodec_decode_audio4 (_audio_codec_context, _frame, &frame_finished, ©_packet); - if (decode_result >= 0 && frame_finished) { - - /* Where we are in the source, in seconds */ - double const source_pts_seconds = av_q2d (_format_context->streams[copy_packet.stream_index]->time_base) - * av_frame_get_best_effort_timestamp(_frame); - - /* We only decode audio if we've had our first video packet through, and if it - was before this packet. Until then audio is thrown away. - */ + if (decode_result >= 0) { + if (frame_finished) { - if ((_first_video && _first_video.get() <= source_pts_seconds) || !_opt.decode_video) { - - if (!_first_audio && _opt.decode_video) { - _first_audio = source_pts_seconds; - - /* This is our first audio frame, and if we've arrived here we must have had our - first video frame. Push some silence to make up any gap between our first - video frame and our first audio. - */ - - /* frames of silence that we must push */ - int const s = rint ((_first_audio.get() - _first_video.get()) * ffa->sample_rate ()); - - _film->log()->log ( - String::compose ( - N_("First video at %1, first audio at %2, pushing %3 audio frames of silence for %4 channels (%5 bytes per sample)"), - _first_video.get(), _first_audio.get(), s, ffa->channels(), bytes_per_audio_sample() - ) - ); - - if (s) { - shared_ptr audio (new AudioBuffers (ffa->channels(), s)); - audio->make_silent (); - /* XXX: this time stamp is wrong */ - Audio (audio, source_pts_seconds); - } - } + /* Where we are in the source, in seconds */ + double const source_pts_seconds = av_q2d (_format_context->streams[copy_packet.stream_index]->time_base) + * av_frame_get_best_effort_timestamp(_frame); int const data_size = av_samples_get_buffer_size ( 0, _audio_codec_context->channels, _frame->nb_samples, audio_sample_format (), 1 ); assert (_audio_codec_context->channels == _film->audio_channels()); - Audio (deinterleave_audio (_frame->data, data_size), source_pts_seconds ); + Audio (deinterleave_audio (_frame->data, data_size), source_pts_seconds); } - } - - if (decode_result >= 0) { + copy_packet.data += decode_result; copy_packet.size -= decode_result; } diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h index 1bb14ce9c..2a4d40b1d 100644 --- a/src/lib/ffmpeg_decoder.h +++ b/src/lib/ffmpeg_decoder.h @@ -111,9 +111,7 @@ private: AVSampleFormat audio_sample_format () const; int bytes_per_audio_sample () const; - void out_with_sync (); - void filter_and_emit_video (AVFrame *); - double frame_time () const; + void filter_and_emit_video (); void setup_general (); void setup_video (); @@ -143,9 +141,6 @@ private: AVPacket _packet; - boost::optional _first_video; - boost::optional _first_audio; - std::list > _filter_graphs; boost::mutex _filter_graphs_mutex; }; diff --git a/src/lib/imagemagick_decoder.cc b/src/lib/imagemagick_decoder.cc index 38dace6de..119f05792 100644 --- a/src/lib/imagemagick_decoder.cc +++ b/src/lib/imagemagick_decoder.cc @@ -31,6 +31,8 @@ using std::cout; using boost::shared_ptr; using libdcp::Size; +/* XXX: reads a directory and then ignores it */ + ImageMagickDecoder::ImageMagickDecoder ( boost::shared_ptr f, DecodeOptions o) : Decoder (f, o) @@ -77,8 +79,8 @@ ImageMagickDecoder::pass () return true; } - /* XXX: timestamp is wrong */ - repeat_last_video (0); + /* XXX: timestamp */ + emit_video (_image, 0); return false; } @@ -101,9 +103,10 @@ ImageMagickDecoder::pass () delete magick_image; - image = image->crop (_film->crop(), true); - - emit_video (image, 0); + _image = image->crop (_film->crop(), true); + + /* XXX: timestamp */ + emit_video (_image, 0); ++_iter; return false; @@ -131,6 +134,7 @@ ImageMagickDecoder::seek_to_last () bool ImageMagickDecoder::seek (double t) { + /* XXX: frames_per_second == 0 */ int const f = t * frames_per_second(); _iter = _files.begin (); diff --git a/src/lib/imagemagick_decoder.h b/src/lib/imagemagick_decoder.h index 0e375f6e9..ef550c651 100644 --- a/src/lib/imagemagick_decoder.h +++ b/src/lib/imagemagick_decoder.h @@ -86,4 +86,7 @@ private: std::list _files; std::list::iterator _iter; + + boost::shared_ptr _image; + }; diff --git a/src/lib/matcher.cc b/src/lib/matcher.cc index 3a513b24e..70a9b2a85 100644 --- a/src/lib/matcher.cc +++ b/src/lib/matcher.cc @@ -24,6 +24,8 @@ #include "i18n.h" using std::min; +using std::cout; +using std::list; using boost::shared_ptr; Matcher::Matcher (Log* log, int sample_rate, float frames_per_second) @@ -37,22 +39,72 @@ Matcher::Matcher (Log* log, int sample_rate, float frames_per_second) } void -Matcher::process_video (boost::shared_ptr i, bool same, boost::shared_ptr s, double) +Matcher::process_video (boost::shared_ptr image, bool same, boost::shared_ptr sub, double t) { - Video (i, same, s); - _video_frames++; + _pixel_format = image->pixel_format (); + _size = image->size (); - _pixel_format = i->pixel_format (); - _size = i->size (); + if (!_first_input) { + _first_input = t; + } + + if (_audio_frames == 0 && _pending_audio.empty ()) { + /* No audio yet; we must postpone this frame until we have some */ + _pending_video.push_back (VideoRecord (image, same, sub, t)); + } else if (!_pending_audio.empty() && _pending_video.empty ()) { + /* First video since we got audio */ + _pending_video.push_back (VideoRecord (image, same, sub, t)); + fix_start (); + } else { + /* Normal running */ + + /* Difference between where this video is and where it should be */ + double const delta = t - _first_input.get() - _video_frames / _frames_per_second; + double const one_frame = 1 / _frames_per_second; + + if (delta > one_frame) { + /* Insert frames to make up the difference */ + int const extra = rint (delta / one_frame); + for (int i = 0; i < extra; ++i) { + repeat_last_video (); + _log->log (String::compose ("Extra video frame inserted at %1s", _video_frames / _frames_per_second)); + } + } + + if (delta > -one_frame) { + Video (image, same, sub); + ++_video_frames; + } else { + /* We are omitting a frame to keep things right */ + _log->log (String::compose ("Frame removed at %1s", t)); + } + } + + _last_image = image; + _last_subtitle = sub; } void -Matcher::process_audio (boost::shared_ptr b, double) +Matcher::process_audio (boost::shared_ptr b, double t) { - Audio (b); - _audio_frames += b->frames (); - _channels = b->channels (); + + if (!_first_input) { + _first_input = t; + } + + if (_video_frames == 0 && _pending_video.empty ()) { + /* No video yet; we must postpone these data until we have some */ + _pending_audio.push_back (AudioRecord (b, t)); + } else if (!_pending_video.empty() && _pending_audio.empty ()) { + /* First audio since we got video */ + _pending_audio.push_back (AudioRecord (b, t)); + fix_start (); + } else { + /* Normal running. We assume audio time stamps are consecutive */ + Audio (b); + _audio_frames += b->frames (); + } } void @@ -63,38 +115,58 @@ Matcher::process_end () return; } - int64_t audio_short_by_frames = video_frames_to_audio_frames (_video_frames, _sample_rate, _frames_per_second) - _audio_frames; - - _log->log ( - String::compose ( - N_("Matching processor has seen %1 video frames (which equals %2 audio frames) and %3 audio frames"), - _video_frames, - video_frames_to_audio_frames (_video_frames, _sample_rate, _frames_per_second), - _audio_frames - ) - ); + match ((double (_audio_frames) / _sample_rate) - (double (_video_frames) / _frames_per_second)); +} + +void +Matcher::fix_start () +{ + assert (!_pending_video.empty ()); + assert (!_pending_audio.empty ()); + + _log->log (String::compose ("Fixing start; video at %1, audio at %2", _pending_video.front().time, _pending_audio.front().time)); + + match (_pending_video.front().time - _pending_audio.front().time); + + for (list::iterator i = _pending_video.begin(); i != _pending_video.end(); ++i) { + Video (i->image, i->same, i->subtitle); + } + + for (list::iterator i = _pending_audio.begin(); i != _pending_audio.end(); ++i) { + Audio (i->audio); + } - if (audio_short_by_frames < 0) { - - _log->log (String::compose (N_("%1 too many audio frames"), -audio_short_by_frames)); - - /* We have seen more audio than video. Emit enough black video frames so that we reverse this */ - int const black_video_frames = ceil (-audio_short_by_frames * _frames_per_second / _sample_rate); + _pending_video.clear (); + _pending_audio.clear (); +} + +void +Matcher::match (double extra_video_needed) +{ + if (extra_video_needed) { + + /* Emit black video frames */ + int const black_video_frames = ceil (extra_video_needed * _frames_per_second); + _log->log (String::compose (N_("Emitting %1 frames of black video"), black_video_frames)); shared_ptr black (new SimpleImage (_pixel_format.get(), _size.get(), true)); black->make_black (); for (int i = 0; i < black_video_frames; ++i) { Video (black, i != 0, shared_ptr()); + ++_video_frames; } - - /* Now recompute our check value */ - audio_short_by_frames = video_frames_to_audio_frames (_video_frames, _sample_rate, _frames_per_second) - _audio_frames; + + extra_video_needed -= black_video_frames / _frames_per_second; } - - if (audio_short_by_frames > 0) { - _log->log (String::compose (N_("Emitted %1 too few audio frames"), audio_short_by_frames)); + + if (extra_video_needed < 0) { + + /* Emit silence */ + + int64_t to_do = rint (-extra_video_needed * _sample_rate); + _log->log (String::compose (N_("Emitted %1 frames of silence"), to_do)); /* Do things in half second blocks as I think there may be limits to what FFmpeg (and in particular the resampler) can cope with. @@ -103,7 +175,6 @@ Matcher::process_end () shared_ptr b (new AudioBuffers (_channels.get(), block)); b->make_silent (); - int64_t to_do = audio_short_by_frames; while (to_do > 0) { int64_t const this_time = min (to_do, block); b->set_frames (this_time); @@ -113,3 +184,16 @@ Matcher::process_end () } } } + +void +Matcher::repeat_last_video () +{ + if (!_last_image) { + _last_image.reset (new SimpleImage (_pixel_format.get(), _size.get(), true)); + _last_image->make_black (); + } + + Video (_last_image, true, _last_subtitle); + ++_video_frames; +} + diff --git a/src/lib/matcher.h b/src/lib/matcher.h index 4a66f4e70..2f580b589 100644 --- a/src/lib/matcher.h +++ b/src/lib/matcher.h @@ -30,6 +30,10 @@ public: void process_end (); private: + void fix_start (); + void match (double); + void repeat_last_video (); + int _sample_rate; float _frames_per_second; int _video_frames; @@ -37,4 +41,36 @@ private: boost::optional _pixel_format; boost::optional _size; boost::optional _channels; + + struct VideoRecord { + VideoRecord (boost::shared_ptr i, bool s, boost::shared_ptr sub, double t) + : image (i) + , same (s) + , subtitle (sub) + , time (t) + {} + + boost::shared_ptr image; + bool same; + boost::shared_ptr subtitle; + double time; + }; + + std::list _pending_video; + + struct AudioRecord { + AudioRecord (boost::shared_ptr a, double t) + : audio (a) + , time (t) + {} + + boost::shared_ptr audio; + double time; + }; + + std::list _pending_audio; + + boost::optional _first_input; + boost::shared_ptr _last_image; + boost::shared_ptr _last_subtitle; }; diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc index 773688b34..7fff93c45 100644 --- a/src/lib/video_decoder.cc +++ b/src/lib/video_decoder.cc @@ -27,6 +27,7 @@ #include "i18n.h" +using std::cout; using boost::shared_ptr; using boost::optional; @@ -55,21 +56,6 @@ VideoDecoder::emit_video (shared_ptr image, double t) _last_source_time = t; } -/** Called by subclasses to repeat the last video frame that we - * passed to emit_video(). If emit_video hasn't yet been called, - * we will generate a black frame. - */ -void -VideoDecoder::repeat_last_video (double t) -{ - if (!_last_image) { - _last_image.reset (new SimpleImage (pixel_format(), native_size(), true)); - _last_image->make_black (); - } - - signal_video (_last_image, true, _last_subtitle, t); -} - /** Emit our signal to say that some video data is ready. * @param image Video frame. * @param same true if `image' is the same as the last one we emitted. @@ -81,9 +67,6 @@ VideoDecoder::signal_video (shared_ptr image, bool same, shared_ptr, double); void emit_subtitle (boost::shared_ptr); - void repeat_last_video (double t); /** Subtitle stream to use when decoding */ boost::shared_ptr _subtitle_stream; @@ -81,9 +80,6 @@ private: double _last_source_time; boost::shared_ptr _timed_subtitle; - - boost::shared_ptr _last_image; - boost::shared_ptr _last_subtitle; }; #endif -- cgit v1.2.3 From 422341d1cb6bc8cbb6be76eac239c40cb4061c79 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 6 Mar 2013 00:51:44 +0000 Subject: Revert "Split timed from untimed sinks / sources. Should produce same output, in theory." This reverts commit 18614dda0d53b713ace5ad1df57298d049dba87f. --- src/lib/ab_transcoder.cc | 7 +++---- src/lib/audio_decoder.h | 2 +- src/lib/audio_sink.h | 7 ------- src/lib/audio_source.cc | 6 ------ src/lib/audio_source.h | 12 ----------- src/lib/combiner.cc | 8 ++++---- src/lib/combiner.h | 6 +++--- src/lib/delay_line.cc | 7 +++---- src/lib/delay_line.h | 4 ++-- src/lib/external_audio_decoder.cc | 4 +--- src/lib/ffmpeg_decoder.cc | 8 +++----- src/lib/gain.cc | 2 +- src/lib/gain.h | 2 +- src/lib/imagemagick_decoder.cc | 3 +-- src/lib/matcher.cc | 6 +++--- src/lib/matcher.h | 6 +++--- src/lib/processor.h | 42 +++++++++++++++++++++++++++++++++++++++ src/lib/transcoder.cc | 3 +-- src/lib/video_decoder.cc | 10 +++++----- src/lib/video_decoder.h | 6 +++--- src/lib/video_sink.h | 12 ----------- src/lib/video_source.cc | 6 ------ src/lib/video_source.h | 23 ++------------------- test/test.cc | 6 ++---- 24 files changed, 84 insertions(+), 114 deletions(-) (limited to 'src') diff --git a/src/lib/ab_transcoder.cc b/src/lib/ab_transcoder.cc index 373549b57..4ed5d02ca 100644 --- a/src/lib/ab_transcoder.cc +++ b/src/lib/ab_transcoder.cc @@ -70,15 +70,14 @@ ABTranscoder::ABTranscoder ( _db.video->set_subtitle_stream (_film_a->subtitle_stream ()); _da.audio->set_audio_stream (_film_a->audio_stream ()); - _da.video->Video.connect (bind (&Combiner::process_video, _combiner, _1, _2, _3, _4)); - _db.video->Video.connect (bind (&Combiner::process_video_b, _combiner, _1, _2, _3, _4)); + _da.video->Video.connect (bind (&Combiner::process_video, _combiner, _1, _2, _3)); + _db.video->Video.connect (bind (&Combiner::process_video_b, _combiner, _1, _2, _3)); if (_matcher) { _combiner->connect_video (_matcher); _matcher->connect_video (_encoder); } else { - /* Remove timestamp from the output of the combiner */ - _combiner->Video.connect (bind (&Encoder::process_video, _encoder, _1, _2, _3)); + _combiner->connect_video (_encoder); } if (_matcher && _delay_line) { diff --git a/src/lib/audio_decoder.h b/src/lib/audio_decoder.h index cfe94b528..9bef8e0e7 100644 --- a/src/lib/audio_decoder.h +++ b/src/lib/audio_decoder.h @@ -31,7 +31,7 @@ /** @class AudioDecoder. * @brief Parent class for audio decoders. */ -class AudioDecoder : public TimedAudioSource, public virtual Decoder +class AudioDecoder : public AudioSource, public virtual Decoder { public: AudioDecoder (boost::shared_ptr, DecodeOptions); diff --git a/src/lib/audio_sink.h b/src/lib/audio_sink.h index a222bd6a0..11d578a60 100644 --- a/src/lib/audio_sink.h +++ b/src/lib/audio_sink.h @@ -27,11 +27,4 @@ public: virtual void process_audio (boost::shared_ptr) = 0; }; -class TimedAudioSink -{ -public: - /** Call with some audio data */ - virtual void process_audio (boost::shared_ptr, double t) = 0; -}; - #endif diff --git a/src/lib/audio_source.cc b/src/lib/audio_source.cc index bca3562cf..53b0dda15 100644 --- a/src/lib/audio_source.cc +++ b/src/lib/audio_source.cc @@ -28,9 +28,3 @@ AudioSource::connect_audio (shared_ptr s) { Audio.connect (bind (&AudioSink::process_audio, s, _1)); } - -void -TimedAudioSource::connect_audio (shared_ptr s) -{ - Audio.connect (bind (&TimedAudioSink::process_audio, s, _1, _2)); -} diff --git a/src/lib/audio_source.h b/src/lib/audio_source.h index 3dc998cca..5a1510d3c 100644 --- a/src/lib/audio_source.h +++ b/src/lib/audio_source.h @@ -28,7 +28,6 @@ class AudioBuffers; class AudioSink; -class TimedAudioSink; /** A class that emits audio data */ class AudioSource @@ -40,15 +39,4 @@ public: void connect_audio (boost::shared_ptr); }; - -/** A class that emits audio data with timestamps */ -class TimedAudioSource -{ -public: - /** Emitted when some audio data is ready */ - boost::signals2::signal, double)> Audio; - - void connect_audio (boost::shared_ptr); -}; - #endif diff --git a/src/lib/combiner.cc b/src/lib/combiner.cc index e628f3a84..68aafd2a2 100644 --- a/src/lib/combiner.cc +++ b/src/lib/combiner.cc @@ -23,7 +23,7 @@ using boost::shared_ptr; Combiner::Combiner (Log* log) - : Processor (log) + : VideoProcessor (log) { } @@ -33,7 +33,7 @@ Combiner::Combiner (Log* log) * @param image Frame image. */ void -Combiner::process_video (shared_ptr image, bool, shared_ptr, double) +Combiner::process_video (shared_ptr image, bool, shared_ptr) { _image = image; } @@ -43,7 +43,7 @@ Combiner::process_video (shared_ptr image, bool, shared_ptr, do * @param sub Subtitle (which will be put onto the whole frame) */ void -Combiner::process_video_b (shared_ptr image, bool, shared_ptr sub, double t) +Combiner::process_video_b (shared_ptr image, bool, shared_ptr sub) { /* Copy the right half of this image into our _image */ /* XXX: this should probably be in the Image class */ @@ -62,6 +62,6 @@ Combiner::process_video_b (shared_ptr image, bool, shared_ptr s } } - Video (_image, false, sub, t); + Video (_image, false, sub); _image.reset (); } diff --git a/src/lib/combiner.h b/src/lib/combiner.h index c52c53ed9..7fad1aeae 100644 --- a/src/lib/combiner.h +++ b/src/lib/combiner.h @@ -28,13 +28,13 @@ * one image used for the left half of the screen and the other for * the right. */ -class Combiner : public Processor, public TimedVideoSink, public TimedVideoSource +class Combiner : public VideoProcessor { public: Combiner (Log* log); - void process_video (boost::shared_ptr i, bool, boost::shared_ptr s, double t); - void process_video_b (boost::shared_ptr i, bool, boost::shared_ptr s, double t); + void process_video (boost::shared_ptr i, bool, boost::shared_ptr s); + void process_video_b (boost::shared_ptr i, bool, boost::shared_ptr s); private: /** The image that we are currently working on */ diff --git a/src/lib/delay_line.cc b/src/lib/delay_line.cc index 84785cfc6..4ad172781 100644 --- a/src/lib/delay_line.cc +++ b/src/lib/delay_line.cc @@ -31,7 +31,7 @@ using boost::shared_ptr; * @param frames Delay in frames, +ve to move audio later. */ DelayLine::DelayLine (Log* log, int channels, int frames) - : Processor (log) + : AudioProcessor (log) , _negative_delay_remaining (0) , _frames (frames) { @@ -47,9 +47,8 @@ DelayLine::DelayLine (Log* log, int channels, int frames) } } -/* XXX: can we just get rid of all this and fiddle with the timestamp? */ void -DelayLine::process_audio (shared_ptr data, double t) +DelayLine::process_audio (shared_ptr data) { if (_buffers) { /* We have some buffers, so we are moving the audio later */ @@ -90,5 +89,5 @@ DelayLine::process_audio (shared_ptr data, double t) } } - Audio (data, t); + Audio (data); } diff --git a/src/lib/delay_line.h b/src/lib/delay_line.h index 8c4a3953c..4d6f1313b 100644 --- a/src/lib/delay_line.h +++ b/src/lib/delay_line.h @@ -23,12 +23,12 @@ class AudioBuffers; /** A delay line for audio */ -class DelayLine : public Processor, public TimedAudioSink, public TimedAudioSource +class DelayLine : public AudioProcessor { public: DelayLine (Log* log, int channels, int frames); - void process_audio (boost::shared_ptr, double); + void process_audio (boost::shared_ptr); private: boost::shared_ptr _buffers; diff --git a/src/lib/external_audio_decoder.cc b/src/lib/external_audio_decoder.cc index 50e5852c5..1248b5a3b 100644 --- a/src/lib/external_audio_decoder.cc +++ b/src/lib/external_audio_decoder.cc @@ -115,7 +115,6 @@ ExternalAudioDecoder::pass () sf_count_t const block = _audio_stream->sample_rate() / 2; shared_ptr audio (new AudioBuffers (_audio_stream->channels(), block)); - sf_count_t done = 0; while (frames > 0) { sf_count_t const this_time = min (block, frames); for (size_t i = 0; i < sndfiles.size(); ++i) { @@ -127,8 +126,7 @@ ExternalAudioDecoder::pass () } audio->set_frames (this_time); - Audio (audio, double(done) / _audio_stream->sample_rate()); - done += this_time; + Audio (audio); frames -= this_time; } diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 32c8e224a..ac25844e3 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -640,8 +640,7 @@ FFmpegDecoder::out_with_sync () if (delta > one_frame) { int const extra = rint (delta / one_frame); for (int i = 0; i < extra; ++i) { - /* XXX: timestamp is wrong */ - repeat_last_video (source_pts_seconds); + repeat_last_video (); _film->log()->log ( String::compose ( N_("Extra video frame inserted at %1s; source frame %2, source PTS %3 (at %4 fps)"), @@ -740,8 +739,7 @@ FFmpegDecoder::decode_audio_packet () if (s) { shared_ptr audio (new AudioBuffers (ffa->channels(), s)); audio->make_silent (); - /* XXX: this time stamp is wrong */ - Audio (audio, source_pts_seconds); + Audio (audio); } } @@ -750,7 +748,7 @@ FFmpegDecoder::decode_audio_packet () ); assert (_audio_codec_context->channels == _film->audio_channels()); - Audio (deinterleave_audio (_frame->data, data_size), source_pts_seconds ); + Audio (deinterleave_audio (_frame->data, data_size)); } } diff --git a/src/lib/gain.cc b/src/lib/gain.cc index 35ce27cea..cec3b3c62 100644 --- a/src/lib/gain.cc +++ b/src/lib/gain.cc @@ -23,7 +23,7 @@ using boost::shared_ptr; /** @param gain gain in dB */ Gain::Gain (Log* log, float gain) - : Processor (log) + : AudioProcessor (log) , _gain (gain) { diff --git a/src/lib/gain.h b/src/lib/gain.h index 449473582..716ee9b51 100644 --- a/src/lib/gain.h +++ b/src/lib/gain.h @@ -19,7 +19,7 @@ #include "processor.h" -class Gain : public Processor, public AudioSink, public AudioSource +class Gain : public AudioProcessor { public: Gain (Log* log, float gain); diff --git a/src/lib/imagemagick_decoder.cc b/src/lib/imagemagick_decoder.cc index 38dace6de..5dc0b7b06 100644 --- a/src/lib/imagemagick_decoder.cc +++ b/src/lib/imagemagick_decoder.cc @@ -77,8 +77,7 @@ ImageMagickDecoder::pass () return true; } - /* XXX: timestamp is wrong */ - repeat_last_video (0); + repeat_last_video (); return false; } diff --git a/src/lib/matcher.cc b/src/lib/matcher.cc index 3a513b24e..4cd264338 100644 --- a/src/lib/matcher.cc +++ b/src/lib/matcher.cc @@ -27,7 +27,7 @@ using std::min; using boost::shared_ptr; Matcher::Matcher (Log* log, int sample_rate, float frames_per_second) - : Processor (log) + : AudioVideoProcessor (log) , _sample_rate (sample_rate) , _frames_per_second (frames_per_second) , _video_frames (0) @@ -37,7 +37,7 @@ Matcher::Matcher (Log* log, int sample_rate, float frames_per_second) } void -Matcher::process_video (boost::shared_ptr i, bool same, boost::shared_ptr s, double) +Matcher::process_video (boost::shared_ptr i, bool same, boost::shared_ptr s) { Video (i, same, s); _video_frames++; @@ -47,7 +47,7 @@ Matcher::process_video (boost::shared_ptr i, bool same, boost::shared_ptr } void -Matcher::process_audio (boost::shared_ptr b, double) +Matcher::process_audio (boost::shared_ptr b) { Audio (b); _audio_frames += b->frames (); diff --git a/src/lib/matcher.h b/src/lib/matcher.h index 4a66f4e70..60bb87432 100644 --- a/src/lib/matcher.h +++ b/src/lib/matcher.h @@ -21,12 +21,12 @@ #include "processor.h" #include "ffmpeg_compatibility.h" -class Matcher : public Processor, public TimedVideoSink, public TimedAudioSink, public VideoSource, public AudioSource +class Matcher : public AudioVideoProcessor { public: Matcher (Log* log, int sample_rate, float frames_per_second); - void process_video (boost::shared_ptr i, bool, boost::shared_ptr s, double t); - void process_audio (boost::shared_ptr, double t); + void process_video (boost::shared_ptr i, bool, boost::shared_ptr s); + void process_audio (boost::shared_ptr); void process_end (); private: diff --git a/src/lib/processor.h b/src/lib/processor.h index 863bfdbb5..19d7c4b0c 100644 --- a/src/lib/processor.h +++ b/src/lib/processor.h @@ -53,4 +53,46 @@ protected: Log* _log; ///< log to write to }; +/** @class AudioVideoProcessor + * @brief A processor which handles both video and audio data. + */ +class AudioVideoProcessor : public Processor, public VideoSource, public VideoSink, public AudioSource, public AudioSink +{ +public: + /** Construct an AudioVideoProcessor. + * @param log Log to write to. + */ + AudioVideoProcessor (Log* log) + : Processor (log) + {} +}; + +/** @class AudioProcessor + * @brief A processor which handles just audio data. + */ +class AudioProcessor : public Processor, public AudioSource, public AudioSink +{ +public: + /** Construct an AudioProcessor. + * @param log Log to write to. + */ + AudioProcessor (Log* log) + : Processor (log) + {} +}; + +/** @class VideoProcessor + * @brief A processor which handles just video data. + */ +class VideoProcessor : public Processor, public VideoSource, public VideoSink +{ +public: + /** Construct an VideoProcessor. + * @param log Log to write to. + */ + VideoProcessor (Log* log) + : Processor (log) + {} +}; + #endif diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc index 3beda2b8b..9720ca56a 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -72,8 +72,7 @@ Transcoder::Transcoder (shared_ptr f, DecodeOptions o, Job* j, shared_ptr< _decoders.video->connect_video (_matcher); _matcher->connect_video (_encoder); } else { - /* Discard timestamps here */ - _decoders.video->Video.connect (boost::bind (&Encoder::process_video, _encoder, _1, _2, _3)); + _decoders.video->connect_video (_encoder); } if (_matcher && _delay_line && _decoders.audio) { diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc index 773688b34..891720f6b 100644 --- a/src/lib/video_decoder.cc +++ b/src/lib/video_decoder.cc @@ -51,7 +51,7 @@ VideoDecoder::emit_video (shared_ptr image, double t) sub = _timed_subtitle->subtitle (); } - signal_video (image, false, sub, t); + signal_video (image, false, sub); _last_source_time = t; } @@ -60,14 +60,14 @@ VideoDecoder::emit_video (shared_ptr image, double t) * we will generate a black frame. */ void -VideoDecoder::repeat_last_video (double t) +VideoDecoder::repeat_last_video () { if (!_last_image) { _last_image.reset (new SimpleImage (pixel_format(), native_size(), true)); _last_image->make_black (); } - signal_video (_last_image, true, _last_subtitle, t); + signal_video (_last_image, true, _last_subtitle); } /** Emit our signal to say that some video data is ready. @@ -76,10 +76,10 @@ VideoDecoder::repeat_last_video (double t) * @param sub Subtitle for this frame, or 0. */ void -VideoDecoder::signal_video (shared_ptr image, bool same, shared_ptr sub, double t) +VideoDecoder::signal_video (shared_ptr image, bool same, shared_ptr sub) { TIMING (N_("Decoder emits %1"), _video_frame); - Video (image, same, sub, t); + Video (image, same, sub); ++_video_frame; _last_image = image; diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h index 5e9c60d08..283ab5d88 100644 --- a/src/lib/video_decoder.h +++ b/src/lib/video_decoder.h @@ -24,7 +24,7 @@ #include "stream.h" #include "decoder.h" -class VideoDecoder : public TimedVideoSource, public virtual Decoder +class VideoDecoder : public VideoSource, public virtual Decoder { public: VideoDecoder (boost::shared_ptr, DecodeOptions); @@ -67,7 +67,7 @@ protected: void emit_video (boost::shared_ptr, double); void emit_subtitle (boost::shared_ptr); - void repeat_last_video (double t); + void repeat_last_video (); /** Subtitle stream to use when decoding */ boost::shared_ptr _subtitle_stream; @@ -75,7 +75,7 @@ protected: std::vector > _subtitle_streams; private: - void signal_video (boost::shared_ptr, bool, boost::shared_ptr, double); + void signal_video (boost::shared_ptr, bool, boost::shared_ptr); int _video_frame; double _last_source_time; diff --git a/src/lib/video_sink.h b/src/lib/video_sink.h index 32c7f3b38..7c128cf73 100644 --- a/src/lib/video_sink.h +++ b/src/lib/video_sink.h @@ -37,16 +37,4 @@ public: virtual void process_video (boost::shared_ptr i, bool same, boost::shared_ptr s) = 0; }; -class TimedVideoSink -{ -public: - /** Call with a frame of video. - * @param i Video frame image. - * @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. - * @param t Source timestamp. - */ - virtual void process_video (boost::shared_ptr i, bool same, boost::shared_ptr s, double t) = 0; -}; - #endif diff --git a/src/lib/video_source.cc b/src/lib/video_source.cc index af6f941fd..56742e2b4 100644 --- a/src/lib/video_source.cc +++ b/src/lib/video_source.cc @@ -28,9 +28,3 @@ VideoSource::connect_video (shared_ptr s) { Video.connect (bind (&VideoSink::process_video, s, _1, _2, _3)); } - -void -TimedVideoSource::connect_video (shared_ptr s) -{ - Video.connect (bind (&TimedVideoSink::process_video, s, _1, _2, _3, _4)); -} diff --git a/src/lib/video_source.h b/src/lib/video_source.h index 705b0023a..893629160 100644 --- a/src/lib/video_source.h +++ b/src/lib/video_source.h @@ -29,12 +29,11 @@ #include "util.h" class VideoSink; -class TimedVideoSink; class Subtitle; class Image; -/** @class VideoSource - * @param A class that emits video data without timestamps. +/** @class VideoSink + * @param A class that emits video data. */ class VideoSource { @@ -50,22 +49,4 @@ public: void connect_video (boost::shared_ptr); }; -/** @class TimedVideoSource - * @param A class that emits video data with timestamps. - */ -class TimedVideoSource -{ -public: - - /** Emitted when a video frame is ready. - * First parameter is the video image. - * 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. - * Fourth parameter is the source timestamp of this frame. - */ - boost::signals2::signal, bool, boost::shared_ptr, double)> Video; - - void connect_video (boost::shared_ptr); -}; - #endif diff --git a/test/test.cc b/test/test.cc index b2af8ab22..15c34ca78 100644 --- a/test/test.cc +++ b/test/test.cc @@ -273,8 +273,7 @@ do_positive_delay_line_test (int delay_length, int data_length) } /* This only works because the delay line modifies the parameter */ - /* XXX: timestamp is wrong */ - d.process_audio (data, 0); + d.process_audio (data); returned += data->frames (); for (int j = 0; j < data->frames(); ++j) { @@ -317,8 +316,7 @@ do_negative_delay_line_test (int delay_length, int data_length) } /* This only works because the delay line modifies the parameter */ - /* XXX: timestamp is wrong */ - d.process_audio (data, 0); + d.process_audio (data); returned += data->frames (); for (int j = 0; j < data->frames(); ++j) { -- cgit v1.2.3 From a0fedb33cab65a1be1c49319b7f14319897991f3 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 6 Mar 2013 01:04:23 +0000 Subject: Small simplification. --- src/lib/video_decoder.cc | 15 ++------------- src/lib/video_decoder.h | 2 -- 2 files changed, 2 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc index 7fff93c45..8461b1635 100644 --- a/src/lib/video_decoder.cc +++ b/src/lib/video_decoder.cc @@ -52,21 +52,10 @@ VideoDecoder::emit_video (shared_ptr image, double t) sub = _timed_subtitle->subtitle (); } - signal_video (image, false, sub, t); - _last_source_time = t; -} - -/** Emit our signal to say that some video data is ready. - * @param image Video frame. - * @param same true if `image' is the same as the last one we emitted. - * @param sub Subtitle for this frame, or 0. - */ -void -VideoDecoder::signal_video (shared_ptr image, bool same, shared_ptr sub, double t) -{ - TIMING (N_("Decoder emits %1"), _video_frame); Video (image, same, sub, t); ++_video_frame; + + _last_source_time = t; } /** Set up the current subtitle. This will be put onto frames that diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h index 7d43c9e82..1a02272a5 100644 --- a/src/lib/video_decoder.h +++ b/src/lib/video_decoder.h @@ -74,8 +74,6 @@ protected: std::vector > _subtitle_streams; private: - void signal_video (boost::shared_ptr, bool, boost::shared_ptr, double); - int _video_frame; double _last_source_time; -- cgit v1.2.3 From bb6ceb671f08e0294556036af7ca5f88d1db2fca Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 6 Mar 2013 01:08:31 +0000 Subject: Fix thinko. --- src/lib/matcher.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/matcher.cc b/src/lib/matcher.cc index 70a9b2a85..749acf463 100644 --- a/src/lib/matcher.cc +++ b/src/lib/matcher.cc @@ -143,7 +143,7 @@ Matcher::fix_start () void Matcher::match (double extra_video_needed) { - if (extra_video_needed) { + if (extra_video_needed > 0) { /* Emit black video frames */ -- cgit v1.2.3 From 3f30952afbda7d945998f62fee836afc8bc8a48f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 6 Mar 2013 01:11:01 +0000 Subject: Fix mistake in previous simplification. --- src/lib/video_decoder.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc index 8461b1635..9c0d2bbe3 100644 --- a/src/lib/video_decoder.cc +++ b/src/lib/video_decoder.cc @@ -52,7 +52,7 @@ VideoDecoder::emit_video (shared_ptr image, double t) sub = _timed_subtitle->subtitle (); } - Video (image, same, sub, t); + Video (image, false, sub, t); ++_video_frame; _last_source_time = t; -- cgit v1.2.3 From b3dfeeb7f960b6d3418005351f52c5f6b99e9636 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 6 Mar 2013 11:18:06 +0000 Subject: Tweak rounding. Pass pending video / audio back through so it is treated the same as the first time. --- src/lib/matcher.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/lib/matcher.cc b/src/lib/matcher.cc index 749acf463..2c697157f 100644 --- a/src/lib/matcher.cc +++ b/src/lib/matcher.cc @@ -44,6 +44,8 @@ Matcher::process_video (boost::shared_ptr image, bool same, boost::shared _pixel_format = image->pixel_format (); _size = image->size (); + _log->log(String::compose("Matcher video @ %1 (same=%2)", t, same)); + if (!_first_input) { _first_input = t; } @@ -129,11 +131,11 @@ Matcher::fix_start () match (_pending_video.front().time - _pending_audio.front().time); for (list::iterator i = _pending_video.begin(); i != _pending_video.end(); ++i) { - Video (i->image, i->same, i->subtitle); + process_video (i->image, i->same, i->subtitle, i->time); } for (list::iterator i = _pending_audio.begin(); i != _pending_audio.end(); ++i) { - Audio (i->audio); + process_audio (i->audio, i->time); } _pending_video.clear (); @@ -165,7 +167,7 @@ Matcher::match (double extra_video_needed) /* Emit silence */ - int64_t to_do = rint (-extra_video_needed * _sample_rate); + int64_t to_do = -extra_video_needed * _sample_rate; _log->log (String::compose (N_("Emitted %1 frames of silence"), to_do)); /* Do things in half second blocks as I think there may be limits -- cgit v1.2.3 From da9ab56f39b1d658ccd0e40de2df8e18c9e4cd89 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 6 Mar 2013 14:20:39 +0000 Subject: A little logging. --- src/lib/matcher.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/lib/matcher.cc b/src/lib/matcher.cc index 2c697157f..93531dbc5 100644 --- a/src/lib/matcher.cc +++ b/src/lib/matcher.cc @@ -116,6 +116,9 @@ Matcher::process_end () /* We won't do anything */ return; } + + _log->log (String::compose ("Matcher has seen %1 video frames (which equals %2 audio frames) and %3 audio frames", + _video_frames, video_frames_to_audio_frames (_video_frames, _sample_rate, _frames_per_second), _audio_frames)); match ((double (_audio_frames) / _sample_rate) - (double (_video_frames) / _frames_per_second)); } -- cgit v1.2.3 From be9c85c16c19b6107c33e23eae1cc9405d5203a2 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 6 Mar 2013 14:38:00 +0000 Subject: Drop frames without PTS and only try to fish out leftover frames for codecs with CAP_DELAY. --- src/lib/ffmpeg_decoder.cc | 47 +++++++++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index f801821e9..30972cbf3 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -224,26 +224,32 @@ FFmpegDecoder::pass () av_strerror (r, buf, sizeof(buf)); _film->log()->log (String::compose (N_("error on av_read_frame (%1) (%2)"), buf, r)); } - - /* Get any remaining frames */ - - _packet.data = 0; - _packet.size = 0; - - /* XXX: should we reset _packet.data and size after each *_decode_* call? */ - - int frame_finished; - if (_opt.decode_video) { - while (avcodec_decode_video2 (_video_codec_context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) { - filter_and_emit_video (); + if (_video_codec->capabilities & CODEC_CAP_DELAY) { + + /* Get any remaining frames */ + + _packet.data = 0; + _packet.size = 0; + + /* XXX: should we reset _packet.data and size after each *_decode_* call? */ + + int frame_finished; + + if (_opt.decode_video) { + while (avcodec_decode_video2 (_video_codec_context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) { + filter_and_emit_video (); + } } + + if (_audio_stream && _opt.decode_audio) { + decode_audio_packet (); + } + } else { + _film->log()->log("Codec does not have CAP_DELAY"); } - - if (_audio_stream && _opt.decode_audio) { - decode_audio_packet (); - } - + + return true; } @@ -518,7 +524,12 @@ FFmpegDecoder::filter_and_emit_video () list > images = graph->process (_frame); for (list >::iterator i = images.begin(); i != images.end(); ++i) { - emit_video (*i, av_frame_get_best_effort_timestamp (_frame) * av_q2d (_format_context->streams[_video_stream]->time_base)); + int64_t const bet = av_frame_get_best_effort_timestamp (_frame); + if (bet != AV_NOPTS_VALUE) { + emit_video (*i, bet * av_q2d (_format_context->streams[_video_stream]->time_base)); + } else { + _film->log()->log ("Dropping frame without PTS"); + } } } -- cgit v1.2.3 From bfea14c1655bc4bbadbe3d9e89f4bd2ddf037659 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 6 Mar 2013 22:20:10 +0000 Subject: It appears that it may not be just CAP_DELAY decoders that can produce extra frames at the end. --- src/lib/ffmpeg_decoder.cc | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 30972cbf3..e1834d7f6 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -225,30 +225,24 @@ FFmpegDecoder::pass () _film->log()->log (String::compose (N_("error on av_read_frame (%1) (%2)"), buf, r)); } - if (_video_codec->capabilities & CODEC_CAP_DELAY) { - - /* Get any remaining frames */ - - _packet.data = 0; - _packet.size = 0; - - /* XXX: should we reset _packet.data and size after each *_decode_* call? */ - - int frame_finished; - - if (_opt.decode_video) { - while (avcodec_decode_video2 (_video_codec_context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) { - filter_and_emit_video (); - } - } - - if (_audio_stream && _opt.decode_audio) { - decode_audio_packet (); + /* Get any remaining frames */ + + _packet.data = 0; + _packet.size = 0; + + /* XXX: should we reset _packet.data and size after each *_decode_* call? */ + + int frame_finished; + + if (_opt.decode_video) { + while (avcodec_decode_video2 (_video_codec_context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) { + filter_and_emit_video (); } - } else { - _film->log()->log("Codec does not have CAP_DELAY"); } - + + if (_audio_stream && _opt.decode_audio) { + decode_audio_packet (); + } return true; } -- cgit v1.2.3 From 085d9d4966c32aa1f3661c597b4bc2b47eaefa40 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 6 Mar 2013 22:41:59 +0000 Subject: Catch exception thrown by checking the space on a filesystem using a non-existant file. --- src/lib/job.cc | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/lib/job.cc b/src/lib/job.cc index 8c1612a55..78a7a7577 100644 --- a/src/lib/job.cc +++ b/src/lib/job.cc @@ -69,11 +69,15 @@ Job::run_wrapper () set_state (FINISHED_ERROR); string m = String::compose (_("An error occurred whilst handling the file %1."), boost::filesystem::path (e.filename()).leaf()); - - boost::filesystem::space_info const s = boost::filesystem::space (e.filename()); - if (s.available < pow (1024, 3)) { - m += N_("\n\n"); - m += _("The drive that the film is stored on is low in disc space. Free some more space and try again."); + + try { + boost::filesystem::space_info const s = boost::filesystem::space (e.filename()); + if (s.available < pow (1024, 3)) { + m += N_("\n\n"); + m += _("The drive that the film is stored on is low in disc space. Free some more space and try again."); + } + } catch (...) { + } set_error (e.what(), m); -- cgit v1.2.3 From b0802a7644c12bc039c070367440439f7afe133a Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 6 Mar 2013 22:55:11 +0000 Subject: Hopefully fix up still-image generation. --- src/lib/ffmpeg_decoder.cc | 2 +- src/lib/imagemagick_decoder.cc | 15 +++++---- src/lib/imagemagick_decoder.h | 6 +--- src/lib/matcher.cc | 72 ++++++++++++++++++++---------------------- src/lib/matcher.h | 16 ---------- src/lib/video_decoder.cc | 4 +-- src/lib/video_decoder.h | 2 +- 7 files changed, 47 insertions(+), 70 deletions(-) (limited to 'src') diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index e1834d7f6..2d7092789 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -520,7 +520,7 @@ FFmpegDecoder::filter_and_emit_video () for (list >::iterator i = images.begin(); i != images.end(); ++i) { int64_t const bet = av_frame_get_best_effort_timestamp (_frame); if (bet != AV_NOPTS_VALUE) { - emit_video (*i, bet * av_q2d (_format_context->streams[_video_stream]->time_base)); + emit_video (*i, false, bet * av_q2d (_format_context->streams[_video_stream]->time_base)); } else { _film->log()->log ("Dropping frame without PTS"); } diff --git a/src/lib/imagemagick_decoder.cc b/src/lib/imagemagick_decoder.cc index 119f05792..5ce22c296 100644 --- a/src/lib/imagemagick_decoder.cc +++ b/src/lib/imagemagick_decoder.cc @@ -31,8 +31,6 @@ using std::cout; using boost::shared_ptr; using libdcp::Size; -/* XXX: reads a directory and then ignores it */ - ImageMagickDecoder::ImageMagickDecoder ( boost::shared_ptr f, DecodeOptions o) : Decoder (f, o) @@ -79,8 +77,7 @@ ImageMagickDecoder::pass () return true; } - /* XXX: timestamp */ - emit_video (_image, 0); + emit_video (_image, true, double (video_frame()) / frames_per_second()); return false; } @@ -105,8 +102,7 @@ ImageMagickDecoder::pass () _image = image->crop (_film->crop(), true); - /* XXX: timestamp */ - emit_video (_image, 0); + emit_video (_image, false, double (video_frame()) / frames_per_second()); ++_iter; return false; @@ -134,7 +130,6 @@ ImageMagickDecoder::seek_to_last () bool ImageMagickDecoder::seek (double t) { - /* XXX: frames_per_second == 0 */ int const f = t * frames_per_second(); _iter = _files.begin (); @@ -155,3 +150,9 @@ ImageMagickDecoder::film_changed (Film::Property p) OutputChanged (); } } + +float +ImageMagickDecoder::frames_per_second () const +{ + return _film->source_frame_rate (); +} diff --git a/src/lib/imagemagick_decoder.h b/src/lib/imagemagick_decoder.h index ef550c651..ca8e819d3 100644 --- a/src/lib/imagemagick_decoder.h +++ b/src/lib/imagemagick_decoder.h @@ -28,10 +28,7 @@ class ImageMagickDecoder : public VideoDecoder public: ImageMagickDecoder (boost::shared_ptr, DecodeOptions); - float frames_per_second () const { - /* We don't know */ - return 0; - } + float frames_per_second () const; libdcp::Size native_size () const; @@ -88,5 +85,4 @@ private: std::list::iterator _iter; boost::shared_ptr _image; - }; diff --git a/src/lib/matcher.cc b/src/lib/matcher.cc index 93531dbc5..fbd3e3e76 100644 --- a/src/lib/matcher.cc +++ b/src/lib/matcher.cc @@ -49,37 +49,35 @@ Matcher::process_video (boost::shared_ptr image, bool same, boost::shared if (!_first_input) { _first_input = t; } + + /* Video before audio is fine, since we can make up an arbitrary difference + with audio samples (contrasting with video which is quantised to frames) + */ + + /* Difference between where this video is and where it should be */ + double const delta = t - _first_input.get() - _video_frames / _frames_per_second; + double const one_frame = 1 / _frames_per_second; + + if (delta > one_frame) { + /* Insert frames to make up the difference */ + int const extra = rint (delta / one_frame); + for (int i = 0; i < extra; ++i) { + repeat_last_video (); + _log->log (String::compose ("Extra video frame inserted at %1s", _video_frames / _frames_per_second)); + } + } + + if (delta > -one_frame) { + Video (image, same, sub); + ++_video_frames; + } else { + /* We are omitting a frame to keep things right */ + _log->log (String::compose ("Frame removed at %1s", t)); + } - if (_audio_frames == 0 && _pending_audio.empty ()) { - /* No audio yet; we must postpone this frame until we have some */ - _pending_video.push_back (VideoRecord (image, same, sub, t)); - } else if (!_pending_audio.empty() && _pending_video.empty ()) { + if (!_pending_audio.empty() && _video_frames == 1) { /* First video since we got audio */ - _pending_video.push_back (VideoRecord (image, same, sub, t)); fix_start (); - } else { - /* Normal running */ - - /* Difference between where this video is and where it should be */ - double const delta = t - _first_input.get() - _video_frames / _frames_per_second; - double const one_frame = 1 / _frames_per_second; - - if (delta > one_frame) { - /* Insert frames to make up the difference */ - int const extra = rint (delta / one_frame); - for (int i = 0; i < extra; ++i) { - repeat_last_video (); - _log->log (String::compose ("Extra video frame inserted at %1s", _video_frames / _frames_per_second)); - } - } - - if (delta > -one_frame) { - Video (image, same, sub); - ++_video_frames; - } else { - /* We are omitting a frame to keep things right */ - _log->log (String::compose ("Frame removed at %1s", t)); - } } _last_image = image; @@ -95,10 +93,10 @@ Matcher::process_audio (boost::shared_ptr b, double t) _first_input = t; } - if (_video_frames == 0 && _pending_video.empty ()) { + if (_video_frames == 0) { /* No video yet; we must postpone these data until we have some */ _pending_audio.push_back (AudioRecord (b, t)); - } else if (!_pending_video.empty() && _pending_audio.empty ()) { + } else if (_video_frames > 0 && _pending_audio.empty ()) { /* First audio since we got video */ _pending_audio.push_back (AudioRecord (b, t)); fix_start (); @@ -126,22 +124,20 @@ Matcher::process_end () void Matcher::fix_start () { - assert (!_pending_video.empty ()); assert (!_pending_audio.empty ()); + assert (_first_input); - _log->log (String::compose ("Fixing start; video at %1, audio at %2", _pending_video.front().time, _pending_audio.front().time)); - - match (_pending_video.front().time - _pending_audio.front().time); + _log->log (String::compose ("Fixing start; start at %1, audio at %2", _first_input.get(), _pending_audio.front().time)); - for (list::iterator i = _pending_video.begin(); i != _pending_video.end(); ++i) { - process_video (i->image, i->same, i->subtitle, i->time); - } + /* This will not add any video frames, since the input parameter will always be -ve. + Indeed, it cannot add any, since we've already started adding "real" video. + */ + match (_first_input.get() - _pending_audio.front().time); for (list::iterator i = _pending_audio.begin(); i != _pending_audio.end(); ++i) { process_audio (i->audio, i->time); } - _pending_video.clear (); _pending_audio.clear (); } diff --git a/src/lib/matcher.h b/src/lib/matcher.h index 2f580b589..84ae2f73e 100644 --- a/src/lib/matcher.h +++ b/src/lib/matcher.h @@ -42,22 +42,6 @@ private: boost::optional _size; boost::optional _channels; - struct VideoRecord { - VideoRecord (boost::shared_ptr i, bool s, boost::shared_ptr sub, double t) - : image (i) - , same (s) - , subtitle (sub) - , time (t) - {} - - boost::shared_ptr image; - bool same; - boost::shared_ptr subtitle; - double time; - }; - - std::list _pending_video; - struct AudioRecord { AudioRecord (boost::shared_ptr a, double t) : audio (a) diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc index 9c0d2bbe3..16a076698 100644 --- a/src/lib/video_decoder.cc +++ b/src/lib/video_decoder.cc @@ -45,14 +45,14 @@ VideoDecoder::VideoDecoder (shared_ptr f, DecodeOptions o) * @param t Time of the frame within the source, in seconds. */ void -VideoDecoder::emit_video (shared_ptr image, double t) +VideoDecoder::emit_video (shared_ptr image, bool same, double t) { shared_ptr sub; if (_timed_subtitle && _timed_subtitle->displayed_at (t)) { sub = _timed_subtitle->subtitle (); } - Video (image, false, sub, t); + Video (image, same, sub, t); ++_video_frame; _last_source_time = t; diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h index 1a02272a5..6e4fd48c0 100644 --- a/src/lib/video_decoder.h +++ b/src/lib/video_decoder.h @@ -65,7 +65,7 @@ protected: virtual PixelFormat pixel_format () const = 0; - void emit_video (boost::shared_ptr, double); + void emit_video (boost::shared_ptr, bool, double); void emit_subtitle (boost::shared_ptr); /** Subtitle stream to use when decoding */ -- cgit v1.2.3 From e3ce330c4dc3f59f4e2b942bb6111c308a3d83eb Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 6 Mar 2013 22:56:51 +0000 Subject: Remove believed never-failing checks for audio streams. --- src/lib/transcoder.cc | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc index 3beda2b8b..ae88116a0 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -55,33 +55,22 @@ Transcoder::Transcoder (shared_ptr f, DecodeOptions o, Job* j, shared_ptr< { assert (_encoder); - if (f->audio_stream()) { - shared_ptr st = f->audio_stream(); - _matcher.reset (new Matcher (f->log(), st->sample_rate(), f->source_frame_rate())); - _delay_line.reset (new DelayLine (f->log(), st->channels(), f->audio_delay() * st->sample_rate() / 1000)); - _gain.reset (new Gain (f->log(), f->audio_gain())); - } + shared_ptr st = f->audio_stream(); + _matcher.reset (new Matcher (f->log(), st->sample_rate(), f->source_frame_rate())); + _delay_line.reset (new DelayLine (f->log(), st->channels(), f->audio_delay() * st->sample_rate() / 1000)); + _gain.reset (new Gain (f->log(), f->audio_gain())); /* Set up the decoder to use the film's set streams */ _decoders.video->set_subtitle_stream (f->subtitle_stream ()); - if (_decoders.audio) { - _decoders.audio->set_audio_stream (f->audio_stream ()); - } + _decoders.audio->set_audio_stream (f->audio_stream ()); - if (_matcher) { - _decoders.video->connect_video (_matcher); - _matcher->connect_video (_encoder); - } else { - /* Discard timestamps here */ - _decoders.video->Video.connect (boost::bind (&Encoder::process_video, _encoder, _1, _2, _3)); - } + _decoders.video->connect_video (_matcher); + _matcher->connect_video (_encoder); - if (_matcher && _delay_line && _decoders.audio) { - _decoders.audio->connect_audio (_delay_line); - _delay_line->connect_audio (_matcher); - _matcher->connect_audio (_gain); - _gain->connect_audio (_encoder); - } + _decoders.audio->connect_audio (_delay_line); + _delay_line->connect_audio (_matcher); + _matcher->connect_audio (_gain); + _gain->connect_audio (_encoder); } /** Run the decoder, passing its output to the encoder, until the decoder -- cgit v1.2.3 From 7a9a8229b57139ece3f9848910087310c06169c7 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 6 Mar 2013 23:08:07 +0000 Subject: Try doing delay line by fiddling timestamps. Fix up confusion in A/B transcoder similar to that in standard one. --- src/lib/ab_transcoder.cc | 30 ++++++--------- src/lib/delay_line.cc | 67 ++++++++------------------------- src/lib/delay_line.h | 11 ++---- src/lib/transcoder.cc | 17 +++------ test/test.cc | 98 ------------------------------------------------ 5 files changed, 36 insertions(+), 187 deletions(-) (limited to 'src') diff --git a/src/lib/ab_transcoder.cc b/src/lib/ab_transcoder.cc index 373549b57..3af32f988 100644 --- a/src/lib/ab_transcoder.cc +++ b/src/lib/ab_transcoder.cc @@ -58,12 +58,10 @@ ABTranscoder::ABTranscoder ( _da = decoder_factory (_film_a, o); _db = decoder_factory (_film_b, o); - if (_film_a->audio_stream()) { - shared_ptr st = _film_a->audio_stream(); - _matcher.reset (new Matcher (_film_a->log(), st->sample_rate(), _film_a->source_frame_rate())); - _delay_line.reset (new DelayLine (_film_a->log(), st->channels(), _film_a->audio_delay() * st->sample_rate() / 1000)); - _gain.reset (new Gain (_film_a->log(), _film_a->audio_gain())); - } + shared_ptr st = _film_a->audio_stream(); + _matcher.reset (new Matcher (_film_a->log(), st->sample_rate(), _film_a->source_frame_rate())); + _delay_line.reset (new DelayLine (_film_a->log(), _film_a->audio_delay() / 1000.0f)); + _gain.reset (new Gain (_film_a->log(), _film_a->audio_gain())); /* Set up the decoder to use the film's set streams */ _da.video->set_subtitle_stream (_film_a->subtitle_stream ()); @@ -73,20 +71,14 @@ ABTranscoder::ABTranscoder ( _da.video->Video.connect (bind (&Combiner::process_video, _combiner, _1, _2, _3, _4)); _db.video->Video.connect (bind (&Combiner::process_video_b, _combiner, _1, _2, _3, _4)); - if (_matcher) { - _combiner->connect_video (_matcher); - _matcher->connect_video (_encoder); - } else { - /* Remove timestamp from the output of the combiner */ - _combiner->Video.connect (bind (&Encoder::process_video, _encoder, _1, _2, _3)); - } + _combiner->connect_video (_delay_line); + _delay_line->connect_video (_matcher); + _matcher->connect_video (_encoder); - if (_matcher && _delay_line) { - _da.audio->connect_audio (_delay_line); - _delay_line->connect_audio (_matcher); - _matcher->connect_audio (_gain); - _gain->connect_audio (_encoder); - } + _da.audio->connect_audio (_delay_line); + _delay_line->connect_audio (_matcher); + _matcher->connect_audio (_gain); + _gain->connect_audio (_encoder); } void diff --git a/src/lib/delay_line.cc b/src/lib/delay_line.cc index 84785cfc6..924a1f082 100644 --- a/src/lib/delay_line.cc +++ b/src/lib/delay_line.cc @@ -27,68 +27,31 @@ using std::min; using boost::shared_ptr; -/** @param channels Number of channels of audio. - * @param frames Delay in frames, +ve to move audio later. +/* @param seconds Delay in seconds, +ve to move audio later. */ -DelayLine::DelayLine (Log* log, int channels, int frames) +DelayLine::DelayLine (Log* log, double seconds) : Processor (log) - , _negative_delay_remaining (0) - , _frames (frames) + , _seconds (seconds) { - if (_frames > 0) { - /* We need a buffer to keep some data in */ - _buffers.reset (new AudioBuffers (channels, _frames)); - _buffers->make_silent (); - } else if (_frames < 0) { - /* We can do -ve delays just by chopping off - the start, so no buffer needed. - */ - _negative_delay_remaining = -_frames; - } + } -/* XXX: can we just get rid of all this and fiddle with the timestamp? */ void DelayLine::process_audio (shared_ptr data, double t) { - if (_buffers) { - /* We have some buffers, so we are moving the audio later */ - - /* Copy the input data */ - AudioBuffers input (*data.get ()); - - int to_do = data->frames (); - - /* Write some of our buffer to the output */ - int const from_buffer = min (to_do, _buffers->frames()); - data->copy_from (_buffers.get(), from_buffer, 0, 0); - to_do -= from_buffer; - - /* Write some of the input to the output */ - int const from_input = to_do; - data->copy_from (&input, from_input, 0, from_buffer); - - int const left_in_buffer = _buffers->frames() - from_buffer; - - /* Shuffle our buffer down */ - _buffers->move (from_buffer, 0, left_in_buffer); - - /* Copy remaining input data to our buffer */ - _buffers->copy_from (&input, input.frames() - from_input, from_input, left_in_buffer); - - } else { + if (_seconds > 0) { + t += _seconds; + } - /* Chop the initial data off until _negative_delay_remaining - is zero, then just pass data. - */ + Audio (data, t); +} - int const to_do = min (data->frames(), _negative_delay_remaining); - if (to_do) { - data->move (to_do, 0, data->frames() - to_do); - data->set_frames (data->frames() - to_do); - _negative_delay_remaining -= to_do; - } +void +DelayLine::process_video (boost::shared_ptr image, bool same, boost::shared_ptr sub, double t) +{ + if (_seconds < 0) { + t += _seconds; } - Audio (data, t); + Video (image, same, sub, t); } diff --git a/src/lib/delay_line.h b/src/lib/delay_line.h index 8c4a3953c..a52fb981c 100644 --- a/src/lib/delay_line.h +++ b/src/lib/delay_line.h @@ -20,18 +20,15 @@ #include #include "processor.h" -class AudioBuffers; - /** A delay line for audio */ -class DelayLine : public Processor, public TimedAudioSink, public TimedAudioSource +class DelayLine : public Processor, public TimedAudioSink, public TimedAudioSource, public TimedVideoSink, public TimedVideoSource { public: - DelayLine (Log* log, int channels, int frames); + DelayLine (Log* log, double); + void process_video (boost::shared_ptr, bool, boost::shared_ptr, double); void process_audio (boost::shared_ptr, double); private: - boost::shared_ptr _buffers; - int _negative_delay_remaining; ///< number of frames of negative delay that remain to emit - int _frames; + double _seconds; }; diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc index ae88116a0..8e5e15e7f 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -57,14 +57,15 @@ Transcoder::Transcoder (shared_ptr f, DecodeOptions o, Job* j, shared_ptr< shared_ptr st = f->audio_stream(); _matcher.reset (new Matcher (f->log(), st->sample_rate(), f->source_frame_rate())); - _delay_line.reset (new DelayLine (f->log(), st->channels(), f->audio_delay() * st->sample_rate() / 1000)); + _delay_line.reset (new DelayLine (f->log(), f->audio_delay() / 1000.0f)); _gain.reset (new Gain (f->log(), f->audio_gain())); /* Set up the decoder to use the film's set streams */ _decoders.video->set_subtitle_stream (f->subtitle_stream ()); _decoders.audio->set_audio_stream (f->audio_stream ()); - _decoders.video->connect_video (_matcher); + _decoders.video->connect_video (_delay_line); + _delay_line->connect_video (_matcher); _matcher->connect_video (_encoder); _decoders.audio->connect_audio (_delay_line); @@ -107,14 +108,8 @@ Transcoder::go () throw; } - if (_delay_line) { - _delay_line->process_end (); - } - if (_matcher) { - _matcher->process_end (); - } - if (_gain) { - _gain->process_end (); - } + _delay_line->process_end (); + _matcher->process_end (); + _gain->process_end (); _encoder->process_end (); } diff --git a/test/test.cc b/test/test.cc index b2af8ab22..5e85e0dd5 100644 --- a/test/test.cc +++ b/test/test.cc @@ -28,7 +28,6 @@ #include "job_manager.h" #include "util.h" #include "exceptions.h" -#include "delay_line.h" #include "image.h" #include "log.h" #include "dcp_video_frame.h" @@ -251,103 +250,6 @@ public: void do_log (string) {} }; -void -do_positive_delay_line_test (int delay_length, int data_length) -{ - NullLog log; - - DelayLine d (&log, 6, delay_length); - shared_ptr data (new AudioBuffers (6, data_length)); - - int in = 0; - int out = 0; - int returned = 0; - int zeros = 0; - - for (int i = 0; i < 64; ++i) { - for (int j = 0; j < data_length; ++j) { - for (int c = 0; c < 6; ++c ) { - data->data(c)[j] = in; - ++in; - } - } - - /* This only works because the delay line modifies the parameter */ - /* XXX: timestamp is wrong */ - d.process_audio (data, 0); - returned += data->frames (); - - for (int j = 0; j < data->frames(); ++j) { - if (zeros < delay_length) { - for (int c = 0; c < 6; ++c) { - BOOST_CHECK_EQUAL (data->data(c)[j], 0); - } - ++zeros; - } else { - for (int c = 0; c < 6; ++c) { - BOOST_CHECK_EQUAL (data->data(c)[j], out); - ++out; - } - } - } - } - - BOOST_CHECK_EQUAL (returned, 64 * data_length); -} - -void -do_negative_delay_line_test (int delay_length, int data_length) -{ - NullLog log; - - DelayLine d (&log, 6, delay_length); - shared_ptr data (new AudioBuffers (6, data_length)); - - int in = 0; - int out = -delay_length * 6; - int returned = 0; - - for (int i = 0; i < 256; ++i) { - data->set_frames (data_length); - for (int j = 0; j < data_length; ++j) { - for (int c = 0; c < 6; ++c) { - data->data(c)[j] = in; - ++in; - } - } - - /* This only works because the delay line modifies the parameter */ - /* XXX: timestamp is wrong */ - d.process_audio (data, 0); - returned += data->frames (); - - for (int j = 0; j < data->frames(); ++j) { - for (int c = 0; c < 6; ++c) { - BOOST_CHECK_EQUAL (data->data(c)[j], out); - ++out; - } - } - } - - returned += -delay_length; - BOOST_CHECK_EQUAL (returned, 256 * data_length); -} - -BOOST_AUTO_TEST_CASE (delay_line_test) -{ - do_positive_delay_line_test (64, 128); - do_positive_delay_line_test (128, 64); - do_positive_delay_line_test (3, 512); - do_positive_delay_line_test (512, 3); - - do_positive_delay_line_test (0, 64); - - do_negative_delay_line_test (-64, 128); - do_negative_delay_line_test (-128, 64); - do_negative_delay_line_test (-3, 512); - do_negative_delay_line_test (-512, 3); -} - BOOST_AUTO_TEST_CASE (md5_digest_test) { string const t = md5_digest ("test/md5.test"); -- cgit v1.2.3 From 4de9464d7547954bcc74d4c1337c202dc50f588a Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 6 Mar 2013 23:25:15 +0000 Subject: Hopefully fix thinko. --- src/lib/matcher.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/matcher.cc b/src/lib/matcher.cc index fbd3e3e76..b2bef0269 100644 --- a/src/lib/matcher.cc +++ b/src/lib/matcher.cc @@ -96,7 +96,7 @@ Matcher::process_audio (boost::shared_ptr b, double t) if (_video_frames == 0) { /* No video yet; we must postpone these data until we have some */ _pending_audio.push_back (AudioRecord (b, t)); - } else if (_video_frames > 0 && _pending_audio.empty ()) { + } else if (_video_frames > 0 && _audio_frames == 0) { /* First audio since we got video */ _pending_audio.push_back (AudioRecord (b, t)); fix_start (); -- cgit v1.2.3 From 3994ec6aeb7b1dd07aeac2cd6086f6d0a68352de Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 6 Mar 2013 23:37:59 +0000 Subject: Fix infinite loop. --- src/lib/matcher.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/matcher.cc b/src/lib/matcher.cc index b2bef0269..83a39b6ee 100644 --- a/src/lib/matcher.cc +++ b/src/lib/matcher.cc @@ -96,7 +96,7 @@ Matcher::process_audio (boost::shared_ptr b, double t) if (_video_frames == 0) { /* No video yet; we must postpone these data until we have some */ _pending_audio.push_back (AudioRecord (b, t)); - } else if (_video_frames > 0 && _audio_frames == 0) { + } else if (_video_frames > 0 && _audio_frames == 0 && _pending_audio.empty()) { /* First audio since we got video */ _pending_audio.push_back (AudioRecord (b, t)); fix_start (); -- cgit v1.2.3 From 070e62d79b895c0b1ce31d69594973ced72f699b Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 6 Mar 2013 23:46:04 +0000 Subject: Another attempt to fix up matching. --- src/lib/matcher.cc | 22 +++++++++------------- src/lib/matcher.h | 2 +- 2 files changed, 10 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/lib/matcher.cc b/src/lib/matcher.cc index 83a39b6ee..a751e7297 100644 --- a/src/lib/matcher.cc +++ b/src/lib/matcher.cc @@ -50,6 +50,11 @@ Matcher::process_video (boost::shared_ptr image, bool same, boost::shared _first_input = t; } + if (!_pending_audio.empty() && _video_frames == 0) { + /* First video since we got audio */ + fix_start (t); + } + /* Video before audio is fine, since we can make up an arbitrary difference with audio samples (contrasting with video which is quantised to frames) */ @@ -75,11 +80,6 @@ Matcher::process_video (boost::shared_ptr image, bool same, boost::shared _log->log (String::compose ("Frame removed at %1s", t)); } - if (!_pending_audio.empty() && _video_frames == 1) { - /* First video since we got audio */ - fix_start (); - } - _last_image = image; _last_subtitle = sub; } @@ -99,7 +99,7 @@ Matcher::process_audio (boost::shared_ptr b, double t) } else if (_video_frames > 0 && _audio_frames == 0 && _pending_audio.empty()) { /* First audio since we got video */ _pending_audio.push_back (AudioRecord (b, t)); - fix_start (); + fix_start (_first_input.get ()); } else { /* Normal running. We assume audio time stamps are consecutive */ Audio (b); @@ -122,17 +122,13 @@ Matcher::process_end () } void -Matcher::fix_start () +Matcher::fix_start (double first_video) { assert (!_pending_audio.empty ()); - assert (_first_input); - _log->log (String::compose ("Fixing start; start at %1, audio at %2", _first_input.get(), _pending_audio.front().time)); + _log->log (String::compose ("Fixing start; video at %1, audio at %2", first_video, _pending_audio.front().time)); - /* This will not add any video frames, since the input parameter will always be -ve. - Indeed, it cannot add any, since we've already started adding "real" video. - */ - match (_first_input.get() - _pending_audio.front().time); + match (first_video - _pending_audio.front().time); for (list::iterator i = _pending_audio.begin(); i != _pending_audio.end(); ++i) { process_audio (i->audio, i->time); diff --git a/src/lib/matcher.h b/src/lib/matcher.h index 84ae2f73e..4a387a3f9 100644 --- a/src/lib/matcher.h +++ b/src/lib/matcher.h @@ -30,7 +30,7 @@ public: void process_end (); private: - void fix_start (); + void fix_start (double); void match (double); void repeat_last_video (); -- cgit v1.2.3 From b9fb4a402b411ddf84c10587187e187bcea34a5e Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 7 Mar 2013 10:11:52 +0000 Subject: Another attempt to fix up matching. --- src/lib/matcher.cc | 26 +++++++++++++++++++------- src/lib/matcher.h | 3 +++ 2 files changed, 22 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/lib/matcher.cc b/src/lib/matcher.cc index a751e7297..a74eeabbb 100644 --- a/src/lib/matcher.cc +++ b/src/lib/matcher.cc @@ -34,6 +34,8 @@ Matcher::Matcher (Log* log, int sample_rate, float frames_per_second) , _frames_per_second (frames_per_second) , _video_frames (0) , _audio_frames (0) + , _had_first_video (false) + , _had_first_audio (false) { } @@ -44,17 +46,20 @@ Matcher::process_video (boost::shared_ptr image, bool same, boost::shared _pixel_format = image->pixel_format (); _size = image->size (); - _log->log(String::compose("Matcher video @ %1 (same=%2)", t, same)); + _log->log(String::compose("Matcher video @ %1 [audio=%2, video=%3, pending_audio=%4]", t, _audio_frames, _video_frames, _pending_audio.size())); if (!_first_input) { _first_input = t; } - if (!_pending_audio.empty() && _video_frames == 0) { + bool const this_is_first_video = !_had_first_video; + _had_first_video = true; + + if (this_is_first_video && _had_first_audio) { /* First video since we got audio */ fix_start (t); } - + /* Video before audio is fine, since we can make up an arbitrary difference with audio samples (contrasting with video which is quantised to frames) */ @@ -88,15 +93,20 @@ void Matcher::process_audio (boost::shared_ptr b, double t) { _channels = b->channels (); - + + _log->log (String::compose ("Matcher audio @ %1 [video=%2, audio=%3, pending_audio=%4]", t, _video_frames, _audio_frames, _pending_audio.size())); + if (!_first_input) { _first_input = t; } + + bool const this_is_first_audio = _had_first_audio; + _had_first_audio = true; - if (_video_frames == 0) { + if (!_had_first_video) { /* No video yet; we must postpone these data until we have some */ _pending_audio.push_back (AudioRecord (b, t)); - } else if (_video_frames > 0 && _audio_frames == 0 && _pending_audio.empty()) { + } else if (this_is_first_audio && !_had_first_video) { /* First audio since we got video */ _pending_audio.push_back (AudioRecord (b, t)); fix_start (_first_input.get ()); @@ -140,6 +150,8 @@ Matcher::fix_start (double first_video) void Matcher::match (double extra_video_needed) { + _log->log (String::compose ("Match %1", extra_video_needed)); + if (extra_video_needed > 0) { /* Emit black video frames */ @@ -163,7 +175,7 @@ Matcher::match (double extra_video_needed) /* Emit silence */ int64_t to_do = -extra_video_needed * _sample_rate; - _log->log (String::compose (N_("Emitted %1 frames of silence"), to_do)); + _log->log (String::compose (N_("Emitting %1 frames of silence"), to_do)); /* Do things in half second blocks as I think there may be limits to what FFmpeg (and in particular the resampler) can cope with. diff --git a/src/lib/matcher.h b/src/lib/matcher.h index 4a387a3f9..a7054f540 100644 --- a/src/lib/matcher.h +++ b/src/lib/matcher.h @@ -57,4 +57,7 @@ private: boost::optional _first_input; boost::shared_ptr _last_image; boost::shared_ptr _last_subtitle; + + bool _had_first_video; + bool _had_first_audio; }; -- cgit v1.2.3 From 3881ae48d8f3b945f956a874156857e5e121852e Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 7 Mar 2013 11:25:45 +0000 Subject: Add partial French translation from Olivier (freedcp.net) --- src/lib/po/fr_FR.po | 596 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 596 insertions(+) create mode 100644 src/lib/po/fr_FR.po (limited to 'src') diff --git a/src/lib/po/fr_FR.po b/src/lib/po/fr_FR.po new file mode 100644 index 000000000..4effdf28b --- /dev/null +++ b/src/lib/po/fr_FR.po @@ -0,0 +1,596 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-03-05 13:49+0000\n" +"PO-Revision-Date: 2013-03-07 01:37+0100\n" +"Last-Translator: FreeDCP.net \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: src/lib/transcode_job.cc:90 +msgid "0%" +msgstr "0%" + +#: src/lib/format.cc:75 +msgid "1.19" +msgstr "1.19" + +#: src/lib/format.cc:80 +msgid "1.33" +msgstr "1.33" + +#: src/lib/format.cc:85 +msgid "1.375" +msgstr "1.375" + +#: src/lib/format.cc:100 +msgid "1.66" +msgstr "1.66" + +#: src/lib/format.cc:105 +msgid "1.66 within Flat" +msgstr "1.66 dans Flat" + +#: src/lib/format.cc:115 +msgid "16:9" +msgstr "16:9" + +#: src/lib/format.cc:110 +msgid "16:9 within Flat" +msgstr "16:9 dans Flat" + +#: src/lib/filter.cc:88 +msgid "3D denoiser" +msgstr "3D denoiser" + +#: src/lib/format.cc:90 +msgid "4:3 within Flat" +msgstr "4:3 dans Flat" + +#: src/lib/ab_transcode_job.cc:49 +msgid "A/B transcode %1" +msgstr "A/B transcode %1" + +#: src/lib/format.cc:95 +msgid "Academy" +msgstr "Academy" + +#: src/lib/dcp_content_type.cc:53 +msgid "Advertisement" +msgstr "Advertisement" + +#: src/lib/job.cc:71 +msgid "An error occurred whilst handling the file %1." +msgstr "Une erreure s'est produite durant le traitement du fichier %1." + +#: src/lib/analyse_audio_job.cc:48 +msgid "Analyse audio of %1" +msgstr "Analyse du son de %1" + +#: src/lib/scaler.cc:64 +msgid "Area" +msgstr "Area" + +#: src/lib/scaler.cc:62 +msgid "Bicubic" +msgstr "Bicubic" + +#: src/lib/scaler.cc:69 +msgid "Bilinear" +msgstr "Bilinear" + +#: src/lib/encoder.cc:101 +msgid "Cannot resample audio as libswresample is not present" +msgstr "Ne peux pas re-échantillonner le son car libswresample n'est pas présent." + +#: src/lib/scp_dcp_job.cc:109 +msgid "Copy DCP to TMS" +msgstr "Copier le DCP dans le TMS" + +#: src/lib/scp_dcp_job.cc:128 +msgid "Could not connect to server %1 (%2)" +msgstr "Ne peux pas se connecter au serveur %1 (%2)" + +#: src/lib/scp_dcp_job.cc:150 +msgid "Could not create remote directory %1 (%2)" +msgstr "Ne peux pas créer le dossier distant %1 (%2)" + +#: src/lib/scp_dcp_job.cc:175 +msgid "Could not open %1 to send" +msgstr "Ne peux pas ouvrir %1 pour envoyer" + +#: src/lib/scp_dcp_job.cc:145 +msgid "Could not start SCP session (%1)" +msgstr "Ne peux pas démarrer la session SCP (%1)" + +#: src/lib/scp_dcp_job.cc:187 +msgid "Could not write to remote file (%1)" +msgstr "Ne peux pas ecrire le fichier distant (%1)" + +#: src/lib/filter.cc:77 +msgid "Cubic interpolating deinterlacer" +msgstr "Cubic interpolating deinterlacer" + +#: src/lib/util.cc:965 +msgid "DCP and source have the same rate.\n" +msgstr "Le DCP et la source ont le même taux.\n" + +#: src/lib/util.cc:975 +msgid "DCP will run at %1%% of the source speed." +msgstr "Le DCP va tourner à la vitesse %1%% de la source." + +#: src/lib/util.cc:968 +msgid "DCP will use every other frame of the source.\n" +msgstr "Le DCP utilisera toutes les autres images de la source.\n" + +#: src/lib/filter.cc:68 +#: src/lib/filter.cc:69 +#: src/lib/filter.cc:70 +#: src/lib/filter.cc:71 +#: src/lib/filter.cc:72 +#: src/lib/filter.cc:73 +msgid "De-blocking" +msgstr "De-blocking" + +#: src/lib/filter.cc:75 +#: src/lib/filter.cc:76 +#: src/lib/filter.cc:77 +#: src/lib/filter.cc:78 +#: src/lib/filter.cc:79 +#: src/lib/filter.cc:80 +#: src/lib/filter.cc:81 +#: src/lib/filter.cc:82 +#: src/lib/filter.cc:83 +msgid "De-interlacing" +msgstr "De-interlacing" + +#: src/lib/filter.cc:74 +msgid "Deringing filter" +msgstr "Deringing filter" + +#: src/lib/dolby_cp750.cc:27 +msgid "Dolby CP750" +msgstr "Dolby CP750" + +#: src/lib/util.cc:970 +msgid "Each source frame will be doubled in the DCP.\n" +msgstr "Chaque image source sera doublée dans le DCP.\n" + +#: src/lib/job.cc:287 +msgid "Error (%1)" +msgstr "Erreure (%1)" + +#: src/lib/examine_content_job.cc:55 +msgid "Examine content" +msgstr "Examine le contenu" + +#: src/lib/examine_content_job.cc:58 +msgid "Examine content of %1" +msgstr "Examine le contenu de %1" + +#: src/lib/filter.cc:72 +msgid "Experimental horizontal deblocking filter 1" +msgstr "Experimental horizontal deblocking filter 1" + +#: src/lib/filter.cc:73 +msgid "Experimental vertical deblocking filter 1" +msgstr "Experimental vertical deblocking filter 1" + +#: src/lib/filter.cc:79 +msgid "FFMPEG deinterlacer" +msgstr "FFMPEG deinterlacer" + +#: src/lib/filter.cc:80 +msgid "FIR low-pass deinterlacer" +msgstr "FIR low-pass deinterlacer" + +#: src/lib/scp_dcp_job.cc:138 +msgid "Failed to authenticate with server (%1)" +msgstr "L'authentification avec le serveur (%1) a échouée" + +#: src/lib/scaler.cc:70 +msgid "Fast Bilinear" +msgstr "Fast Bilinear" + +#: src/lib/dcp_content_type.cc:44 +msgid "Feature" +msgstr "Feature" + +#: src/lib/format.cc:120 +msgid "Flat" +msgstr "Flat" + +#: src/lib/format.cc:130 +msgid "Flat without stretch" +msgstr "Flat sans étirement" + +#: src/lib/filter.cc:85 +msgid "Force quantizer" +msgstr "Force quantizer" + +#: src/lib/scaler.cc:65 +msgid "Gaussian" +msgstr "Gaussian" + +#: src/lib/filter.cc:86 +msgid "Gradient debander" +msgstr "Gradient debander" + +#: src/lib/filter.cc:89 +msgid "High quality 3D denoiser" +msgstr "High quality 3D denoiser" + +#: src/lib/filter.cc:68 +msgid "Horizontal deblocking filter" +msgstr "Horizontal deblocking filter" + +#: src/lib/filter.cc:70 +msgid "Horizontal deblocking filter A" +msgstr "Horizontal deblocking filter A" + +#: src/lib/job.cc:87 +#: src/lib/job.cc:96 +msgid "It is not known what caused this error. The best idea is to report the problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" +msgstr "La cause de l'erreure n'est pas connue. La meilleure chose est de reporter le problème à la liste de discution de DCD-o-matic (dvdomatic@carlh.net)" + +#: src/lib/filter.cc:82 +msgid "Kernel deinterlacer" +msgstr "Kernel deinterlacer" + +#: src/lib/scaler.cc:66 +msgid "Lanczos" +msgstr "Lanczos" + +#: src/lib/filter.cc:75 +msgid "Linear blend deinterlacer" +msgstr "Linear blend deinterlacer" + +#: src/lib/filter.cc:76 +msgid "Linear interpolating deinterlacer" +msgstr "Linear interpolating deinterlacer" + +#: src/lib/filter.cc:78 +msgid "Median deinterlacer" +msgstr "Median deinterlacer" + +#: src/lib/filter.cc:74 +#: src/lib/filter.cc:85 +#: src/lib/filter.cc:86 +#: src/lib/filter.cc:87 +#: src/lib/filter.cc:90 +msgid "Misc" +msgstr "Divers" + +#: src/lib/filter.cc:81 +msgid "Motion compensating deinterlacer" +msgstr "Motion compensating deinterlacer" + +#: src/lib/filter.cc:84 +#: src/lib/filter.cc:88 +#: src/lib/filter.cc:89 +#: src/lib/filter.cc:91 +msgid "Noise reduction" +msgstr "Noise reduction" + +#: src/lib/job.cc:285 +msgid "OK (ran for %1)" +msgstr "OK (effectuer durant %1)" + +#: src/lib/filter.cc:91 +msgid "Overcomplete wavelet denoiser" +msgstr "Overcomplete wavelet denoiser" + +#: src/lib/dcp_content_type.cc:51 +msgid "Policy" +msgstr "Policy" + +#: src/lib/dcp_content_type.cc:52 +msgid "Public Service Announcement" +msgstr "Public Service Announcement" + +#: src/lib/dcp_content_type.cc:49 +msgid "Rating" +msgstr "Rating" + +#: src/lib/util.cc:458 +msgid "Rec 709" +msgstr "Rec 709" + +#: src/lib/scp_dcp_job.cc:133 +msgid "SSH error (%1)" +msgstr "Erreure SSH (%1)" + +#: src/lib/format.cc:125 +msgid "Scope" +msgstr "Scope" + +#: src/lib/format.cc:135 +msgid "Scope without stretch" +msgstr "Scope sans étirement" + +#: src/lib/dcp_content_type.cc:45 +msgid "Short" +msgstr "Short" + +#: src/lib/scaler.cc:67 +msgid "Sinc" +msgstr "Sinc" + +#: src/lib/format.cc:76 +msgid "Source scaled to 1.19:1" +msgstr "Source mise à l'échelle en 1.19:1" + +#: src/lib/format.cc:81 +msgid "Source scaled to 1.33:1" +msgstr "Source mise à l'échelle en 1.33:1" + +#: src/lib/format.cc:91 +msgid "Source scaled to 1.33:1 then pillarboxed to Flat" +msgstr "Source mise à l'échelle en 1.33:1 et ensuite \"pillarboxed\" en Flat" + +#: src/lib/format.cc:86 +msgid "Source scaled to 1.375:1" +msgstr "Source mise à l'échelle en 1.375:1" + +#: src/lib/format.cc:96 +msgid "Source scaled to 1.37:1 (Academy ratio)" +msgstr "Source mise à l'échelle en 1.37:1 (Academy ratio)" + +#: src/lib/format.cc:101 +msgid "Source scaled to 1.66:1" +msgstr "Source mise à l'échelle en 1.66:1" + +#: src/lib/format.cc:106 +msgid "Source scaled to 1.66:1 then pillarboxed to Flat" +msgstr "Source mise à l'échelle en 1.66:1 et ensuite \"pillarboxed\" en Flat" + +#: src/lib/format.cc:116 +msgid "Source scaled to 1.78:1" +msgstr "Source mise à l'échelle en 1.78:1" + +#: src/lib/format.cc:111 +msgid "Source scaled to 1.78:1 then pillarboxed to Flat" +msgstr "Source mise à l'échelle en 1.78:1 et ensuite \"pillarboxed\" en Flat" + +#: src/lib/format.cc:121 +msgid "Source scaled to Flat (1.85:1)" +msgstr "Source mise à l'échelle en Flat (1.85:1)" + +#: src/lib/format.cc:126 +msgid "Source scaled to Scope (2.39:1)" +msgstr "Source mise à l'échelle en Scope (2.39:1)" + +#: src/lib/format.cc:131 +msgid "Source scaled to fit Flat preserving its aspect ratio" +msgstr "Source réduite en Flat afin de préserver ses dimensions" + +#: src/lib/format.cc:136 +msgid "Source scaled to fit Scope preserving its aspect ratio" +msgstr "Source réduite en Scope afin de préserver ses dimensions" + +#: src/lib/scaler.cc:68 +msgid "Spline" +msgstr "Spline" + +#: src/lib/dcp_content_type.cc:50 +msgid "Teaser" +msgstr "Teaser" + +#: src/lib/filter.cc:90 +msgid "Telecine filter" +msgstr "Telecine filter" + +#: src/lib/filter.cc:84 +msgid "Temporal noise reducer" +msgstr "Temporal noise reducer" + +#: src/lib/dcp_content_type.cc:47 +msgid "Test" +msgstr "Test" + +#: src/lib/job.cc:76 +msgid "The drive that the film is stored on is low in disc space. Free some more space and try again." +msgstr "Le disque sur lequel le film est stocké a peu d'espace libre. Libérez de la place et essayez à nouveau." + +#: src/lib/dcp_content_type.cc:46 +msgid "Trailer" +msgstr "Trailer" + +#: src/lib/transcode_job.cc:54 +msgid "Transcode %1" +msgstr "Transcode %1" + +#: src/lib/dcp_content_type.cc:48 +msgid "Transitional" +msgstr "Transitional" + +#: src/lib/job.cc:95 +msgid "Unknown error" +msgstr "Erruere inconnue" + +#: src/lib/ffmpeg_decoder.cc:396 +msgid "Unrecognised audio sample format (%1)" +msgstr "Format de son non reconnu (%1)" + +#: src/lib/filter.cc:87 +msgid "Unsharp mask and Gaussian blur" +msgstr "Unsharp mask et Gaussian blur" + +#: src/lib/filter.cc:69 +msgid "Vertical deblocking filter" +msgstr "Vertical deblocking filter" + +#: src/lib/filter.cc:71 +msgid "Vertical deblocking filter A" +msgstr "Vertical deblocking filter A" + +#: src/lib/scp_dcp_job.cc:101 +msgid "Waiting" +msgstr "Attendre" + +#: src/lib/scaler.cc:63 +msgid "X" +msgstr "X" + +#: src/lib/filter.cc:83 +msgid "Yet Another Deinterlacing Filter" +msgstr "Yet Another Deinterlacing Filter" + +#: src/lib/encoder.cc:271 +msgid "adding to queue of %1" +msgstr "ajout à la queue de %1" + +#: src/lib/film.cc:263 +msgid "cannot contain slashes" +msgstr "ne peux pas contenir de slashes" + +#: src/lib/util.cc:499 +msgid "connect timed out" +msgstr "connexion expirée" + +#: src/lib/scp_dcp_job.cc:119 +msgid "connecting" +msgstr "connexion" + +#: src/lib/film.cc:300 +msgid "content" +msgstr "contenu" + +#: src/lib/film.cc:304 +msgid "content type" +msgstr "type de contenu" + +#: src/lib/scp_dcp_job.cc:168 +msgid "copying %1" +msgstr "copie %1" + +#: src/lib/ffmpeg_decoder.cc:191 +msgid "could not find audio decoder" +msgstr "ne trouve pas le decodeur son" + +#: src/lib/ffmpeg_decoder.cc:118 +msgid "could not find stream information" +msgstr "ne peux pas trouver les informations sur le flux" + +#: src/lib/ffmpeg_decoder.cc:210 +msgid "could not find subtitle decoder" +msgstr "ne peux pas trouver de décodeur de sous-titres" + +#: src/lib/ffmpeg_decoder.cc:169 +msgid "could not find video decoder" +msgstr "ne peux pas trouver de decodeur vidéo" + +#: src/lib/external_audio_decoder.cc:72 +msgid "could not open external audio file for reading" +msgstr "ne peux pas ouvrir le fichier audio externe pour lecture" + +#: src/lib/dcp_video_frame.cc:388 +msgid "could not open file for reading" +msgstr "Ne peux pas ouvrir le fichier pour lecture" + +#: src/lib/encoder.cc:137 +#: src/lib/encoder.cc:314 +msgid "could not run sample-rate converter" +msgstr "Ne peux pas lancer sample-rate converter" + +#: src/lib/scp_dcp_job.cc:86 +msgid "could not start SCP session (%1)" +msgstr "ne peux pas lancer de session SCP (%1)" + +#: src/lib/scp_dcp_job.cc:52 +msgid "could not start SSH session" +msgstr "ne peux pas lancer de session SSH" + +#: src/lib/encoder.cc:247 +msgid "decoder sleeps with queue of %1" +msgstr "le decodeur dort en attente de %1" + +#: src/lib/encoder.cc:249 +msgid "decoder wakes with queue of %1" +msgstr "le decodeur se réveille en attente de %1" + +#: src/lib/external_audio_decoder.cc:94 +msgid "external audio files have differing lengths" +msgstr "Les fichiers audio externes ont une durée différente." + +#: src/lib/external_audio_decoder.cc:76 +msgid "external audio files must be mono" +msgstr "Les fichiers audio externes doivent être en mono" + +#: src/lib/film.cc:296 +msgid "format" +msgstr "format" + +#: src/lib/transcode_job.cc:103 +msgid "frames per second" +msgstr "images par secondes" + +#: src/lib/util.cc:115 +msgid "hour" +msgstr "heure" + +#: src/lib/util.cc:112 +#: src/lib/util.cc:117 +msgid "hours" +msgstr "heures" + +#: src/lib/util.cc:122 +msgid "minute" +msgstr "minute" + +#: src/lib/util.cc:124 +msgid "minutes" +msgstr "minutes" + +#: src/lib/util.cc:642 +msgid "missing key %1 in key-value set" +msgstr "missing key %1 in key-value set" + +#: src/lib/subtitle.cc:52 +msgid "multi-part subtitles not yet supported" +msgstr "sous-titres en plusieurs parites pas encore supportés" + +#: src/lib/film.cc:263 +#: src/lib/film.cc:308 +msgid "name" +msgstr "nom" + +#: src/lib/imagemagick_decoder.cc:60 +msgid "no still image files found" +msgstr "pas d'image fixe trouvée" + +#: src/lib/subtitle.cc:58 +msgid "non-bitmap subtitles not yet supported" +msgstr "Sous-titres non-bitmap non supportés actuellement" + +#. / TRANSLATORS: remaining here follows an amount of time that is remaining +#. / on an operation. +#: src/lib/job.cc:282 +msgid "remaining" +msgstr "restant" + +#: src/lib/util.cc:456 +msgid "sRGB" +msgstr "sRGB" + +#: src/lib/util.cc:127 +msgid "seconds" +msgstr "secondes" + +#: src/lib/film.cc:274 +msgid "still" +msgstr "encore" + +#: src/lib/film.cc:274 +msgid "video" +msgstr "vidéo" + -- cgit v1.2.3 From 12e7eb5824624f38a7385db42ec3336147b039d5 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 7 Mar 2013 13:08:58 +0000 Subject: Add basic translator info. --- src/tools/dvdomatic.cc | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index f5d9bdf18..8cbd85270 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -407,12 +407,18 @@ private: } info.SetDescription (_("Free, open-source DCP generation from almost anything.")); info.SetCopyright (_("(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen")); + wxArrayString authors; authors.Add (wxT ("Carl Hetherington")); authors.Add (wxT ("Terrence Meiczinger")); authors.Add (wxT ("Paul Davis")); authors.Add (wxT ("Ole Laursen")); info.SetDevelopers (authors); + + wxArrayString translators; + translators.Add (wxT ("Olivier (freedcp.net")); + info.SetTranslators (translators); + info.SetWebSite (wxT ("http://carlh.net/software/dvdomatic")); wxAboutBox (info); } -- cgit v1.2.3 From 8b5b0e26e86b2916a8bfff193e71865fb5396b55 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 7 Mar 2013 22:08:01 +0000 Subject: Add another bit of Olivier's translation. --- src/tools/po/fr_FR.po | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 src/tools/po/fr_FR.po (limited to 'src') diff --git a/src/tools/po/fr_FR.po b/src/tools/po/fr_FR.po new file mode 100644 index 000000000..13fdb5a77 --- /dev/null +++ b/src/tools/po/fr_FR.po @@ -0,0 +1,114 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-03-05 13:49+0000\n" +"PO-Revision-Date: 2013-03-07 01:38+0100\n" +"Last-Translator: FreeDCP.net \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: src/tools/dvdomatic.cc:177 +msgid "&Analyse audio" +msgstr "&Analyer le son" + +#: src/tools/dvdomatic.cc:183 +msgid "&Edit" +msgstr "&Edition" + +#: src/tools/dvdomatic.cc:182 +msgid "&File" +msgstr "&Fichier" + +#: src/tools/dvdomatic.cc:185 +msgid "&Help" +msgstr "&Aide" + +#: src/tools/dvdomatic.cc:184 +msgid "&Jobs" +msgstr "&Travaux" + +#: src/tools/dvdomatic.cc:173 +msgid "&Make DCP" +msgstr "&Creer le DCP" + +#: src/tools/dvdomatic.cc:161 +msgid "&Open..." +msgstr "&Ouvrir" + +#: src/tools/dvdomatic.cc:170 +msgid "&Preferences..." +msgstr "&Préférences..." + +#: src/tools/dvdomatic.cc:165 +msgid "&Properties..." +msgstr "&Propriétés..." + +#: src/tools/dvdomatic.cc:167 +msgid "&Quit" +msgstr "&Quitter" + +#: src/tools/dvdomatic.cc:163 +msgid "&Save" +msgstr "&Sauver" + +#: src/tools/dvdomatic.cc:174 +msgid "&Send DCP to TMS" +msgstr "&Envoyer le DCP dans le TMS" + +#: src/tools/dvdomatic.cc:409 +msgid "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" +msgstr "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" + +#: src/tools/dvdomatic.cc:180 +msgid "About" +msgstr "&A Propos" + +#: src/tools/dvdomatic.cc:482 +msgid "Could not load film %1 (%2)" +msgstr "Ne peux pas charger le film %1 (%2)" + +#: src/tools/dvdomatic.cc:331 +#, c-format +msgid "Could not open film at %s (%s)" +msgstr "Ne peux pas ouvrir le film à %s (%s)" + +#: src/tools/dvdomatic.cc:287 +#: src/tools/dvdomatic.cc:402 +#: src/tools/dvdomatic.cc:486 +msgid "DVD-o-matic" +msgstr "DVD-o-matic" + +#: src/tools/dvdomatic.cc:75 +msgid "Film changed" +msgstr "Film changé" + +#: src/tools/dvdomatic.cc:408 +msgid "Free, open-source DCP generation from almost anything." +msgstr "Outil libre et open-source de génération de DCP pour presque tous les formats." + +#: src/tools/dvdomatic.cc:160 +msgid "New..." +msgstr "Nouveau..." + +#: src/tools/dvdomatic.cc:175 +msgid "S&how DCP" +msgstr "Monter le DCP" + +#: src/tools/dvdomatic.cc:319 +msgid "Select film to open" +msgstr "Séléctionner le film à ouvrir" + +#: src/tools/dvdomatic.cc:303 +#, c-format +msgid "The directory %s already exists." +msgstr "Le dossier %s existe déjà." + -- cgit v1.2.3 From fda4b7ffbc70e63061c741a90dfdc81602764610 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 7 Mar 2013 22:10:16 +0000 Subject: Missing bracket. --- src/tools/dvdomatic.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 8cbd85270..741498c47 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -416,7 +416,7 @@ private: info.SetDevelopers (authors); wxArrayString translators; - translators.Add (wxT ("Olivier (freedcp.net")); + translators.Add (wxT ("Olivier (freedcp.net)")); info.SetTranslators (translators); info.SetWebSite (wxT ("http://carlh.net/software/dvdomatic")); -- cgit v1.2.3 From 5f3d6026a68118666988b997c7ced189b93fabb4 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 7 Mar 2013 23:48:31 +0000 Subject: Non-exposed but working language config option. --- src/lib/config.cc | 16 +++++++++++++--- src/lib/config.h | 9 +++++++++ src/tools/dvdomatic.cc | 5 +++++ 3 files changed, 27 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/lib/config.cc b/src/lib/config.cc index f5273b875..ad132437a 100644 --- a/src/lib/config.cc +++ b/src/lib/config.cc @@ -94,6 +94,8 @@ Config::Config () _tms_password = v; } else if (k == N_("sound_processor")) { _sound_processor = SoundProcessor::from_id (v); + } else if (k == "language") { + _language = v; } _default_dci_metadata.read (k, v); @@ -128,8 +130,11 @@ Config::write () const ofstream f (file().c_str ()); f << N_("num_local_encoding_threads ") << _num_local_encoding_threads << N_("\n") << N_("default_directory ") << _default_directory << N_("\n") - << N_("server_port ") << _server_port << N_("\n") - << N_("reference_scaler ") << _reference_scaler->id () << N_("\n"); + << N_("server_port ") << _server_port << N_("\n"); + + if (_reference_scaler) { + f << "reference_scaler " << _reference_scaler->id () << "\n"; + } for (vector::const_iterator i = _reference_filters.begin(); i != _reference_filters.end(); ++i) { f << N_("reference_filter ") << (*i)->id () << N_("\n"); @@ -143,7 +148,12 @@ Config::write () const f << N_("tms_path ") << _tms_path << N_("\n"); f << N_("tms_user ") << _tms_user << N_("\n"); f << N_("tms_password ") << _tms_password << N_("\n"); - f << N_("sound_processor ") << _sound_processor->id () << N_("\n"); + if (_sound_processor) { + f << "sound_processor " << _sound_processor->id () << "\n"; + } + if (_language) { + f << "language " << _language.get() << "\n"; + } _default_dci_metadata.write (f); } diff --git a/src/lib/config.h b/src/lib/config.h index fed297ad0..0e9c4a60a 100644 --- a/src/lib/config.h +++ b/src/lib/config.h @@ -103,6 +103,10 @@ public: return _default_dci_metadata; } + boost::optional language () const { + return _language; + } + /** @param n New number of local encoding threads */ void set_num_local_encoding_threads (int n) { _num_local_encoding_threads = n; @@ -157,6 +161,10 @@ public: void set_default_dci_metadata (DCIMetadata d) { _default_dci_metadata = d; } + + void set_language (std::string l) { + _language = l; + } void write () const; @@ -192,6 +200,7 @@ private: std::list _allowed_dcp_frame_rates; /** Default DCI metadata for newly-created Films */ DCIMetadata _default_dci_metadata; + boost::optional _language; /** Singleton instance, or 0 */ static Config* _instance; diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 741498c47..d08975061 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -444,6 +444,11 @@ void setup_i18n () { int language = wxLANGUAGE_DEFAULT; + + if (Config::instance()->language()) { + wxLanguageInfo const * li = wxLocale::FindLanguageInfo (std_to_wx (Config::instance()->language().get())); + language = li->Language; + } if (wxLocale::IsAvailable (language)) { locale = new wxLocale (language, wxLOCALE_LOAD_DEFAULT); -- cgit v1.2.3 From df499ab4fd81b3cf4686f2e97fd4c9cd339dfdff Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 8 Mar 2013 00:24:51 +0000 Subject: More Windows i18n tinkering. --- src/tools/dvdomatic.cc | 3 +++ windows/installer.nsi.32.in | 10 +++++----- windows/installer.nsi.64.in | 10 +++++----- 3 files changed, 13 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index d08975061..4874e6ef8 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -456,6 +456,9 @@ setup_i18n () #ifdef __WXGTK__ locale->AddCatalogLookupPathPrefix (wxT (LOCALE_PREFIX "/locale")); #endif +#ifdef __WXMSW__ + locale->AddCatalogLookupPathPrefix (wxT ("../locale")); +#endif locale->AddCatalog (wxT ("libdvdomatic-wx")); locale->AddCatalog (wxT ("dvdomatic")); diff --git a/windows/installer.nsi.32.in b/windows/installer.nsi.32.in index 0a993d6bf..c90c97e71 100644 --- a/windows/installer.nsi.32.in +++ b/windows/installer.nsi.32.in @@ -86,11 +86,6 @@ File "%binaries%/src/tools/dvdomatic.exe" File "%binaries%/src/tools/servomatic_cli.exe" File "%binaries%/src/tools/servomatic_gui.exe" -SetOutPath "$INSTDIR\locale\fr_FR" - -File "%binaries%/src/tools/mo/fr_FR/dvdomatic.mo" -File "%binaries%/src/lib/mo/fr_FR/libdvdomatic.mo" - # I don't know why, but sometimes it seems that # delegates.xml must be in with the binaries, and # sometimes in the $PROFILE. Meh. @@ -98,6 +93,11 @@ File "%deps%/etc/ImageMagick/delegates.xml" SetOutPath "$PROFILE\.magick" File "%deps%/etc/ImageMagick/delegates.xml" +SetOutPath "$INSTDIR\locale\fr_FR" + +File "%binaries%/src/tools/mo/fr_FR/dvdomatic.mo" +File "%binaries%/src/lib/mo/fr_FR/libdvdomatic.mo" + CreateShortCut "$DESKTOP\DVD-o-matic.lnk" "$INSTDIR\bin\dvdomatic.exe" "" CreateShortCut "$DESKTOP\DVD-o-matic encode server.lnk" "$INSTDIR\bin\servomatic_gui.exe" "" diff --git a/windows/installer.nsi.64.in b/windows/installer.nsi.64.in index 33e3c7fe1..6f7bc5830 100644 --- a/windows/installer.nsi.64.in +++ b/windows/installer.nsi.64.in @@ -96,11 +96,6 @@ File "%binaries%/src/tools/dvdomatic.exe" File "%binaries%/src/tools/servomatic_cli.exe" File "%binaries%/src/tools/servomatic_gui.exe" -SetOutPath "$INSTDIR\locale\fr_FR" - -File "%binaries%/src/tools/mo/fr_FR/dvdomatic.mo" -File "%binaries%/src/lib/mo/fr_FR/libdvdomatic.mo" - # I don't know why, but sometimes it seems that # delegates.xml must be in with the binaries, and # sometimes in the $PROFILE. Meh. @@ -108,6 +103,11 @@ File "%deps%/etc/ImageMagick/delegates.xml" SetOutPath "$PROFILE\.magick" File "%deps%/etc/ImageMagick/delegates.xml" +SetOutPath "$INSTDIR\locale\fr_FR" + +File "%binaries%/src/tools/mo/fr_FR/dvdomatic.mo" +File "%binaries%/src/lib/mo/fr_FR/libdvdomatic.mo" + CreateShortCut "$DESKTOP\DVD-o-matic.lnk" "$INSTDIR\bin\dvdomatic.exe" "" CreateShortCut "$DESKTOP\DVD-o-matic encode server.lnk" "$INSTDIR\bin\servomatic_gui.exe" "" -- cgit v1.2.3 From 1895cfd9642f53dd4ea83e53a655f93c8a65b37e Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 8 Mar 2013 11:03:42 +0000 Subject: Fix windows i18n file install path. --- src/tools/dvdomatic.cc | 3 --- windows/installer.nsi.32.in | 2 +- windows/installer.nsi.64.in | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 4874e6ef8..d08975061 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -456,9 +456,6 @@ setup_i18n () #ifdef __WXGTK__ locale->AddCatalogLookupPathPrefix (wxT (LOCALE_PREFIX "/locale")); #endif -#ifdef __WXMSW__ - locale->AddCatalogLookupPathPrefix (wxT ("../locale")); -#endif locale->AddCatalog (wxT ("libdvdomatic-wx")); locale->AddCatalog (wxT ("dvdomatic")); diff --git a/windows/installer.nsi.32.in b/windows/installer.nsi.32.in index c90c97e71..5383907d5 100644 --- a/windows/installer.nsi.32.in +++ b/windows/installer.nsi.32.in @@ -93,7 +93,7 @@ File "%deps%/etc/ImageMagick/delegates.xml" SetOutPath "$PROFILE\.magick" File "%deps%/etc/ImageMagick/delegates.xml" -SetOutPath "$INSTDIR\locale\fr_FR" +SetOutPath "$INSTDIR\bin\fr_FR" File "%binaries%/src/tools/mo/fr_FR/dvdomatic.mo" File "%binaries%/src/lib/mo/fr_FR/libdvdomatic.mo" diff --git a/windows/installer.nsi.64.in b/windows/installer.nsi.64.in index 6f7bc5830..5b3f48546 100644 --- a/windows/installer.nsi.64.in +++ b/windows/installer.nsi.64.in @@ -103,7 +103,7 @@ File "%deps%/etc/ImageMagick/delegates.xml" SetOutPath "$PROFILE\.magick" File "%deps%/etc/ImageMagick/delegates.xml" -SetOutPath "$INSTDIR\locale\fr_FR" +SetOutPath "$INSTDIR\bin\fr_FR" File "%binaries%/src/tools/mo/fr_FR/dvdomatic.mo" File "%binaries%/src/lib/mo/fr_FR/libdvdomatic.mo" -- cgit v1.2.3 From a9172427858ec747ed5ff6ff4c2ab6eba1613135 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 8 Mar 2013 20:04:05 +0000 Subject: Disable show audio button when there is no audio (#73). --- src/lib/film.cc | 18 ++++++++++++++++++ src/lib/film.h | 2 +- src/wx/film_editor.cc | 12 ++++++++++++ src/wx/film_editor.h | 1 + 4 files changed, 32 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/film.cc b/src/lib/film.cc index 8f545952b..20e08c037 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -1434,3 +1434,21 @@ Film::have_dcp () const return true; } + +bool +Film::has_audio () const +{ + if (use_content_audio()) { + return audio_stream(); + } + + vector const e = external_audio (); + for (vector::const_iterator i = e.begin(); i != e.end(); ++i) { + if (!i->empty ()) { + return true; + } + } + + return false; +} + diff --git a/src/lib/film.h b/src/lib/film.h index 9921acbb4..88f6fbcd7 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -327,7 +327,7 @@ public: } boost::shared_ptr audio_stream () const; - + bool has_audio () const; /* SET */ diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index b9a4012e3..dcd18c97f 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -617,6 +617,7 @@ FilmEditor::film_changed (Film::Property p) setup_formats (); setup_subtitle_control_sensitivity (); setup_streams (); + setup_show_audio_sensitivity (); break; case Film::TRUST_CONTENT_HEADER: checked_set (_trust_content_header, _film->trust_content_header ()); @@ -627,6 +628,7 @@ FilmEditor::film_changed (Film::Property p) break; case Film::CONTENT_AUDIO_STREAMS: setup_streams (); + setup_show_audio_sensitivity (); break; case Film::FORMAT: { @@ -754,6 +756,7 @@ FilmEditor::film_changed (Film::Property p) setup_dcp_name (); setup_audio_details (); setup_audio_control_sensitivity (); + setup_show_audio_sensitivity (); break; case Film::USE_CONTENT_AUDIO: checked_set (_use_content_audio, _film->use_content_audio()); @@ -761,6 +764,7 @@ FilmEditor::film_changed (Film::Property p) setup_dcp_name (); setup_audio_details (); setup_audio_control_sensitivity (); + setup_show_audio_sensitivity (); break; case Film::SUBTITLE_STREAM: if (_film->subtitle_stream()) { @@ -774,6 +778,7 @@ FilmEditor::film_changed (Film::Property p) checked_set (_external_audio[i], a[i]); } setup_audio_details (); + setup_show_audio_sensitivity (); break; } case Film::DCP_FRAME_RATE: @@ -915,6 +920,7 @@ FilmEditor::set_things_sensitive (bool s) setup_subtitle_control_sensitivity (); setup_audio_control_sensitivity (); + setup_show_audio_sensitivity (); } /** Called when the `Edit filters' button has been clicked */ @@ -1289,3 +1295,9 @@ FilmEditor::best_dcp_frame_rate_clicked (wxCommandEvent &) _film->set_dcp_frame_rate (best_dcp_frame_rate (_film->source_frame_rate ())); } + +void +FilmEditor::setup_show_audio_sensitivity () +{ + _show_audio->Enable (_film && _film->has_audio ()); +} diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index 29b453b8b..e5b619886 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -98,6 +98,7 @@ private: void setup_streams (); void setup_audio_details (); void setup_dcp_name (); + void setup_show_audio_sensitivity (); wxControl* video_control (wxControl *); wxControl* still_control (wxControl *); -- cgit v1.2.3 From 6ab3bf8add89cf16fd9d7f644527a2ca8207e83e Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 8 Mar 2013 20:11:32 +0000 Subject: Disable content audio selector if there is none (#41). --- src/wx/film_editor.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index dcd18c97f..82c8a76a8 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -1129,7 +1129,7 @@ FilmEditor::setup_subtitle_control_sensitivity () void FilmEditor::setup_audio_control_sensitivity () { - _use_content_audio->Enable (_generally_sensitive); + _use_content_audio->Enable (_generally_sensitive && _film && !_film->content_audio_streams().empty()); _use_external_audio->Enable (_generally_sensitive); bool const source = _generally_sensitive && _use_content_audio->GetValue(); @@ -1224,7 +1224,7 @@ FilmEditor::subtitle_stream_changed (wxCommandEvent &) void FilmEditor::setup_audio_details () { - if (!_film->audio_stream()) { + if (!_film->content_audio_stream()) { _audio->SetLabel (wxT ("")); } else { stringstream s; -- cgit v1.2.3 From bb95f333f15ace7c032bb5b5761b512b6fe2e84e Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 8 Mar 2013 21:03:28 +0000 Subject: Numerous fixes to A/B mode so that at least it doesn't crash (#72). --- src/lib/ab_transcoder.cc | 17 +++++++++++++---- src/lib/combiner.cc | 2 +- src/lib/combiner.h | 2 +- src/lib/dcp_video_frame.cc | 2 +- src/lib/dcp_video_frame.h | 4 ++-- src/lib/delay_line.cc | 2 +- src/lib/delay_line.h | 2 +- src/lib/film.cc | 9 +++++---- src/lib/film.h | 4 ++-- src/lib/gain.cc | 2 +- src/lib/gain.h | 2 +- src/lib/matcher.cc | 2 +- src/lib/matcher.h | 2 +- src/lib/processor.h | 10 +++++----- src/lib/server.cc | 2 +- src/lib/server.h | 4 ++-- src/lib/transcoder.cc | 1 - src/tools/dvdomatic.cc | 10 +++++++--- src/tools/servomatic_cli.cc | 9 ++++++--- src/tools/servomatic_gui.cc | 13 ++++++++----- src/tools/servomatictest.cc | 6 +++--- test/test.cc | 14 +++++++------- 22 files changed, 70 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/src/lib/ab_transcoder.cc b/src/lib/ab_transcoder.cc index 4ed5d02ca..3a1cd83d7 100644 --- a/src/lib/ab_transcoder.cc +++ b/src/lib/ab_transcoder.cc @@ -40,6 +40,7 @@ using std::string; using boost::shared_ptr; +using boost::dynamic_pointer_cast; /** @param a Film to use for the left half of the screen. * @param b Film to use for the right half of the screen. @@ -54,6 +55,7 @@ ABTranscoder::ABTranscoder ( , _film_b (b) , _job (j) , _encoder (e) + , _combiner (new Combiner (a->log())) { _da = decoder_factory (_film_a, o); _db = decoder_factory (_film_b, o); @@ -92,17 +94,24 @@ void ABTranscoder::go () { _encoder->process_begin (); + + bool done[3] = { false, false, false }; while (1) { - bool const va = _da.video->pass (); - bool const vb = _db.video->pass (); - bool const a = _da.audio->pass (); + done[0] = _da.video->pass (); + done[1] = _db.video->pass (); + + if (!done[2] && _da.audio && dynamic_pointer_cast (_da.audio) != dynamic_pointer_cast (_da.video)) { + done[2] = _da.audio->pass (); + } else { + done[2] = true; + } if (_job) { _da.video->set_progress (_job); } - if (va && vb && a) { + if (done[0] && done[1] && done[2]) { break; } } diff --git a/src/lib/combiner.cc b/src/lib/combiner.cc index 68aafd2a2..12ce4a96e 100644 --- a/src/lib/combiner.cc +++ b/src/lib/combiner.cc @@ -22,7 +22,7 @@ using boost::shared_ptr; -Combiner::Combiner (Log* log) +Combiner::Combiner (shared_ptr log) : VideoProcessor (log) { diff --git a/src/lib/combiner.h b/src/lib/combiner.h index 7fad1aeae..68026eaff 100644 --- a/src/lib/combiner.h +++ b/src/lib/combiner.h @@ -31,7 +31,7 @@ class Combiner : public VideoProcessor { public: - Combiner (Log* log); + Combiner (boost::shared_ptr log); void process_video (boost::shared_ptr i, bool, boost::shared_ptr s); void process_video_b (boost::shared_ptr i, bool, boost::shared_ptr s); diff --git a/src/lib/dcp_video_frame.cc b/src/lib/dcp_video_frame.cc index 67617c63c..d735122b5 100644 --- a/src/lib/dcp_video_frame.cc +++ b/src/lib/dcp_video_frame.cc @@ -80,7 +80,7 @@ using libdcp::Size; DCPVideoFrame::DCPVideoFrame ( shared_ptr yuv, shared_ptr sub, Size out, int p, int subtitle_offset, float subtitle_scale, - Scaler const * s, int f, int dcp_fps, string pp, int clut, int bw, Log* l + Scaler const * s, int f, int dcp_fps, string pp, int clut, int bw, shared_ptr l ) : _input (yuv) , _subtitle (sub) diff --git a/src/lib/dcp_video_frame.h b/src/lib/dcp_video_frame.h index 6794765ac..4ceb07d26 100644 --- a/src/lib/dcp_video_frame.h +++ b/src/lib/dcp_video_frame.h @@ -107,7 +107,7 @@ class DCPVideoFrame public: DCPVideoFrame ( boost::shared_ptr, boost::shared_ptr, libdcp::Size, - int, int, float, Scaler const *, int, int, std::string, int, int, Log * + int, int, float, Scaler const *, int, int, std::string, int, int, boost::shared_ptr ); virtual ~DCPVideoFrame (); @@ -135,7 +135,7 @@ private: int _colour_lut; ///< Colour look-up table to use int _j2k_bandwidth; ///< J2K bandwidth to use - Log* _log; ///< log + boost::shared_ptr _log; ///< log opj_image_cmptparm_t _cmptparm[3]; ///< libopenjpeg's opj_image_cmptparm_t opj_image* _image; ///< libopenjpeg's image container diff --git a/src/lib/delay_line.cc b/src/lib/delay_line.cc index 4ad172781..53da9a412 100644 --- a/src/lib/delay_line.cc +++ b/src/lib/delay_line.cc @@ -30,7 +30,7 @@ using boost::shared_ptr; /** @param channels Number of channels of audio. * @param frames Delay in frames, +ve to move audio later. */ -DelayLine::DelayLine (Log* log, int channels, int frames) +DelayLine::DelayLine (shared_ptr log, int channels, int frames) : AudioProcessor (log) , _negative_delay_remaining (0) , _frames (frames) diff --git a/src/lib/delay_line.h b/src/lib/delay_line.h index 4d6f1313b..c51784f35 100644 --- a/src/lib/delay_line.h +++ b/src/lib/delay_line.h @@ -26,7 +26,7 @@ class AudioBuffers; class DelayLine : public AudioProcessor { public: - DelayLine (Log* log, int channels, int frames); + DelayLine (boost::shared_ptr log, int channels, int frames); void process_audio (boost::shared_ptr); diff --git a/src/lib/film.cc b/src/lib/film.cc index 20e08c037..8028f40ef 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -144,12 +144,13 @@ Film::Film (string d, bool must_exist) read_metadata (); } - _log = new FileLog (file ("log")); + _log.reset (new FileLog (file ("log"))); } Film::Film (Film const & o) : boost::enable_shared_from_this (o) - , _log (0) + /* note: the copied film shares the original's log */ + , _log (o._log) , _directory (o._directory) , _name (o._name) , _use_dci_name (o._use_dci_name) @@ -188,12 +189,12 @@ Film::Film (Film const & o) , _source_frame_rate (o._source_frame_rate) , _dirty (o._dirty) { - + } Film::~Film () { - delete _log; + } string diff --git a/src/lib/film.h b/src/lib/film.h index 88f6fbcd7..2ab4a9450 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -77,7 +77,7 @@ public: /** @return Logger. * It is safe to call this from any thread. */ - Log* log () const { + boost::shared_ptr log () const { return _log; } @@ -382,7 +382,7 @@ public: private: /** Log to write to */ - Log* _log; + boost::shared_ptr _log; /** Any running ExamineContentJob, or 0 */ boost::shared_ptr _examine_content_job; diff --git a/src/lib/gain.cc b/src/lib/gain.cc index cec3b3c62..df7011d2e 100644 --- a/src/lib/gain.cc +++ b/src/lib/gain.cc @@ -22,7 +22,7 @@ using boost::shared_ptr; /** @param gain gain in dB */ -Gain::Gain (Log* log, float gain) +Gain::Gain (shared_ptr log, float gain) : AudioProcessor (log) , _gain (gain) { diff --git a/src/lib/gain.h b/src/lib/gain.h index 716ee9b51..d462e5aee 100644 --- a/src/lib/gain.h +++ b/src/lib/gain.h @@ -22,7 +22,7 @@ class Gain : public AudioProcessor { public: - Gain (Log* log, float gain); + Gain (boost::shared_ptr log, float gain); void process_audio (boost::shared_ptr); diff --git a/src/lib/matcher.cc b/src/lib/matcher.cc index 4cd264338..48f6ed912 100644 --- a/src/lib/matcher.cc +++ b/src/lib/matcher.cc @@ -26,7 +26,7 @@ using std::min; using boost::shared_ptr; -Matcher::Matcher (Log* log, int sample_rate, float frames_per_second) +Matcher::Matcher (shared_ptr log, int sample_rate, float frames_per_second) : AudioVideoProcessor (log) , _sample_rate (sample_rate) , _frames_per_second (frames_per_second) diff --git a/src/lib/matcher.h b/src/lib/matcher.h index 60bb87432..b1680e131 100644 --- a/src/lib/matcher.h +++ b/src/lib/matcher.h @@ -24,7 +24,7 @@ class Matcher : public AudioVideoProcessor { public: - Matcher (Log* log, int sample_rate, float frames_per_second); + Matcher (boost::shared_ptr log, int sample_rate, float frames_per_second); void process_video (boost::shared_ptr i, bool, boost::shared_ptr s); void process_audio (boost::shared_ptr); void process_end (); diff --git a/src/lib/processor.h b/src/lib/processor.h index 19d7c4b0c..1ba396f2f 100644 --- a/src/lib/processor.h +++ b/src/lib/processor.h @@ -40,7 +40,7 @@ public: /** Construct a Processor. * @param log Log to use. */ - Processor (Log* log) + Processor (boost::shared_ptr log) : _log (log) {} @@ -50,7 +50,7 @@ public: virtual void process_end () {} protected: - Log* _log; ///< log to write to + boost::shared_ptr _log; ///< log to write to }; /** @class AudioVideoProcessor @@ -62,7 +62,7 @@ public: /** Construct an AudioVideoProcessor. * @param log Log to write to. */ - AudioVideoProcessor (Log* log) + AudioVideoProcessor (boost::shared_ptr log) : Processor (log) {} }; @@ -76,7 +76,7 @@ public: /** Construct an AudioProcessor. * @param log Log to write to. */ - AudioProcessor (Log* log) + AudioProcessor (boost::shared_ptr log) : Processor (log) {} }; @@ -90,7 +90,7 @@ public: /** Construct an VideoProcessor. * @param log Log to write to. */ - VideoProcessor (Log* log) + VideoProcessor (boost::shared_ptr log) : Processor (log) {} }; diff --git a/src/lib/server.cc b/src/lib/server.cc index 76a25bfbb..9c5a77f68 100644 --- a/src/lib/server.cc +++ b/src/lib/server.cc @@ -77,7 +77,7 @@ ServerDescription::as_metadata () const return s.str (); } -Server::Server (Log* log) +Server::Server (shared_ptr log) : _log (log) { diff --git a/src/lib/server.h b/src/lib/server.h index 32ba8dc4b..89aeca626 100644 --- a/src/lib/server.h +++ b/src/lib/server.h @@ -76,7 +76,7 @@ private: class Server { public: - Server (Log* log); + Server (boost::shared_ptr log); void run (int num_threads); @@ -88,5 +88,5 @@ private: std::list > _queue; boost::mutex _worker_mutex; boost::condition _worker_condition; - Log* _log; + boost::shared_ptr _log; }; diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc index 9720ca56a..e0f3a03a2 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -38,7 +38,6 @@ #include "audio_decoder.h" using std::string; -using std::cout; using boost::shared_ptr; using boost::dynamic_pointer_cast; diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 4874e6ef8..230e02c88 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -482,12 +482,16 @@ class App : public wxApp #ifdef DVDOMATIC_POSIX unsetenv ("UBUNTU_MENUPROXY"); #endif - + + /* This needs to be before setup_i18n, as setup_i18n() will + create a Config object, which needs Scalers to have + been created. + */ + dvdomatic_setup (); + wxInitAllImageHandlers (); setup_i18n (); - dvdomatic_setup (); - if (!film_to_load.empty() && boost::filesystem::is_directory (film_to_load)) { try { film.reset (new Film (film_to_load)); diff --git a/src/tools/servomatic_cli.cc b/src/tools/servomatic_cli.cc index f8e713193..6626d45b9 100644 --- a/src/tools/servomatic_cli.cc +++ b/src/tools/servomatic_cli.cc @@ -42,7 +42,10 @@ #include "log.h" #include "version.h" -using namespace std; +using std::cerr; +using std::string; +using std::cout; +using boost::shared_ptr; static void help (string n) @@ -87,8 +90,8 @@ main (int argc, char* argv[]) } Scaler::setup_scalers (); - FileLog log ("servomatic.log"); - Server server (&log); + shared_ptr log (new FileLog ("servomatic.log")); + Server server (log); server.run (num_threads); return 0; } diff --git a/src/tools/servomatic_gui.cc b/src/tools/servomatic_gui.cc index 610ba8005..dd169725f 100644 --- a/src/tools/servomatic_gui.cc +++ b/src/tools/servomatic_gui.cc @@ -25,8 +25,11 @@ #include "lib/server.h" #include "lib/config.h" -using namespace std; -using namespace boost; +using std::cout; +using std::string; +using boost::shared_ptr; +using boost::thread; +using boost::bind; enum { ID_status = 1, @@ -52,7 +55,7 @@ private: string _log; }; -static MemoryLog memory_log; +static shared_ptr memory_log (new MemoryLog); class StatusDialog : public wxDialog { @@ -77,7 +80,7 @@ public: private: void update (wxTimerEvent &) { - _text->ChangeValue (std_to_wx (memory_log.get ())); + _text->ChangeValue (std_to_wx (memory_log->get ())); _sizer->Layout (); } @@ -141,7 +144,7 @@ private: void main_thread () { - Server server (&memory_log); + Server server (memory_log); server.run (Config::instance()->num_local_encoding_threads ()); } diff --git a/src/tools/servomatictest.cc b/src/tools/servomatictest.cc index 91ad02120..f5756c693 100644 --- a/src/tools/servomatictest.cc +++ b/src/tools/servomatictest.cc @@ -43,7 +43,7 @@ using std::pair; using boost::shared_ptr; static ServerDescription* server; -static FileLog log_ ("servomatictest.log"); +static shared_ptr log_ (new FileLog ("servomatictest.log")); static int frame = 0; void @@ -53,14 +53,14 @@ process_video (shared_ptr image, bool, shared_ptr sub) new DCPVideoFrame ( image, sub, libdcp::Size (1024, 1024), 0, 0, 0, - Scaler::from_id ("bicubic"), frame, 24, "", 0, 250000000, &log_) + Scaler::from_id ("bicubic"), frame, 24, "", 0, 250000000, log_) ); shared_ptr remote ( new DCPVideoFrame ( image, sub, libdcp::Size (1024, 1024), 0, 0, 0, - Scaler::from_id ("bicubic"), frame, 24, "", 0, 250000000, &log_) + Scaler::from_id ("bicubic"), frame, 24, "", 0, 250000000, log_) ); cout << "Frame " << frame << ": "; diff --git a/test/test.cc b/test/test.cc index 15c34ca78..448168f24 100644 --- a/test/test.cc +++ b/test/test.cc @@ -254,9 +254,9 @@ public: void do_positive_delay_line_test (int delay_length, int data_length) { - NullLog log; + shared_ptr log (new NullLog); - DelayLine d (&log, 6, delay_length); + DelayLine d (log, 6, delay_length); shared_ptr data (new AudioBuffers (6, data_length)); int in = 0; @@ -297,9 +297,9 @@ do_positive_delay_line_test (int delay_length, int data_length) void do_negative_delay_line_test (int delay_length, int data_length) { - NullLog log; + shared_ptr log (new NullLog); - DelayLine d (&log, 6, delay_length); + DelayLine d (log, 6, delay_length); shared_ptr data (new AudioBuffers (6, data_length)); int in = 0; @@ -406,7 +406,7 @@ BOOST_AUTO_TEST_CASE (client_server_test) shared_ptr subtitle (new Subtitle (Position (50, 60), sub_image)); - FileLog log ("build/test/client_server_test.log"); + shared_ptr log (new FileLog ("build/test/client_server_test.log")); shared_ptr frame ( new DCPVideoFrame ( @@ -422,14 +422,14 @@ BOOST_AUTO_TEST_CASE (client_server_test) "", 0, 200000000, - &log + log ) ); shared_ptr locally_encoded = frame->encode_locally (); BOOST_ASSERT (locally_encoded); - Server* server = new Server (&log); + Server* server = new Server (log); new thread (boost::bind (&Server::run, server, 2)); -- cgit v1.2.3 From 7339bd0457584dc8996a472ee7264a59a779c68e Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 8 Mar 2013 21:27:01 +0000 Subject: Fix crash on analysing audio when we think the film is zero length. --- src/lib/analyse_audio_job.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/analyse_audio_job.cc b/src/lib/analyse_audio_job.cc index 41f918f34..de2632b0a 100644 --- a/src/lib/analyse_audio_job.cc +++ b/src/lib/analyse_audio_job.cc @@ -67,7 +67,7 @@ AnalyseAudioJob::run () decoders.audio->Audio.connect (bind (&AnalyseAudioJob::audio, this, _1)); int64_t total_audio_frames = video_frames_to_audio_frames (_film->length().get(), _film->audio_stream()->sample_rate(), _film->source_frame_rate()); - _samples_per_point = total_audio_frames / _num_points; + _samples_per_point = min (1, total_audio_frames / _num_points); _current.resize (_film->audio_stream()->channels ()); _analysis.reset (new AudioAnalysis (_film->audio_stream()->channels())); -- cgit v1.2.3 From 031a4066190454b1a4d933b74e86a053673a5e43 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 8 Mar 2013 22:51:39 +0000 Subject: Stop infinite loop if audio analysis fails. --- src/lib/analyse_audio_job.cc | 3 ++- src/lib/film.cc | 7 +++++-- src/lib/film.h | 2 +- src/wx/audio_dialog.cc | 4 ++-- src/wx/audio_dialog.h | 2 +- 5 files changed, 11 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/lib/analyse_audio_job.cc b/src/lib/analyse_audio_job.cc index de2632b0a..92c3cdd4e 100644 --- a/src/lib/analyse_audio_job.cc +++ b/src/lib/analyse_audio_job.cc @@ -29,6 +29,7 @@ using std::string; using std::max; +using std::min; using std::cout; using boost::shared_ptr; @@ -67,7 +68,7 @@ AnalyseAudioJob::run () decoders.audio->Audio.connect (bind (&AnalyseAudioJob::audio, this, _1)); int64_t total_audio_frames = video_frames_to_audio_frames (_film->length().get(), _film->audio_stream()->sample_rate(), _film->source_frame_rate()); - _samples_per_point = min (1, total_audio_frames / _num_points); + _samples_per_point = max (1L, total_audio_frames / _num_points); _current.resize (_film->audio_stream()->channels ()); _analysis.reset (new AudioAnalysis (_film->audio_stream()->channels())); diff --git a/src/lib/film.cc b/src/lib/film.cc index 8028f40ef..46b48f511 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -351,9 +351,12 @@ void Film::analyse_audio_finished () { ensure_ui_thread (); - _analyse_audio_job.reset (); - AudioAnalysisFinished (); + if (_analyse_audio_job->finished_ok ()) { + AudioAnalysisSucceeded (); + } + + _analyse_audio_job.reset (); } void diff --git a/src/lib/film.h b/src/lib/film.h index 2ab4a9450..150e384bc 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -374,7 +374,7 @@ public: /** Emitted when some property has changed */ mutable boost::signals2::signal Changed; - boost::signals2::signal AudioAnalysisFinished; + boost::signals2::signal AudioAnalysisSucceeded; /** Current version number of the state file */ static int const state_version; diff --git a/src/wx/audio_dialog.cc b/src/wx/audio_dialog.cc index 5bac8eabe..ba7ddd8f7 100644 --- a/src/wx/audio_dialog.cc +++ b/src/wx/audio_dialog.cc @@ -87,7 +87,7 @@ void AudioDialog::set_film (boost::shared_ptr f) { _film_changed_connection.disconnect (); - _film_audio_analysis_finished_connection.disconnect (); + _film_audio_analysis_succeeded_connection.disconnect (); _film = f; @@ -96,7 +96,7 @@ AudioDialog::set_film (boost::shared_ptr f) _plot->set_gain (_film->audio_gain ()); _film_changed_connection = _film->Changed.connect (bind (&AudioDialog::film_changed, this, _1)); - _film_audio_analysis_finished_connection = _film->AudioAnalysisFinished.connect (bind (&AudioDialog::try_to_load_analysis, this)); + _film_audio_analysis_succeeded_connection = _film->AudioAnalysisSucceeded.connect (bind (&AudioDialog::try_to_load_analysis, this)); SetTitle (std_to_wx (String::compose (wx_to_std (_("DVD-o-matic audio - %1")), _film->name()))); } diff --git a/src/wx/audio_dialog.h b/src/wx/audio_dialog.h index 16cb356fe..514faeea0 100644 --- a/src/wx/audio_dialog.h +++ b/src/wx/audio_dialog.h @@ -47,5 +47,5 @@ private: wxCheckBox* _type_checkbox[AudioPoint::COUNT]; wxSlider* _smoothing; boost::signals2::scoped_connection _film_changed_connection; - boost::signals2::scoped_connection _film_audio_analysis_finished_connection; + boost::signals2::scoped_connection _film_audio_analysis_succeeded_connection; }; -- cgit v1.2.3 From 2bde54c29e6b36c75948ca1d3efcda0535d148d7 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 8 Mar 2013 23:13:23 +0000 Subject: Remove un-read intrinsic_duration. --- src/lib/dcp_video_frame.cc | 2 +- src/lib/film.cc | 17 ----------------- src/lib/film.h | 7 ------- src/lib/transcode_job.cc | 3 --- src/lib/writer.cc | 2 -- src/wx/film_editor.cc | 2 -- 6 files changed, 1 insertion(+), 32 deletions(-) (limited to 'src') diff --git a/src/lib/dcp_video_frame.cc b/src/lib/dcp_video_frame.cc index d735122b5..d674393a9 100644 --- a/src/lib/dcp_video_frame.cc +++ b/src/lib/dcp_video_frame.cc @@ -70,7 +70,7 @@ using libdcp::Size; * @param out Required size of output, in pixels (including any padding). * @param s Scaler to use. * @param p Number of pixels of padding either side of the image. - * @param f Index of the frame within the DCP's intrinsic duration. + * @param f Index of the frame within the DCP. * @param fps Frames per second of the Film's source. * @param pp FFmpeg post-processing string to use. * @param clut Colour look-up table to use (see Config::colour_lut_index ()) diff --git a/src/lib/film.cc b/src/lib/film.cc index 46b48f511..77f9828cd 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -181,7 +181,6 @@ Film::Film (Film const & o) , _dcp_frame_rate (o._dcp_frame_rate) , _size (o._size) , _length (o._length) - , _dcp_intrinsic_duration (o._dcp_intrinsic_duration) , _content_digest (o._content_digest) , _content_audio_streams (o._content_audio_streams) , _external_audio_stream (o._external_audio_stream) @@ -454,7 +453,6 @@ Film::write_metadata () const f << "width " << _size.width << endl; f << "height " << _size.height << endl; f << "length " << _length.get_value_or(0) << endl; - f << "dcp_intrinsic_duration " << _dcp_intrinsic_duration.get_value_or(0) << endl; f << "content_digest " << _content_digest << endl; for (vector >::const_iterator i = _content_audio_streams.begin(); i != _content_audio_streams.end(); ++i) { @@ -595,11 +593,6 @@ Film::read_metadata () if (vv) { _length = vv; } - } else if (k == "dcp_intrinsic_duration") { - int const vv = atoi (v.c_str ()); - if (vv) { - _dcp_intrinsic_duration = vv; - } } else if (k == "content_digest") { _content_digest = v; } else if (k == "content_audio_stream" || (!version && k == "audio_stream")) { @@ -1294,16 +1287,6 @@ Film::unset_length () signal_changed (LENGTH); } -void -Film::set_dcp_intrinsic_duration (int d) -{ - { - boost::mutex::scoped_lock lm (_state_mutex); - _dcp_intrinsic_duration = d; - } - signal_changed (DCP_INTRINSIC_DURATION); -} - void Film::set_content_digest (string d) { diff --git a/src/lib/film.h b/src/lib/film.h index 150e384bc..698e7ef46 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -98,10 +98,6 @@ public: std::string dci_name (bool if_created_now) const; std::string dcp_name (bool if_created_now = false) const; - boost::optional dcp_intrinsic_duration () const { - return _dcp_intrinsic_duration; - } - /** @return true if our state has changed since we last saved it */ bool dirty () const { return _dirty; @@ -145,7 +141,6 @@ public: DCI_METADATA, SIZE, LENGTH, - DCP_INTRINSIC_DURATION, CONTENT_AUDIO_STREAMS, SUBTITLE_STREAMS, SOURCE_FRAME_RATE, @@ -365,7 +360,6 @@ public: void set_size (libdcp::Size); void set_length (SourceFrame); void unset_length (); - void set_dcp_intrinsic_duration (int); void set_content_digest (std::string); void set_content_audio_streams (std::vector >); void set_subtitle_streams (std::vector >); @@ -477,7 +471,6 @@ private: libdcp::Size _size; /** The length of the source, in video frames (as far as we know) */ boost::optional _length; - boost::optional _dcp_intrinsic_duration; /** MD5 digest of our content file */ std::string _content_digest; /** The audio streams in our content */ diff --git a/src/lib/transcode_job.cc b/src/lib/transcode_job.cc index f7cc500fe..234ebe051 100644 --- a/src/lib/transcode_job.cc +++ b/src/lib/transcode_job.cc @@ -68,10 +68,7 @@ TranscodeJob::run () set_progress (1); set_state (FINISHED_OK); - _film->set_dcp_intrinsic_duration (_encoder->video_frames_out ()); - _film->log()->log (N_("Transcode job completed successfully")); - _film->log()->log (String::compose (N_("DCP intrinsic duration is %1"), _encoder->video_frames_out())); } catch (std::exception& e) { diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 5a2f7c9a9..06acaa1f6 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -261,8 +261,6 @@ Writer::finish () int const frames = _last_written_frame + 1; int const duration = frames - _film->trim_start() - _film->trim_end(); - _film->set_dcp_intrinsic_duration (frames); - _picture_asset->set_entry_point (_film->trim_start ()); _picture_asset->set_duration (duration); diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 82c8a76a8..20dbc88ef 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -698,8 +698,6 @@ FilmEditor::film_changed (Film::Property p) _trim_end->SetRange (0, _film->length().get()); } break; - case Film::DCP_INTRINSIC_DURATION: - break; case Film::DCP_CONTENT_TYPE: checked_set (_dcp_content_type, DCPContentType::as_index (_film->dcp_content_type ())); setup_dcp_name (); -- cgit v1.2.3 From 0a7004ab20d6bc3d20c1956df355384fa7f2da30 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 12 Mar 2013 22:15:36 +0000 Subject: Try to copy instead of hard linking if the hard-link fails (#77). --- src/lib/writer.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 06acaa1f6..6ca56ec4e 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -273,8 +273,12 @@ Writer::finish () boost::filesystem::path to; to /= _film->dir (_film->dcp_name()); to /= N_("video.mxf"); - - boost::filesystem::create_hard_link (from, to); + + boost::system::error_code ec; + if (boost::filesystem::create_hard_link (from, to, ec)) { + /* hard link failed; copy instead */ + boost::filesystem::copy_file (from, to); + } /* And update the asset */ -- cgit v1.2.3 From 72234d49c16bad30d66256dd6e82d1359f4f830b Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 12 Mar 2013 22:18:00 +0000 Subject: Fix previous. --- src/lib/writer.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 6ca56ec4e..33f574f56 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -275,7 +275,8 @@ Writer::finish () to /= N_("video.mxf"); boost::system::error_code ec; - if (boost::filesystem::create_hard_link (from, to, ec)) { + boost::filesystem::create_hard_link (from, to, ec); + if (ec) { /* hard link failed; copy instead */ boost::filesystem::copy_file (from, to); } -- cgit v1.2.3 From 7d262f9be3a4c5d8da07dce42f7e2da708f6c7f4 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 12 Mar 2013 22:19:13 +0000 Subject: Log failure to hard-link. --- src/lib/writer.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 33f574f56..2d7ee9ba3 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -279,6 +279,7 @@ Writer::finish () if (ec) { /* hard link failed; copy instead */ boost::filesystem::copy_file (from, to); + _film->log()->log ("Hard-link failed; fell back to copying"); } /* And update the asset */ -- cgit v1.2.3 From a19426aefeccc1b3bc11b454328ef948549011ed Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 12 Mar 2013 23:53:26 +0000 Subject: Updated fr_FR translation from Olivier. --- src/lib/po/fr_FR.po | 36 ++-- src/tools/po/fr_FR.po | 14 +- src/wx/po/fr_FR.po | 475 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 502 insertions(+), 23 deletions(-) create mode 100644 src/wx/po/fr_FR.po (limited to 'src') diff --git a/src/lib/po/fr_FR.po b/src/lib/po/fr_FR.po index 4effdf28b..7e4744397 100644 --- a/src/lib/po/fr_FR.po +++ b/src/lib/po/fr_FR.po @@ -5,16 +5,18 @@ # msgid "" msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" +"Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-03-05 13:49+0000\n" -"PO-Revision-Date: 2013-03-07 01:37+0100\n" +"PO-Revision-Date: 2013-03-13 00:23+0100\n" "Last-Translator: FreeDCP.net \n" -"Language-Team: LANGUAGE \n" +"Language-Team: FreeDCP.net \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: French\n" +"X-Poedit-Country: FRANCE\n" #: src/lib/transcode_job.cc:90 msgid "0%" @@ -70,7 +72,7 @@ msgstr "Advertisement" #: src/lib/job.cc:71 msgid "An error occurred whilst handling the file %1." -msgstr "Une erreure s'est produite durant le traitement du fichier %1." +msgstr "Une erreur s'est produite durant le traitement du fichier %1." #: src/lib/analyse_audio_job.cc:48 msgid "Analyse audio of %1" @@ -114,7 +116,7 @@ msgstr "Ne peux pas démarrer la session SCP (%1)" #: src/lib/scp_dcp_job.cc:187 msgid "Could not write to remote file (%1)" -msgstr "Ne peux pas ecrire le fichier distant (%1)" +msgstr "Ne peux pas écrire le fichier distant (%1)" #: src/lib/filter.cc:77 msgid "Cubic interpolating deinterlacer" @@ -167,7 +169,7 @@ msgstr "Chaque image source sera doublée dans le DCP.\n" #: src/lib/job.cc:287 msgid "Error (%1)" -msgstr "Erreure (%1)" +msgstr "Erreur (%1)" #: src/lib/examine_content_job.cc:55 msgid "Examine content" @@ -240,7 +242,7 @@ msgstr "Horizontal deblocking filter A" #: src/lib/job.cc:87 #: src/lib/job.cc:96 msgid "It is not known what caused this error. The best idea is to report the problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" -msgstr "La cause de l'erreure n'est pas connue. La meilleure chose est de reporter le problème à la liste de discution de DCD-o-matic (dvdomatic@carlh.net)" +msgstr "La cause de l’erreur n'est pas connue. La meilleure chose est de reporter le problème à la liste de discutions de DCD-o-matic (dvdomatic@carlh.net)" #: src/lib/filter.cc:82 msgid "Kernel deinterlacer" @@ -307,7 +309,7 @@ msgstr "Rec 709" #: src/lib/scp_dcp_job.cc:133 msgid "SSH error (%1)" -msgstr "Erreure SSH (%1)" +msgstr "Erreur SSH (%1)" #: src/lib/format.cc:125 msgid "Scope" @@ -415,7 +417,7 @@ msgstr "Transitional" #: src/lib/job.cc:95 msgid "Unknown error" -msgstr "Erruere inconnue" +msgstr "Erreur inconnue" #: src/lib/ffmpeg_decoder.cc:396 msgid "Unrecognised audio sample format (%1)" @@ -451,7 +453,7 @@ msgstr "ajout à la queue de %1" #: src/lib/film.cc:263 msgid "cannot contain slashes" -msgstr "ne peux pas contenir de slashes" +msgstr "ne peux pas contenir de slashs" #: src/lib/util.cc:499 msgid "connect timed out" @@ -475,7 +477,7 @@ msgstr "copie %1" #: src/lib/ffmpeg_decoder.cc:191 msgid "could not find audio decoder" -msgstr "ne trouve pas le decodeur son" +msgstr "ne trouve pas le décodeur son" #: src/lib/ffmpeg_decoder.cc:118 msgid "could not find stream information" @@ -487,7 +489,7 @@ msgstr "ne peux pas trouver de décodeur de sous-titres" #: src/lib/ffmpeg_decoder.cc:169 msgid "could not find video decoder" -msgstr "ne peux pas trouver de decodeur vidéo" +msgstr "ne peux pas trouver de décodeur vidéo" #: src/lib/external_audio_decoder.cc:72 msgid "could not open external audio file for reading" @@ -512,11 +514,11 @@ msgstr "ne peux pas lancer de session SSH" #: src/lib/encoder.cc:247 msgid "decoder sleeps with queue of %1" -msgstr "le decodeur dort en attente de %1" +msgstr "le décodeur dort en attente de %1" #: src/lib/encoder.cc:249 msgid "decoder wakes with queue of %1" -msgstr "le decodeur se réveille en attente de %1" +msgstr "le décodeur se réveille en attente de %1" #: src/lib/external_audio_decoder.cc:94 msgid "external audio files have differing lengths" @@ -553,11 +555,11 @@ msgstr "minutes" #: src/lib/util.cc:642 msgid "missing key %1 in key-value set" -msgstr "missing key %1 in key-value set" +msgstr "" #: src/lib/subtitle.cc:52 msgid "multi-part subtitles not yet supported" -msgstr "sous-titres en plusieurs parites pas encore supportés" +msgstr "sous-titres en plusieurs parties pas encore supportés" #: src/lib/film.cc:263 #: src/lib/film.cc:308 @@ -570,7 +572,7 @@ msgstr "pas d'image fixe trouvée" #: src/lib/subtitle.cc:58 msgid "non-bitmap subtitles not yet supported" -msgstr "Sous-titres non-bitmap non supportés actuellement" +msgstr "sous-titres non-bitmap non supportés actuellement" #. / TRANSLATORS: remaining here follows an amount of time that is remaining #. / on an operation. diff --git a/src/tools/po/fr_FR.po b/src/tools/po/fr_FR.po index 13fdb5a77..ccb4d7906 100644 --- a/src/tools/po/fr_FR.po +++ b/src/tools/po/fr_FR.po @@ -5,20 +5,22 @@ # msgid "" msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" +"Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-03-05 13:49+0000\n" -"PO-Revision-Date: 2013-03-07 01:38+0100\n" +"PO-Revision-Date: 2013-03-13 00:17+0100\n" "Last-Translator: FreeDCP.net \n" -"Language-Team: LANGUAGE \n" +"Language-Team: FreeDCP.net \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: French\n" +"X-Poedit-Country: FRANCE\n" #: src/tools/dvdomatic.cc:177 msgid "&Analyse audio" -msgstr "&Analyer le son" +msgstr "&Analyser le son" #: src/tools/dvdomatic.cc:183 msgid "&Edit" @@ -38,7 +40,7 @@ msgstr "&Travaux" #: src/tools/dvdomatic.cc:173 msgid "&Make DCP" -msgstr "&Creer le DCP" +msgstr "&Créer le DCP" #: src/tools/dvdomatic.cc:161 msgid "&Open..." @@ -105,7 +107,7 @@ msgstr "Monter le DCP" #: src/tools/dvdomatic.cc:319 msgid "Select film to open" -msgstr "Séléctionner le film à ouvrir" +msgstr "Sélectionner le film à ouvrir" #: src/tools/dvdomatic.cc:303 #, c-format diff --git a/src/wx/po/fr_FR.po b/src/wx/po/fr_FR.po new file mode 100644 index 000000000..91bec71e8 --- /dev/null +++ b/src/wx/po/fr_FR.po @@ -0,0 +1,475 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: DVD-o-matic FRENCH\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-03-05 13:49+0000\n" +"PO-Revision-Date: 2013-03-13 00:15+0100\n" +"Last-Translator: FreeDCP.net \n" +"Language-Team: FreeDCP.net \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: French\n" +"X-Poedit-Country: FRANCE\n" + +#: src/wx/film_editor.cc:441 +msgid "%" +msgstr "%" + +#: src/wx/film_editor.cc:1226 +msgid "1 channel" +msgstr "1 canal" + +#: src/wx/film_editor.cc:185 +msgid "A/B" +msgstr "A/B" + +#: src/wx/config_dialog.cc:124 +msgid "Add" +msgstr "Ajouter" + +#: src/wx/audio_dialog.cc:32 +#: src/wx/film_editor.cc:78 +msgid "Audio" +msgstr "Son" + +#: src/wx/film_editor.cc:382 +msgid "Audio Delay" +msgstr "Délai du Son" + +#: src/wx/film_editor.cc:370 +msgid "Audio Gain" +msgstr "Gain du Volume" + +#: src/wx/dci_metadata_dialog.cc:33 +msgid "Audio Language (e.g. EN)" +msgstr "Langage Audio (ex. FR)" + +#: src/wx/job_wrapper.cc:38 +#, c-format +msgid "Bad setting for %s (%s)" +msgstr "Mauvais réglage pour %s (%s)" + +#: src/wx/film_editor.cc:297 +msgid "Bottom crop" +msgstr "Découpe bas" + +#: src/wx/dir_picker_ctrl.cc:38 +msgid "Browse..." +msgstr "Naviguer..." + +#: src/wx/gain_calculator_dialog.cc:36 +msgid "But I have to use fader" +msgstr "Mais je dois utiliser ce volume" + +#: src/wx/film_editor.cc:375 +msgid "Calculate..." +msgstr "Calcul..." + +#: src/wx/audio_dialog.cc:43 +msgid "Channels" +msgstr "C anaux" + +#: src/wx/film_editor.cc:326 +msgid "Colour look-up table" +msgstr "" + +#: src/wx/film_editor.cc:121 +msgid "Content" +msgstr "Contenu" + +#: src/wx/film_editor.cc:131 +msgid "Content Type" +msgstr "Type de Contenu" + +#: src/wx/film_viewer.cc:414 +#, c-format +msgid "Could not decode video for view (%s)" +msgstr "Ne peux pas décoder la vidéo pour affichage (%s)" + +#: src/wx/job_wrapper.cc:40 +#, c-format +msgid "Could not make DCP: %s" +msgstr "Impossible de créer le DCP: %s" + +#: src/wx/film_viewer.cc:108 +#, c-format +msgid "Could not open content file (%s)" +msgstr "Ne peux pas ouvrir le contenu (%s)" + +#: src/wx/film_editor.cc:505 +#, c-format +msgid "Could not set content: %s" +msgstr "Ne peux pas sélectionner le contenu: %s" + +#: src/wx/new_film_dialog.cc:46 +msgid "Create in folder" +msgstr "Créer dans le dossier" + +#: src/wx/dci_metadata_dialog.cc:28 +msgid "DCI name" +msgstr "Nom DCI" + +#: src/wx/film_editor.cc:142 +msgid "DCP Frame Rate" +msgstr "Fréquence d'images du DCP" + +#: src/wx/film_editor.cc:110 +msgid "DCP Name" +msgstr "Nom du DCP" + +#: src/wx/wx_util.cc:61 +msgid "DVD-o-matic" +msgstr "DVD-o-matic" + +#: src/wx/config_dialog.cc:44 +msgid "DVD-o-matic Preferences" +msgstr "Préférences DVD-o-matic" + +#: src/wx/audio_dialog.cc:101 +msgid "DVD-o-matic audio - %1" +msgstr "Son DVD-o-matic - %1" + +#: src/wx/config_dialog.cc:83 +msgid "Default DCI name details" +msgstr "Détails du nom DCI par défaut" + +#: src/wx/config_dialog.cc:74 +msgid "Default directory for new films" +msgstr "Dossier par défaut des nouveaux films" + +#: src/wx/film_editor.cc:117 +#: src/wx/job_manager_view.cc:88 +msgid "Details..." +msgstr "Détails..." + +#: src/wx/properties_dialog.cc:45 +msgid "Disk space required" +msgstr "Espace disque requis" + +#: src/wx/film_editor.cc:192 +msgid "Duration" +msgstr "Durée" + +#: src/wx/config_dialog.cc:126 +msgid "Edit" +msgstr "Édition" + +#: src/wx/config_dialog.cc:84 +#: src/wx/config_dialog.cc:103 +#: src/wx/film_editor.cc:309 +msgid "Edit..." +msgstr "Éditer..." + +#: src/wx/config_dialog.cc:109 +msgid "Encoding Servers" +msgstr "Serveurs d'Encodage" + +#: src/wx/film_editor.cc:177 +msgid "End" +msgstr "Fin" + +#: src/wx/dci_metadata_dialog.cc:53 +msgid "Facility (e.g. DLA)" +msgstr "Laboratoire (ex. DLA)" + +#: src/wx/film_editor.cc:74 +msgid "Film" +msgstr "Film" + +#: src/wx/properties_dialog.cc:36 +msgid "Film Properties" +msgstr "Propriétés du film" + +#: src/wx/new_film_dialog.cc:42 +msgid "Film name" +msgstr "Nom du fichier" + +#: src/wx/film_editor.cc:304 +#: src/wx/filter_dialog.cc:32 +msgid "Filters" +msgstr "Filtres" + +#: src/wx/film_editor.cc:269 +msgid "Format" +msgstr "Format" + +#: src/wx/properties_dialog.cc:41 +msgid "Frames" +msgstr "Images" + +#: src/wx/properties_dialog.cc:49 +msgid "Frames already encoded" +msgstr "Images déjà encodées" + +#: src/wx/gain_calculator_dialog.cc:27 +msgid "Gain Calculator" +msgstr "Calcul du Gain" + +#: src/wx/properties_dialog.cc:59 +msgid "Gb" +msgstr "Gb" + +#: src/wx/server_dialog.cc:36 +msgid "Host name or IP address" +msgstr "Nom d'hôte ou adresse IP" + +#: src/wx/film_editor.cc:1230 +msgid "Hz" +msgstr "Hz" + +#: src/wx/gain_calculator_dialog.cc:32 +msgid "I want to play this back at fader" +msgstr "Je veux le jouer à ce volume" + +#: src/wx/config_dialog.cc:113 +msgid "IP address" +msgstr "Adresse IP" + +#: src/wx/film_editor.cc:336 +msgid "JPEG2000 bandwidth" +msgstr "Qualité JPEG2000" + +#: src/wx/film_editor.cc:282 +msgid "Left crop" +msgstr "Découpe gauche" + +#: src/wx/film_editor.cc:165 +msgid "Length" +msgstr "Longueur" + +#: src/wx/film_editor.cc:340 +msgid "MBps" +msgstr "MBps" + +#: src/wx/dir_picker_ctrl.cc:52 +msgid "My Documents" +msgstr "Mes Documents" + +#: src/wx/film_editor.cc:105 +msgid "Name" +msgstr "Nom" + +#: src/wx/new_film_dialog.cc:33 +msgid "New Film" +msgstr "Nouveau Film" + +#: src/wx/film_editor.cc:306 +#: src/wx/film_editor.cc:663 +msgid "None" +msgstr "Aucun" + +#: src/wx/film_editor.cc:136 +msgid "Original Frame Rate" +msgstr "Cadence d'images originale" + +#: src/wx/film_editor.cc:160 +msgid "Original Size" +msgstr "Taille Originale" + +#: src/wx/dci_metadata_dialog.cc:57 +msgid "Package Type (e.g. OV)" +msgstr "Type de Version (ex. OV)" + +#: src/wx/audio_dialog.cc:60 +msgid "Peak" +msgstr "Pointe" + +#: src/wx/film_viewer.cc:54 +msgid "Play" +msgstr "Jouer" + +#: src/wx/audio_plot.cc:109 +msgid "Please wait; audio is being analysed..." +msgstr "Merci de patienter; la piste son est analysée..." + +#: src/wx/audio_dialog.cc:61 +msgid "RMS" +msgstr "RMS" + +#: src/wx/dci_metadata_dialog.cc:45 +msgid "Rating (e.g. 15)" +msgstr "Rating (ex. 15)" + +#: src/wx/config_dialog.cc:99 +msgid "Reference filters for A/B" +msgstr "Filtres de référence pour A/B" + +#: src/wx/config_dialog.cc:88 +msgid "Reference scaler for A/B" +msgstr "Échelle de référence pour A7B" + +#: src/wx/config_dialog.cc:128 +msgid "Remove" +msgstr "Supprimer" + +#: src/wx/film_editor.cc:287 +msgid "Right crop" +msgstr "Découpe droite" + +#: src/wx/job_manager_view.cc:104 +msgid "Running" +msgstr "Progression" + +#: src/wx/film_editor.cc:316 +msgid "Scaler" +msgstr "Mise à l'échelle" + +#: src/wx/film_editor.cc:408 +msgid "Select Audio File" +msgstr "Sélectionner le Fichier Son" + +#: src/wx/film_editor.cc:122 +msgid "Select Content File" +msgstr "Sélectionner le fichier de Contenu" + +#: src/wx/server_dialog.cc:25 +msgid "Server" +msgstr "Serveur" + +#: src/wx/film_editor.cc:365 +msgid "Show Audio..." +msgstr "Montrer le son..." + +#: src/wx/audio_dialog.cc:71 +msgid "Smoothing" +msgstr "" + +#: src/wx/film_editor.cc:174 +msgid "Start" +msgstr "Début" + +#: src/wx/dci_metadata_dialog.cc:49 +msgid "Studio (e.g. TCF)" +msgstr "Studio (ex. TCF)" + +#: src/wx/dci_metadata_dialog.cc:37 +msgid "Subtitle Language (e.g. FR)" +msgstr "Langue de Sous-titres (ex. FR)" + +#: src/wx/film_editor.cc:432 +msgid "Subtitle Offset" +msgstr "" + +#: src/wx/film_editor.cc:437 +msgid "Subtitle Scale" +msgstr "" + +#: src/wx/film_editor.cc:80 +msgid "Subtitles" +msgstr "Sous-Titres" + +#: src/wx/config_dialog.cc:49 +msgid "TMS IP address" +msgstr "Adresse IP du TMS" + +#: src/wx/config_dialog.cc:64 +msgid "TMS password" +msgstr "Mot de Passe du TMS" + +#: src/wx/config_dialog.cc:54 +msgid "TMS target path" +msgstr "Chemin d'accès du TMS" + +#: src/wx/config_dialog.cc:59 +msgid "TMS user name" +msgstr "Nom d'utilisateur du TMS" + +#: src/wx/dci_metadata_dialog.cc:41 +msgid "Territory (e.g. UK)" +msgstr "Territoire (ex. FR)" + +#: src/wx/config_dialog.cc:117 +msgid "Threads" +msgstr "Processeurs" + +#: src/wx/server_dialog.cc:40 +msgid "Threads to use" +msgstr "Nombre de processeurs à utiliser" + +#: src/wx/config_dialog.cc:69 +msgid "Threads to use for encoding on this host" +msgstr "Nombre de processeurs à utiliser sur cet hôte" + +#: src/wx/audio_plot.cc:139 +msgid "Time" +msgstr "Durée" + +#: src/wx/film_editor.cc:292 +msgid "Top crop" +msgstr "Découpe haut" + +#: src/wx/film_editor.cc:172 +msgid "Trim frames" +msgstr "" + +#: src/wx/film_editor.cc:126 +msgid "Trust content's header" +msgstr "Faire confiance au contenu" + +#: src/wx/audio_dialog.cc:55 +msgid "Type" +msgstr "Type" + +#: src/wx/film_editor.cc:115 +msgid "Use DCI name" +msgstr "Utiliser le nom DCI" + +#: src/wx/film_editor.cc:146 +msgid "Use best" +msgstr "Utiliser le meilleur" + +#: src/wx/film_editor.cc:392 +msgid "Use content's audio" +msgstr "Utiliser la piste audio du contenu" + +#: src/wx/film_editor.cc:402 +msgid "Use external audio" +msgstr "Utiliser une source audio externe" + +#: src/wx/film_editor.cc:76 +msgid "Video" +msgstr "Vidéo" + +#: src/wx/film_editor.cc:425 +msgid "With Subtitles" +msgstr "Avec Sous-titres" + +#: src/wx/film_editor.cc:1228 +msgid "channels" +msgstr "canaux" + +#: src/wx/properties_dialog.cc:50 +msgid "counting..." +msgstr "compte..." + +#: src/wx/film_editor.cc:374 +msgid "dB" +msgstr "dB" + +#: src/wx/film_editor.cc:689 +#: src/wx/film_editor.cc:691 +msgid "frames" +msgstr "images" + +#. / TRANSLATORS: this is an abbreviation for milliseconds, the unit of time +#: src/wx/film_editor.cc:387 +msgid "ms" +msgstr "ms" + +#. / TRANSLATORS: `s' here is an abbreviation for seconds, the unit of time +#: src/wx/film_editor.cc:198 +msgid "s" +msgstr "s" + +#: src/wx/properties_dialog.cc:62 +#: src/wx/properties_dialog.cc:63 +msgid "unknown" +msgstr "inconnu" + -- cgit v1.2.3 From ffd67de21310dfaca4b379c2a9869ea6ce946fd6 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 14 Mar 2013 15:50:28 +0000 Subject: Fix build on some compilers. --- src/lib/analyse_audio_job.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/analyse_audio_job.cc b/src/lib/analyse_audio_job.cc index 92c3cdd4e..43eecbcbd 100644 --- a/src/lib/analyse_audio_job.cc +++ b/src/lib/analyse_audio_job.cc @@ -68,7 +68,7 @@ AnalyseAudioJob::run () decoders.audio->Audio.connect (bind (&AnalyseAudioJob::audio, this, _1)); int64_t total_audio_frames = video_frames_to_audio_frames (_film->length().get(), _film->audio_stream()->sample_rate(), _film->source_frame_rate()); - _samples_per_point = max (1L, total_audio_frames / _num_points); + _samples_per_point = max (int64_t (1), total_audio_frames / _num_points); _current.resize (_film->audio_stream()->channels ()); _analysis.reset (new AudioAnalysis (_film->audio_stream()->channels())); -- cgit v1.2.3 From 9fe1a5c6dd0c0b90d2fa20d77a86e30a3c7a966b Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 16 Mar 2013 20:48:27 +0000 Subject: Remove unused method. --- src/lib/imagemagick_decoder.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src') diff --git a/src/lib/imagemagick_decoder.h b/src/lib/imagemagick_decoder.h index 0e375f6e9..2f4e2c967 100644 --- a/src/lib/imagemagick_decoder.h +++ b/src/lib/imagemagick_decoder.h @@ -52,10 +52,6 @@ public: return 0; } - bool has_subtitles () const { - return false; - } - bool seek (double); bool seek_to_last (); -- cgit v1.2.3 From 9c4c94748ee6bcdec09c63974a4f06d3835db4c5 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 17 Mar 2013 15:51:42 +0000 Subject: Rename ExternalAudioDecoder -> SndfileDecoder. --- src/lib/decoder_factory.cc | 6 +- src/lib/external_audio_decoder.cc | 188 -------------------------------------- src/lib/external_audio_decoder.h | 54 ----------- src/lib/film.cc | 16 ++-- src/lib/film.h | 2 +- src/lib/sndfile_decoder.cc | 188 ++++++++++++++++++++++++++++++++++++++ src/lib/sndfile_decoder.h | 54 +++++++++++ src/lib/stream.cc | 4 +- src/lib/wscript | 2 +- src/wx/film_editor.cc | 1 - test/test.cc | 4 +- 11 files changed, 259 insertions(+), 260 deletions(-) delete mode 100644 src/lib/external_audio_decoder.cc delete mode 100644 src/lib/external_audio_decoder.h create mode 100644 src/lib/sndfile_decoder.cc create mode 100644 src/lib/sndfile_decoder.h (limited to 'src') diff --git a/src/lib/decoder_factory.cc b/src/lib/decoder_factory.cc index 478ccd1c1..f7f9f4074 100644 --- a/src/lib/decoder_factory.cc +++ b/src/lib/decoder_factory.cc @@ -25,7 +25,7 @@ #include "ffmpeg_decoder.h" #include "imagemagick_decoder.h" #include "film.h" -#include "external_audio_decoder.h" +#include "sndfile_decoder.h" #include "decoder_factory.h" using std::string; @@ -47,7 +47,7 @@ decoder_factory ( /* A single image file, or a directory of them */ return Decoders ( shared_ptr (new ImageMagickDecoder (f, o)), - shared_ptr (new ExternalAudioDecoder (f, o)) + shared_ptr (new SndfileDecoder (f, o)) ); } @@ -56,5 +56,5 @@ decoder_factory ( return Decoders (fd, fd); } - return Decoders (fd, shared_ptr (new ExternalAudioDecoder (f, o))); + return Decoders (fd, shared_ptr (new SndfileDecoder (f, o))); } diff --git a/src/lib/external_audio_decoder.cc b/src/lib/external_audio_decoder.cc deleted file mode 100644 index 1248b5a3b..000000000 --- a/src/lib/external_audio_decoder.cc +++ /dev/null @@ -1,188 +0,0 @@ -/* - Copyright (C) 2012 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include -#include -#include "external_audio_decoder.h" -#include "film.h" -#include "exceptions.h" - -#include "i18n.h" - -using std::vector; -using std::string; -using std::stringstream; -using std::min; -using std::cout; -using boost::shared_ptr; -using boost::optional; - -ExternalAudioDecoder::ExternalAudioDecoder (shared_ptr f, DecodeOptions o) - : Decoder (f, o) - , AudioDecoder (f, o) -{ - sf_count_t frames; - vector sf = open_files (frames); - close_files (sf); -} - -vector -ExternalAudioDecoder::open_files (sf_count_t & frames) -{ - vector const files = _film->external_audio (); - - int N = 0; - for (size_t i = 0; i < files.size(); ++i) { - if (!files[i].empty()) { - N = i + 1; - } - } - - if (N == 0) { - return vector (); - } - - bool first = true; - frames = 0; - - vector sndfiles; - for (size_t i = 0; i < (size_t) N; ++i) { - if (files[i].empty ()) { - sndfiles.push_back (0); - } else { - SF_INFO info; - SNDFILE* s = sf_open (files[i].c_str(), SFM_READ, &info); - if (!s) { - throw DecodeError (_("could not open external audio file for reading")); - } - - if (info.channels != 1) { - throw DecodeError (_("external audio files must be mono")); - } - - sndfiles.push_back (s); - - if (first) { - shared_ptr st ( - new ExternalAudioStream ( - info.samplerate, av_get_default_channel_layout (N) - ) - ); - - _audio_streams.push_back (st); - _audio_stream = st; - frames = info.frames; - first = false; - } else { - if (info.frames != frames) { - throw DecodeError (_("external audio files have differing lengths")); - } - } - } - } - - return sndfiles; -} - -bool -ExternalAudioDecoder::pass () -{ - sf_count_t frames; - vector sndfiles = open_files (frames); - if (sndfiles.empty()) { - return true; - } - - /* Do things in half second blocks as I think there may be limits - to what FFmpeg (and in particular the resampler) can cope with. - */ - sf_count_t const block = _audio_stream->sample_rate() / 2; - - shared_ptr audio (new AudioBuffers (_audio_stream->channels(), block)); - while (frames > 0) { - sf_count_t const this_time = min (block, frames); - for (size_t i = 0; i < sndfiles.size(); ++i) { - if (!sndfiles[i]) { - audio->make_silent (i); - } else { - sf_read_float (sndfiles[i], audio->data(i), block); - } - } - - audio->set_frames (this_time); - Audio (audio); - frames -= this_time; - } - - close_files (sndfiles); - - return true; -} - -void -ExternalAudioDecoder::close_files (vector const & sndfiles) -{ - for (size_t i = 0; i < sndfiles.size(); ++i) { - sf_close (sndfiles[i]); - } -} - -shared_ptr -ExternalAudioStream::create () -{ - return shared_ptr (new ExternalAudioStream); -} - -shared_ptr -ExternalAudioStream::create (string t, optional v) -{ - if (!v) { - /* version < 1; no type in the string, and there's only FFmpeg streams anyway */ - return shared_ptr (); - } - - stringstream s (t); - string type; - s >> type; - if (type != N_("external")) { - return shared_ptr (); - } - - return shared_ptr (new ExternalAudioStream (t, v)); -} - -ExternalAudioStream::ExternalAudioStream (string t, optional v) -{ - assert (v); - - stringstream s (t); - string type; - s >> type >> _sample_rate >> _channel_layout; -} - -ExternalAudioStream::ExternalAudioStream () -{ - -} - -string -ExternalAudioStream::to_string () const -{ - return String::compose (N_("external %1 %2"), _sample_rate, _channel_layout); -} diff --git a/src/lib/external_audio_decoder.h b/src/lib/external_audio_decoder.h deleted file mode 100644 index 6f010abb1..000000000 --- a/src/lib/external_audio_decoder.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - Copyright (C) 2012 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include -#include "decoder.h" -#include "audio_decoder.h" -#include "stream.h" - -class ExternalAudioStream : public AudioStream -{ -public: - ExternalAudioStream (int sample_rate, int64_t layout) - : AudioStream (sample_rate, layout) - {} - - std::string to_string () const; - - static boost::shared_ptr create (); - static boost::shared_ptr create (std::string t, boost::optional v); - -private: - friend class stream_test; - - ExternalAudioStream (); - ExternalAudioStream (std::string t, boost::optional v); -}; - -class ExternalAudioDecoder : public AudioDecoder -{ -public: - ExternalAudioDecoder (boost::shared_ptr, DecodeOptions); - - bool pass (); - -private: - std::vector open_files (sf_count_t &); - void close_files (std::vector const &); -}; diff --git a/src/lib/film.cc b/src/lib/film.cc index 77f9828cd..c84042451 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -50,7 +50,7 @@ #include "ui_signaller.h" #include "video_decoder.h" #include "audio_decoder.h" -#include "external_audio_decoder.h" +#include "sndfile_decoder.h" #include "analyse_audio_job.h" #include "i18n.h" @@ -138,7 +138,7 @@ Film::Film (string d, bool must_exist) } } - _external_audio_stream = ExternalAudioStream::create (); + _sndfile_stream = SndfileStream::create (); if (must_exist) { read_metadata (); @@ -183,7 +183,7 @@ Film::Film (Film const & o) , _length (o._length) , _content_digest (o._content_digest) , _content_audio_streams (o._content_audio_streams) - , _external_audio_stream (o._external_audio_stream) + , _sndfile_stream (o._sndfile_stream) , _subtitle_streams (o._subtitle_streams) , _source_frame_rate (o._source_frame_rate) , _dirty (o._dirty) @@ -459,7 +459,7 @@ Film::write_metadata () const f << "content_audio_stream " << (*i)->to_string () << endl; } - f << "external_audio_stream " << _external_audio_stream->to_string() << endl; + f << "external_audio_stream " << _sndfile_stream->to_string() << endl; for (vector >::const_iterator i = _subtitle_streams.begin(); i != _subtitle_streams.end(); ++i) { f << "subtitle_stream " << (*i)->to_string () << endl; @@ -598,7 +598,7 @@ Film::read_metadata () } else if (k == "content_audio_stream" || (!version && k == "audio_stream")) { _content_audio_streams.push_back (audio_stream_factory (v, version)); } else if (k == "external_audio_stream") { - _external_audio_stream = audio_stream_factory (v, version); + _sndfile_stream = audio_stream_factory (v, version); } else if (k == "subtitle_stream") { _subtitle_streams.push_back (subtitle_stream_factory (v, version)); } else if (k == "source_frame_rate") { @@ -1127,9 +1127,9 @@ Film::set_external_audio (vector a) _external_audio = a; } - shared_ptr decoder (new ExternalAudioDecoder (shared_from_this(), DecodeOptions())); + shared_ptr decoder (new SndfileDecoder (shared_from_this(), DecodeOptions())); if (decoder->audio_stream()) { - _external_audio_stream = decoder->audio_stream (); + _sndfile_stream = decoder->audio_stream (); } signal_changed (EXTERNAL_AUDIO); @@ -1364,7 +1364,7 @@ Film::audio_stream () const return _content_audio_stream; } - return _external_audio_stream; + return _sndfile_stream; } string diff --git a/src/lib/film.h b/src/lib/film.h index 698e7ef46..adc4b0eec 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -476,7 +476,7 @@ private: /** The audio streams in our content */ std::vector > _content_audio_streams; /** A stream to represent possible external audio (will always exist) */ - boost::shared_ptr _external_audio_stream; + boost::shared_ptr _sndfile_stream; /** the subtitle streams that we can use */ std::vector > _subtitle_streams; /** Frames per second of the source */ diff --git a/src/lib/sndfile_decoder.cc b/src/lib/sndfile_decoder.cc new file mode 100644 index 000000000..0e3e5e234 --- /dev/null +++ b/src/lib/sndfile_decoder.cc @@ -0,0 +1,188 @@ +/* + Copyright (C) 2012 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include +#include "sndfile_decoder.h" +#include "film.h" +#include "exceptions.h" + +#include "i18n.h" + +using std::vector; +using std::string; +using std::stringstream; +using std::min; +using std::cout; +using boost::shared_ptr; +using boost::optional; + +SndfileDecoder::SndfileDecoder (shared_ptr f, DecodeOptions o) + : Decoder (f, o) + , AudioDecoder (f, o) +{ + sf_count_t frames; + vector sf = open_files (frames); + close_files (sf); +} + +vector +SndfileDecoder::open_files (sf_count_t & frames) +{ + vector const files = _film->external_audio (); + + int N = 0; + for (size_t i = 0; i < files.size(); ++i) { + if (!files[i].empty()) { + N = i + 1; + } + } + + if (N == 0) { + return vector (); + } + + bool first = true; + frames = 0; + + vector sndfiles; + for (size_t i = 0; i < (size_t) N; ++i) { + if (files[i].empty ()) { + sndfiles.push_back (0); + } else { + SF_INFO info; + SNDFILE* s = sf_open (files[i].c_str(), SFM_READ, &info); + if (!s) { + throw DecodeError (_("could not open external audio file for reading")); + } + + if (info.channels != 1) { + throw DecodeError (_("external audio files must be mono")); + } + + sndfiles.push_back (s); + + if (first) { + shared_ptr st ( + new SndfileStream ( + info.samplerate, av_get_default_channel_layout (N) + ) + ); + + _audio_streams.push_back (st); + _audio_stream = st; + frames = info.frames; + first = false; + } else { + if (info.frames != frames) { + throw DecodeError (_("external audio files have differing lengths")); + } + } + } + } + + return sndfiles; +} + +bool +SndfileDecoder::pass () +{ + sf_count_t frames; + vector sndfiles = open_files (frames); + if (sndfiles.empty()) { + return true; + } + + /* Do things in half second blocks as I think there may be limits + to what FFmpeg (and in particular the resampler) can cope with. + */ + sf_count_t const block = _audio_stream->sample_rate() / 2; + + shared_ptr audio (new AudioBuffers (_audio_stream->channels(), block)); + while (frames > 0) { + sf_count_t const this_time = min (block, frames); + for (size_t i = 0; i < sndfiles.size(); ++i) { + if (!sndfiles[i]) { + audio->make_silent (i); + } else { + sf_read_float (sndfiles[i], audio->data(i), block); + } + } + + audio->set_frames (this_time); + Audio (audio); + frames -= this_time; + } + + close_files (sndfiles); + + return true; +} + +void +SndfileDecoder::close_files (vector const & sndfiles) +{ + for (size_t i = 0; i < sndfiles.size(); ++i) { + sf_close (sndfiles[i]); + } +} + +shared_ptr +SndfileStream::create () +{ + return shared_ptr (new SndfileStream); +} + +shared_ptr +SndfileStream::create (string t, optional v) +{ + if (!v) { + /* version < 1; no type in the string, and there's only FFmpeg streams anyway */ + return shared_ptr (); + } + + stringstream s (t); + string type; + s >> type; + if (type != N_("external")) { + return shared_ptr (); + } + + return shared_ptr (new SndfileStream (t, v)); +} + +SndfileStream::SndfileStream (string t, optional v) +{ + assert (v); + + stringstream s (t); + string type; + s >> type >> _sample_rate >> _channel_layout; +} + +SndfileStream::SndfileStream () +{ + +} + +string +SndfileStream::to_string () const +{ + return String::compose (N_("external %1 %2"), _sample_rate, _channel_layout); +} diff --git a/src/lib/sndfile_decoder.h b/src/lib/sndfile_decoder.h new file mode 100644 index 000000000..e16eab673 --- /dev/null +++ b/src/lib/sndfile_decoder.h @@ -0,0 +1,54 @@ +/* + Copyright (C) 2012-2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include "decoder.h" +#include "audio_decoder.h" +#include "stream.h" + +class SndfileStream : public AudioStream +{ +public: + SndfileStream (int sample_rate, int64_t layout) + : AudioStream (sample_rate, layout) + {} + + std::string to_string () const; + + static boost::shared_ptr create (); + static boost::shared_ptr create (std::string t, boost::optional v); + +private: + friend class stream_test; + + SndfileStream (); + SndfileStream (std::string t, boost::optional v); +}; + +class SndfileDecoder : public AudioDecoder +{ +public: + SndfileDecoder (boost::shared_ptr, DecodeOptions); + + bool pass (); + +private: + std::vector open_files (sf_count_t &); + void close_files (std::vector const &); +}; diff --git a/src/lib/stream.cc b/src/lib/stream.cc index e5a2bbc2b..bfe7b5eb4 100644 --- a/src/lib/stream.cc +++ b/src/lib/stream.cc @@ -21,7 +21,7 @@ #include "compose.hpp" #include "stream.h" #include "ffmpeg_decoder.h" -#include "external_audio_decoder.h" +#include "sndfile_decoder.h" #include "i18n.h" @@ -74,7 +74,7 @@ audio_stream_factory (string t, optional v) s = FFmpegAudioStream::create (t, v); if (!s) { - s = ExternalAudioStream::create (t, v); + s = SndfileStream::create (t, v); } return s; diff --git a/src/lib/wscript b/src/lib/wscript index d36a24e7a..de39345d5 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -20,7 +20,6 @@ sources = """ dolby_cp750.cc encoder.cc examine_content_job.cc - external_audio_decoder.cc filter_graph.cc ffmpeg_compatibility.cc ffmpeg_decoder.cc @@ -38,6 +37,7 @@ sources = """ scp_dcp_job.cc scaler.cc server.cc + sndfile_decoder.cc sound_processor.cc stream.cc subtitle.cc diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 20dbc88ef..2553d0bd5 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -37,7 +37,6 @@ #include "lib/filter.h" #include "lib/config.h" #include "lib/ffmpeg_decoder.h" -#include "lib/external_audio_decoder.h" #include "filter_dialog.h" #include "wx_util.h" #include "film_editor.h" diff --git a/test/test.cc b/test/test.cc index 448168f24..f31b3b1ca 100644 --- a/test/test.cc +++ b/test/test.cc @@ -39,7 +39,7 @@ #include "subtitle.h" #include "scaler.h" #include "ffmpeg_decoder.h" -#include "external_audio_decoder.h" +#include "sndfile_decoder.h" #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MODULE dvdomatic_test #include @@ -191,7 +191,7 @@ BOOST_AUTO_TEST_CASE (stream_test) BOOST_CHECK_EQUAL (a.name(), "hello there world"); BOOST_CHECK_EQUAL (a.to_string(), "ffmpeg 4 44100 1 hello there world"); - ExternalAudioStream e ("external 44100 1", boost::optional (1)); + SndfileStream e ("external 44100 1", boost::optional (1)); BOOST_CHECK_EQUAL (e.sample_rate(), 44100); BOOST_CHECK_EQUAL (e.channel_layout(), 1); BOOST_CHECK_EQUAL (e.to_string(), "external 44100 1"); -- cgit v1.2.3 From 6d760b958fd70ac53559a7ad8da9adf02d1514fa Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 19 Mar 2013 20:29:14 +0000 Subject: Add Italian translation from Massimiliano Broggi --- src/lib/po/it_IT.po | 585 ++++++++++++++++++++++++++++++++++++++++++++ src/tools/po/it_IT.po | 115 +++++++++ src/wx/po/it_IT.po | 466 +++++++++++++++++++++++++++++++++++ windows/installer.nsi.32.in | 7 +- windows/installer.nsi.64.in | 8 +- 5 files changed, 1177 insertions(+), 4 deletions(-) create mode 100644 src/lib/po/it_IT.po create mode 100644 src/tools/po/it_IT.po create mode 100644 src/wx/po/it_IT.po (limited to 'src') diff --git a/src/lib/po/it_IT.po b/src/lib/po/it_IT.po new file mode 100644 index 000000000..46e533450 --- /dev/null +++ b/src/lib/po/it_IT.po @@ -0,0 +1,585 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: IT VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-03-15 08:39+0000\n" +"PO-Revision-Date: 2013-03-18 16:46+0100\n" +"Last-Translator: Maci \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.5.5\n" +"Language: Italiano\n" + +#: src/lib/transcode_job.cc:87 +msgid "0%" +msgstr "0%" + +#: src/lib/format.cc:75 +msgid "1.19" +msgstr "1.19" + +#: src/lib/format.cc:80 +msgid "1.33" +msgstr "1.33" + +#: src/lib/format.cc:85 +msgid "1.375" +msgstr "1.375" + +#: src/lib/format.cc:100 +msgid "1.66" +msgstr "1.66" + +#: src/lib/format.cc:105 +msgid "1.66 within Flat" +msgstr "1.66 all'interno di Flat" + +#: src/lib/format.cc:115 +msgid "16:9" +msgstr "16:9" + +#: src/lib/format.cc:110 +msgid "16:9 within Flat" +msgstr "16:9 all'interno di Flat" + +#: src/lib/filter.cc:88 +msgid "3D denoiser" +msgstr "Riduttore di rumore 3D" + +#: src/lib/format.cc:90 +msgid "4:3 within Flat" +msgstr "4:3 all'interno di Flat" + +#: src/lib/ab_transcode_job.cc:49 +msgid "A/B transcode %1" +msgstr "Transcodifica A/B %1" + +#: src/lib/format.cc:95 +msgid "Academy" +msgstr "Academy" + +#: src/lib/dcp_content_type.cc:53 +msgid "Advertisement" +msgstr "Pubblicità" + +#: src/lib/job.cc:71 +msgid "An error occurred whilst handling the file %1." +msgstr "Errore durante l'elaborazione del file %1." + +#: src/lib/analyse_audio_job.cc:49 +msgid "Analyse audio of %1" +msgstr "Analizzo l'audio di %1" + +#: src/lib/scaler.cc:64 +msgid "Area" +msgstr "Area" + +#: src/lib/scaler.cc:62 +msgid "Bicubic" +msgstr "Bicubica" + +#: src/lib/scaler.cc:69 +msgid "Bilinear" +msgstr "Bilineare" + +#: src/lib/encoder.cc:101 +msgid "Cannot resample audio as libswresample is not present" +msgstr "Non posso ricampionare l'audio perchè libswresample non è presente" + +#: src/lib/scp_dcp_job.cc:109 +msgid "Copy DCP to TMS" +msgstr "Copia del DCP al TMS" + +#: src/lib/scp_dcp_job.cc:128 +msgid "Could not connect to server %1 (%2)" +msgstr "Non posso connetermi al server %1 (%2)" + +#: src/lib/scp_dcp_job.cc:150 +msgid "Could not create remote directory %1 (%2)" +msgstr "Non posso creare la directory remota %1 (%2)" + +#: src/lib/scp_dcp_job.cc:175 +msgid "Could not open %1 to send" +msgstr "Non posso aprire %1 da inviare" + +#: src/lib/scp_dcp_job.cc:145 +msgid "Could not start SCP session (%1)" +msgstr "Non posso avviare la sessione SCP (%1)" + +#: src/lib/scp_dcp_job.cc:187 +msgid "Could not write to remote file (%1)" +msgstr "Non posso scrivere il file remoto (%1)" + +#: src/lib/filter.cc:77 +msgid "Cubic interpolating deinterlacer" +msgstr "Deinterlacciatore cubico interpolato" + +#: src/lib/util.cc:965 +msgid "DCP and source have the same rate.\n" +msgstr "Il DCP e il sorgente hanno la stessa frequenza.\n" + +#: src/lib/util.cc:975 +msgid "DCP will run at %1%% of the source speed." +msgstr "Il DCP andrà al %1%% della velocità del sorgente." + +#: src/lib/util.cc:968 +msgid "DCP will use every other frame of the source.\n" +msgstr "Il DCP userà ogni altro fotogramma del sorgente.\n" + +#: src/lib/filter.cc:68 src/lib/filter.cc:69 src/lib/filter.cc:70 +#: src/lib/filter.cc:71 src/lib/filter.cc:72 src/lib/filter.cc:73 +msgid "De-blocking" +msgstr "Sbloccaggio" + +#: src/lib/filter.cc:75 src/lib/filter.cc:76 src/lib/filter.cc:77 +#: src/lib/filter.cc:78 src/lib/filter.cc:79 src/lib/filter.cc:80 +#: src/lib/filter.cc:81 src/lib/filter.cc:82 src/lib/filter.cc:83 +msgid "De-interlacing" +msgstr "De-interlacciamento" + +#: src/lib/filter.cc:74 +msgid "Deringing filter" +msgstr "Filtro deringing" + +#: src/lib/dolby_cp750.cc:27 +msgid "Dolby CP750" +msgstr "Dolby CP750" + +#: src/lib/util.cc:970 +msgid "Each source frame will be doubled in the DCP.\n" +msgstr "Ogni fotogramma del sorgente sarà raddoppiato nel DCP.\n" + +#: src/lib/job.cc:287 +msgid "Error (%1)" +msgstr "Errore (%1)" + +#: src/lib/examine_content_job.cc:55 +msgid "Examine content" +msgstr "Esamino il contenuto" + +#: src/lib/examine_content_job.cc:58 +msgid "Examine content of %1" +msgstr "Esamo il contenuto di %1" + +#: src/lib/filter.cc:72 +msgid "Experimental horizontal deblocking filter 1" +msgstr "Filtro di sblocco sperimentale orizzontale 1" + +#: src/lib/filter.cc:73 +msgid "Experimental vertical deblocking filter 1" +msgstr "Filtro di sblocco sperimentale verticale 1" + +#: src/lib/filter.cc:79 +msgid "FFMPEG deinterlacer" +msgstr "Deinterlacciatore FFMPEG" + +#: src/lib/filter.cc:80 +msgid "FIR low-pass deinterlacer" +msgstr "Deinterlacciatore FIR low-pass" + +#: src/lib/scp_dcp_job.cc:138 +msgid "Failed to authenticate with server (%1)" +msgstr "Autenticazione col server fallita (%1) " + +#: src/lib/scaler.cc:70 +msgid "Fast Bilinear" +msgstr "Bilineare rapida" + +#: src/lib/dcp_content_type.cc:44 +msgid "Feature" +msgstr "Caratteristica" + +#: src/lib/format.cc:120 +msgid "Flat" +msgstr "Flat" + +#: src/lib/format.cc:130 +msgid "Flat without stretch" +msgstr "Flat senza stiramento" + +#: src/lib/filter.cc:85 +msgid "Force quantizer" +msgstr "Forza quantizzatore" + +#: src/lib/scaler.cc:65 +msgid "Gaussian" +msgstr "Gaussiana" + +#: src/lib/filter.cc:86 +msgid "Gradient debander" +msgstr "Gradiente debander" + +#: src/lib/filter.cc:89 +msgid "High quality 3D denoiser" +msgstr "Riduttore di rumore 3D di alta qualità" + +#: src/lib/filter.cc:68 +msgid "Horizontal deblocking filter" +msgstr "Filtro sblocco orizzontale" + +#: src/lib/filter.cc:70 +msgid "Horizontal deblocking filter A" +msgstr "Filtro A sblocco orizzontale" + +#: src/lib/job.cc:87 src/lib/job.cc:96 +msgid "" +"It is not known what caused this error. The best idea is to report the " +"problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" +msgstr "" +"Non sappiamo cosa ha causato questo errore. La cosa migliore è di inviare un " +"report del problema alla mailing list di DVD-o-matic (dvdomatic@carlh.net)" + +#: src/lib/filter.cc:82 +msgid "Kernel deinterlacer" +msgstr "Deinterlacciatore Kernel" + +#: src/lib/scaler.cc:66 +msgid "Lanczos" +msgstr "Lanczos" + +#: src/lib/filter.cc:75 +msgid "Linear blend deinterlacer" +msgstr "Deinterlacciatore lineare miscelato" + +#: src/lib/filter.cc:76 +msgid "Linear interpolating deinterlacer" +msgstr "Deinterlacciatore lineare interpolato" + +#: src/lib/filter.cc:78 +msgid "Median deinterlacer" +msgstr "Deinterlacciatore mediano" + +#: src/lib/filter.cc:74 src/lib/filter.cc:85 src/lib/filter.cc:86 +#: src/lib/filter.cc:87 src/lib/filter.cc:90 +msgid "Misc" +msgstr "Varie" + +#: src/lib/filter.cc:81 +msgid "Motion compensating deinterlacer" +msgstr "Dinterlacciatore compensativo di movimento" + +#: src/lib/filter.cc:84 src/lib/filter.cc:88 src/lib/filter.cc:89 +#: src/lib/filter.cc:91 +msgid "Noise reduction" +msgstr "Riduzione del rumore" + +#: src/lib/job.cc:285 +msgid "OK (ran for %1)" +msgstr "OK (procede al %1)" + +#: src/lib/filter.cc:91 +msgid "Overcomplete wavelet denoiser" +msgstr "Overcomplete wavelet denoiser" + +#: src/lib/dcp_content_type.cc:51 +msgid "Policy" +msgstr "Politica" + +#: src/lib/dcp_content_type.cc:52 +msgid "Public Service Announcement" +msgstr "Annuncio di pubblico servizio" + +#: src/lib/dcp_content_type.cc:49 +msgid "Rating" +msgstr "Punteggio" + +#: src/lib/util.cc:458 +msgid "Rec 709" +msgstr "Rec 709" + +#: src/lib/scp_dcp_job.cc:133 +msgid "SSH error (%1)" +msgstr "Errore SSH (%1)" + +#: src/lib/format.cc:125 +msgid "Scope" +msgstr "Scope" + +#: src/lib/format.cc:135 +msgid "Scope without stretch" +msgstr "Scope senza stiramento" + +#: src/lib/dcp_content_type.cc:45 +msgid "Short" +msgstr "Corto" + +#: src/lib/scaler.cc:67 +msgid "Sinc" +msgstr "Sinc" + +#: src/lib/format.cc:76 +msgid "Source scaled to 1.19:1" +msgstr "Sorgente scalato a 1.19:1" + +#: src/lib/format.cc:81 +msgid "Source scaled to 1.33:1" +msgstr "Sorgente scalato a 1.33:1" + +#: src/lib/format.cc:91 +msgid "Source scaled to 1.33:1 then pillarboxed to Flat" +msgstr "Sorgente scalato a 1.33:1 e poi inviato come Flat" + +#: src/lib/format.cc:86 +msgid "Source scaled to 1.375:1" +msgstr "Sorgente scalato a 1.375:1" + +#: src/lib/format.cc:96 +msgid "Source scaled to 1.37:1 (Academy ratio)" +msgstr "Sorgente scalato a 1.37:1 (Academy ratio)" + +#: src/lib/format.cc:101 +msgid "Source scaled to 1.66:1" +msgstr "Sorgente scalato a 1.66:1" + +#: src/lib/format.cc:106 +msgid "Source scaled to 1.66:1 then pillarboxed to Flat" +msgstr "Sorgente scalato a 1.66:1 e poi inviato come Flat" + +#: src/lib/format.cc:116 +msgid "Source scaled to 1.78:1" +msgstr "Sorgente scalato a 1.78:1" + +#: src/lib/format.cc:111 +msgid "Source scaled to 1.78:1 then pillarboxed to Flat" +msgstr "Sorgente scalato a 1.78:1 e poi inviato come Flat" + +#: src/lib/format.cc:121 +msgid "Source scaled to Flat (1.85:1)" +msgstr "Sorgente scalato a Flat (1.85:1)" + +#: src/lib/format.cc:126 +msgid "Source scaled to Scope (2.39:1)" +msgstr "Sorgente scalato a Scope (2.39:1)" + +#: src/lib/format.cc:131 +msgid "Source scaled to fit Flat preserving its aspect ratio" +msgstr "Sorgente scalato per adattarsi a Flat mantentendo le sue proporzioni" + +#: src/lib/format.cc:136 +msgid "Source scaled to fit Scope preserving its aspect ratio" +msgstr "Sorgente scalato per adattarsi a Scope mantentendo le sue proporzioni" + +#: src/lib/scaler.cc:68 +msgid "Spline" +msgstr "Spline" + +#: src/lib/dcp_content_type.cc:50 +msgid "Teaser" +msgstr "Teaser" + +#: src/lib/filter.cc:90 +msgid "Telecine filter" +msgstr "Filtro telecinema" + +#: src/lib/filter.cc:84 +msgid "Temporal noise reducer" +msgstr "Riduttore temporale di rumore" + +#: src/lib/dcp_content_type.cc:47 +msgid "Test" +msgstr "Prova" + +#: src/lib/job.cc:76 +msgid "" +"The drive that the film is stored on is low in disc space. Free some more " +"space and try again." +msgstr "" +"Il disco dove è memorizzato il film ha poco spazio a disposizione. Liberare " +"altro spazio e riprovare." + +#: src/lib/dcp_content_type.cc:46 +msgid "Trailer" +msgstr "Prossimamente" + +#: src/lib/transcode_job.cc:54 +msgid "Transcode %1" +msgstr "Transcodifica %1" + +#: src/lib/dcp_content_type.cc:48 +msgid "Transitional" +msgstr "Di transizione" + +#: src/lib/job.cc:95 +msgid "Unknown error" +msgstr "Errore sconosciuto" + +#: src/lib/ffmpeg_decoder.cc:396 +msgid "Unrecognised audio sample format (%1)" +msgstr "Formato di campionamento audio non riconosciuto (%1)" + +#: src/lib/filter.cc:87 +msgid "Unsharp mask and Gaussian blur" +msgstr "Maschera unsharp e sfocatura Gaussiana" + +#: src/lib/filter.cc:69 +msgid "Vertical deblocking filter" +msgstr "Filtro di sblocco verticale" + +#: src/lib/filter.cc:71 +msgid "Vertical deblocking filter A" +msgstr "Filtro A di sblocco verticale" + +#: src/lib/scp_dcp_job.cc:101 +msgid "Waiting" +msgstr "Aspetta" + +#: src/lib/scaler.cc:63 +msgid "X" +msgstr "X" + +#: src/lib/filter.cc:83 +msgid "Yet Another Deinterlacing Filter" +msgstr "Ancora un altro filtro di deinterlacciamento" + +#: src/lib/encoder.cc:271 +msgid "adding to queue of %1" +msgstr "aggiungo alla coda %1" + +#: src/lib/film.cc:263 +msgid "cannot contain slashes" +msgstr "non può contenere barre" + +#: src/lib/util.cc:499 +msgid "connect timed out" +msgstr "connessione scaduta" + +#: src/lib/scp_dcp_job.cc:119 +msgid "connecting" +msgstr "mi sto connettendo" + +#: src/lib/film.cc:300 +msgid "content" +msgstr "contenuto" + +#: src/lib/film.cc:304 +msgid "content type" +msgstr "tipo di contenuto" + +#: src/lib/scp_dcp_job.cc:168 +msgid "copying %1" +msgstr "copia %1" + +#: src/lib/ffmpeg_decoder.cc:191 +msgid "could not find audio decoder" +msgstr "non riesco a trovare il decoder audio" + +#: src/lib/ffmpeg_decoder.cc:118 +msgid "could not find stream information" +msgstr "non riesco a trovare informazioni sullo streaming" + +#: src/lib/ffmpeg_decoder.cc:210 +msgid "could not find subtitle decoder" +msgstr "non riesco a trovare il decoder dei sottotitoli" + +#: src/lib/ffmpeg_decoder.cc:169 +msgid "could not find video decoder" +msgstr "non riesco a trovare il decoder video" + +#: src/lib/external_audio_decoder.cc:72 +msgid "could not open external audio file for reading" +msgstr "non riesco ad aprire il file dell'audio esterno per leggerlo" + +#: src/lib/dcp_video_frame.cc:388 +msgid "could not open file for reading" +msgstr "non riesco ad aprire il file per leggerlo" + +#: src/lib/encoder.cc:137 src/lib/encoder.cc:314 +msgid "could not run sample-rate converter" +msgstr "non riesco a lanciare il convertitore della frequenza di campionamento" + +#: src/lib/scp_dcp_job.cc:86 +msgid "could not start SCP session (%1)" +msgstr "non posso avviare la sessione SCP (%1)" + +#: src/lib/scp_dcp_job.cc:52 +msgid "could not start SSH session" +msgstr "non posso avviare la sessione SSH" + +#: src/lib/encoder.cc:247 +msgid "decoder sleeps with queue of %1" +msgstr "il decoder è in pausa con la coda di %1" + +#: src/lib/encoder.cc:249 +msgid "decoder wakes with queue of %1" +msgstr "il decoder riparte con la coda di %1" + +#: src/lib/external_audio_decoder.cc:94 +msgid "external audio files have differing lengths" +msgstr "i files dell'audio esterno hanno durata diversa" + +#: src/lib/external_audio_decoder.cc:76 +msgid "external audio files must be mono" +msgstr "i files dell'audio esterno devono essere mono" + +#: src/lib/film.cc:296 +msgid "format" +msgstr "formato" + +#: src/lib/transcode_job.cc:100 +msgid "frames per second" +msgstr "fotogrammi al secondo" + +#: src/lib/util.cc:115 +msgid "hour" +msgstr "ora" + +#: src/lib/util.cc:112 src/lib/util.cc:117 +msgid "hours" +msgstr "ore" + +#: src/lib/util.cc:122 +msgid "minute" +msgstr "minuto" + +#: src/lib/util.cc:124 +msgid "minutes" +msgstr "minuti" + +#: src/lib/util.cc:642 +msgid "missing key %1 in key-value set" +msgstr "persa la chiave %1 tra i valori chiave" + +#: src/lib/subtitle.cc:52 +msgid "multi-part subtitles not yet supported" +msgstr "sottotitoli multi-part non ancora supportati" + +#: src/lib/film.cc:263 src/lib/film.cc:308 +msgid "name" +msgstr "nome" + +#: src/lib/imagemagick_decoder.cc:60 +msgid "no still image files found" +msgstr "file del fermo immagine non trovati" + +#: src/lib/subtitle.cc:58 +msgid "non-bitmap subtitles not yet supported" +msgstr "sottotitoli non-bitmap non ancora supportati" + +#. / TRANSLATORS: remaining here follows an amount of time that is remaining +#. / on an operation. +#: src/lib/job.cc:282 +msgid "remaining" +msgstr "restano" + +#: src/lib/util.cc:456 +msgid "sRGB" +msgstr "sRGB" + +#: src/lib/util.cc:127 +msgid "seconds" +msgstr "secondi" + +#: src/lib/film.cc:274 +msgid "still" +msgstr "ancora" + +#: src/lib/film.cc:274 +msgid "video" +msgstr "video" diff --git a/src/tools/po/it_IT.po b/src/tools/po/it_IT.po new file mode 100644 index 000000000..0886f3cb3 --- /dev/null +++ b/src/tools/po/it_IT.po @@ -0,0 +1,115 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: IT VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-03-15 08:39+0000\n" +"PO-Revision-Date: 2013-03-18 15:20+0100\n" +"Last-Translator: Maci \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.5.5\n" +"Language: Italiano\n" + +#: src/tools/dvdomatic.cc:177 +msgid "&Analyse audio" +msgstr "&Analizza audio" + +#: src/tools/dvdomatic.cc:183 +msgid "&Edit" +msgstr "&Modifica" + +#: src/tools/dvdomatic.cc:182 +msgid "&File" +msgstr "&File" + +#: src/tools/dvdomatic.cc:185 +msgid "&Help" +msgstr "&Aiuto" + +#: src/tools/dvdomatic.cc:184 +msgid "&Jobs" +msgstr "&Lavori" + +#: src/tools/dvdomatic.cc:173 +msgid "&Make DCP" +msgstr "&Crea DCP" + +#: src/tools/dvdomatic.cc:161 +msgid "&Open..." +msgstr "&Apri..." + +#: src/tools/dvdomatic.cc:170 +msgid "&Preferences..." +msgstr "&Preferenze..." + +#: src/tools/dvdomatic.cc:165 +msgid "&Properties..." +msgstr "&Proprietà..." + +#: src/tools/dvdomatic.cc:167 +msgid "&Quit" +msgstr "&Esci" + +#: src/tools/dvdomatic.cc:163 +msgid "&Save" +msgstr "&Salva" + +#: src/tools/dvdomatic.cc:174 +msgid "&Send DCP to TMS" +msgstr "&Invia DCP a TMS" + +#: src/tools/dvdomatic.cc:409 +msgid "" +"(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" +msgstr "" +"(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" + +#: src/tools/dvdomatic.cc:180 +msgid "About" +msgstr "Informazioni" + +#: src/tools/dvdomatic.cc:497 +msgid "Could not load film %1 (%2)" +msgstr "Non posso caricare il film %1 (%2)" + +#: src/tools/dvdomatic.cc:331 +#, c-format +msgid "Could not open film at %s (%s)" +msgstr "Non posso aprire il film a %s (%s)" + +#: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:402 +#: src/tools/dvdomatic.cc:501 +msgid "DVD-o-matic" +msgstr "DVD-o-matic" + +#: src/tools/dvdomatic.cc:75 +msgid "Film changed" +msgstr "Film modificato" + +#: src/tools/dvdomatic.cc:408 +msgid "Free, open-source DCP generation from almost anything." +msgstr "Genera DCP da quasi tutto, free e open-source." + +#: src/tools/dvdomatic.cc:160 +msgid "New..." +msgstr "Nuovo" + +#: src/tools/dvdomatic.cc:175 +msgid "S&how DCP" +msgstr "&Mostra DCP" + +#: src/tools/dvdomatic.cc:319 +msgid "Select film to open" +msgstr "Seleziona il film da aprire" + +#: src/tools/dvdomatic.cc:303 +#, c-format +msgid "The directory %s already exists." +msgstr "La directory %s esiste già." diff --git a/src/wx/po/it_IT.po b/src/wx/po/it_IT.po new file mode 100644 index 000000000..c8fa5815a --- /dev/null +++ b/src/wx/po/it_IT.po @@ -0,0 +1,466 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: IT VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-03-15 08:39+0000\n" +"PO-Revision-Date: 2013-03-18 17:51+0100\n" +"Last-Translator: Maci \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.5.5\n" +"Language: Italiano\n" + +#: src/wx/film_editor.cc:441 +msgid "%" +msgstr "%" + +#: src/wx/film_editor.cc:1230 +msgid "1 channel" +msgstr "Canale 1" + +#: src/wx/film_editor.cc:185 +msgid "A/B" +msgstr "A/B" + +#: src/wx/config_dialog.cc:124 +msgid "Add" +msgstr "Aggiungi" + +#: src/wx/audio_dialog.cc:32 src/wx/film_editor.cc:78 +msgid "Audio" +msgstr "Audio" + +#: src/wx/film_editor.cc:382 +msgid "Audio Delay" +msgstr "Ritardo dell'audio" + +#: src/wx/film_editor.cc:370 +msgid "Audio Gain" +msgstr "Guadagno dell'audio" + +#: src/wx/dci_metadata_dialog.cc:33 +msgid "Audio Language (e.g. EN)" +msgstr "Lingua dell'audio (es. EN)" + +#: src/wx/job_wrapper.cc:38 +#, c-format +msgid "Bad setting for %s (%s)" +msgstr "Valore sbagliato per %s (%s)" + +#: src/wx/film_editor.cc:297 +msgid "Bottom crop" +msgstr "Taglio inferiore" + +#: src/wx/dir_picker_ctrl.cc:38 +msgid "Browse..." +msgstr "Sfoglia..." + +#: src/wx/gain_calculator_dialog.cc:36 +msgid "But I have to use fader" +msgstr "Ma devo usare il fader" + +#: src/wx/film_editor.cc:375 +msgid "Calculate..." +msgstr "Calcola..." + +#: src/wx/audio_dialog.cc:43 +msgid "Channels" +msgstr "Canali" + +#: src/wx/film_editor.cc:326 +msgid "Colour look-up table" +msgstr "Tabella per ricerca del colore" + +#: src/wx/film_editor.cc:121 +msgid "Content" +msgstr "Contenuto" + +#: src/wx/film_editor.cc:131 +msgid "Content Type" +msgstr "Tipo di contenuto" + +#: src/wx/film_viewer.cc:414 +#, c-format +msgid "Could not decode video for view (%s)" +msgstr "Non posso decodificare il video per guardarlo (%s)" + +#: src/wx/job_wrapper.cc:40 +#, c-format +msgid "Could not make DCP: %s" +msgstr "Non posso creare il DCP: %s" + +#: src/wx/film_viewer.cc:108 +#, c-format +msgid "Could not open content file (%s)" +msgstr "Non posso aprire il file del contenuto (%s)" + +#: src/wx/film_editor.cc:505 +#, c-format +msgid "Could not set content: %s" +msgstr "Non posso regolare il contenuto: %s" + +#: src/wx/new_film_dialog.cc:46 +msgid "Create in folder" +msgstr "Crea nella cartella" + +#: src/wx/dci_metadata_dialog.cc:28 +msgid "DCI name" +msgstr "Nome del DCP" + +#: src/wx/film_editor.cc:142 +msgid "DCP Frame Rate" +msgstr "Frequenza fotogrammi del DCP" + +#: src/wx/film_editor.cc:110 +msgid "DCP Name" +msgstr "Nome del DCP" + +#: src/wx/wx_util.cc:61 +msgid "DVD-o-matic" +msgstr "DVD-o-matic" + +#: src/wx/config_dialog.cc:44 +msgid "DVD-o-matic Preferences" +msgstr "Preferenze DVD-o-matic" + +#: src/wx/audio_dialog.cc:101 +msgid "DVD-o-matic audio - %1" +msgstr "Audio DVD-o-matic - %1" + +#: src/wx/config_dialog.cc:83 +msgid "Default DCI name details" +msgstr "Dettagli del nome di default DCI" + +#: src/wx/config_dialog.cc:74 +msgid "Default directory for new films" +msgstr "Directory di default per i nuovi films" + +#: src/wx/film_editor.cc:117 src/wx/job_manager_view.cc:88 +msgid "Details..." +msgstr "Dettagli" + +#: src/wx/properties_dialog.cc:45 +msgid "Disk space required" +msgstr "Spazio su disco rischiesto" + +#: src/wx/film_editor.cc:192 +msgid "Duration" +msgstr "Durata" + +#: src/wx/config_dialog.cc:126 +msgid "Edit" +msgstr "Modifica" + +#: src/wx/config_dialog.cc:84 src/wx/config_dialog.cc:103 +#: src/wx/film_editor.cc:309 +msgid "Edit..." +msgstr "Modifica..." + +#: src/wx/config_dialog.cc:109 +msgid "Encoding Servers" +msgstr "Servers di codifica" + +#: src/wx/film_editor.cc:177 +msgid "End" +msgstr "Fine" + +#: src/wx/dci_metadata_dialog.cc:53 +msgid "Facility (e.g. DLA)" +msgstr "Facility (es. DLA)" + +#: src/wx/film_editor.cc:74 +msgid "Film" +msgstr "Film" + +#: src/wx/properties_dialog.cc:36 +msgid "Film Properties" +msgstr "Proprietà del film" + +#: src/wx/new_film_dialog.cc:42 +msgid "Film name" +msgstr "Nome del film" + +#: src/wx/film_editor.cc:304 src/wx/filter_dialog.cc:32 +msgid "Filters" +msgstr "Filtri" + +#: src/wx/film_editor.cc:269 +msgid "Format" +msgstr "Formato" + +#: src/wx/properties_dialog.cc:41 +msgid "Frames" +msgstr "Fotogrammi" + +#: src/wx/properties_dialog.cc:49 +msgid "Frames already encoded" +msgstr "Fotogrammi già codificati" + +#: src/wx/gain_calculator_dialog.cc:27 +msgid "Gain Calculator" +msgstr "Calcolatore del guadagno" + +#: src/wx/properties_dialog.cc:59 +msgid "Gb" +msgstr "Gb" + +#: src/wx/server_dialog.cc:36 +msgid "Host name or IP address" +msgstr "Nome dell'Host o indirizzo IP" + +#: src/wx/film_editor.cc:1234 +msgid "Hz" +msgstr "Hz" + +#: src/wx/gain_calculator_dialog.cc:32 +msgid "I want to play this back at fader" +msgstr "Voglio riprodurrlo back at fader" + +#: src/wx/config_dialog.cc:113 +msgid "IP address" +msgstr "Indirizzo IP" + +#: src/wx/film_editor.cc:336 +msgid "JPEG2000 bandwidth" +msgstr "Banda passante JPEG2000" + +#: src/wx/film_editor.cc:282 +msgid "Left crop" +msgstr "Taglio sinistro" + +#: src/wx/film_editor.cc:165 +msgid "Length" +msgstr "Lunghezza" + +#: src/wx/film_editor.cc:340 +msgid "MBps" +msgstr "MBps" + +#: src/wx/dir_picker_ctrl.cc:52 +msgid "My Documents" +msgstr "Documenti" + +#: src/wx/film_editor.cc:105 +msgid "Name" +msgstr "Nome" + +#: src/wx/new_film_dialog.cc:33 +msgid "New Film" +msgstr "Nuovo Film" + +#: src/wx/film_editor.cc:306 src/wx/film_editor.cc:665 +msgid "None" +msgstr "Nessuno" + +#: src/wx/film_editor.cc:136 +msgid "Original Frame Rate" +msgstr "Frequenza Fotogrammi Originale" + +#: src/wx/film_editor.cc:160 +msgid "Original Size" +msgstr "Dimensione Originale" + +#: src/wx/dci_metadata_dialog.cc:57 +msgid "Package Type (e.g. OV)" +msgstr "Tipo di Package (es. OV)" + +#: src/wx/audio_dialog.cc:60 +msgid "Peak" +msgstr "Picco" + +#: src/wx/film_viewer.cc:54 +msgid "Play" +msgstr "Riproduci" + +#: src/wx/audio_plot.cc:109 +msgid "Please wait; audio is being analysed..." +msgstr "Attendere prego; sto analizzando l'audio..." + +#: src/wx/audio_dialog.cc:61 +msgid "RMS" +msgstr "RMS" + +#: src/wx/dci_metadata_dialog.cc:45 +msgid "Rating (e.g. 15)" +msgstr "Classificazione (es. 15)" + +#: src/wx/config_dialog.cc:99 +msgid "Reference filters for A/B" +msgstr "Riferimento dei filtri per A/B" + +#: src/wx/config_dialog.cc:88 +msgid "Reference scaler for A/B" +msgstr "Scalatura di riferimento per A/B" + +#: src/wx/config_dialog.cc:128 +msgid "Remove" +msgstr "Rimuovi" + +#: src/wx/film_editor.cc:287 +msgid "Right crop" +msgstr "Taglio destro" + +#: src/wx/job_manager_view.cc:104 +msgid "Running" +msgstr "In corso" + +#: src/wx/film_editor.cc:316 +msgid "Scaler" +msgstr "Scaler" + +#: src/wx/film_editor.cc:408 +msgid "Select Audio File" +msgstr "Seleziona File Audio" + +#: src/wx/film_editor.cc:122 +msgid "Select Content File" +msgstr "Seleziona FIle del Contenuto" + +#: src/wx/server_dialog.cc:25 +msgid "Server" +msgstr "Server" + +#: src/wx/film_editor.cc:365 +msgid "Show Audio..." +msgstr "Mostra Audio..." + +#: src/wx/audio_dialog.cc:71 +msgid "Smoothing" +msgstr "Levigatura" + +#: src/wx/film_editor.cc:174 +msgid "Start" +msgstr "Avvio" + +#: src/wx/dci_metadata_dialog.cc:49 +msgid "Studio (e.g. TCF)" +msgstr "Studio (es. TCF)" + +#: src/wx/dci_metadata_dialog.cc:37 +msgid "Subtitle Language (e.g. FR)" +msgstr "Lingua dei Sottotitoli (es. FR)" + +#: src/wx/film_editor.cc:432 +msgid "Subtitle Offset" +msgstr "Sfalsamento dei Sottotitoli" + +#: src/wx/film_editor.cc:437 +msgid "Subtitle Scale" +msgstr "Scala dei Sottotitoli" + +#: src/wx/film_editor.cc:80 +msgid "Subtitles" +msgstr "Sottotitoli" + +#: src/wx/config_dialog.cc:49 +msgid "TMS IP address" +msgstr "Indirizzo IP del TMS" + +#: src/wx/config_dialog.cc:64 +msgid "TMS password" +msgstr "Password del TMS" + +#: src/wx/config_dialog.cc:54 +msgid "TMS target path" +msgstr "Percorso di destinazione del TMS" + +#: src/wx/config_dialog.cc:59 +msgid "TMS user name" +msgstr "Nome utente del TMS" + +#: src/wx/dci_metadata_dialog.cc:41 +msgid "Territory (e.g. UK)" +msgstr "Nazione (es. UK)" + +#: src/wx/config_dialog.cc:117 +msgid "Threads" +msgstr "Threads" + +#: src/wx/server_dialog.cc:40 +msgid "Threads to use" +msgstr "Threads da usare" + +#: src/wx/config_dialog.cc:69 +msgid "Threads to use for encoding on this host" +msgstr "Threads da usare per codificare su questo host" + +#: src/wx/audio_plot.cc:139 +msgid "Time" +msgstr "Tempo" + +#: src/wx/film_editor.cc:292 +msgid "Top crop" +msgstr "Taglio superiore" + +#: src/wx/film_editor.cc:172 +msgid "Trim frames" +msgstr "Taglia fotogrammi" + +#: src/wx/film_editor.cc:126 +msgid "Trust content's header" +msgstr "Conferma l'intestazione del contenuto" + +#: src/wx/audio_dialog.cc:55 +msgid "Type" +msgstr "Tipo" + +#: src/wx/film_editor.cc:115 +msgid "Use DCI name" +msgstr "Usa nome DCI" + +#: src/wx/film_editor.cc:146 +msgid "Use best" +msgstr "Usa il migliore" + +#: src/wx/film_editor.cc:392 +msgid "Use content's audio" +msgstr "Usa l'audio del contenuto" + +#: src/wx/film_editor.cc:402 +msgid "Use external audio" +msgstr "Usa l'audio esterno" + +#: src/wx/film_editor.cc:76 +msgid "Video" +msgstr "Video" + +#: src/wx/film_editor.cc:425 +msgid "With Subtitles" +msgstr "Con Sottotitoli" + +#: src/wx/film_editor.cc:1232 +msgid "channels" +msgstr "canali" + +#: src/wx/properties_dialog.cc:50 +msgid "counting..." +msgstr "conteggio..." + +#: src/wx/film_editor.cc:374 +msgid "dB" +msgstr "dB" + +#: src/wx/film_editor.cc:691 src/wx/film_editor.cc:693 +msgid "frames" +msgstr "fotogrammi" + +#. / TRANSLATORS: this is an abbreviation for milliseconds, the unit of time +#: src/wx/film_editor.cc:387 +msgid "ms" +msgstr "ms" + +#. / TRANSLATORS: `s' here is an abbreviation for seconds, the unit of time +#: src/wx/film_editor.cc:198 +msgid "s" +msgstr "s" + +#: src/wx/properties_dialog.cc:62 src/wx/properties_dialog.cc:63 +msgid "unknown" +msgstr "sconosciuto" diff --git a/windows/installer.nsi.32.in b/windows/installer.nsi.32.in index 5383907d5..8eb8db9e4 100644 --- a/windows/installer.nsi.32.in +++ b/windows/installer.nsi.32.in @@ -94,9 +94,12 @@ SetOutPath "$PROFILE\.magick" File "%deps%/etc/ImageMagick/delegates.xml" SetOutPath "$INSTDIR\bin\fr_FR" - -File "%binaries%/src/tools/mo/fr_FR/dvdomatic.mo" File "%binaries%/src/lib/mo/fr_FR/libdvdomatic.mo" +File "%binaries%/src/tools/mo/fr_FR/dvdomatic.mo" +SetOutPath "$INSTDIR\bin\it_IT" +File "%binaries%/src/lib/mo/it_IT/libdvdomatic.mo" +File "%binaries%/src/wx/mo/it_IT/libdvdomatic.mo" +File "%binaries%/src/tools/mo/it_IT/dvdomatic.mo" CreateShortCut "$DESKTOP\DVD-o-matic.lnk" "$INSTDIR\bin\dvdomatic.exe" "" CreateShortCut "$DESKTOP\DVD-o-matic encode server.lnk" "$INSTDIR\bin\servomatic_gui.exe" "" diff --git a/windows/installer.nsi.64.in b/windows/installer.nsi.64.in index 5b3f48546..cb92153ef 100644 --- a/windows/installer.nsi.64.in +++ b/windows/installer.nsi.64.in @@ -104,9 +104,13 @@ SetOutPath "$PROFILE\.magick" File "%deps%/etc/ImageMagick/delegates.xml" SetOutPath "$INSTDIR\bin\fr_FR" - -File "%binaries%/src/tools/mo/fr_FR/dvdomatic.mo" File "%binaries%/src/lib/mo/fr_FR/libdvdomatic.mo" +File "%binaries%/src/tools/mo/fr_FR/dvdomatic.mo" + +SetOutPath "$INSTDIR\bin\it_IT" +File "%binaries%/src/lib/mo/it_IT/libdvdomatic.mo" +File "%binaries%/src/wx/mo/it_IT/libdvdomatic.mo" +File "%binaries%/src/tools/mo/it_IT/dvdomatic.mo" CreateShortCut "$DESKTOP\DVD-o-matic.lnk" "$INSTDIR\bin\dvdomatic.exe" "" CreateShortCut "$DESKTOP\DVD-o-matic encode server.lnk" "$INSTDIR\bin\servomatic_gui.exe" "" -- cgit v1.2.3 From 82628368addd017a922c54fbf4a2a379ba9a1e81 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 19 Mar 2013 20:46:07 +0000 Subject: Add more translator credits. --- src/tools/dvdomatic.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 084e0fff7..6196f8a16 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -417,6 +417,9 @@ private: wxArrayString translators; translators.Add (wxT ("Olivier (freedcp.net)")); + translators.Add (wxT ("Lilian Lefranc")); + translators.Add (wxT ("Thierry Journet")); + translators.Add (wxT ("Massimiliano Broggi")); info.SetTranslators (translators); info.SetWebSite (wxT ("http://carlh.net/software/dvdomatic")); -- cgit v1.2.3 From 581ff020c77d8b24eb5521e137871ebf7061c74a Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 20 Mar 2013 10:05:28 +0000 Subject: Fix Olivier's name in the translation credits. --- src/tools/dvdomatic.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 6196f8a16..d0e4dd1f2 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -416,7 +416,7 @@ private: info.SetDevelopers (authors); wxArrayString translators; - translators.Add (wxT ("Olivier (freedcp.net)")); + translators.Add (wxT ("Olivier Perriere (freedcp.net)")); translators.Add (wxT ("Lilian Lefranc")); translators.Add (wxT ("Thierry Journet")); translators.Add (wxT ("Massimiliano Broggi")); -- cgit v1.2.3 From 8dcf4f4b9a8eb2642cb8bc6b68f228d4e8f982c7 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 20 Mar 2013 10:07:07 +0000 Subject: Updated French translation. --- src/lib/po/fr_FR.po | 188 +++++++++++++++++++++++++------------------------- src/tools/po/fr_FR.po | 34 +++++---- src/wx/po/fr_FR.po | 130 +++++++++++++++++----------------- 3 files changed, 173 insertions(+), 179 deletions(-) (limited to 'src') diff --git a/src/lib/po/fr_FR.po b/src/lib/po/fr_FR.po index 7e4744397..887c79862 100644 --- a/src/lib/po/fr_FR.po +++ b/src/lib/po/fr_FR.po @@ -8,15 +8,13 @@ msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-03-05 13:49+0000\n" -"PO-Revision-Date: 2013-03-13 00:23+0100\n" +"PO-Revision-Date: 2013-03-20 00:39+0100\n" "Last-Translator: FreeDCP.net \n" -"Language-Team: FreeDCP.net \n" +"Language-Team: \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Poedit-Language: French\n" -"X-Poedit-Country: FRANCE\n" #: src/lib/transcode_job.cc:90 msgid "0%" @@ -52,7 +50,7 @@ msgstr "16:9 dans Flat" #: src/lib/filter.cc:88 msgid "3D denoiser" -msgstr "3D denoiser" +msgstr "D??bruitage 3D" #: src/lib/format.cc:90 msgid "4:3 within Flat" @@ -60,7 +58,7 @@ msgstr "4:3 dans Flat" #: src/lib/ab_transcode_job.cc:49 msgid "A/B transcode %1" -msgstr "A/B transcode %1" +msgstr "Transcodage A/B %1" #: src/lib/format.cc:95 msgid "Academy" @@ -72,7 +70,7 @@ msgstr "Advertisement" #: src/lib/job.cc:71 msgid "An error occurred whilst handling the file %1." -msgstr "Une erreur s'est produite durant le traitement du fichier %1." +msgstr "Une erreur s'est produite lors du traitement du fichier %1." #: src/lib/analyse_audio_job.cc:48 msgid "Analyse audio of %1" @@ -84,15 +82,15 @@ msgstr "Area" #: src/lib/scaler.cc:62 msgid "Bicubic" -msgstr "Bicubic" +msgstr "Bicubique" #: src/lib/scaler.cc:69 msgid "Bilinear" -msgstr "Bilinear" +msgstr "Bilin??aire" #: src/lib/encoder.cc:101 msgid "Cannot resample audio as libswresample is not present" -msgstr "Ne peux pas re-échantillonner le son car libswresample n'est pas présent." +msgstr "R??-??chantillonnage du son impossible : libswresample est absent" #: src/lib/scp_dcp_job.cc:109 msgid "Copy DCP to TMS" @@ -100,39 +98,39 @@ msgstr "Copier le DCP dans le TMS" #: src/lib/scp_dcp_job.cc:128 msgid "Could not connect to server %1 (%2)" -msgstr "Ne peux pas se connecter au serveur %1 (%2)" +msgstr "Connexion au serveur %1 (%2) impossible" #: src/lib/scp_dcp_job.cc:150 msgid "Could not create remote directory %1 (%2)" -msgstr "Ne peux pas créer le dossier distant %1 (%2)" +msgstr "Cr??ation du dossier distant %1 (%2) impossible" #: src/lib/scp_dcp_job.cc:175 msgid "Could not open %1 to send" -msgstr "Ne peux pas ouvrir %1 pour envoyer" +msgstr "Ouverture de %1 pour envoi impossible" #: src/lib/scp_dcp_job.cc:145 msgid "Could not start SCP session (%1)" -msgstr "Ne peux pas démarrer la session SCP (%1)" +msgstr "D??marrage de session SCP (%1) impossible" #: src/lib/scp_dcp_job.cc:187 msgid "Could not write to remote file (%1)" -msgstr "Ne peux pas écrire le fichier distant (%1)" +msgstr "??criture vers fichier distant (%1) impossible" #: src/lib/filter.cc:77 msgid "Cubic interpolating deinterlacer" -msgstr "Cubic interpolating deinterlacer" +msgstr "D??sentrelacement cubique interpol??" #: src/lib/util.cc:965 msgid "DCP and source have the same rate.\n" -msgstr "Le DCP et la source ont le même taux.\n" +msgstr "Le DCP et la source ont les m??mes cadences.\n" #: src/lib/util.cc:975 msgid "DCP will run at %1%% of the source speed." -msgstr "Le DCP va tourner à la vitesse %1%% de la source." +msgstr "La cadence du DCP sera %1%% par rapport ?? la source" #: src/lib/util.cc:968 msgid "DCP will use every other frame of the source.\n" -msgstr "Le DCP utilisera toutes les autres images de la source.\n" +msgstr "Le DCP utilisera une image sur deux de la source.\n" #: src/lib/filter.cc:68 #: src/lib/filter.cc:69 @@ -141,7 +139,7 @@ msgstr "Le DCP utilisera toutes les autres images de la source.\n" #: src/lib/filter.cc:72 #: src/lib/filter.cc:73 msgid "De-blocking" -msgstr "De-blocking" +msgstr "De-bloc" #: src/lib/filter.cc:75 #: src/lib/filter.cc:76 @@ -153,11 +151,11 @@ msgstr "De-blocking" #: src/lib/filter.cc:82 #: src/lib/filter.cc:83 msgid "De-interlacing" -msgstr "De-interlacing" +msgstr "D??sentrelacement" #: src/lib/filter.cc:74 msgid "Deringing filter" -msgstr "Deringing filter" +msgstr "Filtre anti bourdonnement" #: src/lib/dolby_cp750.cc:27 msgid "Dolby CP750" @@ -165,7 +163,7 @@ msgstr "Dolby CP750" #: src/lib/util.cc:970 msgid "Each source frame will be doubled in the DCP.\n" -msgstr "Chaque image source sera doublée dans le DCP.\n" +msgstr "Chaque image source sera dupliqu??e dans le DCP.\n" #: src/lib/job.cc:287 msgid "Error (%1)" @@ -173,35 +171,35 @@ msgstr "Erreur (%1)" #: src/lib/examine_content_job.cc:55 msgid "Examine content" -msgstr "Examine le contenu" +msgstr "Examen du contenu" #: src/lib/examine_content_job.cc:58 msgid "Examine content of %1" -msgstr "Examine le contenu de %1" +msgstr "Examen du contenu de %1" #: src/lib/filter.cc:72 msgid "Experimental horizontal deblocking filter 1" -msgstr "Experimental horizontal deblocking filter 1" +msgstr "Filtre d??-bloc horizontal 1" #: src/lib/filter.cc:73 msgid "Experimental vertical deblocking filter 1" -msgstr "Experimental vertical deblocking filter 1" +msgstr "Filtre d??-bloc vertical 1" #: src/lib/filter.cc:79 msgid "FFMPEG deinterlacer" -msgstr "FFMPEG deinterlacer" +msgstr "D??sentrelaceur FFMPEG" #: src/lib/filter.cc:80 msgid "FIR low-pass deinterlacer" -msgstr "FIR low-pass deinterlacer" +msgstr "D??sentrelaceur passe-bas FIR" #: src/lib/scp_dcp_job.cc:138 msgid "Failed to authenticate with server (%1)" -msgstr "L'authentification avec le serveur (%1) a échouée" +msgstr "L'authentification du serveur (%1) a ??chou??e" #: src/lib/scaler.cc:70 msgid "Fast Bilinear" -msgstr "Fast Bilinear" +msgstr "Bilin??aire rapide" #: src/lib/dcp_content_type.cc:44 msgid "Feature" @@ -213,40 +211,40 @@ msgstr "Flat" #: src/lib/format.cc:130 msgid "Flat without stretch" -msgstr "Flat sans étirement" +msgstr "Flat sans ??tirement" #: src/lib/filter.cc:85 msgid "Force quantizer" -msgstr "Force quantizer" +msgstr "Forcer la quantification" #: src/lib/scaler.cc:65 msgid "Gaussian" -msgstr "Gaussian" +msgstr "Gaussien" #: src/lib/filter.cc:86 msgid "Gradient debander" -msgstr "Gradient debander" +msgstr "Corrections des bandes du d??grad??" #: src/lib/filter.cc:89 msgid "High quality 3D denoiser" -msgstr "High quality 3D denoiser" +msgstr "D??bruiteur 3D haute qualit??" #: src/lib/filter.cc:68 msgid "Horizontal deblocking filter" -msgstr "Horizontal deblocking filter" +msgstr "Filtre d??bloc horizontal" #: src/lib/filter.cc:70 msgid "Horizontal deblocking filter A" -msgstr "Horizontal deblocking filter A" +msgstr "Filtre d??-bloc horizontal" #: src/lib/job.cc:87 #: src/lib/job.cc:96 msgid "It is not known what caused this error. The best idea is to report the problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" -msgstr "La cause de l’erreur n'est pas connue. La meilleure chose est de reporter le problème à la liste de discutions de DCD-o-matic (dvdomatic@carlh.net)" +msgstr "Erreur ind??termin??e. Merci de rapporter le probl??me ?? la liste DVD-o-matic (dvdomatic@carlh.net)" #: src/lib/filter.cc:82 msgid "Kernel deinterlacer" -msgstr "Kernel deinterlacer" +msgstr "D??sentrelaceur noyau" #: src/lib/scaler.cc:66 msgid "Lanczos" @@ -254,15 +252,15 @@ msgstr "Lanczos" #: src/lib/filter.cc:75 msgid "Linear blend deinterlacer" -msgstr "Linear blend deinterlacer" +msgstr "D??sentrelaceur par m??lange interpol??" #: src/lib/filter.cc:76 msgid "Linear interpolating deinterlacer" -msgstr "Linear interpolating deinterlacer" +msgstr "D??sentrelaceur lin??aire interpol??" #: src/lib/filter.cc:78 msgid "Median deinterlacer" -msgstr "Median deinterlacer" +msgstr "D??sentrelaceur m??dian" #: src/lib/filter.cc:74 #: src/lib/filter.cc:85 @@ -274,22 +272,22 @@ msgstr "Divers" #: src/lib/filter.cc:81 msgid "Motion compensating deinterlacer" -msgstr "Motion compensating deinterlacer" +msgstr "D??sentrelaceur par compensation de mouvement" #: src/lib/filter.cc:84 #: src/lib/filter.cc:88 #: src/lib/filter.cc:89 #: src/lib/filter.cc:91 msgid "Noise reduction" -msgstr "Noise reduction" +msgstr "R??duction de bruit" #: src/lib/job.cc:285 msgid "OK (ran for %1)" -msgstr "OK (effectuer durant %1)" +msgstr "OK (processus %1)" #: src/lib/filter.cc:91 msgid "Overcomplete wavelet denoiser" -msgstr "Overcomplete wavelet denoiser" +msgstr "R??duction de bruit par ondelettes" #: src/lib/dcp_content_type.cc:51 msgid "Policy" @@ -317,7 +315,7 @@ msgstr "Scope" #: src/lib/format.cc:135 msgid "Scope without stretch" -msgstr "Scope sans étirement" +msgstr "Scope sans d??formation" #: src/lib/dcp_content_type.cc:45 msgid "Short" @@ -329,55 +327,55 @@ msgstr "Sinc" #: src/lib/format.cc:76 msgid "Source scaled to 1.19:1" -msgstr "Source mise à l'échelle en 1.19:1" +msgstr "Source mise ?? l'??chelle en 1.19:1" #: src/lib/format.cc:81 msgid "Source scaled to 1.33:1" -msgstr "Source mise à l'échelle en 1.33:1" +msgstr "Source mise ?? l'??chelle en 1.33:1" #: src/lib/format.cc:91 msgid "Source scaled to 1.33:1 then pillarboxed to Flat" -msgstr "Source mise à l'échelle en 1.33:1 et ensuite \"pillarboxed\" en Flat" +msgstr "Source mise ?? l'??chelle en 1.33:1 puis contenue dans Flat" #: src/lib/format.cc:86 msgid "Source scaled to 1.375:1" -msgstr "Source mise à l'échelle en 1.375:1" +msgstr "Source mise ?? l'??chelle en 1.375:1" #: src/lib/format.cc:96 msgid "Source scaled to 1.37:1 (Academy ratio)" -msgstr "Source mise à l'échelle en 1.37:1 (Academy ratio)" +msgstr "Source mise ?? l'??chelle en 1.37:1 (ratio \"academy\")" #: src/lib/format.cc:101 msgid "Source scaled to 1.66:1" -msgstr "Source mise à l'échelle en 1.66:1" +msgstr "Source mise ?? l'??chelle en 1.66:1" #: src/lib/format.cc:106 msgid "Source scaled to 1.66:1 then pillarboxed to Flat" -msgstr "Source mise à l'échelle en 1.66:1 et ensuite \"pillarboxed\" en Flat" +msgstr "Source mise ?? l'??chelle en 1.66:1 puis contenue dans Flat" #: src/lib/format.cc:116 msgid "Source scaled to 1.78:1" -msgstr "Source mise à l'échelle en 1.78:1" +msgstr "Source mise ?? l'??chelle en 1.78:1" #: src/lib/format.cc:111 msgid "Source scaled to 1.78:1 then pillarboxed to Flat" -msgstr "Source mise à l'échelle en 1.78:1 et ensuite \"pillarboxed\" en Flat" +msgstr "Source mise ?? l'??chelle en 1.78:1 puis contenue dans Flat" #: src/lib/format.cc:121 msgid "Source scaled to Flat (1.85:1)" -msgstr "Source mise à l'échelle en Flat (1.85:1)" +msgstr "Source mise ?? l'??chelle en Flat (1.85:1)" #: src/lib/format.cc:126 msgid "Source scaled to Scope (2.39:1)" -msgstr "Source mise à l'échelle en Scope (2.39:1)" +msgstr "Source mise ?? l'??chelle en Scope (2.39:1)" #: src/lib/format.cc:131 msgid "Source scaled to fit Flat preserving its aspect ratio" -msgstr "Source réduite en Flat afin de préserver ses dimensions" +msgstr "Source r??duite en Flat afin de pr??server ses dimensions" #: src/lib/format.cc:136 msgid "Source scaled to fit Scope preserving its aspect ratio" -msgstr "Source réduite en Scope afin de préserver ses dimensions" +msgstr "Source r??duite en Scope afin de pr??server ses dimensions" #: src/lib/scaler.cc:68 msgid "Spline" @@ -389,11 +387,11 @@ msgstr "Teaser" #: src/lib/filter.cc:90 msgid "Telecine filter" -msgstr "Telecine filter" +msgstr "Filtre t??l??cin??ma" #: src/lib/filter.cc:84 msgid "Temporal noise reducer" -msgstr "Temporal noise reducer" +msgstr "R??duction de bruit temporel" #: src/lib/dcp_content_type.cc:47 msgid "Test" @@ -401,7 +399,7 @@ msgstr "Test" #: src/lib/job.cc:76 msgid "The drive that the film is stored on is low in disc space. Free some more space and try again." -msgstr "Le disque sur lequel le film est stocké a peu d'espace libre. Libérez de la place et essayez à nouveau." +msgstr "Le disque contenant le film est plein. Lib??rez de l'espace et essayez ?? nouveau." #: src/lib/dcp_content_type.cc:46 msgid "Trailer" @@ -409,7 +407,7 @@ msgstr "Trailer" #: src/lib/transcode_job.cc:54 msgid "Transcode %1" -msgstr "Transcode %1" +msgstr "Transcodage %1" #: src/lib/dcp_content_type.cc:48 msgid "Transitional" @@ -421,23 +419,23 @@ msgstr "Erreur inconnue" #: src/lib/ffmpeg_decoder.cc:396 msgid "Unrecognised audio sample format (%1)" -msgstr "Format de son non reconnu (%1)" +msgstr "??chantillonnage audio (%1) inconnu" #: src/lib/filter.cc:87 msgid "Unsharp mask and Gaussian blur" -msgstr "Unsharp mask et Gaussian blur" +msgstr "Adoucissement et flou Gaussien" #: src/lib/filter.cc:69 msgid "Vertical deblocking filter" -msgstr "Vertical deblocking filter" +msgstr "Filtre d??-bloc vertical" #: src/lib/filter.cc:71 msgid "Vertical deblocking filter A" -msgstr "Vertical deblocking filter A" +msgstr "Filtre d??-bloc vertical A" #: src/lib/scp_dcp_job.cc:101 msgid "Waiting" -msgstr "Attendre" +msgstr "En cours" #: src/lib/scaler.cc:63 msgid "X" @@ -445,19 +443,19 @@ msgstr "X" #: src/lib/filter.cc:83 msgid "Yet Another Deinterlacing Filter" -msgstr "Yet Another Deinterlacing Filter" +msgstr "Un autre filtre de d??sentrelacement" #: src/lib/encoder.cc:271 msgid "adding to queue of %1" -msgstr "ajout à la queue de %1" +msgstr "Mise en file d'attente de %1" #: src/lib/film.cc:263 msgid "cannot contain slashes" -msgstr "ne peux pas contenir de slashs" +msgstr "slash interdit" #: src/lib/util.cc:499 msgid "connect timed out" -msgstr "connexion expirée" +msgstr "temps de connexion expir??" #: src/lib/scp_dcp_job.cc:119 msgid "connecting" @@ -473,60 +471,60 @@ msgstr "type de contenu" #: src/lib/scp_dcp_job.cc:168 msgid "copying %1" -msgstr "copie %1" +msgstr "copie de %1" #: src/lib/ffmpeg_decoder.cc:191 msgid "could not find audio decoder" -msgstr "ne trouve pas le décodeur son" +msgstr "d??codeur audio introuvable" #: src/lib/ffmpeg_decoder.cc:118 msgid "could not find stream information" -msgstr "ne peux pas trouver les informations sur le flux" +msgstr "information du flux introuvable" #: src/lib/ffmpeg_decoder.cc:210 msgid "could not find subtitle decoder" -msgstr "ne peux pas trouver de décodeur de sous-titres" +msgstr "d??codeur de sous-titre introuvable" #: src/lib/ffmpeg_decoder.cc:169 msgid "could not find video decoder" -msgstr "ne peux pas trouver de décodeur vidéo" +msgstr "d??codeur vid??o introuvable" #: src/lib/external_audio_decoder.cc:72 msgid "could not open external audio file for reading" -msgstr "ne peux pas ouvrir le fichier audio externe pour lecture" +msgstr "lecture du fichier audio externe impossible" #: src/lib/dcp_video_frame.cc:388 msgid "could not open file for reading" -msgstr "Ne peux pas ouvrir le fichier pour lecture" +msgstr "lecture du fichier impossible" #: src/lib/encoder.cc:137 #: src/lib/encoder.cc:314 msgid "could not run sample-rate converter" -msgstr "Ne peux pas lancer sample-rate converter" +msgstr "conversion de la fr??quence d'??chantillonnage impossible" #: src/lib/scp_dcp_job.cc:86 msgid "could not start SCP session (%1)" -msgstr "ne peux pas lancer de session SCP (%1)" +msgstr "d??marrage de session SCP (%1) impossible" #: src/lib/scp_dcp_job.cc:52 msgid "could not start SSH session" -msgstr "ne peux pas lancer de session SSH" +msgstr "d??marrage de session SSH impossible" #: src/lib/encoder.cc:247 msgid "decoder sleeps with queue of %1" -msgstr "le décodeur dort en attente de %1" +msgstr "d??codeur en veille avec %1 en file d'attente" #: src/lib/encoder.cc:249 msgid "decoder wakes with queue of %1" -msgstr "le décodeur se réveille en attente de %1" +msgstr "reprise du d??codage avec %1 en file d'attente" #: src/lib/external_audio_decoder.cc:94 msgid "external audio files have differing lengths" -msgstr "Les fichiers audio externes ont une durée différente." +msgstr "Les fichiers audio externes ont des dur??es diff??rentes" #: src/lib/external_audio_decoder.cc:76 msgid "external audio files must be mono" -msgstr "Les fichiers audio externes doivent être en mono" +msgstr "les fichiers audio externes doivent ??tre en mono" #: src/lib/film.cc:296 msgid "format" @@ -534,7 +532,7 @@ msgstr "format" #: src/lib/transcode_job.cc:103 msgid "frames per second" -msgstr "images par secondes" +msgstr "images par seconde" #: src/lib/util.cc:115 msgid "hour" @@ -555,11 +553,11 @@ msgstr "minutes" #: src/lib/util.cc:642 msgid "missing key %1 in key-value set" -msgstr "" +msgstr "cl?? %1 non s??lectionn??e" #: src/lib/subtitle.cc:52 msgid "multi-part subtitles not yet supported" -msgstr "sous-titres en plusieurs parties pas encore supportés" +msgstr "sous-titres en plusieurs parties non support??s" #: src/lib/film.cc:263 #: src/lib/film.cc:308 @@ -568,11 +566,11 @@ msgstr "nom" #: src/lib/imagemagick_decoder.cc:60 msgid "no still image files found" -msgstr "pas d'image fixe trouvée" +msgstr "aucune image fixe trouv??e" #: src/lib/subtitle.cc:58 msgid "non-bitmap subtitles not yet supported" -msgstr "sous-titres non-bitmap non supportés actuellement" +msgstr "sous-titres non-bitmap non support??s actuellement" #. / TRANSLATORS: remaining here follows an amount of time that is remaining #. / on an operation. @@ -590,9 +588,9 @@ msgstr "secondes" #: src/lib/film.cc:274 msgid "still" -msgstr "encore" +msgstr "fixe" #: src/lib/film.cc:274 msgid "video" -msgstr "vidéo" +msgstr "vid??o" diff --git a/src/tools/po/fr_FR.po b/src/tools/po/fr_FR.po index ccb4d7906..f38f07d6e 100644 --- a/src/tools/po/fr_FR.po +++ b/src/tools/po/fr_FR.po @@ -8,15 +8,13 @@ msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-03-05 13:49+0000\n" -"PO-Revision-Date: 2013-03-13 00:17+0100\n" -"Last-Translator: FreeDCP.net \n" -"Language-Team: FreeDCP.net \n" +"PO-Revision-Date: 2013-03-13 22:33+0100\n" +"Last-Translator: \n" +"Language-Team: \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Poedit-Language: French\n" -"X-Poedit-Country: FRANCE\n" #: src/tools/dvdomatic.cc:177 msgid "&Analyse audio" @@ -40,19 +38,19 @@ msgstr "&Travaux" #: src/tools/dvdomatic.cc:173 msgid "&Make DCP" -msgstr "&Créer le DCP" +msgstr "&Cr??er le DCP" #: src/tools/dvdomatic.cc:161 msgid "&Open..." -msgstr "&Ouvrir" +msgstr "&Ouvrir..." #: src/tools/dvdomatic.cc:170 msgid "&Preferences..." -msgstr "&Préférences..." +msgstr "&Pr??f??rences..." #: src/tools/dvdomatic.cc:165 msgid "&Properties..." -msgstr "&Propriétés..." +msgstr "&Propri??t??s..." #: src/tools/dvdomatic.cc:167 msgid "&Quit" @@ -60,7 +58,7 @@ msgstr "&Quitter" #: src/tools/dvdomatic.cc:163 msgid "&Save" -msgstr "&Sauver" +msgstr "&Enregistrer" #: src/tools/dvdomatic.cc:174 msgid "&Send DCP to TMS" @@ -72,16 +70,16 @@ msgstr "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole La #: src/tools/dvdomatic.cc:180 msgid "About" -msgstr "&A Propos" +msgstr "A Propos" #: src/tools/dvdomatic.cc:482 msgid "Could not load film %1 (%2)" -msgstr "Ne peux pas charger le film %1 (%2)" +msgstr "Impossible de charger le film %1 (%2)" #: src/tools/dvdomatic.cc:331 #, c-format msgid "Could not open film at %s (%s)" -msgstr "Ne peux pas ouvrir le film à %s (%s)" +msgstr "Impossible d'ouvrir le film ?? %s (%s)" #: src/tools/dvdomatic.cc:287 #: src/tools/dvdomatic.cc:402 @@ -91,11 +89,11 @@ msgstr "DVD-o-matic" #: src/tools/dvdomatic.cc:75 msgid "Film changed" -msgstr "Film changé" +msgstr "Film chang??" #: src/tools/dvdomatic.cc:408 msgid "Free, open-source DCP generation from almost anything." -msgstr "Outil libre et open-source de génération de DCP pour presque tous les formats." +msgstr "Cr??ation de DCP libre et open-source ?? partir de presque tout." #: src/tools/dvdomatic.cc:160 msgid "New..." @@ -103,14 +101,14 @@ msgstr "Nouveau..." #: src/tools/dvdomatic.cc:175 msgid "S&how DCP" -msgstr "Monter le DCP" +msgstr "Voir le DCP" #: src/tools/dvdomatic.cc:319 msgid "Select film to open" -msgstr "Sélectionner le film à ouvrir" +msgstr "S??lectionner le film ?? ouvrir" #: src/tools/dvdomatic.cc:303 #, c-format msgid "The directory %s already exists." -msgstr "Le dossier %s existe déjà." +msgstr "Le dossier %s existe d??j??." diff --git a/src/wx/po/fr_FR.po b/src/wx/po/fr_FR.po index 91bec71e8..55732911c 100644 --- a/src/wx/po/fr_FR.po +++ b/src/wx/po/fr_FR.po @@ -8,15 +8,13 @@ msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-03-05 13:49+0000\n" -"PO-Revision-Date: 2013-03-13 00:15+0100\n" +"PO-Revision-Date: 2013-03-20 00:34+0100\n" "Last-Translator: FreeDCP.net \n" -"Language-Team: FreeDCP.net \n" +"Language-Team: \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Poedit-Language: French\n" -"X-Poedit-Country: FRANCE\n" #: src/wx/film_editor.cc:441 msgid "%" @@ -37,36 +35,36 @@ msgstr "Ajouter" #: src/wx/audio_dialog.cc:32 #: src/wx/film_editor.cc:78 msgid "Audio" -msgstr "Son" +msgstr "Audio" #: src/wx/film_editor.cc:382 msgid "Audio Delay" -msgstr "Délai du Son" +msgstr "D??lai audio" #: src/wx/film_editor.cc:370 msgid "Audio Gain" -msgstr "Gain du Volume" +msgstr "Gain audio" #: src/wx/dci_metadata_dialog.cc:33 msgid "Audio Language (e.g. EN)" -msgstr "Langage Audio (ex. FR)" +msgstr "Langue audio (ex. FR)" #: src/wx/job_wrapper.cc:38 #, c-format msgid "Bad setting for %s (%s)" -msgstr "Mauvais réglage pour %s (%s)" +msgstr "Mauvais param??tre pour %s (%s)" #: src/wx/film_editor.cc:297 msgid "Bottom crop" -msgstr "Découpe bas" +msgstr "D??coupe bas" #: src/wx/dir_picker_ctrl.cc:38 msgid "Browse..." -msgstr "Naviguer..." +msgstr "Parcourir..." #: src/wx/gain_calculator_dialog.cc:36 msgid "But I have to use fader" -msgstr "Mais je dois utiliser ce volume" +msgstr "Je souhaite utiliser ce volume" #: src/wx/film_editor.cc:375 msgid "Calculate..." @@ -74,11 +72,11 @@ msgstr "Calcul..." #: src/wx/audio_dialog.cc:43 msgid "Channels" -msgstr "C anaux" +msgstr "Canaux" #: src/wx/film_editor.cc:326 msgid "Colour look-up table" -msgstr "" +msgstr "Espace colorim??trique" #: src/wx/film_editor.cc:121 msgid "Content" @@ -91,26 +89,26 @@ msgstr "Type de Contenu" #: src/wx/film_viewer.cc:414 #, c-format msgid "Could not decode video for view (%s)" -msgstr "Ne peux pas décoder la vidéo pour affichage (%s)" +msgstr "D??codage de la vid??o pour visualisation impossible (%s)" #: src/wx/job_wrapper.cc:40 #, c-format msgid "Could not make DCP: %s" -msgstr "Impossible de créer le DCP: %s" +msgstr "Impossible de cr??er le DCP : %s" #: src/wx/film_viewer.cc:108 #, c-format msgid "Could not open content file (%s)" -msgstr "Ne peux pas ouvrir le contenu (%s)" +msgstr "Ouverture du contenu impossible (%s)" #: src/wx/film_editor.cc:505 #, c-format msgid "Could not set content: %s" -msgstr "Ne peux pas sélectionner le contenu: %s" +msgstr "S??lectionner du contenu impossible : %s" #: src/wx/new_film_dialog.cc:46 msgid "Create in folder" -msgstr "Créer dans le dossier" +msgstr "Cr??er dans le dossier" #: src/wx/dci_metadata_dialog.cc:28 msgid "DCI name" @@ -118,7 +116,7 @@ msgstr "Nom DCI" #: src/wx/film_editor.cc:142 msgid "DCP Frame Rate" -msgstr "Fréquence d'images du DCP" +msgstr "Cadence image du DCP" #: src/wx/film_editor.cc:110 msgid "DCP Name" @@ -130,7 +128,7 @@ msgstr "DVD-o-matic" #: src/wx/config_dialog.cc:44 msgid "DVD-o-matic Preferences" -msgstr "Préférences DVD-o-matic" +msgstr "Pr??f??rences DVD-o-matic" #: src/wx/audio_dialog.cc:101 msgid "DVD-o-matic audio - %1" @@ -138,16 +136,16 @@ msgstr "Son DVD-o-matic - %1" #: src/wx/config_dialog.cc:83 msgid "Default DCI name details" -msgstr "Détails du nom DCI par défaut" +msgstr "D??tails du nom DCI par d??faut" #: src/wx/config_dialog.cc:74 msgid "Default directory for new films" -msgstr "Dossier par défaut des nouveaux films" +msgstr "Dossier par d??faut des nouveaux films" #: src/wx/film_editor.cc:117 #: src/wx/job_manager_view.cc:88 msgid "Details..." -msgstr "Détails..." +msgstr "D??tails..." #: src/wx/properties_dialog.cc:45 msgid "Disk space required" @@ -155,21 +153,21 @@ msgstr "Espace disque requis" #: src/wx/film_editor.cc:192 msgid "Duration" -msgstr "Durée" +msgstr "Dur??e" #: src/wx/config_dialog.cc:126 msgid "Edit" -msgstr "Édition" +msgstr "??dition" #: src/wx/config_dialog.cc:84 #: src/wx/config_dialog.cc:103 #: src/wx/film_editor.cc:309 msgid "Edit..." -msgstr "Éditer..." +msgstr "??diter..." #: src/wx/config_dialog.cc:109 msgid "Encoding Servers" -msgstr "Serveurs d'Encodage" +msgstr "Serveurs d'encodage" #: src/wx/film_editor.cc:177 msgid "End" @@ -185,11 +183,11 @@ msgstr "Film" #: src/wx/properties_dialog.cc:36 msgid "Film Properties" -msgstr "Propriétés du film" +msgstr "Propri??t??s du film" #: src/wx/new_film_dialog.cc:42 msgid "Film name" -msgstr "Nom du fichier" +msgstr "Nom du Film" #: src/wx/film_editor.cc:304 #: src/wx/filter_dialog.cc:32 @@ -206,11 +204,11 @@ msgstr "Images" #: src/wx/properties_dialog.cc:49 msgid "Frames already encoded" -msgstr "Images déjà encodées" +msgstr "Images d??j?? encod??es" #: src/wx/gain_calculator_dialog.cc:27 msgid "Gain Calculator" -msgstr "Calcul du Gain" +msgstr "Calculateur de gain" #: src/wx/properties_dialog.cc:59 msgid "Gb" @@ -218,7 +216,7 @@ msgstr "Gb" #: src/wx/server_dialog.cc:36 msgid "Host name or IP address" -msgstr "Nom d'hôte ou adresse IP" +msgstr "Nom de l'h??te ou adresse IP" #: src/wx/film_editor.cc:1230 msgid "Hz" @@ -226,7 +224,7 @@ msgstr "Hz" #: src/wx/gain_calculator_dialog.cc:32 msgid "I want to play this back at fader" -msgstr "Je veux le jouer à ce volume" +msgstr "Je veux le jouer ?? ce volume" #: src/wx/config_dialog.cc:113 msgid "IP address" @@ -234,11 +232,11 @@ msgstr "Adresse IP" #: src/wx/film_editor.cc:336 msgid "JPEG2000 bandwidth" -msgstr "Qualité JPEG2000" +msgstr "Qualit?? JPEG2000" #: src/wx/film_editor.cc:282 msgid "Left crop" -msgstr "Découpe gauche" +msgstr "D??coupe gauche" #: src/wx/film_editor.cc:165 msgid "Length" @@ -275,19 +273,19 @@ msgstr "Taille Originale" #: src/wx/dci_metadata_dialog.cc:57 msgid "Package Type (e.g. OV)" -msgstr "Type de Version (ex. OV)" +msgstr "Type de paquet (ex. OV)" #: src/wx/audio_dialog.cc:60 msgid "Peak" -msgstr "Pointe" +msgstr "Cr??te" #: src/wx/film_viewer.cc:54 msgid "Play" -msgstr "Jouer" +msgstr "Lecture" #: src/wx/audio_plot.cc:109 msgid "Please wait; audio is being analysed..." -msgstr "Merci de patienter; la piste son est analysée..." +msgstr "Merci de patienter ; analyse de la piste son..." #: src/wx/audio_dialog.cc:61 msgid "RMS" @@ -299,11 +297,11 @@ msgstr "Rating (ex. 15)" #: src/wx/config_dialog.cc:99 msgid "Reference filters for A/B" -msgstr "Filtres de référence pour A/B" +msgstr "Filtres de r??f??rence pour A/B" #: src/wx/config_dialog.cc:88 msgid "Reference scaler for A/B" -msgstr "Échelle de référence pour A7B" +msgstr "??chelle de r??f??rence pour A7B" #: src/wx/config_dialog.cc:128 msgid "Remove" @@ -311,7 +309,7 @@ msgstr "Supprimer" #: src/wx/film_editor.cc:287 msgid "Right crop" -msgstr "Découpe droite" +msgstr "D??coupe droite" #: src/wx/job_manager_view.cc:104 msgid "Running" @@ -319,15 +317,15 @@ msgstr "Progression" #: src/wx/film_editor.cc:316 msgid "Scaler" -msgstr "Mise à l'échelle" +msgstr "Mise ?? l'??chelle" #: src/wx/film_editor.cc:408 msgid "Select Audio File" -msgstr "Sélectionner le Fichier Son" +msgstr "S??lectionner le fichier son" #: src/wx/film_editor.cc:122 msgid "Select Content File" -msgstr "Sélectionner le fichier de Contenu" +msgstr "S??lectionner le fichier vid??o" #: src/wx/server_dialog.cc:25 msgid "Server" @@ -339,11 +337,11 @@ msgstr "Montrer le son..." #: src/wx/audio_dialog.cc:71 msgid "Smoothing" -msgstr "" +msgstr "Lissage" #: src/wx/film_editor.cc:174 msgid "Start" -msgstr "Début" +msgstr "D??but" #: src/wx/dci_metadata_dialog.cc:49 msgid "Studio (e.g. TCF)" @@ -351,19 +349,19 @@ msgstr "Studio (ex. TCF)" #: src/wx/dci_metadata_dialog.cc:37 msgid "Subtitle Language (e.g. FR)" -msgstr "Langue de Sous-titres (ex. FR)" +msgstr "Langue de sous-titres (ex. FR)" #: src/wx/film_editor.cc:432 msgid "Subtitle Offset" -msgstr "" +msgstr "D??calage du sous-titre" #: src/wx/film_editor.cc:437 msgid "Subtitle Scale" -msgstr "" +msgstr "Taille du sous-titre" #: src/wx/film_editor.cc:80 msgid "Subtitles" -msgstr "Sous-Titres" +msgstr "Sous-titres" #: src/wx/config_dialog.cc:49 msgid "TMS IP address" @@ -371,11 +369,11 @@ msgstr "Adresse IP du TMS" #: src/wx/config_dialog.cc:64 msgid "TMS password" -msgstr "Mot de Passe du TMS" +msgstr "Mot de passe du TMS" #: src/wx/config_dialog.cc:54 msgid "TMS target path" -msgstr "Chemin d'accès du TMS" +msgstr "Chemin d'acc??s du TMS" #: src/wx/config_dialog.cc:59 msgid "TMS user name" @@ -387,31 +385,31 @@ msgstr "Territoire (ex. FR)" #: src/wx/config_dialog.cc:117 msgid "Threads" -msgstr "Processeurs" +msgstr "Processus" #: src/wx/server_dialog.cc:40 msgid "Threads to use" -msgstr "Nombre de processeurs à utiliser" +msgstr "Nombre de processus ?? utiliser" #: src/wx/config_dialog.cc:69 msgid "Threads to use for encoding on this host" -msgstr "Nombre de processeurs à utiliser sur cet hôte" +msgstr "Nombre de processus ?? utiliser sur cet h??te" #: src/wx/audio_plot.cc:139 msgid "Time" -msgstr "Durée" +msgstr "Dur??e" #: src/wx/film_editor.cc:292 msgid "Top crop" -msgstr "Découpe haut" +msgstr "D??coupe haut" #: src/wx/film_editor.cc:172 msgid "Trim frames" -msgstr "" +msgstr "Images coup??es" #: src/wx/film_editor.cc:126 msgid "Trust content's header" -msgstr "Faire confiance au contenu" +msgstr "Faire confiance ?? l'en-t??te" #: src/wx/audio_dialog.cc:55 msgid "Type" @@ -423,11 +421,11 @@ msgstr "Utiliser le nom DCI" #: src/wx/film_editor.cc:146 msgid "Use best" -msgstr "Utiliser le meilleur" +msgstr "Automatique" #: src/wx/film_editor.cc:392 msgid "Use content's audio" -msgstr "Utiliser la piste audio du contenu" +msgstr "Utiliser le son int??gr??" #: src/wx/film_editor.cc:402 msgid "Use external audio" @@ -435,11 +433,11 @@ msgstr "Utiliser une source audio externe" #: src/wx/film_editor.cc:76 msgid "Video" -msgstr "Vidéo" +msgstr "Vid??o" #: src/wx/film_editor.cc:425 msgid "With Subtitles" -msgstr "Avec Sous-titres" +msgstr "Avec sous-titres" #: src/wx/film_editor.cc:1228 msgid "channels" @@ -447,7 +445,7 @@ msgstr "canaux" #: src/wx/properties_dialog.cc:50 msgid "counting..." -msgstr "compte..." +msgstr "calcul..." #: src/wx/film_editor.cc:374 msgid "dB" -- cgit v1.2.3 From b19e695723dc7f3a34b655414cad1a80f95b55b7 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 20 Mar 2013 10:22:56 +0000 Subject: Make exception strings translatable (#81). --- src/lib/exceptions.cc | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/exceptions.h | 29 +++++------------------- src/lib/wscript | 1 + 3 files changed, 70 insertions(+), 23 deletions(-) create mode 100644 src/lib/exceptions.cc (limited to 'src') diff --git a/src/lib/exceptions.cc b/src/lib/exceptions.cc new file mode 100644 index 000000000..bc6ac27c8 --- /dev/null +++ b/src/lib/exceptions.cc @@ -0,0 +1,63 @@ +/* + Copyright (C) 2012-2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "exceptions.h" +#include "compose.hpp" + +#include "i18n.h" + +using std::string; + +/** @param f File that we were trying to open */ +OpenFileError::OpenFileError (string f) + : FileError (String::compose (_("could not open file %1"), f), f) +{ + +} + +/** @param f File that we were trying to create */ +CreateFileError::CreateFileError (string f) + : FileError (String::compose (_("could not create file %1"), f), f) +{ + +} + +ReadFileError::ReadFileError (string f, int e) + : FileError ("", f) +{ + _what = String::compose (_("could not read from file %1 (%2)"), f, strerror (e)); +} + +WriteFileError::WriteFileError (std::string f, int e) + : FileError ("", f) +{ + _what = String::compose (_("could not write to file %1 (%2)"), f, strerror (e)); +} + +MissingSettingError::MissingSettingError (string s) + : SettingError (s, String::compose (_("missing required setting %1"), s)) +{ + +} + +PixelFormatError::PixelFormatError (std::string o, AVPixelFormat f) + : StringError (String::compose (_("Cannot handle pixel format %1 during %2"), f, o)) +{ + +} diff --git a/src/lib/exceptions.h b/src/lib/exceptions.h index 277355117..e45a62353 100644 --- a/src/lib/exceptions.h +++ b/src/lib/exceptions.h @@ -31,7 +31,6 @@ extern "C" { #include } -#include "compose.hpp" /** @class StringError * @brief A parent class for exceptions using messages held in a std::string @@ -113,9 +112,7 @@ class OpenFileError : public FileError { public: /** @param f File that we were trying to open */ - OpenFileError (std::string f) - : FileError ("could not open file " + f, f) - {} + OpenFileError (std::string f); }; /** @class CreateFileError. @@ -125,9 +122,7 @@ class CreateFileError : public FileError { public: /** @param f File that we were trying to create */ - CreateFileError (std::string f) - : FileError ("could not create file " + f, f) - {} + CreateFileError (std::string f); }; @@ -140,11 +135,7 @@ public: /** @param f File that we were trying to read from. * @param e errno value, or 0. */ - ReadFileError (std::string f, int e = 0) - : FileError ("", f) - { - _what = String::compose ("could not read from file %1 (%2)", f, strerror (e)); - } + ReadFileError (std::string f, int e = 0); }; /** @class WriteFileError. @@ -156,11 +147,7 @@ public: /** @param f File that we were trying to write to. * @param e errno value, or 0. */ - WriteFileError (std::string f, int e) - : FileError ("", f) - { - _what = String::compose ("could not write to file %1 (%2)", f, strerror (e)); - } + WriteFileError (std::string f, int e); }; /** @class SettingError. @@ -195,9 +182,7 @@ class MissingSettingError : public SettingError { public: /** @param s Name of setting that was required */ - MissingSettingError (std::string s) - : SettingError (s, "missing required setting " + s) - {} + MissingSettingError (std::string s); }; /** @class BadSettingError @@ -226,9 +211,7 @@ public: class PixelFormatError : public StringError { public: - PixelFormatError (std::string o, AVPixelFormat f) - : StringError (String::compose ("Cannot handle pixel format %1 during %2", f, o)) - {} + PixelFormatError (std::string o, AVPixelFormat f); }; class ExceptionStore diff --git a/src/lib/wscript b/src/lib/wscript index de39345d5..8b49e5933 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -20,6 +20,7 @@ sources = """ dolby_cp750.cc encoder.cc examine_content_job.cc + exceptions.cc filter_graph.cc ffmpeg_compatibility.cc ffmpeg_decoder.cc -- cgit v1.2.3 From bacdb2fee1a921060ad40e2db14c4e787ae188a9 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 20 Mar 2013 10:41:25 +0000 Subject: Target pot_merge to merge new .pot files with existing .po; update translations accordingly. --- ChangeLog | 4 ++ i18n.py | 11 ++++- src/lib/po/fr_FR.po | 102 ++++++++++++++++++++++++------------------ src/lib/po/it_IT.po | 42 +++++++++++++++--- src/lib/wscript | 3 ++ src/tools/po/fr_FR.po | 16 +++---- src/tools/po/it_IT.po | 8 ++-- src/tools/wscript | 3 ++ src/wscript | 5 +++ src/wx/po/fr_FR.po | 120 +++++++++++++++++++++++--------------------------- src/wx/po/it_IT.po | 110 ++++++++++++++++++++++----------------------- src/wx/wscript | 3 ++ wscript | 3 ++ 13 files changed, 247 insertions(+), 183 deletions(-) (limited to 'src') diff --git a/ChangeLog b/ChangeLog index e9872734d..955a6104c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-03-20 Carl Hetherington + + * Make exception strings translatable (#81). + 2013-03-19 Carl Hetherington * Version 0.78beta2 released. diff --git a/i18n.py b/i18n.py index 8e2fd6404..ce28d25e9 100644 --- a/i18n.py +++ b/i18n.py @@ -2,6 +2,10 @@ import glob import os from waflib import Logs +def command(c): + print c + os.system(c) + def pot(dir, sources, name): s = "" for f in sources.split('\n'): @@ -16,8 +20,11 @@ def pot(dir, sources, name): except: pass - os.system('xgettext -d %s -s --keyword=_ --add-comments=/ -p %s -o %s.pot %s' % (name, d, name, s)) - + command('xgettext -d %s -s --keyword=_ --add-comments=/ -p %s -o %s.pot %s' % (name, d, name, s)) + +def pot_merge(dir, name): + for f in glob.glob(os.path.join(os.getcwd(), dir, 'po', '*.po')): + command('msgmerge %s %s.pot -o %s' % (f, os.path.join('build', dir, name), f)) def po_to_mo(dir, name, bld): for f in glob.glob(os.path.join(os.getcwd(), dir, 'po', '*.po')): diff --git a/src/lib/po/fr_FR.po b/src/lib/po/fr_FR.po index 887c79862..56bd03fac 100644 --- a/src/lib/po/fr_FR.po +++ b/src/lib/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-05 13:49+0000\n" +"POT-Creation-Date: 2013-03-20 10:29+0000\n" "PO-Revision-Date: 2013-03-20 00:39+0100\n" "Last-Translator: FreeDCP.net \n" "Language-Team: \n" @@ -16,7 +16,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: src/lib/transcode_job.cc:90 +#: src/lib/transcode_job.cc:87 msgid "0%" msgstr "0%" @@ -72,7 +72,7 @@ msgstr "Advertisement" msgid "An error occurred whilst handling the file %1." msgstr "Une erreur s'est produite lors du traitement du fichier %1." -#: src/lib/analyse_audio_job.cc:48 +#: src/lib/analyse_audio_job.cc:49 msgid "Analyse audio of %1" msgstr "Analyse du son de %1" @@ -88,6 +88,10 @@ msgstr "Bicubique" msgid "Bilinear" msgstr "Bilin??aire" +#: src/lib/exceptions.cc:60 +msgid "Cannot handle pixel format %1 during %2" +msgstr "" + #: src/lib/encoder.cc:101 msgid "Cannot resample audio as libswresample is not present" msgstr "R??-??chantillonnage du son impossible : libswresample est absent" @@ -132,24 +136,14 @@ msgstr "La cadence du DCP sera %1%% par rapport ?? la source" msgid "DCP will use every other frame of the source.\n" msgstr "Le DCP utilisera une image sur deux de la source.\n" -#: src/lib/filter.cc:68 -#: src/lib/filter.cc:69 -#: src/lib/filter.cc:70 -#: src/lib/filter.cc:71 -#: src/lib/filter.cc:72 -#: src/lib/filter.cc:73 +#: src/lib/filter.cc:68 src/lib/filter.cc:69 src/lib/filter.cc:70 +#: src/lib/filter.cc:71 src/lib/filter.cc:72 src/lib/filter.cc:73 msgid "De-blocking" msgstr "De-bloc" -#: src/lib/filter.cc:75 -#: src/lib/filter.cc:76 -#: src/lib/filter.cc:77 -#: src/lib/filter.cc:78 -#: src/lib/filter.cc:79 -#: src/lib/filter.cc:80 -#: src/lib/filter.cc:81 -#: src/lib/filter.cc:82 -#: src/lib/filter.cc:83 +#: src/lib/filter.cc:75 src/lib/filter.cc:76 src/lib/filter.cc:77 +#: src/lib/filter.cc:78 src/lib/filter.cc:79 src/lib/filter.cc:80 +#: src/lib/filter.cc:81 src/lib/filter.cc:82 src/lib/filter.cc:83 msgid "De-interlacing" msgstr "D??sentrelacement" @@ -237,10 +231,13 @@ msgstr "Filtre d??bloc horizontal" msgid "Horizontal deblocking filter A" msgstr "Filtre d??-bloc horizontal" -#: src/lib/job.cc:87 -#: src/lib/job.cc:96 -msgid "It is not known what caused this error. The best idea is to report the problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" -msgstr "Erreur ind??termin??e. Merci de rapporter le probl??me ?? la liste DVD-o-matic (dvdomatic@carlh.net)" +#: src/lib/job.cc:87 src/lib/job.cc:96 +msgid "" +"It is not known what caused this error. The best idea is to report the " +"problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" +msgstr "" +"Erreur ind??termin??e. Merci de rapporter le probl??me ?? la liste DVD-o-" +"matic (dvdomatic@carlh.net)" #: src/lib/filter.cc:82 msgid "Kernel deinterlacer" @@ -262,11 +259,8 @@ msgstr "D??sentrelaceur lin??aire interpol??" msgid "Median deinterlacer" msgstr "D??sentrelaceur m??dian" -#: src/lib/filter.cc:74 -#: src/lib/filter.cc:85 -#: src/lib/filter.cc:86 -#: src/lib/filter.cc:87 -#: src/lib/filter.cc:90 +#: src/lib/filter.cc:74 src/lib/filter.cc:85 src/lib/filter.cc:86 +#: src/lib/filter.cc:87 src/lib/filter.cc:90 msgid "Misc" msgstr "Divers" @@ -274,9 +268,7 @@ msgstr "Divers" msgid "Motion compensating deinterlacer" msgstr "D??sentrelaceur par compensation de mouvement" -#: src/lib/filter.cc:84 -#: src/lib/filter.cc:88 -#: src/lib/filter.cc:89 +#: src/lib/filter.cc:84 src/lib/filter.cc:88 src/lib/filter.cc:89 #: src/lib/filter.cc:91 msgid "Noise reduction" msgstr "R??duction de bruit" @@ -398,8 +390,12 @@ msgid "Test" msgstr "Test" #: src/lib/job.cc:76 -msgid "The drive that the film is stored on is low in disc space. Free some more space and try again." -msgstr "Le disque contenant le film est plein. Lib??rez de l'espace et essayez ?? nouveau." +msgid "" +"The drive that the film is stored on is low in disc space. Free some more " +"space and try again." +msgstr "" +"Le disque contenant le film est plein. Lib??rez de l'espace et essayez ?? " +"nouveau." #: src/lib/dcp_content_type.cc:46 msgid "Trailer" @@ -473,6 +469,11 @@ msgstr "type de contenu" msgid "copying %1" msgstr "copie de %1" +#: src/lib/exceptions.cc:36 +#, fuzzy +msgid "could not create file %1" +msgstr "??criture vers fichier distant (%1) impossible" + #: src/lib/ffmpeg_decoder.cc:191 msgid "could not find audio decoder" msgstr "d??codeur audio introuvable" @@ -489,16 +490,25 @@ msgstr "d??codeur de sous-titre introuvable" msgid "could not find video decoder" msgstr "d??codeur vid??o introuvable" -#: src/lib/external_audio_decoder.cc:72 +#: src/lib/sndfile_decoder.cc:72 msgid "could not open external audio file for reading" msgstr "lecture du fichier audio externe impossible" +#: src/lib/exceptions.cc:29 +#, fuzzy +msgid "could not open file %1" +msgstr "lecture du fichier impossible" + #: src/lib/dcp_video_frame.cc:388 msgid "could not open file for reading" msgstr "lecture du fichier impossible" -#: src/lib/encoder.cc:137 -#: src/lib/encoder.cc:314 +#: src/lib/exceptions.cc:44 +#, fuzzy +msgid "could not read from file %1 (%2)" +msgstr "Cr??ation du dossier distant %1 (%2) impossible" + +#: src/lib/encoder.cc:137 src/lib/encoder.cc:314 msgid "could not run sample-rate converter" msgstr "conversion de la fr??quence d'??chantillonnage impossible" @@ -510,6 +520,11 @@ msgstr "d??marrage de session SCP (%1) impossible" msgid "could not start SSH session" msgstr "d??marrage de session SSH impossible" +#: src/lib/exceptions.cc:50 +#, fuzzy +msgid "could not write to file %1 (%2)" +msgstr "??criture vers fichier distant (%1) impossible" + #: src/lib/encoder.cc:247 msgid "decoder sleeps with queue of %1" msgstr "d??codeur en veille avec %1 en file d'attente" @@ -518,11 +533,11 @@ msgstr "d??codeur en veille avec %1 en file d'attente" msgid "decoder wakes with queue of %1" msgstr "reprise du d??codage avec %1 en file d'attente" -#: src/lib/external_audio_decoder.cc:94 +#: src/lib/sndfile_decoder.cc:94 msgid "external audio files have differing lengths" msgstr "Les fichiers audio externes ont des dur??es diff??rentes" -#: src/lib/external_audio_decoder.cc:76 +#: src/lib/sndfile_decoder.cc:76 msgid "external audio files must be mono" msgstr "les fichiers audio externes doivent ??tre en mono" @@ -530,7 +545,7 @@ msgstr "les fichiers audio externes doivent ??tre en mono" msgid "format" msgstr "format" -#: src/lib/transcode_job.cc:103 +#: src/lib/transcode_job.cc:100 msgid "frames per second" msgstr "images par seconde" @@ -538,8 +553,7 @@ msgstr "images par seconde" msgid "hour" msgstr "heure" -#: src/lib/util.cc:112 -#: src/lib/util.cc:117 +#: src/lib/util.cc:112 src/lib/util.cc:117 msgid "hours" msgstr "heures" @@ -555,12 +569,15 @@ msgstr "minutes" msgid "missing key %1 in key-value set" msgstr "cl?? %1 non s??lectionn??e" +#: src/lib/exceptions.cc:54 +msgid "missing required setting %1" +msgstr "" + #: src/lib/subtitle.cc:52 msgid "multi-part subtitles not yet supported" msgstr "sous-titres en plusieurs parties non support??s" -#: src/lib/film.cc:263 -#: src/lib/film.cc:308 +#: src/lib/film.cc:263 src/lib/film.cc:308 msgid "name" msgstr "nom" @@ -593,4 +610,3 @@ msgstr "fixe" #: src/lib/film.cc:274 msgid "video" msgstr "vid??o" - diff --git a/src/lib/po/it_IT.po b/src/lib/po/it_IT.po index 46e533450..a5a868ca0 100644 --- a/src/lib/po/it_IT.po +++ b/src/lib/po/it_IT.po @@ -7,15 +7,15 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-15 08:39+0000\n" +"POT-Creation-Date: 2013-03-20 10:29+0000\n" "PO-Revision-Date: 2013-03-18 16:46+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" +"Language: Italiano\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" -"Language: Italiano\n" #: src/lib/transcode_job.cc:87 msgid "0%" @@ -89,6 +89,10 @@ msgstr "Bicubica" msgid "Bilinear" msgstr "Bilineare" +#: src/lib/exceptions.cc:60 +msgid "Cannot handle pixel format %1 during %2" +msgstr "" + #: src/lib/encoder.cc:101 msgid "Cannot resample audio as libswresample is not present" msgstr "Non posso ricampionare l'audio perchè libswresample non è presente" @@ -233,8 +237,8 @@ msgid "" "It is not known what caused this error. The best idea is to report the " "problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" msgstr "" -"Non sappiamo cosa ha causato questo errore. La cosa migliore è di inviare un " -"report del problema alla mailing list di DVD-o-matic (dvdomatic@carlh.net)" +"Non sappiamo cosa ha causato questo errore. La cosa migliore è di inviare " +"un report del problema alla mailing list di DVD-o-matic (dvdomatic@carlh.net)" #: src/lib/filter.cc:82 msgid "Kernel deinterlacer" @@ -466,6 +470,11 @@ msgstr "tipo di contenuto" msgid "copying %1" msgstr "copia %1" +#: src/lib/exceptions.cc:36 +#, fuzzy +msgid "could not create file %1" +msgstr "Non posso scrivere il file remoto (%1)" + #: src/lib/ffmpeg_decoder.cc:191 msgid "could not find audio decoder" msgstr "non riesco a trovare il decoder audio" @@ -482,14 +491,24 @@ msgstr "non riesco a trovare il decoder dei sottotitoli" msgid "could not find video decoder" msgstr "non riesco a trovare il decoder video" -#: src/lib/external_audio_decoder.cc:72 +#: src/lib/sndfile_decoder.cc:72 msgid "could not open external audio file for reading" msgstr "non riesco ad aprire il file dell'audio esterno per leggerlo" +#: src/lib/exceptions.cc:29 +#, fuzzy +msgid "could not open file %1" +msgstr "non riesco ad aprire il file per leggerlo" + #: src/lib/dcp_video_frame.cc:388 msgid "could not open file for reading" msgstr "non riesco ad aprire il file per leggerlo" +#: src/lib/exceptions.cc:44 +#, fuzzy +msgid "could not read from file %1 (%2)" +msgstr "Non posso creare la directory remota %1 (%2)" + #: src/lib/encoder.cc:137 src/lib/encoder.cc:314 msgid "could not run sample-rate converter" msgstr "non riesco a lanciare il convertitore della frequenza di campionamento" @@ -502,6 +521,11 @@ msgstr "non posso avviare la sessione SCP (%1)" msgid "could not start SSH session" msgstr "non posso avviare la sessione SSH" +#: src/lib/exceptions.cc:50 +#, fuzzy +msgid "could not write to file %1 (%2)" +msgstr "Non posso scrivere il file remoto (%1)" + #: src/lib/encoder.cc:247 msgid "decoder sleeps with queue of %1" msgstr "il decoder è in pausa con la coda di %1" @@ -510,11 +534,11 @@ msgstr "il decoder è in pausa con la coda di %1" msgid "decoder wakes with queue of %1" msgstr "il decoder riparte con la coda di %1" -#: src/lib/external_audio_decoder.cc:94 +#: src/lib/sndfile_decoder.cc:94 msgid "external audio files have differing lengths" msgstr "i files dell'audio esterno hanno durata diversa" -#: src/lib/external_audio_decoder.cc:76 +#: src/lib/sndfile_decoder.cc:76 msgid "external audio files must be mono" msgstr "i files dell'audio esterno devono essere mono" @@ -546,6 +570,10 @@ msgstr "minuti" msgid "missing key %1 in key-value set" msgstr "persa la chiave %1 tra i valori chiave" +#: src/lib/exceptions.cc:54 +msgid "missing required setting %1" +msgstr "" + #: src/lib/subtitle.cc:52 msgid "multi-part subtitles not yet supported" msgstr "sottotitoli multi-part non ancora supportati" diff --git a/src/lib/wscript b/src/lib/wscript index 8b49e5933..5d9f5626a 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -75,3 +75,6 @@ def build(bld): def pot(bld): i18n.pot(os.path.join('src', 'lib'), sources, 'libdvdomatic') + +def pot_merge(bld): + i18n.pot_merge(os.path.join('src', 'lib'), 'libdvdomatic') diff --git a/src/tools/po/fr_FR.po b/src/tools/po/fr_FR.po index f38f07d6e..273c1fc32 100644 --- a/src/tools/po/fr_FR.po +++ b/src/tools/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-05 13:49+0000\n" +"POT-Creation-Date: 2013-03-20 10:29+0000\n" "PO-Revision-Date: 2013-03-13 22:33+0100\n" "Last-Translator: \n" "Language-Team: \n" @@ -65,14 +65,16 @@ msgid "&Send DCP to TMS" msgstr "&Envoyer le DCP dans le TMS" #: src/tools/dvdomatic.cc:409 -msgid "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" -msgstr "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" +msgid "" +"(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" +msgstr "" +"(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" #: src/tools/dvdomatic.cc:180 msgid "About" msgstr "A Propos" -#: src/tools/dvdomatic.cc:482 +#: src/tools/dvdomatic.cc:500 msgid "Could not load film %1 (%2)" msgstr "Impossible de charger le film %1 (%2)" @@ -81,9 +83,8 @@ msgstr "Impossible de charger le film %1 (%2)" msgid "Could not open film at %s (%s)" msgstr "Impossible d'ouvrir le film ?? %s (%s)" -#: src/tools/dvdomatic.cc:287 -#: src/tools/dvdomatic.cc:402 -#: src/tools/dvdomatic.cc:486 +#: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:402 +#: src/tools/dvdomatic.cc:504 msgid "DVD-o-matic" msgstr "DVD-o-matic" @@ -111,4 +112,3 @@ msgstr "S??lectionner le film ?? ouvrir" #, c-format msgid "The directory %s already exists." msgstr "Le dossier %s existe d??j??." - diff --git a/src/tools/po/it_IT.po b/src/tools/po/it_IT.po index 0886f3cb3..c22a536fe 100644 --- a/src/tools/po/it_IT.po +++ b/src/tools/po/it_IT.po @@ -7,15 +7,15 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-15 08:39+0000\n" +"POT-Creation-Date: 2013-03-20 10:29+0000\n" "PO-Revision-Date: 2013-03-18 15:20+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" +"Language: Italiano\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" -"Language: Italiano\n" #: src/tools/dvdomatic.cc:177 msgid "&Analyse audio" @@ -75,7 +75,7 @@ msgstr "" msgid "About" msgstr "Informazioni" -#: src/tools/dvdomatic.cc:497 +#: src/tools/dvdomatic.cc:500 msgid "Could not load film %1 (%2)" msgstr "Non posso caricare il film %1 (%2)" @@ -85,7 +85,7 @@ msgid "Could not open film at %s (%s)" msgstr "Non posso aprire il film a %s (%s)" #: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:402 -#: src/tools/dvdomatic.cc:501 +#: src/tools/dvdomatic.cc:504 msgid "DVD-o-matic" msgstr "DVD-o-matic" diff --git a/src/tools/wscript b/src/tools/wscript index 64d5efe56..9f0f52152 100644 --- a/src/tools/wscript +++ b/src/tools/wscript @@ -27,3 +27,6 @@ def build(bld): def pot(bld): i18n.pot(os.path.join('src', 'tools'), 'dvdomatic.cc', 'dvdomatic') + +def pot_merge(bld): + i18n.pot_merge(os.path.join('src', 'tools'), 'dvdomatic') diff --git a/src/wscript b/src/wscript index f7f888acd..a4cf349f9 100644 --- a/src/wscript +++ b/src/wscript @@ -12,3 +12,8 @@ def pot(bld): bld.recurse('lib') bld.recurse('wx') bld.recurse('tools') + +def pot_merge(bld): + bld.recurse('lib') + bld.recurse('wx') + bld.recurse('tools') diff --git a/src/wx/po/fr_FR.po b/src/wx/po/fr_FR.po index 55732911c..f91279213 100644 --- a/src/wx/po/fr_FR.po +++ b/src/wx/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-05 13:49+0000\n" +"POT-Creation-Date: 2013-03-20 10:29+0000\n" "PO-Revision-Date: 2013-03-20 00:34+0100\n" "Last-Translator: FreeDCP.net \n" "Language-Team: \n" @@ -16,15 +16,15 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: src/wx/film_editor.cc:441 +#: src/wx/film_editor.cc:440 msgid "%" msgstr "%" -#: src/wx/film_editor.cc:1226 +#: src/wx/film_editor.cc:1229 msgid "1 channel" msgstr "1 canal" -#: src/wx/film_editor.cc:185 +#: src/wx/film_editor.cc:184 msgid "A/B" msgstr "A/B" @@ -32,16 +32,15 @@ msgstr "A/B" msgid "Add" msgstr "Ajouter" -#: src/wx/audio_dialog.cc:32 -#: src/wx/film_editor.cc:78 +#: src/wx/audio_dialog.cc:32 src/wx/film_editor.cc:77 msgid "Audio" msgstr "Audio" -#: src/wx/film_editor.cc:382 +#: src/wx/film_editor.cc:381 msgid "Audio Delay" msgstr "D??lai audio" -#: src/wx/film_editor.cc:370 +#: src/wx/film_editor.cc:369 msgid "Audio Gain" msgstr "Gain audio" @@ -54,7 +53,7 @@ msgstr "Langue audio (ex. FR)" msgid "Bad setting for %s (%s)" msgstr "Mauvais param??tre pour %s (%s)" -#: src/wx/film_editor.cc:297 +#: src/wx/film_editor.cc:296 msgid "Bottom crop" msgstr "D??coupe bas" @@ -66,7 +65,7 @@ msgstr "Parcourir..." msgid "But I have to use fader" msgstr "Je souhaite utiliser ce volume" -#: src/wx/film_editor.cc:375 +#: src/wx/film_editor.cc:374 msgid "Calculate..." msgstr "Calcul..." @@ -74,15 +73,15 @@ msgstr "Calcul..." msgid "Channels" msgstr "Canaux" -#: src/wx/film_editor.cc:326 +#: src/wx/film_editor.cc:325 msgid "Colour look-up table" msgstr "Espace colorim??trique" -#: src/wx/film_editor.cc:121 +#: src/wx/film_editor.cc:120 msgid "Content" msgstr "Contenu" -#: src/wx/film_editor.cc:131 +#: src/wx/film_editor.cc:130 msgid "Content Type" msgstr "Type de Contenu" @@ -101,7 +100,7 @@ msgstr "Impossible de cr??er le DCP : %s" msgid "Could not open content file (%s)" msgstr "Ouverture du contenu impossible (%s)" -#: src/wx/film_editor.cc:505 +#: src/wx/film_editor.cc:504 #, c-format msgid "Could not set content: %s" msgstr "S??lectionner du contenu impossible : %s" @@ -114,11 +113,11 @@ msgstr "Cr??er dans le dossier" msgid "DCI name" msgstr "Nom DCI" -#: src/wx/film_editor.cc:142 +#: src/wx/film_editor.cc:141 msgid "DCP Frame Rate" msgstr "Cadence image du DCP" -#: src/wx/film_editor.cc:110 +#: src/wx/film_editor.cc:109 msgid "DCP Name" msgstr "Nom du DCP" @@ -142,8 +141,7 @@ msgstr "D??tails du nom DCI par d??faut" msgid "Default directory for new films" msgstr "Dossier par d??faut des nouveaux films" -#: src/wx/film_editor.cc:117 -#: src/wx/job_manager_view.cc:88 +#: src/wx/film_editor.cc:116 src/wx/job_manager_view.cc:88 msgid "Details..." msgstr "D??tails..." @@ -151,7 +149,7 @@ msgstr "D??tails..." msgid "Disk space required" msgstr "Espace disque requis" -#: src/wx/film_editor.cc:192 +#: src/wx/film_editor.cc:191 msgid "Duration" msgstr "Dur??e" @@ -159,9 +157,8 @@ msgstr "Dur??e" msgid "Edit" msgstr "??dition" -#: src/wx/config_dialog.cc:84 -#: src/wx/config_dialog.cc:103 -#: src/wx/film_editor.cc:309 +#: src/wx/config_dialog.cc:84 src/wx/config_dialog.cc:103 +#: src/wx/film_editor.cc:308 msgid "Edit..." msgstr "??diter..." @@ -169,7 +166,7 @@ msgstr "??diter..." msgid "Encoding Servers" msgstr "Serveurs d'encodage" -#: src/wx/film_editor.cc:177 +#: src/wx/film_editor.cc:176 msgid "End" msgstr "Fin" @@ -177,7 +174,7 @@ msgstr "Fin" msgid "Facility (e.g. DLA)" msgstr "Laboratoire (ex. DLA)" -#: src/wx/film_editor.cc:74 +#: src/wx/film_editor.cc:73 msgid "Film" msgstr "Film" @@ -189,12 +186,11 @@ msgstr "Propri??t??s du film" msgid "Film name" msgstr "Nom du Film" -#: src/wx/film_editor.cc:304 -#: src/wx/filter_dialog.cc:32 +#: src/wx/film_editor.cc:303 src/wx/filter_dialog.cc:32 msgid "Filters" msgstr "Filtres" -#: src/wx/film_editor.cc:269 +#: src/wx/film_editor.cc:268 msgid "Format" msgstr "Format" @@ -218,7 +214,7 @@ msgstr "Gb" msgid "Host name or IP address" msgstr "Nom de l'h??te ou adresse IP" -#: src/wx/film_editor.cc:1230 +#: src/wx/film_editor.cc:1233 msgid "Hz" msgstr "Hz" @@ -230,19 +226,19 @@ msgstr "Je veux le jouer ?? ce volume" msgid "IP address" msgstr "Adresse IP" -#: src/wx/film_editor.cc:336 +#: src/wx/film_editor.cc:335 msgid "JPEG2000 bandwidth" msgstr "Qualit?? JPEG2000" -#: src/wx/film_editor.cc:282 +#: src/wx/film_editor.cc:281 msgid "Left crop" msgstr "D??coupe gauche" -#: src/wx/film_editor.cc:165 +#: src/wx/film_editor.cc:164 msgid "Length" msgstr "Longueur" -#: src/wx/film_editor.cc:340 +#: src/wx/film_editor.cc:339 msgid "MBps" msgstr "MBps" @@ -250,7 +246,7 @@ msgstr "MBps" msgid "My Documents" msgstr "Mes Documents" -#: src/wx/film_editor.cc:105 +#: src/wx/film_editor.cc:104 msgid "Name" msgstr "Nom" @@ -258,16 +254,15 @@ msgstr "Nom" msgid "New Film" msgstr "Nouveau Film" -#: src/wx/film_editor.cc:306 -#: src/wx/film_editor.cc:663 +#: src/wx/film_editor.cc:305 src/wx/film_editor.cc:664 msgid "None" msgstr "Aucun" -#: src/wx/film_editor.cc:136 +#: src/wx/film_editor.cc:135 msgid "Original Frame Rate" msgstr "Cadence d'images originale" -#: src/wx/film_editor.cc:160 +#: src/wx/film_editor.cc:159 msgid "Original Size" msgstr "Taille Originale" @@ -307,7 +302,7 @@ msgstr "??chelle de r??f??rence pour A7B" msgid "Remove" msgstr "Supprimer" -#: src/wx/film_editor.cc:287 +#: src/wx/film_editor.cc:286 msgid "Right crop" msgstr "D??coupe droite" @@ -315,15 +310,15 @@ msgstr "D??coupe droite" msgid "Running" msgstr "Progression" -#: src/wx/film_editor.cc:316 +#: src/wx/film_editor.cc:315 msgid "Scaler" msgstr "Mise ?? l'??chelle" -#: src/wx/film_editor.cc:408 +#: src/wx/film_editor.cc:407 msgid "Select Audio File" msgstr "S??lectionner le fichier son" -#: src/wx/film_editor.cc:122 +#: src/wx/film_editor.cc:121 msgid "Select Content File" msgstr "S??lectionner le fichier vid??o" @@ -331,7 +326,7 @@ msgstr "S??lectionner le fichier vid??o" msgid "Server" msgstr "Serveur" -#: src/wx/film_editor.cc:365 +#: src/wx/film_editor.cc:364 msgid "Show Audio..." msgstr "Montrer le son..." @@ -339,7 +334,7 @@ msgstr "Montrer le son..." msgid "Smoothing" msgstr "Lissage" -#: src/wx/film_editor.cc:174 +#: src/wx/film_editor.cc:173 msgid "Start" msgstr "D??but" @@ -351,15 +346,15 @@ msgstr "Studio (ex. TCF)" msgid "Subtitle Language (e.g. FR)" msgstr "Langue de sous-titres (ex. FR)" -#: src/wx/film_editor.cc:432 +#: src/wx/film_editor.cc:431 msgid "Subtitle Offset" msgstr "D??calage du sous-titre" -#: src/wx/film_editor.cc:437 +#: src/wx/film_editor.cc:436 msgid "Subtitle Scale" msgstr "Taille du sous-titre" -#: src/wx/film_editor.cc:80 +#: src/wx/film_editor.cc:79 msgid "Subtitles" msgstr "Sous-titres" @@ -399,15 +394,15 @@ msgstr "Nombre de processus ?? utiliser sur cet h??te" msgid "Time" msgstr "Dur??e" -#: src/wx/film_editor.cc:292 +#: src/wx/film_editor.cc:291 msgid "Top crop" msgstr "D??coupe haut" -#: src/wx/film_editor.cc:172 +#: src/wx/film_editor.cc:171 msgid "Trim frames" msgstr "Images coup??es" -#: src/wx/film_editor.cc:126 +#: src/wx/film_editor.cc:125 msgid "Trust content's header" msgstr "Faire confiance ?? l'en-t??te" @@ -415,31 +410,31 @@ msgstr "Faire confiance ?? l'en-t??te" msgid "Type" msgstr "Type" -#: src/wx/film_editor.cc:115 +#: src/wx/film_editor.cc:114 msgid "Use DCI name" msgstr "Utiliser le nom DCI" -#: src/wx/film_editor.cc:146 +#: src/wx/film_editor.cc:145 msgid "Use best" msgstr "Automatique" -#: src/wx/film_editor.cc:392 +#: src/wx/film_editor.cc:391 msgid "Use content's audio" msgstr "Utiliser le son int??gr??" -#: src/wx/film_editor.cc:402 +#: src/wx/film_editor.cc:401 msgid "Use external audio" msgstr "Utiliser une source audio externe" -#: src/wx/film_editor.cc:76 +#: src/wx/film_editor.cc:75 msgid "Video" msgstr "Vid??o" -#: src/wx/film_editor.cc:425 +#: src/wx/film_editor.cc:424 msgid "With Subtitles" msgstr "Avec sous-titres" -#: src/wx/film_editor.cc:1228 +#: src/wx/film_editor.cc:1231 msgid "channels" msgstr "canaux" @@ -447,27 +442,24 @@ msgstr "canaux" msgid "counting..." msgstr "calcul..." -#: src/wx/film_editor.cc:374 +#: src/wx/film_editor.cc:373 msgid "dB" msgstr "dB" -#: src/wx/film_editor.cc:689 -#: src/wx/film_editor.cc:691 +#: src/wx/film_editor.cc:690 src/wx/film_editor.cc:692 msgid "frames" msgstr "images" #. / TRANSLATORS: this is an abbreviation for milliseconds, the unit of time -#: src/wx/film_editor.cc:387 +#: src/wx/film_editor.cc:386 msgid "ms" msgstr "ms" #. / TRANSLATORS: `s' here is an abbreviation for seconds, the unit of time -#: src/wx/film_editor.cc:198 +#: src/wx/film_editor.cc:197 msgid "s" msgstr "s" -#: src/wx/properties_dialog.cc:62 -#: src/wx/properties_dialog.cc:63 +#: src/wx/properties_dialog.cc:62 src/wx/properties_dialog.cc:63 msgid "unknown" msgstr "inconnu" - diff --git a/src/wx/po/it_IT.po b/src/wx/po/it_IT.po index c8fa5815a..7a9e22634 100644 --- a/src/wx/po/it_IT.po +++ b/src/wx/po/it_IT.po @@ -7,25 +7,25 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-15 08:39+0000\n" +"POT-Creation-Date: 2013-03-20 10:29+0000\n" "PO-Revision-Date: 2013-03-18 17:51+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" +"Language: Italiano\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" -"Language: Italiano\n" -#: src/wx/film_editor.cc:441 +#: src/wx/film_editor.cc:440 msgid "%" msgstr "%" -#: src/wx/film_editor.cc:1230 +#: src/wx/film_editor.cc:1229 msgid "1 channel" msgstr "Canale 1" -#: src/wx/film_editor.cc:185 +#: src/wx/film_editor.cc:184 msgid "A/B" msgstr "A/B" @@ -33,15 +33,15 @@ msgstr "A/B" msgid "Add" msgstr "Aggiungi" -#: src/wx/audio_dialog.cc:32 src/wx/film_editor.cc:78 +#: src/wx/audio_dialog.cc:32 src/wx/film_editor.cc:77 msgid "Audio" msgstr "Audio" -#: src/wx/film_editor.cc:382 +#: src/wx/film_editor.cc:381 msgid "Audio Delay" msgstr "Ritardo dell'audio" -#: src/wx/film_editor.cc:370 +#: src/wx/film_editor.cc:369 msgid "Audio Gain" msgstr "Guadagno dell'audio" @@ -54,7 +54,7 @@ msgstr "Lingua dell'audio (es. EN)" msgid "Bad setting for %s (%s)" msgstr "Valore sbagliato per %s (%s)" -#: src/wx/film_editor.cc:297 +#: src/wx/film_editor.cc:296 msgid "Bottom crop" msgstr "Taglio inferiore" @@ -66,7 +66,7 @@ msgstr "Sfoglia..." msgid "But I have to use fader" msgstr "Ma devo usare il fader" -#: src/wx/film_editor.cc:375 +#: src/wx/film_editor.cc:374 msgid "Calculate..." msgstr "Calcola..." @@ -74,15 +74,15 @@ msgstr "Calcola..." msgid "Channels" msgstr "Canali" -#: src/wx/film_editor.cc:326 +#: src/wx/film_editor.cc:325 msgid "Colour look-up table" msgstr "Tabella per ricerca del colore" -#: src/wx/film_editor.cc:121 +#: src/wx/film_editor.cc:120 msgid "Content" msgstr "Contenuto" -#: src/wx/film_editor.cc:131 +#: src/wx/film_editor.cc:130 msgid "Content Type" msgstr "Tipo di contenuto" @@ -101,7 +101,7 @@ msgstr "Non posso creare il DCP: %s" msgid "Could not open content file (%s)" msgstr "Non posso aprire il file del contenuto (%s)" -#: src/wx/film_editor.cc:505 +#: src/wx/film_editor.cc:504 #, c-format msgid "Could not set content: %s" msgstr "Non posso regolare il contenuto: %s" @@ -114,11 +114,11 @@ msgstr "Crea nella cartella" msgid "DCI name" msgstr "Nome del DCP" -#: src/wx/film_editor.cc:142 +#: src/wx/film_editor.cc:141 msgid "DCP Frame Rate" msgstr "Frequenza fotogrammi del DCP" -#: src/wx/film_editor.cc:110 +#: src/wx/film_editor.cc:109 msgid "DCP Name" msgstr "Nome del DCP" @@ -142,7 +142,7 @@ msgstr "Dettagli del nome di default DCI" msgid "Default directory for new films" msgstr "Directory di default per i nuovi films" -#: src/wx/film_editor.cc:117 src/wx/job_manager_view.cc:88 +#: src/wx/film_editor.cc:116 src/wx/job_manager_view.cc:88 msgid "Details..." msgstr "Dettagli" @@ -150,7 +150,7 @@ msgstr "Dettagli" msgid "Disk space required" msgstr "Spazio su disco rischiesto" -#: src/wx/film_editor.cc:192 +#: src/wx/film_editor.cc:191 msgid "Duration" msgstr "Durata" @@ -159,7 +159,7 @@ msgid "Edit" msgstr "Modifica" #: src/wx/config_dialog.cc:84 src/wx/config_dialog.cc:103 -#: src/wx/film_editor.cc:309 +#: src/wx/film_editor.cc:308 msgid "Edit..." msgstr "Modifica..." @@ -167,7 +167,7 @@ msgstr "Modifica..." msgid "Encoding Servers" msgstr "Servers di codifica" -#: src/wx/film_editor.cc:177 +#: src/wx/film_editor.cc:176 msgid "End" msgstr "Fine" @@ -175,7 +175,7 @@ msgstr "Fine" msgid "Facility (e.g. DLA)" msgstr "Facility (es. DLA)" -#: src/wx/film_editor.cc:74 +#: src/wx/film_editor.cc:73 msgid "Film" msgstr "Film" @@ -187,11 +187,11 @@ msgstr "Proprietà del film" msgid "Film name" msgstr "Nome del film" -#: src/wx/film_editor.cc:304 src/wx/filter_dialog.cc:32 +#: src/wx/film_editor.cc:303 src/wx/filter_dialog.cc:32 msgid "Filters" msgstr "Filtri" -#: src/wx/film_editor.cc:269 +#: src/wx/film_editor.cc:268 msgid "Format" msgstr "Formato" @@ -215,7 +215,7 @@ msgstr "Gb" msgid "Host name or IP address" msgstr "Nome dell'Host o indirizzo IP" -#: src/wx/film_editor.cc:1234 +#: src/wx/film_editor.cc:1233 msgid "Hz" msgstr "Hz" @@ -227,19 +227,19 @@ msgstr "Voglio riprodurrlo back at fader" msgid "IP address" msgstr "Indirizzo IP" -#: src/wx/film_editor.cc:336 +#: src/wx/film_editor.cc:335 msgid "JPEG2000 bandwidth" msgstr "Banda passante JPEG2000" -#: src/wx/film_editor.cc:282 +#: src/wx/film_editor.cc:281 msgid "Left crop" msgstr "Taglio sinistro" -#: src/wx/film_editor.cc:165 +#: src/wx/film_editor.cc:164 msgid "Length" msgstr "Lunghezza" -#: src/wx/film_editor.cc:340 +#: src/wx/film_editor.cc:339 msgid "MBps" msgstr "MBps" @@ -247,7 +247,7 @@ msgstr "MBps" msgid "My Documents" msgstr "Documenti" -#: src/wx/film_editor.cc:105 +#: src/wx/film_editor.cc:104 msgid "Name" msgstr "Nome" @@ -255,15 +255,15 @@ msgstr "Nome" msgid "New Film" msgstr "Nuovo Film" -#: src/wx/film_editor.cc:306 src/wx/film_editor.cc:665 +#: src/wx/film_editor.cc:305 src/wx/film_editor.cc:664 msgid "None" msgstr "Nessuno" -#: src/wx/film_editor.cc:136 +#: src/wx/film_editor.cc:135 msgid "Original Frame Rate" msgstr "Frequenza Fotogrammi Originale" -#: src/wx/film_editor.cc:160 +#: src/wx/film_editor.cc:159 msgid "Original Size" msgstr "Dimensione Originale" @@ -303,7 +303,7 @@ msgstr "Scalatura di riferimento per A/B" msgid "Remove" msgstr "Rimuovi" -#: src/wx/film_editor.cc:287 +#: src/wx/film_editor.cc:286 msgid "Right crop" msgstr "Taglio destro" @@ -311,15 +311,15 @@ msgstr "Taglio destro" msgid "Running" msgstr "In corso" -#: src/wx/film_editor.cc:316 +#: src/wx/film_editor.cc:315 msgid "Scaler" msgstr "Scaler" -#: src/wx/film_editor.cc:408 +#: src/wx/film_editor.cc:407 msgid "Select Audio File" msgstr "Seleziona File Audio" -#: src/wx/film_editor.cc:122 +#: src/wx/film_editor.cc:121 msgid "Select Content File" msgstr "Seleziona FIle del Contenuto" @@ -327,7 +327,7 @@ msgstr "Seleziona FIle del Contenuto" msgid "Server" msgstr "Server" -#: src/wx/film_editor.cc:365 +#: src/wx/film_editor.cc:364 msgid "Show Audio..." msgstr "Mostra Audio..." @@ -335,7 +335,7 @@ msgstr "Mostra Audio..." msgid "Smoothing" msgstr "Levigatura" -#: src/wx/film_editor.cc:174 +#: src/wx/film_editor.cc:173 msgid "Start" msgstr "Avvio" @@ -347,15 +347,15 @@ msgstr "Studio (es. TCF)" msgid "Subtitle Language (e.g. FR)" msgstr "Lingua dei Sottotitoli (es. FR)" -#: src/wx/film_editor.cc:432 +#: src/wx/film_editor.cc:431 msgid "Subtitle Offset" msgstr "Sfalsamento dei Sottotitoli" -#: src/wx/film_editor.cc:437 +#: src/wx/film_editor.cc:436 msgid "Subtitle Scale" msgstr "Scala dei Sottotitoli" -#: src/wx/film_editor.cc:80 +#: src/wx/film_editor.cc:79 msgid "Subtitles" msgstr "Sottotitoli" @@ -395,15 +395,15 @@ msgstr "Threads da usare per codificare su questo host" msgid "Time" msgstr "Tempo" -#: src/wx/film_editor.cc:292 +#: src/wx/film_editor.cc:291 msgid "Top crop" msgstr "Taglio superiore" -#: src/wx/film_editor.cc:172 +#: src/wx/film_editor.cc:171 msgid "Trim frames" msgstr "Taglia fotogrammi" -#: src/wx/film_editor.cc:126 +#: src/wx/film_editor.cc:125 msgid "Trust content's header" msgstr "Conferma l'intestazione del contenuto" @@ -411,31 +411,31 @@ msgstr "Conferma l'intestazione del contenuto" msgid "Type" msgstr "Tipo" -#: src/wx/film_editor.cc:115 +#: src/wx/film_editor.cc:114 msgid "Use DCI name" msgstr "Usa nome DCI" -#: src/wx/film_editor.cc:146 +#: src/wx/film_editor.cc:145 msgid "Use best" msgstr "Usa il migliore" -#: src/wx/film_editor.cc:392 +#: src/wx/film_editor.cc:391 msgid "Use content's audio" msgstr "Usa l'audio del contenuto" -#: src/wx/film_editor.cc:402 +#: src/wx/film_editor.cc:401 msgid "Use external audio" msgstr "Usa l'audio esterno" -#: src/wx/film_editor.cc:76 +#: src/wx/film_editor.cc:75 msgid "Video" msgstr "Video" -#: src/wx/film_editor.cc:425 +#: src/wx/film_editor.cc:424 msgid "With Subtitles" msgstr "Con Sottotitoli" -#: src/wx/film_editor.cc:1232 +#: src/wx/film_editor.cc:1231 msgid "channels" msgstr "canali" @@ -443,21 +443,21 @@ msgstr "canali" msgid "counting..." msgstr "conteggio..." -#: src/wx/film_editor.cc:374 +#: src/wx/film_editor.cc:373 msgid "dB" msgstr "dB" -#: src/wx/film_editor.cc:691 src/wx/film_editor.cc:693 +#: src/wx/film_editor.cc:690 src/wx/film_editor.cc:692 msgid "frames" msgstr "fotogrammi" #. / TRANSLATORS: this is an abbreviation for milliseconds, the unit of time -#: src/wx/film_editor.cc:387 +#: src/wx/film_editor.cc:386 msgid "ms" msgstr "ms" #. / TRANSLATORS: `s' here is an abbreviation for seconds, the unit of time -#: src/wx/film_editor.cc:198 +#: src/wx/film_editor.cc:197 msgid "s" msgstr "s" diff --git a/src/wx/wscript b/src/wx/wscript index cc303f5e8..42bb8ca88 100644 --- a/src/wx/wscript +++ b/src/wx/wscript @@ -44,3 +44,6 @@ def build(bld): def pot(bld): i18n.pot(os.path.join('src', 'wx'), sources, 'libdvdomatic-wx') + +def pot_merge(bld): + i18n.pot_merge(os.path.join('src', 'wx'), 'libdvdomatic-wx') diff --git a/wscript b/wscript index b61b3b4cb..2b03c89cb 100644 --- a/wscript +++ b/wscript @@ -267,3 +267,6 @@ def post(ctx): def pot(bld): bld.recurse('src') + +def pot_merge(bld): + bld.recurse('src') -- cgit v1.2.3 From 723e2e3113a55bc34915fffe2bc45494266625fe Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 20 Mar 2013 13:37:17 +0000 Subject: Replace Italian translation with updated version, and with hopefully fixed encoding. --- src/lib/po/it_IT.po | 62 +++++++---------------- src/tools/po/it_IT.po | 16 +++--- src/wx/po/it_IT.po | 136 +++++++++++++++++++++++++------------------------- 3 files changed, 93 insertions(+), 121 deletions(-) (limited to 'src') diff --git a/src/lib/po/it_IT.po b/src/lib/po/it_IT.po index a5a868ca0..96a21263a 100644 --- a/src/lib/po/it_IT.po +++ b/src/lib/po/it_IT.po @@ -7,15 +7,15 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-20 10:29+0000\n" -"PO-Revision-Date: 2013-03-18 16:46+0100\n" +"POT-Creation-Date: 2013-03-15 08:39+0000\n" +"PO-Revision-Date: 2013-03-20 11:45+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" -"Language: Italiano\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" +"Language: Italiano\n" #: src/lib/transcode_job.cc:87 msgid "0%" @@ -67,7 +67,7 @@ msgstr "Academy" #: src/lib/dcp_content_type.cc:53 msgid "Advertisement" -msgstr "Pubblicità" +msgstr "Pubblicità" #: src/lib/job.cc:71 msgid "An error occurred whilst handling the file %1." @@ -89,13 +89,9 @@ msgstr "Bicubica" msgid "Bilinear" msgstr "Bilineare" -#: src/lib/exceptions.cc:60 -msgid "Cannot handle pixel format %1 during %2" -msgstr "" - #: src/lib/encoder.cc:101 msgid "Cannot resample audio as libswresample is not present" -msgstr "Non posso ricampionare l'audio perchè libswresample non è presente" +msgstr "Non posso ricampionare l'audio perchè libswresample non è presente" #: src/lib/scp_dcp_job.cc:109 msgid "Copy DCP to TMS" @@ -131,11 +127,11 @@ msgstr "Il DCP e il sorgente hanno la stessa frequenza.\n" #: src/lib/util.cc:975 msgid "DCP will run at %1%% of the source speed." -msgstr "Il DCP andrà al %1%% della velocità del sorgente." +msgstr "Il DCP andrà al %1%% della velocità del sorgente." #: src/lib/util.cc:968 msgid "DCP will use every other frame of the source.\n" -msgstr "Il DCP userà ogni altro fotogramma del sorgente.\n" +msgstr "Il DCP userà ogni altro fotogramma del sorgente.\n" #: src/lib/filter.cc:68 src/lib/filter.cc:69 src/lib/filter.cc:70 #: src/lib/filter.cc:71 src/lib/filter.cc:72 src/lib/filter.cc:73 @@ -158,7 +154,7 @@ msgstr "Dolby CP750" #: src/lib/util.cc:970 msgid "Each source frame will be doubled in the DCP.\n" -msgstr "Ogni fotogramma del sorgente sarà raddoppiato nel DCP.\n" +msgstr "Ogni fotogramma del sorgente sarà raddoppiato nel DCP.\n" #: src/lib/job.cc:287 msgid "Error (%1)" @@ -222,7 +218,7 @@ msgstr "Gradiente debander" #: src/lib/filter.cc:89 msgid "High quality 3D denoiser" -msgstr "Riduttore di rumore 3D di alta qualità" +msgstr "Riduttore di rumore 3D di alta qualità" #: src/lib/filter.cc:68 msgid "Horizontal deblocking filter" @@ -237,8 +233,8 @@ msgid "" "It is not known what caused this error. The best idea is to report the " "problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" msgstr "" -"Non sappiamo cosa ha causato questo errore. La cosa migliore è di inviare " -"un report del problema alla mailing list di DVD-o-matic (dvdomatic@carlh.net)" +"Non sappiamo cosa ha causato questo errore. La cosa migliore è inviare un " +"report del problema alla mailing list di DVD-o-matic (dvdomatic@carlh.net)" #: src/lib/filter.cc:82 msgid "Kernel deinterlacer" @@ -395,7 +391,7 @@ msgid "" "The drive that the film is stored on is low in disc space. Free some more " "space and try again." msgstr "" -"Il disco dove è memorizzato il film ha poco spazio a disposizione. Liberare " +"Sul disco dove è memorizzato il film non c'è abbastanza spazio. Liberare " "altro spazio e riprovare." #: src/lib/dcp_content_type.cc:46 @@ -448,7 +444,7 @@ msgstr "aggiungo alla coda %1" #: src/lib/film.cc:263 msgid "cannot contain slashes" -msgstr "non può contenere barre" +msgstr "non può contenere barre" #: src/lib/util.cc:499 msgid "connect timed out" @@ -470,11 +466,6 @@ msgstr "tipo di contenuto" msgid "copying %1" msgstr "copia %1" -#: src/lib/exceptions.cc:36 -#, fuzzy -msgid "could not create file %1" -msgstr "Non posso scrivere il file remoto (%1)" - #: src/lib/ffmpeg_decoder.cc:191 msgid "could not find audio decoder" msgstr "non riesco a trovare il decoder audio" @@ -491,24 +482,14 @@ msgstr "non riesco a trovare il decoder dei sottotitoli" msgid "could not find video decoder" msgstr "non riesco a trovare il decoder video" -#: src/lib/sndfile_decoder.cc:72 +#: src/lib/external_audio_decoder.cc:72 msgid "could not open external audio file for reading" msgstr "non riesco ad aprire il file dell'audio esterno per leggerlo" -#: src/lib/exceptions.cc:29 -#, fuzzy -msgid "could not open file %1" -msgstr "non riesco ad aprire il file per leggerlo" - #: src/lib/dcp_video_frame.cc:388 msgid "could not open file for reading" msgstr "non riesco ad aprire il file per leggerlo" -#: src/lib/exceptions.cc:44 -#, fuzzy -msgid "could not read from file %1 (%2)" -msgstr "Non posso creare la directory remota %1 (%2)" - #: src/lib/encoder.cc:137 src/lib/encoder.cc:314 msgid "could not run sample-rate converter" msgstr "non riesco a lanciare il convertitore della frequenza di campionamento" @@ -521,24 +502,19 @@ msgstr "non posso avviare la sessione SCP (%1)" msgid "could not start SSH session" msgstr "non posso avviare la sessione SSH" -#: src/lib/exceptions.cc:50 -#, fuzzy -msgid "could not write to file %1 (%2)" -msgstr "Non posso scrivere il file remoto (%1)" - #: src/lib/encoder.cc:247 msgid "decoder sleeps with queue of %1" -msgstr "il decoder è in pausa con la coda di %1" +msgstr "il decoder è in pausa con la coda di %1" #: src/lib/encoder.cc:249 msgid "decoder wakes with queue of %1" msgstr "il decoder riparte con la coda di %1" -#: src/lib/sndfile_decoder.cc:94 +#: src/lib/external_audio_decoder.cc:94 msgid "external audio files have differing lengths" msgstr "i files dell'audio esterno hanno durata diversa" -#: src/lib/sndfile_decoder.cc:76 +#: src/lib/external_audio_decoder.cc:76 msgid "external audio files must be mono" msgstr "i files dell'audio esterno devono essere mono" @@ -570,10 +546,6 @@ msgstr "minuti" msgid "missing key %1 in key-value set" msgstr "persa la chiave %1 tra i valori chiave" -#: src/lib/exceptions.cc:54 -msgid "missing required setting %1" -msgstr "" - #: src/lib/subtitle.cc:52 msgid "multi-part subtitles not yet supported" msgstr "sottotitoli multi-part non ancora supportati" diff --git a/src/tools/po/it_IT.po b/src/tools/po/it_IT.po index c22a536fe..07fd648c8 100644 --- a/src/tools/po/it_IT.po +++ b/src/tools/po/it_IT.po @@ -7,15 +7,15 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-20 10:29+0000\n" -"PO-Revision-Date: 2013-03-18 15:20+0100\n" +"POT-Creation-Date: 2013-03-15 08:39+0000\n" +"PO-Revision-Date: 2013-03-20 12:03+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" -"Language: Italiano\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" +"Language: Italiano\n" #: src/tools/dvdomatic.cc:177 msgid "&Analyse audio" @@ -51,7 +51,7 @@ msgstr "&Preferenze..." #: src/tools/dvdomatic.cc:165 msgid "&Properties..." -msgstr "&Proprietà..." +msgstr "&Proprieta'..." #: src/tools/dvdomatic.cc:167 msgid "&Quit" @@ -75,17 +75,17 @@ msgstr "" msgid "About" msgstr "Informazioni" -#: src/tools/dvdomatic.cc:500 +#: src/tools/dvdomatic.cc:497 msgid "Could not load film %1 (%2)" msgstr "Non posso caricare il film %1 (%2)" #: src/tools/dvdomatic.cc:331 #, c-format msgid "Could not open film at %s (%s)" -msgstr "Non posso aprire il film a %s (%s)" +msgstr "Non posso aprire il film in %s (%s)" #: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:402 -#: src/tools/dvdomatic.cc:504 +#: src/tools/dvdomatic.cc:501 msgid "DVD-o-matic" msgstr "DVD-o-matic" @@ -112,4 +112,4 @@ msgstr "Seleziona il film da aprire" #: src/tools/dvdomatic.cc:303 #, c-format msgid "The directory %s already exists." -msgstr "La directory %s esiste già." +msgstr "La directory %s esiste già." diff --git a/src/wx/po/it_IT.po b/src/wx/po/it_IT.po index 7a9e22634..d1e8e9355 100644 --- a/src/wx/po/it_IT.po +++ b/src/wx/po/it_IT.po @@ -7,25 +7,25 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-20 10:29+0000\n" -"PO-Revision-Date: 2013-03-18 17:51+0100\n" +"POT-Creation-Date: 2013-03-15 08:39+0000\n" +"PO-Revision-Date: 2013-03-20 11:50+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" -"Language: Italiano\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" +"Language: Italiano\n" -#: src/wx/film_editor.cc:440 +#: src/wx/film_editor.cc:441 msgid "%" msgstr "%" -#: src/wx/film_editor.cc:1229 +#: src/wx/film_editor.cc:1230 msgid "1 channel" msgstr "Canale 1" -#: src/wx/film_editor.cc:184 +#: src/wx/film_editor.cc:185 msgid "A/B" msgstr "A/B" @@ -33,15 +33,15 @@ msgstr "A/B" msgid "Add" msgstr "Aggiungi" -#: src/wx/audio_dialog.cc:32 src/wx/film_editor.cc:77 +#: src/wx/audio_dialog.cc:32 src/wx/film_editor.cc:78 msgid "Audio" msgstr "Audio" -#: src/wx/film_editor.cc:381 +#: src/wx/film_editor.cc:382 msgid "Audio Delay" msgstr "Ritardo dell'audio" -#: src/wx/film_editor.cc:369 +#: src/wx/film_editor.cc:370 msgid "Audio Gain" msgstr "Guadagno dell'audio" @@ -54,9 +54,9 @@ msgstr "Lingua dell'audio (es. EN)" msgid "Bad setting for %s (%s)" msgstr "Valore sbagliato per %s (%s)" -#: src/wx/film_editor.cc:296 +#: src/wx/film_editor.cc:297 msgid "Bottom crop" -msgstr "Taglio inferiore" +msgstr "Taglio in basso" #: src/wx/dir_picker_ctrl.cc:38 msgid "Browse..." @@ -66,7 +66,7 @@ msgstr "Sfoglia..." msgid "But I have to use fader" msgstr "Ma devo usare il fader" -#: src/wx/film_editor.cc:374 +#: src/wx/film_editor.cc:375 msgid "Calculate..." msgstr "Calcola..." @@ -74,15 +74,15 @@ msgstr "Calcola..." msgid "Channels" msgstr "Canali" -#: src/wx/film_editor.cc:325 +#: src/wx/film_editor.cc:326 msgid "Colour look-up table" msgstr "Tabella per ricerca del colore" -#: src/wx/film_editor.cc:120 +#: src/wx/film_editor.cc:121 msgid "Content" msgstr "Contenuto" -#: src/wx/film_editor.cc:130 +#: src/wx/film_editor.cc:131 msgid "Content Type" msgstr "Tipo di contenuto" @@ -101,7 +101,7 @@ msgstr "Non posso creare il DCP: %s" msgid "Could not open content file (%s)" msgstr "Non posso aprire il file del contenuto (%s)" -#: src/wx/film_editor.cc:504 +#: src/wx/film_editor.cc:505 #, c-format msgid "Could not set content: %s" msgstr "Non posso regolare il contenuto: %s" @@ -114,11 +114,11 @@ msgstr "Crea nella cartella" msgid "DCI name" msgstr "Nome del DCP" -#: src/wx/film_editor.cc:141 +#: src/wx/film_editor.cc:142 msgid "DCP Frame Rate" msgstr "Frequenza fotogrammi del DCP" -#: src/wx/film_editor.cc:109 +#: src/wx/film_editor.cc:110 msgid "DCP Name" msgstr "Nome del DCP" @@ -142,7 +142,7 @@ msgstr "Dettagli del nome di default DCI" msgid "Default directory for new films" msgstr "Directory di default per i nuovi films" -#: src/wx/film_editor.cc:116 src/wx/job_manager_view.cc:88 +#: src/wx/film_editor.cc:117 src/wx/job_manager_view.cc:88 msgid "Details..." msgstr "Dettagli" @@ -150,7 +150,7 @@ msgstr "Dettagli" msgid "Disk space required" msgstr "Spazio su disco rischiesto" -#: src/wx/film_editor.cc:191 +#: src/wx/film_editor.cc:192 msgid "Duration" msgstr "Durata" @@ -159,7 +159,7 @@ msgid "Edit" msgstr "Modifica" #: src/wx/config_dialog.cc:84 src/wx/config_dialog.cc:103 -#: src/wx/film_editor.cc:308 +#: src/wx/film_editor.cc:309 msgid "Edit..." msgstr "Modifica..." @@ -167,7 +167,7 @@ msgstr "Modifica..." msgid "Encoding Servers" msgstr "Servers di codifica" -#: src/wx/film_editor.cc:176 +#: src/wx/film_editor.cc:177 msgid "End" msgstr "Fine" @@ -175,23 +175,23 @@ msgstr "Fine" msgid "Facility (e.g. DLA)" msgstr "Facility (es. DLA)" -#: src/wx/film_editor.cc:73 +#: src/wx/film_editor.cc:74 msgid "Film" msgstr "Film" #: src/wx/properties_dialog.cc:36 msgid "Film Properties" -msgstr "Proprietà del film" +msgstr "Proprietà del film" #: src/wx/new_film_dialog.cc:42 msgid "Film name" msgstr "Nome del film" -#: src/wx/film_editor.cc:303 src/wx/filter_dialog.cc:32 +#: src/wx/film_editor.cc:304 src/wx/filter_dialog.cc:32 msgid "Filters" msgstr "Filtri" -#: src/wx/film_editor.cc:268 +#: src/wx/film_editor.cc:269 msgid "Format" msgstr "Formato" @@ -201,7 +201,7 @@ msgstr "Fotogrammi" #: src/wx/properties_dialog.cc:49 msgid "Frames already encoded" -msgstr "Fotogrammi già codificati" +msgstr "Fotogrammi già codificati" #: src/wx/gain_calculator_dialog.cc:27 msgid "Gain Calculator" @@ -215,7 +215,7 @@ msgstr "Gb" msgid "Host name or IP address" msgstr "Nome dell'Host o indirizzo IP" -#: src/wx/film_editor.cc:1233 +#: src/wx/film_editor.cc:1234 msgid "Hz" msgstr "Hz" @@ -227,19 +227,19 @@ msgstr "Voglio riprodurrlo back at fader" msgid "IP address" msgstr "Indirizzo IP" -#: src/wx/film_editor.cc:335 +#: src/wx/film_editor.cc:336 msgid "JPEG2000 bandwidth" msgstr "Banda passante JPEG2000" -#: src/wx/film_editor.cc:281 +#: src/wx/film_editor.cc:282 msgid "Left crop" -msgstr "Taglio sinistro" +msgstr "Taglio a sinistra" -#: src/wx/film_editor.cc:164 +#: src/wx/film_editor.cc:165 msgid "Length" msgstr "Lunghezza" -#: src/wx/film_editor.cc:339 +#: src/wx/film_editor.cc:340 msgid "MBps" msgstr "MBps" @@ -247,7 +247,7 @@ msgstr "MBps" msgid "My Documents" msgstr "Documenti" -#: src/wx/film_editor.cc:104 +#: src/wx/film_editor.cc:105 msgid "Name" msgstr "Nome" @@ -255,15 +255,15 @@ msgstr "Nome" msgid "New Film" msgstr "Nuovo Film" -#: src/wx/film_editor.cc:305 src/wx/film_editor.cc:664 +#: src/wx/film_editor.cc:306 src/wx/film_editor.cc:665 msgid "None" msgstr "Nessuno" -#: src/wx/film_editor.cc:135 +#: src/wx/film_editor.cc:136 msgid "Original Frame Rate" -msgstr "Frequenza Fotogrammi Originale" +msgstr "Frequenza fotogrammi originale" -#: src/wx/film_editor.cc:159 +#: src/wx/film_editor.cc:160 msgid "Original Size" msgstr "Dimensione Originale" @@ -293,41 +293,41 @@ msgstr "Classificazione (es. 15)" #: src/wx/config_dialog.cc:99 msgid "Reference filters for A/B" -msgstr "Riferimento dei filtri per A/B" +msgstr "Filtri di riferimento A/B" #: src/wx/config_dialog.cc:88 msgid "Reference scaler for A/B" -msgstr "Scalatura di riferimento per A/B" +msgstr "Scalatura di riferimento A/B" #: src/wx/config_dialog.cc:128 msgid "Remove" msgstr "Rimuovi" -#: src/wx/film_editor.cc:286 +#: src/wx/film_editor.cc:287 msgid "Right crop" -msgstr "Taglio destro" +msgstr "Taglio a destra" #: src/wx/job_manager_view.cc:104 msgid "Running" msgstr "In corso" -#: src/wx/film_editor.cc:315 +#: src/wx/film_editor.cc:316 msgid "Scaler" msgstr "Scaler" -#: src/wx/film_editor.cc:407 +#: src/wx/film_editor.cc:408 msgid "Select Audio File" msgstr "Seleziona File Audio" -#: src/wx/film_editor.cc:121 +#: src/wx/film_editor.cc:122 msgid "Select Content File" -msgstr "Seleziona FIle del Contenuto" +msgstr "Seleziona il file con il contenuto" #: src/wx/server_dialog.cc:25 msgid "Server" msgstr "Server" -#: src/wx/film_editor.cc:364 +#: src/wx/film_editor.cc:365 msgid "Show Audio..." msgstr "Mostra Audio..." @@ -335,9 +335,9 @@ msgstr "Mostra Audio..." msgid "Smoothing" msgstr "Levigatura" -#: src/wx/film_editor.cc:173 +#: src/wx/film_editor.cc:174 msgid "Start" -msgstr "Avvio" +msgstr "Inizio" #: src/wx/dci_metadata_dialog.cc:49 msgid "Studio (e.g. TCF)" @@ -347,15 +347,15 @@ msgstr "Studio (es. TCF)" msgid "Subtitle Language (e.g. FR)" msgstr "Lingua dei Sottotitoli (es. FR)" -#: src/wx/film_editor.cc:431 +#: src/wx/film_editor.cc:432 msgid "Subtitle Offset" msgstr "Sfalsamento dei Sottotitoli" -#: src/wx/film_editor.cc:436 +#: src/wx/film_editor.cc:437 msgid "Subtitle Scale" msgstr "Scala dei Sottotitoli" -#: src/wx/film_editor.cc:79 +#: src/wx/film_editor.cc:80 msgid "Subtitles" msgstr "Sottotitoli" @@ -395,15 +395,15 @@ msgstr "Threads da usare per codificare su questo host" msgid "Time" msgstr "Tempo" -#: src/wx/film_editor.cc:291 +#: src/wx/film_editor.cc:292 msgid "Top crop" -msgstr "Taglio superiore" +msgstr "Taglio in alto" -#: src/wx/film_editor.cc:171 +#: src/wx/film_editor.cc:172 msgid "Trim frames" msgstr "Taglia fotogrammi" -#: src/wx/film_editor.cc:125 +#: src/wx/film_editor.cc:126 msgid "Trust content's header" msgstr "Conferma l'intestazione del contenuto" @@ -411,31 +411,31 @@ msgstr "Conferma l'intestazione del contenuto" msgid "Type" msgstr "Tipo" -#: src/wx/film_editor.cc:114 +#: src/wx/film_editor.cc:115 msgid "Use DCI name" msgstr "Usa nome DCI" -#: src/wx/film_editor.cc:145 +#: src/wx/film_editor.cc:146 msgid "Use best" -msgstr "Usa il migliore" +msgstr "Usa la migliore" -#: src/wx/film_editor.cc:391 +#: src/wx/film_editor.cc:392 msgid "Use content's audio" msgstr "Usa l'audio del contenuto" -#: src/wx/film_editor.cc:401 +#: src/wx/film_editor.cc:402 msgid "Use external audio" msgstr "Usa l'audio esterno" -#: src/wx/film_editor.cc:75 +#: src/wx/film_editor.cc:76 msgid "Video" msgstr "Video" -#: src/wx/film_editor.cc:424 +#: src/wx/film_editor.cc:425 msgid "With Subtitles" msgstr "Con Sottotitoli" -#: src/wx/film_editor.cc:1231 +#: src/wx/film_editor.cc:1232 msgid "channels" msgstr "canali" @@ -443,21 +443,21 @@ msgstr "canali" msgid "counting..." msgstr "conteggio..." -#: src/wx/film_editor.cc:373 +#: src/wx/film_editor.cc:374 msgid "dB" msgstr "dB" -#: src/wx/film_editor.cc:690 src/wx/film_editor.cc:692 +#: src/wx/film_editor.cc:691 src/wx/film_editor.cc:693 msgid "frames" msgstr "fotogrammi" #. / TRANSLATORS: this is an abbreviation for milliseconds, the unit of time -#: src/wx/film_editor.cc:386 +#: src/wx/film_editor.cc:387 msgid "ms" msgstr "ms" #. / TRANSLATORS: `s' here is an abbreviation for seconds, the unit of time -#: src/wx/film_editor.cc:197 +#: src/wx/film_editor.cc:198 msgid "s" msgstr "s" -- cgit v1.2.3 From bac13662dc8a3b400121d04e65d24e47720164e4 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 20 Mar 2013 13:38:10 +0000 Subject: Merge new messages into italian translation. --- src/lib/po/it_IT.po | 38 ++++++++++++++--- src/tools/po/it_IT.po | 8 ++-- src/wx/po/it_IT.po | 110 +++++++++++++++++++++++++------------------------- 3 files changed, 92 insertions(+), 64 deletions(-) (limited to 'src') diff --git a/src/lib/po/it_IT.po b/src/lib/po/it_IT.po index 96a21263a..9c7dc4851 100644 --- a/src/lib/po/it_IT.po +++ b/src/lib/po/it_IT.po @@ -7,15 +7,15 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-15 08:39+0000\n" +"POT-Creation-Date: 2013-03-20 13:37+0000\n" "PO-Revision-Date: 2013-03-20 11:45+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" +"Language: Italiano\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" -"Language: Italiano\n" #: src/lib/transcode_job.cc:87 msgid "0%" @@ -89,6 +89,10 @@ msgstr "Bicubica" msgid "Bilinear" msgstr "Bilineare" +#: src/lib/exceptions.cc:60 +msgid "Cannot handle pixel format %1 during %2" +msgstr "" + #: src/lib/encoder.cc:101 msgid "Cannot resample audio as libswresample is not present" msgstr "Non posso ricampionare l'audio perchè libswresample non è presente" @@ -466,6 +470,11 @@ msgstr "tipo di contenuto" msgid "copying %1" msgstr "copia %1" +#: src/lib/exceptions.cc:36 +#, fuzzy +msgid "could not create file %1" +msgstr "Non posso scrivere il file remoto (%1)" + #: src/lib/ffmpeg_decoder.cc:191 msgid "could not find audio decoder" msgstr "non riesco a trovare il decoder audio" @@ -482,14 +491,24 @@ msgstr "non riesco a trovare il decoder dei sottotitoli" msgid "could not find video decoder" msgstr "non riesco a trovare il decoder video" -#: src/lib/external_audio_decoder.cc:72 +#: src/lib/sndfile_decoder.cc:72 msgid "could not open external audio file for reading" msgstr "non riesco ad aprire il file dell'audio esterno per leggerlo" +#: src/lib/exceptions.cc:29 +#, fuzzy +msgid "could not open file %1" +msgstr "non riesco ad aprire il file per leggerlo" + #: src/lib/dcp_video_frame.cc:388 msgid "could not open file for reading" msgstr "non riesco ad aprire il file per leggerlo" +#: src/lib/exceptions.cc:44 +#, fuzzy +msgid "could not read from file %1 (%2)" +msgstr "Non posso creare la directory remota %1 (%2)" + #: src/lib/encoder.cc:137 src/lib/encoder.cc:314 msgid "could not run sample-rate converter" msgstr "non riesco a lanciare il convertitore della frequenza di campionamento" @@ -502,6 +521,11 @@ msgstr "non posso avviare la sessione SCP (%1)" msgid "could not start SSH session" msgstr "non posso avviare la sessione SSH" +#: src/lib/exceptions.cc:50 +#, fuzzy +msgid "could not write to file %1 (%2)" +msgstr "Non posso scrivere il file remoto (%1)" + #: src/lib/encoder.cc:247 msgid "decoder sleeps with queue of %1" msgstr "il decoder è in pausa con la coda di %1" @@ -510,11 +534,11 @@ msgstr "il decoder è in pausa con la coda di %1" msgid "decoder wakes with queue of %1" msgstr "il decoder riparte con la coda di %1" -#: src/lib/external_audio_decoder.cc:94 +#: src/lib/sndfile_decoder.cc:94 msgid "external audio files have differing lengths" msgstr "i files dell'audio esterno hanno durata diversa" -#: src/lib/external_audio_decoder.cc:76 +#: src/lib/sndfile_decoder.cc:76 msgid "external audio files must be mono" msgstr "i files dell'audio esterno devono essere mono" @@ -546,6 +570,10 @@ msgstr "minuti" msgid "missing key %1 in key-value set" msgstr "persa la chiave %1 tra i valori chiave" +#: src/lib/exceptions.cc:54 +msgid "missing required setting %1" +msgstr "" + #: src/lib/subtitle.cc:52 msgid "multi-part subtitles not yet supported" msgstr "sottotitoli multi-part non ancora supportati" diff --git a/src/tools/po/it_IT.po b/src/tools/po/it_IT.po index 07fd648c8..89385047b 100644 --- a/src/tools/po/it_IT.po +++ b/src/tools/po/it_IT.po @@ -7,15 +7,15 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-15 08:39+0000\n" +"POT-Creation-Date: 2013-03-20 13:37+0000\n" "PO-Revision-Date: 2013-03-20 12:03+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" +"Language: Italiano\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" -"Language: Italiano\n" #: src/tools/dvdomatic.cc:177 msgid "&Analyse audio" @@ -75,7 +75,7 @@ msgstr "" msgid "About" msgstr "Informazioni" -#: src/tools/dvdomatic.cc:497 +#: src/tools/dvdomatic.cc:500 msgid "Could not load film %1 (%2)" msgstr "Non posso caricare il film %1 (%2)" @@ -85,7 +85,7 @@ msgid "Could not open film at %s (%s)" msgstr "Non posso aprire il film in %s (%s)" #: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:402 -#: src/tools/dvdomatic.cc:501 +#: src/tools/dvdomatic.cc:504 msgid "DVD-o-matic" msgstr "DVD-o-matic" diff --git a/src/wx/po/it_IT.po b/src/wx/po/it_IT.po index d1e8e9355..89ae9efec 100644 --- a/src/wx/po/it_IT.po +++ b/src/wx/po/it_IT.po @@ -7,25 +7,25 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-15 08:39+0000\n" +"POT-Creation-Date: 2013-03-20 13:37+0000\n" "PO-Revision-Date: 2013-03-20 11:50+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" +"Language: Italiano\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" -"Language: Italiano\n" -#: src/wx/film_editor.cc:441 +#: src/wx/film_editor.cc:440 msgid "%" msgstr "%" -#: src/wx/film_editor.cc:1230 +#: src/wx/film_editor.cc:1229 msgid "1 channel" msgstr "Canale 1" -#: src/wx/film_editor.cc:185 +#: src/wx/film_editor.cc:184 msgid "A/B" msgstr "A/B" @@ -33,15 +33,15 @@ msgstr "A/B" msgid "Add" msgstr "Aggiungi" -#: src/wx/audio_dialog.cc:32 src/wx/film_editor.cc:78 +#: src/wx/audio_dialog.cc:32 src/wx/film_editor.cc:77 msgid "Audio" msgstr "Audio" -#: src/wx/film_editor.cc:382 +#: src/wx/film_editor.cc:381 msgid "Audio Delay" msgstr "Ritardo dell'audio" -#: src/wx/film_editor.cc:370 +#: src/wx/film_editor.cc:369 msgid "Audio Gain" msgstr "Guadagno dell'audio" @@ -54,7 +54,7 @@ msgstr "Lingua dell'audio (es. EN)" msgid "Bad setting for %s (%s)" msgstr "Valore sbagliato per %s (%s)" -#: src/wx/film_editor.cc:297 +#: src/wx/film_editor.cc:296 msgid "Bottom crop" msgstr "Taglio in basso" @@ -66,7 +66,7 @@ msgstr "Sfoglia..." msgid "But I have to use fader" msgstr "Ma devo usare il fader" -#: src/wx/film_editor.cc:375 +#: src/wx/film_editor.cc:374 msgid "Calculate..." msgstr "Calcola..." @@ -74,15 +74,15 @@ msgstr "Calcola..." msgid "Channels" msgstr "Canali" -#: src/wx/film_editor.cc:326 +#: src/wx/film_editor.cc:325 msgid "Colour look-up table" msgstr "Tabella per ricerca del colore" -#: src/wx/film_editor.cc:121 +#: src/wx/film_editor.cc:120 msgid "Content" msgstr "Contenuto" -#: src/wx/film_editor.cc:131 +#: src/wx/film_editor.cc:130 msgid "Content Type" msgstr "Tipo di contenuto" @@ -101,7 +101,7 @@ msgstr "Non posso creare il DCP: %s" msgid "Could not open content file (%s)" msgstr "Non posso aprire il file del contenuto (%s)" -#: src/wx/film_editor.cc:505 +#: src/wx/film_editor.cc:504 #, c-format msgid "Could not set content: %s" msgstr "Non posso regolare il contenuto: %s" @@ -114,11 +114,11 @@ msgstr "Crea nella cartella" msgid "DCI name" msgstr "Nome del DCP" -#: src/wx/film_editor.cc:142 +#: src/wx/film_editor.cc:141 msgid "DCP Frame Rate" msgstr "Frequenza fotogrammi del DCP" -#: src/wx/film_editor.cc:110 +#: src/wx/film_editor.cc:109 msgid "DCP Name" msgstr "Nome del DCP" @@ -142,7 +142,7 @@ msgstr "Dettagli del nome di default DCI" msgid "Default directory for new films" msgstr "Directory di default per i nuovi films" -#: src/wx/film_editor.cc:117 src/wx/job_manager_view.cc:88 +#: src/wx/film_editor.cc:116 src/wx/job_manager_view.cc:88 msgid "Details..." msgstr "Dettagli" @@ -150,7 +150,7 @@ msgstr "Dettagli" msgid "Disk space required" msgstr "Spazio su disco rischiesto" -#: src/wx/film_editor.cc:192 +#: src/wx/film_editor.cc:191 msgid "Duration" msgstr "Durata" @@ -159,7 +159,7 @@ msgid "Edit" msgstr "Modifica" #: src/wx/config_dialog.cc:84 src/wx/config_dialog.cc:103 -#: src/wx/film_editor.cc:309 +#: src/wx/film_editor.cc:308 msgid "Edit..." msgstr "Modifica..." @@ -167,7 +167,7 @@ msgstr "Modifica..." msgid "Encoding Servers" msgstr "Servers di codifica" -#: src/wx/film_editor.cc:177 +#: src/wx/film_editor.cc:176 msgid "End" msgstr "Fine" @@ -175,7 +175,7 @@ msgstr "Fine" msgid "Facility (e.g. DLA)" msgstr "Facility (es. DLA)" -#: src/wx/film_editor.cc:74 +#: src/wx/film_editor.cc:73 msgid "Film" msgstr "Film" @@ -187,11 +187,11 @@ msgstr "Proprietà del film" msgid "Film name" msgstr "Nome del film" -#: src/wx/film_editor.cc:304 src/wx/filter_dialog.cc:32 +#: src/wx/film_editor.cc:303 src/wx/filter_dialog.cc:32 msgid "Filters" msgstr "Filtri" -#: src/wx/film_editor.cc:269 +#: src/wx/film_editor.cc:268 msgid "Format" msgstr "Formato" @@ -215,7 +215,7 @@ msgstr "Gb" msgid "Host name or IP address" msgstr "Nome dell'Host o indirizzo IP" -#: src/wx/film_editor.cc:1234 +#: src/wx/film_editor.cc:1233 msgid "Hz" msgstr "Hz" @@ -227,19 +227,19 @@ msgstr "Voglio riprodurrlo back at fader" msgid "IP address" msgstr "Indirizzo IP" -#: src/wx/film_editor.cc:336 +#: src/wx/film_editor.cc:335 msgid "JPEG2000 bandwidth" msgstr "Banda passante JPEG2000" -#: src/wx/film_editor.cc:282 +#: src/wx/film_editor.cc:281 msgid "Left crop" msgstr "Taglio a sinistra" -#: src/wx/film_editor.cc:165 +#: src/wx/film_editor.cc:164 msgid "Length" msgstr "Lunghezza" -#: src/wx/film_editor.cc:340 +#: src/wx/film_editor.cc:339 msgid "MBps" msgstr "MBps" @@ -247,7 +247,7 @@ msgstr "MBps" msgid "My Documents" msgstr "Documenti" -#: src/wx/film_editor.cc:105 +#: src/wx/film_editor.cc:104 msgid "Name" msgstr "Nome" @@ -255,15 +255,15 @@ msgstr "Nome" msgid "New Film" msgstr "Nuovo Film" -#: src/wx/film_editor.cc:306 src/wx/film_editor.cc:665 +#: src/wx/film_editor.cc:305 src/wx/film_editor.cc:664 msgid "None" msgstr "Nessuno" -#: src/wx/film_editor.cc:136 +#: src/wx/film_editor.cc:135 msgid "Original Frame Rate" msgstr "Frequenza fotogrammi originale" -#: src/wx/film_editor.cc:160 +#: src/wx/film_editor.cc:159 msgid "Original Size" msgstr "Dimensione Originale" @@ -303,7 +303,7 @@ msgstr "Scalatura di riferimento A/B" msgid "Remove" msgstr "Rimuovi" -#: src/wx/film_editor.cc:287 +#: src/wx/film_editor.cc:286 msgid "Right crop" msgstr "Taglio a destra" @@ -311,15 +311,15 @@ msgstr "Taglio a destra" msgid "Running" msgstr "In corso" -#: src/wx/film_editor.cc:316 +#: src/wx/film_editor.cc:315 msgid "Scaler" msgstr "Scaler" -#: src/wx/film_editor.cc:408 +#: src/wx/film_editor.cc:407 msgid "Select Audio File" msgstr "Seleziona File Audio" -#: src/wx/film_editor.cc:122 +#: src/wx/film_editor.cc:121 msgid "Select Content File" msgstr "Seleziona il file con il contenuto" @@ -327,7 +327,7 @@ msgstr "Seleziona il file con il contenuto" msgid "Server" msgstr "Server" -#: src/wx/film_editor.cc:365 +#: src/wx/film_editor.cc:364 msgid "Show Audio..." msgstr "Mostra Audio..." @@ -335,7 +335,7 @@ msgstr "Mostra Audio..." msgid "Smoothing" msgstr "Levigatura" -#: src/wx/film_editor.cc:174 +#: src/wx/film_editor.cc:173 msgid "Start" msgstr "Inizio" @@ -347,15 +347,15 @@ msgstr "Studio (es. TCF)" msgid "Subtitle Language (e.g. FR)" msgstr "Lingua dei Sottotitoli (es. FR)" -#: src/wx/film_editor.cc:432 +#: src/wx/film_editor.cc:431 msgid "Subtitle Offset" msgstr "Sfalsamento dei Sottotitoli" -#: src/wx/film_editor.cc:437 +#: src/wx/film_editor.cc:436 msgid "Subtitle Scale" msgstr "Scala dei Sottotitoli" -#: src/wx/film_editor.cc:80 +#: src/wx/film_editor.cc:79 msgid "Subtitles" msgstr "Sottotitoli" @@ -395,15 +395,15 @@ msgstr "Threads da usare per codificare su questo host" msgid "Time" msgstr "Tempo" -#: src/wx/film_editor.cc:292 +#: src/wx/film_editor.cc:291 msgid "Top crop" msgstr "Taglio in alto" -#: src/wx/film_editor.cc:172 +#: src/wx/film_editor.cc:171 msgid "Trim frames" msgstr "Taglia fotogrammi" -#: src/wx/film_editor.cc:126 +#: src/wx/film_editor.cc:125 msgid "Trust content's header" msgstr "Conferma l'intestazione del contenuto" @@ -411,31 +411,31 @@ msgstr "Conferma l'intestazione del contenuto" msgid "Type" msgstr "Tipo" -#: src/wx/film_editor.cc:115 +#: src/wx/film_editor.cc:114 msgid "Use DCI name" msgstr "Usa nome DCI" -#: src/wx/film_editor.cc:146 +#: src/wx/film_editor.cc:145 msgid "Use best" msgstr "Usa la migliore" -#: src/wx/film_editor.cc:392 +#: src/wx/film_editor.cc:391 msgid "Use content's audio" msgstr "Usa l'audio del contenuto" -#: src/wx/film_editor.cc:402 +#: src/wx/film_editor.cc:401 msgid "Use external audio" msgstr "Usa l'audio esterno" -#: src/wx/film_editor.cc:76 +#: src/wx/film_editor.cc:75 msgid "Video" msgstr "Video" -#: src/wx/film_editor.cc:425 +#: src/wx/film_editor.cc:424 msgid "With Subtitles" msgstr "Con Sottotitoli" -#: src/wx/film_editor.cc:1232 +#: src/wx/film_editor.cc:1231 msgid "channels" msgstr "canali" @@ -443,21 +443,21 @@ msgstr "canali" msgid "counting..." msgstr "conteggio..." -#: src/wx/film_editor.cc:374 +#: src/wx/film_editor.cc:373 msgid "dB" msgstr "dB" -#: src/wx/film_editor.cc:691 src/wx/film_editor.cc:693 +#: src/wx/film_editor.cc:690 src/wx/film_editor.cc:692 msgid "frames" msgstr "fotogrammi" #. / TRANSLATORS: this is an abbreviation for milliseconds, the unit of time -#: src/wx/film_editor.cc:387 +#: src/wx/film_editor.cc:386 msgid "ms" msgstr "ms" #. / TRANSLATORS: `s' here is an abbreviation for seconds, the unit of time -#: src/wx/film_editor.cc:198 +#: src/wx/film_editor.cc:197 msgid "s" msgstr "s" -- cgit v1.2.3 From 53a3ea31e2ffb413dc926ff44e1a9fc98189834f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 20 Mar 2013 13:40:59 +0000 Subject: Hopefully fix French translation encoding. --- src/lib/po/fr_FR.po | 232 +++++++++++++++++++++++--------------------------- src/tools/po/fr_FR.po | 32 +++---- src/wx/po/fr_FR.po | 198 +++++++++++++++++++++--------------------- 3 files changed, 227 insertions(+), 235 deletions(-) (limited to 'src') diff --git a/src/lib/po/fr_FR.po b/src/lib/po/fr_FR.po index 56bd03fac..e48d0423d 100644 --- a/src/lib/po/fr_FR.po +++ b/src/lib/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-20 10:29+0000\n" +"POT-Creation-Date: 2013-03-05 13:49+0000\n" "PO-Revision-Date: 2013-03-20 00:39+0100\n" "Last-Translator: FreeDCP.net \n" "Language-Team: \n" @@ -16,7 +16,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: src/lib/transcode_job.cc:87 +#: src/lib/transcode_job.cc:90 msgid "0%" msgstr "0%" @@ -50,7 +50,7 @@ msgstr "16:9 dans Flat" #: src/lib/filter.cc:88 msgid "3D denoiser" -msgstr "D??bruitage 3D" +msgstr "Débruitage 3D" #: src/lib/format.cc:90 msgid "4:3 within Flat" @@ -72,7 +72,7 @@ msgstr "Advertisement" msgid "An error occurred whilst handling the file %1." msgstr "Une erreur s'est produite lors du traitement du fichier %1." -#: src/lib/analyse_audio_job.cc:49 +#: src/lib/analyse_audio_job.cc:48 msgid "Analyse audio of %1" msgstr "Analyse du son de %1" @@ -86,15 +86,11 @@ msgstr "Bicubique" #: src/lib/scaler.cc:69 msgid "Bilinear" -msgstr "Bilin??aire" - -#: src/lib/exceptions.cc:60 -msgid "Cannot handle pixel format %1 during %2" -msgstr "" +msgstr "Bilinéaire" #: src/lib/encoder.cc:101 msgid "Cannot resample audio as libswresample is not present" -msgstr "R??-??chantillonnage du son impossible : libswresample est absent" +msgstr "Ré-échantillonnage du son impossible : libswresample est absent" #: src/lib/scp_dcp_job.cc:109 msgid "Copy DCP to TMS" @@ -106,7 +102,7 @@ msgstr "Connexion au serveur %1 (%2) impossible" #: src/lib/scp_dcp_job.cc:150 msgid "Could not create remote directory %1 (%2)" -msgstr "Cr??ation du dossier distant %1 (%2) impossible" +msgstr "Création du dossier distant %1 (%2) impossible" #: src/lib/scp_dcp_job.cc:175 msgid "Could not open %1 to send" @@ -114,38 +110,48 @@ msgstr "Ouverture de %1 pour envoi impossible" #: src/lib/scp_dcp_job.cc:145 msgid "Could not start SCP session (%1)" -msgstr "D??marrage de session SCP (%1) impossible" +msgstr "Démarrage de session SCP (%1) impossible" #: src/lib/scp_dcp_job.cc:187 msgid "Could not write to remote file (%1)" -msgstr "??criture vers fichier distant (%1) impossible" +msgstr "Écriture vers fichier distant (%1) impossible" #: src/lib/filter.cc:77 msgid "Cubic interpolating deinterlacer" -msgstr "D??sentrelacement cubique interpol??" +msgstr "Désentrelacement cubique interpolé" #: src/lib/util.cc:965 msgid "DCP and source have the same rate.\n" -msgstr "Le DCP et la source ont les m??mes cadences.\n" +msgstr "Le DCP et la source ont les mêmes cadences.\n" #: src/lib/util.cc:975 msgid "DCP will run at %1%% of the source speed." -msgstr "La cadence du DCP sera %1%% par rapport ?? la source" +msgstr "La cadence du DCP sera %1%% par rapport à la source" #: src/lib/util.cc:968 msgid "DCP will use every other frame of the source.\n" msgstr "Le DCP utilisera une image sur deux de la source.\n" -#: src/lib/filter.cc:68 src/lib/filter.cc:69 src/lib/filter.cc:70 -#: src/lib/filter.cc:71 src/lib/filter.cc:72 src/lib/filter.cc:73 +#: src/lib/filter.cc:68 +#: src/lib/filter.cc:69 +#: src/lib/filter.cc:70 +#: src/lib/filter.cc:71 +#: src/lib/filter.cc:72 +#: src/lib/filter.cc:73 msgid "De-blocking" msgstr "De-bloc" -#: src/lib/filter.cc:75 src/lib/filter.cc:76 src/lib/filter.cc:77 -#: src/lib/filter.cc:78 src/lib/filter.cc:79 src/lib/filter.cc:80 -#: src/lib/filter.cc:81 src/lib/filter.cc:82 src/lib/filter.cc:83 +#: src/lib/filter.cc:75 +#: src/lib/filter.cc:76 +#: src/lib/filter.cc:77 +#: src/lib/filter.cc:78 +#: src/lib/filter.cc:79 +#: src/lib/filter.cc:80 +#: src/lib/filter.cc:81 +#: src/lib/filter.cc:82 +#: src/lib/filter.cc:83 msgid "De-interlacing" -msgstr "D??sentrelacement" +msgstr "Désentrelacement" #: src/lib/filter.cc:74 msgid "Deringing filter" @@ -157,7 +163,7 @@ msgstr "Dolby CP750" #: src/lib/util.cc:970 msgid "Each source frame will be doubled in the DCP.\n" -msgstr "Chaque image source sera dupliqu??e dans le DCP.\n" +msgstr "Chaque image source sera dupliquée dans le DCP.\n" #: src/lib/job.cc:287 msgid "Error (%1)" @@ -173,27 +179,27 @@ msgstr "Examen du contenu de %1" #: src/lib/filter.cc:72 msgid "Experimental horizontal deblocking filter 1" -msgstr "Filtre d??-bloc horizontal 1" +msgstr "Filtre dé-bloc horizontal 1" #: src/lib/filter.cc:73 msgid "Experimental vertical deblocking filter 1" -msgstr "Filtre d??-bloc vertical 1" +msgstr "Filtre dé-bloc vertical 1" #: src/lib/filter.cc:79 msgid "FFMPEG deinterlacer" -msgstr "D??sentrelaceur FFMPEG" +msgstr "Désentrelaceur FFMPEG" #: src/lib/filter.cc:80 msgid "FIR low-pass deinterlacer" -msgstr "D??sentrelaceur passe-bas FIR" +msgstr "Désentrelaceur passe-bas FIR" #: src/lib/scp_dcp_job.cc:138 msgid "Failed to authenticate with server (%1)" -msgstr "L'authentification du serveur (%1) a ??chou??e" +msgstr "L'authentification du serveur (%1) a échouée" #: src/lib/scaler.cc:70 msgid "Fast Bilinear" -msgstr "Bilin??aire rapide" +msgstr "Bilinéaire rapide" #: src/lib/dcp_content_type.cc:44 msgid "Feature" @@ -205,7 +211,7 @@ msgstr "Flat" #: src/lib/format.cc:130 msgid "Flat without stretch" -msgstr "Flat sans ??tirement" +msgstr "Flat sans étirement" #: src/lib/filter.cc:85 msgid "Force quantizer" @@ -217,31 +223,28 @@ msgstr "Gaussien" #: src/lib/filter.cc:86 msgid "Gradient debander" -msgstr "Corrections des bandes du d??grad??" +msgstr "Corrections des bandes du dégradé" #: src/lib/filter.cc:89 msgid "High quality 3D denoiser" -msgstr "D??bruiteur 3D haute qualit??" +msgstr "Débruiteur 3D haute qualité" #: src/lib/filter.cc:68 msgid "Horizontal deblocking filter" -msgstr "Filtre d??bloc horizontal" +msgstr "Filtre débloc horizontal" #: src/lib/filter.cc:70 msgid "Horizontal deblocking filter A" -msgstr "Filtre d??-bloc horizontal" +msgstr "Filtre dé-bloc horizontal" -#: src/lib/job.cc:87 src/lib/job.cc:96 -msgid "" -"It is not known what caused this error. The best idea is to report the " -"problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" -msgstr "" -"Erreur ind??termin??e. Merci de rapporter le probl??me ?? la liste DVD-o-" -"matic (dvdomatic@carlh.net)" +#: src/lib/job.cc:87 +#: src/lib/job.cc:96 +msgid "It is not known what caused this error. The best idea is to report the problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" +msgstr "Erreur indéterminée. Merci de rapporter le problème à la liste DVD-o-matic (dvdomatic@carlh.net)" #: src/lib/filter.cc:82 msgid "Kernel deinterlacer" -msgstr "D??sentrelaceur noyau" +msgstr "Désentrelaceur noyau" #: src/lib/scaler.cc:66 msgid "Lanczos" @@ -249,29 +252,34 @@ msgstr "Lanczos" #: src/lib/filter.cc:75 msgid "Linear blend deinterlacer" -msgstr "D??sentrelaceur par m??lange interpol??" +msgstr "Désentrelaceur par mélange interpolé" #: src/lib/filter.cc:76 msgid "Linear interpolating deinterlacer" -msgstr "D??sentrelaceur lin??aire interpol??" +msgstr "Désentrelaceur linéaire interpolé" #: src/lib/filter.cc:78 msgid "Median deinterlacer" -msgstr "D??sentrelaceur m??dian" +msgstr "Désentrelaceur médian" -#: src/lib/filter.cc:74 src/lib/filter.cc:85 src/lib/filter.cc:86 -#: src/lib/filter.cc:87 src/lib/filter.cc:90 +#: src/lib/filter.cc:74 +#: src/lib/filter.cc:85 +#: src/lib/filter.cc:86 +#: src/lib/filter.cc:87 +#: src/lib/filter.cc:90 msgid "Misc" msgstr "Divers" #: src/lib/filter.cc:81 msgid "Motion compensating deinterlacer" -msgstr "D??sentrelaceur par compensation de mouvement" +msgstr "Désentrelaceur par compensation de mouvement" -#: src/lib/filter.cc:84 src/lib/filter.cc:88 src/lib/filter.cc:89 +#: src/lib/filter.cc:84 +#: src/lib/filter.cc:88 +#: src/lib/filter.cc:89 #: src/lib/filter.cc:91 msgid "Noise reduction" -msgstr "R??duction de bruit" +msgstr "Réduction de bruit" #: src/lib/job.cc:285 msgid "OK (ran for %1)" @@ -279,7 +287,7 @@ msgstr "OK (processus %1)" #: src/lib/filter.cc:91 msgid "Overcomplete wavelet denoiser" -msgstr "R??duction de bruit par ondelettes" +msgstr "Réduction de bruit par ondelettes" #: src/lib/dcp_content_type.cc:51 msgid "Policy" @@ -307,7 +315,7 @@ msgstr "Scope" #: src/lib/format.cc:135 msgid "Scope without stretch" -msgstr "Scope sans d??formation" +msgstr "Scope sans déformation" #: src/lib/dcp_content_type.cc:45 msgid "Short" @@ -319,55 +327,55 @@ msgstr "Sinc" #: src/lib/format.cc:76 msgid "Source scaled to 1.19:1" -msgstr "Source mise ?? l'??chelle en 1.19:1" +msgstr "Source mise à l'échelle en 1.19:1" #: src/lib/format.cc:81 msgid "Source scaled to 1.33:1" -msgstr "Source mise ?? l'??chelle en 1.33:1" +msgstr "Source mise à l'échelle en 1.33:1" #: src/lib/format.cc:91 msgid "Source scaled to 1.33:1 then pillarboxed to Flat" -msgstr "Source mise ?? l'??chelle en 1.33:1 puis contenue dans Flat" +msgstr "Source mise à l'échelle en 1.33:1 puis contenue dans Flat" #: src/lib/format.cc:86 msgid "Source scaled to 1.375:1" -msgstr "Source mise ?? l'??chelle en 1.375:1" +msgstr "Source mise à l'échelle en 1.375:1" #: src/lib/format.cc:96 msgid "Source scaled to 1.37:1 (Academy ratio)" -msgstr "Source mise ?? l'??chelle en 1.37:1 (ratio \"academy\")" +msgstr "Source mise à l'échelle en 1.37:1 (ratio \"academy\")" #: src/lib/format.cc:101 msgid "Source scaled to 1.66:1" -msgstr "Source mise ?? l'??chelle en 1.66:1" +msgstr "Source mise à l'échelle en 1.66:1" #: src/lib/format.cc:106 msgid "Source scaled to 1.66:1 then pillarboxed to Flat" -msgstr "Source mise ?? l'??chelle en 1.66:1 puis contenue dans Flat" +msgstr "Source mise à l'échelle en 1.66:1 puis contenue dans Flat" #: src/lib/format.cc:116 msgid "Source scaled to 1.78:1" -msgstr "Source mise ?? l'??chelle en 1.78:1" +msgstr "Source mise à l'échelle en 1.78:1" #: src/lib/format.cc:111 msgid "Source scaled to 1.78:1 then pillarboxed to Flat" -msgstr "Source mise ?? l'??chelle en 1.78:1 puis contenue dans Flat" +msgstr "Source mise à l'échelle en 1.78:1 puis contenue dans Flat" #: src/lib/format.cc:121 msgid "Source scaled to Flat (1.85:1)" -msgstr "Source mise ?? l'??chelle en Flat (1.85:1)" +msgstr "Source mise à l'échelle en Flat (1.85:1)" #: src/lib/format.cc:126 msgid "Source scaled to Scope (2.39:1)" -msgstr "Source mise ?? l'??chelle en Scope (2.39:1)" +msgstr "Source mise à l'échelle en Scope (2.39:1)" #: src/lib/format.cc:131 msgid "Source scaled to fit Flat preserving its aspect ratio" -msgstr "Source r??duite en Flat afin de pr??server ses dimensions" +msgstr "Source réduite en Flat afin de préserver ses dimensions" #: src/lib/format.cc:136 msgid "Source scaled to fit Scope preserving its aspect ratio" -msgstr "Source r??duite en Scope afin de pr??server ses dimensions" +msgstr "Source réduite en Scope afin de préserver ses dimensions" #: src/lib/scaler.cc:68 msgid "Spline" @@ -379,23 +387,19 @@ msgstr "Teaser" #: src/lib/filter.cc:90 msgid "Telecine filter" -msgstr "Filtre t??l??cin??ma" +msgstr "Filtre télécinéma" #: src/lib/filter.cc:84 msgid "Temporal noise reducer" -msgstr "R??duction de bruit temporel" +msgstr "Réduction de bruit temporel" #: src/lib/dcp_content_type.cc:47 msgid "Test" msgstr "Test" #: src/lib/job.cc:76 -msgid "" -"The drive that the film is stored on is low in disc space. Free some more " -"space and try again." -msgstr "" -"Le disque contenant le film est plein. Lib??rez de l'espace et essayez ?? " -"nouveau." +msgid "The drive that the film is stored on is low in disc space. Free some more space and try again." +msgstr "Le disque contenant le film est plein. Libérez de l'espace et essayez à nouveau." #: src/lib/dcp_content_type.cc:46 msgid "Trailer" @@ -415,7 +419,7 @@ msgstr "Erreur inconnue" #: src/lib/ffmpeg_decoder.cc:396 msgid "Unrecognised audio sample format (%1)" -msgstr "??chantillonnage audio (%1) inconnu" +msgstr "Échantillonnage audio (%1) inconnu" #: src/lib/filter.cc:87 msgid "Unsharp mask and Gaussian blur" @@ -423,11 +427,11 @@ msgstr "Adoucissement et flou Gaussien" #: src/lib/filter.cc:69 msgid "Vertical deblocking filter" -msgstr "Filtre d??-bloc vertical" +msgstr "Filtre dé-bloc vertical" #: src/lib/filter.cc:71 msgid "Vertical deblocking filter A" -msgstr "Filtre d??-bloc vertical A" +msgstr "Filtre dé-bloc vertical A" #: src/lib/scp_dcp_job.cc:101 msgid "Waiting" @@ -439,7 +443,7 @@ msgstr "X" #: src/lib/filter.cc:83 msgid "Yet Another Deinterlacing Filter" -msgstr "Un autre filtre de d??sentrelacement" +msgstr "Un autre filtre de désentrelacement" #: src/lib/encoder.cc:271 msgid "adding to queue of %1" @@ -451,7 +455,7 @@ msgstr "slash interdit" #: src/lib/util.cc:499 msgid "connect timed out" -msgstr "temps de connexion expir??" +msgstr "temps de connexion expiré" #: src/lib/scp_dcp_job.cc:119 msgid "connecting" @@ -469,14 +473,9 @@ msgstr "type de contenu" msgid "copying %1" msgstr "copie de %1" -#: src/lib/exceptions.cc:36 -#, fuzzy -msgid "could not create file %1" -msgstr "??criture vers fichier distant (%1) impossible" - #: src/lib/ffmpeg_decoder.cc:191 msgid "could not find audio decoder" -msgstr "d??codeur audio introuvable" +msgstr "décodeur audio introuvable" #: src/lib/ffmpeg_decoder.cc:118 msgid "could not find stream information" @@ -484,68 +483,54 @@ msgstr "information du flux introuvable" #: src/lib/ffmpeg_decoder.cc:210 msgid "could not find subtitle decoder" -msgstr "d??codeur de sous-titre introuvable" +msgstr "décodeur de sous-titre introuvable" #: src/lib/ffmpeg_decoder.cc:169 msgid "could not find video decoder" -msgstr "d??codeur vid??o introuvable" +msgstr "décodeur vidéo introuvable" -#: src/lib/sndfile_decoder.cc:72 +#: src/lib/external_audio_decoder.cc:72 msgid "could not open external audio file for reading" msgstr "lecture du fichier audio externe impossible" -#: src/lib/exceptions.cc:29 -#, fuzzy -msgid "could not open file %1" -msgstr "lecture du fichier impossible" - #: src/lib/dcp_video_frame.cc:388 msgid "could not open file for reading" msgstr "lecture du fichier impossible" -#: src/lib/exceptions.cc:44 -#, fuzzy -msgid "could not read from file %1 (%2)" -msgstr "Cr??ation du dossier distant %1 (%2) impossible" - -#: src/lib/encoder.cc:137 src/lib/encoder.cc:314 +#: src/lib/encoder.cc:137 +#: src/lib/encoder.cc:314 msgid "could not run sample-rate converter" -msgstr "conversion de la fr??quence d'??chantillonnage impossible" +msgstr "conversion de la fréquence d'échantillonnage impossible" #: src/lib/scp_dcp_job.cc:86 msgid "could not start SCP session (%1)" -msgstr "d??marrage de session SCP (%1) impossible" +msgstr "démarrage de session SCP (%1) impossible" #: src/lib/scp_dcp_job.cc:52 msgid "could not start SSH session" -msgstr "d??marrage de session SSH impossible" - -#: src/lib/exceptions.cc:50 -#, fuzzy -msgid "could not write to file %1 (%2)" -msgstr "??criture vers fichier distant (%1) impossible" +msgstr "démarrage de session SSH impossible" #: src/lib/encoder.cc:247 msgid "decoder sleeps with queue of %1" -msgstr "d??codeur en veille avec %1 en file d'attente" +msgstr "décodeur en veille avec %1 en file d'attente" #: src/lib/encoder.cc:249 msgid "decoder wakes with queue of %1" -msgstr "reprise du d??codage avec %1 en file d'attente" +msgstr "reprise du décodage avec %1 en file d'attente" -#: src/lib/sndfile_decoder.cc:94 +#: src/lib/external_audio_decoder.cc:94 msgid "external audio files have differing lengths" -msgstr "Les fichiers audio externes ont des dur??es diff??rentes" +msgstr "Les fichiers audio externes ont des durées différentes" -#: src/lib/sndfile_decoder.cc:76 +#: src/lib/external_audio_decoder.cc:76 msgid "external audio files must be mono" -msgstr "les fichiers audio externes doivent ??tre en mono" +msgstr "les fichiers audio externes doivent être en mono" #: src/lib/film.cc:296 msgid "format" msgstr "format" -#: src/lib/transcode_job.cc:100 +#: src/lib/transcode_job.cc:103 msgid "frames per second" msgstr "images par seconde" @@ -553,7 +538,8 @@ msgstr "images par seconde" msgid "hour" msgstr "heure" -#: src/lib/util.cc:112 src/lib/util.cc:117 +#: src/lib/util.cc:112 +#: src/lib/util.cc:117 msgid "hours" msgstr "heures" @@ -567,27 +553,24 @@ msgstr "minutes" #: src/lib/util.cc:642 msgid "missing key %1 in key-value set" -msgstr "cl?? %1 non s??lectionn??e" - -#: src/lib/exceptions.cc:54 -msgid "missing required setting %1" -msgstr "" +msgstr "clé %1 non sélectionnée" #: src/lib/subtitle.cc:52 msgid "multi-part subtitles not yet supported" -msgstr "sous-titres en plusieurs parties non support??s" +msgstr "sous-titres en plusieurs parties non supportés" -#: src/lib/film.cc:263 src/lib/film.cc:308 +#: src/lib/film.cc:263 +#: src/lib/film.cc:308 msgid "name" msgstr "nom" #: src/lib/imagemagick_decoder.cc:60 msgid "no still image files found" -msgstr "aucune image fixe trouv??e" +msgstr "aucune image fixe trouvée" #: src/lib/subtitle.cc:58 msgid "non-bitmap subtitles not yet supported" -msgstr "sous-titres non-bitmap non support??s actuellement" +msgstr "sous-titres non-bitmap non supportés actuellement" #. / TRANSLATORS: remaining here follows an amount of time that is remaining #. / on an operation. @@ -609,4 +592,5 @@ msgstr "fixe" #: src/lib/film.cc:274 msgid "video" -msgstr "vid??o" +msgstr "vidéo" + diff --git a/src/tools/po/fr_FR.po b/src/tools/po/fr_FR.po index 273c1fc32..844406978 100644 --- a/src/tools/po/fr_FR.po +++ b/src/tools/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-20 10:29+0000\n" +"POT-Creation-Date: 2013-03-05 13:49+0000\n" "PO-Revision-Date: 2013-03-13 22:33+0100\n" "Last-Translator: \n" "Language-Team: \n" @@ -38,7 +38,7 @@ msgstr "&Travaux" #: src/tools/dvdomatic.cc:173 msgid "&Make DCP" -msgstr "&Cr??er le DCP" +msgstr "&Créer le DCP" #: src/tools/dvdomatic.cc:161 msgid "&Open..." @@ -46,11 +46,11 @@ msgstr "&Ouvrir..." #: src/tools/dvdomatic.cc:170 msgid "&Preferences..." -msgstr "&Pr??f??rences..." +msgstr "&Préférences..." #: src/tools/dvdomatic.cc:165 msgid "&Properties..." -msgstr "&Propri??t??s..." +msgstr "&Propriétés..." #: src/tools/dvdomatic.cc:167 msgid "&Quit" @@ -65,36 +65,35 @@ msgid "&Send DCP to TMS" msgstr "&Envoyer le DCP dans le TMS" #: src/tools/dvdomatic.cc:409 -msgid "" -"(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" -msgstr "" -"(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" +msgid "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" +msgstr "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" #: src/tools/dvdomatic.cc:180 msgid "About" msgstr "A Propos" -#: src/tools/dvdomatic.cc:500 +#: src/tools/dvdomatic.cc:482 msgid "Could not load film %1 (%2)" msgstr "Impossible de charger le film %1 (%2)" #: src/tools/dvdomatic.cc:331 #, c-format msgid "Could not open film at %s (%s)" -msgstr "Impossible d'ouvrir le film ?? %s (%s)" +msgstr "Impossible d'ouvrir le film à %s (%s)" -#: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:402 -#: src/tools/dvdomatic.cc:504 +#: src/tools/dvdomatic.cc:287 +#: src/tools/dvdomatic.cc:402 +#: src/tools/dvdomatic.cc:486 msgid "DVD-o-matic" msgstr "DVD-o-matic" #: src/tools/dvdomatic.cc:75 msgid "Film changed" -msgstr "Film chang??" +msgstr "Film changé" #: src/tools/dvdomatic.cc:408 msgid "Free, open-source DCP generation from almost anything." -msgstr "Cr??ation de DCP libre et open-source ?? partir de presque tout." +msgstr "Création de DCP libre et open-source à partir de presque tout." #: src/tools/dvdomatic.cc:160 msgid "New..." @@ -106,9 +105,10 @@ msgstr "Voir le DCP" #: src/tools/dvdomatic.cc:319 msgid "Select film to open" -msgstr "S??lectionner le film ?? ouvrir" +msgstr "Sélectionner le film à ouvrir" #: src/tools/dvdomatic.cc:303 #, c-format msgid "The directory %s already exists." -msgstr "Le dossier %s existe d??j??." +msgstr "Le dossier %s existe déjà." + diff --git a/src/wx/po/fr_FR.po b/src/wx/po/fr_FR.po index f91279213..d482d54e4 100644 --- a/src/wx/po/fr_FR.po +++ b/src/wx/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-20 10:29+0000\n" +"POT-Creation-Date: 2013-03-05 13:49+0000\n" "PO-Revision-Date: 2013-03-20 00:34+0100\n" "Last-Translator: FreeDCP.net \n" "Language-Team: \n" @@ -16,15 +16,15 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: src/wx/film_editor.cc:440 +#: src/wx/film_editor.cc:441 msgid "%" msgstr "%" -#: src/wx/film_editor.cc:1229 +#: src/wx/film_editor.cc:1226 msgid "1 channel" msgstr "1 canal" -#: src/wx/film_editor.cc:184 +#: src/wx/film_editor.cc:185 msgid "A/B" msgstr "A/B" @@ -32,15 +32,16 @@ msgstr "A/B" msgid "Add" msgstr "Ajouter" -#: src/wx/audio_dialog.cc:32 src/wx/film_editor.cc:77 +#: src/wx/audio_dialog.cc:32 +#: src/wx/film_editor.cc:78 msgid "Audio" msgstr "Audio" -#: src/wx/film_editor.cc:381 +#: src/wx/film_editor.cc:382 msgid "Audio Delay" -msgstr "D??lai audio" +msgstr "Délai audio" -#: src/wx/film_editor.cc:369 +#: src/wx/film_editor.cc:370 msgid "Audio Gain" msgstr "Gain audio" @@ -51,11 +52,11 @@ msgstr "Langue audio (ex. FR)" #: src/wx/job_wrapper.cc:38 #, c-format msgid "Bad setting for %s (%s)" -msgstr "Mauvais param??tre pour %s (%s)" +msgstr "Mauvais paramètre pour %s (%s)" -#: src/wx/film_editor.cc:296 +#: src/wx/film_editor.cc:297 msgid "Bottom crop" -msgstr "D??coupe bas" +msgstr "Découpe bas" #: src/wx/dir_picker_ctrl.cc:38 msgid "Browse..." @@ -65,7 +66,7 @@ msgstr "Parcourir..." msgid "But I have to use fader" msgstr "Je souhaite utiliser ce volume" -#: src/wx/film_editor.cc:374 +#: src/wx/film_editor.cc:375 msgid "Calculate..." msgstr "Calcul..." @@ -73,51 +74,51 @@ msgstr "Calcul..." msgid "Channels" msgstr "Canaux" -#: src/wx/film_editor.cc:325 +#: src/wx/film_editor.cc:326 msgid "Colour look-up table" -msgstr "Espace colorim??trique" +msgstr "Espace colorimétrique" -#: src/wx/film_editor.cc:120 +#: src/wx/film_editor.cc:121 msgid "Content" msgstr "Contenu" -#: src/wx/film_editor.cc:130 +#: src/wx/film_editor.cc:131 msgid "Content Type" msgstr "Type de Contenu" #: src/wx/film_viewer.cc:414 #, c-format msgid "Could not decode video for view (%s)" -msgstr "D??codage de la vid??o pour visualisation impossible (%s)" +msgstr "Décodage de la vidéo pour visualisation impossible (%s)" #: src/wx/job_wrapper.cc:40 #, c-format msgid "Could not make DCP: %s" -msgstr "Impossible de cr??er le DCP : %s" +msgstr "Impossible de créer le DCP : %s" #: src/wx/film_viewer.cc:108 #, c-format msgid "Could not open content file (%s)" msgstr "Ouverture du contenu impossible (%s)" -#: src/wx/film_editor.cc:504 +#: src/wx/film_editor.cc:505 #, c-format msgid "Could not set content: %s" -msgstr "S??lectionner du contenu impossible : %s" +msgstr "Sélectionner du contenu impossible : %s" #: src/wx/new_film_dialog.cc:46 msgid "Create in folder" -msgstr "Cr??er dans le dossier" +msgstr "Créer dans le dossier" #: src/wx/dci_metadata_dialog.cc:28 msgid "DCI name" msgstr "Nom DCI" -#: src/wx/film_editor.cc:141 +#: src/wx/film_editor.cc:142 msgid "DCP Frame Rate" msgstr "Cadence image du DCP" -#: src/wx/film_editor.cc:109 +#: src/wx/film_editor.cc:110 msgid "DCP Name" msgstr "Nom du DCP" @@ -127,7 +128,7 @@ msgstr "DVD-o-matic" #: src/wx/config_dialog.cc:44 msgid "DVD-o-matic Preferences" -msgstr "Pr??f??rences DVD-o-matic" +msgstr "Préférences DVD-o-matic" #: src/wx/audio_dialog.cc:101 msgid "DVD-o-matic audio - %1" @@ -135,38 +136,40 @@ msgstr "Son DVD-o-matic - %1" #: src/wx/config_dialog.cc:83 msgid "Default DCI name details" -msgstr "D??tails du nom DCI par d??faut" +msgstr "Détails du nom DCI par défaut" #: src/wx/config_dialog.cc:74 msgid "Default directory for new films" -msgstr "Dossier par d??faut des nouveaux films" +msgstr "Dossier par défaut des nouveaux films" -#: src/wx/film_editor.cc:116 src/wx/job_manager_view.cc:88 +#: src/wx/film_editor.cc:117 +#: src/wx/job_manager_view.cc:88 msgid "Details..." -msgstr "D??tails..." +msgstr "Détails..." #: src/wx/properties_dialog.cc:45 msgid "Disk space required" msgstr "Espace disque requis" -#: src/wx/film_editor.cc:191 +#: src/wx/film_editor.cc:192 msgid "Duration" -msgstr "Dur??e" +msgstr "Durée" #: src/wx/config_dialog.cc:126 msgid "Edit" -msgstr "??dition" +msgstr "Édition" -#: src/wx/config_dialog.cc:84 src/wx/config_dialog.cc:103 -#: src/wx/film_editor.cc:308 +#: src/wx/config_dialog.cc:84 +#: src/wx/config_dialog.cc:103 +#: src/wx/film_editor.cc:309 msgid "Edit..." -msgstr "??diter..." +msgstr "Éditer..." #: src/wx/config_dialog.cc:109 msgid "Encoding Servers" msgstr "Serveurs d'encodage" -#: src/wx/film_editor.cc:176 +#: src/wx/film_editor.cc:177 msgid "End" msgstr "Fin" @@ -174,23 +177,24 @@ msgstr "Fin" msgid "Facility (e.g. DLA)" msgstr "Laboratoire (ex. DLA)" -#: src/wx/film_editor.cc:73 +#: src/wx/film_editor.cc:74 msgid "Film" msgstr "Film" #: src/wx/properties_dialog.cc:36 msgid "Film Properties" -msgstr "Propri??t??s du film" +msgstr "Propriétés du film" #: src/wx/new_film_dialog.cc:42 msgid "Film name" msgstr "Nom du Film" -#: src/wx/film_editor.cc:303 src/wx/filter_dialog.cc:32 +#: src/wx/film_editor.cc:304 +#: src/wx/filter_dialog.cc:32 msgid "Filters" msgstr "Filtres" -#: src/wx/film_editor.cc:268 +#: src/wx/film_editor.cc:269 msgid "Format" msgstr "Format" @@ -200,7 +204,7 @@ msgstr "Images" #: src/wx/properties_dialog.cc:49 msgid "Frames already encoded" -msgstr "Images d??j?? encod??es" +msgstr "Images déjà encodées" #: src/wx/gain_calculator_dialog.cc:27 msgid "Gain Calculator" @@ -212,33 +216,33 @@ msgstr "Gb" #: src/wx/server_dialog.cc:36 msgid "Host name or IP address" -msgstr "Nom de l'h??te ou adresse IP" +msgstr "Nom de l'hôte ou adresse IP" -#: src/wx/film_editor.cc:1233 +#: src/wx/film_editor.cc:1230 msgid "Hz" msgstr "Hz" #: src/wx/gain_calculator_dialog.cc:32 msgid "I want to play this back at fader" -msgstr "Je veux le jouer ?? ce volume" +msgstr "Je veux le jouer à ce volume" #: src/wx/config_dialog.cc:113 msgid "IP address" msgstr "Adresse IP" -#: src/wx/film_editor.cc:335 +#: src/wx/film_editor.cc:336 msgid "JPEG2000 bandwidth" -msgstr "Qualit?? JPEG2000" +msgstr "Qualité JPEG2000" -#: src/wx/film_editor.cc:281 +#: src/wx/film_editor.cc:282 msgid "Left crop" -msgstr "D??coupe gauche" +msgstr "Découpe gauche" -#: src/wx/film_editor.cc:164 +#: src/wx/film_editor.cc:165 msgid "Length" msgstr "Longueur" -#: src/wx/film_editor.cc:339 +#: src/wx/film_editor.cc:340 msgid "MBps" msgstr "MBps" @@ -246,7 +250,7 @@ msgstr "MBps" msgid "My Documents" msgstr "Mes Documents" -#: src/wx/film_editor.cc:104 +#: src/wx/film_editor.cc:105 msgid "Name" msgstr "Nom" @@ -254,15 +258,16 @@ msgstr "Nom" msgid "New Film" msgstr "Nouveau Film" -#: src/wx/film_editor.cc:305 src/wx/film_editor.cc:664 +#: src/wx/film_editor.cc:306 +#: src/wx/film_editor.cc:663 msgid "None" msgstr "Aucun" -#: src/wx/film_editor.cc:135 +#: src/wx/film_editor.cc:136 msgid "Original Frame Rate" msgstr "Cadence d'images originale" -#: src/wx/film_editor.cc:159 +#: src/wx/film_editor.cc:160 msgid "Original Size" msgstr "Taille Originale" @@ -272,7 +277,7 @@ msgstr "Type de paquet (ex. OV)" #: src/wx/audio_dialog.cc:60 msgid "Peak" -msgstr "Cr??te" +msgstr "Crête" #: src/wx/film_viewer.cc:54 msgid "Play" @@ -292,41 +297,41 @@ msgstr "Rating (ex. 15)" #: src/wx/config_dialog.cc:99 msgid "Reference filters for A/B" -msgstr "Filtres de r??f??rence pour A/B" +msgstr "Filtres de référence pour A/B" #: src/wx/config_dialog.cc:88 msgid "Reference scaler for A/B" -msgstr "??chelle de r??f??rence pour A7B" +msgstr "Échelle de référence pour A7B" #: src/wx/config_dialog.cc:128 msgid "Remove" msgstr "Supprimer" -#: src/wx/film_editor.cc:286 +#: src/wx/film_editor.cc:287 msgid "Right crop" -msgstr "D??coupe droite" +msgstr "Découpe droite" #: src/wx/job_manager_view.cc:104 msgid "Running" msgstr "Progression" -#: src/wx/film_editor.cc:315 +#: src/wx/film_editor.cc:316 msgid "Scaler" -msgstr "Mise ?? l'??chelle" +msgstr "Mise à l'échelle" -#: src/wx/film_editor.cc:407 +#: src/wx/film_editor.cc:408 msgid "Select Audio File" -msgstr "S??lectionner le fichier son" +msgstr "Sélectionner le fichier son" -#: src/wx/film_editor.cc:121 +#: src/wx/film_editor.cc:122 msgid "Select Content File" -msgstr "S??lectionner le fichier vid??o" +msgstr "Sélectionner le fichier vidéo" #: src/wx/server_dialog.cc:25 msgid "Server" msgstr "Serveur" -#: src/wx/film_editor.cc:364 +#: src/wx/film_editor.cc:365 msgid "Show Audio..." msgstr "Montrer le son..." @@ -334,9 +339,9 @@ msgstr "Montrer le son..." msgid "Smoothing" msgstr "Lissage" -#: src/wx/film_editor.cc:173 +#: src/wx/film_editor.cc:174 msgid "Start" -msgstr "D??but" +msgstr "Début" #: src/wx/dci_metadata_dialog.cc:49 msgid "Studio (e.g. TCF)" @@ -346,15 +351,15 @@ msgstr "Studio (ex. TCF)" msgid "Subtitle Language (e.g. FR)" msgstr "Langue de sous-titres (ex. FR)" -#: src/wx/film_editor.cc:431 +#: src/wx/film_editor.cc:432 msgid "Subtitle Offset" -msgstr "D??calage du sous-titre" +msgstr "Décalage du sous-titre" -#: src/wx/film_editor.cc:436 +#: src/wx/film_editor.cc:437 msgid "Subtitle Scale" msgstr "Taille du sous-titre" -#: src/wx/film_editor.cc:79 +#: src/wx/film_editor.cc:80 msgid "Subtitles" msgstr "Sous-titres" @@ -368,7 +373,7 @@ msgstr "Mot de passe du TMS" #: src/wx/config_dialog.cc:54 msgid "TMS target path" -msgstr "Chemin d'acc??s du TMS" +msgstr "Chemin d'accès du TMS" #: src/wx/config_dialog.cc:59 msgid "TMS user name" @@ -384,57 +389,57 @@ msgstr "Processus" #: src/wx/server_dialog.cc:40 msgid "Threads to use" -msgstr "Nombre de processus ?? utiliser" +msgstr "Nombre de processus à utiliser" #: src/wx/config_dialog.cc:69 msgid "Threads to use for encoding on this host" -msgstr "Nombre de processus ?? utiliser sur cet h??te" +msgstr "Nombre de processus à utiliser sur cet hôte" #: src/wx/audio_plot.cc:139 msgid "Time" -msgstr "Dur??e" +msgstr "Durée" -#: src/wx/film_editor.cc:291 +#: src/wx/film_editor.cc:292 msgid "Top crop" -msgstr "D??coupe haut" +msgstr "Découpe haut" -#: src/wx/film_editor.cc:171 +#: src/wx/film_editor.cc:172 msgid "Trim frames" -msgstr "Images coup??es" +msgstr "Images coupées" -#: src/wx/film_editor.cc:125 +#: src/wx/film_editor.cc:126 msgid "Trust content's header" -msgstr "Faire confiance ?? l'en-t??te" +msgstr "Faire confiance à l'en-tête" #: src/wx/audio_dialog.cc:55 msgid "Type" msgstr "Type" -#: src/wx/film_editor.cc:114 +#: src/wx/film_editor.cc:115 msgid "Use DCI name" msgstr "Utiliser le nom DCI" -#: src/wx/film_editor.cc:145 +#: src/wx/film_editor.cc:146 msgid "Use best" msgstr "Automatique" -#: src/wx/film_editor.cc:391 +#: src/wx/film_editor.cc:392 msgid "Use content's audio" -msgstr "Utiliser le son int??gr??" +msgstr "Utiliser le son intégré" -#: src/wx/film_editor.cc:401 +#: src/wx/film_editor.cc:402 msgid "Use external audio" msgstr "Utiliser une source audio externe" -#: src/wx/film_editor.cc:75 +#: src/wx/film_editor.cc:76 msgid "Video" -msgstr "Vid??o" +msgstr "Vidéo" -#: src/wx/film_editor.cc:424 +#: src/wx/film_editor.cc:425 msgid "With Subtitles" msgstr "Avec sous-titres" -#: src/wx/film_editor.cc:1231 +#: src/wx/film_editor.cc:1228 msgid "channels" msgstr "canaux" @@ -442,24 +447,27 @@ msgstr "canaux" msgid "counting..." msgstr "calcul..." -#: src/wx/film_editor.cc:373 +#: src/wx/film_editor.cc:374 msgid "dB" msgstr "dB" -#: src/wx/film_editor.cc:690 src/wx/film_editor.cc:692 +#: src/wx/film_editor.cc:689 +#: src/wx/film_editor.cc:691 msgid "frames" msgstr "images" #. / TRANSLATORS: this is an abbreviation for milliseconds, the unit of time -#: src/wx/film_editor.cc:386 +#: src/wx/film_editor.cc:387 msgid "ms" msgstr "ms" #. / TRANSLATORS: `s' here is an abbreviation for seconds, the unit of time -#: src/wx/film_editor.cc:197 +#: src/wx/film_editor.cc:198 msgid "s" msgstr "s" -#: src/wx/properties_dialog.cc:62 src/wx/properties_dialog.cc:63 +#: src/wx/properties_dialog.cc:62 +#: src/wx/properties_dialog.cc:63 msgid "unknown" msgstr "inconnu" + -- cgit v1.2.3 From 8019a8c5a615d557bf54972f34a9faddebcbb93b Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 20 Mar 2013 13:41:16 +0000 Subject: Re-merge French translation. --- src/lib/po/fr_FR.po | 102 ++++++++++++++++++++++++------------------ src/tools/po/fr_FR.po | 16 +++---- src/wx/po/fr_FR.po | 120 +++++++++++++++++++++++--------------------------- 3 files changed, 123 insertions(+), 115 deletions(-) (limited to 'src') diff --git a/src/lib/po/fr_FR.po b/src/lib/po/fr_FR.po index e48d0423d..895afcabe 100644 --- a/src/lib/po/fr_FR.po +++ b/src/lib/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-05 13:49+0000\n" +"POT-Creation-Date: 2013-03-20 13:37+0000\n" "PO-Revision-Date: 2013-03-20 00:39+0100\n" "Last-Translator: FreeDCP.net \n" "Language-Team: \n" @@ -16,7 +16,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: src/lib/transcode_job.cc:90 +#: src/lib/transcode_job.cc:87 msgid "0%" msgstr "0%" @@ -72,7 +72,7 @@ msgstr "Advertisement" msgid "An error occurred whilst handling the file %1." msgstr "Une erreur s'est produite lors du traitement du fichier %1." -#: src/lib/analyse_audio_job.cc:48 +#: src/lib/analyse_audio_job.cc:49 msgid "Analyse audio of %1" msgstr "Analyse du son de %1" @@ -88,6 +88,10 @@ msgstr "Bicubique" msgid "Bilinear" msgstr "Bilinéaire" +#: src/lib/exceptions.cc:60 +msgid "Cannot handle pixel format %1 during %2" +msgstr "" + #: src/lib/encoder.cc:101 msgid "Cannot resample audio as libswresample is not present" msgstr "Ré-échantillonnage du son impossible : libswresample est absent" @@ -132,24 +136,14 @@ msgstr "La cadence du DCP sera %1%% par rapport à la source" msgid "DCP will use every other frame of the source.\n" msgstr "Le DCP utilisera une image sur deux de la source.\n" -#: src/lib/filter.cc:68 -#: src/lib/filter.cc:69 -#: src/lib/filter.cc:70 -#: src/lib/filter.cc:71 -#: src/lib/filter.cc:72 -#: src/lib/filter.cc:73 +#: src/lib/filter.cc:68 src/lib/filter.cc:69 src/lib/filter.cc:70 +#: src/lib/filter.cc:71 src/lib/filter.cc:72 src/lib/filter.cc:73 msgid "De-blocking" msgstr "De-bloc" -#: src/lib/filter.cc:75 -#: src/lib/filter.cc:76 -#: src/lib/filter.cc:77 -#: src/lib/filter.cc:78 -#: src/lib/filter.cc:79 -#: src/lib/filter.cc:80 -#: src/lib/filter.cc:81 -#: src/lib/filter.cc:82 -#: src/lib/filter.cc:83 +#: src/lib/filter.cc:75 src/lib/filter.cc:76 src/lib/filter.cc:77 +#: src/lib/filter.cc:78 src/lib/filter.cc:79 src/lib/filter.cc:80 +#: src/lib/filter.cc:81 src/lib/filter.cc:82 src/lib/filter.cc:83 msgid "De-interlacing" msgstr "Désentrelacement" @@ -237,10 +231,13 @@ msgstr "Filtre débloc horizontal" msgid "Horizontal deblocking filter A" msgstr "Filtre dé-bloc horizontal" -#: src/lib/job.cc:87 -#: src/lib/job.cc:96 -msgid "It is not known what caused this error. The best idea is to report the problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" -msgstr "Erreur indéterminée. Merci de rapporter le problème à la liste DVD-o-matic (dvdomatic@carlh.net)" +#: src/lib/job.cc:87 src/lib/job.cc:96 +msgid "" +"It is not known what caused this error. The best idea is to report the " +"problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" +msgstr "" +"Erreur indéterminée. Merci de rapporter le problème à la liste DVD-o-matic " +"(dvdomatic@carlh.net)" #: src/lib/filter.cc:82 msgid "Kernel deinterlacer" @@ -262,11 +259,8 @@ msgstr "Désentrelaceur linéaire interpolé" msgid "Median deinterlacer" msgstr "Désentrelaceur médian" -#: src/lib/filter.cc:74 -#: src/lib/filter.cc:85 -#: src/lib/filter.cc:86 -#: src/lib/filter.cc:87 -#: src/lib/filter.cc:90 +#: src/lib/filter.cc:74 src/lib/filter.cc:85 src/lib/filter.cc:86 +#: src/lib/filter.cc:87 src/lib/filter.cc:90 msgid "Misc" msgstr "Divers" @@ -274,9 +268,7 @@ msgstr "Divers" msgid "Motion compensating deinterlacer" msgstr "Désentrelaceur par compensation de mouvement" -#: src/lib/filter.cc:84 -#: src/lib/filter.cc:88 -#: src/lib/filter.cc:89 +#: src/lib/filter.cc:84 src/lib/filter.cc:88 src/lib/filter.cc:89 #: src/lib/filter.cc:91 msgid "Noise reduction" msgstr "Réduction de bruit" @@ -398,8 +390,12 @@ msgid "Test" msgstr "Test" #: src/lib/job.cc:76 -msgid "The drive that the film is stored on is low in disc space. Free some more space and try again." -msgstr "Le disque contenant le film est plein. Libérez de l'espace et essayez à nouveau." +msgid "" +"The drive that the film is stored on is low in disc space. Free some more " +"space and try again." +msgstr "" +"Le disque contenant le film est plein. Libérez de l'espace et essayez à " +"nouveau." #: src/lib/dcp_content_type.cc:46 msgid "Trailer" @@ -473,6 +469,11 @@ msgstr "type de contenu" msgid "copying %1" msgstr "copie de %1" +#: src/lib/exceptions.cc:36 +#, fuzzy +msgid "could not create file %1" +msgstr "Écriture vers fichier distant (%1) impossible" + #: src/lib/ffmpeg_decoder.cc:191 msgid "could not find audio decoder" msgstr "décodeur audio introuvable" @@ -489,16 +490,25 @@ msgstr "décodeur de sous-titre introuvable" msgid "could not find video decoder" msgstr "décodeur vidéo introuvable" -#: src/lib/external_audio_decoder.cc:72 +#: src/lib/sndfile_decoder.cc:72 msgid "could not open external audio file for reading" msgstr "lecture du fichier audio externe impossible" +#: src/lib/exceptions.cc:29 +#, fuzzy +msgid "could not open file %1" +msgstr "lecture du fichier impossible" + #: src/lib/dcp_video_frame.cc:388 msgid "could not open file for reading" msgstr "lecture du fichier impossible" -#: src/lib/encoder.cc:137 -#: src/lib/encoder.cc:314 +#: src/lib/exceptions.cc:44 +#, fuzzy +msgid "could not read from file %1 (%2)" +msgstr "Création du dossier distant %1 (%2) impossible" + +#: src/lib/encoder.cc:137 src/lib/encoder.cc:314 msgid "could not run sample-rate converter" msgstr "conversion de la fréquence d'échantillonnage impossible" @@ -510,6 +520,11 @@ msgstr "démarrage de session SCP (%1) impossible" msgid "could not start SSH session" msgstr "démarrage de session SSH impossible" +#: src/lib/exceptions.cc:50 +#, fuzzy +msgid "could not write to file %1 (%2)" +msgstr "Écriture vers fichier distant (%1) impossible" + #: src/lib/encoder.cc:247 msgid "decoder sleeps with queue of %1" msgstr "décodeur en veille avec %1 en file d'attente" @@ -518,11 +533,11 @@ msgstr "décodeur en veille avec %1 en file d'attente" msgid "decoder wakes with queue of %1" msgstr "reprise du décodage avec %1 en file d'attente" -#: src/lib/external_audio_decoder.cc:94 +#: src/lib/sndfile_decoder.cc:94 msgid "external audio files have differing lengths" msgstr "Les fichiers audio externes ont des durées différentes" -#: src/lib/external_audio_decoder.cc:76 +#: src/lib/sndfile_decoder.cc:76 msgid "external audio files must be mono" msgstr "les fichiers audio externes doivent être en mono" @@ -530,7 +545,7 @@ msgstr "les fichiers audio externes doivent être en mono" msgid "format" msgstr "format" -#: src/lib/transcode_job.cc:103 +#: src/lib/transcode_job.cc:100 msgid "frames per second" msgstr "images par seconde" @@ -538,8 +553,7 @@ msgstr "images par seconde" msgid "hour" msgstr "heure" -#: src/lib/util.cc:112 -#: src/lib/util.cc:117 +#: src/lib/util.cc:112 src/lib/util.cc:117 msgid "hours" msgstr "heures" @@ -555,12 +569,15 @@ msgstr "minutes" msgid "missing key %1 in key-value set" msgstr "clé %1 non sélectionnée" +#: src/lib/exceptions.cc:54 +msgid "missing required setting %1" +msgstr "" + #: src/lib/subtitle.cc:52 msgid "multi-part subtitles not yet supported" msgstr "sous-titres en plusieurs parties non supportés" -#: src/lib/film.cc:263 -#: src/lib/film.cc:308 +#: src/lib/film.cc:263 src/lib/film.cc:308 msgid "name" msgstr "nom" @@ -593,4 +610,3 @@ msgstr "fixe" #: src/lib/film.cc:274 msgid "video" msgstr "vidéo" - diff --git a/src/tools/po/fr_FR.po b/src/tools/po/fr_FR.po index 844406978..4f84fee77 100644 --- a/src/tools/po/fr_FR.po +++ b/src/tools/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-05 13:49+0000\n" +"POT-Creation-Date: 2013-03-20 13:37+0000\n" "PO-Revision-Date: 2013-03-13 22:33+0100\n" "Last-Translator: \n" "Language-Team: \n" @@ -65,14 +65,16 @@ msgid "&Send DCP to TMS" msgstr "&Envoyer le DCP dans le TMS" #: src/tools/dvdomatic.cc:409 -msgid "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" -msgstr "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" +msgid "" +"(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" +msgstr "" +"(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" #: src/tools/dvdomatic.cc:180 msgid "About" msgstr "A Propos" -#: src/tools/dvdomatic.cc:482 +#: src/tools/dvdomatic.cc:500 msgid "Could not load film %1 (%2)" msgstr "Impossible de charger le film %1 (%2)" @@ -81,9 +83,8 @@ msgstr "Impossible de charger le film %1 (%2)" msgid "Could not open film at %s (%s)" msgstr "Impossible d'ouvrir le film à %s (%s)" -#: src/tools/dvdomatic.cc:287 -#: src/tools/dvdomatic.cc:402 -#: src/tools/dvdomatic.cc:486 +#: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:402 +#: src/tools/dvdomatic.cc:504 msgid "DVD-o-matic" msgstr "DVD-o-matic" @@ -111,4 +112,3 @@ msgstr "Sélectionner le film à ouvrir" #, c-format msgid "The directory %s already exists." msgstr "Le dossier %s existe déjà." - diff --git a/src/wx/po/fr_FR.po b/src/wx/po/fr_FR.po index d482d54e4..a36d07776 100644 --- a/src/wx/po/fr_FR.po +++ b/src/wx/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-05 13:49+0000\n" +"POT-Creation-Date: 2013-03-20 13:37+0000\n" "PO-Revision-Date: 2013-03-20 00:34+0100\n" "Last-Translator: FreeDCP.net \n" "Language-Team: \n" @@ -16,15 +16,15 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: src/wx/film_editor.cc:441 +#: src/wx/film_editor.cc:440 msgid "%" msgstr "%" -#: src/wx/film_editor.cc:1226 +#: src/wx/film_editor.cc:1229 msgid "1 channel" msgstr "1 canal" -#: src/wx/film_editor.cc:185 +#: src/wx/film_editor.cc:184 msgid "A/B" msgstr "A/B" @@ -32,16 +32,15 @@ msgstr "A/B" msgid "Add" msgstr "Ajouter" -#: src/wx/audio_dialog.cc:32 -#: src/wx/film_editor.cc:78 +#: src/wx/audio_dialog.cc:32 src/wx/film_editor.cc:77 msgid "Audio" msgstr "Audio" -#: src/wx/film_editor.cc:382 +#: src/wx/film_editor.cc:381 msgid "Audio Delay" msgstr "Délai audio" -#: src/wx/film_editor.cc:370 +#: src/wx/film_editor.cc:369 msgid "Audio Gain" msgstr "Gain audio" @@ -54,7 +53,7 @@ msgstr "Langue audio (ex. FR)" msgid "Bad setting for %s (%s)" msgstr "Mauvais paramètre pour %s (%s)" -#: src/wx/film_editor.cc:297 +#: src/wx/film_editor.cc:296 msgid "Bottom crop" msgstr "Découpe bas" @@ -66,7 +65,7 @@ msgstr "Parcourir..." msgid "But I have to use fader" msgstr "Je souhaite utiliser ce volume" -#: src/wx/film_editor.cc:375 +#: src/wx/film_editor.cc:374 msgid "Calculate..." msgstr "Calcul..." @@ -74,15 +73,15 @@ msgstr "Calcul..." msgid "Channels" msgstr "Canaux" -#: src/wx/film_editor.cc:326 +#: src/wx/film_editor.cc:325 msgid "Colour look-up table" msgstr "Espace colorimétrique" -#: src/wx/film_editor.cc:121 +#: src/wx/film_editor.cc:120 msgid "Content" msgstr "Contenu" -#: src/wx/film_editor.cc:131 +#: src/wx/film_editor.cc:130 msgid "Content Type" msgstr "Type de Contenu" @@ -101,7 +100,7 @@ msgstr "Impossible de créer le DCP : %s" msgid "Could not open content file (%s)" msgstr "Ouverture du contenu impossible (%s)" -#: src/wx/film_editor.cc:505 +#: src/wx/film_editor.cc:504 #, c-format msgid "Could not set content: %s" msgstr "Sélectionner du contenu impossible : %s" @@ -114,11 +113,11 @@ msgstr "Créer dans le dossier" msgid "DCI name" msgstr "Nom DCI" -#: src/wx/film_editor.cc:142 +#: src/wx/film_editor.cc:141 msgid "DCP Frame Rate" msgstr "Cadence image du DCP" -#: src/wx/film_editor.cc:110 +#: src/wx/film_editor.cc:109 msgid "DCP Name" msgstr "Nom du DCP" @@ -142,8 +141,7 @@ msgstr "Détails du nom DCI par défaut" msgid "Default directory for new films" msgstr "Dossier par défaut des nouveaux films" -#: src/wx/film_editor.cc:117 -#: src/wx/job_manager_view.cc:88 +#: src/wx/film_editor.cc:116 src/wx/job_manager_view.cc:88 msgid "Details..." msgstr "Détails..." @@ -151,7 +149,7 @@ msgstr "Détails..." msgid "Disk space required" msgstr "Espace disque requis" -#: src/wx/film_editor.cc:192 +#: src/wx/film_editor.cc:191 msgid "Duration" msgstr "Durée" @@ -159,9 +157,8 @@ msgstr "Durée" msgid "Edit" msgstr "Édition" -#: src/wx/config_dialog.cc:84 -#: src/wx/config_dialog.cc:103 -#: src/wx/film_editor.cc:309 +#: src/wx/config_dialog.cc:84 src/wx/config_dialog.cc:103 +#: src/wx/film_editor.cc:308 msgid "Edit..." msgstr "Éditer..." @@ -169,7 +166,7 @@ msgstr "Éditer..." msgid "Encoding Servers" msgstr "Serveurs d'encodage" -#: src/wx/film_editor.cc:177 +#: src/wx/film_editor.cc:176 msgid "End" msgstr "Fin" @@ -177,7 +174,7 @@ msgstr "Fin" msgid "Facility (e.g. DLA)" msgstr "Laboratoire (ex. DLA)" -#: src/wx/film_editor.cc:74 +#: src/wx/film_editor.cc:73 msgid "Film" msgstr "Film" @@ -189,12 +186,11 @@ msgstr "Propriétés du film" msgid "Film name" msgstr "Nom du Film" -#: src/wx/film_editor.cc:304 -#: src/wx/filter_dialog.cc:32 +#: src/wx/film_editor.cc:303 src/wx/filter_dialog.cc:32 msgid "Filters" msgstr "Filtres" -#: src/wx/film_editor.cc:269 +#: src/wx/film_editor.cc:268 msgid "Format" msgstr "Format" @@ -218,7 +214,7 @@ msgstr "Gb" msgid "Host name or IP address" msgstr "Nom de l'hôte ou adresse IP" -#: src/wx/film_editor.cc:1230 +#: src/wx/film_editor.cc:1233 msgid "Hz" msgstr "Hz" @@ -230,19 +226,19 @@ msgstr "Je veux le jouer à ce volume" msgid "IP address" msgstr "Adresse IP" -#: src/wx/film_editor.cc:336 +#: src/wx/film_editor.cc:335 msgid "JPEG2000 bandwidth" msgstr "Qualité JPEG2000" -#: src/wx/film_editor.cc:282 +#: src/wx/film_editor.cc:281 msgid "Left crop" msgstr "Découpe gauche" -#: src/wx/film_editor.cc:165 +#: src/wx/film_editor.cc:164 msgid "Length" msgstr "Longueur" -#: src/wx/film_editor.cc:340 +#: src/wx/film_editor.cc:339 msgid "MBps" msgstr "MBps" @@ -250,7 +246,7 @@ msgstr "MBps" msgid "My Documents" msgstr "Mes Documents" -#: src/wx/film_editor.cc:105 +#: src/wx/film_editor.cc:104 msgid "Name" msgstr "Nom" @@ -258,16 +254,15 @@ msgstr "Nom" msgid "New Film" msgstr "Nouveau Film" -#: src/wx/film_editor.cc:306 -#: src/wx/film_editor.cc:663 +#: src/wx/film_editor.cc:305 src/wx/film_editor.cc:664 msgid "None" msgstr "Aucun" -#: src/wx/film_editor.cc:136 +#: src/wx/film_editor.cc:135 msgid "Original Frame Rate" msgstr "Cadence d'images originale" -#: src/wx/film_editor.cc:160 +#: src/wx/film_editor.cc:159 msgid "Original Size" msgstr "Taille Originale" @@ -307,7 +302,7 @@ msgstr "Échelle de référence pour A7B" msgid "Remove" msgstr "Supprimer" -#: src/wx/film_editor.cc:287 +#: src/wx/film_editor.cc:286 msgid "Right crop" msgstr "Découpe droite" @@ -315,15 +310,15 @@ msgstr "Découpe droite" msgid "Running" msgstr "Progression" -#: src/wx/film_editor.cc:316 +#: src/wx/film_editor.cc:315 msgid "Scaler" msgstr "Mise à l'échelle" -#: src/wx/film_editor.cc:408 +#: src/wx/film_editor.cc:407 msgid "Select Audio File" msgstr "Sélectionner le fichier son" -#: src/wx/film_editor.cc:122 +#: src/wx/film_editor.cc:121 msgid "Select Content File" msgstr "Sélectionner le fichier vidéo" @@ -331,7 +326,7 @@ msgstr "Sélectionner le fichier vidéo" msgid "Server" msgstr "Serveur" -#: src/wx/film_editor.cc:365 +#: src/wx/film_editor.cc:364 msgid "Show Audio..." msgstr "Montrer le son..." @@ -339,7 +334,7 @@ msgstr "Montrer le son..." msgid "Smoothing" msgstr "Lissage" -#: src/wx/film_editor.cc:174 +#: src/wx/film_editor.cc:173 msgid "Start" msgstr "Début" @@ -351,15 +346,15 @@ msgstr "Studio (ex. TCF)" msgid "Subtitle Language (e.g. FR)" msgstr "Langue de sous-titres (ex. FR)" -#: src/wx/film_editor.cc:432 +#: src/wx/film_editor.cc:431 msgid "Subtitle Offset" msgstr "Décalage du sous-titre" -#: src/wx/film_editor.cc:437 +#: src/wx/film_editor.cc:436 msgid "Subtitle Scale" msgstr "Taille du sous-titre" -#: src/wx/film_editor.cc:80 +#: src/wx/film_editor.cc:79 msgid "Subtitles" msgstr "Sous-titres" @@ -399,15 +394,15 @@ msgstr "Nombre de processus à utiliser sur cet hôte" msgid "Time" msgstr "Durée" -#: src/wx/film_editor.cc:292 +#: src/wx/film_editor.cc:291 msgid "Top crop" msgstr "Découpe haut" -#: src/wx/film_editor.cc:172 +#: src/wx/film_editor.cc:171 msgid "Trim frames" msgstr "Images coupées" -#: src/wx/film_editor.cc:126 +#: src/wx/film_editor.cc:125 msgid "Trust content's header" msgstr "Faire confiance à l'en-tête" @@ -415,31 +410,31 @@ msgstr "Faire confiance à l'en-tête" msgid "Type" msgstr "Type" -#: src/wx/film_editor.cc:115 +#: src/wx/film_editor.cc:114 msgid "Use DCI name" msgstr "Utiliser le nom DCI" -#: src/wx/film_editor.cc:146 +#: src/wx/film_editor.cc:145 msgid "Use best" msgstr "Automatique" -#: src/wx/film_editor.cc:392 +#: src/wx/film_editor.cc:391 msgid "Use content's audio" msgstr "Utiliser le son intégré" -#: src/wx/film_editor.cc:402 +#: src/wx/film_editor.cc:401 msgid "Use external audio" msgstr "Utiliser une source audio externe" -#: src/wx/film_editor.cc:76 +#: src/wx/film_editor.cc:75 msgid "Video" msgstr "Vidéo" -#: src/wx/film_editor.cc:425 +#: src/wx/film_editor.cc:424 msgid "With Subtitles" msgstr "Avec sous-titres" -#: src/wx/film_editor.cc:1228 +#: src/wx/film_editor.cc:1231 msgid "channels" msgstr "canaux" @@ -447,27 +442,24 @@ msgstr "canaux" msgid "counting..." msgstr "calcul..." -#: src/wx/film_editor.cc:374 +#: src/wx/film_editor.cc:373 msgid "dB" msgstr "dB" -#: src/wx/film_editor.cc:689 -#: src/wx/film_editor.cc:691 +#: src/wx/film_editor.cc:690 src/wx/film_editor.cc:692 msgid "frames" msgstr "images" #. / TRANSLATORS: this is an abbreviation for milliseconds, the unit of time -#: src/wx/film_editor.cc:387 +#: src/wx/film_editor.cc:386 msgid "ms" msgstr "ms" #. / TRANSLATORS: `s' here is an abbreviation for seconds, the unit of time -#: src/wx/film_editor.cc:198 +#: src/wx/film_editor.cc:197 msgid "s" msgstr "s" -#: src/wx/properties_dialog.cc:62 -#: src/wx/properties_dialog.cc:63 +#: src/wx/properties_dialog.cc:62 src/wx/properties_dialog.cc:63 msgid "unknown" msgstr "inconnu" - -- cgit v1.2.3 From 7ea72d80eb1ddefc8b43afa682f0bf20e9b67b7d Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 20 Mar 2013 15:01:03 +0000 Subject: Try to set gettext up correctly. --- src/lib/util.cc | 7 +++++++ src/lib/util.h | 1 + src/tools/dvdomatic.cc | 2 ++ 3 files changed, 10 insertions(+) (limited to 'src') diff --git a/src/lib/util.cc b/src/lib/util.cc index 53bdb4c79..e043f8576 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -249,6 +249,13 @@ dvdomatic_setup () ui_thread = this_thread::get_id (); } +void +dvdomatic_setup_i18n (string lang) +{ + bindtextdomain ("libdvdomatic", LOCALE_PREFIX); + setlocale (LC_ALL, lang.c_str ()); +} + /** @param start Start position for the crop within the image. * @param size Size of the cropped area. * @return FFmpeg crop filter string. diff --git a/src/lib/util.h b/src/lib/util.h index ec67469c1..60498be5a 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -54,6 +54,7 @@ extern void stacktrace (std::ostream &, int); extern std::string dependency_version_summary (); extern double seconds (struct timeval); extern void dvdomatic_setup (); +extern void dvdomatic_setup_i18n (std::string); extern std::vector split_at_spaces_considering_quotes (std::string); extern std::string md5_digest (std::string); extern std::string md5_digest (void const *, int); diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index d0e4dd1f2..aa936523d 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -469,6 +469,8 @@ setup_i18n () language = wxLANGUAGE_ENGLISH; } } + + dvdomatic_setup_i18n (wx_to_std (locale->GetCanonicalName ())); } class App : public wxApp -- cgit v1.2.3 From 6157fc6d7d8037a239a2494ad89da8c917145dae Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 20 Mar 2013 16:48:11 +0000 Subject: Remove redundant line. --- src/lib/util.cc | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/lib/util.cc b/src/lib/util.cc index e043f8576..abbc35749 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -236,7 +236,6 @@ void dvdomatic_setup () { bindtextdomain ("libdvdomatic", LOCALE_PREFIX); - setlocale (LC_ALL, ""); avfilter_register_all (); -- cgit v1.2.3 From fec9770dd454fdb6902180322fd3d221f2c86ed2 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 21 Mar 2013 11:27:23 +0000 Subject: Try to support UYVY422 (#82). --- src/lib/image.cc | 32 ++++++++++++++++++++++++++++---- test/test.cc | 1 + 2 files changed, 29 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/lib/image.cc b/src/lib/image.cc index 268c08173..2355d22e5 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -75,6 +75,7 @@ Image::lines (int n) const case PIX_FMT_YUV444P9LE: case PIX_FMT_YUV444P10BE: case PIX_FMT_YUV444P10LE: + case PIX_FMT_UYVY422: return size().height; default: throw PixelFormatError (N_("lines()"), _pixel_format); @@ -99,6 +100,7 @@ Image::components () const return 3; case PIX_FMT_RGB24: case PIX_FMT_RGBA: + case PIX_FMT_UYVY422: return 1; default: throw PixelFormatError (N_("components()"), _pixel_format); @@ -211,6 +213,7 @@ Image::post_process (string pp, bool aligned) const break; case PIX_FMT_YUV422P10LE: case PIX_FMT_YUV422P: + case PIX_FMT_UYVY422: pp_format = PP_FORMAT_422; break; case PIX_FMT_YUV444P: @@ -291,6 +294,9 @@ Image::swap_16 (uint16_t v) void Image::make_black () { + /* U/V black value for 8-bit colour */ + static uint8_t const eight_bit_uv = (1 << 7) - 1; + /* U/V black value for 9-bit colour */ static uint16_t const nine_bit_uv = (1 << 8) - 1; @@ -302,8 +308,8 @@ Image::make_black () case PIX_FMT_YUV422P: case PIX_FMT_YUV444P: memset (data()[0], 0, lines(0) * stride()[0]); - memset (data()[1], 0x7f, lines(1) * stride()[1]); - memset (data()[2], 0x7f, lines(2) * stride()[2]); + memset (data()[1], eight_bit_uv, lines(1) * stride()[1]); + memset (data()[2], eight_bit_uv, lines(2) * stride()[2]); break; case PIX_FMT_YUV422P9LE: @@ -329,8 +335,24 @@ Image::make_black () memset (data()[0], 0, lines(0) * stride()[0]); break; + case PIX_FMT_UYVY422: + { + int const Y = lines(0); + int const X = line_size()[0]; + uint8_t* p = data()[0]; + for (int y = 0; y < Y; ++y) { + for (int x = 0; x < X / 4; ++x) { + *p++ = eight_bit_uv; // Cb + *p++ = 0; // Y0 + *p++ = eight_bit_uv; // Cr + *p++ = 0; // Y1 + } + } + break; + } + default: - assert (false); + throw PixelFormatError (N_("make_black()"), _pixel_format); } } @@ -428,6 +450,8 @@ Image::bytes_per_pixel (int c) const } else { return 1; } + case PIX_FMT_UYVY422: + return 2; case PIX_FMT_YUV444P: return 3; case PIX_FMT_YUV444P9BE: @@ -436,7 +460,7 @@ Image::bytes_per_pixel (int c) const case PIX_FMT_YUV444P10BE: return 6; default: - assert (false); + throw PixelFormatError (N_("bytes_per_pixel()"), _pixel_format); } return 0; diff --git a/test/test.cc b/test/test.cc index f31b3b1ca..61e192058 100644 --- a/test/test.cc +++ b/test/test.cc @@ -102,6 +102,7 @@ BOOST_AUTO_TEST_CASE (make_black_test) pix_fmts.push_back (AV_PIX_FMT_YUV444P9BE); pix_fmts.push_back (AV_PIX_FMT_YUV444P10LE); pix_fmts.push_back (AV_PIX_FMT_YUV444P10BE); + pix_fmts.push_back (AV_PIX_FMT_UYVY422); int N = 0; for (list::const_iterator i = pix_fmts.begin(); i != pix_fmts.end(); ++i) { -- cgit v1.2.3 From 9d283e1f5ed5b06dea2ff818daf4eff2a7e8cae5 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 21 Mar 2013 11:37:50 +0000 Subject: Another attempt to fix i18n. --- src/lib/util.cc | 8 +++++++- windows/installer.nsi.32.in | 5 +++-- windows/installer.nsi.64.in | 6 +++--- wscript | 5 +++-- 4 files changed, 16 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/lib/util.cc b/src/lib/util.cc index abbc35749..765835bc4 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -251,8 +251,14 @@ dvdomatic_setup () void dvdomatic_setup_i18n (string lang) { +#ifdef DVDOMATIC_WINDOWS + string const e = "LANGUAGE=" + lang; + putenv (e.c_str()); +#endif + + setlocale (LC_ALL, ""); + textdomain ("libdvdomatic"); bindtextdomain ("libdvdomatic", LOCALE_PREFIX); - setlocale (LC_ALL, lang.c_str ()); } /** @param start Start position for the crop within the image. diff --git a/windows/installer.nsi.32.in b/windows/installer.nsi.32.in index 4911585de..b79703ff1 100644 --- a/windows/installer.nsi.32.in +++ b/windows/installer.nsi.32.in @@ -93,10 +93,11 @@ File "%deps%/etc/ImageMagick/delegates.xml" SetOutPath "$PROFILE\.magick" File "%deps%/etc/ImageMagick/delegates.xml" -SetOutPath "$INSTDIR\bin\fr_FR" +SetOutPath "$INSTDIR\locale\fr_FR" File "%binaries%/src/lib/mo/fr_FR/libdvdomatic.mo" +File "%binaries%/src/wx/mo/fr_FR/libdvdomatic-wx.mo" File "%binaries%/src/tools/mo/fr_FR/dvdomatic.mo" -SetOutPath "$INSTDIR\bin\it_IT" +SetOutPath "$INSTDIR\locale\it_IT" File "%binaries%/src/lib/mo/it_IT/libdvdomatic.mo" File "%binaries%/src/wx/mo/it_IT/libdvdomatic-wx.mo" File "%binaries%/src/tools/mo/it_IT/dvdomatic.mo" diff --git a/windows/installer.nsi.64.in b/windows/installer.nsi.64.in index 295f926b6..21980e61a 100644 --- a/windows/installer.nsi.64.in +++ b/windows/installer.nsi.64.in @@ -103,11 +103,11 @@ File "%deps%/etc/ImageMagick/delegates.xml" SetOutPath "$PROFILE\.magick" File "%deps%/etc/ImageMagick/delegates.xml" -SetOutPath "$INSTDIR\bin\fr_FR" +SetOutPath "$INSTDIR\locale\fr_FR" File "%binaries%/src/lib/mo/fr_FR/libdvdomatic.mo" +File "%binaries%/src/wx/mo/fr_FR/libdvdomatic-wx.mo" File "%binaries%/src/tools/mo/fr_FR/dvdomatic.mo" - -SetOutPath "$INSTDIR\bin\it_IT" +SetOutPath "$INSTDIR\locale\it_IT" File "%binaries%/src/lib/mo/it_IT/libdvdomatic.mo" File "%binaries%/src/wx/mo/it_IT/libdvdomatic-wx.mo" File "%binaries%/src/tools/mo/it_IT/dvdomatic.mo" diff --git a/wscript b/wscript index 4f81e4934..171b71181 100644 --- a/wscript +++ b/wscript @@ -22,11 +22,11 @@ def configure(conf): conf.load('winres') conf.env.append_value('CXXFLAGS', ['-D__STDC_CONSTANT_MACROS', '-msse', '-mfpmath=sse', '-ffast-math', '-fno-strict-aliasing', - '-Wall', '-Wno-attributes', '-Wextra', - '-DLOCALE_PREFIX="%s/share/locale"' % conf.env['PREFIX']]) + '-Wall', '-Wno-attributes', '-Wextra']) if conf.options.target_windows: conf.env.append_value('CXXFLAGS', ['-DDVDOMATIC_WINDOWS', '-DWIN32_LEAN_AND_MEAN', '-DBOOST_USE_WINDOWS_H', '-DUNICODE']) + conv.env.append_value('CXXFLAGS', '-DLOCALE_PREFIX="../locale"') wxrc = os.popen('wx-config --rescomp').read().split()[1:] conf.env.append_value('WINRCFLAGS', wxrc) if conf.options.enable_debug: @@ -37,6 +37,7 @@ def configure(conf): boost_thread = 'boost_thread_win32-mt' else: conf.env.append_value('CXXFLAGS', '-DDVDOMATIC_POSIX') + conf.env.append_value('CXXFLAGS', '-DLOCALE_PREFIX="%s/share/locale"' % conf.env['PREFIX']) boost_lib_suffix = '' boost_thread = 'boost_thread' conf.env.append_value('LINKFLAGS', '-pthread') -- cgit v1.2.3 From 6cb347531ee421d6bb39da5e78d660b594c8c9b6 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 21 Mar 2013 12:05:41 +0000 Subject: Remove duplicate line. --- src/lib/util.cc | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/lib/util.cc b/src/lib/util.cc index 765835bc4..03c1f43dd 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -235,8 +235,6 @@ seconds (struct timeval t) void dvdomatic_setup () { - bindtextdomain ("libdvdomatic", LOCALE_PREFIX); - avfilter_register_all (); Format::setup_formats (); -- cgit v1.2.3 From 1c207805aef4443c5fb6c102e5be8a5b50002868 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 21 Mar 2013 16:31:48 +0000 Subject: Add Manual Acevedo's initial Spanish translation. Hopefully finally fix up translations on Windows. --- src/lib/config.cc | 7 +++ src/lib/config.h | 1 + src/lib/util.cc | 27 ++++++++-- src/lib/util.h | 4 ++ src/tools/dvdomatic.cc | 32 ++++++++---- src/tools/po/es_ES.po | 117 ++++++++++++++++++++++++++++++++++++++++++++ windows/installer.nsi.32.in | 6 ++- windows/installer.nsi.64.in | 4 +- wscript | 3 +- 9 files changed, 181 insertions(+), 20 deletions(-) create mode 100644 src/tools/po/es_ES.po (limited to 'src') diff --git a/src/lib/config.cc b/src/lib/config.cc index ad132437a..5dce3748d 100644 --- a/src/lib/config.cc +++ b/src/lib/config.cc @@ -167,3 +167,10 @@ Config::default_directory_or (string a) const return _default_directory; } + +void +Config::drop () +{ + delete _instance; + _instance = 0; +} diff --git a/src/lib/config.h b/src/lib/config.h index 0e9c4a60a..ee46166e6 100644 --- a/src/lib/config.h +++ b/src/lib/config.h @@ -169,6 +169,7 @@ public: void write () const; static Config* instance (); + static void drop (); private: Config (); diff --git a/src/lib/util.cc b/src/lib/util.cc index 03c1f43dd..593d0e760 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -246,17 +246,36 @@ dvdomatic_setup () ui_thread = this_thread::get_id (); } +#ifdef DVDOMATIC_WINDOWS +boost::filesystem::path +mo_path () +{ + wchar_t buffer[512]; + GetModuleFileName (0, buffer, 512 * sizeof(wchar_t)); + boost::filesystem::path p (buffer); + p = p.parent_path (); + p = p.parent_path (); + p /= "locale"; + return p; +} +#endif + void dvdomatic_setup_i18n (string lang) { + setlocale (LC_ALL, ""); + textdomain ("libdvdomatic"); + #ifdef DVDOMATIC_WINDOWS string const e = "LANGUAGE=" + lang; putenv (e.c_str()); + + bindtextdomain ("libdvdomatic", mo_path().string().c_str()); #endif - - setlocale (LC_ALL, ""); - textdomain ("libdvdomatic"); - bindtextdomain ("libdvdomatic", LOCALE_PREFIX); + +#ifdef DVDOMATIC_POSIX + bindtextdomain ("libdvdomatic", POSIX_LOCALE_PREFIX); +#endif } /** @param start Start position for the crop within the image. diff --git a/src/lib/util.h b/src/lib/util.h index 60498be5a..3d251cf06 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -30,6 +30,7 @@ #include #include #include +#include #include extern "C" { #include @@ -60,6 +61,9 @@ extern std::string md5_digest (std::string); extern std::string md5_digest (void const *, int); extern void ensure_ui_thread (); extern std::string audio_channel_name (int); +#ifdef DVDOMATIC_WINDOWS +extern boost::filesystem::path mo_path (); +#endif typedef int SourceFrame; diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index aa936523d..4a778100c 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -416,10 +416,11 @@ private: info.SetDevelopers (authors); wxArrayString translators; - translators.Add (wxT ("Olivier Perriere (freedcp.net)")); + translators.Add (wxT ("Olivier Perriere")); translators.Add (wxT ("Lilian Lefranc")); translators.Add (wxT ("Thierry Journet")); translators.Add (wxT ("Massimiliano Broggi")); + translators.Add (wxT ("Manuel Acevedo")); info.SetTranslators (translators); info.SetWebSite (wxT ("http://carlh.net/software/dvdomatic")); @@ -456,9 +457,9 @@ setup_i18n () if (wxLocale::IsAvailable (language)) { locale = new wxLocale (language, wxLOCALE_LOAD_DEFAULT); -#ifdef __WXGTK__ - locale->AddCatalogLookupPathPrefix (wxT (LOCALE_PREFIX "/locale")); -#endif +#ifdef DVDOMATIC_WINDOWS + locale->AddCatalogLookupPathPrefix (std_to_wx (mo_path().string())); +#endif locale->AddCatalog (wxT ("libdvdomatic-wx")); locale->AddCatalog (wxT ("dvdomatic")); @@ -485,15 +486,26 @@ class App : public wxApp unsetenv ("UBUNTU_MENUPROXY"); #endif - /* This needs to be before setup_i18n, as setup_i18n() will - create a Config object, which needs Scalers to have - been created. + wxInitAllImageHandlers (); + + /* Enable i18n; this will create a Config object + to look for a force-configured language. This Config + object will be wrong, however, because dvdomatic_setup + hasn't yet been called and there aren't any scalers, filters etc. + set up yet. + */ + setup_i18n (); + + /* Set things up, including scalers / filters etc. + which will now be internationalised correctly. */ dvdomatic_setup (); - wxInitAllImageHandlers (); - setup_i18n (); - + /* Force the configuration to be re-loaded correctly next + time it is needed. + */ + Config::drop (); + if (!film_to_load.empty() && boost::filesystem::is_directory (film_to_load)) { try { film.reset (new Film (film_to_load)); diff --git a/src/tools/po/es_ES.po b/src/tools/po/es_ES.po new file mode 100644 index 000000000..78eecb306 --- /dev/null +++ b/src/tools/po/es_ES.po @@ -0,0 +1,117 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: DVDOMATIC\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-03-15 08:39+0000\n" +"PO-Revision-Date: 2013-03-20 17:05-0500\n" +"Last-Translator: Manuel AC \n" +"Language-Team: Manuel AC \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.5.5\n" +"Language: ES-ES\n" + +#: src/tools/dvdomatic.cc:177 +msgid "&Analyse audio" +msgstr "&Analizar sonido" + +#: src/tools/dvdomatic.cc:183 +msgid "&Edit" +msgstr "&Editar" + +#: src/tools/dvdomatic.cc:182 +msgid "&File" +msgstr "&Archivo" + +#: src/tools/dvdomatic.cc:185 +msgid "&Help" +msgstr "&Ayuda" + +#: src/tools/dvdomatic.cc:184 +msgid "&Jobs" +msgstr "&Tareas" + +#: src/tools/dvdomatic.cc:173 +msgid "&Make DCP" +msgstr "&Hacer DCP" + +#: src/tools/dvdomatic.cc:161 +msgid "&Open..." +msgstr "&Abrir..." + +#: src/tools/dvdomatic.cc:170 +msgid "&Preferences..." +msgstr "&Preferencias..." + +#: src/tools/dvdomatic.cc:165 +msgid "&Properties..." +msgstr "&Propiedades..." + +#: src/tools/dvdomatic.cc:167 +msgid "&Quit" +msgstr "&Salir" + +#: src/tools/dvdomatic.cc:163 +msgid "&Save" +msgstr "&Guardar" + +#: src/tools/dvdomatic.cc:174 +msgid "&Send DCP to TMS" +msgstr "&Enviar DCP al TMS" + +#: src/tools/dvdomatic.cc:409 +msgid "" +"(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" +msgstr "" +"(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" + +#: src/tools/dvdomatic.cc:180 +msgid "About" +msgstr "Acerca de" + +#: src/tools/dvdomatic.cc:497 +msgid "Could not load film %1 (%2)" +msgstr "No se pudo cargar la película %1 (%2)" + +#: src/tools/dvdomatic.cc:331 +#, c-format +msgid "Could not open film at %s (%s)" +msgstr "No se pudo cargar la película en %s (%s)" + +#: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:402 +#: src/tools/dvdomatic.cc:501 +msgid "DVD-o-matic" +msgstr "DVD-o-matic" + +#: src/tools/dvdomatic.cc:75 +msgid "Film changed" +msgstr "Película cambiada" + +#: src/tools/dvdomatic.cc:408 +msgid "Free, open-source DCP generation from almost anything." +msgstr "" +"Generación de DCP a partir de casi cualquier fuente, libre y de código " +"abierto." + +#: src/tools/dvdomatic.cc:160 +msgid "New..." +msgstr "Nuevo..." + +#: src/tools/dvdomatic.cc:175 +msgid "S&how DCP" +msgstr "&Mostrar DCP" + +#: src/tools/dvdomatic.cc:319 +msgid "Select film to open" +msgstr "Selecciona la película a abrir" + +#: src/tools/dvdomatic.cc:303 +#, c-format +msgid "The directory %s already exists." +msgstr "La carpeta %s ya existe." diff --git a/windows/installer.nsi.32.in b/windows/installer.nsi.32.in index b79703ff1..b2bb2f3a9 100644 --- a/windows/installer.nsi.32.in +++ b/windows/installer.nsi.32.in @@ -93,14 +93,16 @@ File "%deps%/etc/ImageMagick/delegates.xml" SetOutPath "$PROFILE\.magick" File "%deps%/etc/ImageMagick/delegates.xml" -SetOutPath "$INSTDIR\locale\fr_FR" +SetOutPath "$INSTDIR\locale\fr\LC_MESSAGES" File "%binaries%/src/lib/mo/fr_FR/libdvdomatic.mo" File "%binaries%/src/wx/mo/fr_FR/libdvdomatic-wx.mo" File "%binaries%/src/tools/mo/fr_FR/dvdomatic.mo" -SetOutPath "$INSTDIR\locale\it_IT" +SetOutPath "$INSTDIR\locale\it\LC_MESSAGES" File "%binaries%/src/lib/mo/it_IT/libdvdomatic.mo" File "%binaries%/src/wx/mo/it_IT/libdvdomatic-wx.mo" File "%binaries%/src/tools/mo/it_IT/dvdomatic.mo" +SetOutPath "$INSTDIR\locale\es\LC_MESSAGES" +File "%binaries%/src/tools/mo/es_ES/dvdomatic.mo" CreateShortCut "$DESKTOP\DVD-o-matic.lnk" "$INSTDIR\bin\dvdomatic.exe" "" CreateShortCut "$DESKTOP\DVD-o-matic encode server.lnk" "$INSTDIR\bin\servomatic_gui.exe" "" diff --git a/windows/installer.nsi.64.in b/windows/installer.nsi.64.in index 21980e61a..921178591 100644 --- a/windows/installer.nsi.64.in +++ b/windows/installer.nsi.64.in @@ -103,11 +103,11 @@ File "%deps%/etc/ImageMagick/delegates.xml" SetOutPath "$PROFILE\.magick" File "%deps%/etc/ImageMagick/delegates.xml" -SetOutPath "$INSTDIR\locale\fr_FR" +SetOutPath "$INSTDIR\locale\fr\LC_MESSAGES" File "%binaries%/src/lib/mo/fr_FR/libdvdomatic.mo" File "%binaries%/src/wx/mo/fr_FR/libdvdomatic-wx.mo" File "%binaries%/src/tools/mo/fr_FR/dvdomatic.mo" -SetOutPath "$INSTDIR\locale\it_IT" +SetOutPath "$INSTDIR\locale\it\LC_MESSAGES" File "%binaries%/src/lib/mo/it_IT/libdvdomatic.mo" File "%binaries%/src/wx/mo/it_IT/libdvdomatic-wx.mo" File "%binaries%/src/tools/mo/it_IT/dvdomatic.mo" diff --git a/wscript b/wscript index 24ebfe548..612abdf22 100644 --- a/wscript +++ b/wscript @@ -26,7 +26,6 @@ def configure(conf): if conf.options.target_windows: conf.env.append_value('CXXFLAGS', ['-DDVDOMATIC_WINDOWS', '-DWIN32_LEAN_AND_MEAN', '-DBOOST_USE_WINDOWS_H', '-DUNICODE']) - conf.env.append_value('CXXFLAGS', '-DLOCALE_PREFIX="../locale"') wxrc = os.popen('wx-config --rescomp').read().split()[1:] conf.env.append_value('WINRCFLAGS', wxrc) if conf.options.enable_debug: @@ -37,7 +36,7 @@ def configure(conf): boost_thread = 'boost_thread_win32-mt' else: conf.env.append_value('CXXFLAGS', '-DDVDOMATIC_POSIX') - conf.env.append_value('CXXFLAGS', '-DLOCALE_PREFIX="%s/share/locale"' % conf.env['PREFIX']) + conf.env.append_value('CXXFLAGS', '-DPOSIX_LOCALE_PREFIX="%s/share/locale"' % conf.env['PREFIX']) boost_lib_suffix = '' boost_thread = 'boost_thread' conf.env.append_value('LINKFLAGS', '-pthread') -- cgit v1.2.3 From bd79dcbba3a58eae1ff366bb0c3b95791dc6010a Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 24 Mar 2013 21:44:25 +0000 Subject: Un-mark some strings that do not need translation. --- src/lib/encoder.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 687dfdd2b..7b338407e 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -244,9 +244,9 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptr= _threads.size() * 2 && !_terminate) { - TIMING (_("decoder sleeps with queue of %1"), _queue.size()); + TIMING ("decoder sleeps with queue of %1", _queue.size()); _condition.wait (lock); - TIMING (_("decoder wakes with queue of %1"), _queue.size()); + TIMING ("decoder wakes with queue of %1", _queue.size()); } if (_terminate) { @@ -268,7 +268,7 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptr const s = Filter::ffmpeg_strings (_film->filters()); - TIMING (_("adding to queue of %1"), _queue.size ()); + TIMING ("adding to queue of %1", _queue.size ()); _queue.push_back (boost::shared_ptr ( new DCPVideoFrame ( image, sub, _film->format()->dcp_size(), _film->format()->dcp_padding (_film), @@ -349,7 +349,7 @@ Encoder::encoder_thread (ServerDescription* server) while (1) { - TIMING (N_("encoder thread %1 sleeps"), boost::this_thread::get_id()); + TIMING ("encoder thread %1 sleeps", boost::this_thread::get_id()); boost::mutex::scoped_lock lock (_mutex); while (_queue.empty () && !_terminate) { _condition.wait (lock); @@ -359,7 +359,7 @@ Encoder::encoder_thread (ServerDescription* server) return; } - TIMING (N_("encoder thread %1 wakes with queue of %2"), boost::this_thread::get_id(), _queue.size()); + TIMING ("encoder thread %1 wakes with queue of %2", boost::this_thread::get_id(), _queue.size()); boost::shared_ptr vf = _queue.front (); _film->log()->log (String::compose (N_("Encoder thread %1 pops frame %2 from queue"), boost::this_thread::get_id(), vf->frame()), Log::VERBOSE); _queue.pop_front (); @@ -393,9 +393,9 @@ Encoder::encoder_thread (ServerDescription* server) } else { try { - TIMING (N_("encoder thread %1 begins local encode of %2"), boost::this_thread::get_id(), vf->frame()); + TIMING ("encoder thread %1 begins local encode of %2", boost::this_thread::get_id(), vf->frame()); encoded = vf->encode_locally (); - TIMING (N_("encoder thread %1 finishes local encode of %2"), boost::this_thread::get_id(), vf->frame()); + TIMING ("encoder thread %1 finishes local encode of %2", boost::this_thread::get_id(), vf->frame()); } catch (std::exception& e) { _film->log()->log (String::compose (N_("Local encode failed (%1)"), e.what ())); } -- cgit v1.2.3 From 5925d300db2a237d59645dc26933c14e9bc94b65 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 24 Mar 2013 21:53:44 +0000 Subject: Fix Manuel's credit. --- src/tools/dvdomatic.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 4a778100c..991b4daf8 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -420,7 +420,7 @@ private: translators.Add (wxT ("Lilian Lefranc")); translators.Add (wxT ("Thierry Journet")); translators.Add (wxT ("Massimiliano Broggi")); - translators.Add (wxT ("Manuel Acevedo")); + translators.Add (wxT ("Manuel AC")); info.SetTranslators (translators); info.SetWebSite (wxT ("http://carlh.net/software/dvdomatic")); -- cgit v1.2.3 From 17097564ffb940478b2d5519302bc3bb9162a965 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 24 Mar 2013 23:24:27 +0000 Subject: User interface for language selection. --- src/tools/dvdomatic.cc | 4 +++- src/wx/config_dialog.cc | 47 +++++++++++++++++++++++++++++++++++++++++++++++ src/wx/config_dialog.h | 4 +++- 3 files changed, 53 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 991b4daf8..66f366a24 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -471,7 +471,9 @@ setup_i18n () } } - dvdomatic_setup_i18n (wx_to_std (locale->GetCanonicalName ())); + if (locale) { + dvdomatic_setup_i18n (wx_to_std (locale->GetCanonicalName ())); + } } class App : public wxApp diff --git a/src/wx/config_dialog.cc b/src/wx/config_dialog.cc index b28c350ea..ea1a7319e 100644 --- a/src/wx/config_dialog.cc +++ b/src/wx/config_dialog.cc @@ -46,6 +46,23 @@ ConfigDialog::ConfigDialog (wxWindow* parent) wxFlexGridSizer* table = new wxFlexGridSizer (3, 6, 6); table->AddGrowableCol (1, 1); + add_label_to_sizer (table, this, _("User interface language")); + _language = new wxChoice (this, wxID_ANY); + _language->Append (wxT ("English")); + _language->Append (wxT ("Français")); + _language->Append (wxT ("Italiano")); + _language->Append (wxT ("Español")); + table->Add (_language, 1, wxEXPAND); + table->AddSpacer (0); + + table->AddSpacer (0); + wxStaticText* restart = add_label_to_sizer (table, this, _("(restart DVD-o-matic to see language changes)")); + wxFont font = restart->GetFont(); + font.SetStyle (wxFONTSTYLE_ITALIC); + font.SetPointSize (font.GetPointSize() - 1); + restart->SetFont (font); + table->AddSpacer (0); + add_label_to_sizer (table, this, _("TMS IP address")); _tms_ip = new wxTextCtrl (this, wxID_ANY); table->Add (_tms_ip, 1, wxEXPAND); @@ -132,6 +149,17 @@ ConfigDialog::ConfigDialog (wxWindow* parent) Config* config = Config::instance (); + if (config->language().get_value_or ("") == "fr") { + _language->SetSelection (1); + } else if (config->language().get_value_or ("") == "it") { + _language->SetSelection (2); + } else if (config->language().get_value_or ("") == "es") { + _language->SetSelection (3); + } else { + _language->SetSelection (0); + } + + _language->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (ConfigDialog::language_changed), 0, this); _tms_ip->SetValue (std_to_wx (config->tms_ip ())); _tms_ip->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (ConfigDialog::tms_ip_changed), 0, this); _tms_path->SetValue (std_to_wx (config->tms_path ())); @@ -184,6 +212,25 @@ ConfigDialog::ConfigDialog (wxWindow* parent) overall_sizer->SetSizeHints (this); } +void +ConfigDialog::language_changed (wxCommandEvent &) +{ + switch (_language->GetSelection ()) { + case 0: + Config::instance()->set_language (""); + break; + case 1: + Config::instance()->set_language ("fr"); + break; + case 2: + Config::instance()->set_language ("it"); + break; + case 3: + Config::instance()->set_language ("es"); + break; + } +} + void ConfigDialog::tms_ip_changed (wxCommandEvent &) { diff --git a/src/wx/config_dialog.h b/src/wx/config_dialog.h index 948bf0571..8a3c81ec9 100644 --- a/src/wx/config_dialog.h +++ b/src/wx/config_dialog.h @@ -39,6 +39,7 @@ public: ConfigDialog (wxWindow *); private: + void language_changed (wxCommandEvent &); void tms_ip_changed (wxCommandEvent &); void tms_path_changed (wxCommandEvent &); void tms_user_changed (wxCommandEvent &); @@ -55,7 +56,8 @@ private: void server_selection_changed (wxListEvent &); void add_server_to_control (ServerDescription *); - + + wxChoice* _language; wxTextCtrl* _tms_ip; wxTextCtrl* _tms_path; wxTextCtrl* _tms_user; -- cgit v1.2.3 From fed8744100ee8e58c09b0394d05ac908f2c4e15f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 25 Mar 2013 22:58:15 +0000 Subject: Improve language setup. --- src/lib/config.h | 4 ++++ src/lib/util.cc | 5 ++++- src/wx/config_dialog.cc | 27 +++++++++++++++++++++++++-- src/wx/config_dialog.h | 3 +++ 4 files changed, 36 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/lib/config.h b/src/lib/config.h index ee46166e6..011ca716f 100644 --- a/src/lib/config.h +++ b/src/lib/config.h @@ -165,6 +165,10 @@ public: void set_language (std::string l) { _language = l; } + + void unset_language () { + _language = boost::none; + } void write () const; diff --git a/src/lib/util.cc b/src/lib/util.cc index 593d0e760..2e4671251 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -271,7 +271,10 @@ dvdomatic_setup_i18n (string lang) putenv (e.c_str()); bindtextdomain ("libdvdomatic", mo_path().string().c_str()); -#endif +#else + /* Hack to silence warning */ + lang.clear (); +#endif #ifdef DVDOMATIC_POSIX bindtextdomain ("libdvdomatic", POSIX_LOCALE_PREFIX); diff --git a/src/wx/config_dialog.cc b/src/wx/config_dialog.cc index ea1a7319e..364336114 100644 --- a/src/wx/config_dialog.cc +++ b/src/wx/config_dialog.cc @@ -46,7 +46,8 @@ ConfigDialog::ConfigDialog (wxWindow* parent) wxFlexGridSizer* table = new wxFlexGridSizer (3, 6, 6); table->AddGrowableCol (1, 1); - add_label_to_sizer (table, this, _("User interface language")); + _set_language = new wxCheckBox (this, wxID_ANY, _("Set language")); + table->Add (_set_language, 1, wxEXPAND); _language = new wxChoice (this, wxID_ANY); _language->Append (wxT ("English")); _language->Append (wxT ("Français")); @@ -149,6 +150,8 @@ ConfigDialog::ConfigDialog (wxWindow* parent) Config* config = Config::instance (); + _set_language->SetValue (config->language ()); + if (config->language().get_value_or ("") == "fr") { _language->SetSelection (1); } else if (config->language().get_value_or ("") == "it") { @@ -158,7 +161,10 @@ ConfigDialog::ConfigDialog (wxWindow* parent) } else { _language->SetSelection (0); } - + + setup_language_sensitivity (); + + _set_language->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (ConfigDialog::set_language_changed), 0, this); _language->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (ConfigDialog::language_changed), 0, this); _tms_ip->SetValue (std_to_wx (config->tms_ip ())); _tms_ip->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (ConfigDialog::tms_ip_changed), 0, this); @@ -371,3 +377,20 @@ ConfigDialog::edit_default_dci_metadata_clicked (wxCommandEvent &) Config::instance()->set_default_dci_metadata (d->dci_metadata ()); d->Destroy (); } + +void +ConfigDialog::set_language_changed (wxCommandEvent& ev) +{ + setup_language_sensitivity (); + if (_set_language->GetValue ()) { + language_changed (ev); + } else { + Config::instance()->unset_language (); + } +} + +void +ConfigDialog::setup_language_sensitivity () +{ + _language->Enable (_set_language->GetValue ()); +} diff --git a/src/wx/config_dialog.h b/src/wx/config_dialog.h index 8a3c81ec9..f6f3b3707 100644 --- a/src/wx/config_dialog.h +++ b/src/wx/config_dialog.h @@ -39,6 +39,7 @@ public: ConfigDialog (wxWindow *); private: + void set_language_changed (wxCommandEvent &); void language_changed (wxCommandEvent &); void tms_ip_changed (wxCommandEvent &); void tms_path_changed (wxCommandEvent &); @@ -56,7 +57,9 @@ private: void server_selection_changed (wxListEvent &); void add_server_to_control (ServerDescription *); + void setup_language_sensitivity (); + wxCheckBox* _set_language; wxChoice* _language; wxTextCtrl* _tms_ip; wxTextCtrl* _tms_path; -- cgit v1.2.3 From 04271e8ad9df1c4f57ec04f42c3bb6acebbb85e8 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 25 Mar 2013 23:01:54 +0000 Subject: Updated it_IT translation from Massimiliano. --- src/tools/po/it_IT.po | 12 ++--- src/wx/po/it_IT.po | 120 +++++++++++++++++++++++++------------------------- 2 files changed, 66 insertions(+), 66 deletions(-) (limited to 'src') diff --git a/src/tools/po/it_IT.po b/src/tools/po/it_IT.po index 89385047b..23574ee41 100644 --- a/src/tools/po/it_IT.po +++ b/src/tools/po/it_IT.po @@ -7,15 +7,15 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-20 13:37+0000\n" -"PO-Revision-Date: 2013-03-20 12:03+0100\n" +"POT-Creation-Date: 2013-03-15 08:39+0000\n" +"PO-Revision-Date: 2013-03-22 18:03+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" -"Language: Italiano\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" +"Language: Italiano\n" #: src/tools/dvdomatic.cc:177 msgid "&Analyse audio" @@ -75,7 +75,7 @@ msgstr "" msgid "About" msgstr "Informazioni" -#: src/tools/dvdomatic.cc:500 +#: src/tools/dvdomatic.cc:497 msgid "Could not load film %1 (%2)" msgstr "Non posso caricare il film %1 (%2)" @@ -85,7 +85,7 @@ msgid "Could not open film at %s (%s)" msgstr "Non posso aprire il film in %s (%s)" #: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:402 -#: src/tools/dvdomatic.cc:504 +#: src/tools/dvdomatic.cc:501 msgid "DVD-o-matic" msgstr "DVD-o-matic" @@ -112,4 +112,4 @@ msgstr "Seleziona il film da aprire" #: src/tools/dvdomatic.cc:303 #, c-format msgid "The directory %s already exists." -msgstr "La directory %s esiste già." +msgstr "La directory %s esiste gia'." diff --git a/src/wx/po/it_IT.po b/src/wx/po/it_IT.po index 89ae9efec..5f6b62fb2 100644 --- a/src/wx/po/it_IT.po +++ b/src/wx/po/it_IT.po @@ -7,25 +7,25 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-20 13:37+0000\n" -"PO-Revision-Date: 2013-03-20 11:50+0100\n" +"POT-Creation-Date: 2013-03-15 08:39+0000\n" +"PO-Revision-Date: 2013-03-22 18:10+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" -"Language: Italiano\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" +"Language: Italiano\n" -#: src/wx/film_editor.cc:440 +#: src/wx/film_editor.cc:441 msgid "%" msgstr "%" -#: src/wx/film_editor.cc:1229 +#: src/wx/film_editor.cc:1230 msgid "1 channel" msgstr "Canale 1" -#: src/wx/film_editor.cc:184 +#: src/wx/film_editor.cc:185 msgid "A/B" msgstr "A/B" @@ -33,15 +33,15 @@ msgstr "A/B" msgid "Add" msgstr "Aggiungi" -#: src/wx/audio_dialog.cc:32 src/wx/film_editor.cc:77 +#: src/wx/audio_dialog.cc:32 src/wx/film_editor.cc:78 msgid "Audio" msgstr "Audio" -#: src/wx/film_editor.cc:381 +#: src/wx/film_editor.cc:382 msgid "Audio Delay" msgstr "Ritardo dell'audio" -#: src/wx/film_editor.cc:369 +#: src/wx/film_editor.cc:370 msgid "Audio Gain" msgstr "Guadagno dell'audio" @@ -54,7 +54,7 @@ msgstr "Lingua dell'audio (es. EN)" msgid "Bad setting for %s (%s)" msgstr "Valore sbagliato per %s (%s)" -#: src/wx/film_editor.cc:296 +#: src/wx/film_editor.cc:297 msgid "Bottom crop" msgstr "Taglio in basso" @@ -64,9 +64,9 @@ msgstr "Sfoglia..." #: src/wx/gain_calculator_dialog.cc:36 msgid "But I have to use fader" -msgstr "Ma devo usare il fader" +msgstr "Ma dovrò riprodurre con il fader a" -#: src/wx/film_editor.cc:374 +#: src/wx/film_editor.cc:375 msgid "Calculate..." msgstr "Calcola..." @@ -74,15 +74,15 @@ msgstr "Calcola..." msgid "Channels" msgstr "Canali" -#: src/wx/film_editor.cc:325 +#: src/wx/film_editor.cc:326 msgid "Colour look-up table" msgstr "Tabella per ricerca del colore" -#: src/wx/film_editor.cc:120 +#: src/wx/film_editor.cc:121 msgid "Content" msgstr "Contenuto" -#: src/wx/film_editor.cc:130 +#: src/wx/film_editor.cc:131 msgid "Content Type" msgstr "Tipo di contenuto" @@ -101,7 +101,7 @@ msgstr "Non posso creare il DCP: %s" msgid "Could not open content file (%s)" msgstr "Non posso aprire il file del contenuto (%s)" -#: src/wx/film_editor.cc:504 +#: src/wx/film_editor.cc:505 #, c-format msgid "Could not set content: %s" msgstr "Non posso regolare il contenuto: %s" @@ -114,11 +114,11 @@ msgstr "Crea nella cartella" msgid "DCI name" msgstr "Nome del DCP" -#: src/wx/film_editor.cc:141 +#: src/wx/film_editor.cc:142 msgid "DCP Frame Rate" msgstr "Frequenza fotogrammi del DCP" -#: src/wx/film_editor.cc:109 +#: src/wx/film_editor.cc:110 msgid "DCP Name" msgstr "Nome del DCP" @@ -142,7 +142,7 @@ msgstr "Dettagli del nome di default DCI" msgid "Default directory for new films" msgstr "Directory di default per i nuovi films" -#: src/wx/film_editor.cc:116 src/wx/job_manager_view.cc:88 +#: src/wx/film_editor.cc:117 src/wx/job_manager_view.cc:88 msgid "Details..." msgstr "Dettagli" @@ -150,7 +150,7 @@ msgstr "Dettagli" msgid "Disk space required" msgstr "Spazio su disco rischiesto" -#: src/wx/film_editor.cc:191 +#: src/wx/film_editor.cc:192 msgid "Duration" msgstr "Durata" @@ -159,7 +159,7 @@ msgid "Edit" msgstr "Modifica" #: src/wx/config_dialog.cc:84 src/wx/config_dialog.cc:103 -#: src/wx/film_editor.cc:308 +#: src/wx/film_editor.cc:309 msgid "Edit..." msgstr "Modifica..." @@ -167,7 +167,7 @@ msgstr "Modifica..." msgid "Encoding Servers" msgstr "Servers di codifica" -#: src/wx/film_editor.cc:176 +#: src/wx/film_editor.cc:177 msgid "End" msgstr "Fine" @@ -175,7 +175,7 @@ msgstr "Fine" msgid "Facility (e.g. DLA)" msgstr "Facility (es. DLA)" -#: src/wx/film_editor.cc:73 +#: src/wx/film_editor.cc:74 msgid "Film" msgstr "Film" @@ -187,11 +187,11 @@ msgstr "Proprietà del film" msgid "Film name" msgstr "Nome del film" -#: src/wx/film_editor.cc:303 src/wx/filter_dialog.cc:32 +#: src/wx/film_editor.cc:304 src/wx/filter_dialog.cc:32 msgid "Filters" msgstr "Filtri" -#: src/wx/film_editor.cc:268 +#: src/wx/film_editor.cc:269 msgid "Format" msgstr "Formato" @@ -205,7 +205,7 @@ msgstr "Fotogrammi già codificati" #: src/wx/gain_calculator_dialog.cc:27 msgid "Gain Calculator" -msgstr "Calcolatore del guadagno" +msgstr "Calcola il guadagno audio" #: src/wx/properties_dialog.cc:59 msgid "Gb" @@ -215,31 +215,31 @@ msgstr "Gb" msgid "Host name or IP address" msgstr "Nome dell'Host o indirizzo IP" -#: src/wx/film_editor.cc:1233 +#: src/wx/film_editor.cc:1234 msgid "Hz" msgstr "Hz" #: src/wx/gain_calculator_dialog.cc:32 msgid "I want to play this back at fader" -msgstr "Voglio riprodurrlo back at fader" +msgstr "Sto usando il fader a" #: src/wx/config_dialog.cc:113 msgid "IP address" msgstr "Indirizzo IP" -#: src/wx/film_editor.cc:335 +#: src/wx/film_editor.cc:336 msgid "JPEG2000 bandwidth" msgstr "Banda passante JPEG2000" -#: src/wx/film_editor.cc:281 +#: src/wx/film_editor.cc:282 msgid "Left crop" msgstr "Taglio a sinistra" -#: src/wx/film_editor.cc:164 +#: src/wx/film_editor.cc:165 msgid "Length" msgstr "Lunghezza" -#: src/wx/film_editor.cc:339 +#: src/wx/film_editor.cc:340 msgid "MBps" msgstr "MBps" @@ -247,7 +247,7 @@ msgstr "MBps" msgid "My Documents" msgstr "Documenti" -#: src/wx/film_editor.cc:104 +#: src/wx/film_editor.cc:105 msgid "Name" msgstr "Nome" @@ -255,15 +255,15 @@ msgstr "Nome" msgid "New Film" msgstr "Nuovo Film" -#: src/wx/film_editor.cc:305 src/wx/film_editor.cc:664 +#: src/wx/film_editor.cc:306 src/wx/film_editor.cc:665 msgid "None" msgstr "Nessuno" -#: src/wx/film_editor.cc:135 +#: src/wx/film_editor.cc:136 msgid "Original Frame Rate" msgstr "Frequenza fotogrammi originale" -#: src/wx/film_editor.cc:159 +#: src/wx/film_editor.cc:160 msgid "Original Size" msgstr "Dimensione Originale" @@ -303,7 +303,7 @@ msgstr "Scalatura di riferimento A/B" msgid "Remove" msgstr "Rimuovi" -#: src/wx/film_editor.cc:286 +#: src/wx/film_editor.cc:287 msgid "Right crop" msgstr "Taglio a destra" @@ -311,15 +311,15 @@ msgstr "Taglio a destra" msgid "Running" msgstr "In corso" -#: src/wx/film_editor.cc:315 +#: src/wx/film_editor.cc:316 msgid "Scaler" msgstr "Scaler" -#: src/wx/film_editor.cc:407 +#: src/wx/film_editor.cc:408 msgid "Select Audio File" -msgstr "Seleziona File Audio" +msgstr "Seleziona file audio" -#: src/wx/film_editor.cc:121 +#: src/wx/film_editor.cc:122 msgid "Select Content File" msgstr "Seleziona il file con il contenuto" @@ -327,7 +327,7 @@ msgstr "Seleziona il file con il contenuto" msgid "Server" msgstr "Server" -#: src/wx/film_editor.cc:364 +#: src/wx/film_editor.cc:365 msgid "Show Audio..." msgstr "Mostra Audio..." @@ -335,7 +335,7 @@ msgstr "Mostra Audio..." msgid "Smoothing" msgstr "Levigatura" -#: src/wx/film_editor.cc:173 +#: src/wx/film_editor.cc:174 msgid "Start" msgstr "Inizio" @@ -347,15 +347,15 @@ msgstr "Studio (es. TCF)" msgid "Subtitle Language (e.g. FR)" msgstr "Lingua dei Sottotitoli (es. FR)" -#: src/wx/film_editor.cc:431 +#: src/wx/film_editor.cc:432 msgid "Subtitle Offset" msgstr "Sfalsamento dei Sottotitoli" -#: src/wx/film_editor.cc:436 +#: src/wx/film_editor.cc:437 msgid "Subtitle Scale" msgstr "Scala dei Sottotitoli" -#: src/wx/film_editor.cc:79 +#: src/wx/film_editor.cc:80 msgid "Subtitles" msgstr "Sottotitoli" @@ -395,15 +395,15 @@ msgstr "Threads da usare per codificare su questo host" msgid "Time" msgstr "Tempo" -#: src/wx/film_editor.cc:291 +#: src/wx/film_editor.cc:292 msgid "Top crop" msgstr "Taglio in alto" -#: src/wx/film_editor.cc:171 +#: src/wx/film_editor.cc:172 msgid "Trim frames" msgstr "Taglia fotogrammi" -#: src/wx/film_editor.cc:125 +#: src/wx/film_editor.cc:126 msgid "Trust content's header" msgstr "Conferma l'intestazione del contenuto" @@ -411,31 +411,31 @@ msgstr "Conferma l'intestazione del contenuto" msgid "Type" msgstr "Tipo" -#: src/wx/film_editor.cc:114 +#: src/wx/film_editor.cc:115 msgid "Use DCI name" msgstr "Usa nome DCI" -#: src/wx/film_editor.cc:145 +#: src/wx/film_editor.cc:146 msgid "Use best" msgstr "Usa la migliore" -#: src/wx/film_editor.cc:391 +#: src/wx/film_editor.cc:392 msgid "Use content's audio" msgstr "Usa l'audio del contenuto" -#: src/wx/film_editor.cc:401 +#: src/wx/film_editor.cc:402 msgid "Use external audio" msgstr "Usa l'audio esterno" -#: src/wx/film_editor.cc:75 +#: src/wx/film_editor.cc:76 msgid "Video" msgstr "Video" -#: src/wx/film_editor.cc:424 +#: src/wx/film_editor.cc:425 msgid "With Subtitles" msgstr "Con Sottotitoli" -#: src/wx/film_editor.cc:1231 +#: src/wx/film_editor.cc:1232 msgid "channels" msgstr "canali" @@ -443,21 +443,21 @@ msgstr "canali" msgid "counting..." msgstr "conteggio..." -#: src/wx/film_editor.cc:373 +#: src/wx/film_editor.cc:374 msgid "dB" msgstr "dB" -#: src/wx/film_editor.cc:690 src/wx/film_editor.cc:692 +#: src/wx/film_editor.cc:691 src/wx/film_editor.cc:693 msgid "frames" msgstr "fotogrammi" #. / TRANSLATORS: this is an abbreviation for milliseconds, the unit of time -#: src/wx/film_editor.cc:386 +#: src/wx/film_editor.cc:387 msgid "ms" msgstr "ms" #. / TRANSLATORS: `s' here is an abbreviation for seconds, the unit of time -#: src/wx/film_editor.cc:197 +#: src/wx/film_editor.cc:198 msgid "s" msgstr "s" -- cgit v1.2.3 From 99d08c12756cd936585d777b7a91ecbba35fa4c3 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 25 Mar 2013 23:53:59 +0000 Subject: Translation fixes from Lilian Lefranc. --- src/lib/po/fr_FR.po | 2 +- src/wx/film_editor.cc | 14 ++++++++------ src/wx/po/fr_FR.po | 6 +++--- src/wx/properties_dialog.cc | 2 +- 4 files changed, 13 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/lib/po/fr_FR.po b/src/lib/po/fr_FR.po index 895afcabe..7832e4223 100644 --- a/src/lib/po/fr_FR.po +++ b/src/lib/po/fr_FR.po @@ -225,7 +225,7 @@ msgstr "Débruiteur 3D haute qualité" #: src/lib/filter.cc:68 msgid "Horizontal deblocking filter" -msgstr "Filtre débloc horizontal" +msgstr "Filtre dé-bloc horizontal" #: src/lib/filter.cc:70 msgid "Horizontal deblocking filter A" diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 2553d0bd5..cb596d6e0 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -687,9 +687,11 @@ FilmEditor::film_changed (Film::Property p) break; case Film::LENGTH: if (_film->source_frame_rate() > 0 && _film->length()) { - s << _film->length().get() << " " << _("frames") << "; " << seconds_to_hms (_film->length().get() / _film->source_frame_rate()); + s << _film->length().get() << " " + << std_to_wx (_("frames")) << "; " << seconds_to_hms (_film->length().get() / _film->source_frame_rate()); } else if (_film->length()) { - s << _film->length().get() << " " << _("frames"); + s << _film->length().get() << " " + << std_to_wx (_("frames")); } _length->SetLabel (std_to_wx (s.str ())); if (_film->length()) { @@ -842,7 +844,7 @@ FilmEditor::set_film (shared_ptr f) if (_film) { FileChanged (_film->directory ()); } else { - FileChanged (wx_to_std (N_(""))); + FileChanged (""); } if (_audio_dialog) { @@ -1226,11 +1228,11 @@ FilmEditor::setup_audio_details () } else { stringstream s; if (_film->audio_stream()->channels() == 1) { - s << _("1 channel"); + s << wx_to_std (_("1 channel")); } else { - s << _film->audio_stream()->channels () << " " << _("channels"); + s << _film->audio_stream()->channels () << " " << wx_to_std (_("channels")); } - s << ", " << _film->audio_stream()->sample_rate() << _("Hz"); + s << ", " << _film->audio_stream()->sample_rate() << wx_to_std (_("Hz")); _audio->SetLabel (std_to_wx (s.str ())); } } diff --git a/src/wx/po/fr_FR.po b/src/wx/po/fr_FR.po index a36d07776..669283aa6 100644 --- a/src/wx/po/fr_FR.po +++ b/src/wx/po/fr_FR.po @@ -236,7 +236,7 @@ msgstr "Découpe gauche" #: src/wx/film_editor.cc:164 msgid "Length" -msgstr "Longueur" +msgstr "Longueur durée" #: src/wx/film_editor.cc:339 msgid "MBps" @@ -296,7 +296,7 @@ msgstr "Filtres de référence pour A/B" #: src/wx/config_dialog.cc:88 msgid "Reference scaler for A/B" -msgstr "Échelle de référence pour A7B" +msgstr "Échelle de référence pour A/B" #: src/wx/config_dialog.cc:128 msgid "Remove" @@ -328,7 +328,7 @@ msgstr "Serveur" #: src/wx/film_editor.cc:364 msgid "Show Audio..." -msgstr "Montrer le son..." +msgstr "Analyser le son..." #: src/wx/audio_dialog.cc:71 msgid "Smoothing" diff --git a/src/wx/properties_dialog.cc b/src/wx/properties_dialog.cc index f4acb6b1a..02f848c01 100644 --- a/src/wx/properties_dialog.cc +++ b/src/wx/properties_dialog.cc @@ -56,7 +56,7 @@ PropertiesDialog::PropertiesDialog (wxWindow* parent, shared_ptr film) int const dcp_length = _film->length().get() * frc.factor(); double const disk = ((double) _film->j2k_bandwidth() / 8) * dcp_length / (_film->dcp_frame_rate() * 1073741824); stringstream s; - s << fixed << setprecision (1) << disk << _("Gb"); + s << fixed << setprecision (1) << disk << wx_to_std (_("Gb")); _disk->SetLabel (std_to_wx (s.str ())); } else { _frames->SetLabel (_("unknown")); -- cgit v1.2.3 From 9a47f2dfa7e166dc7a07fafd2cb7d41f64957fc7 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 25 Mar 2013 23:55:12 +0000 Subject: Fixes to previous. --- src/wx/film_editor.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index cb596d6e0..ec99f4d9d 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -688,10 +688,10 @@ FilmEditor::film_changed (Film::Property p) case Film::LENGTH: if (_film->source_frame_rate() > 0 && _film->length()) { s << _film->length().get() << " " - << std_to_wx (_("frames")) << "; " << seconds_to_hms (_film->length().get() / _film->source_frame_rate()); + << wx_to_std (_("frames")) << "; " << seconds_to_hms (_film->length().get() / _film->source_frame_rate()); } else if (_film->length()) { s << _film->length().get() << " " - << std_to_wx (_("frames")); + << wx_to_std (_("frames")); } _length->SetLabel (std_to_wx (s.str ())); if (_film->length()) { -- cgit v1.2.3 From e14edb562b6b7516ee3a2805d2669662da4da8bc Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 26 Mar 2013 00:07:45 +0000 Subject: Try to stop trailing underscores at the ends of DCI names (#88). --- src/lib/film.cc | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/lib/film.cc b/src/lib/film.cc index c84042451..bd11c1eb5 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -755,70 +755,67 @@ Film::dci_name (bool if_created_now) const fixed_name = fixed_name.substr (0, 14); } - d << fixed_name << "_"; + d << fixed_name; if (dcp_content_type()) { - d << dcp_content_type()->dci_name() << "_"; + d << "_" << dcp_content_type()->dci_name(); } if (format()) { - d << format()->dci_name() << "_"; + d << "_" << format()->dci_name(); } DCIMetadata const dm = dci_metadata (); if (!dm.audio_language.empty ()) { - d << dm.audio_language; - if (!dm.subtitle_language.empty() && with_subtitles()) { + d << "_" << dm.audio_language; + if (!dm.subtitle_language.empty()) { d << "-" << dm.subtitle_language; } else { d << "-XX"; } - - d << "_"; } if (!dm.territory.empty ()) { - d << dm.territory; + d << "_" << dm.territory; if (!dm.rating.empty ()) { d << "-" << dm.rating; } - d << "_"; } switch (audio_channels()) { case 1: - d << "10_"; + d << "_10"; break; case 2: - d << "20_"; + d << "_20"; break; case 6: - d << "51_"; + d << "_51"; break; case 8: - d << "71_"; + d << "_71"; break; } - d << "2K_"; + d << "_2K"; if (!dm.studio.empty ()) { - d << dm.studio << "_"; + d << "_" << dm.studio; } if (if_created_now) { - d << boost::gregorian::to_iso_string (boost::gregorian::day_clock::local_day ()) << "_"; + d << "_" << boost::gregorian::to_iso_string (boost::gregorian::day_clock::local_day ()); } else { - d << boost::gregorian::to_iso_string (_dci_date) << "_"; + d << "_" << boost::gregorian::to_iso_string (_dci_date); } if (!dm.facility.empty ()) { - d << dm.facility << "_"; + d << "_" << dm.facility; } if (!dm.package_type.empty ()) { - d << dm.package_type; + d << "_" << dm.package_type; } return d.str (); -- cgit v1.2.3 From 8bb8f8e8d11ffbf7c18d6162c9983d1a18f4311b Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 26 Mar 2013 00:55:58 +0000 Subject: Basics of allowing job cancellation (#83, #16). --- src/lib/job.cc | 30 ++++++++++++++++++++++++++++-- src/lib/job.h | 14 ++++++++++---- src/wx/job_manager_view.cc | 29 ++++++++++++++++++++++++----- src/wx/job_manager_view.h | 2 ++ 4 files changed, 64 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/lib/job.cc b/src/lib/job.cc index 8c1612a55..ace02b8b3 100644 --- a/src/lib/job.cc +++ b/src/lib/job.cc @@ -38,6 +38,7 @@ using boost::shared_ptr; */ Job::Job (shared_ptr f) : _film (f) + , _thread (0) , _state (NEW) , _start_time (0) , _progress_unknown (false) @@ -52,7 +53,7 @@ Job::start () { set_state (RUNNING); _start_time = time (0); - boost::thread (boost::bind (&Job::run_wrapper, this)); + _thread = new boost::thread (boost::bind (&Job::run_wrapper, this)); } /** A wrapper for the ::run() method to catch exceptions */ @@ -77,6 +78,10 @@ Job::run_wrapper () } set_error (e.what(), m); + + } catch (boost::thread_interrupted &) { + + set_state (FINISHED_CANCELLED); } catch (std::exception& e) { @@ -120,7 +125,7 @@ bool Job::finished () const { boost::mutex::scoped_lock lm (_state_mutex); - return _state == FINISHED_OK || _state == FINISHED_ERROR; + return _state == FINISHED_OK || _state == FINISHED_ERROR || _state == FINISHED_CANCELLED; } /** @return true if the job has finished successfully */ @@ -139,6 +144,13 @@ Job::finished_in_error () const return _state == FINISHED_ERROR; } +bool +Job::finished_cancelled () const +{ + boost::mutex::scoped_lock lm (_state_mutex); + return _state == FINISHED_CANCELLED; +} + /** Set the state of this job. * @param s New state. */ @@ -173,6 +185,7 @@ Job::set_progress (float p) boost::mutex::scoped_lock lm (_progress_mutex); _progress_unknown = false; _stack.back().normalised = p; + boost::this_thread::interruption_point (); } /** @return fractional overall progress, or -1 if not known */ @@ -285,6 +298,8 @@ Job::status () const s << String::compose (_("OK (ran for %1)"), seconds_to_hms (_ran_for)); } else if (finished_in_error ()) { s << String::compose (_("Error (%1)"), error_summary()); + } else if (finished_cancelled ()) { + s << _("Cancelled"); } return s.str (); @@ -296,3 +311,14 @@ Job::remaining_time () const { return elapsed_time() / overall_progress() - elapsed_time(); } + +void +Job::cancel () +{ + if (!_thread) { + return; + } + + _thread->interrupt (); + _thread->join (); +} diff --git a/src/lib/job.h b/src/lib/job.h index c98dbaea1..fd036bce2 100644 --- a/src/lib/job.h +++ b/src/lib/job.h @@ -28,6 +28,7 @@ #include #include #include +#include class Film; @@ -46,12 +47,14 @@ public: virtual void run () = 0; void start (); + void cancel (); bool is_new () const; bool running () const; bool finished () const; bool finished_ok () const; bool finished_in_error () const; + bool finished_cancelled () const; std::string error_summary () const; std::string error_details () const; @@ -74,10 +77,11 @@ protected: /** Description of a job's state */ enum State { - NEW, ///< the job hasn't been started yet - RUNNING, ///< the job is running - FINISHED_OK, ///< the job has finished successfully - FINISHED_ERROR ///< the job has finished in error + NEW, ///< the job hasn't been started yet + RUNNING, ///< the job is running + FINISHED_OK, ///< the job has finished successfully + FINISHED_ERROR, ///< the job has finished in error + FINISHED_CANCELLED ///< the job was cancelled }; void set_state (State); @@ -90,6 +94,8 @@ private: void run_wrapper (); + boost::thread* _thread; + /** mutex for _state and _error */ mutable boost::mutex _state_mutex; /** current state of the job */ diff --git a/src/wx/job_manager_view.cc b/src/wx/job_manager_view.cc index 7361f29a8..f7d2315cc 100644 --- a/src/wx/job_manager_view.cc +++ b/src/wx/job_manager_view.cc @@ -42,7 +42,7 @@ JobManagerView::JobManagerView (wxWindow* parent) sizer->Add (_panel, 1, wxEXPAND); SetSizer (sizer); - _table = new wxFlexGridSizer (4, 6, 6); + _table = new wxFlexGridSizer (5, 6, 6); _table->AddGrowableCol (1, 1); _panel->SetSizer (_table); @@ -85,10 +85,14 @@ JobManagerView::update () r.message = new wxStaticText (_panel, wxID_ANY, std_to_wx ("")); _table->Insert (index + 2, r.message, 1, wxALIGN_CENTER_VERTICAL | wxALL, 6); + r.cancel = new wxButton (_panel, wxID_ANY, _("Cancel")); + r.cancel->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (JobManagerView::cancel_clicked), 0, this); + _table->Insert (index + 3, r.cancel, 1, wxALIGN_CENTER_VERTICAL | wxALL, 6); + r.details = new wxButton (_panel, wxID_ANY, _("Details...")); r.details->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (JobManagerView::details_clicked), 0, this); r.details->Enable (false); - _table->Insert (index + 3, r.details, 1, wxALIGN_CENTER_VERTICAL | wxALL, 6); + _table->Insert (index + 4, r.details, 1, wxALIGN_CENTER_VERTICAL | wxALL, 6); _job_records[*i] = r; } @@ -105,18 +109,21 @@ JobManagerView::update () _job_records[*i].gauge->Pulse (); } } - + if ((*i)->finished() && !_job_records[*i].finalised) { - _job_records[*i].gauge->SetValue (100); checked_set (_job_records[*i].message, st); + if (!(*i)->finished_cancelled()) { + _job_records[*i].gauge->SetValue (100); + } (*i)->Finished (); _job_records[*i].finalised = true; + _job_records[*i].cancel->Enable (false); if (!(*i)->error_details().empty ()) { _job_records[*i].details->Enable (true); } } - index += 4; + index += 5; } _table->Layout (); @@ -136,3 +143,15 @@ JobManagerView::details_clicked (wxCommandEvent& ev) } } } + +void +JobManagerView::cancel_clicked (wxCommandEvent& ev) +{ + wxObject* o = ev.GetEventObject (); + + for (map, JobRecord>::iterator i = _job_records.begin(); i != _job_records.end(); ++i) { + if (i->second.cancel == o) { + i->first->cancel (); + } + } +} diff --git a/src/wx/job_manager_view.h b/src/wx/job_manager_view.h index d43e795ea..72ac85c02 100644 --- a/src/wx/job_manager_view.h +++ b/src/wx/job_manager_view.h @@ -39,6 +39,7 @@ public: private: void periodic (wxTimerEvent &); + void cancel_clicked (wxCommandEvent &); void details_clicked (wxCommandEvent &); boost::shared_ptr _timer; @@ -47,6 +48,7 @@ private: struct JobRecord { wxGauge* gauge; wxStaticText* message; + wxButton* cancel; wxButton* details; bool finalised; }; -- cgit v1.2.3 From 88b7359bcea1ff64bf9f138dc701c6fd55ba500c Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 26 Mar 2013 10:33:21 +0000 Subject: Updated Spanish translation from Manual AC. --- src/lib/po/es_ES.po | 586 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/tools/po/es_ES.po | 8 +- src/wx/po/es_ES.po | 466 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 1056 insertions(+), 4 deletions(-) create mode 100644 src/lib/po/es_ES.po create mode 100644 src/wx/po/es_ES.po (limited to 'src') diff --git a/src/lib/po/es_ES.po b/src/lib/po/es_ES.po new file mode 100644 index 000000000..c84563355 --- /dev/null +++ b/src/lib/po/es_ES.po @@ -0,0 +1,586 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: LIBDVDOMATIC\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-03-15 08:39+0000\n" +"PO-Revision-Date: 2013-03-23 22:42-0500\n" +"Last-Translator: Manuel AC \n" +"Language-Team: Manuel AC \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.5.5\n" +"Language: es-ES\n" + +#: src/lib/transcode_job.cc:87 +msgid "0%" +msgstr "0%" + +#: src/lib/format.cc:75 +msgid "1.19" +msgstr "1.19" + +#: src/lib/format.cc:80 +msgid "1.33" +msgstr "1.33" + +#: src/lib/format.cc:85 +msgid "1.375" +msgstr "1.375" + +#: src/lib/format.cc:100 +msgid "1.66" +msgstr "1.66" + +#: src/lib/format.cc:105 +msgid "1.66 within Flat" +msgstr "1.66 en Flat" + +#: src/lib/format.cc:115 +msgid "16:9" +msgstr "16:9" + +#: src/lib/format.cc:110 +msgid "16:9 within Flat" +msgstr "16:9 en Flat" + +#: src/lib/filter.cc:88 +msgid "3D denoiser" +msgstr "reducción de ruido 3D" + +#: src/lib/format.cc:90 +msgid "4:3 within Flat" +msgstr "4:3 en Flat" + +#: src/lib/ab_transcode_job.cc:49 +msgid "A/B transcode %1" +msgstr "Codificación A/B %1" + +#: src/lib/format.cc:95 +msgid "Academy" +msgstr "Academy" + +#: src/lib/dcp_content_type.cc:53 +msgid "Advertisement" +msgstr "Publicidad" + +#: src/lib/job.cc:71 +msgid "An error occurred whilst handling the file %1." +msgstr "Ha ocurrido un error con el fichero %1." + +#: src/lib/analyse_audio_job.cc:49 +msgid "Analyse audio of %1" +msgstr "Analizar audio de %1" + +#: src/lib/scaler.cc:64 +msgid "Area" +msgstr "Área" + +#: src/lib/scaler.cc:62 +msgid "Bicubic" +msgstr "Bicúbico" + +#: src/lib/scaler.cc:69 +msgid "Bilinear" +msgstr "Bilineal" + +#: src/lib/encoder.cc:101 +msgid "Cannot resample audio as libswresample is not present" +msgstr "" +"No se puede redimensionar el sonido porque no se encuentra libswresample" + +#: src/lib/scp_dcp_job.cc:109 +msgid "Copy DCP to TMS" +msgstr "Copiar DCP al TMS" + +#: src/lib/scp_dcp_job.cc:128 +msgid "Could not connect to server %1 (%2)" +msgstr "No se pudo conectar al servidor %1 (%2)" + +#: src/lib/scp_dcp_job.cc:150 +msgid "Could not create remote directory %1 (%2)" +msgstr "No se pudo crear la carpeta remota %1 (%2)" + +#: src/lib/scp_dcp_job.cc:175 +msgid "Could not open %1 to send" +msgstr "No se pudo abrir %1 para enviar" + +#: src/lib/scp_dcp_job.cc:145 +msgid "Could not start SCP session (%1)" +msgstr "No se pudo iniciar la sesión SCP (%1)" + +#: src/lib/scp_dcp_job.cc:187 +msgid "Could not write to remote file (%1)" +msgstr "No se pudo escribir el fichero remoto (%1)" + +#: src/lib/filter.cc:77 +msgid "Cubic interpolating deinterlacer" +msgstr "Desentrelazado por interpolación cúbica" + +#: src/lib/util.cc:965 +msgid "DCP and source have the same rate.\n" +msgstr "La fuente y el DCP tienen la misma velocidad.\n" + +#: src/lib/util.cc:975 +msgid "DCP will run at %1%% of the source speed." +msgstr "El DCP se reproducirá al %1%% de la velocidad de la fuente." + +#: src/lib/util.cc:968 +msgid "DCP will use every other frame of the source.\n" +msgstr "El DCP usará fotogramas alternos de la fuente.\n" + +#: src/lib/filter.cc:68 src/lib/filter.cc:69 src/lib/filter.cc:70 +#: src/lib/filter.cc:71 src/lib/filter.cc:72 src/lib/filter.cc:73 +msgid "De-blocking" +msgstr "" + +#: src/lib/filter.cc:75 src/lib/filter.cc:76 src/lib/filter.cc:77 +#: src/lib/filter.cc:78 src/lib/filter.cc:79 src/lib/filter.cc:80 +#: src/lib/filter.cc:81 src/lib/filter.cc:82 src/lib/filter.cc:83 +msgid "De-interlacing" +msgstr "Desentrelazado" + +#: src/lib/filter.cc:74 +msgid "Deringing filter" +msgstr "" + +#: src/lib/dolby_cp750.cc:27 +msgid "Dolby CP750" +msgstr "Dolby CP750" + +#: src/lib/util.cc:970 +msgid "Each source frame will be doubled in the DCP.\n" +msgstr "Se doblará cada fotograma de la fuente en el DCP.\n" + +#: src/lib/job.cc:287 +msgid "Error (%1)" +msgstr "Error (%1)" + +#: src/lib/examine_content_job.cc:55 +msgid "Examine content" +msgstr "Examinar contenido" + +#: src/lib/examine_content_job.cc:58 +msgid "Examine content of %1" +msgstr "Examinar contenido de %1" + +#: src/lib/filter.cc:72 +msgid "Experimental horizontal deblocking filter 1" +msgstr "" + +#: src/lib/filter.cc:73 +msgid "Experimental vertical deblocking filter 1" +msgstr "" + +#: src/lib/filter.cc:79 +msgid "FFMPEG deinterlacer" +msgstr "Desentrelazado FFMPEG" + +#: src/lib/filter.cc:80 +msgid "FIR low-pass deinterlacer" +msgstr "Desentrelazado paso bajo FIR" + +#: src/lib/scp_dcp_job.cc:138 +msgid "Failed to authenticate with server (%1)" +msgstr "Fallo al identificarse con el servidor (%1)" + +#: src/lib/scaler.cc:70 +msgid "Fast Bilinear" +msgstr "Bilineal rápido" + +#: src/lib/dcp_content_type.cc:44 +msgid "Feature" +msgstr "Película" + +#: src/lib/format.cc:120 +msgid "Flat" +msgstr "Flat" + +#: src/lib/format.cc:130 +msgid "Flat without stretch" +msgstr "Flat sin deformación" + +#: src/lib/filter.cc:85 +msgid "Force quantizer" +msgstr "" + +#: src/lib/scaler.cc:65 +msgid "Gaussian" +msgstr "Gaussiano" + +#: src/lib/filter.cc:86 +msgid "Gradient debander" +msgstr "" + +#: src/lib/filter.cc:89 +msgid "High quality 3D denoiser" +msgstr "Reductor de ruido 3D de alta calidad" + +#: src/lib/filter.cc:68 +msgid "Horizontal deblocking filter" +msgstr "" + +#: src/lib/filter.cc:70 +msgid "Horizontal deblocking filter A" +msgstr "" + +#: src/lib/job.cc:87 src/lib/job.cc:96 +msgid "" +"It is not known what caused this error. The best idea is to report the " +"problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" +msgstr "" +"Error desconocido. La mejor idea es informar del problema a la lista de " +"correo de DVD-O-matic (dvdomatic@carlh.net)" + +#: src/lib/filter.cc:82 +msgid "Kernel deinterlacer" +msgstr "" + +#: src/lib/scaler.cc:66 +msgid "Lanczos" +msgstr "Lanczos" + +#: src/lib/filter.cc:75 +msgid "Linear blend deinterlacer" +msgstr "" + +#: src/lib/filter.cc:76 +msgid "Linear interpolating deinterlacer" +msgstr "" + +#: src/lib/filter.cc:78 +msgid "Median deinterlacer" +msgstr "" + +#: src/lib/filter.cc:74 src/lib/filter.cc:85 src/lib/filter.cc:86 +#: src/lib/filter.cc:87 src/lib/filter.cc:90 +msgid "Misc" +msgstr "Miscelánea" + +#: src/lib/filter.cc:81 +msgid "Motion compensating deinterlacer" +msgstr "" + +#: src/lib/filter.cc:84 src/lib/filter.cc:88 src/lib/filter.cc:89 +#: src/lib/filter.cc:91 +msgid "Noise reduction" +msgstr "Reducción de ruido" + +#: src/lib/job.cc:285 +msgid "OK (ran for %1)" +msgstr "OK (ejecución %1)" + +#: src/lib/filter.cc:91 +msgid "Overcomplete wavelet denoiser" +msgstr "" + +#: src/lib/dcp_content_type.cc:51 +msgid "Policy" +msgstr "" + +#: src/lib/dcp_content_type.cc:52 +msgid "Public Service Announcement" +msgstr "Anuncio de servicio público" + +#: src/lib/dcp_content_type.cc:49 +msgid "Rating" +msgstr "Clasificación" + +#: src/lib/util.cc:458 +msgid "Rec 709" +msgstr "Rec 709" + +#: src/lib/scp_dcp_job.cc:133 +msgid "SSH error (%1)" +msgstr "error SSH (%1)" + +#: src/lib/format.cc:125 +msgid "Scope" +msgstr "Scope" + +#: src/lib/format.cc:135 +msgid "Scope without stretch" +msgstr "Scope sin deformación" + +#: src/lib/dcp_content_type.cc:45 +msgid "Short" +msgstr "Cortometraje" + +#: src/lib/scaler.cc:67 +msgid "Sinc" +msgstr "" + +#: src/lib/format.cc:76 +msgid "Source scaled to 1.19:1" +msgstr "Fuente escalada a 1.19:1" + +#: src/lib/format.cc:81 +msgid "Source scaled to 1.33:1" +msgstr "Fuente escalada a 1.33:1" + +#: src/lib/format.cc:91 +msgid "Source scaled to 1.33:1 then pillarboxed to Flat" +msgstr "Fuente escalada a 1.33:1 con bandas hasta Flat" + +#: src/lib/format.cc:86 +msgid "Source scaled to 1.375:1" +msgstr "Fuente escalada a 1.375:1" + +#: src/lib/format.cc:96 +msgid "Source scaled to 1.37:1 (Academy ratio)" +msgstr "Fuente escalada a 1.37:1 (Academy)" + +#: src/lib/format.cc:101 +msgid "Source scaled to 1.66:1" +msgstr "Fuente escalada a 1.66:1" + +#: src/lib/format.cc:106 +msgid "Source scaled to 1.66:1 then pillarboxed to Flat" +msgstr "Fuente escalada a 1.66:1 con bandas hasta Flat" + +#: src/lib/format.cc:116 +msgid "Source scaled to 1.78:1" +msgstr "Fuente escalada a 1.78:1" + +#: src/lib/format.cc:111 +msgid "Source scaled to 1.78:1 then pillarboxed to Flat" +msgstr "Fuente escalada a 1.78:1 con bandas hasta Flat" + +#: src/lib/format.cc:121 +msgid "Source scaled to Flat (1.85:1)" +msgstr "Fuente escalada a Flat (1.85:1)" + +#: src/lib/format.cc:126 +msgid "Source scaled to Scope (2.39:1)" +msgstr "Fuente escalada a Scope (2.39:1)" + +#: src/lib/format.cc:131 +msgid "Source scaled to fit Flat preserving its aspect ratio" +msgstr "Fuente escalada a Flat conservando el ratio de aspecto" + +#: src/lib/format.cc:136 +msgid "Source scaled to fit Scope preserving its aspect ratio" +msgstr "Fuente escalada a Scope conservando el ratio de aspecto" + +#: src/lib/scaler.cc:68 +msgid "Spline" +msgstr "" + +#: src/lib/dcp_content_type.cc:50 +msgid "Teaser" +msgstr "Teaser" + +#: src/lib/filter.cc:90 +msgid "Telecine filter" +msgstr "Filtro telecine" + +#: src/lib/filter.cc:84 +msgid "Temporal noise reducer" +msgstr "" + +#: src/lib/dcp_content_type.cc:47 +msgid "Test" +msgstr "Test" + +#: src/lib/job.cc:76 +msgid "" +"The drive that the film is stored on is low in disc space. Free some more " +"space and try again." +msgstr "" +"En el dispositivo donde se encuentra la película queda poco espacio. Libere " +"espacio en el disco y pruebe de nuevo." + +#: src/lib/dcp_content_type.cc:46 +msgid "Trailer" +msgstr "Trailer" + +#: src/lib/transcode_job.cc:54 +msgid "Transcode %1" +msgstr "Codificar %1" + +#: src/lib/dcp_content_type.cc:48 +msgid "Transitional" +msgstr "Transitional" + +#: src/lib/job.cc:95 +msgid "Unknown error" +msgstr "Error desconocido" + +#: src/lib/ffmpeg_decoder.cc:396 +msgid "Unrecognised audio sample format (%1)" +msgstr "Formato de audio desconocido (%1)" + +#: src/lib/filter.cc:87 +msgid "Unsharp mask and Gaussian blur" +msgstr "" + +#: src/lib/filter.cc:69 +msgid "Vertical deblocking filter" +msgstr "" + +#: src/lib/filter.cc:71 +msgid "Vertical deblocking filter A" +msgstr "" + +#: src/lib/scp_dcp_job.cc:101 +msgid "Waiting" +msgstr "Esperando" + +#: src/lib/scaler.cc:63 +msgid "X" +msgstr "X" + +#: src/lib/filter.cc:83 +msgid "Yet Another Deinterlacing Filter" +msgstr "" + +#: src/lib/encoder.cc:271 +msgid "adding to queue of %1" +msgstr "añadiendo a la cola de %1" + +#: src/lib/film.cc:263 +msgid "cannot contain slashes" +msgstr "no puede contener barras" + +#: src/lib/util.cc:499 +msgid "connect timed out" +msgstr "tiempo de conexión agotado" + +#: src/lib/scp_dcp_job.cc:119 +msgid "connecting" +msgstr "conectando" + +#: src/lib/film.cc:300 +msgid "content" +msgstr "contenido" + +#: src/lib/film.cc:304 +msgid "content type" +msgstr "tipo de contenido" + +#: src/lib/scp_dcp_job.cc:168 +msgid "copying %1" +msgstr "copiando %1" + +#: src/lib/ffmpeg_decoder.cc:191 +msgid "could not find audio decoder" +msgstr "no se encontró el decodificador de audio" + +#: src/lib/ffmpeg_decoder.cc:118 +msgid "could not find stream information" +msgstr "no se pudo encontrar información del flujo" + +#: src/lib/ffmpeg_decoder.cc:210 +msgid "could not find subtitle decoder" +msgstr "no se pudo encontrar decodificador de subtítutlos" + +#: src/lib/ffmpeg_decoder.cc:169 +msgid "could not find video decoder" +msgstr "no se pudo encontrar decodificador de vídeo" + +#: src/lib/external_audio_decoder.cc:72 +msgid "could not open external audio file for reading" +msgstr "no se pudo leer el fichero externo de audio" + +#: src/lib/dcp_video_frame.cc:388 +msgid "could not open file for reading" +msgstr "no se pudo abrir el fichero para lectura" + +#: src/lib/encoder.cc:137 src/lib/encoder.cc:314 +msgid "could not run sample-rate converter" +msgstr "no se pudo ejecutar el conversor de velocidad" + +#: src/lib/scp_dcp_job.cc:86 +msgid "could not start SCP session (%1)" +msgstr "no se pudo abrir la sesión SCP (%1)" + +#: src/lib/scp_dcp_job.cc:52 +msgid "could not start SSH session" +msgstr "no se pudo abrir la sesión SSH" + +#: src/lib/encoder.cc:247 +msgid "decoder sleeps with queue of %1" +msgstr "" + +#: src/lib/encoder.cc:249 +msgid "decoder wakes with queue of %1" +msgstr "" + +#: src/lib/external_audio_decoder.cc:94 +msgid "external audio files have differing lengths" +msgstr "los ficheros externos de sonido tienen duraciones diferentes" + +#: src/lib/external_audio_decoder.cc:76 +msgid "external audio files must be mono" +msgstr "los ficheros externos de sonido deben ser mono" + +#: src/lib/film.cc:296 +msgid "format" +msgstr "formato" + +#: src/lib/transcode_job.cc:100 +msgid "frames per second" +msgstr "fotogramas por segundo" + +#: src/lib/util.cc:115 +msgid "hour" +msgstr "hora" + +#: src/lib/util.cc:112 src/lib/util.cc:117 +msgid "hours" +msgstr "horas" + +#: src/lib/util.cc:122 +msgid "minute" +msgstr "minuto" + +#: src/lib/util.cc:124 +msgid "minutes" +msgstr "minutos" + +#: src/lib/util.cc:642 +msgid "missing key %1 in key-value set" +msgstr "falta la clave %1 en el par clave-valor" + +#: src/lib/subtitle.cc:52 +msgid "multi-part subtitles not yet supported" +msgstr "todavía no se soportan subtítulos en múltiples partes" + +#: src/lib/film.cc:263 src/lib/film.cc:308 +msgid "name" +msgstr "nombre" + +#: src/lib/imagemagick_decoder.cc:60 +msgid "no still image files found" +msgstr "no se encuentran imágenes fijas" + +#: src/lib/subtitle.cc:58 +msgid "non-bitmap subtitles not yet supported" +msgstr "todavía no se soportan subtítulos que no son en mapas de bits" + +#. / TRANSLATORS: remaining here follows an amount of time that is remaining +#. / on an operation. +#: src/lib/job.cc:282 +msgid "remaining" +msgstr "pendiente" + +#: src/lib/util.cc:456 +msgid "sRGB" +msgstr "sRGB" + +#: src/lib/util.cc:127 +msgid "seconds" +msgstr "segundos" + +#: src/lib/film.cc:274 +msgid "still" +msgstr "imagen fija" + +#: src/lib/film.cc:274 +msgid "video" +msgstr "vídeo" diff --git a/src/tools/po/es_ES.po b/src/tools/po/es_ES.po index 78eecb306..9851fbda5 100644 --- a/src/tools/po/es_ES.po +++ b/src/tools/po/es_ES.po @@ -8,18 +8,18 @@ msgstr "" "Project-Id-Version: DVDOMATIC\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-03-15 08:39+0000\n" -"PO-Revision-Date: 2013-03-20 17:05-0500\n" +"PO-Revision-Date: 2013-03-23 21:08-0500\n" "Last-Translator: Manuel AC \n" "Language-Team: Manuel AC \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" -"Language: ES-ES\n" +"Language: es-ES\n" #: src/tools/dvdomatic.cc:177 msgid "&Analyse audio" -msgstr "&Analizar sonido" +msgstr "&Analizar audio" #: src/tools/dvdomatic.cc:183 msgid "&Edit" @@ -39,7 +39,7 @@ msgstr "&Tareas" #: src/tools/dvdomatic.cc:173 msgid "&Make DCP" -msgstr "&Hacer DCP" +msgstr "&Crear DCP" #: src/tools/dvdomatic.cc:161 msgid "&Open..." diff --git a/src/wx/po/es_ES.po b/src/wx/po/es_ES.po new file mode 100644 index 000000000..1aebfed7f --- /dev/null +++ b/src/wx/po/es_ES.po @@ -0,0 +1,466 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: libdvdomatic-wx\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-03-15 08:39+0000\n" +"PO-Revision-Date: 2013-03-23 21:20-0500\n" +"Last-Translator: Manuel AC \n" +"Language-Team: Manuel AC \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.5.5\n" +"Language: es-ES\n" + +#: src/wx/film_editor.cc:441 +msgid "%" +msgstr "%" + +#: src/wx/film_editor.cc:1230 +msgid "1 channel" +msgstr "1 canal" + +#: src/wx/film_editor.cc:185 +msgid "A/B" +msgstr "A/B" + +#: src/wx/config_dialog.cc:124 +msgid "Add" +msgstr "Añadir" + +#: src/wx/audio_dialog.cc:32 src/wx/film_editor.cc:78 +msgid "Audio" +msgstr "Audio" + +#: src/wx/film_editor.cc:382 +msgid "Audio Delay" +msgstr "Retardo del audio" + +#: src/wx/film_editor.cc:370 +msgid "Audio Gain" +msgstr "Ganancia del audio" + +#: src/wx/dci_metadata_dialog.cc:33 +msgid "Audio Language (e.g. EN)" +msgstr "Idioma del audio (ej. ES)" + +#: src/wx/job_wrapper.cc:38 +#, c-format +msgid "Bad setting for %s (%s)" +msgstr "Configuración erronea para %s (%s)" + +#: src/wx/film_editor.cc:297 +msgid "Bottom crop" +msgstr "Recortar abajo" + +#: src/wx/dir_picker_ctrl.cc:38 +msgid "Browse..." +msgstr "Explorar..." + +#: src/wx/gain_calculator_dialog.cc:36 +msgid "But I have to use fader" +msgstr "pero tengo que usar el fader a" + +#: src/wx/film_editor.cc:375 +msgid "Calculate..." +msgstr "Calcular..." + +#: src/wx/audio_dialog.cc:43 +msgid "Channels" +msgstr "Canales" + +#: src/wx/film_editor.cc:326 +msgid "Colour look-up table" +msgstr "Tabla de referencia de colores" + +#: src/wx/film_editor.cc:121 +msgid "Content" +msgstr "Contenido" + +#: src/wx/film_editor.cc:131 +msgid "Content Type" +msgstr "Tipo de contenido" + +#: src/wx/film_viewer.cc:414 +#, c-format +msgid "Could not decode video for view (%s)" +msgstr "No se pudo decodificar el vídeo para mostrarlo (%s)" + +#: src/wx/job_wrapper.cc:40 +#, c-format +msgid "Could not make DCP: %s" +msgstr "No se pudo crear el DCP: %s" + +#: src/wx/film_viewer.cc:108 +#, c-format +msgid "Could not open content file (%s)" +msgstr "No se pudo abrir el fichero (%s)" + +#: src/wx/film_editor.cc:505 +#, c-format +msgid "Could not set content: %s" +msgstr "No se pudo establecer el contenido: %s" + +#: src/wx/new_film_dialog.cc:46 +msgid "Create in folder" +msgstr "Crear en carpeta" + +#: src/wx/dci_metadata_dialog.cc:28 +msgid "DCI name" +msgstr "Nombre DCI" + +#: src/wx/film_editor.cc:142 +msgid "DCP Frame Rate" +msgstr "Velocidad DCP" + +#: src/wx/film_editor.cc:110 +msgid "DCP Name" +msgstr "Nombre DCP" + +#: src/wx/wx_util.cc:61 +msgid "DVD-o-matic" +msgstr "DVD-o-matic" + +#: src/wx/config_dialog.cc:44 +msgid "DVD-o-matic Preferences" +msgstr "Preferencias DVD-o-matic" + +#: src/wx/audio_dialog.cc:101 +msgid "DVD-o-matic audio - %1" +msgstr "Audio DVD-o-matic - %1" + +#: src/wx/config_dialog.cc:83 +msgid "Default DCI name details" +msgstr "Detalles por defecto del nombre DCI" + +#: src/wx/config_dialog.cc:74 +msgid "Default directory for new films" +msgstr "Carpeta por defecto para nuevas películas" + +#: src/wx/film_editor.cc:117 src/wx/job_manager_view.cc:88 +msgid "Details..." +msgstr "Detalles..." + +#: src/wx/properties_dialog.cc:45 +msgid "Disk space required" +msgstr "Espacio requerido en disco" + +#: src/wx/film_editor.cc:192 +msgid "Duration" +msgstr "Duración" + +#: src/wx/config_dialog.cc:126 +msgid "Edit" +msgstr "Editar" + +#: src/wx/config_dialog.cc:84 src/wx/config_dialog.cc:103 +#: src/wx/film_editor.cc:309 +msgid "Edit..." +msgstr "Editar..." + +#: src/wx/config_dialog.cc:109 +msgid "Encoding Servers" +msgstr "Servidores de codificación" + +#: src/wx/film_editor.cc:177 +msgid "End" +msgstr "Fin" + +#: src/wx/dci_metadata_dialog.cc:53 +msgid "Facility (e.g. DLA)" +msgstr "Compañía (ej. DLA)" + +#: src/wx/film_editor.cc:74 +msgid "Film" +msgstr "Película" + +#: src/wx/properties_dialog.cc:36 +msgid "Film Properties" +msgstr "Propiedades de la película" + +#: src/wx/new_film_dialog.cc:42 +msgid "Film name" +msgstr "Nombre de la película" + +#: src/wx/film_editor.cc:304 src/wx/filter_dialog.cc:32 +msgid "Filters" +msgstr "Filtros" + +#: src/wx/film_editor.cc:269 +msgid "Format" +msgstr "Formato" + +#: src/wx/properties_dialog.cc:41 +msgid "Frames" +msgstr "Fotogramas" + +#: src/wx/properties_dialog.cc:49 +msgid "Frames already encoded" +msgstr "Fotogramas ya codificados" + +#: src/wx/gain_calculator_dialog.cc:27 +msgid "Gain Calculator" +msgstr "Calculadora de ganancia" + +#: src/wx/properties_dialog.cc:59 +msgid "Gb" +msgstr "Gb" + +#: src/wx/server_dialog.cc:36 +msgid "Host name or IP address" +msgstr "Nombre o dirección IP" + +#: src/wx/film_editor.cc:1234 +msgid "Hz" +msgstr "Hz" + +#: src/wx/gain_calculator_dialog.cc:32 +msgid "I want to play this back at fader" +msgstr "Quiero reproducir con el fader a" + +#: src/wx/config_dialog.cc:113 +msgid "IP address" +msgstr "Dirección IP" + +#: src/wx/film_editor.cc:336 +msgid "JPEG2000 bandwidth" +msgstr "Ancho de banda JPEG2000" + +#: src/wx/film_editor.cc:282 +msgid "Left crop" +msgstr "Recorte izquierda" + +#: src/wx/film_editor.cc:165 +msgid "Length" +msgstr "Longitud" + +#: src/wx/film_editor.cc:340 +msgid "MBps" +msgstr "MBps" + +#: src/wx/dir_picker_ctrl.cc:52 +msgid "My Documents" +msgstr "Mis documentos" + +#: src/wx/film_editor.cc:105 +msgid "Name" +msgstr "Nombre" + +#: src/wx/new_film_dialog.cc:33 +msgid "New Film" +msgstr "Nueva película" + +#: src/wx/film_editor.cc:306 src/wx/film_editor.cc:665 +msgid "None" +msgstr "Ninguno" + +#: src/wx/film_editor.cc:136 +msgid "Original Frame Rate" +msgstr "Velocidad original" + +#: src/wx/film_editor.cc:160 +msgid "Original Size" +msgstr "Tamaño original" + +#: src/wx/dci_metadata_dialog.cc:57 +msgid "Package Type (e.g. OV)" +msgstr "Tipo de paquete (ej. OV)" + +#: src/wx/audio_dialog.cc:60 +msgid "Peak" +msgstr "Pico" + +#: src/wx/film_viewer.cc:54 +msgid "Play" +msgstr "Reproducir" + +#: src/wx/audio_plot.cc:109 +msgid "Please wait; audio is being analysed..." +msgstr "Por favor espere, el audio está siendo analizado..." + +#: src/wx/audio_dialog.cc:61 +msgid "RMS" +msgstr "RMS" + +#: src/wx/dci_metadata_dialog.cc:45 +msgid "Rating (e.g. 15)" +msgstr "Clasificación (ej. 16)" + +#: src/wx/config_dialog.cc:99 +msgid "Reference filters for A/B" +msgstr "Filtros de referencia para A/B" + +#: src/wx/config_dialog.cc:88 +msgid "Reference scaler for A/B" +msgstr "Escalador de referencia para A/B" + +#: src/wx/config_dialog.cc:128 +msgid "Remove" +msgstr "Quitar" + +#: src/wx/film_editor.cc:287 +msgid "Right crop" +msgstr "Recorte derecha" + +#: src/wx/job_manager_view.cc:104 +msgid "Running" +msgstr "Ejecutando" + +#: src/wx/film_editor.cc:316 +msgid "Scaler" +msgstr "Escalador" + +#: src/wx/film_editor.cc:408 +msgid "Select Audio File" +msgstr "Seleccionar fichero de audio" + +#: src/wx/film_editor.cc:122 +msgid "Select Content File" +msgstr "Seleccionar fichero de contenido" + +#: src/wx/server_dialog.cc:25 +msgid "Server" +msgstr "Servidor" + +#: src/wx/film_editor.cc:365 +msgid "Show Audio..." +msgstr "Mostrar audio..." + +#: src/wx/audio_dialog.cc:71 +msgid "Smoothing" +msgstr "Suavizado" + +#: src/wx/film_editor.cc:174 +msgid "Start" +msgstr "Inicio" + +#: src/wx/dci_metadata_dialog.cc:49 +msgid "Studio (e.g. TCF)" +msgstr "Estudio (ej. TCF)" + +#: src/wx/dci_metadata_dialog.cc:37 +msgid "Subtitle Language (e.g. FR)" +msgstr "Idioma del subtítulo (ej. EN)" + +#: src/wx/film_editor.cc:432 +msgid "Subtitle Offset" +msgstr "Desplazamiento del subtítulo" + +#: src/wx/film_editor.cc:437 +msgid "Subtitle Scale" +msgstr "Escala del subtítulo" + +#: src/wx/film_editor.cc:80 +msgid "Subtitles" +msgstr "Subtítulos" + +#: src/wx/config_dialog.cc:49 +msgid "TMS IP address" +msgstr "Dirección IP del TMS" + +#: src/wx/config_dialog.cc:64 +msgid "TMS password" +msgstr "Clave del TMS" + +#: src/wx/config_dialog.cc:54 +msgid "TMS target path" +msgstr "Ruta en el TMS" + +#: src/wx/config_dialog.cc:59 +msgid "TMS user name" +msgstr "Usuario del TMS" + +#: src/wx/dci_metadata_dialog.cc:41 +msgid "Territory (e.g. UK)" +msgstr "Territorio (ej. ES)" + +#: src/wx/config_dialog.cc:117 +msgid "Threads" +msgstr "Hilos" + +#: src/wx/server_dialog.cc:40 +msgid "Threads to use" +msgstr "Hilos a utilizar" + +#: src/wx/config_dialog.cc:69 +msgid "Threads to use for encoding on this host" +msgstr "Hilos a utilizar para la codificación en esta máquina" + +#: src/wx/audio_plot.cc:139 +msgid "Time" +msgstr "Tiempo" + +#: src/wx/film_editor.cc:292 +msgid "Top crop" +msgstr "Recortar arriba" + +#: src/wx/film_editor.cc:172 +msgid "Trim frames" +msgstr "Recortar fotogramas" + +#: src/wx/film_editor.cc:126 +msgid "Trust content's header" +msgstr "Confiar en la cabecera del contenido" + +#: src/wx/audio_dialog.cc:55 +msgid "Type" +msgstr "Tipo" + +#: src/wx/film_editor.cc:115 +msgid "Use DCI name" +msgstr "Usar el nombre DCI" + +#: src/wx/film_editor.cc:146 +msgid "Use best" +msgstr "Usar el mejor" + +#: src/wx/film_editor.cc:392 +msgid "Use content's audio" +msgstr "Usar el audio del contenido" + +#: src/wx/film_editor.cc:402 +msgid "Use external audio" +msgstr "Usar audio externo" + +#: src/wx/film_editor.cc:76 +msgid "Video" +msgstr "Vídeo" + +#: src/wx/film_editor.cc:425 +msgid "With Subtitles" +msgstr "Con subtítulos" + +#: src/wx/film_editor.cc:1232 +msgid "channels" +msgstr "canales" + +#: src/wx/properties_dialog.cc:50 +msgid "counting..." +msgstr "contando..." + +#: src/wx/film_editor.cc:374 +msgid "dB" +msgstr "dB" + +#: src/wx/film_editor.cc:691 src/wx/film_editor.cc:693 +msgid "frames" +msgstr "fotogramas" + +#. / TRANSLATORS: this is an abbreviation for milliseconds, the unit of time +#: src/wx/film_editor.cc:387 +msgid "ms" +msgstr "ms" + +#. / TRANSLATORS: `s' here is an abbreviation for seconds, the unit of time +#: src/wx/film_editor.cc:198 +msgid "s" +msgstr "s" + +#: src/wx/properties_dialog.cc:62 src/wx/properties_dialog.cc:63 +msgid "unknown" +msgstr "desconocido" -- cgit v1.2.3 From ea9e85f7f92d45d0ed3ae0e10c01eaa294ca3a38 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 26 Mar 2013 14:12:38 +0000 Subject: Merge updated pot files. --- src/lib/po/es_ES.po | 85 +++++++++++++++++---------- src/lib/po/fr_FR.po | 57 +++++++++--------- src/lib/po/it_IT.po | 57 +++++++++--------- src/tools/po/es_ES.po | 8 +-- src/tools/po/fr_FR.po | 6 +- src/tools/po/it_IT.po | 8 +-- src/wx/po/es_ES.po | 156 +++++++++++++++++++++++++++----------------------- src/wx/po/fr_FR.po | 58 +++++++++++-------- src/wx/po/it_IT.po | 156 +++++++++++++++++++++++++++----------------------- 9 files changed, 326 insertions(+), 265 deletions(-) (limited to 'src') diff --git a/src/lib/po/es_ES.po b/src/lib/po/es_ES.po index c84563355..18e53d3b7 100644 --- a/src/lib/po/es_ES.po +++ b/src/lib/po/es_ES.po @@ -7,15 +7,15 @@ msgid "" msgstr "" "Project-Id-Version: LIBDVDOMATIC\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-15 08:39+0000\n" +"POT-Creation-Date: 2013-03-26 14:11+0000\n" "PO-Revision-Date: 2013-03-23 22:42-0500\n" "Last-Translator: Manuel AC \n" "Language-Team: Manuel AC \n" +"Language: es-ES\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" -"Language: es-ES\n" #: src/lib/transcode_job.cc:87 msgid "0%" @@ -69,7 +69,7 @@ msgstr "Academy" msgid "Advertisement" msgstr "Publicidad" -#: src/lib/job.cc:71 +#: src/lib/job.cc:72 msgid "An error occurred whilst handling the file %1." msgstr "Ha ocurrido un error con el fichero %1." @@ -89,6 +89,14 @@ msgstr "Bicúbico" msgid "Bilinear" msgstr "Bilineal" +#: src/lib/job.cc:302 +msgid "Cancelled" +msgstr "" + +#: src/lib/exceptions.cc:60 +msgid "Cannot handle pixel format %1 during %2" +msgstr "" + #: src/lib/encoder.cc:101 msgid "Cannot resample audio as libswresample is not present" msgstr "" @@ -122,15 +130,15 @@ msgstr "No se pudo escribir el fichero remoto (%1)" msgid "Cubic interpolating deinterlacer" msgstr "Desentrelazado por interpolación cúbica" -#: src/lib/util.cc:965 +#: src/lib/util.cc:997 msgid "DCP and source have the same rate.\n" msgstr "La fuente y el DCP tienen la misma velocidad.\n" -#: src/lib/util.cc:975 +#: src/lib/util.cc:1007 msgid "DCP will run at %1%% of the source speed." msgstr "El DCP se reproducirá al %1%% de la velocidad de la fuente." -#: src/lib/util.cc:968 +#: src/lib/util.cc:1000 msgid "DCP will use every other frame of the source.\n" msgstr "El DCP usará fotogramas alternos de la fuente.\n" @@ -153,11 +161,11 @@ msgstr "" msgid "Dolby CP750" msgstr "Dolby CP750" -#: src/lib/util.cc:970 +#: src/lib/util.cc:1002 msgid "Each source frame will be doubled in the DCP.\n" msgstr "Se doblará cada fotograma de la fuente en el DCP.\n" -#: src/lib/job.cc:287 +#: src/lib/job.cc:300 msgid "Error (%1)" msgstr "Error (%1)" @@ -229,7 +237,7 @@ msgstr "" msgid "Horizontal deblocking filter A" msgstr "" -#: src/lib/job.cc:87 src/lib/job.cc:96 +#: src/lib/job.cc:92 src/lib/job.cc:101 msgid "" "It is not known what caused this error. The best idea is to report the " "problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" @@ -271,7 +279,7 @@ msgstr "" msgid "Noise reduction" msgstr "Reducción de ruido" -#: src/lib/job.cc:285 +#: src/lib/job.cc:298 msgid "OK (ran for %1)" msgstr "OK (ejecución %1)" @@ -291,7 +299,7 @@ msgstr "Anuncio de servicio público" msgid "Rating" msgstr "Clasificación" -#: src/lib/util.cc:458 +#: src/lib/util.cc:490 msgid "Rec 709" msgstr "Rec 709" @@ -387,7 +395,7 @@ msgstr "" msgid "Test" msgstr "Test" -#: src/lib/job.cc:76 +#: src/lib/job.cc:77 msgid "" "The drive that the film is stored on is low in disc space. Free some more " "space and try again." @@ -407,7 +415,7 @@ msgstr "Codificar %1" msgid "Transitional" msgstr "Transitional" -#: src/lib/job.cc:95 +#: src/lib/job.cc:100 msgid "Unknown error" msgstr "Error desconocido" @@ -439,15 +447,11 @@ msgstr "X" msgid "Yet Another Deinterlacing Filter" msgstr "" -#: src/lib/encoder.cc:271 -msgid "adding to queue of %1" -msgstr "añadiendo a la cola de %1" - #: src/lib/film.cc:263 msgid "cannot contain slashes" msgstr "no puede contener barras" -#: src/lib/util.cc:499 +#: src/lib/util.cc:531 msgid "connect timed out" msgstr "tiempo de conexión agotado" @@ -467,6 +471,11 @@ msgstr "tipo de contenido" msgid "copying %1" msgstr "copiando %1" +#: src/lib/exceptions.cc:36 +#, fuzzy +msgid "could not create file %1" +msgstr "No se pudo escribir el fichero remoto (%1)" + #: src/lib/ffmpeg_decoder.cc:191 msgid "could not find audio decoder" msgstr "no se encontró el decodificador de audio" @@ -483,14 +492,24 @@ msgstr "no se pudo encontrar decodificador de subtítutlos" msgid "could not find video decoder" msgstr "no se pudo encontrar decodificador de vídeo" -#: src/lib/external_audio_decoder.cc:72 +#: src/lib/sndfile_decoder.cc:72 msgid "could not open external audio file for reading" msgstr "no se pudo leer el fichero externo de audio" +#: src/lib/exceptions.cc:29 +#, fuzzy +msgid "could not open file %1" +msgstr "no se pudo abrir el fichero para lectura" + #: src/lib/dcp_video_frame.cc:388 msgid "could not open file for reading" msgstr "no se pudo abrir el fichero para lectura" +#: src/lib/exceptions.cc:44 +#, fuzzy +msgid "could not read from file %1 (%2)" +msgstr "No se pudo crear la carpeta remota %1 (%2)" + #: src/lib/encoder.cc:137 src/lib/encoder.cc:314 msgid "could not run sample-rate converter" msgstr "no se pudo ejecutar el conversor de velocidad" @@ -503,19 +522,16 @@ msgstr "no se pudo abrir la sesión SCP (%1)" msgid "could not start SSH session" msgstr "no se pudo abrir la sesión SSH" -#: src/lib/encoder.cc:247 -msgid "decoder sleeps with queue of %1" -msgstr "" - -#: src/lib/encoder.cc:249 -msgid "decoder wakes with queue of %1" -msgstr "" +#: src/lib/exceptions.cc:50 +#, fuzzy +msgid "could not write to file %1 (%2)" +msgstr "No se pudo escribir el fichero remoto (%1)" -#: src/lib/external_audio_decoder.cc:94 +#: src/lib/sndfile_decoder.cc:94 msgid "external audio files have differing lengths" msgstr "los ficheros externos de sonido tienen duraciones diferentes" -#: src/lib/external_audio_decoder.cc:76 +#: src/lib/sndfile_decoder.cc:76 msgid "external audio files must be mono" msgstr "los ficheros externos de sonido deben ser mono" @@ -543,10 +559,14 @@ msgstr "minuto" msgid "minutes" msgstr "minutos" -#: src/lib/util.cc:642 +#: src/lib/util.cc:674 msgid "missing key %1 in key-value set" msgstr "falta la clave %1 en el par clave-valor" +#: src/lib/exceptions.cc:54 +msgid "missing required setting %1" +msgstr "" + #: src/lib/subtitle.cc:52 msgid "multi-part subtitles not yet supported" msgstr "todavía no se soportan subtítulos en múltiples partes" @@ -565,11 +585,11 @@ msgstr "todavía no se soportan subtítulos que no son en mapas de bits" #. / TRANSLATORS: remaining here follows an amount of time that is remaining #. / on an operation. -#: src/lib/job.cc:282 +#: src/lib/job.cc:295 msgid "remaining" msgstr "pendiente" -#: src/lib/util.cc:456 +#: src/lib/util.cc:488 msgid "sRGB" msgstr "sRGB" @@ -584,3 +604,6 @@ msgstr "imagen fija" #: src/lib/film.cc:274 msgid "video" msgstr "vídeo" + +#~ msgid "adding to queue of %1" +#~ msgstr "añadiendo a la cola de %1" diff --git a/src/lib/po/fr_FR.po b/src/lib/po/fr_FR.po index 7832e4223..98080b61d 100644 --- a/src/lib/po/fr_FR.po +++ b/src/lib/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-20 13:37+0000\n" +"POT-Creation-Date: 2013-03-26 14:11+0000\n" "PO-Revision-Date: 2013-03-20 00:39+0100\n" "Last-Translator: FreeDCP.net \n" "Language-Team: \n" @@ -68,7 +68,7 @@ msgstr "Academy" msgid "Advertisement" msgstr "Advertisement" -#: src/lib/job.cc:71 +#: src/lib/job.cc:72 msgid "An error occurred whilst handling the file %1." msgstr "Une erreur s'est produite lors du traitement du fichier %1." @@ -88,6 +88,10 @@ msgstr "Bicubique" msgid "Bilinear" msgstr "Bilinéaire" +#: src/lib/job.cc:302 +msgid "Cancelled" +msgstr "" + #: src/lib/exceptions.cc:60 msgid "Cannot handle pixel format %1 during %2" msgstr "" @@ -124,15 +128,15 @@ msgstr "Écriture vers fichier distant (%1) impossible" msgid "Cubic interpolating deinterlacer" msgstr "Désentrelacement cubique interpolé" -#: src/lib/util.cc:965 +#: src/lib/util.cc:997 msgid "DCP and source have the same rate.\n" msgstr "Le DCP et la source ont les mêmes cadences.\n" -#: src/lib/util.cc:975 +#: src/lib/util.cc:1007 msgid "DCP will run at %1%% of the source speed." msgstr "La cadence du DCP sera %1%% par rapport à la source" -#: src/lib/util.cc:968 +#: src/lib/util.cc:1000 msgid "DCP will use every other frame of the source.\n" msgstr "Le DCP utilisera une image sur deux de la source.\n" @@ -155,11 +159,11 @@ msgstr "Filtre anti bourdonnement" msgid "Dolby CP750" msgstr "Dolby CP750" -#: src/lib/util.cc:970 +#: src/lib/util.cc:1002 msgid "Each source frame will be doubled in the DCP.\n" msgstr "Chaque image source sera dupliquée dans le DCP.\n" -#: src/lib/job.cc:287 +#: src/lib/job.cc:300 msgid "Error (%1)" msgstr "Erreur (%1)" @@ -231,7 +235,7 @@ msgstr "Filtre dé-bloc horizontal" msgid "Horizontal deblocking filter A" msgstr "Filtre dé-bloc horizontal" -#: src/lib/job.cc:87 src/lib/job.cc:96 +#: src/lib/job.cc:92 src/lib/job.cc:101 msgid "" "It is not known what caused this error. The best idea is to report the " "problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" @@ -273,7 +277,7 @@ msgstr "Désentrelaceur par compensation de mouvement" msgid "Noise reduction" msgstr "Réduction de bruit" -#: src/lib/job.cc:285 +#: src/lib/job.cc:298 msgid "OK (ran for %1)" msgstr "OK (processus %1)" @@ -293,7 +297,7 @@ msgstr "Public Service Announcement" msgid "Rating" msgstr "Rating" -#: src/lib/util.cc:458 +#: src/lib/util.cc:490 msgid "Rec 709" msgstr "Rec 709" @@ -389,7 +393,7 @@ msgstr "Réduction de bruit temporel" msgid "Test" msgstr "Test" -#: src/lib/job.cc:76 +#: src/lib/job.cc:77 msgid "" "The drive that the film is stored on is low in disc space. Free some more " "space and try again." @@ -409,7 +413,7 @@ msgstr "Transcodage %1" msgid "Transitional" msgstr "Transitional" -#: src/lib/job.cc:95 +#: src/lib/job.cc:100 msgid "Unknown error" msgstr "Erreur inconnue" @@ -441,15 +445,11 @@ msgstr "X" msgid "Yet Another Deinterlacing Filter" msgstr "Un autre filtre de désentrelacement" -#: src/lib/encoder.cc:271 -msgid "adding to queue of %1" -msgstr "Mise en file d'attente de %1" - #: src/lib/film.cc:263 msgid "cannot contain slashes" msgstr "slash interdit" -#: src/lib/util.cc:499 +#: src/lib/util.cc:531 msgid "connect timed out" msgstr "temps de connexion expiré" @@ -525,14 +525,6 @@ msgstr "démarrage de session SSH impossible" msgid "could not write to file %1 (%2)" msgstr "Écriture vers fichier distant (%1) impossible" -#: src/lib/encoder.cc:247 -msgid "decoder sleeps with queue of %1" -msgstr "décodeur en veille avec %1 en file d'attente" - -#: src/lib/encoder.cc:249 -msgid "decoder wakes with queue of %1" -msgstr "reprise du décodage avec %1 en file d'attente" - #: src/lib/sndfile_decoder.cc:94 msgid "external audio files have differing lengths" msgstr "Les fichiers audio externes ont des durées différentes" @@ -565,7 +557,7 @@ msgstr "minute" msgid "minutes" msgstr "minutes" -#: src/lib/util.cc:642 +#: src/lib/util.cc:674 msgid "missing key %1 in key-value set" msgstr "clé %1 non sélectionnée" @@ -591,11 +583,11 @@ msgstr "sous-titres non-bitmap non supportés actuellement" #. / TRANSLATORS: remaining here follows an amount of time that is remaining #. / on an operation. -#: src/lib/job.cc:282 +#: src/lib/job.cc:295 msgid "remaining" msgstr "restant" -#: src/lib/util.cc:456 +#: src/lib/util.cc:488 msgid "sRGB" msgstr "sRGB" @@ -610,3 +602,12 @@ msgstr "fixe" #: src/lib/film.cc:274 msgid "video" msgstr "vidéo" + +#~ msgid "adding to queue of %1" +#~ msgstr "Mise en file d'attente de %1" + +#~ msgid "decoder sleeps with queue of %1" +#~ msgstr "décodeur en veille avec %1 en file d'attente" + +#~ msgid "decoder wakes with queue of %1" +#~ msgstr "reprise du décodage avec %1 en file d'attente" diff --git a/src/lib/po/it_IT.po b/src/lib/po/it_IT.po index 9c7dc4851..24cd1c187 100644 --- a/src/lib/po/it_IT.po +++ b/src/lib/po/it_IT.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-20 13:37+0000\n" +"POT-Creation-Date: 2013-03-26 14:11+0000\n" "PO-Revision-Date: 2013-03-20 11:45+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" @@ -69,7 +69,7 @@ msgstr "Academy" msgid "Advertisement" msgstr "Pubblicità" -#: src/lib/job.cc:71 +#: src/lib/job.cc:72 msgid "An error occurred whilst handling the file %1." msgstr "Errore durante l'elaborazione del file %1." @@ -89,6 +89,10 @@ msgstr "Bicubica" msgid "Bilinear" msgstr "Bilineare" +#: src/lib/job.cc:302 +msgid "Cancelled" +msgstr "" + #: src/lib/exceptions.cc:60 msgid "Cannot handle pixel format %1 during %2" msgstr "" @@ -125,15 +129,15 @@ msgstr "Non posso scrivere il file remoto (%1)" msgid "Cubic interpolating deinterlacer" msgstr "Deinterlacciatore cubico interpolato" -#: src/lib/util.cc:965 +#: src/lib/util.cc:997 msgid "DCP and source have the same rate.\n" msgstr "Il DCP e il sorgente hanno la stessa frequenza.\n" -#: src/lib/util.cc:975 +#: src/lib/util.cc:1007 msgid "DCP will run at %1%% of the source speed." msgstr "Il DCP andrà al %1%% della velocità del sorgente." -#: src/lib/util.cc:968 +#: src/lib/util.cc:1000 msgid "DCP will use every other frame of the source.\n" msgstr "Il DCP userà ogni altro fotogramma del sorgente.\n" @@ -156,11 +160,11 @@ msgstr "Filtro deringing" msgid "Dolby CP750" msgstr "Dolby CP750" -#: src/lib/util.cc:970 +#: src/lib/util.cc:1002 msgid "Each source frame will be doubled in the DCP.\n" msgstr "Ogni fotogramma del sorgente sarà raddoppiato nel DCP.\n" -#: src/lib/job.cc:287 +#: src/lib/job.cc:300 msgid "Error (%1)" msgstr "Errore (%1)" @@ -232,7 +236,7 @@ msgstr "Filtro sblocco orizzontale" msgid "Horizontal deblocking filter A" msgstr "Filtro A sblocco orizzontale" -#: src/lib/job.cc:87 src/lib/job.cc:96 +#: src/lib/job.cc:92 src/lib/job.cc:101 msgid "" "It is not known what caused this error. The best idea is to report the " "problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" @@ -274,7 +278,7 @@ msgstr "Dinterlacciatore compensativo di movimento" msgid "Noise reduction" msgstr "Riduzione del rumore" -#: src/lib/job.cc:285 +#: src/lib/job.cc:298 msgid "OK (ran for %1)" msgstr "OK (procede al %1)" @@ -294,7 +298,7 @@ msgstr "Annuncio di pubblico servizio" msgid "Rating" msgstr "Punteggio" -#: src/lib/util.cc:458 +#: src/lib/util.cc:490 msgid "Rec 709" msgstr "Rec 709" @@ -390,7 +394,7 @@ msgstr "Riduttore temporale di rumore" msgid "Test" msgstr "Prova" -#: src/lib/job.cc:76 +#: src/lib/job.cc:77 msgid "" "The drive that the film is stored on is low in disc space. Free some more " "space and try again." @@ -410,7 +414,7 @@ msgstr "Transcodifica %1" msgid "Transitional" msgstr "Di transizione" -#: src/lib/job.cc:95 +#: src/lib/job.cc:100 msgid "Unknown error" msgstr "Errore sconosciuto" @@ -442,15 +446,11 @@ msgstr "X" msgid "Yet Another Deinterlacing Filter" msgstr "Ancora un altro filtro di deinterlacciamento" -#: src/lib/encoder.cc:271 -msgid "adding to queue of %1" -msgstr "aggiungo alla coda %1" - #: src/lib/film.cc:263 msgid "cannot contain slashes" msgstr "non può contenere barre" -#: src/lib/util.cc:499 +#: src/lib/util.cc:531 msgid "connect timed out" msgstr "connessione scaduta" @@ -526,14 +526,6 @@ msgstr "non posso avviare la sessione SSH" msgid "could not write to file %1 (%2)" msgstr "Non posso scrivere il file remoto (%1)" -#: src/lib/encoder.cc:247 -msgid "decoder sleeps with queue of %1" -msgstr "il decoder è in pausa con la coda di %1" - -#: src/lib/encoder.cc:249 -msgid "decoder wakes with queue of %1" -msgstr "il decoder riparte con la coda di %1" - #: src/lib/sndfile_decoder.cc:94 msgid "external audio files have differing lengths" msgstr "i files dell'audio esterno hanno durata diversa" @@ -566,7 +558,7 @@ msgstr "minuto" msgid "minutes" msgstr "minuti" -#: src/lib/util.cc:642 +#: src/lib/util.cc:674 msgid "missing key %1 in key-value set" msgstr "persa la chiave %1 tra i valori chiave" @@ -592,11 +584,11 @@ msgstr "sottotitoli non-bitmap non ancora supportati" #. / TRANSLATORS: remaining here follows an amount of time that is remaining #. / on an operation. -#: src/lib/job.cc:282 +#: src/lib/job.cc:295 msgid "remaining" msgstr "restano" -#: src/lib/util.cc:456 +#: src/lib/util.cc:488 msgid "sRGB" msgstr "sRGB" @@ -611,3 +603,12 @@ msgstr "ancora" #: src/lib/film.cc:274 msgid "video" msgstr "video" + +#~ msgid "adding to queue of %1" +#~ msgstr "aggiungo alla coda %1" + +#~ msgid "decoder sleeps with queue of %1" +#~ msgstr "il decoder è in pausa con la coda di %1" + +#~ msgid "decoder wakes with queue of %1" +#~ msgstr "il decoder riparte con la coda di %1" diff --git a/src/tools/po/es_ES.po b/src/tools/po/es_ES.po index 9851fbda5..c114c7ae9 100644 --- a/src/tools/po/es_ES.po +++ b/src/tools/po/es_ES.po @@ -7,15 +7,15 @@ msgid "" msgstr "" "Project-Id-Version: DVDOMATIC\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-15 08:39+0000\n" +"POT-Creation-Date: 2013-03-26 14:11+0000\n" "PO-Revision-Date: 2013-03-23 21:08-0500\n" "Last-Translator: Manuel AC \n" "Language-Team: Manuel AC \n" +"Language: es-ES\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" -"Language: es-ES\n" #: src/tools/dvdomatic.cc:177 msgid "&Analyse audio" @@ -75,7 +75,7 @@ msgstr "" msgid "About" msgstr "Acerca de" -#: src/tools/dvdomatic.cc:497 +#: src/tools/dvdomatic.cc:516 msgid "Could not load film %1 (%2)" msgstr "No se pudo cargar la película %1 (%2)" @@ -85,7 +85,7 @@ msgid "Could not open film at %s (%s)" msgstr "No se pudo cargar la película en %s (%s)" #: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:402 -#: src/tools/dvdomatic.cc:501 +#: src/tools/dvdomatic.cc:520 msgid "DVD-o-matic" msgstr "DVD-o-matic" diff --git a/src/tools/po/fr_FR.po b/src/tools/po/fr_FR.po index 4f84fee77..39001297b 100644 --- a/src/tools/po/fr_FR.po +++ b/src/tools/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-20 13:37+0000\n" +"POT-Creation-Date: 2013-03-26 14:11+0000\n" "PO-Revision-Date: 2013-03-13 22:33+0100\n" "Last-Translator: \n" "Language-Team: \n" @@ -74,7 +74,7 @@ msgstr "" msgid "About" msgstr "A Propos" -#: src/tools/dvdomatic.cc:500 +#: src/tools/dvdomatic.cc:516 msgid "Could not load film %1 (%2)" msgstr "Impossible de charger le film %1 (%2)" @@ -84,7 +84,7 @@ msgid "Could not open film at %s (%s)" msgstr "Impossible d'ouvrir le film à %s (%s)" #: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:402 -#: src/tools/dvdomatic.cc:504 +#: src/tools/dvdomatic.cc:520 msgid "DVD-o-matic" msgstr "DVD-o-matic" diff --git a/src/tools/po/it_IT.po b/src/tools/po/it_IT.po index 23574ee41..33f412b78 100644 --- a/src/tools/po/it_IT.po +++ b/src/tools/po/it_IT.po @@ -7,15 +7,15 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-15 08:39+0000\n" +"POT-Creation-Date: 2013-03-26 14:11+0000\n" "PO-Revision-Date: 2013-03-22 18:03+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" +"Language: Italiano\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" -"Language: Italiano\n" #: src/tools/dvdomatic.cc:177 msgid "&Analyse audio" @@ -75,7 +75,7 @@ msgstr "" msgid "About" msgstr "Informazioni" -#: src/tools/dvdomatic.cc:497 +#: src/tools/dvdomatic.cc:516 msgid "Could not load film %1 (%2)" msgstr "Non posso caricare il film %1 (%2)" @@ -85,7 +85,7 @@ msgid "Could not open film at %s (%s)" msgstr "Non posso aprire il film in %s (%s)" #: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:402 -#: src/tools/dvdomatic.cc:501 +#: src/tools/dvdomatic.cc:520 msgid "DVD-o-matic" msgstr "DVD-o-matic" diff --git a/src/wx/po/es_ES.po b/src/wx/po/es_ES.po index 1aebfed7f..3aeda7d73 100644 --- a/src/wx/po/es_ES.po +++ b/src/wx/po/es_ES.po @@ -7,41 +7,45 @@ msgid "" msgstr "" "Project-Id-Version: libdvdomatic-wx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-15 08:39+0000\n" +"POT-Creation-Date: 2013-03-26 14:11+0000\n" "PO-Revision-Date: 2013-03-23 21:20-0500\n" "Last-Translator: Manuel AC \n" "Language-Team: Manuel AC \n" +"Language: es-ES\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" -"Language: es-ES\n" -#: src/wx/film_editor.cc:441 +#: src/wx/film_editor.cc:440 msgid "%" msgstr "%" -#: src/wx/film_editor.cc:1230 +#: src/wx/config_dialog.cc:60 +msgid "(restart DVD-o-matic to see language changes)" +msgstr "" + +#: src/wx/film_editor.cc:1231 msgid "1 channel" msgstr "1 canal" -#: src/wx/film_editor.cc:185 +#: src/wx/film_editor.cc:184 msgid "A/B" msgstr "A/B" -#: src/wx/config_dialog.cc:124 +#: src/wx/config_dialog.cc:142 msgid "Add" msgstr "Añadir" -#: src/wx/audio_dialog.cc:32 src/wx/film_editor.cc:78 +#: src/wx/audio_dialog.cc:32 src/wx/film_editor.cc:77 msgid "Audio" msgstr "Audio" -#: src/wx/film_editor.cc:382 +#: src/wx/film_editor.cc:381 msgid "Audio Delay" msgstr "Retardo del audio" -#: src/wx/film_editor.cc:370 +#: src/wx/film_editor.cc:369 msgid "Audio Gain" msgstr "Ganancia del audio" @@ -54,7 +58,7 @@ msgstr "Idioma del audio (ej. ES)" msgid "Bad setting for %s (%s)" msgstr "Configuración erronea para %s (%s)" -#: src/wx/film_editor.cc:297 +#: src/wx/film_editor.cc:296 msgid "Bottom crop" msgstr "Recortar abajo" @@ -66,23 +70,27 @@ msgstr "Explorar..." msgid "But I have to use fader" msgstr "pero tengo que usar el fader a" -#: src/wx/film_editor.cc:375 +#: src/wx/film_editor.cc:374 msgid "Calculate..." msgstr "Calcular..." +#: src/wx/job_manager_view.cc:88 +msgid "Cancel" +msgstr "" + #: src/wx/audio_dialog.cc:43 msgid "Channels" msgstr "Canales" -#: src/wx/film_editor.cc:326 +#: src/wx/film_editor.cc:325 msgid "Colour look-up table" msgstr "Tabla de referencia de colores" -#: src/wx/film_editor.cc:121 +#: src/wx/film_editor.cc:120 msgid "Content" msgstr "Contenido" -#: src/wx/film_editor.cc:131 +#: src/wx/film_editor.cc:130 msgid "Content Type" msgstr "Tipo de contenido" @@ -101,7 +109,7 @@ msgstr "No se pudo crear el DCP: %s" msgid "Could not open content file (%s)" msgstr "No se pudo abrir el fichero (%s)" -#: src/wx/film_editor.cc:505 +#: src/wx/film_editor.cc:504 #, c-format msgid "Could not set content: %s" msgstr "No se pudo establecer el contenido: %s" @@ -114,11 +122,11 @@ msgstr "Crear en carpeta" msgid "DCI name" msgstr "Nombre DCI" -#: src/wx/film_editor.cc:142 +#: src/wx/film_editor.cc:141 msgid "DCP Frame Rate" msgstr "Velocidad DCP" -#: src/wx/film_editor.cc:110 +#: src/wx/film_editor.cc:109 msgid "DCP Name" msgstr "Nombre DCP" @@ -134,15 +142,15 @@ msgstr "Preferencias DVD-o-matic" msgid "DVD-o-matic audio - %1" msgstr "Audio DVD-o-matic - %1" -#: src/wx/config_dialog.cc:83 +#: src/wx/config_dialog.cc:101 msgid "Default DCI name details" msgstr "Detalles por defecto del nombre DCI" -#: src/wx/config_dialog.cc:74 +#: src/wx/config_dialog.cc:92 msgid "Default directory for new films" msgstr "Carpeta por defecto para nuevas películas" -#: src/wx/film_editor.cc:117 src/wx/job_manager_view.cc:88 +#: src/wx/film_editor.cc:116 src/wx/job_manager_view.cc:92 msgid "Details..." msgstr "Detalles..." @@ -150,24 +158,24 @@ msgstr "Detalles..." msgid "Disk space required" msgstr "Espacio requerido en disco" -#: src/wx/film_editor.cc:192 +#: src/wx/film_editor.cc:191 msgid "Duration" msgstr "Duración" -#: src/wx/config_dialog.cc:126 +#: src/wx/config_dialog.cc:144 msgid "Edit" msgstr "Editar" -#: src/wx/config_dialog.cc:84 src/wx/config_dialog.cc:103 -#: src/wx/film_editor.cc:309 +#: src/wx/config_dialog.cc:102 src/wx/config_dialog.cc:121 +#: src/wx/film_editor.cc:308 msgid "Edit..." msgstr "Editar..." -#: src/wx/config_dialog.cc:109 +#: src/wx/config_dialog.cc:127 msgid "Encoding Servers" msgstr "Servidores de codificación" -#: src/wx/film_editor.cc:177 +#: src/wx/film_editor.cc:176 msgid "End" msgstr "Fin" @@ -175,7 +183,7 @@ msgstr "Fin" msgid "Facility (e.g. DLA)" msgstr "Compañía (ej. DLA)" -#: src/wx/film_editor.cc:74 +#: src/wx/film_editor.cc:73 msgid "Film" msgstr "Película" @@ -187,11 +195,11 @@ msgstr "Propiedades de la película" msgid "Film name" msgstr "Nombre de la película" -#: src/wx/film_editor.cc:304 src/wx/filter_dialog.cc:32 +#: src/wx/film_editor.cc:303 src/wx/filter_dialog.cc:32 msgid "Filters" msgstr "Filtros" -#: src/wx/film_editor.cc:269 +#: src/wx/film_editor.cc:268 msgid "Format" msgstr "Formato" @@ -215,7 +223,7 @@ msgstr "Gb" msgid "Host name or IP address" msgstr "Nombre o dirección IP" -#: src/wx/film_editor.cc:1234 +#: src/wx/film_editor.cc:1235 msgid "Hz" msgstr "Hz" @@ -223,23 +231,23 @@ msgstr "Hz" msgid "I want to play this back at fader" msgstr "Quiero reproducir con el fader a" -#: src/wx/config_dialog.cc:113 +#: src/wx/config_dialog.cc:131 msgid "IP address" msgstr "Dirección IP" -#: src/wx/film_editor.cc:336 +#: src/wx/film_editor.cc:335 msgid "JPEG2000 bandwidth" msgstr "Ancho de banda JPEG2000" -#: src/wx/film_editor.cc:282 +#: src/wx/film_editor.cc:281 msgid "Left crop" msgstr "Recorte izquierda" -#: src/wx/film_editor.cc:165 +#: src/wx/film_editor.cc:164 msgid "Length" msgstr "Longitud" -#: src/wx/film_editor.cc:340 +#: src/wx/film_editor.cc:339 msgid "MBps" msgstr "MBps" @@ -247,7 +255,7 @@ msgstr "MBps" msgid "My Documents" msgstr "Mis documentos" -#: src/wx/film_editor.cc:105 +#: src/wx/film_editor.cc:104 msgid "Name" msgstr "Nombre" @@ -255,15 +263,15 @@ msgstr "Nombre" msgid "New Film" msgstr "Nueva película" -#: src/wx/film_editor.cc:306 src/wx/film_editor.cc:665 +#: src/wx/film_editor.cc:305 src/wx/film_editor.cc:664 msgid "None" msgstr "Ninguno" -#: src/wx/film_editor.cc:136 +#: src/wx/film_editor.cc:135 msgid "Original Frame Rate" msgstr "Velocidad original" -#: src/wx/film_editor.cc:160 +#: src/wx/film_editor.cc:159 msgid "Original Size" msgstr "Tamaño original" @@ -291,35 +299,35 @@ msgstr "RMS" msgid "Rating (e.g. 15)" msgstr "Clasificación (ej. 16)" -#: src/wx/config_dialog.cc:99 +#: src/wx/config_dialog.cc:117 msgid "Reference filters for A/B" msgstr "Filtros de referencia para A/B" -#: src/wx/config_dialog.cc:88 +#: src/wx/config_dialog.cc:106 msgid "Reference scaler for A/B" msgstr "Escalador de referencia para A/B" -#: src/wx/config_dialog.cc:128 +#: src/wx/config_dialog.cc:146 msgid "Remove" msgstr "Quitar" -#: src/wx/film_editor.cc:287 +#: src/wx/film_editor.cc:286 msgid "Right crop" msgstr "Recorte derecha" -#: src/wx/job_manager_view.cc:104 +#: src/wx/job_manager_view.cc:108 msgid "Running" msgstr "Ejecutando" -#: src/wx/film_editor.cc:316 +#: src/wx/film_editor.cc:315 msgid "Scaler" msgstr "Escalador" -#: src/wx/film_editor.cc:408 +#: src/wx/film_editor.cc:407 msgid "Select Audio File" msgstr "Seleccionar fichero de audio" -#: src/wx/film_editor.cc:122 +#: src/wx/film_editor.cc:121 msgid "Select Content File" msgstr "Seleccionar fichero de contenido" @@ -327,7 +335,11 @@ msgstr "Seleccionar fichero de contenido" msgid "Server" msgstr "Servidor" -#: src/wx/film_editor.cc:365 +#: src/wx/config_dialog.cc:49 +msgid "Set language" +msgstr "" + +#: src/wx/film_editor.cc:364 msgid "Show Audio..." msgstr "Mostrar audio..." @@ -335,7 +347,7 @@ msgstr "Mostrar audio..." msgid "Smoothing" msgstr "Suavizado" -#: src/wx/film_editor.cc:174 +#: src/wx/film_editor.cc:173 msgid "Start" msgstr "Inicio" @@ -347,31 +359,31 @@ msgstr "Estudio (ej. TCF)" msgid "Subtitle Language (e.g. FR)" msgstr "Idioma del subtítulo (ej. EN)" -#: src/wx/film_editor.cc:432 +#: src/wx/film_editor.cc:431 msgid "Subtitle Offset" msgstr "Desplazamiento del subtítulo" -#: src/wx/film_editor.cc:437 +#: src/wx/film_editor.cc:436 msgid "Subtitle Scale" msgstr "Escala del subtítulo" -#: src/wx/film_editor.cc:80 +#: src/wx/film_editor.cc:79 msgid "Subtitles" msgstr "Subtítulos" -#: src/wx/config_dialog.cc:49 +#: src/wx/config_dialog.cc:67 msgid "TMS IP address" msgstr "Dirección IP del TMS" -#: src/wx/config_dialog.cc:64 +#: src/wx/config_dialog.cc:82 msgid "TMS password" msgstr "Clave del TMS" -#: src/wx/config_dialog.cc:54 +#: src/wx/config_dialog.cc:72 msgid "TMS target path" msgstr "Ruta en el TMS" -#: src/wx/config_dialog.cc:59 +#: src/wx/config_dialog.cc:77 msgid "TMS user name" msgstr "Usuario del TMS" @@ -379,7 +391,7 @@ msgstr "Usuario del TMS" msgid "Territory (e.g. UK)" msgstr "Territorio (ej. ES)" -#: src/wx/config_dialog.cc:117 +#: src/wx/config_dialog.cc:135 msgid "Threads" msgstr "Hilos" @@ -387,7 +399,7 @@ msgstr "Hilos" msgid "Threads to use" msgstr "Hilos a utilizar" -#: src/wx/config_dialog.cc:69 +#: src/wx/config_dialog.cc:87 msgid "Threads to use for encoding on this host" msgstr "Hilos a utilizar para la codificación en esta máquina" @@ -395,15 +407,15 @@ msgstr "Hilos a utilizar para la codificación en esta máquina" msgid "Time" msgstr "Tiempo" -#: src/wx/film_editor.cc:292 +#: src/wx/film_editor.cc:291 msgid "Top crop" msgstr "Recortar arriba" -#: src/wx/film_editor.cc:172 +#: src/wx/film_editor.cc:171 msgid "Trim frames" msgstr "Recortar fotogramas" -#: src/wx/film_editor.cc:126 +#: src/wx/film_editor.cc:125 msgid "Trust content's header" msgstr "Confiar en la cabecera del contenido" @@ -411,31 +423,31 @@ msgstr "Confiar en la cabecera del contenido" msgid "Type" msgstr "Tipo" -#: src/wx/film_editor.cc:115 +#: src/wx/film_editor.cc:114 msgid "Use DCI name" msgstr "Usar el nombre DCI" -#: src/wx/film_editor.cc:146 +#: src/wx/film_editor.cc:145 msgid "Use best" msgstr "Usar el mejor" -#: src/wx/film_editor.cc:392 +#: src/wx/film_editor.cc:391 msgid "Use content's audio" msgstr "Usar el audio del contenido" -#: src/wx/film_editor.cc:402 +#: src/wx/film_editor.cc:401 msgid "Use external audio" msgstr "Usar audio externo" -#: src/wx/film_editor.cc:76 +#: src/wx/film_editor.cc:75 msgid "Video" msgstr "Vídeo" -#: src/wx/film_editor.cc:425 +#: src/wx/film_editor.cc:424 msgid "With Subtitles" msgstr "Con subtítulos" -#: src/wx/film_editor.cc:1232 +#: src/wx/film_editor.cc:1233 msgid "channels" msgstr "canales" @@ -443,21 +455,21 @@ msgstr "canales" msgid "counting..." msgstr "contando..." -#: src/wx/film_editor.cc:374 +#: src/wx/film_editor.cc:373 msgid "dB" msgstr "dB" -#: src/wx/film_editor.cc:691 src/wx/film_editor.cc:693 +#: src/wx/film_editor.cc:691 src/wx/film_editor.cc:694 msgid "frames" msgstr "fotogramas" #. / TRANSLATORS: this is an abbreviation for milliseconds, the unit of time -#: src/wx/film_editor.cc:387 +#: src/wx/film_editor.cc:386 msgid "ms" msgstr "ms" #. / TRANSLATORS: `s' here is an abbreviation for seconds, the unit of time -#: src/wx/film_editor.cc:198 +#: src/wx/film_editor.cc:197 msgid "s" msgstr "s" diff --git a/src/wx/po/fr_FR.po b/src/wx/po/fr_FR.po index 669283aa6..8ab03d1cb 100644 --- a/src/wx/po/fr_FR.po +++ b/src/wx/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-20 13:37+0000\n" +"POT-Creation-Date: 2013-03-26 14:11+0000\n" "PO-Revision-Date: 2013-03-20 00:34+0100\n" "Last-Translator: FreeDCP.net \n" "Language-Team: \n" @@ -20,7 +20,11 @@ msgstr "" msgid "%" msgstr "%" -#: src/wx/film_editor.cc:1229 +#: src/wx/config_dialog.cc:60 +msgid "(restart DVD-o-matic to see language changes)" +msgstr "" + +#: src/wx/film_editor.cc:1231 msgid "1 channel" msgstr "1 canal" @@ -28,7 +32,7 @@ msgstr "1 canal" msgid "A/B" msgstr "A/B" -#: src/wx/config_dialog.cc:124 +#: src/wx/config_dialog.cc:142 msgid "Add" msgstr "Ajouter" @@ -69,6 +73,10 @@ msgstr "Je souhaite utiliser ce volume" msgid "Calculate..." msgstr "Calcul..." +#: src/wx/job_manager_view.cc:88 +msgid "Cancel" +msgstr "" + #: src/wx/audio_dialog.cc:43 msgid "Channels" msgstr "Canaux" @@ -133,15 +141,15 @@ msgstr "Préférences DVD-o-matic" msgid "DVD-o-matic audio - %1" msgstr "Son DVD-o-matic - %1" -#: src/wx/config_dialog.cc:83 +#: src/wx/config_dialog.cc:101 msgid "Default DCI name details" msgstr "Détails du nom DCI par défaut" -#: src/wx/config_dialog.cc:74 +#: src/wx/config_dialog.cc:92 msgid "Default directory for new films" msgstr "Dossier par défaut des nouveaux films" -#: src/wx/film_editor.cc:116 src/wx/job_manager_view.cc:88 +#: src/wx/film_editor.cc:116 src/wx/job_manager_view.cc:92 msgid "Details..." msgstr "Détails..." @@ -153,16 +161,16 @@ msgstr "Espace disque requis" msgid "Duration" msgstr "Durée" -#: src/wx/config_dialog.cc:126 +#: src/wx/config_dialog.cc:144 msgid "Edit" msgstr "Édition" -#: src/wx/config_dialog.cc:84 src/wx/config_dialog.cc:103 +#: src/wx/config_dialog.cc:102 src/wx/config_dialog.cc:121 #: src/wx/film_editor.cc:308 msgid "Edit..." msgstr "Éditer..." -#: src/wx/config_dialog.cc:109 +#: src/wx/config_dialog.cc:127 msgid "Encoding Servers" msgstr "Serveurs d'encodage" @@ -214,7 +222,7 @@ msgstr "Gb" msgid "Host name or IP address" msgstr "Nom de l'hôte ou adresse IP" -#: src/wx/film_editor.cc:1233 +#: src/wx/film_editor.cc:1235 msgid "Hz" msgstr "Hz" @@ -222,7 +230,7 @@ msgstr "Hz" msgid "I want to play this back at fader" msgstr "Je veux le jouer à ce volume" -#: src/wx/config_dialog.cc:113 +#: src/wx/config_dialog.cc:131 msgid "IP address" msgstr "Adresse IP" @@ -290,15 +298,15 @@ msgstr "RMS" msgid "Rating (e.g. 15)" msgstr "Rating (ex. 15)" -#: src/wx/config_dialog.cc:99 +#: src/wx/config_dialog.cc:117 msgid "Reference filters for A/B" msgstr "Filtres de référence pour A/B" -#: src/wx/config_dialog.cc:88 +#: src/wx/config_dialog.cc:106 msgid "Reference scaler for A/B" msgstr "Échelle de référence pour A/B" -#: src/wx/config_dialog.cc:128 +#: src/wx/config_dialog.cc:146 msgid "Remove" msgstr "Supprimer" @@ -306,7 +314,7 @@ msgstr "Supprimer" msgid "Right crop" msgstr "Découpe droite" -#: src/wx/job_manager_view.cc:104 +#: src/wx/job_manager_view.cc:108 msgid "Running" msgstr "Progression" @@ -326,6 +334,10 @@ msgstr "Sélectionner le fichier vidéo" msgid "Server" msgstr "Serveur" +#: src/wx/config_dialog.cc:49 +msgid "Set language" +msgstr "" + #: src/wx/film_editor.cc:364 msgid "Show Audio..." msgstr "Analyser le son..." @@ -358,19 +370,19 @@ msgstr "Taille du sous-titre" msgid "Subtitles" msgstr "Sous-titres" -#: src/wx/config_dialog.cc:49 +#: src/wx/config_dialog.cc:67 msgid "TMS IP address" msgstr "Adresse IP du TMS" -#: src/wx/config_dialog.cc:64 +#: src/wx/config_dialog.cc:82 msgid "TMS password" msgstr "Mot de passe du TMS" -#: src/wx/config_dialog.cc:54 +#: src/wx/config_dialog.cc:72 msgid "TMS target path" msgstr "Chemin d'accès du TMS" -#: src/wx/config_dialog.cc:59 +#: src/wx/config_dialog.cc:77 msgid "TMS user name" msgstr "Nom d'utilisateur du TMS" @@ -378,7 +390,7 @@ msgstr "Nom d'utilisateur du TMS" msgid "Territory (e.g. UK)" msgstr "Territoire (ex. FR)" -#: src/wx/config_dialog.cc:117 +#: src/wx/config_dialog.cc:135 msgid "Threads" msgstr "Processus" @@ -386,7 +398,7 @@ msgstr "Processus" msgid "Threads to use" msgstr "Nombre de processus à utiliser" -#: src/wx/config_dialog.cc:69 +#: src/wx/config_dialog.cc:87 msgid "Threads to use for encoding on this host" msgstr "Nombre de processus à utiliser sur cet hôte" @@ -434,7 +446,7 @@ msgstr "Vidéo" msgid "With Subtitles" msgstr "Avec sous-titres" -#: src/wx/film_editor.cc:1231 +#: src/wx/film_editor.cc:1233 msgid "channels" msgstr "canaux" @@ -446,7 +458,7 @@ msgstr "calcul..." msgid "dB" msgstr "dB" -#: src/wx/film_editor.cc:690 src/wx/film_editor.cc:692 +#: src/wx/film_editor.cc:691 src/wx/film_editor.cc:694 msgid "frames" msgstr "images" diff --git a/src/wx/po/it_IT.po b/src/wx/po/it_IT.po index 5f6b62fb2..c6316e9b9 100644 --- a/src/wx/po/it_IT.po +++ b/src/wx/po/it_IT.po @@ -7,41 +7,45 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-15 08:39+0000\n" +"POT-Creation-Date: 2013-03-26 14:11+0000\n" "PO-Revision-Date: 2013-03-22 18:10+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" +"Language: Italiano\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" -"Language: Italiano\n" -#: src/wx/film_editor.cc:441 +#: src/wx/film_editor.cc:440 msgid "%" msgstr "%" -#: src/wx/film_editor.cc:1230 +#: src/wx/config_dialog.cc:60 +msgid "(restart DVD-o-matic to see language changes)" +msgstr "" + +#: src/wx/film_editor.cc:1231 msgid "1 channel" msgstr "Canale 1" -#: src/wx/film_editor.cc:185 +#: src/wx/film_editor.cc:184 msgid "A/B" msgstr "A/B" -#: src/wx/config_dialog.cc:124 +#: src/wx/config_dialog.cc:142 msgid "Add" msgstr "Aggiungi" -#: src/wx/audio_dialog.cc:32 src/wx/film_editor.cc:78 +#: src/wx/audio_dialog.cc:32 src/wx/film_editor.cc:77 msgid "Audio" msgstr "Audio" -#: src/wx/film_editor.cc:382 +#: src/wx/film_editor.cc:381 msgid "Audio Delay" msgstr "Ritardo dell'audio" -#: src/wx/film_editor.cc:370 +#: src/wx/film_editor.cc:369 msgid "Audio Gain" msgstr "Guadagno dell'audio" @@ -54,7 +58,7 @@ msgstr "Lingua dell'audio (es. EN)" msgid "Bad setting for %s (%s)" msgstr "Valore sbagliato per %s (%s)" -#: src/wx/film_editor.cc:297 +#: src/wx/film_editor.cc:296 msgid "Bottom crop" msgstr "Taglio in basso" @@ -66,23 +70,27 @@ msgstr "Sfoglia..." msgid "But I have to use fader" msgstr "Ma dovrò riprodurre con il fader a" -#: src/wx/film_editor.cc:375 +#: src/wx/film_editor.cc:374 msgid "Calculate..." msgstr "Calcola..." +#: src/wx/job_manager_view.cc:88 +msgid "Cancel" +msgstr "" + #: src/wx/audio_dialog.cc:43 msgid "Channels" msgstr "Canali" -#: src/wx/film_editor.cc:326 +#: src/wx/film_editor.cc:325 msgid "Colour look-up table" msgstr "Tabella per ricerca del colore" -#: src/wx/film_editor.cc:121 +#: src/wx/film_editor.cc:120 msgid "Content" msgstr "Contenuto" -#: src/wx/film_editor.cc:131 +#: src/wx/film_editor.cc:130 msgid "Content Type" msgstr "Tipo di contenuto" @@ -101,7 +109,7 @@ msgstr "Non posso creare il DCP: %s" msgid "Could not open content file (%s)" msgstr "Non posso aprire il file del contenuto (%s)" -#: src/wx/film_editor.cc:505 +#: src/wx/film_editor.cc:504 #, c-format msgid "Could not set content: %s" msgstr "Non posso regolare il contenuto: %s" @@ -114,11 +122,11 @@ msgstr "Crea nella cartella" msgid "DCI name" msgstr "Nome del DCP" -#: src/wx/film_editor.cc:142 +#: src/wx/film_editor.cc:141 msgid "DCP Frame Rate" msgstr "Frequenza fotogrammi del DCP" -#: src/wx/film_editor.cc:110 +#: src/wx/film_editor.cc:109 msgid "DCP Name" msgstr "Nome del DCP" @@ -134,15 +142,15 @@ msgstr "Preferenze DVD-o-matic" msgid "DVD-o-matic audio - %1" msgstr "Audio DVD-o-matic - %1" -#: src/wx/config_dialog.cc:83 +#: src/wx/config_dialog.cc:101 msgid "Default DCI name details" msgstr "Dettagli del nome di default DCI" -#: src/wx/config_dialog.cc:74 +#: src/wx/config_dialog.cc:92 msgid "Default directory for new films" msgstr "Directory di default per i nuovi films" -#: src/wx/film_editor.cc:117 src/wx/job_manager_view.cc:88 +#: src/wx/film_editor.cc:116 src/wx/job_manager_view.cc:92 msgid "Details..." msgstr "Dettagli" @@ -150,24 +158,24 @@ msgstr "Dettagli" msgid "Disk space required" msgstr "Spazio su disco rischiesto" -#: src/wx/film_editor.cc:192 +#: src/wx/film_editor.cc:191 msgid "Duration" msgstr "Durata" -#: src/wx/config_dialog.cc:126 +#: src/wx/config_dialog.cc:144 msgid "Edit" msgstr "Modifica" -#: src/wx/config_dialog.cc:84 src/wx/config_dialog.cc:103 -#: src/wx/film_editor.cc:309 +#: src/wx/config_dialog.cc:102 src/wx/config_dialog.cc:121 +#: src/wx/film_editor.cc:308 msgid "Edit..." msgstr "Modifica..." -#: src/wx/config_dialog.cc:109 +#: src/wx/config_dialog.cc:127 msgid "Encoding Servers" msgstr "Servers di codifica" -#: src/wx/film_editor.cc:177 +#: src/wx/film_editor.cc:176 msgid "End" msgstr "Fine" @@ -175,7 +183,7 @@ msgstr "Fine" msgid "Facility (e.g. DLA)" msgstr "Facility (es. DLA)" -#: src/wx/film_editor.cc:74 +#: src/wx/film_editor.cc:73 msgid "Film" msgstr "Film" @@ -187,11 +195,11 @@ msgstr "Proprietà del film" msgid "Film name" msgstr "Nome del film" -#: src/wx/film_editor.cc:304 src/wx/filter_dialog.cc:32 +#: src/wx/film_editor.cc:303 src/wx/filter_dialog.cc:32 msgid "Filters" msgstr "Filtri" -#: src/wx/film_editor.cc:269 +#: src/wx/film_editor.cc:268 msgid "Format" msgstr "Formato" @@ -215,7 +223,7 @@ msgstr "Gb" msgid "Host name or IP address" msgstr "Nome dell'Host o indirizzo IP" -#: src/wx/film_editor.cc:1234 +#: src/wx/film_editor.cc:1235 msgid "Hz" msgstr "Hz" @@ -223,23 +231,23 @@ msgstr "Hz" msgid "I want to play this back at fader" msgstr "Sto usando il fader a" -#: src/wx/config_dialog.cc:113 +#: src/wx/config_dialog.cc:131 msgid "IP address" msgstr "Indirizzo IP" -#: src/wx/film_editor.cc:336 +#: src/wx/film_editor.cc:335 msgid "JPEG2000 bandwidth" msgstr "Banda passante JPEG2000" -#: src/wx/film_editor.cc:282 +#: src/wx/film_editor.cc:281 msgid "Left crop" msgstr "Taglio a sinistra" -#: src/wx/film_editor.cc:165 +#: src/wx/film_editor.cc:164 msgid "Length" msgstr "Lunghezza" -#: src/wx/film_editor.cc:340 +#: src/wx/film_editor.cc:339 msgid "MBps" msgstr "MBps" @@ -247,7 +255,7 @@ msgstr "MBps" msgid "My Documents" msgstr "Documenti" -#: src/wx/film_editor.cc:105 +#: src/wx/film_editor.cc:104 msgid "Name" msgstr "Nome" @@ -255,15 +263,15 @@ msgstr "Nome" msgid "New Film" msgstr "Nuovo Film" -#: src/wx/film_editor.cc:306 src/wx/film_editor.cc:665 +#: src/wx/film_editor.cc:305 src/wx/film_editor.cc:664 msgid "None" msgstr "Nessuno" -#: src/wx/film_editor.cc:136 +#: src/wx/film_editor.cc:135 msgid "Original Frame Rate" msgstr "Frequenza fotogrammi originale" -#: src/wx/film_editor.cc:160 +#: src/wx/film_editor.cc:159 msgid "Original Size" msgstr "Dimensione Originale" @@ -291,35 +299,35 @@ msgstr "RMS" msgid "Rating (e.g. 15)" msgstr "Classificazione (es. 15)" -#: src/wx/config_dialog.cc:99 +#: src/wx/config_dialog.cc:117 msgid "Reference filters for A/B" msgstr "Filtri di riferimento A/B" -#: src/wx/config_dialog.cc:88 +#: src/wx/config_dialog.cc:106 msgid "Reference scaler for A/B" msgstr "Scalatura di riferimento A/B" -#: src/wx/config_dialog.cc:128 +#: src/wx/config_dialog.cc:146 msgid "Remove" msgstr "Rimuovi" -#: src/wx/film_editor.cc:287 +#: src/wx/film_editor.cc:286 msgid "Right crop" msgstr "Taglio a destra" -#: src/wx/job_manager_view.cc:104 +#: src/wx/job_manager_view.cc:108 msgid "Running" msgstr "In corso" -#: src/wx/film_editor.cc:316 +#: src/wx/film_editor.cc:315 msgid "Scaler" msgstr "Scaler" -#: src/wx/film_editor.cc:408 +#: src/wx/film_editor.cc:407 msgid "Select Audio File" msgstr "Seleziona file audio" -#: src/wx/film_editor.cc:122 +#: src/wx/film_editor.cc:121 msgid "Select Content File" msgstr "Seleziona il file con il contenuto" @@ -327,7 +335,11 @@ msgstr "Seleziona il file con il contenuto" msgid "Server" msgstr "Server" -#: src/wx/film_editor.cc:365 +#: src/wx/config_dialog.cc:49 +msgid "Set language" +msgstr "" + +#: src/wx/film_editor.cc:364 msgid "Show Audio..." msgstr "Mostra Audio..." @@ -335,7 +347,7 @@ msgstr "Mostra Audio..." msgid "Smoothing" msgstr "Levigatura" -#: src/wx/film_editor.cc:174 +#: src/wx/film_editor.cc:173 msgid "Start" msgstr "Inizio" @@ -347,31 +359,31 @@ msgstr "Studio (es. TCF)" msgid "Subtitle Language (e.g. FR)" msgstr "Lingua dei Sottotitoli (es. FR)" -#: src/wx/film_editor.cc:432 +#: src/wx/film_editor.cc:431 msgid "Subtitle Offset" msgstr "Sfalsamento dei Sottotitoli" -#: src/wx/film_editor.cc:437 +#: src/wx/film_editor.cc:436 msgid "Subtitle Scale" msgstr "Scala dei Sottotitoli" -#: src/wx/film_editor.cc:80 +#: src/wx/film_editor.cc:79 msgid "Subtitles" msgstr "Sottotitoli" -#: src/wx/config_dialog.cc:49 +#: src/wx/config_dialog.cc:67 msgid "TMS IP address" msgstr "Indirizzo IP del TMS" -#: src/wx/config_dialog.cc:64 +#: src/wx/config_dialog.cc:82 msgid "TMS password" msgstr "Password del TMS" -#: src/wx/config_dialog.cc:54 +#: src/wx/config_dialog.cc:72 msgid "TMS target path" msgstr "Percorso di destinazione del TMS" -#: src/wx/config_dialog.cc:59 +#: src/wx/config_dialog.cc:77 msgid "TMS user name" msgstr "Nome utente del TMS" @@ -379,7 +391,7 @@ msgstr "Nome utente del TMS" msgid "Territory (e.g. UK)" msgstr "Nazione (es. UK)" -#: src/wx/config_dialog.cc:117 +#: src/wx/config_dialog.cc:135 msgid "Threads" msgstr "Threads" @@ -387,7 +399,7 @@ msgstr "Threads" msgid "Threads to use" msgstr "Threads da usare" -#: src/wx/config_dialog.cc:69 +#: src/wx/config_dialog.cc:87 msgid "Threads to use for encoding on this host" msgstr "Threads da usare per codificare su questo host" @@ -395,15 +407,15 @@ msgstr "Threads da usare per codificare su questo host" msgid "Time" msgstr "Tempo" -#: src/wx/film_editor.cc:292 +#: src/wx/film_editor.cc:291 msgid "Top crop" msgstr "Taglio in alto" -#: src/wx/film_editor.cc:172 +#: src/wx/film_editor.cc:171 msgid "Trim frames" msgstr "Taglia fotogrammi" -#: src/wx/film_editor.cc:126 +#: src/wx/film_editor.cc:125 msgid "Trust content's header" msgstr "Conferma l'intestazione del contenuto" @@ -411,31 +423,31 @@ msgstr "Conferma l'intestazione del contenuto" msgid "Type" msgstr "Tipo" -#: src/wx/film_editor.cc:115 +#: src/wx/film_editor.cc:114 msgid "Use DCI name" msgstr "Usa nome DCI" -#: src/wx/film_editor.cc:146 +#: src/wx/film_editor.cc:145 msgid "Use best" msgstr "Usa la migliore" -#: src/wx/film_editor.cc:392 +#: src/wx/film_editor.cc:391 msgid "Use content's audio" msgstr "Usa l'audio del contenuto" -#: src/wx/film_editor.cc:402 +#: src/wx/film_editor.cc:401 msgid "Use external audio" msgstr "Usa l'audio esterno" -#: src/wx/film_editor.cc:76 +#: src/wx/film_editor.cc:75 msgid "Video" msgstr "Video" -#: src/wx/film_editor.cc:425 +#: src/wx/film_editor.cc:424 msgid "With Subtitles" msgstr "Con Sottotitoli" -#: src/wx/film_editor.cc:1232 +#: src/wx/film_editor.cc:1233 msgid "channels" msgstr "canali" @@ -443,21 +455,21 @@ msgstr "canali" msgid "counting..." msgstr "conteggio..." -#: src/wx/film_editor.cc:374 +#: src/wx/film_editor.cc:373 msgid "dB" msgstr "dB" -#: src/wx/film_editor.cc:691 src/wx/film_editor.cc:693 +#: src/wx/film_editor.cc:691 src/wx/film_editor.cc:694 msgid "frames" msgstr "fotogrammi" #. / TRANSLATORS: this is an abbreviation for milliseconds, the unit of time -#: src/wx/film_editor.cc:387 +#: src/wx/film_editor.cc:386 msgid "ms" msgstr "ms" #. / TRANSLATORS: `s' here is an abbreviation for seconds, the unit of time -#: src/wx/film_editor.cc:198 +#: src/wx/film_editor.cc:197 msgid "s" msgstr "s" -- cgit v1.2.3 From 692c40f6b5a189b2014ed0b8aa3094f2fa93d26a Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 26 Mar 2013 14:54:51 +0000 Subject: Fix untranslated sound channel names. --- src/lib/po/es_ES.po | 26 +++++++++++++++++++++++++- src/lib/po/fr_FR.po | 26 +++++++++++++++++++++++++- src/lib/po/it_IT.po | 26 +++++++++++++++++++++++++- src/lib/util.cc | 12 ++++++------ src/tools/po/es_ES.po | 2 +- src/tools/po/fr_FR.po | 2 +- src/tools/po/it_IT.po | 2 +- src/wx/po/es_ES.po | 2 +- src/wx/po/fr_FR.po | 2 +- src/wx/po/it_IT.po | 2 +- 10 files changed, 87 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/lib/po/es_ES.po b/src/lib/po/es_ES.po index 18e53d3b7..a25c1fe2b 100644 --- a/src/lib/po/es_ES.po +++ b/src/lib/po/es_ES.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: LIBDVDOMATIC\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-26 14:11+0000\n" +"POT-Creation-Date: 2013-03-26 14:54+0000\n" "PO-Revision-Date: 2013-03-23 22:42-0500\n" "Last-Translator: Manuel AC \n" "Language-Team: Manuel AC \n" @@ -102,6 +102,10 @@ msgid "Cannot resample audio as libswresample is not present" msgstr "" "No se puede redimensionar el sonido porque no se encuentra libswresample" +#: src/lib/util.cc:922 +msgid "Centre" +msgstr "" + #: src/lib/scp_dcp_job.cc:109 msgid "Copy DCP to TMS" msgstr "Copiar DCP al TMS" @@ -253,6 +257,18 @@ msgstr "" msgid "Lanczos" msgstr "Lanczos" +#: src/lib/util.cc:920 +msgid "Left" +msgstr "" + +#: src/lib/util.cc:924 +msgid "Left surround" +msgstr "" + +#: src/lib/util.cc:923 +msgid "Lfe (sub)" +msgstr "" + #: src/lib/filter.cc:75 msgid "Linear blend deinterlacer" msgstr "" @@ -303,6 +319,14 @@ msgstr "Clasificación" msgid "Rec 709" msgstr "Rec 709" +#: src/lib/util.cc:921 +msgid "Right" +msgstr "" + +#: src/lib/util.cc:925 +msgid "Right surround" +msgstr "" + #: src/lib/scp_dcp_job.cc:133 msgid "SSH error (%1)" msgstr "error SSH (%1)" diff --git a/src/lib/po/fr_FR.po b/src/lib/po/fr_FR.po index 98080b61d..1731b4c49 100644 --- a/src/lib/po/fr_FR.po +++ b/src/lib/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-26 14:11+0000\n" +"POT-Creation-Date: 2013-03-26 14:54+0000\n" "PO-Revision-Date: 2013-03-20 00:39+0100\n" "Last-Translator: FreeDCP.net \n" "Language-Team: \n" @@ -100,6 +100,10 @@ msgstr "" msgid "Cannot resample audio as libswresample is not present" msgstr "Ré-échantillonnage du son impossible : libswresample est absent" +#: src/lib/util.cc:922 +msgid "Centre" +msgstr "" + #: src/lib/scp_dcp_job.cc:109 msgid "Copy DCP to TMS" msgstr "Copier le DCP dans le TMS" @@ -251,6 +255,18 @@ msgstr "Désentrelaceur noyau" msgid "Lanczos" msgstr "Lanczos" +#: src/lib/util.cc:920 +msgid "Left" +msgstr "" + +#: src/lib/util.cc:924 +msgid "Left surround" +msgstr "" + +#: src/lib/util.cc:923 +msgid "Lfe (sub)" +msgstr "" + #: src/lib/filter.cc:75 msgid "Linear blend deinterlacer" msgstr "Désentrelaceur par mélange interpolé" @@ -301,6 +317,14 @@ msgstr "Rating" msgid "Rec 709" msgstr "Rec 709" +#: src/lib/util.cc:921 +msgid "Right" +msgstr "" + +#: src/lib/util.cc:925 +msgid "Right surround" +msgstr "" + #: src/lib/scp_dcp_job.cc:133 msgid "SSH error (%1)" msgstr "Erreur SSH (%1)" diff --git a/src/lib/po/it_IT.po b/src/lib/po/it_IT.po index 24cd1c187..67f8f4c45 100644 --- a/src/lib/po/it_IT.po +++ b/src/lib/po/it_IT.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-26 14:11+0000\n" +"POT-Creation-Date: 2013-03-26 14:54+0000\n" "PO-Revision-Date: 2013-03-20 11:45+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" @@ -101,6 +101,10 @@ msgstr "" msgid "Cannot resample audio as libswresample is not present" msgstr "Non posso ricampionare l'audio perchè libswresample non è presente" +#: src/lib/util.cc:922 +msgid "Centre" +msgstr "" + #: src/lib/scp_dcp_job.cc:109 msgid "Copy DCP to TMS" msgstr "Copia del DCP al TMS" @@ -252,6 +256,18 @@ msgstr "Deinterlacciatore Kernel" msgid "Lanczos" msgstr "Lanczos" +#: src/lib/util.cc:920 +msgid "Left" +msgstr "" + +#: src/lib/util.cc:924 +msgid "Left surround" +msgstr "" + +#: src/lib/util.cc:923 +msgid "Lfe (sub)" +msgstr "" + #: src/lib/filter.cc:75 msgid "Linear blend deinterlacer" msgstr "Deinterlacciatore lineare miscelato" @@ -302,6 +318,14 @@ msgstr "Punteggio" msgid "Rec 709" msgstr "Rec 709" +#: src/lib/util.cc:921 +msgid "Right" +msgstr "" + +#: src/lib/util.cc:925 +msgid "Right surround" +msgstr "" + #: src/lib/scp_dcp_job.cc:133 msgid "SSH error (%1)" msgstr "Errore SSH (%1)" diff --git a/src/lib/util.cc b/src/lib/util.cc index 2e4671251..9a7794ce8 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -917,12 +917,12 @@ audio_channel_name (int c) enhancement channel (sub-woofer)./ */ string const channels[] = { - "Left", - "Right", - "Centre", - "Lfe (sub)", - "Left surround", - "Right surround", + _("Left"), + _("Right"), + _("Centre"), + _("Lfe (sub)"), + _("Left surround"), + _("Right surround"), }; return channels[c]; diff --git a/src/tools/po/es_ES.po b/src/tools/po/es_ES.po index c114c7ae9..c330b69cf 100644 --- a/src/tools/po/es_ES.po +++ b/src/tools/po/es_ES.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVDOMATIC\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-26 14:11+0000\n" +"POT-Creation-Date: 2013-03-26 14:54+0000\n" "PO-Revision-Date: 2013-03-23 21:08-0500\n" "Last-Translator: Manuel AC \n" "Language-Team: Manuel AC \n" diff --git a/src/tools/po/fr_FR.po b/src/tools/po/fr_FR.po index 39001297b..54fb2d070 100644 --- a/src/tools/po/fr_FR.po +++ b/src/tools/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-26 14:11+0000\n" +"POT-Creation-Date: 2013-03-26 14:54+0000\n" "PO-Revision-Date: 2013-03-13 22:33+0100\n" "Last-Translator: \n" "Language-Team: \n" diff --git a/src/tools/po/it_IT.po b/src/tools/po/it_IT.po index 33f412b78..dce686281 100644 --- a/src/tools/po/it_IT.po +++ b/src/tools/po/it_IT.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-26 14:11+0000\n" +"POT-Creation-Date: 2013-03-26 14:54+0000\n" "PO-Revision-Date: 2013-03-22 18:03+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" diff --git a/src/wx/po/es_ES.po b/src/wx/po/es_ES.po index 3aeda7d73..23d9e1a32 100644 --- a/src/wx/po/es_ES.po +++ b/src/wx/po/es_ES.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: libdvdomatic-wx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-26 14:11+0000\n" +"POT-Creation-Date: 2013-03-26 14:54+0000\n" "PO-Revision-Date: 2013-03-23 21:20-0500\n" "Last-Translator: Manuel AC \n" "Language-Team: Manuel AC \n" diff --git a/src/wx/po/fr_FR.po b/src/wx/po/fr_FR.po index 8ab03d1cb..1adef7c2b 100644 --- a/src/wx/po/fr_FR.po +++ b/src/wx/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-26 14:11+0000\n" +"POT-Creation-Date: 2013-03-26 14:54+0000\n" "PO-Revision-Date: 2013-03-20 00:34+0100\n" "Last-Translator: FreeDCP.net \n" "Language-Team: \n" diff --git a/src/wx/po/it_IT.po b/src/wx/po/it_IT.po index c6316e9b9..e4e32e9e7 100644 --- a/src/wx/po/it_IT.po +++ b/src/wx/po/it_IT.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-26 14:11+0000\n" +"POT-Creation-Date: 2013-03-26 14:54+0000\n" "PO-Revision-Date: 2013-03-22 18:10+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" -- cgit v1.2.3 From 2f2a08ec7d5114a479b3ce180a645c3ccb6e0ff6 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 26 Mar 2013 14:55:43 +0000 Subject: Translate Cancel into French. --- src/wx/po/fr_FR.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/wx/po/fr_FR.po b/src/wx/po/fr_FR.po index 1adef7c2b..3c5ff2bfd 100644 --- a/src/wx/po/fr_FR.po +++ b/src/wx/po/fr_FR.po @@ -75,7 +75,7 @@ msgstr "Calcul..." #: src/wx/job_manager_view.cc:88 msgid "Cancel" -msgstr "" +msgstr "Annuler" #: src/wx/audio_dialog.cc:43 msgid "Channels" -- cgit v1.2.3 From ba0a895137b630f5d308b123ef886d68090f855d Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 26 Mar 2013 16:28:28 +0000 Subject: More fr_FR tweaks from Lilian. --- src/lib/po/fr_FR.po | 4 ++-- src/wx/po/fr_FR.po | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/lib/po/fr_FR.po b/src/lib/po/fr_FR.po index 1731b4c49..3f07c4f07 100644 --- a/src/lib/po/fr_FR.po +++ b/src/lib/po/fr_FR.po @@ -213,7 +213,7 @@ msgstr "Flat" #: src/lib/format.cc:130 msgid "Flat without stretch" -msgstr "Flat sans étirement" +msgstr "Flat sans déformation" #: src/lib/filter.cc:85 msgid "Force quantizer" @@ -311,7 +311,7 @@ msgstr "Public Service Announcement" #: src/lib/dcp_content_type.cc:49 msgid "Rating" -msgstr "Rating" +msgstr "Classification" #: src/lib/util.cc:490 msgid "Rec 709" diff --git a/src/wx/po/fr_FR.po b/src/wx/po/fr_FR.po index 3c5ff2bfd..fdcd91a28 100644 --- a/src/wx/po/fr_FR.po +++ b/src/wx/po/fr_FR.po @@ -244,7 +244,7 @@ msgstr "Découpe gauche" #: src/wx/film_editor.cc:164 msgid "Length" -msgstr "Longueur durée" +msgstr "Longueur / durée" #: src/wx/film_editor.cc:339 msgid "MBps" -- cgit v1.2.3 From 09594dda3d006672309dbe2f886563f4ef5d2ab6 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 26 Mar 2013 16:59:30 +0000 Subject: Try to fix mangled wx/std string conversions. --- src/tools/dvdomatic.cc | 2 +- src/wx/job_wrapper.cc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 66f366a24..2ad41b2cb 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -328,7 +328,7 @@ private: } catch (std::exception& e) { wxString p = c->GetPath (); wxCharBuffer b = p.ToUTF8 (); - error_dialog (this, wxString::Format (_("Could not open film at %s (%s)"), p.data(), e.what())); + error_dialog (this, wxString::Format (_("Could not open film at %s (%s)"), p.data(), std_to_wx (e.what()))); } } diff --git a/src/wx/job_wrapper.cc b/src/wx/job_wrapper.cc index 8ddd3a348..ede11762c 100644 --- a/src/wx/job_wrapper.cc +++ b/src/wx/job_wrapper.cc @@ -35,8 +35,8 @@ JobWrapper::make_dcp (wxWindow* parent, shared_ptr film) try { film->make_dcp (); } catch (BadSettingError& e) { - error_dialog (parent, wxString::Format (_("Bad setting for %s (%s)"), e.setting().c_str(), e.what())); + error_dialog (parent, wxString::Format (_("Bad setting for %s (%s)"), std_to_wx (e.setting().c_str()), std_to_wx (e.what()))); } catch (std::exception& e) { - error_dialog (parent, wxString::Format (_("Could not make DCP: %s"), e.what ())); + error_dialog (parent, wxString::Format (_("Could not make DCP: %s"), std_to_wx (e.what ()))); } } -- cgit v1.2.3 From 6713cba3044efdb7623edfb92c94fb74aaf9a518 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 26 Mar 2013 17:32:44 +0000 Subject: Missing fr_FR translations for sound channel names from Lilian. --- src/lib/po/fr_FR.po | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/lib/po/fr_FR.po b/src/lib/po/fr_FR.po index 3f07c4f07..a4fb54755 100644 --- a/src/lib/po/fr_FR.po +++ b/src/lib/po/fr_FR.po @@ -257,15 +257,15 @@ msgstr "Lanczos" #: src/lib/util.cc:920 msgid "Left" -msgstr "" +msgstr "Gauche" #: src/lib/util.cc:924 msgid "Left surround" -msgstr "" +msgstr "Arrière gauche" #: src/lib/util.cc:923 msgid "Lfe (sub)" -msgstr "" +msgstr "Basses fréquences" #: src/lib/filter.cc:75 msgid "Linear blend deinterlacer" @@ -319,11 +319,11 @@ msgstr "Rec 709" #: src/lib/util.cc:921 msgid "Right" -msgstr "" +msgstr "Droite" #: src/lib/util.cc:925 msgid "Right surround" -msgstr "" +msgstr "Arrière droite" #: src/lib/scp_dcp_job.cc:133 msgid "SSH error (%1)" -- cgit v1.2.3 From a97ae09e4e9946f168c38174cb83f7dd29235997 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 26 Mar 2013 21:13:40 +0000 Subject: Yet another try at the wxString / std::string / i18n mess. --- src/tools/dvdomatic.cc | 6 +++--- src/tools/po/es_ES.po | 8 ++++---- src/tools/po/fr_FR.po | 8 ++++---- src/tools/po/it_IT.po | 8 ++++---- src/wx/film_editor.cc | 2 +- src/wx/film_viewer.cc | 4 ++-- src/wx/job_wrapper.cc | 4 ++-- src/wx/po/es_ES.po | 20 ++++++++++---------- src/wx/po/fr_FR.po | 20 ++++++++++---------- src/wx/po/it_IT.po | 20 ++++++++++---------- 10 files changed, 50 insertions(+), 50 deletions(-) (limited to 'src') diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 2ad41b2cb..f6dc587c9 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -71,7 +71,7 @@ public: { _dialog = new wxMessageDialog ( 0, - std_to_wx (String::compose ("Save changes to film \"%1\" before closing?", film->name())), + std_to_wx (String::compose (wx_to_std (_("Save changes to film \"%1\" before closing?")), film->name())), _("Film changed"), wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION ); @@ -300,7 +300,7 @@ private: if (r == wxID_OK) { if (boost::filesystem::exists (d->get_path())) { - error_dialog (this, wxString::Format (_("The directory %s already exists."), d->get_path().c_str())); + error_dialog (this, std_to_wx (String::compose (wx_to_std (_("The directory %1 already exists.")), d->get_path().c_str()))); return; } @@ -328,7 +328,7 @@ private: } catch (std::exception& e) { wxString p = c->GetPath (); wxCharBuffer b = p.ToUTF8 (); - error_dialog (this, wxString::Format (_("Could not open film at %s (%s)"), p.data(), std_to_wx (e.what()))); + error_dialog (this, std_to_wx (String::compose (wx_to_std (_("Could not open film at %1 (%2)")), wx_to_std (p), e.what()))); } } diff --git a/src/tools/po/es_ES.po b/src/tools/po/es_ES.po index c330b69cf..5b3330b70 100644 --- a/src/tools/po/es_ES.po +++ b/src/tools/po/es_ES.po @@ -81,8 +81,8 @@ msgstr "No se pudo cargar la película %1 (%2)" #: src/tools/dvdomatic.cc:331 #, c-format -msgid "Could not open film at %s (%s)" -msgstr "No se pudo cargar la película en %s (%s)" +msgid "Could not open film at %1 (%2)" +msgstr "No se pudo cargar la película en %1 (%2)" #: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:402 #: src/tools/dvdomatic.cc:520 @@ -113,5 +113,5 @@ msgstr "Selecciona la película a abrir" #: src/tools/dvdomatic.cc:303 #, c-format -msgid "The directory %s already exists." -msgstr "La carpeta %s ya existe." +msgid "The directory %1 already exists." +msgstr "La carpeta %1 ya existe." diff --git a/src/tools/po/fr_FR.po b/src/tools/po/fr_FR.po index 54fb2d070..857e5b512 100644 --- a/src/tools/po/fr_FR.po +++ b/src/tools/po/fr_FR.po @@ -80,8 +80,8 @@ msgstr "Impossible de charger le film %1 (%2)" #: src/tools/dvdomatic.cc:331 #, c-format -msgid "Could not open film at %s (%s)" -msgstr "Impossible d'ouvrir le film à %s (%s)" +msgid "Could not open film at %1 (%2)" +msgstr "Impossible d'ouvrir le film à %1 (%2)" #: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:402 #: src/tools/dvdomatic.cc:520 @@ -110,5 +110,5 @@ msgstr "Sélectionner le film à ouvrir" #: src/tools/dvdomatic.cc:303 #, c-format -msgid "The directory %s already exists." -msgstr "Le dossier %s existe déjà." +msgid "The directory %1 already exists." +msgstr "Le dossier %1 existe déjà." diff --git a/src/tools/po/it_IT.po b/src/tools/po/it_IT.po index dce686281..2ce0cb11e 100644 --- a/src/tools/po/it_IT.po +++ b/src/tools/po/it_IT.po @@ -81,8 +81,8 @@ msgstr "Non posso caricare il film %1 (%2)" #: src/tools/dvdomatic.cc:331 #, c-format -msgid "Could not open film at %s (%s)" -msgstr "Non posso aprire il film in %s (%s)" +msgid "Could not open film at %1 (%2)" +msgstr "Non posso aprire il film in %1 (%2)" #: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:402 #: src/tools/dvdomatic.cc:520 @@ -111,5 +111,5 @@ msgstr "Seleziona il film da aprire" #: src/tools/dvdomatic.cc:303 #, c-format -msgid "The directory %s already exists." -msgstr "La directory %s esiste gia'." +msgid "The directory %1 already exists." +msgstr "La directory %1 esiste gia'." diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index ec99f4d9d..4ef30fd05 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -501,7 +501,7 @@ FilmEditor::content_changed (wxCommandEvent &) _film->set_content (wx_to_std (_content->GetPath ())); } catch (std::exception& e) { _content->SetPath (std_to_wx (_film->directory ())); - error_dialog (this, wxString::Format (_("Could not set content: %s"), e.what ())); + error_dialog (this, std_to_wx (String::compose (wx_to_std (_("Could not set content: %1")), e.what ()))); } } diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index a40a3c78d..a7f370f00 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -105,7 +105,7 @@ FilmViewer::film_changed (Film::Property p) try { _decoders = decoder_factory (_film, o); } catch (StringError& e) { - error_dialog (this, wxString::Format (_("Could not open content file (%s)"), e.what())); + error_dialog (this, std_to_wx (String::compose (wx_to_std (_("Could not open content file (%1)")), e.what()))); return; } @@ -411,7 +411,7 @@ FilmViewer::get_frame () } catch (DecodeError& e) { _play_button->SetValue (false); check_play_state (); - error_dialog (this, wxString::Format (_("Could not decode video for view (%s)"), e.what())); + error_dialog (this, std_to_wx (String::compose (wx_to_std (_("Could not decode video for view (%1)")), e.what()))); } } diff --git a/src/wx/job_wrapper.cc b/src/wx/job_wrapper.cc index ede11762c..f0b506ba5 100644 --- a/src/wx/job_wrapper.cc +++ b/src/wx/job_wrapper.cc @@ -35,8 +35,8 @@ JobWrapper::make_dcp (wxWindow* parent, shared_ptr film) try { film->make_dcp (); } catch (BadSettingError& e) { - error_dialog (parent, wxString::Format (_("Bad setting for %s (%s)"), std_to_wx (e.setting().c_str()), std_to_wx (e.what()))); + error_dialog (parent, std_to_wx (String::compose (wx_to_std (_("Bad setting for %1 (%2)")), e.setting(), e.what()))); } catch (std::exception& e) { - error_dialog (parent, wxString::Format (_("Could not make DCP: %s"), std_to_wx (e.what ()))); + error_dialog (parent, std_to_wx (String::compose (wx_to_std (_("Could not make DCP: %1")), e.what()))); } } diff --git a/src/wx/po/es_ES.po b/src/wx/po/es_ES.po index 23d9e1a32..b142f8321 100644 --- a/src/wx/po/es_ES.po +++ b/src/wx/po/es_ES.po @@ -55,8 +55,8 @@ msgstr "Idioma del audio (ej. ES)" #: src/wx/job_wrapper.cc:38 #, c-format -msgid "Bad setting for %s (%s)" -msgstr "Configuración erronea para %s (%s)" +msgid "Bad setting for %1 (%2)" +msgstr "Configuración erronea para %1 (%2)" #: src/wx/film_editor.cc:296 msgid "Bottom crop" @@ -96,23 +96,23 @@ msgstr "Tipo de contenido" #: src/wx/film_viewer.cc:414 #, c-format -msgid "Could not decode video for view (%s)" -msgstr "No se pudo decodificar el vídeo para mostrarlo (%s)" +msgid "Could not decode video for view (%1)" +msgstr "No se pudo decodificar el vídeo para mostrarlo (%1)" #: src/wx/job_wrapper.cc:40 #, c-format -msgid "Could not make DCP: %s" -msgstr "No se pudo crear el DCP: %s" +msgid "Could not make DCP: %1" +msgstr "No se pudo crear el DCP: %1" #: src/wx/film_viewer.cc:108 #, c-format -msgid "Could not open content file (%s)" -msgstr "No se pudo abrir el fichero (%s)" +msgid "Could not open content file (%1)" +msgstr "No se pudo abrir el fichero (%1)" #: src/wx/film_editor.cc:504 #, c-format -msgid "Could not set content: %s" -msgstr "No se pudo establecer el contenido: %s" +msgid "Could not set content: %1" +msgstr "No se pudo establecer el contenido: %1" #: src/wx/new_film_dialog.cc:46 msgid "Create in folder" diff --git a/src/wx/po/fr_FR.po b/src/wx/po/fr_FR.po index fdcd91a28..e929598c2 100644 --- a/src/wx/po/fr_FR.po +++ b/src/wx/po/fr_FR.po @@ -54,8 +54,8 @@ msgstr "Langue audio (ex. FR)" #: src/wx/job_wrapper.cc:38 #, c-format -msgid "Bad setting for %s (%s)" -msgstr "Mauvais paramètre pour %s (%s)" +msgid "Bad setting for %1 (%2)" +msgstr "Mauvais paramètre pour %1 (%2)" #: src/wx/film_editor.cc:296 msgid "Bottom crop" @@ -95,23 +95,23 @@ msgstr "Type de Contenu" #: src/wx/film_viewer.cc:414 #, c-format -msgid "Could not decode video for view (%s)" -msgstr "Décodage de la vidéo pour visualisation impossible (%s)" +msgid "Could not decode video for view (%1)" +msgstr "Décodage de la vidéo pour visualisation impossible (%1)" #: src/wx/job_wrapper.cc:40 #, c-format -msgid "Could not make DCP: %s" -msgstr "Impossible de créer le DCP : %s" +msgid "Could not make DCP: %1" +msgstr "Impossible de créer le DCP : %1" #: src/wx/film_viewer.cc:108 #, c-format -msgid "Could not open content file (%s)" -msgstr "Ouverture du contenu impossible (%s)" +msgid "Could not open content file (%1)" +msgstr "Ouverture du contenu impossible (%1)" #: src/wx/film_editor.cc:504 #, c-format -msgid "Could not set content: %s" -msgstr "Sélectionner du contenu impossible : %s" +msgid "Could not set content: %1" +msgstr "Sélectionner du contenu impossible : %1" #: src/wx/new_film_dialog.cc:46 msgid "Create in folder" diff --git a/src/wx/po/it_IT.po b/src/wx/po/it_IT.po index e4e32e9e7..c33f6a099 100644 --- a/src/wx/po/it_IT.po +++ b/src/wx/po/it_IT.po @@ -55,8 +55,8 @@ msgstr "Lingua dell'audio (es. EN)" #: src/wx/job_wrapper.cc:38 #, c-format -msgid "Bad setting for %s (%s)" -msgstr "Valore sbagliato per %s (%s)" +msgid "Bad setting for %1 (%2)" +msgstr "Valore sbagliato per %1 (%2)" #: src/wx/film_editor.cc:296 msgid "Bottom crop" @@ -96,23 +96,23 @@ msgstr "Tipo di contenuto" #: src/wx/film_viewer.cc:414 #, c-format -msgid "Could not decode video for view (%s)" -msgstr "Non posso decodificare il video per guardarlo (%s)" +msgid "Could not decode video for view (%1)" +msgstr "Non posso decodificare il video per guardarlo (%1)" #: src/wx/job_wrapper.cc:40 #, c-format -msgid "Could not make DCP: %s" -msgstr "Non posso creare il DCP: %s" +msgid "Could not make DCP: %1" +msgstr "Non posso creare il DCP: %1" #: src/wx/film_viewer.cc:108 #, c-format -msgid "Could not open content file (%s)" -msgstr "Non posso aprire il file del contenuto (%s)" +msgid "Could not open content file (%1)" +msgstr "Non posso aprire il file del contenuto (%1)" #: src/wx/film_editor.cc:504 #, c-format -msgid "Could not set content: %s" -msgstr "Non posso regolare il contenuto: %s" +msgid "Could not set content: %1" +msgstr "Non posso regolare il contenuto: %1" #: src/wx/new_film_dialog.cc:46 msgid "Create in folder" -- cgit v1.2.3 From 419bcdc816802e50fdebb89bc9dd4a73ede103f5 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 27 Mar 2013 12:19:57 +0000 Subject: More fighting with i18n woes. --- src/lib/po/fr_FR.po | 10 +++------- src/lib/util.cc | 25 +++++++++++++++++-------- src/tools/dvdomatic.cc | 4 ++-- src/tools/po/es_ES.po | 12 ++++++------ src/tools/po/fr_FR.po | 12 ++++++------ src/tools/po/it_IT.po | 12 ++++++------ src/wx/po/es_ES.po | 24 ++++++++++++------------ src/wx/po/fr_FR.po | 24 ++++++++++++------------ src/wx/po/it_IT.po | 24 ++++++++++++------------ 9 files changed, 76 insertions(+), 71 deletions(-) (limited to 'src') diff --git a/src/lib/po/fr_FR.po b/src/lib/po/fr_FR.po index a4fb54755..640d6dc71 100644 --- a/src/lib/po/fr_FR.po +++ b/src/lib/po/fr_FR.po @@ -494,7 +494,6 @@ msgid "copying %1" msgstr "copie de %1" #: src/lib/exceptions.cc:36 -#, fuzzy msgid "could not create file %1" msgstr "Écriture vers fichier distant (%1) impossible" @@ -519,18 +518,16 @@ msgid "could not open external audio file for reading" msgstr "lecture du fichier audio externe impossible" #: src/lib/exceptions.cc:29 -#, fuzzy msgid "could not open file %1" -msgstr "lecture du fichier impossible" +msgstr "lecture du fichier (%1) impossible" #: src/lib/dcp_video_frame.cc:388 msgid "could not open file for reading" msgstr "lecture du fichier impossible" #: src/lib/exceptions.cc:44 -#, fuzzy msgid "could not read from file %1 (%2)" -msgstr "Création du dossier distant %1 (%2) impossible" +msgstr "Création du dossier distant %1 impossible (%2)" #: src/lib/encoder.cc:137 src/lib/encoder.cc:314 msgid "could not run sample-rate converter" @@ -545,9 +542,8 @@ msgid "could not start SSH session" msgstr "démarrage de session SSH impossible" #: src/lib/exceptions.cc:50 -#, fuzzy msgid "could not write to file %1 (%2)" -msgstr "Écriture vers fichier distant (%1) impossible" +msgstr "Écriture vers fichier distant (%1) impossible (%2)" #: src/lib/sndfile_decoder.cc:94 msgid "external audio files have differing lengths" diff --git a/src/lib/util.cc b/src/lib/util.cc index 9a7794ce8..48cb17c26 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -263,22 +263,31 @@ mo_path () void dvdomatic_setup_i18n (string lang) { +#ifdef DVDOMATIC_POSIX + lang += ".UTF8"; +#endif + + if (!lang.empty ()) { + /* Override our environment language; this is essential on + Windows. + */ + char cmd[64]; + snprintf (cmd, sizeof(cmd), "LANGUAGE=%s", lang.c_str ()); + putenv (cmd); + snprintf (cmd, sizeof(cmd), "LANG=%s", lang.c_str ()); + putenv (cmd); + } + setlocale (LC_ALL, ""); textdomain ("libdvdomatic"); - -#ifdef DVDOMATIC_WINDOWS - string const e = "LANGUAGE=" + lang; - putenv (e.c_str()); +#ifdef DVDOMATIC_WINDOWS bindtextdomain ("libdvdomatic", mo_path().string().c_str()); -#else - /* Hack to silence warning */ - lang.clear (); #endif #ifdef DVDOMATIC_POSIX bindtextdomain ("libdvdomatic", POSIX_LOCALE_PREFIX); -#endif +#endif } /** @param start Start position for the crop within the image. diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index f6dc587c9..71b8ff6c4 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -284,7 +284,7 @@ private: void file_changed (string f) { stringstream s; - s << _("DVD-o-matic"); + s << wx_to_std (_("DVD-o-matic")); if (!f.empty ()) { s << " - " << f; } @@ -328,7 +328,7 @@ private: } catch (std::exception& e) { wxString p = c->GetPath (); wxCharBuffer b = p.ToUTF8 (); - error_dialog (this, std_to_wx (String::compose (wx_to_std (_("Could not open film at %1 (%2)")), wx_to_std (p), e.what()))); + error_dialog (this, wxString::Format (_("Could not open film at %s (%s)"), p.data(), std_to_wx (e.what()).data())); } } diff --git a/src/tools/po/es_ES.po b/src/tools/po/es_ES.po index 5b3330b70..23b2c9cdc 100644 --- a/src/tools/po/es_ES.po +++ b/src/tools/po/es_ES.po @@ -76,13 +76,13 @@ msgid "About" msgstr "Acerca de" #: src/tools/dvdomatic.cc:516 -msgid "Could not load film %1 (%2)" -msgstr "No se pudo cargar la película %1 (%2)" +msgid "Could not load film %s (%s)" +msgstr "No se pudo cargar la película %s (%s)" #: src/tools/dvdomatic.cc:331 #, c-format -msgid "Could not open film at %1 (%2)" -msgstr "No se pudo cargar la película en %1 (%2)" +msgid "Could not open film at %s (%s)" +msgstr "No se pudo cargar la película en %s (%s)" #: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:402 #: src/tools/dvdomatic.cc:520 @@ -113,5 +113,5 @@ msgstr "Selecciona la película a abrir" #: src/tools/dvdomatic.cc:303 #, c-format -msgid "The directory %1 already exists." -msgstr "La carpeta %1 ya existe." +msgid "The directory %s already exists." +msgstr "La carpeta %s ya existe." diff --git a/src/tools/po/fr_FR.po b/src/tools/po/fr_FR.po index 857e5b512..b0c46117d 100644 --- a/src/tools/po/fr_FR.po +++ b/src/tools/po/fr_FR.po @@ -75,13 +75,13 @@ msgid "About" msgstr "A Propos" #: src/tools/dvdomatic.cc:516 -msgid "Could not load film %1 (%2)" -msgstr "Impossible de charger le film %1 (%2)" +msgid "Could not load film %s (%s)" +msgstr "Impossible de charger le film %s (%s)" #: src/tools/dvdomatic.cc:331 #, c-format -msgid "Could not open film at %1 (%2)" -msgstr "Impossible d'ouvrir le film à %1 (%2)" +msgid "Could not open film at %s (%s)" +msgstr "Impossible d'ouvrir le film à %s (%s)" #: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:402 #: src/tools/dvdomatic.cc:520 @@ -110,5 +110,5 @@ msgstr "Sélectionner le film à ouvrir" #: src/tools/dvdomatic.cc:303 #, c-format -msgid "The directory %1 already exists." -msgstr "Le dossier %1 existe déjà." +msgid "The directory %s already exists." +msgstr "Le dossier %s existe déjà." diff --git a/src/tools/po/it_IT.po b/src/tools/po/it_IT.po index 2ce0cb11e..906653093 100644 --- a/src/tools/po/it_IT.po +++ b/src/tools/po/it_IT.po @@ -76,13 +76,13 @@ msgid "About" msgstr "Informazioni" #: src/tools/dvdomatic.cc:516 -msgid "Could not load film %1 (%2)" -msgstr "Non posso caricare il film %1 (%2)" +msgid "Could not load film %s (%s)" +msgstr "Non posso caricare il film %s (%s)" #: src/tools/dvdomatic.cc:331 #, c-format -msgid "Could not open film at %1 (%2)" -msgstr "Non posso aprire il film in %1 (%2)" +msgid "Could not open film at %s (%s)" +msgstr "Non posso aprire il film in %s (%s)" #: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:402 #: src/tools/dvdomatic.cc:520 @@ -111,5 +111,5 @@ msgstr "Seleziona il film da aprire" #: src/tools/dvdomatic.cc:303 #, c-format -msgid "The directory %1 already exists." -msgstr "La directory %1 esiste gia'." +msgid "The directory %s already exists." +msgstr "La directory %s esiste gia'." diff --git a/src/wx/po/es_ES.po b/src/wx/po/es_ES.po index b142f8321..58092d00b 100644 --- a/src/wx/po/es_ES.po +++ b/src/wx/po/es_ES.po @@ -55,8 +55,8 @@ msgstr "Idioma del audio (ej. ES)" #: src/wx/job_wrapper.cc:38 #, c-format -msgid "Bad setting for %1 (%2)" -msgstr "Configuración erronea para %1 (%2)" +msgid "Bad setting for %s (%s)" +msgstr "Configuración erronea para %s (%s)" #: src/wx/film_editor.cc:296 msgid "Bottom crop" @@ -96,23 +96,23 @@ msgstr "Tipo de contenido" #: src/wx/film_viewer.cc:414 #, c-format -msgid "Could not decode video for view (%1)" -msgstr "No se pudo decodificar el vídeo para mostrarlo (%1)" +msgid "Could not decode video for view (%s)" +msgstr "No se pudo decodificar el vídeo para mostrarlo (%s)" #: src/wx/job_wrapper.cc:40 #, c-format -msgid "Could not make DCP: %1" -msgstr "No se pudo crear el DCP: %1" +msgid "Could not make DCP: %s" +msgstr "No se pudo crear el DCP: %s" #: src/wx/film_viewer.cc:108 #, c-format -msgid "Could not open content file (%1)" -msgstr "No se pudo abrir el fichero (%1)" +msgid "Could not open content file (%s)" +msgstr "No se pudo abrir el fichero (%s)" #: src/wx/film_editor.cc:504 #, c-format -msgid "Could not set content: %1" -msgstr "No se pudo establecer el contenido: %1" +msgid "Could not set content: %s" +msgstr "No se pudo establecer el contenido: %s" #: src/wx/new_film_dialog.cc:46 msgid "Create in folder" @@ -139,8 +139,8 @@ msgid "DVD-o-matic Preferences" msgstr "Preferencias DVD-o-matic" #: src/wx/audio_dialog.cc:101 -msgid "DVD-o-matic audio - %1" -msgstr "Audio DVD-o-matic - %1" +msgid "DVD-o-matic audio - %s" +msgstr "Audio DVD-o-matic - %s" #: src/wx/config_dialog.cc:101 msgid "Default DCI name details" diff --git a/src/wx/po/fr_FR.po b/src/wx/po/fr_FR.po index e929598c2..87e24df69 100644 --- a/src/wx/po/fr_FR.po +++ b/src/wx/po/fr_FR.po @@ -54,8 +54,8 @@ msgstr "Langue audio (ex. FR)" #: src/wx/job_wrapper.cc:38 #, c-format -msgid "Bad setting for %1 (%2)" -msgstr "Mauvais paramètre pour %1 (%2)" +msgid "Bad setting for %s (%s)" +msgstr "Mauvais paramètre pour %s (%s)" #: src/wx/film_editor.cc:296 msgid "Bottom crop" @@ -95,23 +95,23 @@ msgstr "Type de Contenu" #: src/wx/film_viewer.cc:414 #, c-format -msgid "Could not decode video for view (%1)" -msgstr "Décodage de la vidéo pour visualisation impossible (%1)" +msgid "Could not decode video for view (%s)" +msgstr "Décodage de la vidéo pour visualisation impossible (%s)" #: src/wx/job_wrapper.cc:40 #, c-format -msgid "Could not make DCP: %1" -msgstr "Impossible de créer le DCP : %1" +msgid "Could not make DCP: %s" +msgstr "Impossible de créer le DCP : %s" #: src/wx/film_viewer.cc:108 #, c-format -msgid "Could not open content file (%1)" -msgstr "Ouverture du contenu impossible (%1)" +msgid "Could not open content file (%s)" +msgstr "Ouverture du contenu impossible (%s)" #: src/wx/film_editor.cc:504 #, c-format -msgid "Could not set content: %1" -msgstr "Sélectionner du contenu impossible : %1" +msgid "Could not set content: %s" +msgstr "Sélectionner du contenu impossible : %s" #: src/wx/new_film_dialog.cc:46 msgid "Create in folder" @@ -138,8 +138,8 @@ msgid "DVD-o-matic Preferences" msgstr "Préférences DVD-o-matic" #: src/wx/audio_dialog.cc:101 -msgid "DVD-o-matic audio - %1" -msgstr "Son DVD-o-matic - %1" +msgid "DVD-o-matic audio - %s" +msgstr "Son DVD-o-matic - %s" #: src/wx/config_dialog.cc:101 msgid "Default DCI name details" diff --git a/src/wx/po/it_IT.po b/src/wx/po/it_IT.po index c33f6a099..2e65d7d98 100644 --- a/src/wx/po/it_IT.po +++ b/src/wx/po/it_IT.po @@ -55,8 +55,8 @@ msgstr "Lingua dell'audio (es. EN)" #: src/wx/job_wrapper.cc:38 #, c-format -msgid "Bad setting for %1 (%2)" -msgstr "Valore sbagliato per %1 (%2)" +msgid "Bad setting for %s (%s)" +msgstr "Valore sbagliato per %s (%s)" #: src/wx/film_editor.cc:296 msgid "Bottom crop" @@ -96,23 +96,23 @@ msgstr "Tipo di contenuto" #: src/wx/film_viewer.cc:414 #, c-format -msgid "Could not decode video for view (%1)" -msgstr "Non posso decodificare il video per guardarlo (%1)" +msgid "Could not decode video for view (%s)" +msgstr "Non posso decodificare il video per guardarlo (%s)" #: src/wx/job_wrapper.cc:40 #, c-format -msgid "Could not make DCP: %1" -msgstr "Non posso creare il DCP: %1" +msgid "Could not make DCP: %s" +msgstr "Non posso creare il DCP: %s" #: src/wx/film_viewer.cc:108 #, c-format -msgid "Could not open content file (%1)" -msgstr "Non posso aprire il file del contenuto (%1)" +msgid "Could not open content file (%s)" +msgstr "Non posso aprire il file del contenuto (%s)" #: src/wx/film_editor.cc:504 #, c-format -msgid "Could not set content: %1" -msgstr "Non posso regolare il contenuto: %1" +msgid "Could not set content: %s" +msgstr "Non posso regolare il contenuto: %s" #: src/wx/new_film_dialog.cc:46 msgid "Create in folder" @@ -139,8 +139,8 @@ msgid "DVD-o-matic Preferences" msgstr "Preferenze DVD-o-matic" #: src/wx/audio_dialog.cc:101 -msgid "DVD-o-matic audio - %1" -msgstr "Audio DVD-o-matic - %1" +msgid "DVD-o-matic audio - %s" +msgstr "Audio DVD-o-matic - %s" #: src/wx/config_dialog.cc:101 msgid "Default DCI name details" -- cgit v1.2.3 From d3167c49a0b497a288529a837d2ca3eb5121fb37 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 27 Mar 2013 12:26:41 +0000 Subject: Another try at the wxString / std / i18n confusions. --- src/wx/audio_dialog.cc | 2 +- src/wx/film_editor.cc | 2 +- src/wx/film_viewer.cc | 4 ++-- src/wx/gain_calculator_dialog.cc | 2 +- src/wx/job_wrapper.cc | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/wx/audio_dialog.cc b/src/wx/audio_dialog.cc index ba7ddd8f7..3e43d484f 100644 --- a/src/wx/audio_dialog.cc +++ b/src/wx/audio_dialog.cc @@ -98,7 +98,7 @@ AudioDialog::set_film (boost::shared_ptr f) _film_changed_connection = _film->Changed.connect (bind (&AudioDialog::film_changed, this, _1)); _film_audio_analysis_succeeded_connection = _film->AudioAnalysisSucceeded.connect (bind (&AudioDialog::try_to_load_analysis, this)); - SetTitle (std_to_wx (String::compose (wx_to_std (_("DVD-o-matic audio - %1")), _film->name()))); + SetTitle (wxString::Format (_("DVD-o-matic audio - %1"), std_to_wx(_film->name()).data())); } void diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 4ef30fd05..a94ed7b2d 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -501,7 +501,7 @@ FilmEditor::content_changed (wxCommandEvent &) _film->set_content (wx_to_std (_content->GetPath ())); } catch (std::exception& e) { _content->SetPath (std_to_wx (_film->directory ())); - error_dialog (this, std_to_wx (String::compose (wx_to_std (_("Could not set content: %1")), e.what ()))); + error_dialog (this, wxString::Format (_("Could not set content: %1"), std_to_wx (e.what()).data())); } } diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index a7f370f00..08eade4d0 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -105,7 +105,7 @@ FilmViewer::film_changed (Film::Property p) try { _decoders = decoder_factory (_film, o); } catch (StringError& e) { - error_dialog (this, std_to_wx (String::compose (wx_to_std (_("Could not open content file (%1)")), e.what()))); + error_dialog (this, wxString::Format (_("Could not open content file (%s)"), std_to_wx(e.what()).data())); return; } @@ -411,7 +411,7 @@ FilmViewer::get_frame () } catch (DecodeError& e) { _play_button->SetValue (false); check_play_state (); - error_dialog (this, std_to_wx (String::compose (wx_to_std (_("Could not decode video for view (%1)")), e.what()))); + error_dialog (this, wxString::Format (_("Could not decode video for view (%s)"), std_to_wx(e.what()).data())); } } diff --git a/src/wx/gain_calculator_dialog.cc b/src/wx/gain_calculator_dialog.cc index 7f4b774c0..22e6b447a 100644 --- a/src/wx/gain_calculator_dialog.cc +++ b/src/wx/gain_calculator_dialog.cc @@ -24,7 +24,7 @@ using namespace boost; GainCalculatorDialog::GainCalculatorDialog (wxWindow* parent) - : wxDialog (parent, wxID_ANY, wxString (_("Gain Calculator"))) + : wxDialog (parent, wxID_ANY, _("Gain Calculator")) { wxFlexGridSizer* table = new wxFlexGridSizer (2, 6, 6); table->AddGrowableCol (1, 1); diff --git a/src/wx/job_wrapper.cc b/src/wx/job_wrapper.cc index f0b506ba5..d6ae828b4 100644 --- a/src/wx/job_wrapper.cc +++ b/src/wx/job_wrapper.cc @@ -35,8 +35,8 @@ JobWrapper::make_dcp (wxWindow* parent, shared_ptr film) try { film->make_dcp (); } catch (BadSettingError& e) { - error_dialog (parent, std_to_wx (String::compose (wx_to_std (_("Bad setting for %1 (%2)")), e.setting(), e.what()))); + error_dialog (parent, wxString::Format (_("Bad setting for %1 (%2)"), std_to_wx(e.setting()).data(), std_to_wx(e.what()).data())); } catch (std::exception& e) { - error_dialog (parent, std_to_wx (String::compose (wx_to_std (_("Could not make DCP: %1")), e.what()))); + error_dialog (parent, wxString::Format (_("Could not make DCP: %1"), std_to_wx(e.what()).data())); } } -- cgit v1.2.3 From 58723875416b5d285426b6355792f4607d00804c Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 27 Mar 2013 14:49:13 +0000 Subject: Fix a few format strings. --- src/wx/audio_dialog.cc | 2 +- src/wx/film_editor.cc | 2 +- src/wx/job_wrapper.cc | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/wx/audio_dialog.cc b/src/wx/audio_dialog.cc index 3e43d484f..3d17988b6 100644 --- a/src/wx/audio_dialog.cc +++ b/src/wx/audio_dialog.cc @@ -98,7 +98,7 @@ AudioDialog::set_film (boost::shared_ptr f) _film_changed_connection = _film->Changed.connect (bind (&AudioDialog::film_changed, this, _1)); _film_audio_analysis_succeeded_connection = _film->AudioAnalysisSucceeded.connect (bind (&AudioDialog::try_to_load_analysis, this)); - SetTitle (wxString::Format (_("DVD-o-matic audio - %1"), std_to_wx(_film->name()).data())); + SetTitle (wxString::Format (_("DVD-o-matic audio - %s"), std_to_wx(_film->name()).data())); } void diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index a94ed7b2d..c1d679665 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -501,7 +501,7 @@ FilmEditor::content_changed (wxCommandEvent &) _film->set_content (wx_to_std (_content->GetPath ())); } catch (std::exception& e) { _content->SetPath (std_to_wx (_film->directory ())); - error_dialog (this, wxString::Format (_("Could not set content: %1"), std_to_wx (e.what()).data())); + error_dialog (this, wxString::Format (_("Could not set content: %s"), std_to_wx (e.what()).data())); } } diff --git a/src/wx/job_wrapper.cc b/src/wx/job_wrapper.cc index d6ae828b4..df4aa7d2e 100644 --- a/src/wx/job_wrapper.cc +++ b/src/wx/job_wrapper.cc @@ -35,8 +35,8 @@ JobWrapper::make_dcp (wxWindow* parent, shared_ptr film) try { film->make_dcp (); } catch (BadSettingError& e) { - error_dialog (parent, wxString::Format (_("Bad setting for %1 (%2)"), std_to_wx(e.setting()).data(), std_to_wx(e.what()).data())); + error_dialog (parent, wxString::Format (_("Bad setting for %s (%s)"), std_to_wx(e.setting()).data(), std_to_wx(e.what()).data())); } catch (std::exception& e) { - error_dialog (parent, wxString::Format (_("Could not make DCP: %1"), std_to_wx(e.what()).data())); + error_dialog (parent, wxString::Format (_("Could not make DCP: %s"), std_to_wx(e.what()).data())); } } -- cgit v1.2.3 From 619389ffd6b562349a3f42f6ceadbdcb0ea0b915 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 27 Mar 2013 15:17:45 +0000 Subject: Fix erroneous disk space reports (#93). --- src/wx/properties_dialog.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/wx/properties_dialog.cc b/src/wx/properties_dialog.cc index 02f848c01..44a713dc3 100644 --- a/src/wx/properties_dialog.cc +++ b/src/wx/properties_dialog.cc @@ -54,7 +54,7 @@ PropertiesDialog::PropertiesDialog (wxWindow* parent, shared_ptr film) _frames->SetLabel (std_to_wx (lexical_cast (_film->length().get()))); FrameRateConversion frc (_film->source_frame_rate(), _film->dcp_frame_rate()); int const dcp_length = _film->length().get() * frc.factor(); - double const disk = ((double) _film->j2k_bandwidth() / 8) * dcp_length / (_film->dcp_frame_rate() * 1073741824); + double const disk = ((double) _film->j2k_bandwidth() / 8) * dcp_length / (_film->dcp_frame_rate() * 1073741824.0f); stringstream s; s << fixed << setprecision (1) << disk << wx_to_std (_("Gb")); _disk->SetLabel (std_to_wx (s.str ())); -- cgit v1.2.3 From b4142a9bf53c291bba8662de3b36dde1b7e19c48 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 28 Mar 2013 10:34:35 +0000 Subject: Add Swedish translation from Adam Klotblixt --- src/lib/po/sv_SE.po | 622 ++++++++++++++++++++++++++++++++++++++++++++++++ src/tools/dvdomatic.cc | 1 + src/tools/po/sv_SE.po | 119 +++++++++ src/wx/config_dialog.cc | 6 + src/wx/po/sv_SE.po | 494 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 1242 insertions(+) create mode 100644 src/lib/po/sv_SE.po create mode 100644 src/tools/po/sv_SE.po create mode 100644 src/wx/po/sv_SE.po (limited to 'src') diff --git a/src/lib/po/sv_SE.po b/src/lib/po/sv_SE.po new file mode 100644 index 000000000..23c133a81 --- /dev/null +++ b/src/lib/po/sv_SE.po @@ -0,0 +1,622 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: DVD-o-matic\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-03-26 14:07+0000\n" +"PO-Revision-Date: 2013-03-28 10:40+0100\n" +"Last-Translator: Adam Klotblixt \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.5.5\n" + +#: src/lib/transcode_job.cc:87 +msgid "0%" +msgstr "0%" + +#: src/lib/format.cc:75 +msgid "1.19" +msgstr "1,19" + +#: src/lib/format.cc:80 +msgid "1.33" +msgstr "1,33" + +#: src/lib/format.cc:85 +msgid "1.375" +msgstr "1,375" + +#: src/lib/format.cc:100 +msgid "1.66" +msgstr "1,66" + +#: src/lib/format.cc:105 +msgid "1.66 within Flat" +msgstr "1,66 innanför Flat" + +#: src/lib/format.cc:115 +msgid "16:9" +msgstr "16:9" + +#: src/lib/format.cc:110 +msgid "16:9 within Flat" +msgstr "16:9 innanför Flat" + +#: src/lib/filter.cc:88 +msgid "3D denoiser" +msgstr "3D brusreducering" + +#: src/lib/format.cc:90 +msgid "4:3 within Flat" +msgstr "4:3 innanför Flat" + +#: src/lib/ab_transcode_job.cc:49 +msgid "A/B transcode %1" +msgstr "A/B konvertera %1" + +#: src/lib/format.cc:95 +msgid "Academy" +msgstr "Academy" + +#: src/lib/dcp_content_type.cc:53 +msgid "Advertisement" +msgstr "Reklam" + +#: src/lib/job.cc:72 +msgid "An error occurred whilst handling the file %1." +msgstr "Ett fel inträffade vid hantering av filen (%1)" + +#: src/lib/analyse_audio_job.cc:49 +msgid "Analyse audio of %1" +msgstr "Analysera %1s audio" + +#: src/lib/scaler.cc:64 +msgid "Area" +msgstr "Yta" + +#: src/lib/scaler.cc:62 +msgid "Bicubic" +msgstr "Bikubisk" + +#: src/lib/scaler.cc:69 +msgid "Bilinear" +msgstr "Bilinjär" + +#: src/lib/job.cc:302 +msgid "Cancelled" +msgstr "Avbruten" + +#: src/lib/exceptions.cc:60 +msgid "Cannot handle pixel format %1 during %2" +msgstr "Kan inte hantera pixelformat %1 under %2" + +#: src/lib/encoder.cc:101 +msgid "Cannot resample audio as libswresample is not present" +msgstr "Kan inte omsampla ljudet eftersom libswresample inte finns tillgängligt" + +#: src/lib/scp_dcp_job.cc:109 +msgid "Copy DCP to TMS" +msgstr "Kopiera DCP till TMS" + +#: src/lib/scp_dcp_job.cc:128 +msgid "Could not connect to server %1 (%2)" +msgstr "Kunde inte ansluta till server %1 (%2)" + +#: src/lib/scp_dcp_job.cc:150 +msgid "Could not create remote directory %1 (%2)" +msgstr "Kunde inte skapa fjärrkatalog %1 (%2)" + +#: src/lib/scp_dcp_job.cc:175 +msgid "Could not open %1 to send" +msgstr "Kunde inte öppna %1 för att skicka" + +#: src/lib/scp_dcp_job.cc:145 +msgid "Could not start SCP session (%1)" +msgstr "Kunde inte starta SCP-session (%1)" + +#: src/lib/scp_dcp_job.cc:187 +msgid "Could not write to remote file (%1)" +msgstr "Kunde inte skriva till fjärrfil (%1)" + +#: src/lib/filter.cc:77 +msgid "Cubic interpolating deinterlacer" +msgstr "Kubiskt interpolerande avflätare" + +#: src/lib/util.cc:997 +msgid "DCP and source have the same rate.\n" +msgstr "DCP och källa har samma bildfrekvens.\n" + +#: src/lib/util.cc:1007 +msgid "DCP will run at %1%% of the source speed." +msgstr "DCP kommer att köras på %1%% av källans hastighet." + +#: src/lib/util.cc:1000 +msgid "DCP will use every other frame of the source.\n" +msgstr "DCP kommer att använda varannan bild från källan.\n" + +#: src/lib/filter.cc:68 +#: src/lib/filter.cc:69 +#: src/lib/filter.cc:70 +#: src/lib/filter.cc:71 +#: src/lib/filter.cc:72 +#: src/lib/filter.cc:73 +msgid "De-blocking" +msgstr "Kantighetsutjämning" + +#: src/lib/filter.cc:75 +#: src/lib/filter.cc:76 +#: src/lib/filter.cc:77 +#: src/lib/filter.cc:78 +#: src/lib/filter.cc:79 +#: src/lib/filter.cc:80 +#: src/lib/filter.cc:81 +#: src/lib/filter.cc:82 +#: src/lib/filter.cc:83 +msgid "De-interlacing" +msgstr "Avflätning" + +# Ja vad heter "dering" på svenska? +#: src/lib/filter.cc:74 +#, fuzzy +msgid "Deringing filter" +msgstr "Avringningsfilter" + +#: src/lib/dolby_cp750.cc:27 +msgid "Dolby CP750" +msgstr "Dolby CP750" + +#: src/lib/util.cc:1002 +msgid "Each source frame will be doubled in the DCP.\n" +msgstr "Varje bild från källan kommer att användas två gånger i DCPn.\n" + +#: src/lib/job.cc:300 +msgid "Error (%1)" +msgstr "Fel (%1)" + +#: src/lib/examine_content_job.cc:55 +msgid "Examine content" +msgstr "Undersök innehållet" + +#: src/lib/examine_content_job.cc:58 +msgid "Examine content of %1" +msgstr "Undersök innehållet i %1" + +#: src/lib/filter.cc:72 +msgid "Experimental horizontal deblocking filter 1" +msgstr "Experimentellt filter för horisontal kantighetsutjämning 1" + +#: src/lib/filter.cc:73 +msgid "Experimental vertical deblocking filter 1" +msgstr "Experimentellt filter för vertikal kantighetsutjämning 1" + +#: src/lib/filter.cc:79 +msgid "FFMPEG deinterlacer" +msgstr "FFMPEG avflätare" + +#: src/lib/filter.cc:80 +msgid "FIR low-pass deinterlacer" +msgstr "FIR lågpass-avflätare" + +#: src/lib/scp_dcp_job.cc:138 +msgid "Failed to authenticate with server (%1)" +msgstr "Misslyckades att autentisera med server (%1)" + +#: src/lib/scaler.cc:70 +msgid "Fast Bilinear" +msgstr "Snabb bilinjär" + +#: src/lib/dcp_content_type.cc:44 +msgid "Feature" +msgstr "Egenskap" + +#: src/lib/format.cc:120 +msgid "Flat" +msgstr "Flat" + +#: src/lib/format.cc:130 +msgid "Flat without stretch" +msgstr "Flat utan utsträckning" + +#: src/lib/filter.cc:85 +msgid "Force quantizer" +msgstr "Tvinga kvantiserare" + +#: src/lib/scaler.cc:65 +msgid "Gaussian" +msgstr "Gaussisk" + +#: src/lib/filter.cc:86 +msgid "Gradient debander" +msgstr "Gradientutjämnare" + +#: src/lib/filter.cc:89 +msgid "High quality 3D denoiser" +msgstr "Högkvalitets 3D-brusreducering" + +#: src/lib/filter.cc:68 +msgid "Horizontal deblocking filter" +msgstr "Filter för horisontal kantighetsutjämning" + +#: src/lib/filter.cc:70 +msgid "Horizontal deblocking filter A" +msgstr "Filter för horisontal kantighetsutjämning A" + +#: src/lib/job.cc:92 +#: src/lib/job.cc:101 +msgid "It is not known what caused this error. The best idea is to report the problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" +msgstr "Det är inte känt vad som orsakade detta fel. Bästa sättet att rapportera problemet är till DVD-o-matics mejl-lista (dvdomatic@carlh.net)" + +#: src/lib/filter.cc:82 +msgid "Kernel deinterlacer" +msgstr "Kernel-avflätare" + +#: src/lib/scaler.cc:66 +msgid "Lanczos" +msgstr "Lanczos" + +#: src/lib/filter.cc:75 +msgid "Linear blend deinterlacer" +msgstr "Linjär blandningsavflätare" + +#: src/lib/filter.cc:76 +msgid "Linear interpolating deinterlacer" +msgstr "Linjär interpolationsavflätare" + +#: src/lib/filter.cc:78 +msgid "Median deinterlacer" +msgstr "Median-avflätare" + +#: src/lib/filter.cc:74 +#: src/lib/filter.cc:85 +#: src/lib/filter.cc:86 +#: src/lib/filter.cc:87 +#: src/lib/filter.cc:90 +msgid "Misc" +msgstr "Diverse" + +#: src/lib/filter.cc:81 +msgid "Motion compensating deinterlacer" +msgstr "Rörelsekompenserande avflätare" + +#: src/lib/filter.cc:84 +#: src/lib/filter.cc:88 +#: src/lib/filter.cc:89 +#: src/lib/filter.cc:91 +msgid "Noise reduction" +msgstr "Brusreducering" + +#: src/lib/job.cc:298 +msgid "OK (ran for %1)" +msgstr "OK (kördes %1)" + +#: src/lib/filter.cc:91 +msgid "Overcomplete wavelet denoiser" +msgstr "Överkomplett wavelet-brusreducering" + +#: src/lib/dcp_content_type.cc:51 +msgid "Policy" +msgstr "Policy" + +#: src/lib/dcp_content_type.cc:52 +msgid "Public Service Announcement" +msgstr "Offentligt Servicemeddelande" + +#: src/lib/dcp_content_type.cc:49 +msgid "Rating" +msgstr "Klassificering" + +#: src/lib/util.cc:490 +msgid "Rec 709" +msgstr "Rec 709" + +#: src/lib/scp_dcp_job.cc:133 +msgid "SSH error (%1)" +msgstr "SSH fel (%1)" + +#: src/lib/format.cc:125 +msgid "Scope" +msgstr "Scope" + +#: src/lib/format.cc:135 +msgid "Scope without stretch" +msgstr "Scope utan utsträckning" + +#: src/lib/dcp_content_type.cc:45 +msgid "Short" +msgstr "Kortfilm" + +#: src/lib/scaler.cc:67 +msgid "Sinc" +msgstr "Sinc" + +#: src/lib/format.cc:76 +msgid "Source scaled to 1.19:1" +msgstr "Källan skalad till 1,19:1" + +#: src/lib/format.cc:81 +msgid "Source scaled to 1.33:1" +msgstr "Källan skalad till 1,33:1" + +#: src/lib/format.cc:91 +msgid "Source scaled to 1.33:1 then pillarboxed to Flat" +msgstr "Källan skalad till 1,33:1, med sorgkanter innanför Flat" + +#: src/lib/format.cc:86 +msgid "Source scaled to 1.375:1" +msgstr "Källan skalad till 1,375:1" + +#: src/lib/format.cc:96 +msgid "Source scaled to 1.37:1 (Academy ratio)" +msgstr "Källan skalad till 1,37:1 (Academy-förhållande)" + +#: src/lib/format.cc:101 +msgid "Source scaled to 1.66:1" +msgstr "Källan skalad till 1,66:1" + +#: src/lib/format.cc:106 +msgid "Source scaled to 1.66:1 then pillarboxed to Flat" +msgstr "Källan skalad till 1,66:1, med sorgkanter innanför Flat" + +#: src/lib/format.cc:116 +msgid "Source scaled to 1.78:1" +msgstr "Källan skalad till 1,78:1" + +#: src/lib/format.cc:111 +msgid "Source scaled to 1.78:1 then pillarboxed to Flat" +msgstr "Källan skalad till 1,78:1, med sorgkanter innanför Flat" + +#: src/lib/format.cc:121 +msgid "Source scaled to Flat (1.85:1)" +msgstr "Källan skalad till Flat (1,85:1)" + +#: src/lib/format.cc:126 +msgid "Source scaled to Scope (2.39:1)" +msgstr "Källan skalad till Scope (2,39:1)" + +#: src/lib/format.cc:131 +msgid "Source scaled to fit Flat preserving its aspect ratio" +msgstr "Källan skalad för att rymmas inom Flat utan att ändra bildförhållandet" + +#: src/lib/format.cc:136 +msgid "Source scaled to fit Scope preserving its aspect ratio" +msgstr "Källan skalad för att rymmas inom Scope utan att ändra bildförhållandet" + +#: src/lib/scaler.cc:68 +msgid "Spline" +msgstr "Spline" + +# Möjligen "Aptitretare" +#: src/lib/dcp_content_type.cc:50 +#, fuzzy +msgid "Teaser" +msgstr "Teaser" + +#: src/lib/filter.cc:90 +msgid "Telecine filter" +msgstr "Telecine-filter" + +#: src/lib/filter.cc:84 +msgid "Temporal noise reducer" +msgstr "Temporal brusreducering" + +#: src/lib/dcp_content_type.cc:47 +msgid "Test" +msgstr "Test" + +#: src/lib/job.cc:77 +msgid "The drive that the film is stored on is low in disc space. Free some more space and try again." +msgstr "Enheten som filmen lagras på har för lite ledigt utrymme. Frigör utrymme och försök igen." + +#: src/lib/dcp_content_type.cc:46 +msgid "Trailer" +msgstr "Trailer" + +#: src/lib/transcode_job.cc:54 +msgid "Transcode %1" +msgstr "Konvertera %1" + +#: src/lib/dcp_content_type.cc:48 +msgid "Transitional" +msgstr "Övergångs-" + +#: src/lib/job.cc:100 +msgid "Unknown error" +msgstr "Okänt fel" + +# Ganska svengelskt... +#: src/lib/ffmpeg_decoder.cc:396 +#, fuzzy +msgid "Unrecognised audio sample format (%1)" +msgstr "Okänt audio-sampelformat (%1)" + +#: src/lib/filter.cc:87 +msgid "Unsharp mask and Gaussian blur" +msgstr "Oskärpemask och Gaussisk suddighet" + +#: src/lib/filter.cc:69 +msgid "Vertical deblocking filter" +msgstr "Filter för vertikal kantighetsutjämning" + +#: src/lib/filter.cc:71 +msgid "Vertical deblocking filter A" +msgstr "Filter för vertikal kantighetsutjämning A" + +#: src/lib/scp_dcp_job.cc:101 +msgid "Waiting" +msgstr "Väntar" + +#: src/lib/scaler.cc:63 +msgid "X" +msgstr "X" + +# Filtret heter så, ska ej översättas? +#: src/lib/filter.cc:83 +#, fuzzy +msgid "Yet Another Deinterlacing Filter" +msgstr "Yet Another Deinterlacing Filter" + +#: src/lib/film.cc:263 +msgid "cannot contain slashes" +msgstr "får inte innehålla snedstreck" + +# mer svengelska +#: src/lib/util.cc:531 +#, fuzzy +msgid "connect timed out" +msgstr "uppkopplingen tajmade ur" + +#: src/lib/scp_dcp_job.cc:119 +msgid "connecting" +msgstr "kopplar upp" + +#: src/lib/film.cc:300 +msgid "content" +msgstr "innehåll" + +#: src/lib/film.cc:304 +msgid "content type" +msgstr "innehållstyp" + +#: src/lib/scp_dcp_job.cc:168 +msgid "copying %1" +msgstr "kopierar %1" + +#: src/lib/exceptions.cc:36 +msgid "could not create file %1" +msgstr "kunde inte skapa fil %1" + +#: src/lib/ffmpeg_decoder.cc:191 +msgid "could not find audio decoder" +msgstr "kunde inte hitta audio-avkodare" + +#: src/lib/ffmpeg_decoder.cc:118 +msgid "could not find stream information" +msgstr "kunde inte hitta information om strömmen" + +#: src/lib/ffmpeg_decoder.cc:210 +msgid "could not find subtitle decoder" +msgstr "kunde inte hitta undertext-avkodare" + +#: src/lib/ffmpeg_decoder.cc:169 +msgid "could not find video decoder" +msgstr "kunde inte hitta video-avkodare" + +#: src/lib/sndfile_decoder.cc:72 +msgid "could not open external audio file for reading" +msgstr "kunde inte öppna extern audio-fil för läsning" + +#: src/lib/exceptions.cc:29 +msgid "could not open file %1" +msgstr "kunde inte öppna fil %1" + +#: src/lib/dcp_video_frame.cc:388 +msgid "could not open file for reading" +msgstr "kunde inte öppna fil för läsning" + +#: src/lib/exceptions.cc:44 +msgid "could not read from file %1 (%2)" +msgstr "kunde inte läsa från fil %1 (%2)" + +#: src/lib/encoder.cc:137 +#: src/lib/encoder.cc:314 +msgid "could not run sample-rate converter" +msgstr "kunde inte köra sampelhastighetskonverteraren" + +#: src/lib/scp_dcp_job.cc:86 +msgid "could not start SCP session (%1)" +msgstr "kunde inte starta SCP-session (%1)" + +#: src/lib/scp_dcp_job.cc:52 +msgid "could not start SSH session" +msgstr "kunde inte starta SSH-session" + +#: src/lib/exceptions.cc:50 +msgid "could not write to file %1 (%2)" +msgstr "kunde inte skriva till fil %1 (%2)" + +#: src/lib/sndfile_decoder.cc:94 +msgid "external audio files have differing lengths" +msgstr "externa audio-filer har olika längder" + +#: src/lib/sndfile_decoder.cc:76 +msgid "external audio files must be mono" +msgstr "externa audio-filer måste vara mono" + +#: src/lib/film.cc:296 +msgid "format" +msgstr "format" + +#: src/lib/transcode_job.cc:100 +msgid "frames per second" +msgstr "bilder per sekund" + +#: src/lib/util.cc:115 +msgid "hour" +msgstr "timme" + +#: src/lib/util.cc:112 +#: src/lib/util.cc:117 +msgid "hours" +msgstr "timmar" + +#: src/lib/util.cc:122 +msgid "minute" +msgstr "minut" + +#: src/lib/util.cc:124 +msgid "minutes" +msgstr "minuter" + +#: src/lib/util.cc:674 +msgid "missing key %1 in key-value set" +msgstr "saknad nyckel %1 i nyckel-värde grupp" + +#: src/lib/exceptions.cc:54 +msgid "missing required setting %1" +msgstr "saknad nödvändig inställning %1" + +#: src/lib/subtitle.cc:52 +msgid "multi-part subtitles not yet supported" +msgstr "undertexter i flera delar stöds inte ännu" + +#: src/lib/film.cc:263 +#: src/lib/film.cc:308 +msgid "name" +msgstr "namn" + +#: src/lib/imagemagick_decoder.cc:60 +msgid "no still image files found" +msgstr "inga stillbildsfiler hittade" + +#: src/lib/subtitle.cc:58 +msgid "non-bitmap subtitles not yet supported" +msgstr "icke-rastergrafiska undertexter stöds inte ännu" + +#. / TRANSLATORS: remaining here follows an amount of time that is remaining +#. / on an operation. +#: src/lib/job.cc:295 +msgid "remaining" +msgstr "återstående tid" + +#: src/lib/util.cc:488 +msgid "sRGB" +msgstr "sRGB" + +#: src/lib/util.cc:127 +msgid "seconds" +msgstr "sekunder" + +#: src/lib/film.cc:274 +msgid "still" +msgstr "stillbild" + +#: src/lib/film.cc:274 +msgid "video" +msgstr "video" + diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 71b8ff6c4..87c079bee 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -421,6 +421,7 @@ private: translators.Add (wxT ("Thierry Journet")); translators.Add (wxT ("Massimiliano Broggi")); translators.Add (wxT ("Manuel AC")); + translators.Add (wxT ("Adam Klotblixt")); info.SetTranslators (translators); info.SetWebSite (wxT ("http://carlh.net/software/dvdomatic")); diff --git a/src/tools/po/sv_SE.po b/src/tools/po/sv_SE.po new file mode 100644 index 000000000..b15529773 --- /dev/null +++ b/src/tools/po/sv_SE.po @@ -0,0 +1,119 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: DVD-o-matic\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-03-26 14:07+0000\n" +"PO-Revision-Date: 2013-03-28 10:43+0100\n" +"Last-Translator: Adam Klotblixt \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.5.5\n" + +#: src/tools/dvdomatic.cc:177 +msgid "&Analyse audio" +msgstr "&Analysera audio" + +#: src/tools/dvdomatic.cc:183 +msgid "&Edit" +msgstr "&Redigera" + +#: src/tools/dvdomatic.cc:182 +msgid "&File" +msgstr "&Fil" + +#: src/tools/dvdomatic.cc:185 +msgid "&Help" +msgstr "&Hjälp" + +#: src/tools/dvdomatic.cc:184 +msgid "&Jobs" +msgstr "&Jobb" + +#: src/tools/dvdomatic.cc:173 +msgid "&Make DCP" +msgstr "&Skapa DCP" + +#: src/tools/dvdomatic.cc:161 +msgid "&Open..." +msgstr "&Öppna" + +#: src/tools/dvdomatic.cc:170 +msgid "&Preferences..." +msgstr "&Inställningar" + +#: src/tools/dvdomatic.cc:165 +msgid "&Properties..." +msgstr "&Egenskaper" + +#: src/tools/dvdomatic.cc:167 +msgid "&Quit" +msgstr "&Avsluta" + +#: src/tools/dvdomatic.cc:163 +msgid "&Save" +msgstr "&Spara" + +#: src/tools/dvdomatic.cc:174 +msgid "&Send DCP to TMS" +msgstr "&Skicka DCP till TMS" + +#: src/tools/dvdomatic.cc:409 +msgid "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" +msgstr "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" + +#: src/tools/dvdomatic.cc:180 +msgid "About" +msgstr "Om" + +#: src/tools/dvdomatic.cc:516 +msgid "Could not load film %1 (%2)" +msgstr "Kunde inte öppna filmen %1 (%2)" + +# "vid" eller nåt annat? +#: src/tools/dvdomatic.cc:331 +#, fuzzy, c-format +msgid "Could not open film at %s (%s)" +msgstr "Kunde inte öppna filmen vid %s (%s)" + +#: src/tools/dvdomatic.cc:287 +#: src/tools/dvdomatic.cc:402 +#: src/tools/dvdomatic.cc:520 +msgid "DVD-o-matic" +msgstr "DVD-o-matic" + +# Film bytt? +#: src/tools/dvdomatic.cc:75 +#, fuzzy +msgid "Film changed" +msgstr "Film ändrad" + +#: src/tools/dvdomatic.cc:408 +msgid "Free, open-source DCP generation from almost anything." +msgstr "Fri, öppen-källkodsprogramvara för DCP-generering från nästan vad som helst." + +# Ny? +#: src/tools/dvdomatic.cc:160 +#, fuzzy +msgid "New..." +msgstr "Skapa..." + +#: src/tools/dvdomatic.cc:175 +msgid "S&how DCP" +msgstr "&Visa DCP" + +#: src/tools/dvdomatic.cc:319 +msgid "Select film to open" +msgstr "Välj film att öppna" + +#: src/tools/dvdomatic.cc:303 +#, c-format +msgid "The directory %s already exists." +msgstr "Katalogen %s finns redan." + diff --git a/src/wx/config_dialog.cc b/src/wx/config_dialog.cc index 364336114..1d025f3fa 100644 --- a/src/wx/config_dialog.cc +++ b/src/wx/config_dialog.cc @@ -53,6 +53,7 @@ ConfigDialog::ConfigDialog (wxWindow* parent) _language->Append (wxT ("Français")); _language->Append (wxT ("Italiano")); _language->Append (wxT ("Español")); + _language->Append (wxT ("Svenska")); table->Add (_language, 1, wxEXPAND); table->AddSpacer (0); @@ -158,6 +159,8 @@ ConfigDialog::ConfigDialog (wxWindow* parent) _language->SetSelection (2); } else if (config->language().get_value_or ("") == "es") { _language->SetSelection (3); + } else if (config->language().get_value_or ("") == "sv") { + _language->SetSelection (4); } else { _language->SetSelection (0); } @@ -234,6 +237,9 @@ ConfigDialog::language_changed (wxCommandEvent &) case 3: Config::instance()->set_language ("es"); break; + case 4: + Config::instance()->set_language ("sv"); + break; } } diff --git a/src/wx/po/sv_SE.po b/src/wx/po/sv_SE.po new file mode 100644 index 000000000..6519c5baf --- /dev/null +++ b/src/wx/po/sv_SE.po @@ -0,0 +1,494 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: DVD-o-matic\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-03-26 14:07+0000\n" +"PO-Revision-Date: 2013-03-28 10:44+0100\n" +"Last-Translator: Adam Klotblixt \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.5.5\n" + +#: src/wx/film_editor.cc:440 +msgid "%" +msgstr "%" + +#: src/wx/config_dialog.cc:60 +msgid "(restart DVD-o-matic to see language changes)" +msgstr "(starta om DVD-o-matic för att se språkändringar)" + +#: src/wx/film_editor.cc:1231 +msgid "1 channel" +msgstr "1 kanal" + +#: src/wx/film_editor.cc:184 +msgid "A/B" +msgstr "A/B" + +#: src/wx/config_dialog.cc:142 +msgid "Add" +msgstr "Lägg till" + +#: src/wx/audio_dialog.cc:32 +#: src/wx/film_editor.cc:77 +msgid "Audio" +msgstr "Audio" + +#: src/wx/film_editor.cc:381 +msgid "Audio Delay" +msgstr "Audio Fördröjning" + +#: src/wx/film_editor.cc:369 +msgid "Audio Gain" +msgstr "Audio Volym" + +#: src/wx/dci_metadata_dialog.cc:33 +msgid "Audio Language (e.g. EN)" +msgstr "Audio Språk (ex. SV)" + +#: src/wx/job_wrapper.cc:38 +#, c-format +msgid "Bad setting for %s (%s)" +msgstr "Felaktig inställning för %s (%s)" + +#: src/wx/film_editor.cc:296 +msgid "Bottom crop" +msgstr "Nedre beskärning" + +#: src/wx/dir_picker_ctrl.cc:38 +msgid "Browse..." +msgstr "Bläddra..." + +# vad åsyftas med "fader"? +#: src/wx/gain_calculator_dialog.cc:36 +#, fuzzy +msgid "But I have to use fader" +msgstr "Men jag måste använda toning" + +#: src/wx/film_editor.cc:374 +msgid "Calculate..." +msgstr "Beräkna..." + +#: src/wx/job_manager_view.cc:88 +msgid "Cancel" +msgstr "Avbryt" + +#: src/wx/audio_dialog.cc:43 +msgid "Channels" +msgstr "Kanaler" + +#: src/wx/film_editor.cc:325 +msgid "Colour look-up table" +msgstr "Färguppslagningstabell" + +#: src/wx/film_editor.cc:120 +msgid "Content" +msgstr "Innehåll" + +#: src/wx/film_editor.cc:130 +msgid "Content Type" +msgstr "Innehållstyp" + +#: src/wx/film_viewer.cc:414 +#, c-format +msgid "Could not decode video for view (%s)" +msgstr "Kunde inte avkoda video för visning (%s)" + +#: src/wx/job_wrapper.cc:40 +#, c-format +msgid "Could not make DCP: %s" +msgstr "Kunde inte skapa DCP: %s" + +#: src/wx/film_viewer.cc:108 +#, c-format +msgid "Could not open content file (%s)" +msgstr "Kunde inte öppna innehållsfilen (%s)" + +#: src/wx/film_editor.cc:504 +#, c-format +msgid "Could not set content: %s" +msgstr "Kunde inte fastställa innehåll: %s" + +#: src/wx/new_film_dialog.cc:46 +msgid "Create in folder" +msgstr "Skapa i katalog" + +#: src/wx/dci_metadata_dialog.cc:28 +msgid "DCI name" +msgstr "DCI namn" + +#: src/wx/film_editor.cc:141 +msgid "DCP Frame Rate" +msgstr "DCP bildhastighet" + +#: src/wx/film_editor.cc:109 +msgid "DCP Name" +msgstr "DCP Namn" + +#: src/wx/wx_util.cc:61 +msgid "DVD-o-matic" +msgstr "DVD-o-matic" + +#: src/wx/config_dialog.cc:44 +msgid "DVD-o-matic Preferences" +msgstr "DVD-o-matic Inställningar" + +#: src/wx/audio_dialog.cc:101 +msgid "DVD-o-matic audio - %1" +msgstr "DVD-o-matic audio - %1" + +#: src/wx/config_dialog.cc:101 +msgid "Default DCI name details" +msgstr "Detaljer om förvalda DCI-namn" + +#: src/wx/config_dialog.cc:92 +msgid "Default directory for new films" +msgstr "Förvald katalog för nya filmer" + +#: src/wx/film_editor.cc:116 +#: src/wx/job_manager_view.cc:92 +msgid "Details..." +msgstr "Detaljer..." + +#: src/wx/properties_dialog.cc:45 +msgid "Disk space required" +msgstr "Diskutrymme som krävs" + +#: src/wx/film_editor.cc:191 +msgid "Duration" +msgstr "Längd" + +#: src/wx/config_dialog.cc:144 +msgid "Edit" +msgstr "Redigera" + +#: src/wx/config_dialog.cc:102 +#: src/wx/config_dialog.cc:121 +#: src/wx/film_editor.cc:308 +msgid "Edit..." +msgstr "Redigera..." + +#: src/wx/config_dialog.cc:127 +msgid "Encoding Servers" +msgstr "Kodningsservrar" + +#: src/wx/film_editor.cc:176 +msgid "End" +msgstr "Slut" + +# vad betyder "facility" i detta sammanhang? +#: src/wx/dci_metadata_dialog.cc:53 +#, fuzzy +msgid "Facility (e.g. DLA)" +msgstr "Enhet (ex. DLA)" + +#: src/wx/film_editor.cc:73 +msgid "Film" +msgstr "Film" + +#: src/wx/properties_dialog.cc:36 +msgid "Film Properties" +msgstr "Film Egenskaper" + +#: src/wx/new_film_dialog.cc:42 +msgid "Film name" +msgstr "film namn" + +#: src/wx/film_editor.cc:303 +#: src/wx/filter_dialog.cc:32 +msgid "Filters" +msgstr "Filter" + +#: src/wx/film_editor.cc:268 +msgid "Format" +msgstr "Format" + +#: src/wx/properties_dialog.cc:41 +msgid "Frames" +msgstr "Bildrutor" + +#: src/wx/properties_dialog.cc:49 +msgid "Frames already encoded" +msgstr "Bildrutor redan kodade" + +#: src/wx/gain_calculator_dialog.cc:27 +msgid "Gain Calculator" +msgstr "Volym Kalkylator" + +#: src/wx/properties_dialog.cc:59 +msgid "Gb" +msgstr "Gb" + +#: src/wx/server_dialog.cc:36 +msgid "Host name or IP address" +msgstr "Värd-namn eller IP-adress" + +#: src/wx/film_editor.cc:1235 +msgid "Hz" +msgstr "Hz" + +# vad åsyftas med "fader"? +#: src/wx/gain_calculator_dialog.cc:32 +#, fuzzy +msgid "I want to play this back at fader" +msgstr "Jag vill spela upp detta med toning" + +#: src/wx/config_dialog.cc:131 +msgid "IP address" +msgstr "IP-adress" + +#: src/wx/film_editor.cc:335 +msgid "JPEG2000 bandwidth" +msgstr "JPEG2000 bandbredd" + +#: src/wx/film_editor.cc:281 +msgid "Left crop" +msgstr "Vänster beskärning" + +#: src/wx/film_editor.cc:164 +msgid "Length" +msgstr "Längd" + +#: src/wx/film_editor.cc:339 +msgid "MBps" +msgstr "MBps" + +#: src/wx/dir_picker_ctrl.cc:52 +msgid "My Documents" +msgstr "Mina Dokument" + +#: src/wx/film_editor.cc:104 +msgid "Name" +msgstr "Namn" + +#: src/wx/new_film_dialog.cc:33 +msgid "New Film" +msgstr "Ny Film" + +#: src/wx/film_editor.cc:305 +#: src/wx/film_editor.cc:664 +msgid "None" +msgstr "Inget" + +#: src/wx/film_editor.cc:135 +msgid "Original Frame Rate" +msgstr "Ursprunglig bildhastighet" + +#: src/wx/film_editor.cc:159 +msgid "Original Size" +msgstr "Ursprunglig Storlek" + +#: src/wx/dci_metadata_dialog.cc:57 +msgid "Package Type (e.g. OV)" +msgstr "Förpackningstyp (ex. OV)" + +#: src/wx/audio_dialog.cc:60 +msgid "Peak" +msgstr "Topp" + +#: src/wx/film_viewer.cc:54 +msgid "Play" +msgstr "Spela" + +#: src/wx/audio_plot.cc:109 +msgid "Please wait; audio is being analysed..." +msgstr "Vänligen vänta; audio analyseras..." + +#: src/wx/audio_dialog.cc:61 +msgid "RMS" +msgstr "RMS" + +# Är det censurklassning som åsyftas? +#: src/wx/dci_metadata_dialog.cc:45 +#, fuzzy +msgid "Rating (e.g. 15)" +msgstr "Klassificering (ex. 15)" + +#: src/wx/config_dialog.cc:117 +msgid "Reference filters for A/B" +msgstr "Referensfilter för A/B" + +#: src/wx/config_dialog.cc:106 +msgid "Reference scaler for A/B" +msgstr "Referensomskalare för A/B" + +#: src/wx/config_dialog.cc:146 +msgid "Remove" +msgstr "Ta bort" + +#: src/wx/film_editor.cc:286 +msgid "Right crop" +msgstr "Höger beskärning" + +#: src/wx/job_manager_view.cc:108 +msgid "Running" +msgstr "Körs" + +#: src/wx/film_editor.cc:315 +msgid "Scaler" +msgstr "Omskalare" + +#: src/wx/film_editor.cc:407 +msgid "Select Audio File" +msgstr "Välj audiofil" + +#: src/wx/film_editor.cc:121 +msgid "Select Content File" +msgstr "Välj innehållsfil" + +#: src/wx/server_dialog.cc:25 +msgid "Server" +msgstr "Server" + +#: src/wx/config_dialog.cc:49 +msgid "Set language" +msgstr "Välj språk" + +#: src/wx/film_editor.cc:364 +msgid "Show Audio..." +msgstr "Visa Audio..." + +#: src/wx/audio_dialog.cc:71 +msgid "Smoothing" +msgstr "Utjämning" + +#: src/wx/film_editor.cc:173 +msgid "Start" +msgstr "Start" + +#: src/wx/dci_metadata_dialog.cc:49 +msgid "Studio (e.g. TCF)" +msgstr "Studio (ex. TCF)" + +#: src/wx/dci_metadata_dialog.cc:37 +msgid "Subtitle Language (e.g. FR)" +msgstr "Undertextspråk (ex. SV)" + +#: src/wx/film_editor.cc:431 +msgid "Subtitle Offset" +msgstr "Undertext Förskjutning" + +#: src/wx/film_editor.cc:436 +msgid "Subtitle Scale" +msgstr "Undertext Skalning" + +#: src/wx/film_editor.cc:79 +msgid "Subtitles" +msgstr "Undertexter" + +#: src/wx/config_dialog.cc:67 +msgid "TMS IP address" +msgstr "TMS IP-adress" + +#: src/wx/config_dialog.cc:82 +msgid "TMS password" +msgstr "TMS lösenord" + +#: src/wx/config_dialog.cc:72 +msgid "TMS target path" +msgstr "TMS målsökväg" + +#: src/wx/config_dialog.cc:77 +msgid "TMS user name" +msgstr "TMS användarnamn" + +#: src/wx/dci_metadata_dialog.cc:41 +msgid "Territory (e.g. UK)" +msgstr "Område (ex. SV)" + +#: src/wx/config_dialog.cc:135 +msgid "Threads" +msgstr "Trådar" + +#: src/wx/server_dialog.cc:40 +msgid "Threads to use" +msgstr "Antal trådar att använda" + +#: src/wx/config_dialog.cc:87 +msgid "Threads to use for encoding on this host" +msgstr "Antal trådar att använda vid kodning på denna maskin" + +#: src/wx/audio_plot.cc:139 +msgid "Time" +msgstr "Tid" + +#: src/wx/film_editor.cc:291 +msgid "Top crop" +msgstr "Övre beskärning" + +#: src/wx/film_editor.cc:171 +msgid "Trim frames" +msgstr "Beskära bilder" + +#: src/wx/film_editor.cc:125 +#, fuzzy +msgid "Trust content's header" +msgstr "Lita på innehållets information" + +#: src/wx/audio_dialog.cc:55 +msgid "Type" +msgstr "Typ" + +#: src/wx/film_editor.cc:114 +msgid "Use DCI name" +msgstr "Använd DCI-namnet" + +#: src/wx/film_editor.cc:145 +msgid "Use best" +msgstr "Använd bästa" + +#: src/wx/film_editor.cc:391 +msgid "Use content's audio" +msgstr "Använd innehållets audio" + +#: src/wx/film_editor.cc:401 +msgid "Use external audio" +msgstr "Använd extern audio" + +#: src/wx/film_editor.cc:75 +msgid "Video" +msgstr "Video" + +#: src/wx/film_editor.cc:424 +msgid "With Subtitles" +msgstr "Med Undertexter" + +#: src/wx/film_editor.cc:1233 +msgid "channels" +msgstr "kanaler" + +#: src/wx/properties_dialog.cc:50 +msgid "counting..." +msgstr "räknar..." + +#: src/wx/film_editor.cc:373 +msgid "dB" +msgstr "dB" + +#: src/wx/film_editor.cc:691 +#: src/wx/film_editor.cc:694 +msgid "frames" +msgstr "bilder" + +#. / TRANSLATORS: this is an abbreviation for milliseconds, the unit of time +#: src/wx/film_editor.cc:386 +msgid "ms" +msgstr "ms" + +#. / TRANSLATORS: `s' here is an abbreviation for seconds, the unit of time +#: src/wx/film_editor.cc:197 +msgid "s" +msgstr "s" + +#: src/wx/properties_dialog.cc:62 +#: src/wx/properties_dialog.cc:63 +msgid "unknown" +msgstr "okänt" + -- cgit v1.2.3 From fe7da4f122aaf96a869226c57b8e935ca28eee49 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 28 Mar 2013 10:35:39 +0000 Subject: pot_merge. --- src/lib/po/es_ES.po | 30 +++++++------- src/lib/po/fr_FR.po | 30 +++++++------- src/lib/po/it_IT.po | 30 +++++++------- src/lib/po/sv_SE.po | 109 ++++++++++++++++++++++++++++---------------------- src/tools/po/es_ES.po | 17 +++++--- src/tools/po/fr_FR.po | 17 +++++--- src/tools/po/it_IT.po | 17 +++++--- src/tools/po/sv_SE.po | 28 ++++++++----- src/wx/po/es_ES.po | 37 ++++++++--------- src/wx/po/fr_FR.po | 37 ++++++++--------- src/wx/po/it_IT.po | 37 ++++++++--------- src/wx/po/sv_SE.po | 60 +++++++++++++-------------- 12 files changed, 241 insertions(+), 208 deletions(-) (limited to 'src') diff --git a/src/lib/po/es_ES.po b/src/lib/po/es_ES.po index a25c1fe2b..22a70f813 100644 --- a/src/lib/po/es_ES.po +++ b/src/lib/po/es_ES.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: LIBDVDOMATIC\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-26 14:54+0000\n" +"POT-Creation-Date: 2013-03-28 10:35+0000\n" "PO-Revision-Date: 2013-03-23 22:42-0500\n" "Last-Translator: Manuel AC \n" "Language-Team: Manuel AC \n" @@ -102,7 +102,7 @@ msgid "Cannot resample audio as libswresample is not present" msgstr "" "No se puede redimensionar el sonido porque no se encuentra libswresample" -#: src/lib/util.cc:922 +#: src/lib/util.cc:931 msgid "Centre" msgstr "" @@ -134,15 +134,15 @@ msgstr "No se pudo escribir el fichero remoto (%1)" msgid "Cubic interpolating deinterlacer" msgstr "Desentrelazado por interpolación cúbica" -#: src/lib/util.cc:997 +#: src/lib/util.cc:1006 msgid "DCP and source have the same rate.\n" msgstr "La fuente y el DCP tienen la misma velocidad.\n" -#: src/lib/util.cc:1007 +#: src/lib/util.cc:1016 msgid "DCP will run at %1%% of the source speed." msgstr "El DCP se reproducirá al %1%% de la velocidad de la fuente." -#: src/lib/util.cc:1000 +#: src/lib/util.cc:1009 msgid "DCP will use every other frame of the source.\n" msgstr "El DCP usará fotogramas alternos de la fuente.\n" @@ -165,7 +165,7 @@ msgstr "" msgid "Dolby CP750" msgstr "Dolby CP750" -#: src/lib/util.cc:1002 +#: src/lib/util.cc:1011 msgid "Each source frame will be doubled in the DCP.\n" msgstr "Se doblará cada fotograma de la fuente en el DCP.\n" @@ -257,15 +257,15 @@ msgstr "" msgid "Lanczos" msgstr "Lanczos" -#: src/lib/util.cc:920 +#: src/lib/util.cc:929 msgid "Left" msgstr "" -#: src/lib/util.cc:924 +#: src/lib/util.cc:933 msgid "Left surround" msgstr "" -#: src/lib/util.cc:923 +#: src/lib/util.cc:932 msgid "Lfe (sub)" msgstr "" @@ -315,15 +315,15 @@ msgstr "Anuncio de servicio público" msgid "Rating" msgstr "Clasificación" -#: src/lib/util.cc:490 +#: src/lib/util.cc:499 msgid "Rec 709" msgstr "Rec 709" -#: src/lib/util.cc:921 +#: src/lib/util.cc:930 msgid "Right" msgstr "" -#: src/lib/util.cc:925 +#: src/lib/util.cc:934 msgid "Right surround" msgstr "" @@ -475,7 +475,7 @@ msgstr "" msgid "cannot contain slashes" msgstr "no puede contener barras" -#: src/lib/util.cc:531 +#: src/lib/util.cc:540 msgid "connect timed out" msgstr "tiempo de conexión agotado" @@ -583,7 +583,7 @@ msgstr "minuto" msgid "minutes" msgstr "minutos" -#: src/lib/util.cc:674 +#: src/lib/util.cc:683 msgid "missing key %1 in key-value set" msgstr "falta la clave %1 en el par clave-valor" @@ -613,7 +613,7 @@ msgstr "todavía no se soportan subtítulos que no son en mapas de bits" msgid "remaining" msgstr "pendiente" -#: src/lib/util.cc:488 +#: src/lib/util.cc:497 msgid "sRGB" msgstr "sRGB" diff --git a/src/lib/po/fr_FR.po b/src/lib/po/fr_FR.po index 640d6dc71..f14cdafa1 100644 --- a/src/lib/po/fr_FR.po +++ b/src/lib/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-26 14:54+0000\n" +"POT-Creation-Date: 2013-03-28 10:35+0000\n" "PO-Revision-Date: 2013-03-20 00:39+0100\n" "Last-Translator: FreeDCP.net \n" "Language-Team: \n" @@ -100,7 +100,7 @@ msgstr "" msgid "Cannot resample audio as libswresample is not present" msgstr "Ré-échantillonnage du son impossible : libswresample est absent" -#: src/lib/util.cc:922 +#: src/lib/util.cc:931 msgid "Centre" msgstr "" @@ -132,15 +132,15 @@ msgstr "Écriture vers fichier distant (%1) impossible" msgid "Cubic interpolating deinterlacer" msgstr "Désentrelacement cubique interpolé" -#: src/lib/util.cc:997 +#: src/lib/util.cc:1006 msgid "DCP and source have the same rate.\n" msgstr "Le DCP et la source ont les mêmes cadences.\n" -#: src/lib/util.cc:1007 +#: src/lib/util.cc:1016 msgid "DCP will run at %1%% of the source speed." msgstr "La cadence du DCP sera %1%% par rapport à la source" -#: src/lib/util.cc:1000 +#: src/lib/util.cc:1009 msgid "DCP will use every other frame of the source.\n" msgstr "Le DCP utilisera une image sur deux de la source.\n" @@ -163,7 +163,7 @@ msgstr "Filtre anti bourdonnement" msgid "Dolby CP750" msgstr "Dolby CP750" -#: src/lib/util.cc:1002 +#: src/lib/util.cc:1011 msgid "Each source frame will be doubled in the DCP.\n" msgstr "Chaque image source sera dupliquée dans le DCP.\n" @@ -255,15 +255,15 @@ msgstr "Désentrelaceur noyau" msgid "Lanczos" msgstr "Lanczos" -#: src/lib/util.cc:920 +#: src/lib/util.cc:929 msgid "Left" msgstr "Gauche" -#: src/lib/util.cc:924 +#: src/lib/util.cc:933 msgid "Left surround" msgstr "Arrière gauche" -#: src/lib/util.cc:923 +#: src/lib/util.cc:932 msgid "Lfe (sub)" msgstr "Basses fréquences" @@ -313,15 +313,15 @@ msgstr "Public Service Announcement" msgid "Rating" msgstr "Classification" -#: src/lib/util.cc:490 +#: src/lib/util.cc:499 msgid "Rec 709" msgstr "Rec 709" -#: src/lib/util.cc:921 +#: src/lib/util.cc:930 msgid "Right" msgstr "Droite" -#: src/lib/util.cc:925 +#: src/lib/util.cc:934 msgid "Right surround" msgstr "Arrière droite" @@ -473,7 +473,7 @@ msgstr "Un autre filtre de désentrelacement" msgid "cannot contain slashes" msgstr "slash interdit" -#: src/lib/util.cc:531 +#: src/lib/util.cc:540 msgid "connect timed out" msgstr "temps de connexion expiré" @@ -577,7 +577,7 @@ msgstr "minute" msgid "minutes" msgstr "minutes" -#: src/lib/util.cc:674 +#: src/lib/util.cc:683 msgid "missing key %1 in key-value set" msgstr "clé %1 non sélectionnée" @@ -607,7 +607,7 @@ msgstr "sous-titres non-bitmap non supportés actuellement" msgid "remaining" msgstr "restant" -#: src/lib/util.cc:488 +#: src/lib/util.cc:497 msgid "sRGB" msgstr "sRGB" diff --git a/src/lib/po/it_IT.po b/src/lib/po/it_IT.po index 67f8f4c45..6de01e576 100644 --- a/src/lib/po/it_IT.po +++ b/src/lib/po/it_IT.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-26 14:54+0000\n" +"POT-Creation-Date: 2013-03-28 10:35+0000\n" "PO-Revision-Date: 2013-03-20 11:45+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" @@ -101,7 +101,7 @@ msgstr "" msgid "Cannot resample audio as libswresample is not present" msgstr "Non posso ricampionare l'audio perchè libswresample non è presente" -#: src/lib/util.cc:922 +#: src/lib/util.cc:931 msgid "Centre" msgstr "" @@ -133,15 +133,15 @@ msgstr "Non posso scrivere il file remoto (%1)" msgid "Cubic interpolating deinterlacer" msgstr "Deinterlacciatore cubico interpolato" -#: src/lib/util.cc:997 +#: src/lib/util.cc:1006 msgid "DCP and source have the same rate.\n" msgstr "Il DCP e il sorgente hanno la stessa frequenza.\n" -#: src/lib/util.cc:1007 +#: src/lib/util.cc:1016 msgid "DCP will run at %1%% of the source speed." msgstr "Il DCP andrà al %1%% della velocità del sorgente." -#: src/lib/util.cc:1000 +#: src/lib/util.cc:1009 msgid "DCP will use every other frame of the source.\n" msgstr "Il DCP userà ogni altro fotogramma del sorgente.\n" @@ -164,7 +164,7 @@ msgstr "Filtro deringing" msgid "Dolby CP750" msgstr "Dolby CP750" -#: src/lib/util.cc:1002 +#: src/lib/util.cc:1011 msgid "Each source frame will be doubled in the DCP.\n" msgstr "Ogni fotogramma del sorgente sarà raddoppiato nel DCP.\n" @@ -256,15 +256,15 @@ msgstr "Deinterlacciatore Kernel" msgid "Lanczos" msgstr "Lanczos" -#: src/lib/util.cc:920 +#: src/lib/util.cc:929 msgid "Left" msgstr "" -#: src/lib/util.cc:924 +#: src/lib/util.cc:933 msgid "Left surround" msgstr "" -#: src/lib/util.cc:923 +#: src/lib/util.cc:932 msgid "Lfe (sub)" msgstr "" @@ -314,15 +314,15 @@ msgstr "Annuncio di pubblico servizio" msgid "Rating" msgstr "Punteggio" -#: src/lib/util.cc:490 +#: src/lib/util.cc:499 msgid "Rec 709" msgstr "Rec 709" -#: src/lib/util.cc:921 +#: src/lib/util.cc:930 msgid "Right" msgstr "" -#: src/lib/util.cc:925 +#: src/lib/util.cc:934 msgid "Right surround" msgstr "" @@ -474,7 +474,7 @@ msgstr "Ancora un altro filtro di deinterlacciamento" msgid "cannot contain slashes" msgstr "non può contenere barre" -#: src/lib/util.cc:531 +#: src/lib/util.cc:540 msgid "connect timed out" msgstr "connessione scaduta" @@ -582,7 +582,7 @@ msgstr "minuto" msgid "minutes" msgstr "minuti" -#: src/lib/util.cc:674 +#: src/lib/util.cc:683 msgid "missing key %1 in key-value set" msgstr "persa la chiave %1 tra i valori chiave" @@ -612,7 +612,7 @@ msgstr "sottotitoli non-bitmap non ancora supportati" msgid "remaining" msgstr "restano" -#: src/lib/util.cc:488 +#: src/lib/util.cc:497 msgid "sRGB" msgstr "sRGB" diff --git a/src/lib/po/sv_SE.po b/src/lib/po/sv_SE.po index 23c133a81..151e3ef58 100644 --- a/src/lib/po/sv_SE.po +++ b/src/lib/po/sv_SE.po @@ -7,10 +7,11 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-26 14:07+0000\n" +"POT-Creation-Date: 2013-03-28 10:35+0000\n" "PO-Revision-Date: 2013-03-28 10:40+0100\n" "Last-Translator: Adam Klotblixt \n" "Language-Team: \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -98,7 +99,12 @@ msgstr "Kan inte hantera pixelformat %1 under %2" #: src/lib/encoder.cc:101 msgid "Cannot resample audio as libswresample is not present" -msgstr "Kan inte omsampla ljudet eftersom libswresample inte finns tillgängligt" +msgstr "" +"Kan inte omsampla ljudet eftersom libswresample inte finns tillgängligt" + +#: src/lib/util.cc:931 +msgid "Centre" +msgstr "" #: src/lib/scp_dcp_job.cc:109 msgid "Copy DCP to TMS" @@ -128,36 +134,26 @@ msgstr "Kunde inte skriva till fjärrfil (%1)" msgid "Cubic interpolating deinterlacer" msgstr "Kubiskt interpolerande avflätare" -#: src/lib/util.cc:997 +#: src/lib/util.cc:1006 msgid "DCP and source have the same rate.\n" msgstr "DCP och källa har samma bildfrekvens.\n" -#: src/lib/util.cc:1007 +#: src/lib/util.cc:1016 msgid "DCP will run at %1%% of the source speed." msgstr "DCP kommer att köras på %1%% av källans hastighet." -#: src/lib/util.cc:1000 +#: src/lib/util.cc:1009 msgid "DCP will use every other frame of the source.\n" msgstr "DCP kommer att använda varannan bild från källan.\n" -#: src/lib/filter.cc:68 -#: src/lib/filter.cc:69 -#: src/lib/filter.cc:70 -#: src/lib/filter.cc:71 -#: src/lib/filter.cc:72 -#: src/lib/filter.cc:73 +#: src/lib/filter.cc:68 src/lib/filter.cc:69 src/lib/filter.cc:70 +#: src/lib/filter.cc:71 src/lib/filter.cc:72 src/lib/filter.cc:73 msgid "De-blocking" msgstr "Kantighetsutjämning" -#: src/lib/filter.cc:75 -#: src/lib/filter.cc:76 -#: src/lib/filter.cc:77 -#: src/lib/filter.cc:78 -#: src/lib/filter.cc:79 -#: src/lib/filter.cc:80 -#: src/lib/filter.cc:81 -#: src/lib/filter.cc:82 -#: src/lib/filter.cc:83 +#: src/lib/filter.cc:75 src/lib/filter.cc:76 src/lib/filter.cc:77 +#: src/lib/filter.cc:78 src/lib/filter.cc:79 src/lib/filter.cc:80 +#: src/lib/filter.cc:81 src/lib/filter.cc:82 src/lib/filter.cc:83 msgid "De-interlacing" msgstr "Avflätning" @@ -171,7 +167,7 @@ msgstr "Avringningsfilter" msgid "Dolby CP750" msgstr "Dolby CP750" -#: src/lib/util.cc:1002 +#: src/lib/util.cc:1011 msgid "Each source frame will be doubled in the DCP.\n" msgstr "Varje bild från källan kommer att användas två gånger i DCPn.\n" @@ -247,10 +243,13 @@ msgstr "Filter för horisontal kantighetsutjämning" msgid "Horizontal deblocking filter A" msgstr "Filter för horisontal kantighetsutjämning A" -#: src/lib/job.cc:92 -#: src/lib/job.cc:101 -msgid "It is not known what caused this error. The best idea is to report the problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" -msgstr "Det är inte känt vad som orsakade detta fel. Bästa sättet att rapportera problemet är till DVD-o-matics mejl-lista (dvdomatic@carlh.net)" +#: src/lib/job.cc:92 src/lib/job.cc:101 +msgid "" +"It is not known what caused this error. The best idea is to report the " +"problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" +msgstr "" +"Det är inte känt vad som orsakade detta fel. Bästa sättet att rapportera " +"problemet är till DVD-o-matics mejl-lista (dvdomatic@carlh.net)" #: src/lib/filter.cc:82 msgid "Kernel deinterlacer" @@ -260,6 +259,18 @@ msgstr "Kernel-avflätare" msgid "Lanczos" msgstr "Lanczos" +#: src/lib/util.cc:929 +msgid "Left" +msgstr "" + +#: src/lib/util.cc:933 +msgid "Left surround" +msgstr "" + +#: src/lib/util.cc:932 +msgid "Lfe (sub)" +msgstr "" + #: src/lib/filter.cc:75 msgid "Linear blend deinterlacer" msgstr "Linjär blandningsavflätare" @@ -272,11 +283,8 @@ msgstr "Linjär interpolationsavflätare" msgid "Median deinterlacer" msgstr "Median-avflätare" -#: src/lib/filter.cc:74 -#: src/lib/filter.cc:85 -#: src/lib/filter.cc:86 -#: src/lib/filter.cc:87 -#: src/lib/filter.cc:90 +#: src/lib/filter.cc:74 src/lib/filter.cc:85 src/lib/filter.cc:86 +#: src/lib/filter.cc:87 src/lib/filter.cc:90 msgid "Misc" msgstr "Diverse" @@ -284,9 +292,7 @@ msgstr "Diverse" msgid "Motion compensating deinterlacer" msgstr "Rörelsekompenserande avflätare" -#: src/lib/filter.cc:84 -#: src/lib/filter.cc:88 -#: src/lib/filter.cc:89 +#: src/lib/filter.cc:84 src/lib/filter.cc:88 src/lib/filter.cc:89 #: src/lib/filter.cc:91 msgid "Noise reduction" msgstr "Brusreducering" @@ -311,10 +317,18 @@ msgstr "Offentligt Servicemeddelande" msgid "Rating" msgstr "Klassificering" -#: src/lib/util.cc:490 +#: src/lib/util.cc:499 msgid "Rec 709" msgstr "Rec 709" +#: src/lib/util.cc:930 +msgid "Right" +msgstr "" + +#: src/lib/util.cc:934 +msgid "Right surround" +msgstr "" + #: src/lib/scp_dcp_job.cc:133 msgid "SSH error (%1)" msgstr "SSH fel (%1)" @@ -385,7 +399,8 @@ msgstr "Källan skalad för att rymmas inom Flat utan att ändra bildförhållan #: src/lib/format.cc:136 msgid "Source scaled to fit Scope preserving its aspect ratio" -msgstr "Källan skalad för att rymmas inom Scope utan att ändra bildförhållandet" +msgstr "" +"Källan skalad för att rymmas inom Scope utan att ändra bildförhållandet" #: src/lib/scaler.cc:68 msgid "Spline" @@ -410,8 +425,12 @@ msgid "Test" msgstr "Test" #: src/lib/job.cc:77 -msgid "The drive that the film is stored on is low in disc space. Free some more space and try again." -msgstr "Enheten som filmen lagras på har för lite ledigt utrymme. Frigör utrymme och försök igen." +msgid "" +"The drive that the film is stored on is low in disc space. Free some more " +"space and try again." +msgstr "" +"Enheten som filmen lagras på har för lite ledigt utrymme. Frigör utrymme och " +"försök igen." #: src/lib/dcp_content_type.cc:46 msgid "Trailer" @@ -466,7 +485,7 @@ msgid "cannot contain slashes" msgstr "får inte innehålla snedstreck" # mer svengelska -#: src/lib/util.cc:531 +#: src/lib/util.cc:540 #, fuzzy msgid "connect timed out" msgstr "uppkopplingen tajmade ur" @@ -523,8 +542,7 @@ msgstr "kunde inte öppna fil för läsning" msgid "could not read from file %1 (%2)" msgstr "kunde inte läsa från fil %1 (%2)" -#: src/lib/encoder.cc:137 -#: src/lib/encoder.cc:314 +#: src/lib/encoder.cc:137 src/lib/encoder.cc:314 msgid "could not run sample-rate converter" msgstr "kunde inte köra sampelhastighetskonverteraren" @@ -560,8 +578,7 @@ msgstr "bilder per sekund" msgid "hour" msgstr "timme" -#: src/lib/util.cc:112 -#: src/lib/util.cc:117 +#: src/lib/util.cc:112 src/lib/util.cc:117 msgid "hours" msgstr "timmar" @@ -573,7 +590,7 @@ msgstr "minut" msgid "minutes" msgstr "minuter" -#: src/lib/util.cc:674 +#: src/lib/util.cc:683 msgid "missing key %1 in key-value set" msgstr "saknad nyckel %1 i nyckel-värde grupp" @@ -585,8 +602,7 @@ msgstr "saknad nödvändig inställning %1" msgid "multi-part subtitles not yet supported" msgstr "undertexter i flera delar stöds inte ännu" -#: src/lib/film.cc:263 -#: src/lib/film.cc:308 +#: src/lib/film.cc:263 src/lib/film.cc:308 msgid "name" msgstr "namn" @@ -604,7 +620,7 @@ msgstr "icke-rastergrafiska undertexter stöds inte ännu" msgid "remaining" msgstr "återstående tid" -#: src/lib/util.cc:488 +#: src/lib/util.cc:497 msgid "sRGB" msgstr "sRGB" @@ -619,4 +635,3 @@ msgstr "stillbild" #: src/lib/film.cc:274 msgid "video" msgstr "video" - diff --git a/src/tools/po/es_ES.po b/src/tools/po/es_ES.po index 23b2c9cdc..cf6f2b889 100644 --- a/src/tools/po/es_ES.po +++ b/src/tools/po/es_ES.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVDOMATIC\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-26 14:54+0000\n" +"POT-Creation-Date: 2013-03-28 10:35+0000\n" "PO-Revision-Date: 2013-03-23 21:08-0500\n" "Last-Translator: Manuel AC \n" "Language-Team: Manuel AC \n" @@ -75,8 +75,9 @@ msgstr "" msgid "About" msgstr "Acerca de" -#: src/tools/dvdomatic.cc:516 -msgid "Could not load film %s (%s)" +#: src/tools/dvdomatic.cc:517 +#, fuzzy +msgid "Could not load film %1 (%2)" msgstr "No se pudo cargar la película %s (%s)" #: src/tools/dvdomatic.cc:331 @@ -85,7 +86,7 @@ msgid "Could not open film at %s (%s)" msgstr "No se pudo cargar la película en %s (%s)" #: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:402 -#: src/tools/dvdomatic.cc:520 +#: src/tools/dvdomatic.cc:521 msgid "DVD-o-matic" msgstr "DVD-o-matic" @@ -107,11 +108,15 @@ msgstr "Nuevo..." msgid "S&how DCP" msgstr "&Mostrar DCP" +#: src/tools/dvdomatic.cc:74 +msgid "Save changes to film \"%1\" before closing?" +msgstr "" + #: src/tools/dvdomatic.cc:319 msgid "Select film to open" msgstr "Selecciona la película a abrir" #: src/tools/dvdomatic.cc:303 -#, c-format -msgid "The directory %s already exists." +#, fuzzy +msgid "The directory %1 already exists." msgstr "La carpeta %s ya existe." diff --git a/src/tools/po/fr_FR.po b/src/tools/po/fr_FR.po index b0c46117d..a9a4a2ae7 100644 --- a/src/tools/po/fr_FR.po +++ b/src/tools/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-26 14:54+0000\n" +"POT-Creation-Date: 2013-03-28 10:35+0000\n" "PO-Revision-Date: 2013-03-13 22:33+0100\n" "Last-Translator: \n" "Language-Team: \n" @@ -74,8 +74,9 @@ msgstr "" msgid "About" msgstr "A Propos" -#: src/tools/dvdomatic.cc:516 -msgid "Could not load film %s (%s)" +#: src/tools/dvdomatic.cc:517 +#, fuzzy +msgid "Could not load film %1 (%2)" msgstr "Impossible de charger le film %s (%s)" #: src/tools/dvdomatic.cc:331 @@ -84,7 +85,7 @@ msgid "Could not open film at %s (%s)" msgstr "Impossible d'ouvrir le film à %s (%s)" #: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:402 -#: src/tools/dvdomatic.cc:520 +#: src/tools/dvdomatic.cc:521 msgid "DVD-o-matic" msgstr "DVD-o-matic" @@ -104,11 +105,15 @@ msgstr "Nouveau..." msgid "S&how DCP" msgstr "Voir le DCP" +#: src/tools/dvdomatic.cc:74 +msgid "Save changes to film \"%1\" before closing?" +msgstr "" + #: src/tools/dvdomatic.cc:319 msgid "Select film to open" msgstr "Sélectionner le film à ouvrir" #: src/tools/dvdomatic.cc:303 -#, c-format -msgid "The directory %s already exists." +#, fuzzy +msgid "The directory %1 already exists." msgstr "Le dossier %s existe déjà." diff --git a/src/tools/po/it_IT.po b/src/tools/po/it_IT.po index 906653093..a1fc9e403 100644 --- a/src/tools/po/it_IT.po +++ b/src/tools/po/it_IT.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-26 14:54+0000\n" +"POT-Creation-Date: 2013-03-28 10:35+0000\n" "PO-Revision-Date: 2013-03-22 18:03+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" @@ -75,8 +75,9 @@ msgstr "" msgid "About" msgstr "Informazioni" -#: src/tools/dvdomatic.cc:516 -msgid "Could not load film %s (%s)" +#: src/tools/dvdomatic.cc:517 +#, fuzzy +msgid "Could not load film %1 (%2)" msgstr "Non posso caricare il film %s (%s)" #: src/tools/dvdomatic.cc:331 @@ -85,7 +86,7 @@ msgid "Could not open film at %s (%s)" msgstr "Non posso aprire il film in %s (%s)" #: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:402 -#: src/tools/dvdomatic.cc:520 +#: src/tools/dvdomatic.cc:521 msgid "DVD-o-matic" msgstr "DVD-o-matic" @@ -105,11 +106,15 @@ msgstr "Nuovo" msgid "S&how DCP" msgstr "&Mostra DCP" +#: src/tools/dvdomatic.cc:74 +msgid "Save changes to film \"%1\" before closing?" +msgstr "" + #: src/tools/dvdomatic.cc:319 msgid "Select film to open" msgstr "Seleziona il film da aprire" #: src/tools/dvdomatic.cc:303 -#, c-format -msgid "The directory %s already exists." +#, fuzzy +msgid "The directory %1 already exists." msgstr "La directory %s esiste gia'." diff --git a/src/tools/po/sv_SE.po b/src/tools/po/sv_SE.po index b15529773..7c1383549 100644 --- a/src/tools/po/sv_SE.po +++ b/src/tools/po/sv_SE.po @@ -7,10 +7,11 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-26 14:07+0000\n" +"POT-Creation-Date: 2013-03-28 10:35+0000\n" "PO-Revision-Date: 2013-03-28 10:43+0100\n" "Last-Translator: Adam Klotblixt \n" "Language-Team: \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -65,14 +66,16 @@ msgid "&Send DCP to TMS" msgstr "&Skicka DCP till TMS" #: src/tools/dvdomatic.cc:409 -msgid "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" -msgstr "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" +msgid "" +"(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" +msgstr "" +"(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" #: src/tools/dvdomatic.cc:180 msgid "About" msgstr "Om" -#: src/tools/dvdomatic.cc:516 +#: src/tools/dvdomatic.cc:517 msgid "Could not load film %1 (%2)" msgstr "Kunde inte öppna filmen %1 (%2)" @@ -82,9 +85,8 @@ msgstr "Kunde inte öppna filmen %1 (%2)" msgid "Could not open film at %s (%s)" msgstr "Kunde inte öppna filmen vid %s (%s)" -#: src/tools/dvdomatic.cc:287 -#: src/tools/dvdomatic.cc:402 -#: src/tools/dvdomatic.cc:520 +#: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:402 +#: src/tools/dvdomatic.cc:521 msgid "DVD-o-matic" msgstr "DVD-o-matic" @@ -96,7 +98,8 @@ msgstr "Film ändrad" #: src/tools/dvdomatic.cc:408 msgid "Free, open-source DCP generation from almost anything." -msgstr "Fri, öppen-källkodsprogramvara för DCP-generering från nästan vad som helst." +msgstr "" +"Fri, öppen-källkodsprogramvara för DCP-generering från nästan vad som helst." # Ny? #: src/tools/dvdomatic.cc:160 @@ -108,12 +111,15 @@ msgstr "Skapa..." msgid "S&how DCP" msgstr "&Visa DCP" +#: src/tools/dvdomatic.cc:74 +msgid "Save changes to film \"%1\" before closing?" +msgstr "" + #: src/tools/dvdomatic.cc:319 msgid "Select film to open" msgstr "Välj film att öppna" #: src/tools/dvdomatic.cc:303 -#, c-format -msgid "The directory %s already exists." +#, fuzzy +msgid "The directory %1 already exists." msgstr "Katalogen %s finns redan." - diff --git a/src/wx/po/es_ES.po b/src/wx/po/es_ES.po index 58092d00b..217175db1 100644 --- a/src/wx/po/es_ES.po +++ b/src/wx/po/es_ES.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: libdvdomatic-wx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-26 14:54+0000\n" +"POT-Creation-Date: 2013-03-28 10:35+0000\n" "PO-Revision-Date: 2013-03-23 21:20-0500\n" "Last-Translator: Manuel AC \n" "Language-Team: Manuel AC \n" @@ -21,7 +21,7 @@ msgstr "" msgid "%" msgstr "%" -#: src/wx/config_dialog.cc:60 +#: src/wx/config_dialog.cc:61 msgid "(restart DVD-o-matic to see language changes)" msgstr "" @@ -33,7 +33,7 @@ msgstr "1 canal" msgid "A/B" msgstr "A/B" -#: src/wx/config_dialog.cc:142 +#: src/wx/config_dialog.cc:143 msgid "Add" msgstr "Añadir" @@ -139,14 +139,15 @@ msgid "DVD-o-matic Preferences" msgstr "Preferencias DVD-o-matic" #: src/wx/audio_dialog.cc:101 +#, c-format msgid "DVD-o-matic audio - %s" msgstr "Audio DVD-o-matic - %s" -#: src/wx/config_dialog.cc:101 +#: src/wx/config_dialog.cc:102 msgid "Default DCI name details" msgstr "Detalles por defecto del nombre DCI" -#: src/wx/config_dialog.cc:92 +#: src/wx/config_dialog.cc:93 msgid "Default directory for new films" msgstr "Carpeta por defecto para nuevas películas" @@ -162,16 +163,16 @@ msgstr "Espacio requerido en disco" msgid "Duration" msgstr "Duración" -#: src/wx/config_dialog.cc:144 +#: src/wx/config_dialog.cc:145 msgid "Edit" msgstr "Editar" -#: src/wx/config_dialog.cc:102 src/wx/config_dialog.cc:121 +#: src/wx/config_dialog.cc:103 src/wx/config_dialog.cc:122 #: src/wx/film_editor.cc:308 msgid "Edit..." msgstr "Editar..." -#: src/wx/config_dialog.cc:127 +#: src/wx/config_dialog.cc:128 msgid "Encoding Servers" msgstr "Servidores de codificación" @@ -231,7 +232,7 @@ msgstr "Hz" msgid "I want to play this back at fader" msgstr "Quiero reproducir con el fader a" -#: src/wx/config_dialog.cc:131 +#: src/wx/config_dialog.cc:132 msgid "IP address" msgstr "Dirección IP" @@ -299,15 +300,15 @@ msgstr "RMS" msgid "Rating (e.g. 15)" msgstr "Clasificación (ej. 16)" -#: src/wx/config_dialog.cc:117 +#: src/wx/config_dialog.cc:118 msgid "Reference filters for A/B" msgstr "Filtros de referencia para A/B" -#: src/wx/config_dialog.cc:106 +#: src/wx/config_dialog.cc:107 msgid "Reference scaler for A/B" msgstr "Escalador de referencia para A/B" -#: src/wx/config_dialog.cc:146 +#: src/wx/config_dialog.cc:147 msgid "Remove" msgstr "Quitar" @@ -371,19 +372,19 @@ msgstr "Escala del subtítulo" msgid "Subtitles" msgstr "Subtítulos" -#: src/wx/config_dialog.cc:67 +#: src/wx/config_dialog.cc:68 msgid "TMS IP address" msgstr "Dirección IP del TMS" -#: src/wx/config_dialog.cc:82 +#: src/wx/config_dialog.cc:83 msgid "TMS password" msgstr "Clave del TMS" -#: src/wx/config_dialog.cc:72 +#: src/wx/config_dialog.cc:73 msgid "TMS target path" msgstr "Ruta en el TMS" -#: src/wx/config_dialog.cc:77 +#: src/wx/config_dialog.cc:78 msgid "TMS user name" msgstr "Usuario del TMS" @@ -391,7 +392,7 @@ msgstr "Usuario del TMS" msgid "Territory (e.g. UK)" msgstr "Territorio (ej. ES)" -#: src/wx/config_dialog.cc:135 +#: src/wx/config_dialog.cc:136 msgid "Threads" msgstr "Hilos" @@ -399,7 +400,7 @@ msgstr "Hilos" msgid "Threads to use" msgstr "Hilos a utilizar" -#: src/wx/config_dialog.cc:87 +#: src/wx/config_dialog.cc:88 msgid "Threads to use for encoding on this host" msgstr "Hilos a utilizar para la codificación en esta máquina" diff --git a/src/wx/po/fr_FR.po b/src/wx/po/fr_FR.po index 87e24df69..2bf923b24 100644 --- a/src/wx/po/fr_FR.po +++ b/src/wx/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-26 14:54+0000\n" +"POT-Creation-Date: 2013-03-28 10:35+0000\n" "PO-Revision-Date: 2013-03-20 00:34+0100\n" "Last-Translator: FreeDCP.net \n" "Language-Team: \n" @@ -20,7 +20,7 @@ msgstr "" msgid "%" msgstr "%" -#: src/wx/config_dialog.cc:60 +#: src/wx/config_dialog.cc:61 msgid "(restart DVD-o-matic to see language changes)" msgstr "" @@ -32,7 +32,7 @@ msgstr "1 canal" msgid "A/B" msgstr "A/B" -#: src/wx/config_dialog.cc:142 +#: src/wx/config_dialog.cc:143 msgid "Add" msgstr "Ajouter" @@ -138,14 +138,15 @@ msgid "DVD-o-matic Preferences" msgstr "Préférences DVD-o-matic" #: src/wx/audio_dialog.cc:101 +#, c-format msgid "DVD-o-matic audio - %s" msgstr "Son DVD-o-matic - %s" -#: src/wx/config_dialog.cc:101 +#: src/wx/config_dialog.cc:102 msgid "Default DCI name details" msgstr "Détails du nom DCI par défaut" -#: src/wx/config_dialog.cc:92 +#: src/wx/config_dialog.cc:93 msgid "Default directory for new films" msgstr "Dossier par défaut des nouveaux films" @@ -161,16 +162,16 @@ msgstr "Espace disque requis" msgid "Duration" msgstr "Durée" -#: src/wx/config_dialog.cc:144 +#: src/wx/config_dialog.cc:145 msgid "Edit" msgstr "Édition" -#: src/wx/config_dialog.cc:102 src/wx/config_dialog.cc:121 +#: src/wx/config_dialog.cc:103 src/wx/config_dialog.cc:122 #: src/wx/film_editor.cc:308 msgid "Edit..." msgstr "Éditer..." -#: src/wx/config_dialog.cc:127 +#: src/wx/config_dialog.cc:128 msgid "Encoding Servers" msgstr "Serveurs d'encodage" @@ -230,7 +231,7 @@ msgstr "Hz" msgid "I want to play this back at fader" msgstr "Je veux le jouer à ce volume" -#: src/wx/config_dialog.cc:131 +#: src/wx/config_dialog.cc:132 msgid "IP address" msgstr "Adresse IP" @@ -298,15 +299,15 @@ msgstr "RMS" msgid "Rating (e.g. 15)" msgstr "Rating (ex. 15)" -#: src/wx/config_dialog.cc:117 +#: src/wx/config_dialog.cc:118 msgid "Reference filters for A/B" msgstr "Filtres de référence pour A/B" -#: src/wx/config_dialog.cc:106 +#: src/wx/config_dialog.cc:107 msgid "Reference scaler for A/B" msgstr "Échelle de référence pour A/B" -#: src/wx/config_dialog.cc:146 +#: src/wx/config_dialog.cc:147 msgid "Remove" msgstr "Supprimer" @@ -370,19 +371,19 @@ msgstr "Taille du sous-titre" msgid "Subtitles" msgstr "Sous-titres" -#: src/wx/config_dialog.cc:67 +#: src/wx/config_dialog.cc:68 msgid "TMS IP address" msgstr "Adresse IP du TMS" -#: src/wx/config_dialog.cc:82 +#: src/wx/config_dialog.cc:83 msgid "TMS password" msgstr "Mot de passe du TMS" -#: src/wx/config_dialog.cc:72 +#: src/wx/config_dialog.cc:73 msgid "TMS target path" msgstr "Chemin d'accès du TMS" -#: src/wx/config_dialog.cc:77 +#: src/wx/config_dialog.cc:78 msgid "TMS user name" msgstr "Nom d'utilisateur du TMS" @@ -390,7 +391,7 @@ msgstr "Nom d'utilisateur du TMS" msgid "Territory (e.g. UK)" msgstr "Territoire (ex. FR)" -#: src/wx/config_dialog.cc:135 +#: src/wx/config_dialog.cc:136 msgid "Threads" msgstr "Processus" @@ -398,7 +399,7 @@ msgstr "Processus" msgid "Threads to use" msgstr "Nombre de processus à utiliser" -#: src/wx/config_dialog.cc:87 +#: src/wx/config_dialog.cc:88 msgid "Threads to use for encoding on this host" msgstr "Nombre de processus à utiliser sur cet hôte" diff --git a/src/wx/po/it_IT.po b/src/wx/po/it_IT.po index 2e65d7d98..9bc7b638a 100644 --- a/src/wx/po/it_IT.po +++ b/src/wx/po/it_IT.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-26 14:54+0000\n" +"POT-Creation-Date: 2013-03-28 10:35+0000\n" "PO-Revision-Date: 2013-03-22 18:10+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" @@ -21,7 +21,7 @@ msgstr "" msgid "%" msgstr "%" -#: src/wx/config_dialog.cc:60 +#: src/wx/config_dialog.cc:61 msgid "(restart DVD-o-matic to see language changes)" msgstr "" @@ -33,7 +33,7 @@ msgstr "Canale 1" msgid "A/B" msgstr "A/B" -#: src/wx/config_dialog.cc:142 +#: src/wx/config_dialog.cc:143 msgid "Add" msgstr "Aggiungi" @@ -139,14 +139,15 @@ msgid "DVD-o-matic Preferences" msgstr "Preferenze DVD-o-matic" #: src/wx/audio_dialog.cc:101 +#, c-format msgid "DVD-o-matic audio - %s" msgstr "Audio DVD-o-matic - %s" -#: src/wx/config_dialog.cc:101 +#: src/wx/config_dialog.cc:102 msgid "Default DCI name details" msgstr "Dettagli del nome di default DCI" -#: src/wx/config_dialog.cc:92 +#: src/wx/config_dialog.cc:93 msgid "Default directory for new films" msgstr "Directory di default per i nuovi films" @@ -162,16 +163,16 @@ msgstr "Spazio su disco rischiesto" msgid "Duration" msgstr "Durata" -#: src/wx/config_dialog.cc:144 +#: src/wx/config_dialog.cc:145 msgid "Edit" msgstr "Modifica" -#: src/wx/config_dialog.cc:102 src/wx/config_dialog.cc:121 +#: src/wx/config_dialog.cc:103 src/wx/config_dialog.cc:122 #: src/wx/film_editor.cc:308 msgid "Edit..." msgstr "Modifica..." -#: src/wx/config_dialog.cc:127 +#: src/wx/config_dialog.cc:128 msgid "Encoding Servers" msgstr "Servers di codifica" @@ -231,7 +232,7 @@ msgstr "Hz" msgid "I want to play this back at fader" msgstr "Sto usando il fader a" -#: src/wx/config_dialog.cc:131 +#: src/wx/config_dialog.cc:132 msgid "IP address" msgstr "Indirizzo IP" @@ -299,15 +300,15 @@ msgstr "RMS" msgid "Rating (e.g. 15)" msgstr "Classificazione (es. 15)" -#: src/wx/config_dialog.cc:117 +#: src/wx/config_dialog.cc:118 msgid "Reference filters for A/B" msgstr "Filtri di riferimento A/B" -#: src/wx/config_dialog.cc:106 +#: src/wx/config_dialog.cc:107 msgid "Reference scaler for A/B" msgstr "Scalatura di riferimento A/B" -#: src/wx/config_dialog.cc:146 +#: src/wx/config_dialog.cc:147 msgid "Remove" msgstr "Rimuovi" @@ -371,19 +372,19 @@ msgstr "Scala dei Sottotitoli" msgid "Subtitles" msgstr "Sottotitoli" -#: src/wx/config_dialog.cc:67 +#: src/wx/config_dialog.cc:68 msgid "TMS IP address" msgstr "Indirizzo IP del TMS" -#: src/wx/config_dialog.cc:82 +#: src/wx/config_dialog.cc:83 msgid "TMS password" msgstr "Password del TMS" -#: src/wx/config_dialog.cc:72 +#: src/wx/config_dialog.cc:73 msgid "TMS target path" msgstr "Percorso di destinazione del TMS" -#: src/wx/config_dialog.cc:77 +#: src/wx/config_dialog.cc:78 msgid "TMS user name" msgstr "Nome utente del TMS" @@ -391,7 +392,7 @@ msgstr "Nome utente del TMS" msgid "Territory (e.g. UK)" msgstr "Nazione (es. UK)" -#: src/wx/config_dialog.cc:135 +#: src/wx/config_dialog.cc:136 msgid "Threads" msgstr "Threads" @@ -399,7 +400,7 @@ msgstr "Threads" msgid "Threads to use" msgstr "Threads da usare" -#: src/wx/config_dialog.cc:87 +#: src/wx/config_dialog.cc:88 msgid "Threads to use for encoding on this host" msgstr "Threads da usare per codificare su questo host" diff --git a/src/wx/po/sv_SE.po b/src/wx/po/sv_SE.po index 6519c5baf..9be9e150d 100644 --- a/src/wx/po/sv_SE.po +++ b/src/wx/po/sv_SE.po @@ -7,10 +7,11 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-26 14:07+0000\n" +"POT-Creation-Date: 2013-03-28 10:35+0000\n" "PO-Revision-Date: 2013-03-28 10:44+0100\n" "Last-Translator: Adam Klotblixt \n" "Language-Team: \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -20,7 +21,7 @@ msgstr "" msgid "%" msgstr "%" -#: src/wx/config_dialog.cc:60 +#: src/wx/config_dialog.cc:61 msgid "(restart DVD-o-matic to see language changes)" msgstr "(starta om DVD-o-matic för att se språkändringar)" @@ -32,12 +33,11 @@ msgstr "1 kanal" msgid "A/B" msgstr "A/B" -#: src/wx/config_dialog.cc:142 +#: src/wx/config_dialog.cc:143 msgid "Add" msgstr "Lägg till" -#: src/wx/audio_dialog.cc:32 -#: src/wx/film_editor.cc:77 +#: src/wx/audio_dialog.cc:32 src/wx/film_editor.cc:77 msgid "Audio" msgstr "Audio" @@ -141,19 +141,19 @@ msgid "DVD-o-matic Preferences" msgstr "DVD-o-matic Inställningar" #: src/wx/audio_dialog.cc:101 -msgid "DVD-o-matic audio - %1" +#, fuzzy, c-format +msgid "DVD-o-matic audio - %s" msgstr "DVD-o-matic audio - %1" -#: src/wx/config_dialog.cc:101 +#: src/wx/config_dialog.cc:102 msgid "Default DCI name details" msgstr "Detaljer om förvalda DCI-namn" -#: src/wx/config_dialog.cc:92 +#: src/wx/config_dialog.cc:93 msgid "Default directory for new films" msgstr "Förvald katalog för nya filmer" -#: src/wx/film_editor.cc:116 -#: src/wx/job_manager_view.cc:92 +#: src/wx/film_editor.cc:116 src/wx/job_manager_view.cc:92 msgid "Details..." msgstr "Detaljer..." @@ -165,17 +165,16 @@ msgstr "Diskutrymme som krävs" msgid "Duration" msgstr "Längd" -#: src/wx/config_dialog.cc:144 +#: src/wx/config_dialog.cc:145 msgid "Edit" msgstr "Redigera" -#: src/wx/config_dialog.cc:102 -#: src/wx/config_dialog.cc:121 +#: src/wx/config_dialog.cc:103 src/wx/config_dialog.cc:122 #: src/wx/film_editor.cc:308 msgid "Edit..." msgstr "Redigera..." -#: src/wx/config_dialog.cc:127 +#: src/wx/config_dialog.cc:128 msgid "Encoding Servers" msgstr "Kodningsservrar" @@ -201,8 +200,7 @@ msgstr "Film Egenskaper" msgid "Film name" msgstr "film namn" -#: src/wx/film_editor.cc:303 -#: src/wx/filter_dialog.cc:32 +#: src/wx/film_editor.cc:303 src/wx/filter_dialog.cc:32 msgid "Filters" msgstr "Filter" @@ -240,7 +238,7 @@ msgstr "Hz" msgid "I want to play this back at fader" msgstr "Jag vill spela upp detta med toning" -#: src/wx/config_dialog.cc:131 +#: src/wx/config_dialog.cc:132 msgid "IP address" msgstr "IP-adress" @@ -272,8 +270,7 @@ msgstr "Namn" msgid "New Film" msgstr "Ny Film" -#: src/wx/film_editor.cc:305 -#: src/wx/film_editor.cc:664 +#: src/wx/film_editor.cc:305 src/wx/film_editor.cc:664 msgid "None" msgstr "Inget" @@ -311,15 +308,15 @@ msgstr "RMS" msgid "Rating (e.g. 15)" msgstr "Klassificering (ex. 15)" -#: src/wx/config_dialog.cc:117 +#: src/wx/config_dialog.cc:118 msgid "Reference filters for A/B" msgstr "Referensfilter för A/B" -#: src/wx/config_dialog.cc:106 +#: src/wx/config_dialog.cc:107 msgid "Reference scaler for A/B" msgstr "Referensomskalare för A/B" -#: src/wx/config_dialog.cc:146 +#: src/wx/config_dialog.cc:147 msgid "Remove" msgstr "Ta bort" @@ -383,19 +380,19 @@ msgstr "Undertext Skalning" msgid "Subtitles" msgstr "Undertexter" -#: src/wx/config_dialog.cc:67 +#: src/wx/config_dialog.cc:68 msgid "TMS IP address" msgstr "TMS IP-adress" -#: src/wx/config_dialog.cc:82 +#: src/wx/config_dialog.cc:83 msgid "TMS password" msgstr "TMS lösenord" -#: src/wx/config_dialog.cc:72 +#: src/wx/config_dialog.cc:73 msgid "TMS target path" msgstr "TMS målsökväg" -#: src/wx/config_dialog.cc:77 +#: src/wx/config_dialog.cc:78 msgid "TMS user name" msgstr "TMS användarnamn" @@ -403,7 +400,7 @@ msgstr "TMS användarnamn" msgid "Territory (e.g. UK)" msgstr "Område (ex. SV)" -#: src/wx/config_dialog.cc:135 +#: src/wx/config_dialog.cc:136 msgid "Threads" msgstr "Trådar" @@ -411,7 +408,7 @@ msgstr "Trådar" msgid "Threads to use" msgstr "Antal trådar att använda" -#: src/wx/config_dialog.cc:87 +#: src/wx/config_dialog.cc:88 msgid "Threads to use for encoding on this host" msgstr "Antal trådar att använda vid kodning på denna maskin" @@ -472,8 +469,7 @@ msgstr "räknar..." msgid "dB" msgstr "dB" -#: src/wx/film_editor.cc:691 -#: src/wx/film_editor.cc:694 +#: src/wx/film_editor.cc:691 src/wx/film_editor.cc:694 msgid "frames" msgstr "bilder" @@ -487,8 +483,6 @@ msgstr "ms" msgid "s" msgstr "s" -#: src/wx/properties_dialog.cc:62 -#: src/wx/properties_dialog.cc:63 +#: src/wx/properties_dialog.cc:62 src/wx/properties_dialog.cc:63 msgid "unknown" msgstr "okänt" - -- cgit v1.2.3 From ed78fd3d138114185e43edf81ffe91db17377da0 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 31 Mar 2013 02:19:40 +0100 Subject: Skeletal remains. --- src/lib/audio_content.h | 8 +++ src/lib/content.h | 17 +++++++ src/lib/ffmpeg_content.h | 8 +++ src/lib/film.cc | 15 ------ src/lib/film.h | 116 +----------------------------------------- src/lib/imagemagick_content.h | 6 +++ src/lib/playlist.h | 30 +++++++++++ src/lib/sndfile_content.h | 7 +++ src/lib/video_content.h | 8 +++ src/lib/video_source.h | 2 +- 10 files changed, 87 insertions(+), 130 deletions(-) create mode 100644 src/lib/audio_content.h create mode 100644 src/lib/content.h create mode 100644 src/lib/ffmpeg_content.h create mode 100644 src/lib/imagemagick_content.h create mode 100644 src/lib/playlist.h create mode 100644 src/lib/sndfile_content.h create mode 100644 src/lib/video_content.h (limited to 'src') diff --git a/src/lib/audio_content.h b/src/lib/audio_content.h new file mode 100644 index 000000000..95fd681a7 --- /dev/null +++ b/src/lib/audio_content.h @@ -0,0 +1,8 @@ +#include "content.h" + +class AudioContent : public virtual Content +{ +public: + + +}; diff --git a/src/lib/content.h b/src/lib/content.h new file mode 100644 index 000000000..c848860aa --- /dev/null +++ b/src/lib/content.h @@ -0,0 +1,17 @@ +#include +#include + +class Content +{ +public: + boost::filesystem::path file () const { + boost::mutex::scoped_lock lm (_mutex); + return _file; + } + +protected: + boost::mutex _mutex; + +private: + boost::filesystem::path _file; +}; diff --git a/src/lib/ffmpeg_content.h b/src/lib/ffmpeg_content.h new file mode 100644 index 000000000..8b3eca62d --- /dev/null +++ b/src/lib/ffmpeg_content.h @@ -0,0 +1,8 @@ +#include "content.h" + +class FFmpegContent : public VideoContent, public AudioContent +{ +public: + + +}; diff --git a/src/lib/film.cc b/src/lib/film.cc index bd11c1eb5..0d969f16d 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -94,10 +94,8 @@ Film::Film (string d, bool must_exist) , _trim_start (0) , _trim_end (0) , _dcp_ab (false) - , _use_content_audio (true) , _audio_gain (0) , _audio_delay (0) - , _still_duration (10) , _with_subtitles (false) , _subtitle_offset (0) , _subtitle_scale (1) @@ -105,7 +103,6 @@ Film::Film (string d, bool must_exist) , _j2k_bandwidth (200000000) , _dci_metadata (Config::instance()->default_dci_metadata ()) , _dcp_frame_rate (0) - , _source_frame_rate (0) , _dirty (false) { set_dci_date_today (); @@ -154,7 +151,6 @@ Film::Film (Film const & o) , _directory (o._directory) , _name (o._name) , _use_dci_name (o._use_dci_name) - , _content (o._content) , _trust_content_header (o._trust_content_header) , _dcp_content_type (o._dcp_content_type) , _format (o._format) @@ -164,13 +160,9 @@ Film::Film (Film const & o) , _trim_start (o._trim_start) , _trim_end (o._trim_end) , _dcp_ab (o._dcp_ab) - , _content_audio_stream (o._content_audio_stream) - , _external_audio (o._external_audio) - , _use_content_audio (o._use_content_audio) , _audio_gain (o._audio_gain) , _audio_delay (o._audio_delay) , _still_duration (o._still_duration) - , _subtitle_stream (o._subtitle_stream) , _with_subtitles (o._with_subtitles) , _subtitle_offset (o._subtitle_offset) , _subtitle_scale (o._subtitle_scale) @@ -179,13 +171,6 @@ Film::Film (Film const & o) , _dci_metadata (o._dci_metadata) , _dci_date (o._dci_date) , _dcp_frame_rate (o._dcp_frame_rate) - , _size (o._size) - , _length (o._length) - , _content_digest (o._content_digest) - , _content_audio_streams (o._content_audio_streams) - , _sndfile_stream (o._sndfile_stream) - , _subtitle_streams (o._subtitle_streams) - , _source_frame_rate (o._source_frame_rate) , _dirty (o._dirty) { diff --git a/src/lib/film.h b/src/lib/film.h index adc4b0eec..2e05d64f4 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -47,6 +47,7 @@ class Log; class ExamineContentJob; class AnalyseAudioJob; class ExternalAudioStream; +class Content; /** @class Film * @brief A representation of a video, maybe with sound. @@ -116,7 +117,6 @@ public: NONE, NAME, USE_DCI_NAME, - CONTENT, TRUST_CONTENT_HEADER, DCP_CONTENT_TYPE, FORMAT, @@ -126,9 +126,6 @@ public: TRIM_START, TRIM_END, DCP_AB, - CONTENT_AUDIO_STREAM, - EXTERNAL_AUDIO, - USE_CONTENT_AUDIO, AUDIO_GAIN, AUDIO_DELAY, STILL_DURATION, @@ -139,11 +136,6 @@ public: COLOUR_LUT, J2K_BANDWIDTH, DCI_METADATA, - SIZE, - LENGTH, - CONTENT_AUDIO_STREAMS, - SUBTITLE_STREAMS, - SOURCE_FRAME_RATE, DCP_FRAME_RATE }; @@ -165,11 +157,6 @@ public: return _use_dci_name; } - std::string content () const { - boost::mutex::scoped_lock lm (_state_mutex); - return _content; - } - bool trust_content_header () const { boost::mutex::scoped_lock lm (_state_mutex); return _trust_content_header; @@ -215,21 +202,6 @@ public: return _dcp_ab; } - boost::shared_ptr content_audio_stream () const { - boost::mutex::scoped_lock lm (_state_mutex); - return _content_audio_stream; - } - - std::vector external_audio () const { - boost::mutex::scoped_lock lm (_state_mutex); - return _external_audio; - } - - bool use_content_audio () const { - boost::mutex::scoped_lock lm (_state_mutex); - return _use_content_audio; - } - float audio_gain () const { boost::mutex::scoped_lock lm (_state_mutex); return _audio_gain; @@ -240,13 +212,6 @@ public: return _audio_delay; } - int still_duration () const { - boost::mutex::scoped_lock lm (_state_mutex); - return _still_duration; - } - - int still_duration_in_frames () const; - boost::shared_ptr subtitle_stream () const { boost::mutex::scoped_lock lm (_state_mutex); return _subtitle_stream; @@ -286,40 +251,6 @@ public: boost::mutex::scoped_lock lm (_state_mutex); return _dcp_frame_rate; } - - libdcp::Size size () const { - boost::mutex::scoped_lock lm (_state_mutex); - return _size; - } - - boost::optional length () const { - boost::mutex::scoped_lock lm (_state_mutex); - return _length; - } - - std::string content_digest () const { - boost::mutex::scoped_lock lm (_state_mutex); - return _content_digest; - } - - std::vector > content_audio_streams () const { - boost::mutex::scoped_lock lm (_state_mutex); - return _content_audio_streams; - } - - std::vector > subtitle_streams () const { - boost::mutex::scoped_lock lm (_state_mutex); - return _subtitle_streams; - } - - float source_frame_rate () const { - boost::mutex::scoped_lock lm (_state_mutex); - if (content_type() == STILL) { - return 24; - } - - return _source_frame_rate; - } boost::shared_ptr audio_stream () const; bool has_audio () const; @@ -329,7 +260,6 @@ public: void set_directory (std::string); void set_name (std::string); void set_use_dci_name (bool); - void set_content (std::string); void set_trust_content_header (bool); void set_dcp_content_type (DCPContentType const *); void set_format (Format const *); @@ -343,13 +273,9 @@ public: void set_trim_start (int); void set_trim_end (int); void set_dcp_ab (bool); - void set_content_audio_stream (boost::shared_ptr); - void set_external_audio (std::vector); - void set_use_content_audio (bool); void set_audio_gain (float); void set_audio_delay (int); void set_still_duration (int); - void set_subtitle_stream (boost::shared_ptr); void set_with_subtitles (bool); void set_subtitle_offset (int); void set_subtitle_scale (float); @@ -357,13 +283,6 @@ public: void set_j2k_bandwidth (int); void set_dci_metadata (DCIMetadata); void set_dcp_frame_rate (int); - void set_size (libdcp::Size); - void set_length (SourceFrame); - void unset_length (); - void set_content_digest (std::string); - void set_content_audio_streams (std::vector >); - void set_subtitle_streams (std::vector >); - void set_source_frame_rate (float); /** Emitted when some property has changed */ mutable boost::signals2::signal Changed; @@ -399,10 +318,7 @@ private: std::string _name; /** True if a auto-generated DCI-compliant name should be used for our DCP */ bool _use_dci_name; - /** File or directory containing content; may be relative to our directory - * or an absolute path. - */ - std::string _content; + std::list > _content; /** If this is true, we will believe the length specified by the content * file's header; if false, we will run through the whole content file * the first time we see it in order to obtain the length. @@ -427,21 +343,10 @@ private: has the specified filters and post-processing. */ bool _dcp_ab; - /** The audio stream to use from our content */ - boost::shared_ptr _content_audio_stream; - /** List of filenames of external audio files, in channel order - (L, R, C, Lfe, Ls, Rs) - */ - std::vector _external_audio; - /** true to use audio from our content file; false to use external audio */ - bool _use_content_audio; /** Gain to apply to audio in dB */ float _audio_gain; /** Delay to apply to audio (positive moves audio later) in milliseconds */ int _audio_delay; - /** Duration to make still-sourced films (in seconds) */ - int _still_duration; - boost::shared_ptr _subtitle_stream; /** True if subtitles should be shown for this film */ bool _with_subtitles; /** y offset for placing subtitles, in source pixels; +ve is further down @@ -465,23 +370,6 @@ private: /** Frames per second to run our DCP at */ int _dcp_frame_rate; - /* Data which are cached to speed things up */ - - /** Size, in pixels, of the source (ignoring cropping) */ - libdcp::Size _size; - /** The length of the source, in video frames (as far as we know) */ - boost::optional _length; - /** MD5 digest of our content file */ - std::string _content_digest; - /** The audio streams in our content */ - std::vector > _content_audio_streams; - /** A stream to represent possible external audio (will always exist) */ - boost::shared_ptr _sndfile_stream; - /** the subtitle streams that we can use */ - std::vector > _subtitle_streams; - /** Frames per second of the source */ - float _source_frame_rate; - /** true if our state has changed since we last saved it */ mutable bool _dirty; diff --git a/src/lib/imagemagick_content.h b/src/lib/imagemagick_content.h new file mode 100644 index 000000000..2a8197b69 --- /dev/null +++ b/src/lib/imagemagick_content.h @@ -0,0 +1,6 @@ +#include "video_content.h" + +class ImageMagickContent : public VideoContent +{ + +}; diff --git a/src/lib/playlist.h b/src/lib/playlist.h new file mode 100644 index 000000000..4add76344 --- /dev/null +++ b/src/lib/playlist.h @@ -0,0 +1,30 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include "video_source.h" +#include "video_sink.h" + +class Content; + +class Playlist : public VideoSource, public AudioSource +{ +public: + Playlist (std::list >); +}; diff --git a/src/lib/sndfile_content.h b/src/lib/sndfile_content.h new file mode 100644 index 000000000..382e55c40 --- /dev/null +++ b/src/lib/sndfile_content.h @@ -0,0 +1,7 @@ +#include "audio_content.h" + +class SndfileContent : public AudioContent +{ +public: + +}; diff --git a/src/lib/video_content.h b/src/lib/video_content.h new file mode 100644 index 000000000..ee4a64fc4 --- /dev/null +++ b/src/lib/video_content.h @@ -0,0 +1,8 @@ +#include "content.h" + +class VideoContent : public virtual Content +{ +public: + + +}; diff --git a/src/lib/video_source.h b/src/lib/video_source.h index 893629160..e60e7dfd0 100644 --- a/src/lib/video_source.h +++ b/src/lib/video_source.h @@ -32,7 +32,7 @@ class VideoSink; class Subtitle; class Image; -/** @class VideoSink +/** @class VideoSource * @param A class that emits video data. */ class VideoSource -- cgit v1.2.3 From 127672223cca569986e35c91265e269ed5a6561c Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 31 Mar 2013 15:09:49 +0100 Subject: Runs. --- doc/design/content.tex | 6 +- src/lib/ab_transcode_job.cc | 2 +- src/lib/ab_transcode_job.h | 3 +- src/lib/ab_transcoder.cc | 48 ++-- src/lib/ab_transcoder.h | 13 +- src/lib/analyse_audio_job.cc | 30 +-- src/lib/audio_content.cc | 7 + src/lib/audio_content.h | 13 +- src/lib/audio_decoder.cc | 9 +- src/lib/audio_decoder.h | 23 +- src/lib/content.cc | 20 ++ src/lib/content.h | 19 +- src/lib/decoder.cc | 15 +- src/lib/decoder.h | 8 +- src/lib/decoder_factory.cc | 19 +- src/lib/encoder.cc | 32 +-- src/lib/encoder.h | 4 +- src/lib/examine_content_job.cc | 67 +----- src/lib/examine_content_job.h | 17 +- src/lib/exceptions.h | 1 + src/lib/ffmpeg_content.cc | 156 +++++++++++++ src/lib/ffmpeg_content.h | 93 +++++++- src/lib/ffmpeg_decoder.cc | 143 +++--------- src/lib/ffmpeg_decoder.h | 51 ++-- src/lib/film.cc | 462 +++++++----------------------------- src/lib/film.h | 31 ++- src/lib/filter_graph.cc | 2 +- src/lib/filter_graph.h | 2 +- src/lib/format.cc | 19 +- src/lib/format.h | 16 +- src/lib/imagemagick_content.cc | 2 + src/lib/imagemagick_content.h | 3 +- src/lib/imagemagick_decoder.cc | 65 ++---- src/lib/imagemagick_decoder.h | 14 +- src/lib/job.cc | 2 - src/lib/job.h | 3 +- src/lib/playlist.cc | 266 +++++++++++++++++++++ src/lib/playlist.h | 56 ++++- src/lib/scp_dcp_job.h | 2 +- src/lib/sndfile_content.cc | 41 ++++ src/lib/sndfile_content.h | 6 + src/lib/sndfile_decoder.cc | 142 ++---------- src/lib/sndfile_decoder.h | 28 +-- src/lib/stream.cc | 92 -------- src/lib/stream.h | 121 ---------- src/lib/transcode_job.cc | 19 +- src/lib/transcode_job.h | 1 - src/lib/transcoder.cc | 51 ++-- src/lib/transcoder.h | 16 +- src/lib/util.cc | 6 +- src/lib/util.h | 4 +- src/lib/video_content.cc | 28 +++ src/lib/video_content.h | 39 ++++ src/lib/video_decoder.cc | 16 +- src/lib/video_decoder.h | 24 +- src/lib/writer.cc | 8 +- src/lib/writer.h | 4 +- src/lib/wscript | 8 +- src/tools/dvdomatic.cc | 3 - src/tools/makedcp.cc | 2 +- src/wx/audio_dialog.cc | 19 +- src/wx/audio_dialog.h | 2 + src/wx/film_editor.cc | 514 +++++++++++++++-------------------------- src/wx/film_editor.h | 51 ++-- src/wx/film_viewer.cc | 40 ++-- src/wx/properties_dialog.cc | 10 +- test/test.cc | 84 ++----- 67 files changed, 1361 insertions(+), 1762 deletions(-) create mode 100644 src/lib/audio_content.cc create mode 100644 src/lib/content.cc create mode 100644 src/lib/ffmpeg_content.cc create mode 100644 src/lib/imagemagick_content.cc create mode 100644 src/lib/playlist.cc create mode 100644 src/lib/sndfile_content.cc delete mode 100644 src/lib/stream.cc delete mode 100644 src/lib/stream.h create mode 100644 src/lib/video_content.cc (limited to 'src') diff --git a/doc/design/content.tex b/doc/design/content.tex index a3c5c5835..0f5f17025 100644 --- a/doc/design/content.tex +++ b/doc/design/content.tex @@ -174,7 +174,7 @@ public: \end{verbatim} Then Film has a \texttt{Playlist} which has a -\texttt{vector}. And it can answer questions +\texttt{vector >}. It can answer questions about audio/video length, frame rate, audio channels and so on. \texttt{Playlist} can also be a source of video and audio, so clients can do: @@ -188,6 +188,8 @@ while (!p->pass ()) { } \end{verbatim} -Playlist could be created on-demand for all the difference it would make. +Playlist could be created on-demand for all the difference it would +make. And perhaps it should, since it will hold Decoders which are +probably run-once. \end{document} diff --git a/src/lib/ab_transcode_job.cc b/src/lib/ab_transcode_job.cc index 4ffdd9af6..f17d43916 100644 --- a/src/lib/ab_transcode_job.cc +++ b/src/lib/ab_transcode_job.cc @@ -54,7 +54,7 @@ ABTranscodeJob::run () { try { /* _film_b is the one with reference filters */ - ABTranscoder w (_film_b, _film, _decode_opt, this, shared_ptr (new Encoder (_film))); + ABTranscoder w (_film_b, _film, _decode_opt, shared_from_this ()); w.go (); set_progress (1); set_state (FINISHED_OK); diff --git a/src/lib/ab_transcode_job.h b/src/lib/ab_transcode_job.h index 8e3cbe2d8..5d029a18b 100644 --- a/src/lib/ab_transcode_job.h +++ b/src/lib/ab_transcode_job.h @@ -46,8 +46,7 @@ public: void run (); private: - DecodeOptions _decode_opt; - /** Copy of our Film using the reference filters and scaler */ boost::shared_ptr _film_b; + DecodeOptions _decode_opt; }; diff --git a/src/lib/ab_transcoder.cc b/src/lib/ab_transcoder.cc index 3a1cd83d7..0c687008d 100644 --- a/src/lib/ab_transcoder.cc +++ b/src/lib/ab_transcoder.cc @@ -21,13 +21,11 @@ #include #include "ab_transcoder.h" #include "film.h" -#include "video_decoder.h" -#include "audio_decoder.h" #include "encoder.h" #include "job.h" #include "options.h" #include "image.h" -#include "decoder_factory.h" +#include "playlist.h" #include "matcher.h" #include "delay_line.h" #include "gain.h" @@ -49,31 +47,23 @@ using boost::dynamic_pointer_cast; * @param e Encoder to use. */ -ABTranscoder::ABTranscoder ( - shared_ptr a, shared_ptr b, DecodeOptions o, Job* j, shared_ptr e) +ABTranscoder::ABTranscoder (shared_ptr a, shared_ptr b, DecodeOptions o, shared_ptr j) : _film_a (a) , _film_b (b) + , _playlist_a (_film_a->playlist ()) + , _playlist_b (_film_b->playlist ()) , _job (j) - , _encoder (e) + , _encoder (new Encoder (_film_a, _playlist_a)) , _combiner (new Combiner (a->log())) { - _da = decoder_factory (_film_a, o); - _db = decoder_factory (_film_b, o); - - if (_film_a->audio_stream()) { - shared_ptr st = _film_a->audio_stream(); - _matcher.reset (new Matcher (_film_a->log(), st->sample_rate(), _film_a->source_frame_rate())); - _delay_line.reset (new DelayLine (_film_a->log(), st->channels(), _film_a->audio_delay() * st->sample_rate() / 1000)); + if (_playlist_a->has_audio ()) { + _matcher.reset (new Matcher (_film_a->log(), _playlist_a->audio_frame_rate(), _playlist_a->video_frame_rate())); + _delay_line.reset (new DelayLine (_film_a->log(), _playlist_a->audio_channels(), _film_a->audio_delay() * _playlist_a->audio_frame_rate() / 1000)); _gain.reset (new Gain (_film_a->log(), _film_a->audio_gain())); } - /* Set up the decoder to use the film's set streams */ - _da.video->set_subtitle_stream (_film_a->subtitle_stream ()); - _db.video->set_subtitle_stream (_film_a->subtitle_stream ()); - _da.audio->set_audio_stream (_film_a->audio_stream ()); - - _da.video->Video.connect (bind (&Combiner::process_video, _combiner, _1, _2, _3)); - _db.video->Video.connect (bind (&Combiner::process_video_b, _combiner, _1, _2, _3)); + _playlist_a->Video.connect (bind (&Combiner::process_video, _combiner, _1, _2, _3)); + _playlist_b->Video.connect (bind (&Combiner::process_video_b, _combiner, _1, _2, _3)); if (_matcher) { _combiner->connect_video (_matcher); @@ -83,7 +73,7 @@ ABTranscoder::ABTranscoder ( } if (_matcher && _delay_line) { - _da.audio->connect_audio (_delay_line); + _playlist_a->connect_audio (_delay_line); _delay_line->connect_audio (_matcher); _matcher->connect_audio (_gain); _gain->connect_audio (_encoder); @@ -95,23 +85,17 @@ ABTranscoder::go () { _encoder->process_begin (); - bool done[3] = { false, false, false }; + bool done[2] = { false, false }; while (1) { - done[0] = _da.video->pass (); - done[1] = _db.video->pass (); - - if (!done[2] && _da.audio && dynamic_pointer_cast (_da.audio) != dynamic_pointer_cast (_da.video)) { - done[2] = _da.audio->pass (); - } else { - done[2] = true; - } + done[0] = _playlist_a->pass (); + done[1] = _playlist_b->pass (); if (_job) { - _da.video->set_progress (_job); + _playlist_a->set_progress (_job); } - if (done[0] && done[1] && done[2]) { + if (done[0] && done[1]) { break; } } diff --git a/src/lib/ab_transcoder.h b/src/lib/ab_transcoder.h index 58a08af04..14277c562 100644 --- a/src/lib/ab_transcoder.h +++ b/src/lib/ab_transcoder.h @@ -29,16 +29,14 @@ class Job; class Encoder; -class VideoDecoder; -class AudioDecoder; class Image; class Log; -class Subtitle; class Film; class Matcher; class DelayLine; class Gain; class Combiner; +class Playlist; /** @class ABTranscoder * @brief A transcoder which uses one Film for the left half of the screen, and a different one @@ -51,8 +49,7 @@ public: boost::shared_ptr a, boost::shared_ptr b, DecodeOptions o, - Job* j, - boost::shared_ptr e + boost::shared_ptr j ); void go (); @@ -60,10 +57,10 @@ public: private: boost::shared_ptr _film_a; boost::shared_ptr _film_b; - Job* _job; + boost::shared_ptr _playlist_a; + boost::shared_ptr _playlist_b; + boost::shared_ptr _job; boost::shared_ptr _encoder; - Decoders _da; - Decoders _db; boost::shared_ptr _combiner; boost::shared_ptr _matcher; boost::shared_ptr _delay_line; diff --git a/src/lib/analyse_audio_job.cc b/src/lib/analyse_audio_job.cc index 43eecbcbd..74491943b 100644 --- a/src/lib/analyse_audio_job.cc +++ b/src/lib/analyse_audio_job.cc @@ -22,8 +22,7 @@ #include "compose.hpp" #include "film.h" #include "options.h" -#include "decoder_factory.h" -#include "audio_decoder.h" +#include "playlist.h" #include "i18n.h" @@ -52,29 +51,18 @@ AnalyseAudioJob::name () const void AnalyseAudioJob::run () { - if (!_film->audio_stream () || !_film->length()) { - set_progress (1); - set_state (FINISHED_ERROR); - return; - } - - DecodeOptions options; - options.decode_video = false; - - Decoders decoders = decoder_factory (_film, options); - assert (decoders.audio); + shared_ptr playlist = _film->playlist (); + playlist->disable_video (); - decoders.audio->set_audio_stream (_film->audio_stream ()); - decoders.audio->Audio.connect (bind (&AnalyseAudioJob::audio, this, _1)); + playlist->Audio.connect (bind (&AnalyseAudioJob::audio, this, _1)); - int64_t total_audio_frames = video_frames_to_audio_frames (_film->length().get(), _film->audio_stream()->sample_rate(), _film->source_frame_rate()); - _samples_per_point = max (int64_t (1), total_audio_frames / _num_points); + _samples_per_point = max (int64_t (1), playlist->audio_length() / _num_points); - _current.resize (_film->audio_stream()->channels ()); - _analysis.reset (new AudioAnalysis (_film->audio_stream()->channels())); + _current.resize (playlist->audio_channels ()); + _analysis.reset (new AudioAnalysis (playlist->audio_channels())); - while (!decoders.audio->pass()) { - set_progress (float (_done) / total_audio_frames); + while (!playlist->pass()) { + set_progress (float (_done) / playlist->audio_length ()); } _analysis->write (_film->audio_analysis_path ()); diff --git a/src/lib/audio_content.cc b/src/lib/audio_content.cc new file mode 100644 index 000000000..e9eacfd79 --- /dev/null +++ b/src/lib/audio_content.cc @@ -0,0 +1,7 @@ +#include "audio_content.h" + +AudioContent::AudioContent (boost::filesystem::path f) + : Content (f) +{ + +} diff --git a/src/lib/audio_content.h b/src/lib/audio_content.h index 95fd681a7..e18d1082e 100644 --- a/src/lib/audio_content.h +++ b/src/lib/audio_content.h @@ -1,8 +1,19 @@ +#ifndef DVDOMATIC_AUDIO_CONTENT_H +#define DVDOMATIC_AUDIO_CONTENT_H + #include "content.h" +#include "util.h" class AudioContent : public virtual Content { public: - + AudioContent (boost::filesystem::path); + virtual int audio_channels () const = 0; + virtual ContentAudioFrame audio_length () const = 0; + virtual int audio_frame_rate () const = 0; + virtual int64_t audio_channel_layout () const = 0; + }; + +#endif diff --git a/src/lib/audio_decoder.cc b/src/lib/audio_decoder.cc index a54c14843..a72cf11bb 100644 --- a/src/lib/audio_decoder.cc +++ b/src/lib/audio_decoder.cc @@ -18,19 +18,12 @@ */ #include "audio_decoder.h" -#include "stream.h" using boost::optional; using boost::shared_ptr; -AudioDecoder::AudioDecoder (shared_ptr f, DecodeOptions o) +AudioDecoder::AudioDecoder (shared_ptr f, shared_ptr c, DecodeOptions o) : Decoder (f, o) { } - -void -AudioDecoder::set_audio_stream (shared_ptr s) -{ - _audio_stream = s; -} diff --git a/src/lib/audio_decoder.h b/src/lib/audio_decoder.h index 9bef8e0e7..7d2a2bb62 100644 --- a/src/lib/audio_decoder.h +++ b/src/lib/audio_decoder.h @@ -25,34 +25,17 @@ #define DVDOMATIC_AUDIO_DECODER_H #include "audio_source.h" -#include "stream.h" #include "decoder.h" +class AudioContent; + /** @class AudioDecoder. * @brief Parent class for audio decoders. */ class AudioDecoder : public AudioSource, public virtual Decoder { public: - AudioDecoder (boost::shared_ptr, DecodeOptions); - - virtual void set_audio_stream (boost::shared_ptr); - - /** @return Audio stream that we are using */ - boost::shared_ptr audio_stream () const { - return _audio_stream; - } - - /** @return All available audio streams */ - std::vector > audio_streams () const { - return _audio_streams; - } - -protected: - /** Audio stream that we are using */ - boost::shared_ptr _audio_stream; - /** All available audio streams */ - std::vector > _audio_streams; + AudioDecoder (boost::shared_ptr, boost::shared_ptr, DecodeOptions); }; #endif diff --git a/src/lib/content.cc b/src/lib/content.cc new file mode 100644 index 000000000..2fb94e959 --- /dev/null +++ b/src/lib/content.cc @@ -0,0 +1,20 @@ +#include +#include "content.h" +#include "util.h" + +using std::string; +using boost::shared_ptr; + +Content::Content (boost::filesystem::path f) + : _file (f) +{ + +} + +void +Content::examine (shared_ptr, shared_ptr, bool) +{ + string const d = md5_digest (_file); + boost::mutex::scoped_lock lm (_mutex); + _digest = d; +} diff --git a/src/lib/content.h b/src/lib/content.h index c848860aa..25c097424 100644 --- a/src/lib/content.h +++ b/src/lib/content.h @@ -1,17 +1,34 @@ +#ifndef DVDOMATIC_CONTENT_H +#define DVDOMATIC_CONTENT_H + #include +#include #include +class Job; +class Film; + class Content { public: + Content (boost::filesystem::path); + + virtual void examine (boost::shared_ptr, boost::shared_ptr, bool); + virtual std::string summary () const = 0; + boost::filesystem::path file () const { boost::mutex::scoped_lock lm (_mutex); return _file; } + boost::signals2::signal Changed; + protected: - boost::mutex _mutex; + mutable boost::mutex _mutex; private: boost::filesystem::path _file; + std::string _digest; }; + +#endif diff --git a/src/lib/decoder.cc b/src/lib/decoder.cc index 52b22fa06..2fe265c14 100644 --- a/src/lib/decoder.cc +++ b/src/lib/decoder.cc @@ -22,34 +22,21 @@ */ #include -#include -#include #include "film.h" -#include "format.h" #include "options.h" #include "exceptions.h" -#include "image.h" #include "util.h" -#include "log.h" #include "decoder.h" -#include "delay_line.h" -#include "subtitle.h" -#include "filter_graph.h" #include "i18n.h" using std::string; -using std::stringstream; -using std::min; -using std::pair; -using std::list; using boost::shared_ptr; -using boost::optional; /** @param f Film. * @param o Decode options. */ -Decoder::Decoder (boost::shared_ptr f, DecodeOptions o) +Decoder::Decoder (shared_ptr f, DecodeOptions o) : _film (f) , _opt (o) { diff --git a/src/lib/decoder.h b/src/lib/decoder.h index f2f523516..50aa16dba 100644 --- a/src/lib/decoder.h +++ b/src/lib/decoder.h @@ -30,7 +30,6 @@ #include #include #include "util.h" -#include "stream.h" #include "video_source.h" #include "audio_source.h" #include "film.h" @@ -53,7 +52,7 @@ class FilterGraph; class Decoder { public: - Decoder (boost::shared_ptr, DecodeOptions); + Decoder (boost::shared_ptr, DecodeOptions); virtual ~Decoder () {} virtual bool pass () = 0; @@ -63,14 +62,13 @@ public: boost::signals2::signal OutputChanged; protected: - /** our Film */ - boost::shared_ptr _film; + boost::shared_ptr _film; /** our decode options */ DecodeOptions _opt; private: virtual void film_changed (Film::Property) {} - + boost::signals2::scoped_connection _film_connection; }; diff --git a/src/lib/decoder_factory.cc b/src/lib/decoder_factory.cc index f7f9f4074..feaa1c7ef 100644 --- a/src/lib/decoder_factory.cc +++ b/src/lib/decoder_factory.cc @@ -39,22 +39,5 @@ decoder_factory ( shared_ptr f, DecodeOptions o ) { - if (f->content().empty()) { - return Decoders (); - } - - if (boost::filesystem::is_directory (f->content_path()) || f->content_type() == STILL) { - /* A single image file, or a directory of them */ - return Decoders ( - shared_ptr (new ImageMagickDecoder (f, o)), - shared_ptr (new SndfileDecoder (f, o)) - ); - } - - shared_ptr fd (new FFmpegDecoder (f, o)); - if (f->use_content_audio()) { - return Decoders (fd, fd); - } - - return Decoders (fd, shared_ptr (new SndfileDecoder (f, o))); + return Decoders (); } diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 7b338407e..970213793 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -38,6 +38,7 @@ #include "format.h" #include "cross.h" #include "writer.h" +#include "playlist.h" #include "i18n.h" @@ -53,8 +54,9 @@ using namespace boost; int const Encoder::_history_size = 25; /** @param f Film that we are encoding */ -Encoder::Encoder (shared_ptr f) +Encoder::Encoder (shared_ptr f, shared_ptr p) : _film (f) + , _playlist (p) , _video_frames_in (0) , _video_frames_out (0) #ifdef HAVE_SWRESAMPLE @@ -77,22 +79,22 @@ Encoder::~Encoder () void Encoder::process_begin () { - if (_film->audio_stream() && _film->audio_stream()->sample_rate() != _film->target_audio_sample_rate()) { + if (_playlist->has_audio() && _playlist->audio_frame_rate() != _film->target_audio_sample_rate()) { #ifdef HAVE_SWRESAMPLE stringstream s; - s << String::compose (N_("Will resample audio from %1 to %2"), _film->audio_stream()->sample_rate(), _film->target_audio_sample_rate()); + s << String::compose (N_("Will resample audio from %1 to %2"), _playlist->audio_frame_rate(), _film->target_audio_sample_rate()); _film->log()->log (s.str ()); /* We will be using planar float data when we call the resampler */ _swr_context = swr_alloc_set_opts ( 0, - _film->audio_stream()->channel_layout(), + _playlist->audio_channel_layout(), AV_SAMPLE_FMT_FLTP, _film->target_audio_sample_rate(), - _film->audio_stream()->channel_layout(), + _playlist->audio_channel_layout(), AV_SAMPLE_FMT_FLTP, - _film->audio_stream()->sample_rate(), + _playlist->audio_frame_rate(), 0, 0 ); @@ -118,7 +120,7 @@ Encoder::process_begin () } } - _writer.reset (new Writer (_film)); + _writer.reset (new Writer (_film, _playlist)); } @@ -126,9 +128,9 @@ void Encoder::process_end () { #if HAVE_SWRESAMPLE - if (_film->audio_stream() && _film->audio_stream()->channels() && _swr_context) { + if (_playlist->has_audio() && _playlist->audio_channels() && _swr_context) { - shared_ptr out (new AudioBuffers (_film->audio_stream()->channels(), 256)); + shared_ptr out (new AudioBuffers (_playlist->audio_channels(), 256)); while (1) { int const frames = swr_convert (_swr_context, (uint8_t **) out->data(), 256, 0, 0); @@ -233,7 +235,7 @@ Encoder::frame_done () void Encoder::process_video (shared_ptr image, bool same, boost::shared_ptr sub) { - FrameRateConversion frc (_film->source_frame_rate(), _film->dcp_frame_rate()); + FrameRateConversion frc (_playlist->video_frame_rate(), _film->dcp_frame_rate()); if (frc.skip && (_video_frames_in % 2)) { ++_video_frames_in; @@ -271,7 +273,7 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptr ( new DCPVideoFrame ( - image, sub, _film->format()->dcp_size(), _film->format()->dcp_padding (_film), + image, sub, _film->format()->dcp_size(), _film->format()->dcp_padding (_playlist), _film->subtitle_offset(), _film->subtitle_scale(), _film->scaler(), _video_frames_out, _film->dcp_frame_rate(), s.second, _film->colour_lut(), _film->j2k_bandwidth(), @@ -301,9 +303,9 @@ Encoder::process_audio (shared_ptr data) if (_swr_context) { /* Compute the resampled frames count and add 32 for luck */ - int const max_resampled_frames = ceil ((int64_t) data->frames() * _film->target_audio_sample_rate() / _film->audio_stream()->sample_rate()) + 32; + int const max_resampled_frames = ceil ((int64_t) data->frames() * _film->target_audio_sample_rate() / _playlist->audio_frame_rate()) + 32; - shared_ptr resampled (new AudioBuffers (_film->audio_stream()->channels(), max_resampled_frames)); + shared_ptr resampled (new AudioBuffers (_playlist->audio_channels(), max_resampled_frames)); /* Resample audio */ int const resampled_frames = swr_convert ( @@ -425,8 +427,8 @@ Encoder::encoder_thread (ServerDescription* server) void Encoder::write_audio (shared_ptr data) { - AudioMapping m (_film->audio_channels ()); - if (m.dcp_channels() != _film->audio_channels()) { + AudioMapping m (_playlist->audio_channels ()); + if (m.dcp_channels() != _playlist->audio_channels()) { /* Remap (currently just for mono -> 5.1) */ diff --git a/src/lib/encoder.h b/src/lib/encoder.h index 86880bc34..c84ee027a 100644 --- a/src/lib/encoder.h +++ b/src/lib/encoder.h @@ -51,6 +51,7 @@ class ServerDescription; class DCPVideoFrame; class EncodedData; class Writer; +class Playlist; /** @class Encoder * @brief Encoder to J2K and WAV for DCP. @@ -62,7 +63,7 @@ class Writer; class Encoder : public VideoSink, public AudioSink { public: - Encoder (boost::shared_ptr f); + Encoder (boost::shared_ptr f, boost::shared_ptr); virtual ~Encoder (); /** Called to indicate that a processing run is about to begin */ @@ -95,6 +96,7 @@ private: /** Film that we are encoding */ boost::shared_ptr _film; + boost::shared_ptr _playlist; /** Mutex for _time_history and _last_frame */ mutable boost::mutex _history_mutex; diff --git a/src/lib/examine_content_job.cc b/src/lib/examine_content_job.cc index 4b30c9431..c600132c3 100644 --- a/src/lib/examine_content_job.cc +++ b/src/lib/examine_content_job.cc @@ -17,29 +17,21 @@ */ -/** @file src/examine_content_job.cc - * @brief A class to run through content at high speed to find its length. - */ - #include #include "examine_content_job.h" #include "options.h" -#include "decoder_factory.h" -#include "decoder.h" -#include "transcoder.h" #include "log.h" -#include "film.h" -#include "video_decoder.h" +#include "content.h" #include "i18n.h" using std::string; -using std::vector; -using std::pair; using boost::shared_ptr; -ExamineContentJob::ExamineContentJob (shared_ptr f) +ExamineContentJob::ExamineContentJob (shared_ptr f, shared_ptr c, bool q) : Job (f) + , _content (c) + , _quick (q) { } @@ -51,60 +43,13 @@ ExamineContentJob::~ExamineContentJob () string ExamineContentJob::name () const { - if (_film->name().empty ()) { - return _("Examine content"); - } - - return String::compose (_("Examine content of %1"), _film->name()); + return _("Examine content"); } void ExamineContentJob::run () { - descend (0.5); - _film->set_content_digest (md5_digest (_film->content_path ())); - ascend (); - - descend (0.5); - - /* Set the film's length to either - a) a length judged by running through the content or - b) the length from a decoder's header. - */ - if (!_film->trust_content_header()) { - /* Decode the content to get an accurate length */ - - /* We don't want to use any existing length here, as progress - will be messed up. - */ - _film->unset_length (); - _film->set_crop (Crop ()); - - DecodeOptions o; - o.decode_audio = false; - - Decoders decoders = decoder_factory (_film, o); - - set_progress_unknown (); - while (!decoders.video->pass()) { - /* keep going */ - } - - _film->set_length (decoders.video->video_frame()); - - _film->log()->log (String::compose (N_("Video length examined as %1 frames"), _film->length().get())); - - } else { - - /* Get a quick decoder to get the content's length from its header */ - - Decoders d = decoder_factory (_film, DecodeOptions()); - _film->set_length (d.video->length()); - - _film->log()->log (String::compose (N_("Video length obtained from header as %1 frames"), _film->length().get())); - } - - ascend (); + _content->examine (_film, shared_from_this (), _quick); set_progress (1); set_state (FINISHED_OK); } diff --git a/src/lib/examine_content_job.h b/src/lib/examine_content_job.h index 8ee4f0d60..dc0d53fff 100644 --- a/src/lib/examine_content_job.h +++ b/src/lib/examine_content_job.h @@ -17,22 +17,23 @@ */ -/** @file src/examine_content_job.h - * @brief A class to obtain the length and MD5 digest of a content file. - */ - +#include #include "job.h" -/** @class ExamineContentJob - * @brief A class to obtain the length and MD5 digest of a content file. - */ +class Content; +class Log; + class ExamineContentJob : public Job { public: - ExamineContentJob (boost::shared_ptr); + ExamineContentJob (boost::shared_ptr, boost::shared_ptr, bool); ~ExamineContentJob (); std::string name () const; void run (); + +private: + boost::shared_ptr _content; + bool _quick; }; diff --git a/src/lib/exceptions.h b/src/lib/exceptions.h index e45a62353..6920556e5 100644 --- a/src/lib/exceptions.h +++ b/src/lib/exceptions.h @@ -112,6 +112,7 @@ class OpenFileError : public FileError { public: /** @param f File that we were trying to open */ + /* XXX: should be boost::filesystem::path */ OpenFileError (std::string f); }; diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc new file mode 100644 index 000000000..25efb1ebf --- /dev/null +++ b/src/lib/ffmpeg_content.cc @@ -0,0 +1,156 @@ +#include "ffmpeg_content.h" +#include "ffmpeg_decoder.h" +#include "options.h" +#include "compose.hpp" +#include "job.h" +#include "util.h" +#include "log.h" + +#include "i18n.h" + +using std::string; +using boost::shared_ptr; + +int const FFmpegContentProperty::SUBTITLE_STREAMS = 100; +int const FFmpegContentProperty::SUBTITLE_STREAM = 101; +int const FFmpegContentProperty::AUDIO_STREAMS = 102; +int const FFmpegContentProperty::AUDIO_STREAM = 103; + +FFmpegContent::FFmpegContent (boost::filesystem::path f) + : Content (f) + , VideoContent (f) + , AudioContent (f) +{ + +} + +void +FFmpegContent::examine (shared_ptr film, shared_ptr job, bool quick) +{ + job->descend (0.5); + Content::examine (film, job, quick); + job->ascend (); + + job->set_progress_unknown (); + + DecodeOptions o; + o.decode_audio = false; + shared_ptr decoder (new FFmpegDecoder (film, shared_from_this (), o)); + + ContentVideoFrame video_length = 0; + if (quick) { + video_length = decoder->video_length (); + film->log()->log (String::compose ("Video length obtained from header as %1 frames", decoder->video_length ())); + } else { + while (!decoder->pass ()) { + /* keep going */ + } + + video_length = decoder->video_frame (); + film->log()->log (String::compose ("Video length examined as %1 frames", decoder->video_frame ())); + } + + { + boost::mutex::scoped_lock lm (_mutex); + + _video_length = video_length; + + _subtitle_streams = decoder->subtitle_streams (); + if (!_subtitle_streams.empty ()) { + _subtitle_stream = _subtitle_streams.front (); + } + + _audio_streams = decoder->audio_streams (); + if (!_audio_streams.empty ()) { + _audio_stream = _audio_streams.front (); + } + } + + take_from_video_decoder (decoder); + + Changed (VideoContentProperty::VIDEO_LENGTH); + Changed (FFmpegContentProperty::SUBTITLE_STREAMS); + Changed (FFmpegContentProperty::SUBTITLE_STREAM); + Changed (FFmpegContentProperty::AUDIO_STREAMS); + Changed (FFmpegContentProperty::AUDIO_STREAM); +} + +string +FFmpegContent::summary () const +{ + return String::compose (_("Movie: %1"), file().filename ()); +} + +void +FFmpegContent::set_subtitle_stream (FFmpegSubtitleStream s) +{ + { + boost::mutex::scoped_lock lm (_mutex); + _subtitle_stream = s; + } + + Changed (FFmpegContentProperty::SUBTITLE_STREAM); +} + +void +FFmpegContent::set_audio_stream (FFmpegAudioStream s) +{ + { + boost::mutex::scoped_lock lm (_mutex); + _audio_stream = s; + } + + Changed (FFmpegContentProperty::AUDIO_STREAM); +} + +ContentAudioFrame +FFmpegContent::audio_length () const +{ + if (!_audio_stream) { + return 0; + } + + return video_frames_to_audio_frames (_video_length, audio_frame_rate(), video_frame_rate()); +} + +int +FFmpegContent::audio_channels () const +{ + if (!_audio_stream) { + return 0; + } + + return _audio_stream->channels (); +} + +int +FFmpegContent::audio_frame_rate () const +{ + if (!_audio_stream) { + return 0; + } + + return _audio_stream->frame_rate; +} + +int64_t +FFmpegContent::audio_channel_layout () const +{ + if (!_audio_stream) { + return 0; + } + + return _audio_stream->channel_layout; +} + +bool +operator== (FFmpegSubtitleStream const & a, FFmpegSubtitleStream const & b) +{ + return a.id == b.id; +} + +bool +operator== (FFmpegAudioStream const & a, FFmpegAudioStream const & b) +{ + return a.id == b.id; +} diff --git a/src/lib/ffmpeg_content.h b/src/lib/ffmpeg_content.h index 8b3eca62d..83474ea66 100644 --- a/src/lib/ffmpeg_content.h +++ b/src/lib/ffmpeg_content.h @@ -1,8 +1,97 @@ -#include "content.h" +#ifndef DVDOMATIC_FFMPEG_CONTENT_H +#define DVDOMATIC_FFMPEG_CONTENT_H -class FFmpegContent : public VideoContent, public AudioContent +#include +#include "video_content.h" +#include "audio_content.h" + +class FFmpegAudioStream +{ +public: + FFmpegAudioStream (std::string n, int i, int f, int64_t c) + : name (n) + , id (i) + , frame_rate (f) + , channel_layout (c) + {} + + int channels () const { + return av_get_channel_layout_nb_channels (channel_layout); + } + + std::string name; + int id; + int frame_rate; + int64_t channel_layout; +}; + +extern bool operator== (FFmpegAudioStream const & a, FFmpegAudioStream const & b); + +class FFmpegSubtitleStream +{ +public: + FFmpegSubtitleStream (std::string n, int i) + : name (n) + , id (i) + {} + + std::string name; + int id; +}; + +extern bool operator== (FFmpegSubtitleStream const & a, FFmpegSubtitleStream const & b); + +class FFmpegContentProperty : public VideoContentProperty +{ +public: + static int const SUBTITLE_STREAMS; + static int const SUBTITLE_STREAM; + static int const AUDIO_STREAMS; + static int const AUDIO_STREAM; +}; + +class FFmpegContent : public VideoContent, public AudioContent, public boost::enable_shared_from_this { public: + FFmpegContent (boost::filesystem::path); + void examine (boost::shared_ptr, boost::shared_ptr, bool); + std::string summary () const; + /* AudioContent */ + int audio_channels () const; + ContentAudioFrame audio_length () const; + int audio_frame_rate () const; + int64_t audio_channel_layout () const; + + std::vector subtitle_streams () const { + boost::mutex::scoped_lock lm (_mutex); + return _subtitle_streams; + } + + boost::optional subtitle_stream () const { + boost::mutex::scoped_lock lm (_mutex); + return _subtitle_stream; + } + + std::vector audio_streams () const { + boost::mutex::scoped_lock lm (_mutex); + return _audio_streams; + } + + boost::optional audio_stream () const { + boost::mutex::scoped_lock lm (_mutex); + return _audio_stream; + } + + void set_subtitle_stream (FFmpegSubtitleStream); + void set_audio_stream (FFmpegAudioStream); + +private: + std::vector _subtitle_streams; + boost::optional _subtitle_stream; + std::vector _audio_streams; + boost::optional _audio_stream; }; + +#endif diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index ac25844e3..c8e46776f 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -62,10 +62,11 @@ using boost::optional; using boost::dynamic_pointer_cast; using libdcp::Size; -FFmpegDecoder::FFmpegDecoder (shared_ptr f, DecodeOptions o) +FFmpegDecoder::FFmpegDecoder (shared_ptr f, shared_ptr c, DecodeOptions o) : Decoder (f, o) - , VideoDecoder (f, o) - , AudioDecoder (f, o) + , VideoDecoder (f, c, o) + , AudioDecoder (f, c, o) + , _ffmpeg_content (c) , _format_context (0) , _video_stream (-1) , _frame (0) @@ -110,8 +111,8 @@ FFmpegDecoder::setup_general () { av_register_all (); - if (avformat_open_input (&_format_context, _film->content_path().c_str(), 0, 0) < 0) { - throw OpenFileError (_film->content_path ()); + if (avformat_open_input (&_format_context, _ffmpeg_content->file().string().c_str(), 0, 0) < 0) { + throw OpenFileError (_ffmpeg_content->file().string ()); } if (avformat_find_stream_info (_format_context, 0) < 0) { @@ -135,17 +136,11 @@ FFmpegDecoder::setup_general () } _audio_streams.push_back ( - shared_ptr ( - new FFmpegAudioStream (stream_name (s), i, s->codec->sample_rate, s->codec->channel_layout) - ) + FFmpegAudioStream (stream_name (s), i, s->codec->sample_rate, s->codec->channel_layout) ); } else if (s->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) { - _subtitle_streams.push_back ( - shared_ptr ( - new SubtitleStream (stream_name (s), i) - ) - ); + _subtitle_streams.push_back (FFmpegSubtitleStream (stream_name (s), i)); } } @@ -177,14 +172,11 @@ FFmpegDecoder::setup_video () void FFmpegDecoder::setup_audio () { - if (!_audio_stream) { + if (!_ffmpeg_content->audio_stream ()) { return; } - shared_ptr ffa = dynamic_pointer_cast (_audio_stream); - assert (ffa); - - _audio_codec_context = _format_context->streams[ffa->id()]->codec; + _audio_codec_context = _format_context->streams[_ffmpeg_content->audio_stream()->id]->codec; _audio_codec = avcodec_find_decoder (_audio_codec_context->codec_id); if (_audio_codec == 0) { @@ -199,11 +191,11 @@ FFmpegDecoder::setup_audio () void FFmpegDecoder::setup_subtitle () { - if (!_subtitle_stream || _subtitle_stream->id() >= int (_format_context->nb_streams)) { + if (!_ffmpeg_content->subtitle_stream() || _ffmpeg_content->subtitle_stream()->id >= int (_format_context->nb_streams)) { return; } - _subtitle_codec_context = _format_context->streams[_subtitle_stream->id()]->codec; + _subtitle_codec_context = _format_context->streams[_ffmpeg_content->subtitle_stream()->id]->codec; _subtitle_codec = avcodec_find_decoder (_subtitle_codec_context->codec_id); if (_subtitle_codec == 0) { @@ -244,7 +236,7 @@ FFmpegDecoder::pass () } } - if (_audio_stream && _opt.decode_audio) { + if (_ffmpeg_content->audio_stream() && _opt.decode_audio) { decode_audio_packet (); } @@ -253,8 +245,6 @@ FFmpegDecoder::pass () avcodec_get_frame_defaults (_frame); - shared_ptr ffa = dynamic_pointer_cast (_audio_stream); - if (_packet.stream_index == _video_stream && _opt.decode_video) { int frame_finished; @@ -272,9 +262,9 @@ FFmpegDecoder::pass () } } - } else if (ffa && _packet.stream_index == ffa->id() && _opt.decode_audio) { + } else if (_ffmpeg_content->audio_stream() && _packet.stream_index == _ffmpeg_content->audio_stream()->id && _opt.decode_audio) { decode_audio_packet (); - } else if (_subtitle_stream && _packet.stream_index == _subtitle_stream->id() && _opt.decode_subtitles && _first_video) { + } else if (_ffmpeg_content->subtitle_stream() && _packet.stream_index == _ffmpeg_content->subtitle_stream()->id && _opt.decode_subtitles && _first_video) { int got_subtitle; AVSubtitle sub; @@ -306,19 +296,16 @@ FFmpegDecoder::pass () shared_ptr FFmpegDecoder::deinterleave_audio (uint8_t** data, int size) { - assert (_film->audio_channels()); + assert (_ffmpeg_content->audio_channels()); assert (bytes_per_audio_sample()); - shared_ptr ffa = dynamic_pointer_cast (_audio_stream); - assert (ffa); - /* Deinterleave and convert to float */ - assert ((size % (bytes_per_audio_sample() * ffa->channels())) == 0); + assert ((size % (bytes_per_audio_sample() * _ffmpeg_content->audio_channels())) == 0); int const total_samples = size / bytes_per_audio_sample(); - int const frames = total_samples / _film->audio_channels(); - shared_ptr audio (new AudioBuffers (ffa->channels(), frames)); + int const frames = total_samples / _ffmpeg_content->audio_channels(); + shared_ptr audio (new AudioBuffers (_ffmpeg_content->audio_channels(), frames)); switch (audio_sample_format()) { case AV_SAMPLE_FMT_S16: @@ -330,7 +317,7 @@ FFmpegDecoder::deinterleave_audio (uint8_t** data, int size) audio->data(channel)[sample] = float(*p++) / (1 << 15); ++channel; - if (channel == _film->audio_channels()) { + if (channel == _ffmpeg_content->audio_channels()) { channel = 0; ++sample; } @@ -341,7 +328,7 @@ FFmpegDecoder::deinterleave_audio (uint8_t** data, int size) case AV_SAMPLE_FMT_S16P: { int16_t** p = reinterpret_cast (data); - for (int i = 0; i < _film->audio_channels(); ++i) { + for (int i = 0; i < _ffmpeg_content->audio_channels(); ++i) { for (int j = 0; j < frames; ++j) { audio->data(i)[j] = static_cast(p[i][j]) / (1 << 15); } @@ -358,7 +345,7 @@ FFmpegDecoder::deinterleave_audio (uint8_t** data, int size) audio->data(channel)[sample] = static_cast(*p++) / (1 << 31); ++channel; - if (channel == _film->audio_channels()) { + if (channel == _ffmpeg_content->audio_channels()) { channel = 0; ++sample; } @@ -375,7 +362,7 @@ FFmpegDecoder::deinterleave_audio (uint8_t** data, int size) audio->data(channel)[sample] = *p++; ++channel; - if (channel == _film->audio_channels()) { + if (channel == _ffmpeg_content->audio_channels()) { channel = 0; ++sample; } @@ -386,7 +373,7 @@ FFmpegDecoder::deinterleave_audio (uint8_t** data, int size) case AV_SAMPLE_FMT_FLTP: { float** p = reinterpret_cast (data); - for (int i = 0; i < _film->audio_channels(); ++i) { + for (int i = 0; i < _ffmpeg_content->audio_channels(); ++i) { memcpy (audio->data(i), p[i], frames * sizeof(float)); } } @@ -488,21 +475,6 @@ FFmpegDecoder::bytes_per_audio_sample () const return av_get_bytes_per_sample (audio_sample_format ()); } -void -FFmpegDecoder::set_audio_stream (shared_ptr s) -{ - AudioDecoder::set_audio_stream (s); - setup_audio (); -} - -void -FFmpegDecoder::set_subtitle_stream (shared_ptr s) -{ - VideoDecoder::set_subtitle_stream (s); - setup_subtitle (); - OutputChanged (); -} - void FFmpegDecoder::filter_and_emit_video (AVFrame* frame) { @@ -561,58 +533,6 @@ FFmpegDecoder::do_seek (double p, bool backwards) return r < 0; } -shared_ptr -FFmpegAudioStream::create (string t, optional v) -{ - if (!v) { - /* version < 1; no type in the string, and there's only FFmpeg streams anyway */ - return shared_ptr (new FFmpegAudioStream (t, v)); - } - - stringstream s (t); - string type; - s >> type; - if (type != N_("ffmpeg")) { - return shared_ptr (); - } - - return shared_ptr (new FFmpegAudioStream (t, v)); -} - -FFmpegAudioStream::FFmpegAudioStream (string t, optional version) -{ - stringstream n (t); - - int name_index = 4; - if (!version) { - name_index = 2; - int channels; - n >> _id >> channels; - _channel_layout = av_get_default_channel_layout (channels); - _sample_rate = 0; - } else { - string type; - /* Current (marked version 1) */ - n >> type >> _id >> _sample_rate >> _channel_layout; - assert (type == N_("ffmpeg")); - } - - for (int i = 0; i < name_index; ++i) { - size_t const s = t.find (' '); - if (s != string::npos) { - t = t.substr (s + 1); - } - } - - _name = t; -} - -string -FFmpegAudioStream::to_string () const -{ - return String::compose (N_("ffmpeg %1 %2 %3 %4"), _id, _sample_rate, _channel_layout, _name); -} - void FFmpegDecoder::out_with_sync () { @@ -678,8 +598,8 @@ FFmpegDecoder::film_changed (Film::Property p) } /** @return Length (in video frames) according to our content's header */ -SourceFrame -FFmpegDecoder::length () const +ContentVideoFrame +FFmpegDecoder::video_length () const { return (double(_format_context->duration) / AV_TIME_BASE) * frames_per_second(); } @@ -693,9 +613,6 @@ FFmpegDecoder::frame_time () const void FFmpegDecoder::decode_audio_packet () { - shared_ptr ffa = dynamic_pointer_cast (_audio_stream); - assert (ffa); - /* Audio packets can contain multiple frames, so we may have to call avcodec_decode_audio4 several times. */ @@ -727,17 +644,17 @@ FFmpegDecoder::decode_audio_packet () */ /* frames of silence that we must push */ - int const s = rint ((_first_audio.get() - _first_video.get()) * ffa->sample_rate ()); + int const s = rint ((_first_audio.get() - _first_video.get()) * _ffmpeg_content->audio_frame_rate ()); _film->log()->log ( String::compose ( N_("First video at %1, first audio at %2, pushing %3 audio frames of silence for %4 channels (%5 bytes per sample)"), - _first_video.get(), _first_audio.get(), s, ffa->channels(), bytes_per_audio_sample() + _first_video.get(), _first_audio.get(), s, _ffmpeg_content->audio_channels(), bytes_per_audio_sample() ) ); if (s) { - shared_ptr audio (new AudioBuffers (ffa->channels(), s)); + shared_ptr audio (new AudioBuffers (_ffmpeg_content->audio_channels(), s)); audio->make_silent (); Audio (audio); } @@ -747,7 +664,7 @@ FFmpegDecoder::decode_audio_packet () 0, _audio_codec_context->channels, _frame->nb_samples, audio_sample_format (), 1 ); - assert (_audio_codec_context->channels == _film->audio_channels()); + assert (_audio_codec_context->channels == _ffmpeg_content->audio_channels()); Audio (deinterleave_audio (_frame->data, data_size)); } } diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h index 1bb14ce9c..a0900d89f 100644 --- a/src/lib/ffmpeg_decoder.h +++ b/src/lib/ffmpeg_decoder.h @@ -36,6 +36,7 @@ extern "C" { #include "video_decoder.h" #include "audio_decoder.h" #include "film.h" +#include "ffmpeg_content.h" struct AVFilterGraph; struct AVCodecContext; @@ -50,62 +51,37 @@ class Options; class Image; class Log; -class FFmpegAudioStream : public AudioStream -{ -public: - FFmpegAudioStream (std::string n, int i, int s, int64_t c) - : AudioStream (s, c) - , _name (n) - , _id (i) - {} - - std::string to_string () const; - - std::string name () const { - return _name; - } - - int id () const { - return _id; - } - - static boost::shared_ptr create (std::string t, boost::optional v); - -private: - friend class stream_test; - - FFmpegAudioStream (std::string t, boost::optional v); - - std::string _name; - int _id; -}; - /** @class FFmpegDecoder * @brief A decoder using FFmpeg to decode content. */ class FFmpegDecoder : public VideoDecoder, public AudioDecoder { public: - FFmpegDecoder (boost::shared_ptr, DecodeOptions); + FFmpegDecoder (boost::shared_ptr, boost::shared_ptr, DecodeOptions); ~FFmpegDecoder (); float frames_per_second () const; libdcp::Size native_size () const; - SourceFrame length () const; + ContentVideoFrame video_length () const; int time_base_numerator () const; int time_base_denominator () const; int sample_aspect_ratio_numerator () const; int sample_aspect_ratio_denominator () const; - void set_audio_stream (boost::shared_ptr); - void set_subtitle_stream (boost::shared_ptr); + std::vector subtitle_streams () const { + return _subtitle_streams; + } + + std::vector audio_streams () const { + return _audio_streams; + } bool seek (double); bool seek_to_last (); + bool pass (); private: - bool pass (); bool do_seek (double p, bool); PixelFormat pixel_format () const; AVSampleFormat audio_sample_format () const; @@ -129,6 +105,8 @@ private: std::string stream_name (AVStream* s) const; + boost::shared_ptr _ffmpeg_content; + AVFormatContext* _format_context; int _video_stream; @@ -148,4 +126,7 @@ private: std::list > _filter_graphs; boost::mutex _filter_graphs_mutex; + + std::vector _subtitle_streams; + std::vector _audio_streams; }; diff --git a/src/lib/film.cc b/src/lib/film.cc index 0d969f16d..f69f63fd8 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -52,6 +52,7 @@ #include "audio_decoder.h" #include "sndfile_decoder.h" #include "analyse_audio_job.h" +#include "playlist.h" #include "i18n.h" @@ -135,8 +136,6 @@ Film::Film (string d, bool must_exist) } } - _sndfile_stream = SndfileStream::create (); - if (must_exist) { read_metadata (); } @@ -162,7 +161,6 @@ Film::Film (Film const & o) , _dcp_ab (o._dcp_ab) , _audio_gain (o._audio_gain) , _audio_delay (o._audio_delay) - , _still_duration (o._still_duration) , _with_subtitles (o._with_subtitles) , _subtitle_offset (o._subtitle_offset) , _subtitle_scale (o._subtitle_scale) @@ -186,6 +184,10 @@ Film::video_state_identifier () const { assert (format ()); + return "XXX"; + +#if 0 + pair f = Filter::ffmpeg_strings (filters()); stringstream s; @@ -204,6 +206,7 @@ Film::video_state_identifier () const } return s.str (); +#endif } /** @return The path to the directory to write video frame info files to */ @@ -234,7 +237,7 @@ Film::audio_analysis_path () const { boost::filesystem::path p; p /= "analysis"; - p /= content_digest(); + p /= "XXX";//content_digest(); return file (p.string ()); } @@ -256,12 +259,12 @@ Film::make_dcp () log()->log (String::compose ("Starting to make DCP on %1", buffer)); } - log()->log (String::compose ("Content is %1; type %2", content_path(), (content_type() == STILL ? _("still") : _("video")))); - if (length()) { - log()->log (String::compose ("Content length %1", length().get())); - } - log()->log (String::compose ("Content digest %1", content_digest())); - log()->log (String::compose ("Content at %1 fps, DCP at %2 fps", source_frame_rate(), dcp_frame_rate())); +// log()->log (String::compose ("Content is %1; type %2", content_path(), (content_type() == STILL ? _("still") : _("video")))); +// if (length()) { +// log()->log (String::compose ("Content length %1", length().get())); +// } +// log()->log (String::compose ("Content digest %1", content_digest())); +// log()->log (String::compose ("Content at %1 fps, DCP at %2 fps", source_frame_rate(), dcp_frame_rate())); log()->log (String::compose ("%1 threads", Config::instance()->num_local_encoding_threads())); log()->log (String::compose ("J2K bandwidth %1", j2k_bandwidth())); #ifdef DVDOMATIC_DEBUG @@ -318,17 +321,13 @@ Film::analyse_audio () JobManager::instance()->add (_analyse_audio_job); } -/** Start a job to examine our content file */ +/** Start a job to examine a piece of content */ void -Film::examine_content () +Film::examine_content (shared_ptr c) { - if (_examine_content_job) { - return; - } - - _examine_content_job.reset (new ExamineContentJob (shared_from_this())); - _examine_content_job->Finished.connect (bind (&Film::examine_content_finished, this)); - JobManager::instance()->add (_examine_content_job); + shared_ptr j (new ExamineContentJob (shared_from_this(), c, trust_content_header ())); + j->Finished.connect (bind (&Film::examine_content_finished, this)); + JobManager::instance()->add (j); } void @@ -346,7 +345,7 @@ Film::analyse_audio_finished () void Film::examine_content_finished () { - _examine_content_job.reset (); + /* XXX */ } /** Start a job to send our DCP to the configured TMS */ @@ -395,7 +394,7 @@ Film::write_metadata () const /* User stuff */ f << "name " << _name << endl; f << "use_dci_name " << _use_dci_name << endl; - f << "content " << _content << endl; +// f << "content " << _content << endl; f << "trust_content_header " << (_trust_content_header ? "1" : "0") << endl; if (_dcp_content_type) { f << "dcp_content_type " << _dcp_content_type->dci_name () << endl; @@ -414,19 +413,19 @@ Film::write_metadata () const f << "trim_start " << _trim_start << endl; f << "trim_end " << _trim_end << endl; f << "dcp_ab " << (_dcp_ab ? "1" : "0") << endl; - if (_content_audio_stream) { - f << "selected_content_audio_stream " << _content_audio_stream->to_string() << endl; - } - for (vector::const_iterator i = _external_audio.begin(); i != _external_audio.end(); ++i) { - f << "external_audio " << *i << endl; - } - f << "use_content_audio " << (_use_content_audio ? "1" : "0") << endl; +// if (_content_audio_stream) { +// f << "selected_content_audio_stream " << _content_audio_stream->to_string() << endl; +// } +// for (vector::const_iterator i = _external_audio.begin(); i != _external_audio.end(); ++i) { +// f << "external_audio " << *i << endl; +// } +// f << "use_content_audio " << (_use_content_audio ? "1" : "0") << endl; f << "audio_gain " << _audio_gain << endl; f << "audio_delay " << _audio_delay << endl; - f << "still_duration " << _still_duration << endl; - if (_subtitle_stream) { - f << "selected_subtitle_stream " << _subtitle_stream->to_string() << endl; - } +// f << "still_duration " << _still_duration << endl; +// if (_subtitle_stream) { +// f << "selected_subtitle_stream " << _subtitle_stream->to_string() << endl; +// } f << "with_subtitles " << _with_subtitles << endl; f << "subtitle_offset " << _subtitle_offset << endl; f << "subtitle_scale " << _subtitle_scale << endl; @@ -435,22 +434,22 @@ Film::write_metadata () const _dci_metadata.write (f); f << "dci_date " << boost::gregorian::to_iso_string (_dci_date) << endl; f << "dcp_frame_rate " << _dcp_frame_rate << endl; - f << "width " << _size.width << endl; - f << "height " << _size.height << endl; - f << "length " << _length.get_value_or(0) << endl; - f << "content_digest " << _content_digest << endl; +// f << "width " << _size.width << endl; +// f << "height " << _size.height << endl; +// f << "length " << _length.get_value_or(0) << endl; +// f << "content_digest " << _content_digest << endl; - for (vector >::const_iterator i = _content_audio_streams.begin(); i != _content_audio_streams.end(); ++i) { - f << "content_audio_stream " << (*i)->to_string () << endl; - } +// for (vector >::const_iterator i = _content_audio_streams.begin(); i != _content_audio_streams.end(); ++i) { +// f << "content_audio_stream " << (*i)->to_string () << endl; +// } - f << "external_audio_stream " << _sndfile_stream->to_string() << endl; +// f << "external_audio_stream " << _sndfile_stream->to_string() << endl; - for (vector >::const_iterator i = _subtitle_streams.begin(); i != _subtitle_streams.end(); ++i) { - f << "subtitle_stream " << (*i)->to_string () << endl; - } +// for (vector >::const_iterator i = _subtitle_streams.begin(); i != _subtitle_streams.end(); ++i) { +// f << "subtitle_stream " << (*i)->to_string () << endl; +// } - f << "source_frame_rate " << _source_frame_rate << endl; +// f << "source_frame_rate " << _source_frame_rate << endl; _dirty = false; } @@ -461,9 +460,9 @@ Film::read_metadata () { boost::mutex::scoped_lock lm (_state_mutex); - _external_audio.clear (); - _content_audio_streams.clear (); - _subtitle_streams.clear (); +// _external_audio.clear (); +// _content_audio_streams.clear (); +// _subtitle_streams.clear (); boost::optional version; @@ -499,7 +498,7 @@ Film::read_metadata () } else if (k == "use_dci_name") { _use_dci_name = (v == "1"); } else if (k == "content") { - _content = v; +// _content = v; } else if (k == "trust_content_header") { _trust_content_header = (v == "1"); } else if (k == "dcp_content_type") { @@ -532,23 +531,23 @@ Film::read_metadata () if (!version) { audio_stream_index = atoi (v.c_str ()); } else { - _content_audio_stream = audio_stream_factory (v, version); +// _content_audio_stream = audio_stream_factory (v, version); } } else if (k == "external_audio") { - _external_audio.push_back (v); +// _external_audio.push_back (v); } else if (k == "use_content_audio") { - _use_content_audio = (v == "1"); +// _use_content_audio = (v == "1"); } else if (k == "audio_gain") { _audio_gain = atof (v.c_str ()); } else if (k == "audio_delay") { _audio_delay = atoi (v.c_str ()); } else if (k == "still_duration") { - _still_duration = atoi (v.c_str ()); +// _still_duration = atoi (v.c_str ()); } else if (k == "selected_subtitle_stream") { if (!version) { subtitle_stream_index = atoi (v.c_str ()); } else { - _subtitle_stream = subtitle_stream_factory (v, version); +// _subtitle_stream = subtitle_stream_factory (v, version); } } else if (k == "with_subtitles") { _with_subtitles = (v == "1"); @@ -570,50 +569,31 @@ Film::read_metadata () /* Cached stuff */ if (k == "width") { - _size.width = atoi (v.c_str ()); +// _size.width = atoi (v.c_str ()); } else if (k == "height") { - _size.height = atoi (v.c_str ()); +// _size.height = atoi (v.c_str ()); } else if (k == "length") { int const vv = atoi (v.c_str ()); if (vv) { - _length = vv; +// _length = vv; } } else if (k == "content_digest") { - _content_digest = v; +// _content_digest = v; } else if (k == "content_audio_stream" || (!version && k == "audio_stream")) { - _content_audio_streams.push_back (audio_stream_factory (v, version)); +// _content_audio_streams.push_back (audio_stream_factory (v, version)); } else if (k == "external_audio_stream") { - _sndfile_stream = audio_stream_factory (v, version); +// _sndfile_stream = audio_stream_factory (v, version); } else if (k == "subtitle_stream") { - _subtitle_streams.push_back (subtitle_stream_factory (v, version)); +// _subtitle_streams.push_back (subtitle_stream_factory (v, version)); } else if (k == "source_frame_rate") { - _source_frame_rate = atof (v.c_str ()); +// _source_frame_rate = atof (v.c_str ()); } else if (version < 4 && k == "frames_per_second") { - _source_frame_rate = atof (v.c_str ()); +// _source_frame_rate = atof (v.c_str ()); /* Fill in what would have been used for DCP frame rate by the older version */ - _dcp_frame_rate = best_dcp_frame_rate (_source_frame_rate); +// _dcp_frame_rate = best_dcp_frame_rate (_source_frame_rate); } } - if (!version) { - if (audio_sample_rate) { - /* version < 1 didn't specify sample rate in the audio streams, so fill it in here */ - for (vector >::iterator i = _content_audio_streams.begin(); i != _content_audio_streams.end(); ++i) { - (*i)->set_sample_rate (audio_sample_rate.get()); - } - } - - /* also the selected stream was specified as an index */ - if (audio_stream_index && audio_stream_index.get() >= 0 && audio_stream_index.get() < (int) _content_audio_streams.size()) { - _content_audio_stream = _content_audio_streams[audio_stream_index.get()]; - } - - /* similarly the subtitle */ - if (subtitle_stream_index && subtitle_stream_index.get() >= 0 && subtitle_stream_index.get() < (int) _subtitle_streams.size()) { - _subtitle_stream = _subtitle_streams[subtitle_stream_index.get()]; - } - } - _dirty = false; } @@ -661,47 +641,21 @@ Film::file (string f) const return p.string (); } -/** @return full path of the content (actual video) file - * of the Film. - */ -string -Film::content_path () const -{ - boost::mutex::scoped_lock lm (_state_mutex); - if (boost::filesystem::path(_content).has_root_directory ()) { - return _content; - } - - return file (_content); -} - -ContentType -Film::content_type () const -{ - if (boost::filesystem::is_directory (_content)) { - /* Directory of images, we assume */ - return VIDEO; - } - - if (still_image_file (_content)) { - return STILL; - } - - return VIDEO; -} - /** @return The sampling rate that we will resample the audio to */ int Film::target_audio_sample_rate () const { - if (!audio_stream()) { + /* XXX: how often is this method called? */ + + boost::shared_ptr p = playlist (); + if (p->has_audio ()) { return 0; } /* Resample to a DCI-approved sample rate */ - double t = dcp_audio_sample_rate (audio_stream()->sample_rate()); + double t = dcp_audio_sample_rate (p->audio_frame_rate()); - FrameRateConversion frc (source_frame_rate(), dcp_frame_rate()); + FrameRateConversion frc (p->video_frame_rate(), dcp_frame_rate()); /* Compensate if the DCP is being run at a different frame rate to the source; that is, if the video is run such that it will @@ -710,18 +664,12 @@ Film::target_audio_sample_rate () const */ if (frc.change_speed) { - t *= source_frame_rate() * frc.factor() / dcp_frame_rate(); + t *= p->video_frame_rate() * frc.factor() / dcp_frame_rate(); } return rint (t); } -int -Film::still_duration_in_frames () const -{ - return still_duration() * source_frame_rate(); -} - /** @return a DCI-compliant name for a DCP of this film */ string Film::dci_name (bool if_created_now) const @@ -768,7 +716,8 @@ Film::dci_name (bool if_created_now) const } } - switch (audio_channels()) { + /* XXX */ + switch (2) { case 1: d << "_10"; break; @@ -846,98 +795,6 @@ Film::set_use_dci_name (bool u) signal_changed (USE_DCI_NAME); } -void -Film::set_content (string c) -{ - string check = directory (); - - boost::filesystem::path slash ("/"); - string platform_slash = slash.make_preferred().string (); - - if (!ends_with (check, platform_slash)) { - check += platform_slash; - } - - if (boost::filesystem::path(c).has_root_directory () && starts_with (c, check)) { - c = c.substr (_directory.length() + 1); - } - - string old_content; - - { - boost::mutex::scoped_lock lm (_state_mutex); - if (c == _content) { - return; - } - - old_content = _content; - _content = c; - } - - /* Reset streams here in case the new content doesn't have one or the other */ - _content_audio_stream = shared_ptr (); - _subtitle_stream = shared_ptr (); - - /* Start off using content audio */ - set_use_content_audio (true); - - /* Create a temporary decoder so that we can get information - about the content. - */ - - try { - Decoders d = decoder_factory (shared_from_this(), DecodeOptions()); - - set_size (d.video->native_size ()); - set_source_frame_rate (d.video->frames_per_second ()); - set_dcp_frame_rate (best_dcp_frame_rate (source_frame_rate ())); - set_subtitle_streams (d.video->subtitle_streams ()); - if (d.audio) { - set_content_audio_streams (d.audio->audio_streams ()); - } - - { - boost::mutex::scoped_lock lm (_state_mutex); - _content = c; - } - - signal_changed (CONTENT); - - /* Start off with the first audio and subtitle streams */ - if (d.audio && !d.audio->audio_streams().empty()) { - set_content_audio_stream (d.audio->audio_streams().front()); - } - - if (!d.video->subtitle_streams().empty()) { - set_subtitle_stream (d.video->subtitle_streams().front()); - } - - examine_content (); - - } catch (...) { - - boost::mutex::scoped_lock lm (_state_mutex); - _content = old_content; - throw; - - } - - /* Default format */ - switch (content_type()) { - case STILL: - set_format (Format::from_id ("var-185")); - break; - case VIDEO: - set_format (Format::from_id ("185")); - break; - } - - /* Still image DCPs must use external audio */ - if (content_type() == STILL) { - set_use_content_audio (false); - } -} - void Film::set_trust_content_header (bool t) { @@ -950,7 +807,8 @@ Film::set_trust_content_header (bool t) if (!_trust_content_header && !content().empty()) { /* We just said that we don't trust the content's header */ - examine_content (); + /* XXX */ +// examine_content (); } } @@ -1091,43 +949,6 @@ Film::set_dcp_ab (bool a) signal_changed (DCP_AB); } -void -Film::set_content_audio_stream (shared_ptr s) -{ - { - boost::mutex::scoped_lock lm (_state_mutex); - _content_audio_stream = s; - } - signal_changed (CONTENT_AUDIO_STREAM); -} - -void -Film::set_external_audio (vector a) -{ - { - boost::mutex::scoped_lock lm (_state_mutex); - _external_audio = a; - } - - shared_ptr decoder (new SndfileDecoder (shared_from_this(), DecodeOptions())); - if (decoder->audio_stream()) { - _sndfile_stream = decoder->audio_stream (); - } - - signal_changed (EXTERNAL_AUDIO); -} - -void -Film::set_use_content_audio (bool e) -{ - { - boost::mutex::scoped_lock lm (_state_mutex); - _use_content_audio = e; - } - - signal_changed (USE_CONTENT_AUDIO); -} - void Film::set_audio_gain (float g) { @@ -1148,26 +969,6 @@ Film::set_audio_delay (int d) signal_changed (AUDIO_DELAY); } -void -Film::set_still_duration (int d) -{ - { - boost::mutex::scoped_lock lm (_state_mutex); - _still_duration = d; - } - signal_changed (STILL_DURATION); -} - -void -Film::set_subtitle_stream (shared_ptr s) -{ - { - boost::mutex::scoped_lock lm (_state_mutex); - _subtitle_stream = s; - } - signal_changed (SUBTITLE_STREAM); -} - void Film::set_with_subtitles (bool w) { @@ -1239,76 +1040,6 @@ Film::set_dcp_frame_rate (int f) signal_changed (DCP_FRAME_RATE); } -void -Film::set_size (libdcp::Size s) -{ - { - boost::mutex::scoped_lock lm (_state_mutex); - _size = s; - } - signal_changed (SIZE); -} - -void -Film::set_length (SourceFrame l) -{ - { - boost::mutex::scoped_lock lm (_state_mutex); - _length = l; - } - signal_changed (LENGTH); -} - -void -Film::unset_length () -{ - { - boost::mutex::scoped_lock lm (_state_mutex); - _length = boost::none; - } - signal_changed (LENGTH); -} - -void -Film::set_content_digest (string d) -{ - { - boost::mutex::scoped_lock lm (_state_mutex); - _content_digest = d; - } - _dirty = true; -} - -void -Film::set_content_audio_streams (vector > s) -{ - { - boost::mutex::scoped_lock lm (_state_mutex); - _content_audio_streams = s; - } - signal_changed (CONTENT_AUDIO_STREAMS); -} - -void -Film::set_subtitle_streams (vector > s) -{ - { - boost::mutex::scoped_lock lm (_state_mutex); - _subtitle_streams = s; - } - signal_changed (SUBTITLE_STREAMS); -} - -void -Film::set_source_frame_rate (float f) -{ - { - boost::mutex::scoped_lock lm (_state_mutex); - _source_frame_rate = f; - } - signal_changed (SOURCE_FRAME_RATE); -} - void Film::signal_changed (Property p) { @@ -1322,33 +1053,12 @@ Film::signal_changed (Property p) } } -int -Film::audio_channels () const -{ - shared_ptr s = audio_stream (); - if (!s) { - return 0; - } - - return s->channels (); -} - void Film::set_dci_date_today () { _dci_date = boost::gregorian::day_clock::local_day (); } -boost::shared_ptr -Film::audio_stream () const -{ - if (use_content_audio()) { - return _content_audio_stream; - } - - return _sndfile_stream; -} - string Film::info_path (int f) const { @@ -1404,20 +1114,22 @@ Film::have_dcp () const return true; } -bool -Film::has_audio () const +shared_ptr +Film::playlist () const { - if (use_content_audio()) { - return audio_stream(); - } + boost::mutex::scoped_lock lm (_state_mutex); + return shared_ptr (new Playlist (shared_from_this (), _content)); +} - vector const e = external_audio (); - for (vector::const_iterator i = e.begin(); i != e.end(); ++i) { - if (!i->empty ()) { - return true; - } +void +Film::add_content (shared_ptr c) +{ + { + boost::mutex::scoped_lock lm (_state_mutex); + _content.push_back (c); } - return false; -} + signal_changed (CONTENT); + examine_content (c); +} diff --git a/src/lib/film.h b/src/lib/film.h index 2e05d64f4..afd57b7c2 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -37,7 +37,6 @@ extern "C" { } #include "dcp_content_type.h" #include "util.h" -#include "stream.h" #include "dci_metadata.h" class Format; @@ -48,6 +47,7 @@ class ExamineContentJob; class AnalyseAudioJob; class ExternalAudioStream; class Content; +class Playlist; /** @class Film * @brief A representation of a video, maybe with sound. @@ -69,7 +69,7 @@ public: std::string video_mxf_filename () const; std::string audio_analysis_path () const; - void examine_content (); + void examine_content (boost::shared_ptr); void analyse_audio (); void send_dcp_to_tms (); @@ -87,9 +87,6 @@ public: std::string file (std::string f) const; std::string dir (std::string d) const; - std::string content_path () const; - ContentType content_type () const; - int target_audio_sample_rate () const; void write_metadata () const; @@ -104,12 +101,12 @@ public: return _dirty; } - int audio_channels () const; - void set_dci_date_today (); bool have_dcp () const; + boost::shared_ptr playlist () const; + /** Identifiers for the parts of our state; used for signalling changes. */ @@ -118,6 +115,7 @@ public: NAME, USE_DCI_NAME, TRUST_CONTENT_HEADER, + CONTENT, DCP_CONTENT_TYPE, FORMAT, CROP, @@ -162,6 +160,11 @@ public: return _trust_content_header; } + std::list > content () const { + boost::mutex::scoped_lock lm (_state_mutex); + return _content; + } + DCPContentType const * dcp_content_type () const { boost::mutex::scoped_lock lm (_state_mutex); return _dcp_content_type; @@ -212,11 +215,6 @@ public: return _audio_delay; } - boost::shared_ptr subtitle_stream () const { - boost::mutex::scoped_lock lm (_state_mutex); - return _subtitle_stream; - } - bool with_subtitles () const { boost::mutex::scoped_lock lm (_state_mutex); return _with_subtitles; @@ -252,15 +250,13 @@ public: return _dcp_frame_rate; } - boost::shared_ptr audio_stream () const; - bool has_audio () const; - /* SET */ void set_directory (std::string); void set_name (std::string); void set_use_dci_name (bool); void set_trust_content_header (bool); + void add_content (boost::shared_ptr); void set_dcp_content_type (DCPContentType const *); void set_format (Format const *); void set_crop (Crop); @@ -297,8 +293,6 @@ private: /** Log to write to */ boost::shared_ptr _log; - /** Any running ExamineContentJob, or 0 */ - boost::shared_ptr _examine_content_job; /** Any running AnalyseAudioJob, or 0 */ boost::shared_ptr _analyse_audio_job; @@ -318,7 +312,8 @@ private: std::string _name; /** True if a auto-generated DCI-compliant name should be used for our DCP */ bool _use_dci_name; - std::list > _content; + typedef std::list > ContentList; + ContentList _content; /** If this is true, we will believe the length specified by the content * file's header; if false, we will run through the whole content file * the first time we see it in order to obtain the length. diff --git a/src/lib/filter_graph.cc b/src/lib/filter_graph.cc index 045cbaa6a..a52c030fe 100644 --- a/src/lib/filter_graph.cc +++ b/src/lib/filter_graph.cc @@ -57,7 +57,7 @@ using libdcp::Size; * @param s Size of the images to process. * @param p Pixel format of the images to process. */ -FilterGraph::FilterGraph (shared_ptr film, FFmpegDecoder* decoder, libdcp::Size s, AVPixelFormat p) +FilterGraph::FilterGraph (shared_ptr film, FFmpegDecoder* decoder, libdcp::Size s, AVPixelFormat p) : _buffer_src_context (0) , _buffer_sink_context (0) , _size (s) diff --git a/src/lib/filter_graph.h b/src/lib/filter_graph.h index 7e4e8422b..db86a677d 100644 --- a/src/lib/filter_graph.h +++ b/src/lib/filter_graph.h @@ -37,7 +37,7 @@ class FFmpegDecoder; class FilterGraph { public: - FilterGraph (boost::shared_ptr film, FFmpegDecoder* decoder, libdcp::Size s, AVPixelFormat p); + FilterGraph (boost::shared_ptr, FFmpegDecoder* decoder, libdcp::Size s, AVPixelFormat p); bool can_process (libdcp::Size s, AVPixelFormat p) const; std::list > process (AVFrame const * frame); diff --git a/src/lib/format.cc b/src/lib/format.cc index b506c7000..05b71f2e5 100644 --- a/src/lib/format.cc +++ b/src/lib/format.cc @@ -29,6 +29,7 @@ #include #include "format.h" #include "film.h" +#include "playlist.h" #include "i18n.h" @@ -206,16 +207,16 @@ FixedFormat::FixedFormat (int r, libdcp::Size dcp, string id, string n, string d * (so there are dcp_padding() pixels on the left and dcp_padding() on the right) */ int -Format::dcp_padding (shared_ptr f) const +Format::dcp_padding (shared_ptr p) const { - int p = rint ((_dcp_size.width - (_dcp_size.height * ratio_as_integer(f) / 100.0)) / 2.0); + int pad = rint ((_dcp_size.width - (_dcp_size.height * ratio_as_integer(p) / 100.0)) / 2.0); /* This comes out -ve for Scope; bodge it */ - if (p < 0) { - p = 0; + if (pad < 0) { + pad = 0; } - return p; + return pad; } float @@ -231,15 +232,15 @@ VariableFormat::VariableFormat (libdcp::Size dcp, string id, string n, string d, } int -VariableFormat::ratio_as_integer (shared_ptr f) const +VariableFormat::ratio_as_integer (shared_ptr p) const { - return rint (ratio_as_float (f) * 100); + return rint (ratio_as_float (p) * 100); } float -VariableFormat::ratio_as_float (shared_ptr f) const +VariableFormat::ratio_as_float (shared_ptr p) const { - return float (f->size().width) / f->size().height; + return float (p->video_size().width) / p->video_size().height; } /** @return A name to be presented to the user */ diff --git a/src/lib/format.h b/src/lib/format.h index 305524628..94c2253de 100644 --- a/src/lib/format.h +++ b/src/lib/format.h @@ -26,7 +26,7 @@ #include #include "util.h" -class Film; +class Playlist; class Format { @@ -42,15 +42,15 @@ public: /** @return the aspect ratio multiplied by 100 * (e.g. 239 for Cinemascope 2.39:1) */ - virtual int ratio_as_integer (boost::shared_ptr f) const = 0; + virtual int ratio_as_integer (boost::shared_ptr f) const = 0; /** @return the ratio as a floating point number */ - virtual float ratio_as_float (boost::shared_ptr f) const = 0; + virtual float ratio_as_float (boost::shared_ptr f) const = 0; /** @return the ratio of the container (including any padding) as a floating point number */ float container_ratio_as_float () const; - int dcp_padding (boost::shared_ptr f) const; + int dcp_padding (boost::shared_ptr) const; /** @return size in pixels of the images that we should * put in a DCP for this ratio. This size will not correspond @@ -115,11 +115,11 @@ class FixedFormat : public Format public: FixedFormat (int, libdcp::Size, std::string, std::string, std::string, std::string); - int ratio_as_integer (boost::shared_ptr) const { + int ratio_as_integer (boost::shared_ptr) const { return _ratio; } - float ratio_as_float (boost::shared_ptr) const { + float ratio_as_float (boost::shared_ptr) const { return _ratio / 100.0; } @@ -136,8 +136,8 @@ class VariableFormat : public Format public: VariableFormat (libdcp::Size, std::string, std::string, std::string, std::string); - int ratio_as_integer (boost::shared_ptr f) const; - float ratio_as_float (boost::shared_ptr f) const; + int ratio_as_integer (boost::shared_ptr f) const; + float ratio_as_float (boost::shared_ptr f) const; std::string name () const; }; diff --git a/src/lib/imagemagick_content.cc b/src/lib/imagemagick_content.cc new file mode 100644 index 000000000..d0887c0aa --- /dev/null +++ b/src/lib/imagemagick_content.cc @@ -0,0 +1,2 @@ +#include "imagemagick_content.h" + diff --git a/src/lib/imagemagick_content.h b/src/lib/imagemagick_content.h index 2a8197b69..985aa0e8d 100644 --- a/src/lib/imagemagick_content.h +++ b/src/lib/imagemagick_content.h @@ -2,5 +2,6 @@ class ImageMagickContent : public VideoContent { - +public: + ImageMagickContent (boost::filesystem::path); }; diff --git a/src/lib/imagemagick_decoder.cc b/src/lib/imagemagick_decoder.cc index 5dc0b7b06..aa3c64f93 100644 --- a/src/lib/imagemagick_decoder.cc +++ b/src/lib/imagemagick_decoder.cc @@ -20,6 +20,7 @@ #include #include #include +#include "imagemagick_content.h" #include "imagemagick_decoder.h" #include "image.h" #include "film.h" @@ -32,37 +33,20 @@ using boost::shared_ptr; using libdcp::Size; ImageMagickDecoder::ImageMagickDecoder ( - boost::shared_ptr f, DecodeOptions o) + shared_ptr f, shared_ptr c, DecodeOptions o) : Decoder (f, o) - , VideoDecoder (f, o) + , VideoDecoder (f, c, o) + , _imagemagick_content (c) + , _position (0) { - if (boost::filesystem::is_directory (_film->content_path())) { - for ( - boost::filesystem::directory_iterator i = boost::filesystem::directory_iterator (_film->content_path()); - i != boost::filesystem::directory_iterator(); - ++i) { - - if (still_image_file (i->path().string())) { - _files.push_back (i->path().string()); - } - } - } else { - _files.push_back (_film->content_path ()); - } - - _iter = _files.begin (); + } libdcp::Size ImageMagickDecoder::native_size () const { - if (_files.empty ()) { - throw DecodeError (_("no still image files found")); - } - - /* Look at the first file and assume its size holds for all */ using namespace MagickCore; - Magick::Image* image = new Magick::Image (_film->content_path ()); + Magick::Image* image = new Magick::Image (_imagemagick_content->file().string()); libdcp::Size const s = libdcp::Size (image->columns(), image->rows()); delete image; @@ -72,16 +56,15 @@ ImageMagickDecoder::native_size () const bool ImageMagickDecoder::pass () { - if (_iter == _files.end()) { - if (video_frame() >= _film->still_duration_in_frames()) { - return true; - } - + if (_position > 0 && _position < _imagemagick_content->video_length ()) { repeat_last_video (); + _position++; return false; + } else if (_position >= _imagemagick_content->video_length ()) { + return true; } - Magick::Image* magick_image = new Magick::Image (_film->content_path ()); + Magick::Image* magick_image = new Magick::Image (_imagemagick_content->file().string ()); libdcp::Size size = native_size (); shared_ptr image (new SimpleImage (PIX_FMT_RGB24, size, false)); @@ -104,7 +87,7 @@ ImageMagickDecoder::pass () emit_video (image, 0); - ++_iter; + ++_position; return false; } @@ -118,10 +101,8 @@ ImageMagickDecoder::pixel_format () const bool ImageMagickDecoder::seek_to_last () { - if (_iter == _files.end()) { - _iter = _files.begin(); - } else { - --_iter; + if (_position > 0) { + --_position; } return false; @@ -130,16 +111,14 @@ ImageMagickDecoder::seek_to_last () bool ImageMagickDecoder::seek (double t) { - int const f = t * frames_per_second(); - - _iter = _files.begin (); - for (int i = 0; i < f; ++i) { - if (_iter == _files.end()) { - return true; - } - ++_iter; + int const f = t * _imagemagick_content->video_frame_rate (); + + if (f >= _imagemagick_content->video_length()) { + _position = 0; + return true; } - + + _position = f; return false; } diff --git a/src/lib/imagemagick_decoder.h b/src/lib/imagemagick_decoder.h index 2f4e2c967..b04bd88b1 100644 --- a/src/lib/imagemagick_decoder.h +++ b/src/lib/imagemagick_decoder.h @@ -23,10 +23,12 @@ namespace Magick { class Image; } +class ImageMagickContent; + class ImageMagickDecoder : public VideoDecoder { public: - ImageMagickDecoder (boost::shared_ptr, DecodeOptions); + ImageMagickDecoder (boost::shared_ptr, boost::shared_ptr, DecodeOptions); float frames_per_second () const { /* We don't know */ @@ -35,7 +37,7 @@ public: libdcp::Size native_size () const; - SourceFrame length () const { + ContentVideoFrame video_length () const { /* We don't know */ return 0; } @@ -54,9 +56,9 @@ public: bool seek (double); bool seek_to_last (); + bool pass (); protected: - bool pass (); PixelFormat pixel_format () const; int time_base_numerator () const { @@ -79,7 +81,7 @@ protected: private: void film_changed (Film::Property); - - std::list _files; - std::list::iterator _iter; + + boost::shared_ptr _imagemagick_content; + ContentVideoFrame _position; }; diff --git a/src/lib/job.cc b/src/lib/job.cc index ace02b8b3..ff0332d6d 100644 --- a/src/lib/job.cc +++ b/src/lib/job.cc @@ -34,8 +34,6 @@ using std::list; using std::stringstream; using boost::shared_ptr; -/** @param s Film that we are operating on. - */ Job::Job (shared_ptr f) : _film (f) , _thread (0) diff --git a/src/lib/job.h b/src/lib/job.h index fd036bce2..f5175c525 100644 --- a/src/lib/job.h +++ b/src/lib/job.h @@ -38,7 +38,7 @@ class Film; class Job : public boost::enable_shared_from_this { public: - Job (boost::shared_ptr s); + Job (boost::shared_ptr); virtual ~Job() {} /** @return user-readable name of this job */ @@ -87,7 +87,6 @@ protected: void set_state (State); void set_error (std::string s, std::string d); - /** Film for this job */ boost::shared_ptr _film; private: diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc new file mode 100644 index 000000000..17ecd2f37 --- /dev/null +++ b/src/lib/playlist.cc @@ -0,0 +1,266 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include "playlist.h" +#include "sndfile_content.h" +#include "sndfile_decoder.h" +#include "ffmpeg_content.h" +#include "ffmpeg_decoder.h" +#include "imagemagick_content.h" +#include "imagemagick_decoder.h" + +using std::list; +using boost::shared_ptr; +using boost::dynamic_pointer_cast; + +Playlist::Playlist (shared_ptr f, list > c) + : _video_from (VIDEO_NONE) + , _audio_from (AUDIO_NONE) + , _ffmpeg_decoder_done (false) +{ + for (list >::const_iterator i = c.begin(); i != c.end(); ++i) { + shared_ptr fc = dynamic_pointer_cast (*i); + if (fc) { + assert (!_ffmpeg); + _ffmpeg = fc; + _video_from = VIDEO_FFMPEG; + if (_audio_from == AUDIO_NONE) { + _audio_from = AUDIO_FFMPEG; + } + } + + shared_ptr ic = dynamic_pointer_cast (*i); + if (ic) { + _imagemagick.push_back (ic); + if (_video_from == VIDEO_NONE) { + _video_from = VIDEO_IMAGEMAGICK; + } + } + + shared_ptr sc = dynamic_pointer_cast (*i); + if (sc) { + _sndfile.push_back (sc); + _audio_from = AUDIO_SNDFILE; + } + } + + if (_video_from == VIDEO_FFMPEG || _audio_from == AUDIO_FFMPEG) { + DecodeOptions o; + /* XXX: decodeoptions */ + _ffmpeg_decoder.reset (new FFmpegDecoder (f, _ffmpeg, o)); + } + + if (_video_from == VIDEO_FFMPEG) { + _ffmpeg_decoder->connect_video (shared_from_this ()); + } + + if (_audio_from == AUDIO_FFMPEG) { + _ffmpeg_decoder->connect_audio (shared_from_this ()); + } + + if (_video_from == VIDEO_IMAGEMAGICK) { + for (list >::iterator i = _imagemagick.begin(); i != _imagemagick.end(); ++i) { + DecodeOptions o; + /* XXX: decodeoptions */ + shared_ptr d (new ImageMagickDecoder (f, *i, o)); + _imagemagick_decoders.push_back (d); + d->connect_video (shared_from_this ()); + } + + _imagemagick_decoder = _imagemagick_decoders.begin (); + } + + if (_audio_from == AUDIO_SNDFILE) { + for (list >::iterator i = _sndfile.begin(); i != _sndfile.end(); ++i) { + DecodeOptions o; + /* XXX: decodeoptions */ + shared_ptr d (new SndfileDecoder (f, *i, o)); + _sndfile_decoders.push_back (d); + d->connect_audio (shared_from_this ()); + } + } +} + +ContentAudioFrame +Playlist::audio_length () const +{ + switch (_audio_from) { + case AUDIO_NONE: + return 0; + case AUDIO_FFMPEG: + return _ffmpeg->audio_length (); + case AUDIO_SNDFILE: + { + ContentAudioFrame l = 0; + for (list >::const_iterator i = _sndfile.begin(); i != _sndfile.end(); ++i) { + l += (*i)->audio_length (); + } + return l; + } + } + + return 0; +} + +int +Playlist::audio_channels () const +{ + switch (_audio_from) { + case AUDIO_NONE: + return 0; + case AUDIO_FFMPEG: + return _ffmpeg->audio_channels (); + case AUDIO_SNDFILE: + { + int c = 0; + for (list >::const_iterator i = _sndfile.begin(); i != _sndfile.end(); ++i) { + c += (*i)->audio_channels (); + } + return c; + } + } + + return 0; +} + +int +Playlist::audio_frame_rate () const +{ + switch (_audio_from) { + case AUDIO_NONE: + return 0; + case AUDIO_FFMPEG: + return _ffmpeg->audio_frame_rate (); + case AUDIO_SNDFILE: + return _sndfile.front()->audio_frame_rate (); + } + + return 0; +} + +int64_t +Playlist::audio_channel_layout () const +{ + switch (_audio_from) { + case AUDIO_NONE: + return 0; + case AUDIO_FFMPEG: + return _ffmpeg->audio_channel_layout (); + case AUDIO_SNDFILE: + /* XXX */ + return 0; + } + + return 0; +} + +float +Playlist::video_frame_rate () const +{ + switch (_video_from) { + case VIDEO_NONE: + return 0; + case VIDEO_FFMPEG: + return _ffmpeg->video_frame_rate (); + case VIDEO_IMAGEMAGICK: + return 24; + } + + return 0; +} + +libdcp::Size +Playlist::video_size () const +{ + switch (_video_from) { + case VIDEO_NONE: + return libdcp::Size (); + case VIDEO_FFMPEG: + return _ffmpeg->video_size (); + case VIDEO_IMAGEMAGICK: + /* XXX */ + return _imagemagick.front()->video_size (); + } + + return libdcp::Size (); +} + +bool +Playlist::has_audio () const +{ + return _audio_from != AUDIO_NONE; +} + +void +Playlist::disable_video () +{ + _video_from = VIDEO_NONE; +} + +bool +Playlist::pass () +{ + bool done = true; + + if (_video_from == VIDEO_FFMPEG || _audio_from == AUDIO_FFMPEG) { + if (!_ffmpeg_decoder_done) { + if (_ffmpeg_decoder->pass ()) { + _ffmpeg_decoder_done = true; + } else { + done = false; + } + } + } + + if (_video_from == VIDEO_IMAGEMAGICK) { + if (_imagemagick_decoder != _imagemagick_decoders.end ()) { + if ((*_imagemagick_decoder)->pass ()) { + _imagemagick_decoder++; + } + + if (_imagemagick_decoder != _imagemagick_decoders.end ()) { + done = false; + } + } + } + + /* XXX: sndfile */ + + return done; +} + +void +Playlist::set_progress (shared_ptr job) +{ + /* XXX */ +} + +void +Playlist::process_video (shared_ptr i, bool same, shared_ptr s) +{ + Video (i, same, s); +} + +void +Playlist::process_audio (shared_ptr b) +{ + Audio (b); +} + diff --git a/src/lib/playlist.h b/src/lib/playlist.h index 4add76344..b42d46036 100644 --- a/src/lib/playlist.h +++ b/src/lib/playlist.h @@ -17,14 +17,66 @@ */ +#include #include +#include #include "video_source.h" +#include "audio_source.h" #include "video_sink.h" +#include "audio_sink.h" class Content; +class FFmpegContent; +class FFmpegDecoder; +class ImageMagickContent; +class ImageMagickDecoder; +class SndfileContent; +class SndfileDecoder; +class Job; +class Film; -class Playlist : public VideoSource, public AudioSource +class Playlist : public VideoSource, public AudioSource, public VideoSink, public AudioSink, public boost::enable_shared_from_this { public: - Playlist (std::list >); + Playlist (boost::shared_ptr, std::list >); + + ContentAudioFrame audio_length () const; + int audio_channels () const; + int audio_frame_rate () const; + int64_t audio_channel_layout () const; + bool has_audio () const; + + float video_frame_rate () const; + libdcp::Size video_size () const; + + void disable_video (); + + bool pass (); + void set_progress (boost::shared_ptr); + +private: + void process_video (boost::shared_ptr i, bool same, boost::shared_ptr s); + void process_audio (boost::shared_ptr); + + enum { + VIDEO_NONE, + VIDEO_FFMPEG, + VIDEO_IMAGEMAGICK + } _video_from; + + enum { + AUDIO_NONE, + AUDIO_FFMPEG, + AUDIO_SNDFILE + } _audio_from; + + boost::shared_ptr _ffmpeg; + std::list > _imagemagick; + std::list > _sndfile; + + boost::shared_ptr _ffmpeg_decoder; + bool _ffmpeg_decoder_done; + std::list > _imagemagick_decoders; + std::list >::iterator _imagemagick_decoder; + std::list > _sndfile_decoders; }; diff --git a/src/lib/scp_dcp_job.h b/src/lib/scp_dcp_job.h index 08d8e2c78..8c16d53fb 100644 --- a/src/lib/scp_dcp_job.h +++ b/src/lib/scp_dcp_job.h @@ -34,7 +34,7 @@ public: private: void set_status (std::string); - + mutable boost::mutex _status_mutex; std::string _status; }; diff --git a/src/lib/sndfile_content.cc b/src/lib/sndfile_content.cc new file mode 100644 index 000000000..8f5b28901 --- /dev/null +++ b/src/lib/sndfile_content.cc @@ -0,0 +1,41 @@ +#include "sndfile_content.h" +#include "compose.hpp" + +#include "i18n.h" + +using namespace std; + +string +SndfileContent::summary () const +{ + return String::compose (_("Sound file: %1"), file().filename ()); +} + +int +SndfileContent::audio_channels () const +{ + /* XXX */ + return 0; +} + +ContentAudioFrame +SndfileContent::audio_length () const +{ + /* XXX */ + return 0; +} + +int +SndfileContent::audio_frame_rate () const +{ + /* XXX */ + return 0; +} + +int64_t +SndfileContent::audio_channel_layout () const +{ + /* XXX */ + return 0; +} + diff --git a/src/lib/sndfile_content.h b/src/lib/sndfile_content.h index 382e55c40..e84617ed3 100644 --- a/src/lib/sndfile_content.h +++ b/src/lib/sndfile_content.h @@ -3,5 +3,11 @@ class SndfileContent : public AudioContent { public: + std::string summary () const; + /* AudioDecoder */ + int audio_channels () const; + ContentAudioFrame audio_length () const; + int audio_frame_rate () const; + int64_t audio_channel_layout () const; }; diff --git a/src/lib/sndfile_decoder.cc b/src/lib/sndfile_decoder.cc index 0e3e5e234..8848ff4f8 100644 --- a/src/lib/sndfile_decoder.cc +++ b/src/lib/sndfile_decoder.cc @@ -19,6 +19,7 @@ #include #include +#include "sndfile_content.h" #include "sndfile_decoder.h" #include "film.h" #include "exceptions.h" @@ -33,156 +34,53 @@ using std::cout; using boost::shared_ptr; using boost::optional; -SndfileDecoder::SndfileDecoder (shared_ptr f, DecodeOptions o) +/* XXX */ + +SndfileDecoder::SndfileDecoder (shared_ptr f, shared_ptr c, DecodeOptions o) : Decoder (f, o) - , AudioDecoder (f, o) + , AudioDecoder (f, c, o) { sf_count_t frames; - vector sf = open_files (frames); - close_files (sf); + SNDFILE* sf = open_file (frames); + sf_close (sf); } -vector -SndfileDecoder::open_files (sf_count_t & frames) +SNDFILE* +SndfileDecoder::open_file (sf_count_t & frames) { - vector const files = _film->external_audio (); - - int N = 0; - for (size_t i = 0; i < files.size(); ++i) { - if (!files[i].empty()) { - N = i + 1; - } - } - - if (N == 0) { - return vector (); - } - - bool first = true; frames = 0; - vector sndfiles; - for (size_t i = 0; i < (size_t) N; ++i) { - if (files[i].empty ()) { - sndfiles.push_back (0); - } else { - SF_INFO info; - SNDFILE* s = sf_open (files[i].c_str(), SFM_READ, &info); - if (!s) { - throw DecodeError (_("could not open external audio file for reading")); - } - - if (info.channels != 1) { - throw DecodeError (_("external audio files must be mono")); - } - - sndfiles.push_back (s); - - if (first) { - shared_ptr st ( - new SndfileStream ( - info.samplerate, av_get_default_channel_layout (N) - ) - ); - - _audio_streams.push_back (st); - _audio_stream = st; - frames = info.frames; - first = false; - } else { - if (info.frames != frames) { - throw DecodeError (_("external audio files have differing lengths")); - } - } - } + SF_INFO info; + SNDFILE* s = sf_open (_sndfile_content->file().string().c_str(), SFM_READ, &info); + if (!s) { + throw DecodeError (_("could not open external audio file for reading")); } - return sndfiles; + frames = info.frames; + return s; } bool SndfileDecoder::pass () { sf_count_t frames; - vector sndfiles = open_files (frames); - if (sndfiles.empty()) { - return true; - } + SNDFILE* sndfile = open_file (frames); /* Do things in half second blocks as I think there may be limits to what FFmpeg (and in particular the resampler) can cope with. */ - sf_count_t const block = _audio_stream->sample_rate() / 2; + sf_count_t const block = _sndfile_content->audio_frame_rate() / 2; - shared_ptr audio (new AudioBuffers (_audio_stream->channels(), block)); + shared_ptr audio (new AudioBuffers (_sndfile_content->audio_channels(), block)); while (frames > 0) { sf_count_t const this_time = min (block, frames); - for (size_t i = 0; i < sndfiles.size(); ++i) { - if (!sndfiles[i]) { - audio->make_silent (i); - } else { - sf_read_float (sndfiles[i], audio->data(i), block); - } - } - + sf_read_float (sndfile, audio->data(0), this_time); audio->set_frames (this_time); Audio (audio); frames -= this_time; } - close_files (sndfiles); + sf_close (sndfile); return true; } - -void -SndfileDecoder::close_files (vector const & sndfiles) -{ - for (size_t i = 0; i < sndfiles.size(); ++i) { - sf_close (sndfiles[i]); - } -} - -shared_ptr -SndfileStream::create () -{ - return shared_ptr (new SndfileStream); -} - -shared_ptr -SndfileStream::create (string t, optional v) -{ - if (!v) { - /* version < 1; no type in the string, and there's only FFmpeg streams anyway */ - return shared_ptr (); - } - - stringstream s (t); - string type; - s >> type; - if (type != N_("external")) { - return shared_ptr (); - } - - return shared_ptr (new SndfileStream (t, v)); -} - -SndfileStream::SndfileStream (string t, optional v) -{ - assert (v); - - stringstream s (t); - string type; - s >> type >> _sample_rate >> _channel_layout; -} - -SndfileStream::SndfileStream () -{ - -} - -string -SndfileStream::to_string () const -{ - return String::compose (N_("external %1 %2"), _sample_rate, _channel_layout); -} diff --git a/src/lib/sndfile_decoder.h b/src/lib/sndfile_decoder.h index e16eab673..c06b97a60 100644 --- a/src/lib/sndfile_decoder.h +++ b/src/lib/sndfile_decoder.h @@ -20,35 +20,19 @@ #include #include "decoder.h" #include "audio_decoder.h" -#include "stream.h" -class SndfileStream : public AudioStream -{ -public: - SndfileStream (int sample_rate, int64_t layout) - : AudioStream (sample_rate, layout) - {} - - std::string to_string () const; - - static boost::shared_ptr create (); - static boost::shared_ptr create (std::string t, boost::optional v); - -private: - friend class stream_test; - - SndfileStream (); - SndfileStream (std::string t, boost::optional v); -}; +class SndfileContent; class SndfileDecoder : public AudioDecoder { public: - SndfileDecoder (boost::shared_ptr, DecodeOptions); + SndfileDecoder (boost::shared_ptr, boost::shared_ptr, DecodeOptions); bool pass (); private: - std::vector open_files (sf_count_t &); - void close_files (std::vector const &); + SNDFILE* open_file (sf_count_t &); + void close_file (SNDFILE*); + + boost::shared_ptr _sndfile_content; }; diff --git a/src/lib/stream.cc b/src/lib/stream.cc deleted file mode 100644 index bfe7b5eb4..000000000 --- a/src/lib/stream.cc +++ /dev/null @@ -1,92 +0,0 @@ -/* - Copyright (C) 2012 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include -#include "compose.hpp" -#include "stream.h" -#include "ffmpeg_decoder.h" -#include "sndfile_decoder.h" - -#include "i18n.h" - -using std::string; -using std::stringstream; -using boost::shared_ptr; -using boost::optional; - -/** Construct a SubtitleStream from a value returned from to_string(). - * @param t String returned from to_string(). - * @param v State file version. - */ -SubtitleStream::SubtitleStream (string t, boost::optional) -{ - stringstream n (t); - n >> _id; - - size_t const s = t.find (' '); - if (s != string::npos) { - _name = t.substr (s + 1); - } -} - -/** @return A canonical string representation of this stream */ -string -SubtitleStream::to_string () const -{ - return String::compose (N_("%1 %2"), _id, _name); -} - -/** Create a SubtitleStream from a value returned from to_string(). - * @param t String returned from to_string(). - * @param v State file version. - */ -shared_ptr -SubtitleStream::create (string t, optional v) -{ - return shared_ptr (new SubtitleStream (t, v)); -} - -/** Create an AudioStream from a string returned from to_string(). - * @param t String returned from to_string(). - * @param v State file version. - * @return AudioStream, or 0. - */ -shared_ptr -audio_stream_factory (string t, optional v) -{ - shared_ptr s; - - s = FFmpegAudioStream::create (t, v); - if (!s) { - s = SndfileStream::create (t, v); - } - - return s; -} - -/** Create a SubtitleStream from a string returned from to_string(). - * @param t String returned from to_string(). - * @param v State file version. - * @return SubtitleStream, or 0. - */ -shared_ptr -subtitle_stream_factory (string t, optional v) -{ - return SubtitleStream::create (t, v); -} diff --git a/src/lib/stream.h b/src/lib/stream.h deleted file mode 100644 index 16b06e4bc..000000000 --- a/src/lib/stream.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - Copyright (C) 2012 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -/** @file src/lib/stream.h - * @brief Representations of audio and subtitle streams. - * - * Some content may have multiple `streams' of audio and/or subtitles; perhaps - * for multiple languages, or for stereo / surround mixes. These classes represent - * those streams, and know about their details. - */ - -#ifndef DVDOMATIC_STREAM_H -#define DVDOMATIC_STREAM_H - -#include -#include -#include -extern "C" { -#include -} - -/** @class Stream - * @brief Parent class for streams. - */ -class Stream -{ -public: - virtual ~Stream () {} - virtual std::string to_string () const = 0; -}; - -/** @class AudioStream - * @brief A stream of audio data. - */ -struct AudioStream : public Stream -{ -public: - AudioStream (int r, int64_t l) - : _sample_rate (r) - , _channel_layout (l) - {} - - /* Only used for backwards compatibility for state file version < 1 */ - void set_sample_rate (int s) { - _sample_rate = s; - } - - int channels () const { - return av_get_channel_layout_nb_channels (_channel_layout); - } - - int sample_rate () const { - return _sample_rate; - } - - int64_t channel_layout () const { - return _channel_layout; - } - -protected: - AudioStream () - : _sample_rate (0) - , _channel_layout (0) - {} - - int _sample_rate; - int64_t _channel_layout; -}; - -/** @class SubtitleStream - * @brief A stream of subtitle data. - */ -class SubtitleStream : public Stream -{ -public: - SubtitleStream (std::string n, int i) - : _name (n) - , _id (i) - {} - - std::string to_string () const; - - std::string name () const { - return _name; - } - - int id () const { - return _id; - } - - static boost::shared_ptr create (std::string t, boost::optional v); - -private: - friend class stream_test; - - SubtitleStream (std::string t, boost::optional v); - - std::string _name; - int _id; -}; - -boost::shared_ptr audio_stream_factory (std::string t, boost::optional version); -boost::shared_ptr subtitle_stream_factory (std::string t, boost::optional version); - -#endif diff --git a/src/lib/transcode_job.cc b/src/lib/transcode_job.cc index 234ebe051..f8810975b 100644 --- a/src/lib/transcode_job.cc +++ b/src/lib/transcode_job.cc @@ -62,8 +62,7 @@ TranscodeJob::run () _film->log()->log (N_("Transcode job starting")); _film->log()->log (String::compose (N_("Audio delay is %1ms"), _film->audio_delay())); - _encoder.reset (new Encoder (_film)); - Transcoder w (_film, _decode_opt, this, _encoder); + Transcoder w (_film, _decode_opt, shared_from_this ()); w.go (); set_progress (1); set_state (FINISHED_OK); @@ -83,11 +82,13 @@ TranscodeJob::run () string TranscodeJob::status () const { - if (!_encoder) { - return _("0%"); - } +// if (!_encoder) { +// return _("0%"); +// } - float const fps = _encoder->current_frames_per_second (); + /* XXX */ +// float const fps = _encoder->current_frames_per_second (); + float const fps = 0; if (fps == 0) { return Job::status (); } @@ -106,12 +107,15 @@ TranscodeJob::status () const int TranscodeJob::remaining_time () const { + return 0; +#if 0 + XXX float fps = _encoder->current_frames_per_second (); if (fps == 0) { return 0; } - if (!_film->length()) { + if (!_video->length()) { return 0; } @@ -126,4 +130,5 @@ TranscodeJob::remaining_time () const /* We assume that dcp_length() is valid, if it is set */ int const left = length - _encoder->video_frames_out(); return left / fps; +#endif } diff --git a/src/lib/transcode_job.h b/src/lib/transcode_job.h index 9b69e4e65..a409ec97e 100644 --- a/src/lib/transcode_job.h +++ b/src/lib/transcode_job.h @@ -44,5 +44,4 @@ protected: private: DecodeOptions _decode_opt; - boost::shared_ptr _encoder; }; diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc index e0f3a03a2..19d067149 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -36,6 +36,7 @@ #include "gain.h" #include "video_decoder.h" #include "audio_decoder.h" +#include "playlist.h" using std::string; using boost::shared_ptr; @@ -47,68 +48,42 @@ using boost::dynamic_pointer_cast; * @param j Job that we are running under, or 0. * @param e Encoder to use. */ -Transcoder::Transcoder (shared_ptr f, DecodeOptions o, Job* j, shared_ptr e) +Transcoder::Transcoder (shared_ptr f, DecodeOptions o, shared_ptr j) : _job (j) - , _encoder (e) - , _decoders (decoder_factory (f, o)) + , _playlist (f->playlist ()) + , _encoder (new Encoder (f, _playlist)) { - assert (_encoder); - - if (f->audio_stream()) { - shared_ptr st = f->audio_stream(); - _matcher.reset (new Matcher (f->log(), st->sample_rate(), f->source_frame_rate())); - _delay_line.reset (new DelayLine (f->log(), st->channels(), f->audio_delay() * st->sample_rate() / 1000)); + if (_playlist->has_audio ()) { + _matcher.reset (new Matcher (f->log(), _playlist->audio_frame_rate(), _playlist->video_frame_rate())); + _delay_line.reset (new DelayLine (f->log(), _playlist->audio_channels(), f->audio_delay() * _playlist->audio_frame_rate() / 1000)); _gain.reset (new Gain (f->log(), f->audio_gain())); } - /* Set up the decoder to use the film's set streams */ - _decoders.video->set_subtitle_stream (f->subtitle_stream ()); - if (_decoders.audio) { - _decoders.audio->set_audio_stream (f->audio_stream ()); - } - if (_matcher) { - _decoders.video->connect_video (_matcher); + _playlist->connect_video (_matcher); _matcher->connect_video (_encoder); } else { - _decoders.video->connect_video (_encoder); + _playlist->connect_video (_encoder); } - if (_matcher && _delay_line && _decoders.audio) { - _decoders.audio->connect_audio (_delay_line); + if (_matcher && _delay_line && _playlist->has_audio ()) { + _playlist->connect_audio (_delay_line); _delay_line->connect_audio (_matcher); _matcher->connect_audio (_gain); _gain->connect_audio (_encoder); } } -/** Run the decoder, passing its output to the encoder, until the decoder - * has no more data to present. - */ void Transcoder::go () { _encoder->process_begin (); try { - bool done[2] = { false, false }; - while (1) { - if (!done[0]) { - done[0] = _decoders.video->pass (); - if (_job) { - _decoders.video->set_progress (_job); - } - } - - if (!done[1] && _decoders.audio && dynamic_pointer_cast (_decoders.audio) != dynamic_pointer_cast (_decoders.video)) { - done[1] = _decoders.audio->pass (); - } else { - done[1] = true; - } - - if (done[0] && done[1]) { + if (_playlist->pass ()) { break; } + _playlist->set_progress (_job); } } catch (...) { diff --git a/src/lib/transcoder.h b/src/lib/transcoder.h index b0c263d07..8d34af948 100644 --- a/src/lib/transcoder.h +++ b/src/lib/transcoder.h @@ -32,9 +32,8 @@ class Encoder; class Matcher; class VideoFilter; class Gain; -class VideoDecoder; -class AudioDecoder; class DelayLine; +class Playlist; /** @class Transcoder * @brief A class which takes a Film and some Options, then uses those to transcode the film. @@ -48,23 +47,16 @@ public: Transcoder ( boost::shared_ptr f, DecodeOptions o, - Job* j, - boost::shared_ptr e + boost::shared_ptr j ); void go (); - boost::shared_ptr video_decoder () const { - return _decoders.video; - } - protected: /** A Job that is running this Transcoder, or 0 */ - Job* _job; - /** The encoder that we will use */ + boost::shared_ptr _job; + boost::shared_ptr _playlist; boost::shared_ptr _encoder; - /** The decoders that we will use */ - Decoders _decoders; boost::shared_ptr _matcher; boost::shared_ptr _delay_line; boost::shared_ptr _gain; diff --git a/src/lib/util.cc b/src/lib/util.cc index 48cb17c26..024740867 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -347,11 +347,11 @@ md5_digest (void const * data, int size) * @return MD5 digest of file's contents. */ string -md5_digest (string file) +md5_digest (boost::filesystem::path file) { - ifstream f (file.c_str(), ios::binary); + ifstream f (file.string().c_str(), ios::binary); if (!f.good ()) { - throw OpenFileError (file); + throw OpenFileError (file.string()); } f.seekg (0, ios::end); diff --git a/src/lib/util.h b/src/lib/util.h index 3d251cf06..87274cfff 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -57,7 +57,7 @@ extern double seconds (struct timeval); extern void dvdomatic_setup (); extern void dvdomatic_setup_i18n (std::string); extern std::vector split_at_spaces_considering_quotes (std::string); -extern std::string md5_digest (std::string); +extern std::string md5_digest (boost::filesystem::path); extern std::string md5_digest (void const *, int); extern void ensure_ui_thread (); extern std::string audio_channel_name (int); @@ -66,6 +66,8 @@ extern boost::filesystem::path mo_path (); #endif typedef int SourceFrame; +typedef int64_t ContentAudioFrame; +typedef int ContentVideoFrame; struct FrameRateConversion { diff --git a/src/lib/video_content.cc b/src/lib/video_content.cc new file mode 100644 index 000000000..9fc5cf1a2 --- /dev/null +++ b/src/lib/video_content.cc @@ -0,0 +1,28 @@ +#include "video_content.h" +#include "video_decoder.h" + +int const VideoContentProperty::VIDEO_LENGTH = 0; +int const VideoContentProperty::VIDEO_SIZE = 1; +int const VideoContentProperty::VIDEO_FRAME_RATE = 2; + +using boost::shared_ptr; + +VideoContent::VideoContent (boost::filesystem::path f) + : Content (f) + , _video_length (0) +{ + +} + +void +VideoContent::take_from_video_decoder (shared_ptr d) +{ + { + boost::mutex::scoped_lock lm (_mutex); + _video_size = d->native_size (); + _video_frame_rate = d->frames_per_second (); + } + + Changed (VideoContentProperty::VIDEO_SIZE); + Changed (VideoContentProperty::VIDEO_FRAME_RATE); +} diff --git a/src/lib/video_content.h b/src/lib/video_content.h index ee4a64fc4..219130668 100644 --- a/src/lib/video_content.h +++ b/src/lib/video_content.h @@ -1,8 +1,47 @@ +#ifndef DVDOMATIC_VIDEO_CONTENT_H +#define DVDOMATIC_VIDEO_CONTENT_H + #include "content.h" +#include "util.h" + +class VideoDecoder; + +class VideoContentProperty +{ +public: + static int const VIDEO_LENGTH; + static int const VIDEO_SIZE; + static int const VIDEO_FRAME_RATE; +}; class VideoContent : public virtual Content { public: + VideoContent (boost::filesystem::path); + + ContentVideoFrame video_length () const { + boost::mutex::scoped_lock lm (_mutex); + return _video_length; + } + + libdcp::Size video_size () const { + boost::mutex::scoped_lock lm (_mutex); + return _video_size; + } + float video_frame_rate () const { + boost::mutex::scoped_lock lm (_mutex); + return _video_frame_rate; + } + +protected: + void take_from_video_decoder (boost::shared_ptr); + ContentVideoFrame _video_length; + +private: + libdcp::Size _video_size; + float _video_frame_rate; }; + +#endif diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc index 891720f6b..ca1e7ab56 100644 --- a/src/lib/video_decoder.cc +++ b/src/lib/video_decoder.cc @@ -30,7 +30,7 @@ using boost::shared_ptr; using boost::optional; -VideoDecoder::VideoDecoder (shared_ptr f, DecodeOptions o) +VideoDecoder::VideoDecoder (shared_ptr f, shared_ptr c, DecodeOptions o) : Decoder (f, o) , _video_frame (0) , _last_source_time (0) @@ -102,21 +102,15 @@ VideoDecoder::emit_subtitle (shared_ptr s) } } -/** Set which stream of subtitles we should use from our source. - * @param s Stream to use. - */ -void -VideoDecoder::set_subtitle_stream (shared_ptr s) -{ - _subtitle_stream = s; -} - void VideoDecoder::set_progress (Job* j) const { assert (j); - + +#if 0 + XXX if (_film->length()) { j->set_progress (float (_video_frame) / _film->length().get()); } +#endif } diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h index 283ab5d88..a52e5448a 100644 --- a/src/lib/video_decoder.h +++ b/src/lib/video_decoder.h @@ -21,42 +21,33 @@ #define DVDOMATIC_VIDEO_DECODER_H #include "video_source.h" -#include "stream.h" #include "decoder.h" +class VideoContent; + class VideoDecoder : public VideoSource, public virtual Decoder { public: - VideoDecoder (boost::shared_ptr, DecodeOptions); + VideoDecoder (boost::shared_ptr, boost::shared_ptr, DecodeOptions); /** @return video frames per second, or 0 if unknown */ virtual float frames_per_second () const = 0; /** @return native size in pixels */ virtual libdcp::Size native_size () const = 0; - /** @return length (in source video frames), according to our content's header */ - virtual SourceFrame length () const = 0; + /** @return length according to our content's header */ + virtual ContentVideoFrame video_length () const = 0; virtual int time_base_numerator () const = 0; virtual int time_base_denominator () const = 0; virtual int sample_aspect_ratio_numerator () const = 0; virtual int sample_aspect_ratio_denominator () const = 0; - virtual void set_subtitle_stream (boost::shared_ptr); - void set_progress (Job *) const; int video_frame () const { return _video_frame; } - boost::shared_ptr subtitle_stream () const { - return _subtitle_stream; - } - - std::vector > subtitle_streams () const { - return _subtitle_streams; - } - double last_source_time () const { return _last_source_time; } @@ -69,11 +60,6 @@ protected: void emit_subtitle (boost::shared_ptr); void repeat_last_video (); - /** Subtitle stream to use when decoding */ - boost::shared_ptr _subtitle_stream; - /** Subtitle streams that this decoder's content has */ - std::vector > _subtitle_streams; - private: void signal_video (boost::shared_ptr, bool, boost::shared_ptr); diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 2d7ee9ba3..5f5dae98f 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -28,6 +28,7 @@ #include "format.h" #include "log.h" #include "dcp_video_frame.h" +#include "playlist.h" #include "i18n.h" @@ -41,8 +42,9 @@ using boost::shared_ptr; int const Writer::_maximum_frames_in_memory = 8; -Writer::Writer (shared_ptr f) +Writer::Writer (shared_ptr f, shared_ptr p) : _film (f) + , _playlist (p) , _first_nonexistant_frame (0) , _thread (0) , _finish (false) @@ -74,7 +76,7 @@ Writer::Writer (shared_ptr f) _picture_asset_writer = _picture_asset->start_write (_first_nonexistant_frame > 0); - AudioMapping m (_film->audio_channels ()); + AudioMapping m (_playlist->audio_channels ()); if (m.dcp_channels() > 0) { _sound_asset.reset ( @@ -83,7 +85,7 @@ Writer::Writer (shared_ptr f) N_("audio.mxf"), _film->dcp_frame_rate (), m.dcp_channels (), - dcp_audio_sample_rate (_film->audio_stream()->sample_rate()) + dcp_audio_sample_rate (_playlist->audio_frame_rate()) ) ); diff --git a/src/lib/writer.h b/src/lib/writer.h index beb16c7b9..920f592b6 100644 --- a/src/lib/writer.h +++ b/src/lib/writer.h @@ -26,6 +26,7 @@ class Film; class EncodedData; class AudioBuffers; +class Playlist; namespace libdcp { class MonoPictureAsset; @@ -63,7 +64,7 @@ bool operator== (QueueItem const & a, QueueItem const & b); class Writer : public ExceptionStore { public: - Writer (boost::shared_ptr); + Writer (boost::shared_ptr, boost::shared_ptr); bool can_fake_write (int) const; @@ -80,6 +81,7 @@ private: /** our Film */ boost::shared_ptr _film; + boost::shared_ptr _playlist; /** the first frame index that does not already exist in our MXF */ int _first_nonexistant_frame; diff --git a/src/lib/wscript b/src/lib/wscript index 5d9f5626a..5510d48a8 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -6,10 +6,12 @@ sources = """ ab_transcoder.cc analyse_audio_job.cc audio_analysis.cc + audio_content.cc audio_decoder.cc audio_source.cc config.cc combiner.cc + content.cc cross.cc dci_metadata.cc dcp_content_type.cc @@ -23,24 +25,27 @@ sources = """ exceptions.cc filter_graph.cc ffmpeg_compatibility.cc + ffmpeg_content.cc ffmpeg_decoder.cc film.cc filter.cc format.cc gain.cc image.cc + imagemagick_content.cc imagemagick_decoder.cc job.cc job_manager.cc log.cc lut.cc matcher.cc + playlist.cc scp_dcp_job.cc scaler.cc server.cc + sndfile_content.cc sndfile_decoder.cc sound_processor.cc - stream.cc subtitle.cc timer.cc transcode_job.cc @@ -48,6 +53,7 @@ sources = """ ui_signaller.cc util.cc version.cc + video_content.cc video_decoder.cc video_source.cc writer.cc diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 87c079bee..a78d03794 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -236,9 +236,6 @@ public: set_menu_sensitivity (); - /* XXX: calling these here is a bit of a hack */ - film_editor->setup_visibility (); - film_editor->FileChanged.connect (bind (&Frame::file_changed, this, _1)); if (film) { file_changed (film->directory ()); diff --git a/src/tools/makedcp.cc b/src/tools/makedcp.cc index 0c6390771..226cde113 100644 --- a/src/tools/makedcp.cc +++ b/src/tools/makedcp.cc @@ -151,7 +151,7 @@ main (int argc, char* argv[]) } cout << "DCP for " << film->name() << "\n"; cout << "Test mode: " << (test_mode ? "yes" : "no") << "\n"; - cout << "Content: " << film->content() << "\n"; +// cout << "Content: " << film->content() << "\n"; pair const f = Filter::ffmpeg_strings (film->filters ()); cout << "Filters: " << f.first << " " << f.second << "\n"; diff --git a/src/wx/audio_dialog.cc b/src/wx/audio_dialog.cc index 3d17988b6..b7384fd14 100644 --- a/src/wx/audio_dialog.cc +++ b/src/wx/audio_dialog.cc @@ -18,10 +18,11 @@ */ #include +#include "lib/audio_analysis.h" +#include "lib/film.h" +#include "lib/playlist.h" #include "audio_dialog.h" #include "audio_plot.h" -#include "audio_analysis.h" -#include "film.h" #include "wx_util.h" using boost::shared_ptr; @@ -90,6 +91,7 @@ AudioDialog::set_film (boost::shared_ptr f) _film_audio_analysis_succeeded_connection.disconnect (); _film = f; + _playlist = _film->playlist (); try_to_load_analysis (); setup_channels (); @@ -104,11 +106,11 @@ AudioDialog::set_film (boost::shared_ptr f) void AudioDialog::setup_channels () { - if (!_film->audio_stream()) { + if (!_playlist->has_audio()) { return; } - AudioMapping m (_film->audio_stream()->channels ()); + AudioMapping m (_playlist->audio_channels ()); for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) { if (m.dcp_to_source(static_cast(i))) { @@ -134,7 +136,7 @@ AudioDialog::try_to_load_analysis () _plot->set_analysis (a); - AudioMapping m (_film->audio_stream()->channels ()); + AudioMapping m (_playlist->audio_channels ()); optional c = m.source_to_dcp (0); if (c) { _channel_checkbox[c.get()]->SetValue (true); @@ -157,7 +159,7 @@ AudioDialog::channel_clicked (wxCommandEvent& ev) assert (c < MAX_AUDIO_CHANNELS); - AudioMapping m (_film->audio_stream()->channels ()); + AudioMapping m (_playlist->audio_channels ()); optional s = m.dcp_to_source (static_cast (c)); if (s) { _plot->set_channel_visible (s.get(), _channel_checkbox[c]->GetValue ()); @@ -171,9 +173,8 @@ AudioDialog::film_changed (Film::Property p) case Film::AUDIO_GAIN: _plot->set_gain (_film->audio_gain ()); break; - case Film::CONTENT_AUDIO_STREAM: - case Film::EXTERNAL_AUDIO: - case Film::USE_CONTENT_AUDIO: + case Film::CONTENT: + _playlist = _film->playlist (); setup_channels (); break; default: diff --git a/src/wx/audio_dialog.h b/src/wx/audio_dialog.h index 514faeea0..3cb9c1726 100644 --- a/src/wx/audio_dialog.h +++ b/src/wx/audio_dialog.h @@ -25,6 +25,7 @@ class AudioPlot; class Film; +class Playlist; class AudioDialog : public wxDialog { @@ -42,6 +43,7 @@ private: void setup_channels (); boost::shared_ptr _film; + boost::shared_ptr _playlist; AudioPlot* _plot; wxCheckBox* _channel_checkbox[MAX_AUDIO_CHANNELS]; wxCheckBox* _type_checkbox[AudioPoint::COUNT]; diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index c1d679665..7dfbf6c50 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -65,12 +66,13 @@ FilmEditor::FilmEditor (shared_ptr f, wxWindow* parent) , _audio_dialog (0) { wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); - SetSizer (s); _notebook = new wxNotebook (this, wxID_ANY); s->Add (_notebook, 1); make_film_panel (); _notebook->AddPage (_film_panel, _("Film"), true); + make_content_panel (); + _notebook->AddPage (_content_panel, _("Content"), false); make_video_panel (); _notebook->AddPage (_video_panel, _("Video"), false); make_audio_panel (); @@ -85,8 +87,9 @@ FilmEditor::FilmEditor (shared_ptr f, wxWindow* parent) bind (&FilmEditor::active_jobs_changed, this, _1) ); - setup_visibility (); setup_formats (); + + SetSizerAndFit (s); } void @@ -117,13 +120,7 @@ FilmEditor::make_film_panel () grid->Add (_edit_dci_button, wxGBPosition (r, 1), wxDefaultSpan); ++r; - add_label_to_grid_bag_sizer (grid, _film_panel, _("Content"), wxGBPosition (r, 0)); - _content = new wxFilePickerCtrl (_film_panel, wxID_ANY, wxT (""), _("Select Content File"), wxT("*.*")); - grid->Add (_content, wxGBPosition (r, 1), wxDefaultSpan, wxEXPAND); - ++r; - _trust_content_header = new wxCheckBox (_film_panel, wxID_ANY, _("Trust content's header")); - video_control (_trust_content_header); grid->Add (_trust_content_header, wxGBPosition (r, 0), wxGBSpan(1, 2)); ++r; @@ -132,9 +129,9 @@ FilmEditor::make_film_panel () grid->Add (_dcp_content_type, wxGBPosition (r, 1)); ++r; - video_control (add_label_to_grid_bag_sizer (grid, _film_panel, _("Original Frame Rate"), wxGBPosition (r, 0))); + add_label_to_grid_bag_sizer (grid, _film_panel, _("Original Frame Rate"), wxGBPosition (r, 0)); _source_frame_rate = new wxStaticText (_film_panel, wxID_ANY, wxT ("")); - grid->Add (video_control (_source_frame_rate), wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); + grid->Add (_source_frame_rate, wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); ++r; { @@ -149,56 +146,42 @@ FilmEditor::make_film_panel () ++r; _frame_rate_description = new wxStaticText (_film_panel, wxID_ANY, wxT (" \n "), wxDefaultPosition, wxDefaultSize); - grid->Add (video_control (_frame_rate_description), wxGBPosition (r, 0), wxGBSpan (1, 2), wxEXPAND | wxALIGN_CENTER_VERTICAL | wxALL, 6); + grid->Add (_frame_rate_description, wxGBPosition (r, 0), wxGBSpan (1, 2), wxEXPAND | wxALIGN_CENTER_VERTICAL | wxALL, 6); wxFont font = _frame_rate_description->GetFont(); font.SetStyle(wxFONTSTYLE_ITALIC); font.SetPointSize(font.GetPointSize() - 1); _frame_rate_description->SetFont(font); ++r; - video_control (add_label_to_grid_bag_sizer (grid, _film_panel, _("Original Size"), wxGBPosition (r, 0))); + add_label_to_grid_bag_sizer (grid, _film_panel, _("Original Size"), wxGBPosition (r, 0)); _original_size = new wxStaticText (_film_panel, wxID_ANY, wxT ("")); - grid->Add (video_control (_original_size), wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); + grid->Add (_original_size, wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); ++r; - video_control (add_label_to_grid_bag_sizer (grid, _film_panel, _("Length"), wxGBPosition (r, 0))); + add_label_to_grid_bag_sizer (grid, _film_panel, _("Length"), wxGBPosition (r, 0)); _length = new wxStaticText (_film_panel, wxID_ANY, wxT ("")); - grid->Add (video_control (_length), wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); + grid->Add (_length, wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); ++r; { - video_control (add_label_to_grid_bag_sizer (grid, _film_panel, _("Trim frames"), wxGBPosition (r, 0))); + add_label_to_grid_bag_sizer (grid, _film_panel, _("Trim frames"), wxGBPosition (r, 0)); wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); - video_control (add_label_to_sizer (s, _film_panel, _("Start"))); + add_label_to_sizer (s, _film_panel, _("Start")); _trim_start = new wxSpinCtrl (_film_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)); - s->Add (video_control (_trim_start)); - video_control (add_label_to_sizer (s, _film_panel, _("End"))); + s->Add (_trim_start); + add_label_to_sizer (s, _film_panel, _("End")); _trim_end = new wxSpinCtrl (_film_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)); - s->Add (video_control (_trim_end)); + s->Add (_trim_end); grid->Add (s, wxGBPosition (r, 1)); } ++r; _dcp_ab = new wxCheckBox (_film_panel, wxID_ANY, _("A/B")); - video_control (_dcp_ab); grid->Add (_dcp_ab, wxGBPosition (r, 0)); ++r; - /* STILL-only stuff */ - { - still_control (add_label_to_grid_bag_sizer (grid, _film_panel, _("Duration"), wxGBPosition (r, 0))); - wxSizer* s = new wxBoxSizer (wxHORIZONTAL); - _still_duration = new wxSpinCtrl (_film_panel); - still_control (_still_duration); - s->Add (_still_duration, 1, wxEXPAND); - /// TRANSLATORS: `s' here is an abbreviation for seconds, the unit of time - still_control (add_label_to_sizer (s, _film_panel, _("s"))); - grid->Add (s, wxGBPosition (r, 1)); - } - ++r; - vector const ct = DCPContentType::all (); for (vector::const_iterator i = ct.begin(); i != ct.end(); ++i) { _dcp_content_type->Append (std_to_wx ((*i)->pretty_name ())); @@ -217,7 +200,6 @@ FilmEditor::connect_to_widgets () _use_dci_name->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::use_dci_name_toggled), 0, this); _edit_dci_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::edit_dci_button_clicked), 0, this); _format->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::format_changed), 0, this); - _content->Connect (wxID_ANY, wxEVT_COMMAND_FILEPICKER_CHANGED, wxCommandEventHandler (FilmEditor::content_changed), 0, this); _trust_content_header->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::trust_content_header_changed), 0, this); _left_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::left_crop_changed), 0, this); _right_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::right_crop_changed), 0, this); @@ -229,7 +211,6 @@ FilmEditor::connect_to_widgets () _dcp_frame_rate->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::dcp_frame_rate_changed), 0, this); _best_dcp_frame_rate->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::best_dcp_frame_rate_clicked), 0, this); _dcp_ab->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::dcp_ab_toggled), 0, this); - _still_duration->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::still_duration_changed), 0, this); _trim_start->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::trim_start_changed), 0, this); _trim_end->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::trim_end_changed), 0, this); _with_subtitles->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::with_subtitles_toggled), 0, this); @@ -237,21 +218,14 @@ FilmEditor::connect_to_widgets () _subtitle_scale->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::subtitle_scale_changed), 0, this); _colour_lut->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::colour_lut_changed), 0, this); _j2k_bandwidth->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::j2k_bandwidth_changed), 0, this); - _subtitle_stream->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::subtitle_stream_changed), 0, this); - _audio_stream->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::audio_stream_changed), 0, this); +// _ffmpeg_subtitle_stream->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::ffmpeg_subtitle_stream_changed), 0, this); +// _ffmpeg_audio_stream->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::ffmpeg_audio_stream_changed), 0, this); _audio_gain->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::audio_gain_changed), 0, this); _audio_gain_calculate_button->Connect ( wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::audio_gain_calculate_button_clicked), 0, this ); _show_audio->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::show_audio_clicked), 0, this); _audio_delay->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::audio_delay_changed), 0, this); - _use_content_audio->Connect (wxID_ANY, wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler (FilmEditor::use_audio_changed), 0, this); - _use_external_audio->Connect (wxID_ANY, wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler (FilmEditor::use_audio_changed), 0, this); - for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) { - _external_audio[i]->Connect ( - wxID_ANY, wxEVT_COMMAND_FILEPICKER_CHANGED, wxCommandEventHandler (FilmEditor::external_audio_changed), 0, this - ); - } } void @@ -300,21 +274,19 @@ FilmEditor::make_video_panel () /* VIDEO-only stuff */ { - video_control (add_label_to_grid_bag_sizer (grid, _video_panel, _("Filters"), wxGBPosition (r, 0))); + add_label_to_grid_bag_sizer (grid, _video_panel, _("Filters"), wxGBPosition (r, 0)); wxSizer* s = new wxBoxSizer (wxHORIZONTAL); _filters = new wxStaticText (_video_panel, wxID_ANY, _("None")); - video_control (_filters); s->Add (_filters, 1, wxEXPAND | wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM | wxRIGHT, 6); _filters_button = new wxButton (_video_panel, wxID_ANY, _("Edit...")); - video_control (_filters_button); s->Add (_filters_button, 0); grid->Add (s, wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); } ++r; - video_control (add_label_to_grid_bag_sizer (grid, _video_panel, _("Scaler"), wxGBPosition (r, 0))); + add_label_to_grid_bag_sizer (grid, _video_panel, _("Scaler"), wxGBPosition (r, 0)); _scaler = new wxChoice (_video_panel, wxID_ANY); - grid->Add (video_control (_scaler), wxGBPosition (r, 1)); + grid->Add (_scaler, wxGBPosition (r, 1)); ++r; vector const sc = Scaler::all (); @@ -345,12 +317,48 @@ FilmEditor::make_video_panel () _top_crop->SetRange (0, 1024); _right_crop->SetRange (0, 1024); _bottom_crop->SetRange (0, 1024); - _still_duration->SetRange (1, 60 * 60); _trim_start->SetRange (0, 100); _trim_end->SetRange (0, 100); _j2k_bandwidth->SetRange (50, 250); } +void +FilmEditor::make_content_panel () +{ + _content_panel = new wxPanel (_notebook); + _content_sizer = new wxBoxSizer (wxVERTICAL); + _content_panel->SetSizer (_content_sizer); + + wxGridBagSizer* grid = new wxGridBagSizer (4, 4); + _content_sizer->Add (grid, 0, wxALL, 8); + + int r = 0; + + { + wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); + + _content = new wxListCtrl (_content_panel, wxID_ANY, wxDefaultPosition, wxSize (320, 160), wxLC_REPORT | wxLC_NO_HEADER | wxLC_SINGLE_SEL); + s->Add (_content, 1, wxEXPAND | wxTOP | wxBOTTOM, 6); + + _content->InsertColumn (0, ""); + + wxBoxSizer* b = new wxBoxSizer (wxVERTICAL); + _content_add = new wxButton (_content_panel, wxID_ANY, _("Add...")); + b->Add (_content_add); + _content_remove = new wxButton (_content_panel, wxID_ANY, _("Remove")); + b->Add (_content_remove); + _content_earlier = new wxButton (_content_panel, wxID_ANY, _("Earlier")); + b->Add (_content_earlier); + _content_later = new wxButton (_content_panel, wxID_ANY, _("Later")); + b->Add (_content_later); + + s->Add (b, 0, wxALL, 4); + + grid->Add (s, wxGBPosition (r, 0), wxGBSpan (1, 2), wxEXPAND); + ++r; + } +} + void FilmEditor::make_audio_panel () { @@ -366,48 +374,26 @@ FilmEditor::make_audio_panel () grid->AddSpacer (0); { - video_control (add_label_to_sizer (grid, _audio_panel, _("Audio Gain"))); + add_label_to_sizer (grid, _audio_panel, _("Audio Gain")); wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); _audio_gain = new wxSpinCtrl (_audio_panel); - s->Add (video_control (_audio_gain), 1); - video_control (add_label_to_sizer (s, _audio_panel, _("dB"))); + s->Add (_audio_gain, 1); + add_label_to_sizer (s, _audio_panel, _("dB")); _audio_gain_calculate_button = new wxButton (_audio_panel, wxID_ANY, _("Calculate...")); - video_control (_audio_gain_calculate_button); s->Add (_audio_gain_calculate_button, 1, wxEXPAND); grid->Add (s); } { - video_control (add_label_to_sizer (grid, _audio_panel, _("Audio Delay"))); + add_label_to_sizer (grid, _audio_panel, _("Audio Delay")); wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); _audio_delay = new wxSpinCtrl (_audio_panel); - s->Add (video_control (_audio_delay), 1); + s->Add (_audio_delay, 1); /// TRANSLATORS: this is an abbreviation for milliseconds, the unit of time - video_control (add_label_to_sizer (s, _audio_panel, _("ms"))); + add_label_to_sizer (s, _audio_panel, _("ms")); grid->Add (s); } - { - _use_content_audio = new wxRadioButton (_audio_panel, wxID_ANY, _("Use content's audio"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP); - grid->Add (video_control (_use_content_audio)); - wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); - _audio_stream = new wxChoice (_audio_panel, wxID_ANY); - s->Add (video_control (_audio_stream), 1); - _audio = new wxStaticText (_audio_panel, wxID_ANY, wxT ("")); - s->Add (video_control (_audio), 1, wxALIGN_CENTER_VERTICAL | wxLEFT, 8); - grid->Add (s, 1, wxEXPAND); - } - - _use_external_audio = new wxRadioButton (_audio_panel, wxID_ANY, _("Use external audio")); - grid->Add (_use_external_audio); - grid->AddSpacer (0); - - for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) { - add_label_to_sizer (grid, _audio_panel, std_to_wx (audio_channel_name (i))); - _external_audio[i] = new wxFilePickerCtrl (_audio_panel, wxID_ANY, wxT (""), _("Select Audio File"), wxT ("*.wav")); - grid->Add (_external_audio[i], 1, wxEXPAND); - } - _audio_gain->SetRange (-60, 60); _audio_delay->SetRange (-1000, 1000); } @@ -422,22 +408,21 @@ FilmEditor::make_subtitle_panel () _subtitle_sizer->Add (grid, 0, wxALL, 8); _with_subtitles = new wxCheckBox (_subtitle_panel, wxID_ANY, _("With Subtitles")); - video_control (_with_subtitles); grid->Add (_with_subtitles, 1); - _subtitle_stream = new wxChoice (_subtitle_panel, wxID_ANY); - grid->Add (video_control (_subtitle_stream)); + _ffmpeg_subtitle_stream = new wxChoice (_subtitle_panel, wxID_ANY); + grid->Add (_ffmpeg_subtitle_stream); - video_control (add_label_to_sizer (grid, _subtitle_panel, _("Subtitle Offset"))); + add_label_to_sizer (grid, _subtitle_panel, _("Subtitle Offset")); _subtitle_offset = new wxSpinCtrl (_subtitle_panel); - grid->Add (video_control (_subtitle_offset), 1); + grid->Add (_subtitle_offset, 1); { - video_control (add_label_to_sizer (grid, _subtitle_panel, _("Subtitle Scale"))); + add_label_to_sizer (grid, _subtitle_panel, _("Subtitle Scale")); wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); _subtitle_scale = new wxSpinCtrl (_subtitle_panel); - s->Add (video_control (_subtitle_scale)); - video_control (add_label_to_sizer (s, _subtitle_panel, _("%"))); + s->Add (_subtitle_scale); + add_label_to_sizer (s, _subtitle_panel, _("%")); grid->Add (s); } @@ -489,22 +474,6 @@ FilmEditor::bottom_crop_changed (wxCommandEvent &) _film->set_bottom_crop (_bottom_crop->GetValue ()); } -/** Called when the content filename has been changed */ -void -FilmEditor::content_changed (wxCommandEvent &) -{ - if (!_film) { - return; - } - - try { - _film->set_content (wx_to_std (_content->GetPath ())); - } catch (std::exception& e) { - _content->SetPath (std_to_wx (_film->directory ())); - error_dialog (this, wxString::Format (_("Could not set content: %s"), std_to_wx (e.what()).data())); - } -} - void FilmEditor::trust_content_header_changed (wxCommandEvent &) { @@ -611,8 +580,7 @@ FilmEditor::film_changed (Film::Property p) case Film::NONE: break; case Film::CONTENT: - checked_set (_content, _film->content ()); - setup_visibility (); + setup_content (); setup_formats (); setup_subtitle_control_sensitivity (); setup_streams (); @@ -621,14 +589,14 @@ FilmEditor::film_changed (Film::Property p) case Film::TRUST_CONTENT_HEADER: checked_set (_trust_content_header, _film->trust_content_header ()); break; - case Film::SUBTITLE_STREAMS: - setup_subtitle_control_sensitivity (); - setup_streams (); - break; - case Film::CONTENT_AUDIO_STREAMS: - setup_streams (); - setup_show_audio_sensitivity (); - break; +// case Film::SUBTITLE_STREAMS: +// setup_subtitle_control_sensitivity (); +// setup_streams (); +// break; +// case Film::CONTENT_AUDIO_STREAMS: +// setup_streams (); +// setup_show_audio_sensitivity (); +// break; case Film::FORMAT: { int n = 0; @@ -673,32 +641,32 @@ FilmEditor::film_changed (Film::Property p) checked_set (_name, _film->name()); setup_dcp_name (); break; - case Film::SOURCE_FRAME_RATE: - s << fixed << setprecision(2) << _film->source_frame_rate(); - _source_frame_rate->SetLabel (std_to_wx (s.str ())); - break; - case Film::SIZE: - if (_film->size().width == 0 && _film->size().height == 0) { - _original_size->SetLabel (wxT ("")); - } else { - s << _film->size().width << " x " << _film->size().height; - _original_size->SetLabel (std_to_wx (s.str ())); - } - break; - case Film::LENGTH: - if (_film->source_frame_rate() > 0 && _film->length()) { - s << _film->length().get() << " " - << wx_to_std (_("frames")) << "; " << seconds_to_hms (_film->length().get() / _film->source_frame_rate()); - } else if (_film->length()) { - s << _film->length().get() << " " - << wx_to_std (_("frames")); - } - _length->SetLabel (std_to_wx (s.str ())); - if (_film->length()) { - _trim_start->SetRange (0, _film->length().get()); - _trim_end->SetRange (0, _film->length().get()); - } - break; +// case Film::SOURCE_FRAME_RATE: +// s << fixed << setprecision(2) << _film->source_frame_rate(); +// _source_frame_rate->SetLabel (std_to_wx (s.str ())); +// break; +// case Film::SIZE: +// if (_film->size().width == 0 && _film->size().height == 0) { +// _original_size->SetLabel (wxT ("")); +// } else { +// s << _film->size().width << " x " << _film->size().height; +// _original_size->SetLabel (std_to_wx (s.str ())); +// } +// break; +// case Film::LENGTH: +// if (_film->source_frame_rate() > 0 && _film->length()) { +// s << _film->length().get() << " " +// << wx_to_std (_("frames")) << "; " << seconds_to_hms (_film->length().get() / _film->source_frame_rate()); +// } else if (_film->length()) { +// s << _film->length().get() << " " +// << wx_to_std (_("frames")); +// } +// _length->SetLabel (std_to_wx (s.str ())); +// if (_film->length()) { +// _trim_start->SetRange (0, _film->length().get()); +// _trim_end->SetRange (0, _film->length().get()); +// } +// break; case Film::DCP_CONTENT_TYPE: checked_set (_dcp_content_type, DCPContentType::as_index (_film->dcp_content_type ())); setup_dcp_name (); @@ -721,9 +689,6 @@ FilmEditor::film_changed (Film::Property p) case Film::AUDIO_DELAY: checked_set (_audio_delay, _film->audio_delay ()); break; - case Film::STILL_DURATION: - checked_set (_still_duration, _film->still_duration ()); - break; case Film::WITH_SUBTITLES: checked_set (_with_subtitles, _film->with_subtitles ()); setup_subtitle_control_sensitivity (); @@ -748,55 +713,36 @@ FilmEditor::film_changed (Film::Property p) case Film::DCI_METADATA: setup_dcp_name (); break; - case Film::CONTENT_AUDIO_STREAM: - if (_film->content_audio_stream()) { - checked_set (_audio_stream, _film->content_audio_stream()->to_string()); - } - setup_dcp_name (); - setup_audio_details (); - setup_audio_control_sensitivity (); - setup_show_audio_sensitivity (); - break; - case Film::USE_CONTENT_AUDIO: - checked_set (_use_content_audio, _film->use_content_audio()); - checked_set (_use_external_audio, !_film->use_content_audio()); - setup_dcp_name (); - setup_audio_details (); - setup_audio_control_sensitivity (); - setup_show_audio_sensitivity (); - break; - case Film::SUBTITLE_STREAM: - if (_film->subtitle_stream()) { - checked_set (_subtitle_stream, _film->subtitle_stream()->to_string()); - } - break; - case Film::EXTERNAL_AUDIO: - { - vector a = _film->external_audio (); - for (size_t i = 0; i < a.size() && i < MAX_AUDIO_CHANNELS; ++i) { - checked_set (_external_audio[i], a[i]); - } - setup_audio_details (); - setup_show_audio_sensitivity (); - break; - } - case Film::DCP_FRAME_RATE: - for (unsigned int i = 0; i < _dcp_frame_rate->GetCount(); ++i) { - if (wx_to_std (_dcp_frame_rate->GetString(i)) == boost::lexical_cast (_film->dcp_frame_rate())) { - if (_dcp_frame_rate->GetSelection() != int(i)) { - _dcp_frame_rate->SetSelection (i); - break; - } - } - } - - if (_film->source_frame_rate()) { - _frame_rate_description->SetLabel (std_to_wx (FrameRateConversion (_film->source_frame_rate(), _film->dcp_frame_rate()).description)); - _best_dcp_frame_rate->Enable (best_dcp_frame_rate (_film->source_frame_rate ()) != _film->dcp_frame_rate ()); - } else { - _frame_rate_description->SetLabel (wxT ("")); - _best_dcp_frame_rate->Disable (); - } +// case Film::CONTENT_AUDIO_STREAM: +// if (_film->content_audio_stream()) { +// checked_set (_audio_stream, _film->content_audio_stream()->to_string()); +// } +// setup_dcp_name (); +// setup_audio_details (); +// setup_show_audio_sensitivity (); +// break; +// case Film::SUBTITLE_STREAM: +// if (_film->subtitle_stream()) { +// checked_set (_subtitle_stream, _film->subtitle_stream()->to_string()); +// } +// break; +// case Film::DCP_FRAME_RATE: +// for (unsigned int i = 0; i < _dcp_frame_rate->GetCount(); ++i) { +// if (wx_to_std (_dcp_frame_rate->GetString(i)) == boost::lexical_cast (_film->dcp_frame_rate())) { +// if (_dcp_frame_rate->GetSelection() != int(i)) { +// _dcp_frame_rate->SetSelection (i); +// break; +// } +// } +// } + +// if (_film->source_frame_rate()) { +// _frame_rate_description->SetLabel (std_to_wx (FrameRateConversion (_film->source_frame_rate(), _film->dcp_frame_rate()).description)); +// _best_dcp_frame_rate->Enable (best_dcp_frame_rate (_film->source_frame_rate ()) != _film->dcp_frame_rate ()); +// } else { +// _frame_rate_description->SetLabel (wxT ("")); +// _best_dcp_frame_rate->Disable (); +// } } } @@ -863,23 +809,14 @@ FilmEditor::set_film (shared_ptr f) film_changed (Film::TRIM_START); film_changed (Film::TRIM_END); film_changed (Film::DCP_AB); - film_changed (Film::CONTENT_AUDIO_STREAM); - film_changed (Film::EXTERNAL_AUDIO); - film_changed (Film::USE_CONTENT_AUDIO); film_changed (Film::AUDIO_GAIN); film_changed (Film::AUDIO_DELAY); - film_changed (Film::STILL_DURATION); film_changed (Film::WITH_SUBTITLES); film_changed (Film::SUBTITLE_OFFSET); film_changed (Film::SUBTITLE_SCALE); film_changed (Film::COLOUR_LUT); film_changed (Film::J2K_BANDWIDTH); film_changed (Film::DCI_METADATA); - film_changed (Film::SIZE); - film_changed (Film::LENGTH); - film_changed (Film::CONTENT_AUDIO_STREAMS); - film_changed (Film::SUBTITLE_STREAMS); - film_changed (Film::SOURCE_FRAME_RATE); film_changed (Film::DCP_FRAME_RATE); } @@ -903,7 +840,7 @@ FilmEditor::set_things_sensitive (bool s) _bottom_crop->Enable (s); _filters_button->Enable (s); _scaler->Enable (s); - _audio_stream->Enable (s); +// _ffmpeg_audio_stream->Enable (s); _dcp_content_type->Enable (s); _dcp_frame_rate->Enable (s); _trim_start->Enable (s); @@ -915,10 +852,8 @@ FilmEditor::set_things_sensitive (bool s) _audio_gain_calculate_button->Enable (s); _show_audio->Enable (s); _audio_delay->Enable (s); - _still_duration->Enable (s); setup_subtitle_control_sensitivity (); - setup_audio_control_sensitivity (); setup_show_audio_sensitivity (); } @@ -966,62 +901,6 @@ FilmEditor::audio_delay_changed (wxCommandEvent &) _film->set_audio_delay (_audio_delay->GetValue ()); } -wxControl * -FilmEditor::video_control (wxControl* c) -{ - _video_controls.push_back (c); - return c; -} - -wxControl * -FilmEditor::still_control (wxControl* c) -{ - _still_controls.push_back (c); - return c; -} - -void -FilmEditor::setup_visibility () -{ - ContentType c = VIDEO; - - if (_film) { - c = _film->content_type (); - } - - for (list::iterator i = _video_controls.begin(); i != _video_controls.end(); ++i) { - (*i)->Show (c == VIDEO); - } - - for (list::iterator i = _still_controls.begin(); i != _still_controls.end(); ++i) { - (*i)->Show (c == STILL); - } - - _notebook->InvalidateBestSize (); - - _film_sizer->Layout (); - _film_sizer->SetSizeHints (_film_panel); - _video_sizer->Layout (); - _video_sizer->SetSizeHints (_video_panel); - _audio_sizer->Layout (); - _audio_sizer->SetSizeHints (_audio_panel); - _subtitle_sizer->Layout (); - _subtitle_sizer->SetSizeHints (_subtitle_panel); - - _notebook->Fit (); - Fit (); -} - -void -FilmEditor::still_duration_changed (wxCommandEvent &) -{ - if (!_film) { - return; - } - - _film->set_still_duration (_still_duration->GetValue ()); -} - void FilmEditor::trim_start_changed (wxCommandEvent &) { @@ -1072,20 +951,7 @@ FilmEditor::audio_gain_calculate_button_clicked (wxCommandEvent &) void FilmEditor::setup_formats () { - ContentType c = VIDEO; - - if (_film) { - c = _film->content_type (); - } - - _formats.clear (); - - vector fmt = Format::all (); - for (vector::iterator i = fmt.begin(); i != fmt.end(); ++i) { - if (c == VIDEO || (c == STILL && dynamic_cast (*i))) { - _formats.push_back (*i); - } - } + _formats = Format::all (); _format->Clear (); for (vector::iterator i = _formats.begin(); i != _formats.end(); ++i) { @@ -1110,7 +976,7 @@ FilmEditor::setup_subtitle_control_sensitivity () { bool h = false; if (_generally_sensitive && _film) { - h = !_film->subtitle_streams().empty(); +// h = !_film->subtitle_streams().empty(); } _with_subtitles->Enable (h); @@ -1120,26 +986,11 @@ FilmEditor::setup_subtitle_control_sensitivity () j = _film->with_subtitles (); } - _subtitle_stream->Enable (j); + _ffmpeg_subtitle_stream->Enable (j); _subtitle_offset->Enable (j); _subtitle_scale->Enable (j); } -void -FilmEditor::setup_audio_control_sensitivity () -{ - _use_content_audio->Enable (_generally_sensitive && _film && !_film->content_audio_streams().empty()); - _use_external_audio->Enable (_generally_sensitive); - - bool const source = _generally_sensitive && _use_content_audio->GetValue(); - bool const external = _generally_sensitive && _use_external_audio->GetValue(); - - _audio_stream->Enable (source); - for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) { - _external_audio[i]->Enable (external); - } -} - void FilmEditor::use_dci_name_toggled (wxCommandEvent &) { @@ -1166,63 +1017,66 @@ FilmEditor::edit_dci_button_clicked (wxCommandEvent &) void FilmEditor::setup_streams () { - _audio_stream->Clear (); - vector > a = _film->content_audio_streams (); - for (vector >::iterator i = a.begin(); i != a.end(); ++i) { - shared_ptr ffa = dynamic_pointer_cast (*i); - assert (ffa); - _audio_stream->Append (std_to_wx (ffa->name()), new wxStringClientData (std_to_wx (ffa->to_string ()))); - } +// _ffmpeg_audio_stream->Clear (); + vector a;// = _film->content_audio_streams (); +// for (vector::iterator i = a.begin(); i != a.end(); ++i) { +// _audio_stream->Append (std_to_wx (ffa->name()), new wxStringClientData (std_to_wx (i->to_string ()))); +// } - if (_film->use_content_audio() && _film->audio_stream()) { - checked_set (_audio_stream, _film->audio_stream()->to_string()); - } - - _subtitle_stream->Clear (); - vector > s = _film->subtitle_streams (); - for (vector >::iterator i = s.begin(); i != s.end(); ++i) { - _subtitle_stream->Append (std_to_wx ((*i)->name()), new wxStringClientData (std_to_wx ((*i)->to_string ()))); - } - if (_film->subtitle_stream()) { - checked_set (_subtitle_stream, _film->subtitle_stream()->to_string()); - } else { - _subtitle_stream->SetSelection (wxNOT_FOUND); - } +// if (_film->use_content_audio() && _film->audio_stream()) { +// checked_set (_audio_stream, _film->audio_stream()->to_string()); +// } + + _ffmpeg_subtitle_stream->Clear (); +// vector > s = _film->subtitle_streams (); +// for (vector >::iterator i = s.begin(); i != s.end(); ++i) { +// _subtitle_stream->Append (std_to_wx ((*i)->name()), new wxStringClientData (std_to_wx ((*i)->to_string ()))); +// } +// if (_film->subtitle_stream()) { +// checked_set (_subtitle_stream, _film->subtitle_stream()->to_string()); +// } else { +// _subtitle_stream->SetSelection (wxNOT_FOUND); +// } } void -FilmEditor::audio_stream_changed (wxCommandEvent &) +FilmEditor::ffmpeg_audio_stream_changed (wxCommandEvent &) { if (!_film) { return; } +#if 0 _film->set_content_audio_stream ( audio_stream_factory ( string_client_data (_audio_stream->GetClientObject (_audio_stream->GetSelection ())), Film::state_version ) ); +#endif } void -FilmEditor::subtitle_stream_changed (wxCommandEvent &) +FilmEditor::ffmpeg_subtitle_stream_changed (wxCommandEvent &) { if (!_film) { return; } +#if 0 _film->set_subtitle_stream ( subtitle_stream_factory ( string_client_data (_subtitle_stream->GetClientObject (_subtitle_stream->GetSelection ())), Film::state_version ) ); +#endif } void FilmEditor::setup_audio_details () { +#if 0 if (!_film->content_audio_stream()) { _audio->SetLabel (wxT ("")); } else { @@ -1235,6 +1089,7 @@ FilmEditor::setup_audio_details () s << ", " << _film->audio_stream()->sample_rate() << wx_to_std (_("Hz")); _audio->SetLabel (std_to_wx (s.str ())); } +#endif } void @@ -1243,23 +1098,6 @@ FilmEditor::active_jobs_changed (bool a) set_things_sensitive (!a); } -void -FilmEditor::use_audio_changed (wxCommandEvent &) -{ - _film->set_use_content_audio (_use_content_audio->GetValue()); -} - -void -FilmEditor::external_audio_changed (wxCommandEvent &) -{ - vector a; - for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) { - a.push_back (wx_to_std (_external_audio[i]->GetPath())); - } - - _film->set_external_audio (a); -} - void FilmEditor::setup_dcp_name () { @@ -1292,11 +1130,23 @@ FilmEditor::best_dcp_frame_rate_clicked (wxCommandEvent &) return; } - _film->set_dcp_frame_rate (best_dcp_frame_rate (_film->source_frame_rate ())); +// _film->set_dcp_frame_rate (best_dcp_frame_rate (_film->source_frame_rate ())); } void FilmEditor::setup_show_audio_sensitivity () { - _show_audio->Enable (_film && _film->has_audio ()); +// _show_audio->Enable (_film && _film->has_audio ()); +} + +void +FilmEditor::setup_content () +{ + _content->DeleteAllItems (); + + list > content = _film->content (); + for (list >::iterator i = content.begin(); i != content.end(); ++i) { + _content->InsertItem (_content->GetItemCount(), std_to_wx ((*i)->summary ())); + } } + diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index e5b619886..6b1d98ea6 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -29,6 +29,7 @@ #include "lib/film.h" class wxNotebook; +class wxListCtrl; class Film; class AudioDialog; @@ -41,12 +42,12 @@ public: FilmEditor (boost::shared_ptr, wxWindow *); void set_film (boost::shared_ptr); - void setup_visibility (); boost::signals2::signal FileChanged; private: void make_film_panel (); + void make_content_panel (); void make_video_panel (); void make_audio_panel (); void make_subtitle_panel (); @@ -60,7 +61,6 @@ private: void right_crop_changed (wxCommandEvent &); void top_crop_changed (wxCommandEvent &); void bottom_crop_changed (wxCommandEvent &); - void content_changed (wxCommandEvent &); void trust_content_header_changed (wxCommandEvent &); void format_changed (wxCommandEvent &); void trim_start_changed (wxCommandEvent &); @@ -77,11 +77,8 @@ private: void subtitle_scale_changed (wxCommandEvent &); void colour_lut_changed (wxCommandEvent &); void j2k_bandwidth_changed (wxCommandEvent &); - void still_duration_changed (wxCommandEvent &); - void audio_stream_changed (wxCommandEvent &); - void subtitle_stream_changed (wxCommandEvent &); - void use_audio_changed (wxCommandEvent &); - void external_audio_changed (wxCommandEvent &); + void ffmpeg_audio_stream_changed (wxCommandEvent &); + void ffmpeg_subtitle_stream_changed (wxCommandEvent &); void dcp_frame_rate_changed (wxCommandEvent &); void best_dcp_frame_rate_clicked (wxCommandEvent &); @@ -94,20 +91,19 @@ private: void set_things_sensitive (bool); void setup_formats (); void setup_subtitle_control_sensitivity (); - void setup_audio_control_sensitivity (); void setup_streams (); void setup_audio_details (); void setup_dcp_name (); void setup_show_audio_sensitivity (); + void setup_content (); - wxControl* video_control (wxControl *); - wxControl* still_control (wxControl *); - void active_jobs_changed (bool); wxNotebook* _notebook; wxPanel* _film_panel; wxSizer* _film_sizer; + wxPanel* _content_panel; + wxSizer* _content_sizer; wxPanel* _video_panel; wxSizer* _video_sizer; wxPanel* _audio_panel; @@ -121,68 +117,47 @@ private: wxTextCtrl* _name; wxStaticText* _dcp_name; wxCheckBox* _use_dci_name; + wxListCtrl* _content; + wxButton* _content_add; + wxButton* _content_remove; + wxButton* _content_earlier; + wxButton* _content_later; wxButton* _edit_dci_button; - /** The Film's format */ wxChoice* _format; wxStaticText* _format_description; - /** The Film's content file */ - wxFilePickerCtrl* _content; wxCheckBox* _trust_content_header; - /** The Film's left crop */ wxSpinCtrl* _left_crop; - /** The Film's right crop */ wxSpinCtrl* _right_crop; - /** The Film's top crop */ wxSpinCtrl* _top_crop; - /** The Film's bottom crop */ wxSpinCtrl* _bottom_crop; - /** Currently-applied filters */ wxStaticText* _filters; - /** Button to open the filters dialogue */ wxButton* _filters_button; - /** The Film's scaler */ wxChoice* _scaler; - wxRadioButton* _use_content_audio; - wxChoice* _audio_stream; - wxRadioButton* _use_external_audio; - wxFilePickerCtrl* _external_audio[MAX_AUDIO_CHANNELS]; - /** The Film's audio gain */ wxSpinCtrl* _audio_gain; - /** A button to open the gain calculation dialogue */ wxButton* _audio_gain_calculate_button; wxButton* _show_audio; - /** The Film's audio delay */ wxSpinCtrl* _audio_delay; wxCheckBox* _with_subtitles; - wxChoice* _subtitle_stream; + wxChoice* _ffmpeg_subtitle_stream; wxSpinCtrl* _subtitle_offset; wxSpinCtrl* _subtitle_scale; wxChoice* _colour_lut; wxSpinCtrl* _j2k_bandwidth; - /** The Film's DCP content type */ wxChoice* _dcp_content_type; - /** The Film's source frame rate */ wxStaticText* _source_frame_rate; wxChoice* _dcp_frame_rate; wxButton* _best_dcp_frame_rate; wxStaticText* _frame_rate_description; - /** The Film's original size */ wxStaticText* _original_size; - /** The Film's length */ wxStaticText* _length; /** The Film's audio details */ wxStaticText* _audio; - /** The Film's duration for still sources */ - wxSpinCtrl* _still_duration; wxSpinCtrl* _trim_start; wxSpinCtrl* _trim_end; /** Selector to generate an A/B comparison DCP */ wxCheckBox* _dcp_ab; - std::list _video_controls; - std::list _still_controls; - std::vector _formats; bool _generally_sensitive; diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 08eade4d0..1e2a74be9 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -114,12 +114,10 @@ FilmViewer::film_changed (Film::Property p) } _decoders.video->Video.connect (bind (&FilmViewer::process_video, this, _1, _2, _3)); _decoders.video->OutputChanged.connect (boost::bind (&FilmViewer::decoder_changed, this)); - _decoders.video->set_subtitle_stream (_film->subtitle_stream()); +// _decoders.video->set_subtitle_stream (_film->subtitle_stream()); calculate_sizes (); get_frame (); _panel->Refresh (); - _slider->Show (_film->content_type() == VIDEO); - _play_button->Show (_film->content_type() == VIDEO); _v_sizer->Layout (); break; } @@ -132,7 +130,7 @@ FilmViewer::film_changed (Film::Property p) break; case Film::SUBTITLE_STREAM: if (_decoders.video) { - _decoders.video->set_subtitle_stream (_film->subtitle_stream ()); +// _decoders.video->set_subtitle_stream (_film->subtitle_stream ()); } break; default: @@ -187,12 +185,12 @@ FilmViewer::timer (wxTimerEvent &) get_frame (); - if (_film->length()) { - int const new_slider_position = 4096 * _decoders.video->last_source_time() / (_film->length().get() / _film->source_frame_rate()); - if (new_slider_position != _slider->GetValue()) { - _slider->SetValue (new_slider_position); - } - } +// if (_film->length()) { +// int const new_slider_position = 4096 * _decoders.video->last_source_time() / (_film->length().get() / _film->source_frame_rate()); +// if (new_slider_position != _slider->GetValue()) { +// _slider->SetValue (new_slider_position); +// } +// } } @@ -233,13 +231,13 @@ FilmViewer::paint_panel (wxPaintEvent &) void FilmViewer::slider_moved (wxScrollEvent &) { - if (!_film || !_film->length() || !_decoders.video) { - return; - } +// if (!_film || !_film->length() || !_decoders.video) { +// return; +// } - if (_decoders.video->seek (_slider->GetValue() * _film->length().get() / (4096 * _film->source_frame_rate()))) { - return; - } +// if (_decoders.video->seek (_slider->GetValue() * _film->length().get() / (4096 * _film->source_frame_rate()))) { +// return; +// } get_frame (); _panel->Refresh (); @@ -294,6 +292,7 @@ FilmViewer::raw_to_display () _clear_required = true; } +#if 0 if (_raw_sub) { /* Our output is already cropped by the decoder, so we need to account for that @@ -314,6 +313,7 @@ FilmViewer::raw_to_display () } else { _display_sub.reset (); } +#endif } void @@ -342,9 +342,9 @@ FilmViewer::calculate_sizes () of our _display_frame. */ _display_frame_x = 0; - if (format) { - _display_frame_x = static_cast (format->dcp_padding (_film)) * _out_size.width / format->dcp_size().width; - } +// if (format) { +// _display_frame_x = static_cast (format->dcp_padding (_film)) * _out_size.width / format->dcp_size().width; +// } _film_size = _out_size; _film_size.width -= _display_frame_x * 2; @@ -369,7 +369,7 @@ FilmViewer::check_play_state () } if (_play_button->GetValue()) { - _timer.Start (1000 / _film->source_frame_rate()); +// _timer.Start (1000 / _film->source_frame_rate()); } else { _timer.Stop (); } diff --git a/src/wx/properties_dialog.cc b/src/wx/properties_dialog.cc index 44a713dc3..06e245832 100644 --- a/src/wx/properties_dialog.cc +++ b/src/wx/properties_dialog.cc @@ -50,6 +50,7 @@ PropertiesDialog::PropertiesDialog (wxWindow* parent, shared_ptr film) _encoded = new ThreadedStaticText (this, _("counting..."), boost::bind (&PropertiesDialog::frames_already_encoded, this)); table->Add (_encoded, 1, wxALIGN_CENTER_VERTICAL); +#if 0 if (_film->length()) { _frames->SetLabel (std_to_wx (lexical_cast (_film->length().get()))); FrameRateConversion frc (_film->source_frame_rate(), _film->dcp_frame_rate()); @@ -62,6 +63,7 @@ PropertiesDialog::PropertiesDialog (wxWindow* parent, shared_ptr film) _frames->SetLabel (_("unknown")); _disk->SetLabel (_("unknown")); } +#endif wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL); overall_sizer->Add (table, 0, wxALL, 6); @@ -85,9 +87,9 @@ PropertiesDialog::frames_already_encoded () const return ""; } - if (_film->length()) { - /* XXX: encoded_frames() should check which frames have been encoded */ - u << " (" << (_film->encoded_frames() * 100 / _film->length().get()) << "%)"; - } +// if (_film->length()) { +// /* XXX: encoded_frames() should check which frames have been encoded */ +// u << " (" << (_film->encoded_frames() * 100 / _film->length().get()) << "%)"; +// } return u.str (); } diff --git a/test/test.cc b/test/test.cc index 61e192058..efa4848f6 100644 --- a/test/test.cc +++ b/test/test.cc @@ -142,7 +142,7 @@ BOOST_AUTO_TEST_CASE (film_metadata_test) BOOST_CHECK (f->filters ().empty()); f->set_name ("fred"); - BOOST_CHECK_THROW (f->set_content ("jim"), OpenFileError); +// BOOST_CHECK_THROW (f->set_content ("jim"), OpenFileError); f->set_dcp_content_type (DCPContentType::from_pretty_name ("Short")); f->set_format (Format::from_nickname ("Flat")); f->set_left_crop (1); @@ -183,50 +183,17 @@ BOOST_AUTO_TEST_CASE (film_metadata_test) BOOST_CHECK_EQUAL (::system (s.str().c_str ()), 0); } -BOOST_AUTO_TEST_CASE (stream_test) -{ - FFmpegAudioStream a ("ffmpeg 4 44100 1 hello there world", boost::optional (1)); - BOOST_CHECK_EQUAL (a.id(), 4); - BOOST_CHECK_EQUAL (a.sample_rate(), 44100); - BOOST_CHECK_EQUAL (a.channel_layout(), 1); - BOOST_CHECK_EQUAL (a.name(), "hello there world"); - BOOST_CHECK_EQUAL (a.to_string(), "ffmpeg 4 44100 1 hello there world"); - - SndfileStream e ("external 44100 1", boost::optional (1)); - BOOST_CHECK_EQUAL (e.sample_rate(), 44100); - BOOST_CHECK_EQUAL (e.channel_layout(), 1); - BOOST_CHECK_EQUAL (e.to_string(), "external 44100 1"); - - SubtitleStream s ("5 a b c", boost::optional (1)); - BOOST_CHECK_EQUAL (s.id(), 5); - BOOST_CHECK_EQUAL (s.name(), "a b c"); - - shared_ptr ff = audio_stream_factory ("ffmpeg 4 44100 1 hello there world", boost::optional (1)); - shared_ptr cff = dynamic_pointer_cast (ff); - BOOST_CHECK (cff); - BOOST_CHECK_EQUAL (cff->id(), 4); - BOOST_CHECK_EQUAL (cff->sample_rate(), 44100); - BOOST_CHECK_EQUAL (cff->channel_layout(), 1); - BOOST_CHECK_EQUAL (cff->name(), "hello there world"); - BOOST_CHECK_EQUAL (cff->to_string(), "ffmpeg 4 44100 1 hello there world"); - - shared_ptr fe = audio_stream_factory ("external 44100 1", boost::optional (1)); - BOOST_CHECK_EQUAL (fe->sample_rate(), 44100); - BOOST_CHECK_EQUAL (fe->channel_layout(), 1); - BOOST_CHECK_EQUAL (fe->to_string(), "external 44100 1"); -} - BOOST_AUTO_TEST_CASE (format_test) { Format::setup_formats (); Format const * f = Format::from_nickname ("Flat"); BOOST_CHECK (f); - BOOST_CHECK_EQUAL (f->ratio_as_integer(shared_ptr ()), 185); +// BOOST_CHECK_EQUAL (f->ratio_as_integer(shared_ptr ()), 185); f = Format::from_nickname ("Scope"); BOOST_CHECK (f); - BOOST_CHECK_EQUAL (f->ratio_as_integer(shared_ptr ()), 239); +// BOOST_CHECK_EQUAL (f->ratio_as_integer(shared_ptr ()), 239); } BOOST_AUTO_TEST_CASE (util_test) @@ -355,17 +322,6 @@ BOOST_AUTO_TEST_CASE (md5_digest_test) BOOST_CHECK_THROW (md5_digest ("foobar"), OpenFileError); } -BOOST_AUTO_TEST_CASE (paths_test) -{ - shared_ptr f = new_test_film ("paths_test"); - f->set_directory ("build/test/a/b/c/d/e"); - - f->_content = "/foo/bar/baz"; - BOOST_CHECK_EQUAL (f->content_path(), "/foo/bar/baz"); - f->_content = "foo/bar/baz"; - BOOST_CHECK_EQUAL (f->content_path(), "build/test/a/b/c/d/e/foo/bar/baz"); -} - void do_remote_encode (shared_ptr frame, ServerDescription* description, shared_ptr locally_encoded) { @@ -457,7 +413,7 @@ BOOST_AUTO_TEST_CASE (make_dcp_test) { shared_ptr film = new_test_film ("make_dcp_test"); film->set_name ("test_film2"); - film->set_content ("../../../test/test.mp4"); +// film->set_content ("../../../test/test.mp4"); film->set_format (Format::from_nickname ("Flat")); film->set_dcp_content_type (DCPContentType::from_pretty_name ("Test")); film->make_dcp (); @@ -487,8 +443,8 @@ BOOST_AUTO_TEST_CASE (make_dcp_with_range_test) { shared_ptr film = new_test_film ("make_dcp_with_range_test"); film->set_name ("test_film3"); - film->set_content ("../../../test/test.mp4"); - film->examine_content (); +// film->set_content ("../../../test/test.mp4"); +// film->examine_content (); film->set_format (Format::from_nickname ("Flat")); film->set_dcp_content_type (DCPContentType::from_pretty_name ("Test")); film->set_trim_end (42); @@ -649,44 +605,44 @@ BOOST_AUTO_TEST_CASE (audio_sampling_rate_test) Config::instance()->set_allowed_dcp_frame_rates (afr); shared_ptr f = new_test_film ("audio_sampling_rate_test"); - f->set_source_frame_rate (24); +// f->set_source_frame_rate (24); f->set_dcp_frame_rate (24); - f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 48000, 0))); +// f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 48000, 0))); BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 48000); - f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 44100, 0))); +// f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 44100, 0))); BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 48000); - f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 80000, 0))); +// f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 80000, 0))); BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 96000); - f->set_source_frame_rate (23.976); +// f->set_source_frame_rate (23.976); f->set_dcp_frame_rate (best_dcp_frame_rate (23.976)); - f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 48000, 0))); +// f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 48000, 0))); BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 47952); - f->set_source_frame_rate (29.97); +// f->set_source_frame_rate (29.97); f->set_dcp_frame_rate (best_dcp_frame_rate (29.97)); BOOST_CHECK_EQUAL (f->dcp_frame_rate (), 30); - f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 48000, 0))); +// f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 48000, 0))); BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 47952); - f->set_source_frame_rate (25); +// f->set_source_frame_rate (25); f->set_dcp_frame_rate (24); - f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 48000, 0))); +// f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 48000, 0))); BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 50000); - f->set_source_frame_rate (25); +// f->set_source_frame_rate (25); f->set_dcp_frame_rate (24); - f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 44100, 0))); +// f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 44100, 0))); BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 50000); /* Check some out-there conversions (not the best) */ - f->set_source_frame_rate (14.99); +// f->set_source_frame_rate (14.99); f->set_dcp_frame_rate (25); - f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 16000, 0))); +// f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 16000, 0))); /* The FrameRateConversion within target_audio_sample_rate should choose to double-up the 14.99 fps video to 30 and then run it slow at 25. */ -- cgit v1.2.3 From 5920000d247ab3ef7fb9ba29c6ba238b323cf909 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 31 Mar 2013 15:24:38 +0100 Subject: Allow adding of content. --- src/lib/imagemagick_content.cc | 25 +++++++++++++++++++++ src/lib/imagemagick_content.h | 4 ++++ src/lib/sndfile_content.cc | 16 +++++++++++++ src/lib/sndfile_content.h | 6 ++++- src/lib/util.cc | 13 ----------- src/lib/util.h | 6 ----- src/wx/film_editor.cc | 51 ++++++++++++++++++++++++++++++++++++++++++ src/wx/film_editor.h | 4 ++++ 8 files changed, 105 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/lib/imagemagick_content.cc b/src/lib/imagemagick_content.cc index d0887c0aa..806c8ac5d 100644 --- a/src/lib/imagemagick_content.cc +++ b/src/lib/imagemagick_content.cc @@ -1,2 +1,27 @@ #include "imagemagick_content.h" +#include "compose.hpp" +#include "i18n.h" + +using std::string; + +ImageMagickContent::ImageMagickContent (boost::filesystem::path f) + : Content (f) + , VideoContent (f) +{ + +} + +string +ImageMagickContent::summary () const +{ + return String::compose (_("Image: %1"), file().filename ()); +} + +bool +ImageMagickContent::valid_file (boost::filesystem::path f) +{ + string ext = f.extension().string(); + transform (ext.begin(), ext.end(), ext.begin(), ::tolower); + return (ext == ".tif" || ext == ".tiff" || ext == ".jpg" || ext == ".jpeg" || ext == ".png" || ext == ".bmp"); +} diff --git a/src/lib/imagemagick_content.h b/src/lib/imagemagick_content.h index 985aa0e8d..0dd5baba8 100644 --- a/src/lib/imagemagick_content.h +++ b/src/lib/imagemagick_content.h @@ -4,4 +4,8 @@ class ImageMagickContent : public VideoContent { public: ImageMagickContent (boost::filesystem::path); + + std::string summary () const; + + static bool valid_file (boost::filesystem::path); }; diff --git a/src/lib/sndfile_content.cc b/src/lib/sndfile_content.cc index 8f5b28901..53df4deea 100644 --- a/src/lib/sndfile_content.cc +++ b/src/lib/sndfile_content.cc @@ -5,6 +5,13 @@ using namespace std; +SndfileContent::SndfileContent (boost::filesystem::path f) + : Content (f) + , AudioContent (f) +{ + +} + string SndfileContent::summary () const { @@ -39,3 +46,12 @@ SndfileContent::audio_channel_layout () const return 0; } + +bool +SndfileContent::valid_file (boost::filesystem::path f) +{ + /* XXX: more extensions */ + string ext = f.extension().string(); + transform (ext.begin(), ext.end(), ext.begin(), ::tolower); + return (ext == ".wav" || ext == ".aif" || ext == ".aiff"); +} diff --git a/src/lib/sndfile_content.h b/src/lib/sndfile_content.h index e84617ed3..10cb428a1 100644 --- a/src/lib/sndfile_content.h +++ b/src/lib/sndfile_content.h @@ -3,11 +3,15 @@ class SndfileContent : public AudioContent { public: + SndfileContent (boost::filesystem::path); + std::string summary () const; - /* AudioDecoder */ + /* AudioContent */ int audio_channels () const; ContentAudioFrame audio_length () const; int audio_frame_rate () const; int64_t audio_channel_layout () const; + + static bool valid_file (boost::filesystem::path); }; diff --git a/src/lib/util.cc b/src/lib/util.cc index 024740867..1c020875a 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -878,19 +878,6 @@ video_frames_to_audio_frames (SourceFrame v, float audio_sample_rate, float fram return ((int64_t) v * audio_sample_rate / frames_per_second); } -/** @param f Filename. - * @return true if this file is a still image, false if it is something else. - */ -bool -still_image_file (string f) -{ - string ext = boost::filesystem::path(f).extension().string(); - - transform (ext.begin(), ext.end(), ext.begin(), ::tolower); - - return (ext == N_(".tif") || ext == N_(".tiff") || ext == N_(".jpg") || ext == N_(".jpeg") || ext == N_(".png") || ext == N_(".bmp")); -} - /** @return A pair containing CPU model name and the number of processors */ pair cpu_info () diff --git a/src/lib/util.h b/src/lib/util.h index 87274cfff..b8c1e3116 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -106,11 +106,6 @@ struct FrameRateConversion int best_dcp_frame_rate (float); -enum ContentType { - STILL, ///< content is still images - VIDEO ///< content is a video -}; - /** @struct Crop * @brief A description of the crop of an image or video. */ @@ -292,7 +287,6 @@ private: }; extern int64_t video_frames_to_audio_frames (SourceFrame v, float audio_sample_rate, float frames_per_second); -extern bool still_image_file (std::string); extern std::pair cpu_info (); #endif diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 7dfbf6c50..ce1c1abe8 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -38,6 +38,8 @@ #include "lib/filter.h" #include "lib/config.h" #include "lib/ffmpeg_decoder.h" +#include "lib/imagemagick_content.h" +#include "lib/sndfile_content.h" #include "filter_dialog.h" #include "wx_util.h" #include "film_editor.h" @@ -201,6 +203,10 @@ FilmEditor::connect_to_widgets () _edit_dci_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::edit_dci_button_clicked), 0, this); _format->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::format_changed), 0, this); _trust_content_header->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::trust_content_header_changed), 0, this); + _content_add->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_add_clicked), 0, this); + _content_remove->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_add_clicked), 0, this); + _content_earlier->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_add_clicked), 0, this); + _content_later->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_add_clicked), 0, this); _left_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::left_crop_changed), 0, this); _right_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::right_crop_changed), 0, this); _top_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::top_crop_changed), 0, this); @@ -834,6 +840,11 @@ FilmEditor::set_things_sensitive (bool s) _format->Enable (s); _content->Enable (s); _trust_content_header->Enable (s); + _content->Enable (s); + _content_add->Enable (s); + _content_remove->Enable (s); + _content_earlier->Enable (s); + _content_later->Enable (s); _left_crop->Enable (s); _right_crop->Enable (s); _top_crop->Enable (s); @@ -1150,3 +1161,43 @@ FilmEditor::setup_content () } } +void +FilmEditor::content_add_clicked (wxCommandEvent &) +{ + wxFileDialog* d = new wxFileDialog (this); + int const r = d->ShowModal (); + d->Destroy (); + + if (r != wxID_OK) { + return; + } + + boost::filesystem::path p (wx_to_std (d->GetPath())); + + if (ImageMagickContent::valid_file (p)) { + _film->add_content (shared_ptr (new ImageMagickContent (p))); + } else if (SndfileContent::valid_file (p)) { + _film->add_content (shared_ptr (new SndfileContent (p))); + } else { + _film->add_content (shared_ptr (new FFmpegContent (p))); + } + +} + +void +FilmEditor::content_remove_clicked (wxCommandEvent &) +{ + +} + +void +FilmEditor::content_earlier_clicked (wxCommandEvent &) +{ + +} + +void +FilmEditor::content_later_clicked (wxCommandEvent &) +{ + +} diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index 6b1d98ea6..52854b894 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -62,6 +62,10 @@ private: void top_crop_changed (wxCommandEvent &); void bottom_crop_changed (wxCommandEvent &); void trust_content_header_changed (wxCommandEvent &); + void content_add_clicked (wxCommandEvent &); + void content_remove_clicked (wxCommandEvent &); + void content_earlier_clicked (wxCommandEvent &); + void content_later_clicked (wxCommandEvent &); void format_changed (wxCommandEvent &); void trim_start_changed (wxCommandEvent &); void trim_end_changed (wxCommandEvent &); -- cgit v1.2.3 From a054c067ab2cbf6c5abc5df4caa08ffaac206f0b Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 31 Mar 2013 16:04:10 +0100 Subject: Content can be added and previewed. --- src/lib/ab_transcode_job.cc | 6 +- src/lib/ab_transcode_job.h | 5 +- src/lib/ab_transcoder.cc | 3 +- src/lib/ab_transcoder.h | 1 - src/lib/analyse_audio_job.cc | 1 - src/lib/audio_decoder.cc | 4 +- src/lib/audio_decoder.h | 2 +- src/lib/dcp_video_frame.cc | 1 - src/lib/decoder.cc | 4 +- src/lib/decoder.h | 5 +- src/lib/decoder_factory.cc | 2 +- src/lib/decoder_factory.h | 4 +- src/lib/encoder.cc | 1 - src/lib/examine_content_job.cc | 1 - src/lib/ffmpeg_content.cc | 5 +- src/lib/ffmpeg_decoder.cc | 31 ++++---- src/lib/ffmpeg_decoder.h | 7 +- src/lib/film.cc | 8 +- src/lib/imagemagick_decoder.cc | 7 +- src/lib/imagemagick_decoder.h | 2 +- src/lib/options.h | 43 ----------- src/lib/playlist.cc | 172 ++++++++++++++++++++++++++++++++--------- src/lib/playlist.h | 12 +++ src/lib/sndfile_decoder.cc | 6 +- src/lib/sndfile_decoder.h | 2 +- src/lib/transcode_job.cc | 6 +- src/lib/transcode_job.h | 6 +- src/lib/transcoder.cc | 4 +- src/lib/transcoder.h | 3 - src/lib/video_decoder.cc | 5 +- src/lib/video_decoder.h | 2 +- src/tools/servomatictest.cc | 11 ++- src/wx/film_editor.cc | 1 + src/wx/film_viewer.cc | 63 +++++++-------- src/wx/film_viewer.h | 2 +- 35 files changed, 232 insertions(+), 206 deletions(-) delete mode 100644 src/lib/options.h (limited to 'src') diff --git a/src/lib/ab_transcode_job.cc b/src/lib/ab_transcode_job.cc index f17d43916..2bdff47de 100644 --- a/src/lib/ab_transcode_job.cc +++ b/src/lib/ab_transcode_job.cc @@ -32,11 +32,9 @@ using std::string; using boost::shared_ptr; /** @param f Film to compare. - * @param o Decode options. */ -ABTranscodeJob::ABTranscodeJob (shared_ptr f, DecodeOptions o) +ABTranscodeJob::ABTranscodeJob (shared_ptr f) : Job (f) - , _decode_opt (o) { _film_b.reset (new Film (*_film)); _film_b->set_scaler (Config::instance()->reference_scaler ()); @@ -54,7 +52,7 @@ ABTranscodeJob::run () { try { /* _film_b is the one with reference filters */ - ABTranscoder w (_film_b, _film, _decode_opt, shared_from_this ()); + ABTranscoder w (_film_b, _film, shared_from_this ()); w.go (); set_progress (1); set_state (FINISHED_OK); diff --git a/src/lib/ab_transcode_job.h b/src/lib/ab_transcode_job.h index 5d029a18b..cd82d4247 100644 --- a/src/lib/ab_transcode_job.h +++ b/src/lib/ab_transcode_job.h @@ -23,7 +23,6 @@ #include #include "job.h" -#include "options.h" class Film; @@ -38,8 +37,7 @@ class ABTranscodeJob : public Job { public: ABTranscodeJob ( - boost::shared_ptr f, - DecodeOptions o + boost::shared_ptr f ); std::string name () const; @@ -48,5 +46,4 @@ public: private: /** Copy of our Film using the reference filters and scaler */ boost::shared_ptr _film_b; - DecodeOptions _decode_opt; }; diff --git a/src/lib/ab_transcoder.cc b/src/lib/ab_transcoder.cc index 0c687008d..6fc438ee8 100644 --- a/src/lib/ab_transcoder.cc +++ b/src/lib/ab_transcoder.cc @@ -23,7 +23,6 @@ #include "film.h" #include "encoder.h" #include "job.h" -#include "options.h" #include "image.h" #include "playlist.h" #include "matcher.h" @@ -47,7 +46,7 @@ using boost::dynamic_pointer_cast; * @param e Encoder to use. */ -ABTranscoder::ABTranscoder (shared_ptr a, shared_ptr b, DecodeOptions o, shared_ptr j) +ABTranscoder::ABTranscoder (shared_ptr a, shared_ptr b, shared_ptr j) : _film_a (a) , _film_b (b) , _playlist_a (_film_a->playlist ()) diff --git a/src/lib/ab_transcoder.h b/src/lib/ab_transcoder.h index 14277c562..090c26fb7 100644 --- a/src/lib/ab_transcoder.h +++ b/src/lib/ab_transcoder.h @@ -48,7 +48,6 @@ public: ABTranscoder ( boost::shared_ptr a, boost::shared_ptr b, - DecodeOptions o, boost::shared_ptr j ); diff --git a/src/lib/analyse_audio_job.cc b/src/lib/analyse_audio_job.cc index 74491943b..6e6dda886 100644 --- a/src/lib/analyse_audio_job.cc +++ b/src/lib/analyse_audio_job.cc @@ -21,7 +21,6 @@ #include "analyse_audio_job.h" #include "compose.hpp" #include "film.h" -#include "options.h" #include "playlist.h" #include "i18n.h" diff --git a/src/lib/audio_decoder.cc b/src/lib/audio_decoder.cc index a72cf11bb..e2006a795 100644 --- a/src/lib/audio_decoder.cc +++ b/src/lib/audio_decoder.cc @@ -22,8 +22,8 @@ using boost::optional; using boost::shared_ptr; -AudioDecoder::AudioDecoder (shared_ptr f, shared_ptr c, DecodeOptions o) - : Decoder (f, o) +AudioDecoder::AudioDecoder (shared_ptr f, shared_ptr c) + : Decoder (f) { } diff --git a/src/lib/audio_decoder.h b/src/lib/audio_decoder.h index 7d2a2bb62..cbb84b52d 100644 --- a/src/lib/audio_decoder.h +++ b/src/lib/audio_decoder.h @@ -35,7 +35,7 @@ class AudioContent; class AudioDecoder : public AudioSource, public virtual Decoder { public: - AudioDecoder (boost::shared_ptr, boost::shared_ptr, DecodeOptions); + AudioDecoder (boost::shared_ptr, boost::shared_ptr); }; #endif diff --git a/src/lib/dcp_video_frame.cc b/src/lib/dcp_video_frame.cc index d674393a9..e9499871a 100644 --- a/src/lib/dcp_video_frame.cc +++ b/src/lib/dcp_video_frame.cc @@ -47,7 +47,6 @@ #include "dcp_video_frame.h" #include "lut.h" #include "config.h" -#include "options.h" #include "exceptions.h" #include "server.h" #include "util.h" diff --git a/src/lib/decoder.cc b/src/lib/decoder.cc index 2fe265c14..c40446919 100644 --- a/src/lib/decoder.cc +++ b/src/lib/decoder.cc @@ -23,7 +23,6 @@ #include #include "film.h" -#include "options.h" #include "exceptions.h" #include "util.h" #include "decoder.h" @@ -36,9 +35,8 @@ using boost::shared_ptr; /** @param f Film. * @param o Decode options. */ -Decoder::Decoder (shared_ptr f, DecodeOptions o) +Decoder::Decoder (shared_ptr f) : _film (f) - , _opt (o) { _film_connection = f->Changed.connect (bind (&Decoder::film_changed, this, _1)); } diff --git a/src/lib/decoder.h b/src/lib/decoder.h index 50aa16dba..4ccdc046f 100644 --- a/src/lib/decoder.h +++ b/src/lib/decoder.h @@ -33,7 +33,6 @@ #include "video_source.h" #include "audio_source.h" #include "film.h" -#include "options.h" class Image; class Log; @@ -52,7 +51,7 @@ class FilterGraph; class Decoder { public: - Decoder (boost::shared_ptr, DecodeOptions); + Decoder (boost::shared_ptr); virtual ~Decoder () {} virtual bool pass () = 0; @@ -63,8 +62,6 @@ public: protected: boost::shared_ptr _film; - /** our decode options */ - DecodeOptions _opt; private: virtual void film_changed (Film::Property) {} diff --git a/src/lib/decoder_factory.cc b/src/lib/decoder_factory.cc index feaa1c7ef..7940edc2e 100644 --- a/src/lib/decoder_factory.cc +++ b/src/lib/decoder_factory.cc @@ -36,7 +36,7 @@ using boost::dynamic_pointer_cast; Decoders decoder_factory ( - shared_ptr f, DecodeOptions o + shared_ptr f ) { return Decoders (); diff --git a/src/lib/decoder_factory.h b/src/lib/decoder_factory.h index 8076b01c7..3fd91f876 100644 --- a/src/lib/decoder_factory.h +++ b/src/lib/decoder_factory.h @@ -24,8 +24,6 @@ * @brief A method to create appropriate decoders for some content. */ -#include "options.h" - class Film; class VideoDecoder; class AudioDecoder; @@ -43,7 +41,7 @@ struct Decoders { }; extern Decoders decoder_factory ( - boost::shared_ptr, DecodeOptions + boost::shared_ptr ); #endif diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 970213793..00807f863 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -27,7 +27,6 @@ #include #include "encoder.h" #include "util.h" -#include "options.h" #include "film.h" #include "log.h" #include "exceptions.h" diff --git a/src/lib/examine_content_job.cc b/src/lib/examine_content_job.cc index c600132c3..aad7f265e 100644 --- a/src/lib/examine_content_job.cc +++ b/src/lib/examine_content_job.cc @@ -19,7 +19,6 @@ #include #include "examine_content_job.h" -#include "options.h" #include "log.h" #include "content.h" diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index 25efb1ebf..6109b7212 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -1,6 +1,5 @@ #include "ffmpeg_content.h" #include "ffmpeg_decoder.h" -#include "options.h" #include "compose.hpp" #include "job.h" #include "util.h" @@ -33,9 +32,7 @@ FFmpegContent::examine (shared_ptr film, shared_ptr job, bool quick) job->set_progress_unknown (); - DecodeOptions o; - o.decode_audio = false; - shared_ptr decoder (new FFmpegDecoder (film, shared_from_this (), o)); + shared_ptr decoder (new FFmpegDecoder (film, shared_from_this (), true, false, false, true)); ContentVideoFrame video_length = 0; if (quick) { diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index c8e46776f..7b56a5971 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -41,7 +41,6 @@ extern "C" { #include "transcoder.h" #include "job.h" #include "filter.h" -#include "options.h" #include "exceptions.h" #include "image.h" #include "util.h" @@ -62,10 +61,10 @@ using boost::optional; using boost::dynamic_pointer_cast; using libdcp::Size; -FFmpegDecoder::FFmpegDecoder (shared_ptr f, shared_ptr c, DecodeOptions o) - : Decoder (f, o) - , VideoDecoder (f, c, o) - , AudioDecoder (f, c, o) +FFmpegDecoder::FFmpegDecoder (shared_ptr f, shared_ptr c, bool video, bool audio, bool subtitles, bool video_sync) + : Decoder (f) + , VideoDecoder (f, c) + , AudioDecoder (f, c) , _ffmpeg_content (c) , _format_context (0) , _video_stream (-1) @@ -76,13 +75,17 @@ FFmpegDecoder::FFmpegDecoder (shared_ptr f, shared_ptr= 0 && frame_finished) { filter_and_emit_video (_frame); } } - if (_ffmpeg_content->audio_stream() && _opt.decode_audio) { + if (_ffmpeg_content->audio_stream() && _decode_audio) { decode_audio_packet (); } @@ -245,7 +248,7 @@ FFmpegDecoder::pass () avcodec_get_frame_defaults (_frame); - if (_packet.stream_index == _video_stream && _opt.decode_video) { + if (_packet.stream_index == _video_stream && _decode_video) { int frame_finished; int const r = avcodec_decode_video2 (_video_codec_context, _frame, &frame_finished, &_packet); @@ -255,16 +258,16 @@ FFmpegDecoder::pass () _film->log()->log (String::compose (N_("Used only %1 bytes of %2 in packet"), r, _packet.size)); } - if (_opt.video_sync) { + if (_video_sync) { out_with_sync (); } else { filter_and_emit_video (_frame); } } - } else if (_ffmpeg_content->audio_stream() && _packet.stream_index == _ffmpeg_content->audio_stream()->id && _opt.decode_audio) { + } else if (_ffmpeg_content->audio_stream() && _packet.stream_index == _ffmpeg_content->audio_stream()->id && _decode_audio) { decode_audio_packet (); - } else if (_ffmpeg_content->subtitle_stream() && _packet.stream_index == _ffmpeg_content->subtitle_stream()->id && _opt.decode_subtitles && _first_video) { + } else if (_ffmpeg_content->subtitle_stream() && _packet.stream_index == _ffmpeg_content->subtitle_stream()->id && _decode_subtitles && _first_video) { int got_subtitle; AVSubtitle sub; @@ -633,9 +636,9 @@ FFmpegDecoder::decode_audio_packet () was before this packet. Until then audio is thrown away. */ - if ((_first_video && _first_video.get() <= source_pts_seconds) || !_opt.decode_video) { + if ((_first_video && _first_video.get() <= source_pts_seconds) || !_decode_video) { - if (!_first_audio && _opt.decode_video) { + if (!_first_audio && _decode_video) { _first_audio = source_pts_seconds; /* This is our first audio frame, and if we've arrived here we must have had our diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h index a0900d89f..ef66f09d9 100644 --- a/src/lib/ffmpeg_decoder.h +++ b/src/lib/ffmpeg_decoder.h @@ -57,7 +57,7 @@ class Log; class FFmpegDecoder : public VideoDecoder, public AudioDecoder { public: - FFmpegDecoder (boost::shared_ptr, boost::shared_ptr, DecodeOptions); + FFmpegDecoder (boost::shared_ptr, boost::shared_ptr, bool video, bool audio, bool subtitles, bool video_sync); ~FFmpegDecoder (); float frames_per_second () const; @@ -129,4 +129,9 @@ private: std::vector _subtitle_streams; std::vector _audio_streams; + + bool _decode_video; + bool _decode_audio; + bool _decode_subtitles; + bool _video_sync; }; diff --git a/src/lib/film.cc b/src/lib/film.cc index f69f63fd8..0e57cf8eb 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -40,7 +40,6 @@ #include "transcode_job.h" #include "scp_dcp_job.h" #include "log.h" -#include "options.h" #include "exceptions.h" #include "examine_content_job.h" #include "scaler.h" @@ -296,15 +295,12 @@ Film::make_dcp () throw MissingSettingError (_("name")); } - DecodeOptions od; - od.decode_subtitles = with_subtitles (); - shared_ptr r; if (dcp_ab()) { - r = JobManager::instance()->add (shared_ptr (new ABTranscodeJob (shared_from_this(), od))); + r = JobManager::instance()->add (shared_ptr (new ABTranscodeJob (shared_from_this()))); } else { - r = JobManager::instance()->add (shared_ptr (new TranscodeJob (shared_from_this(), od))); + r = JobManager::instance()->add (shared_ptr (new TranscodeJob (shared_from_this()))); } } diff --git a/src/lib/imagemagick_decoder.cc b/src/lib/imagemagick_decoder.cc index aa3c64f93..c3723f610 100644 --- a/src/lib/imagemagick_decoder.cc +++ b/src/lib/imagemagick_decoder.cc @@ -32,10 +32,9 @@ using std::cout; using boost::shared_ptr; using libdcp::Size; -ImageMagickDecoder::ImageMagickDecoder ( - shared_ptr f, shared_ptr c, DecodeOptions o) - : Decoder (f, o) - , VideoDecoder (f, c, o) +ImageMagickDecoder::ImageMagickDecoder (shared_ptr f, shared_ptr c) + : Decoder (f) + , VideoDecoder (f, c) , _imagemagick_content (c) , _position (0) { diff --git a/src/lib/imagemagick_decoder.h b/src/lib/imagemagick_decoder.h index b04bd88b1..a26e283c0 100644 --- a/src/lib/imagemagick_decoder.h +++ b/src/lib/imagemagick_decoder.h @@ -28,7 +28,7 @@ class ImageMagickContent; class ImageMagickDecoder : public VideoDecoder { public: - ImageMagickDecoder (boost::shared_ptr, boost::shared_ptr, DecodeOptions); + ImageMagickDecoder (boost::shared_ptr, boost::shared_ptr); float frames_per_second () const { /* We don't know */ diff --git a/src/lib/options.h b/src/lib/options.h deleted file mode 100644 index 0d2c07fd5..000000000 --- a/src/lib/options.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - Copyright (C) 2012 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef DVDOMATIC_OPTIONS_H -#define DVDOMATIC_OPTIONS_H - -/** @file src/options.h - * @brief Options for a decoding operation. - */ - -class DecodeOptions -{ -public: - DecodeOptions () - : decode_video (true) - , decode_audio (true) - , decode_subtitles (false) - , video_sync (true) - {} - - bool decode_video; - bool decode_audio; - bool decode_subtitles; - bool video_sync; -}; - -#endif diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index 17ecd2f37..fc9edac48 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -31,9 +31,12 @@ using boost::shared_ptr; using boost::dynamic_pointer_cast; Playlist::Playlist (shared_ptr f, list > c) - : _video_from (VIDEO_NONE) + : _film (f) + , _video_from (VIDEO_NONE) , _audio_from (AUDIO_NONE) + , _have_setup_decoders (false) , _ffmpeg_decoder_done (false) + , _video_sync (true) { for (list >::const_iterator i = c.begin(); i != c.end(); ++i) { shared_ptr fc = dynamic_pointer_cast (*i); @@ -60,42 +63,6 @@ Playlist::Playlist (shared_ptr f, list > c) _audio_from = AUDIO_SNDFILE; } } - - if (_video_from == VIDEO_FFMPEG || _audio_from == AUDIO_FFMPEG) { - DecodeOptions o; - /* XXX: decodeoptions */ - _ffmpeg_decoder.reset (new FFmpegDecoder (f, _ffmpeg, o)); - } - - if (_video_from == VIDEO_FFMPEG) { - _ffmpeg_decoder->connect_video (shared_from_this ()); - } - - if (_audio_from == AUDIO_FFMPEG) { - _ffmpeg_decoder->connect_audio (shared_from_this ()); - } - - if (_video_from == VIDEO_IMAGEMAGICK) { - for (list >::iterator i = _imagemagick.begin(); i != _imagemagick.end(); ++i) { - DecodeOptions o; - /* XXX: decodeoptions */ - shared_ptr d (new ImageMagickDecoder (f, *i, o)); - _imagemagick_decoders.push_back (d); - d->connect_video (shared_from_this ()); - } - - _imagemagick_decoder = _imagemagick_decoders.begin (); - } - - if (_audio_from == AUDIO_SNDFILE) { - for (list >::iterator i = _sndfile.begin(); i != _sndfile.end(); ++i) { - DecodeOptions o; - /* XXX: decodeoptions */ - shared_ptr d (new SndfileDecoder (f, *i, o)); - _sndfile_decoders.push_back (d); - d->connect_audio (shared_from_this ()); - } - } } ContentAudioFrame @@ -202,6 +169,27 @@ Playlist::video_size () const return libdcp::Size (); } +ContentVideoFrame +Playlist::video_length () const +{ + switch (_video_from) { + case VIDEO_NONE: + return 0; + case VIDEO_FFMPEG: + return _ffmpeg->video_length (); + case VIDEO_IMAGEMAGICK: + { + ContentVideoFrame l = 0; + for (list >::const_iterator i = _imagemagick.begin(); i != _imagemagick.end(); ++i) { + l += (*i)->video_length (); + } + return l; + } + } + + return 0; +} + bool Playlist::has_audio () const { @@ -214,9 +202,26 @@ Playlist::disable_video () _video_from = VIDEO_NONE; } +void +Playlist::disable_audio () +{ + _audio_from = AUDIO_NONE; +} + +void +Playlist::disable_subtitles () +{ + /* XXX */ +} + bool Playlist::pass () { + if (!_have_setup_decoders) { + setup_decoders (); + _have_setup_decoders = true; + } + bool done = true; if (_video_from == VIDEO_FFMPEG || _audio_from == AUDIO_FFMPEG) { @@ -264,3 +269,96 @@ Playlist::process_audio (shared_ptr b) Audio (b); } +bool +Playlist::seek (double t) +{ + bool r = false; + + switch (_video_from) { + case VIDEO_NONE: + break; + case VIDEO_FFMPEG: + if (_ffmpeg_decoder->seek (t)) { + r = true; + } + break; + case VIDEO_IMAGEMAGICK: + if ((*_imagemagick_decoder)->seek (t)) { + r = true; + } + break; + } + + /* XXX: don't seek audio because we don't need to... */ + + return r; +} + +bool +Playlist::seek_to_last () +{ + bool r = false; + + switch (_video_from) { + case VIDEO_NONE: + break; + case VIDEO_FFMPEG: + if (_ffmpeg_decoder->seek_to_last ()) { + r = true; + } + break; + case VIDEO_IMAGEMAGICK: + if ((*_imagemagick_decoder)->seek_to_last ()) { + r = true; + } + break; + } + + /* XXX: don't seek audio because we don't need to... */ + + return r; +} + +void +Playlist::setup_decoders () +{ + if (_video_from == VIDEO_FFMPEG || _audio_from == AUDIO_FFMPEG) { + _ffmpeg_decoder.reset ( + new FFmpegDecoder ( + _film, _ffmpeg, _video_from == VIDEO_FFMPEG, _audio_from == AUDIO_FFMPEG, _film->with_subtitles(), _video_sync + ) + ); + } + + if (_video_from == VIDEO_FFMPEG) { + _ffmpeg_decoder->connect_video (shared_from_this ()); + } + + if (_audio_from == AUDIO_FFMPEG) { + _ffmpeg_decoder->connect_audio (shared_from_this ()); + } + + if (_video_from == VIDEO_IMAGEMAGICK) { + for (list >::iterator i = _imagemagick.begin(); i != _imagemagick.end(); ++i) { + shared_ptr d (new ImageMagickDecoder (_film, *i)); + _imagemagick_decoders.push_back (d); + d->connect_video (shared_from_this ()); + } + + _imagemagick_decoder = _imagemagick_decoders.begin (); + } + + if (_audio_from == AUDIO_SNDFILE) { + for (list >::iterator i = _sndfile.begin(); i != _sndfile.end(); ++i) { + shared_ptr d (new SndfileDecoder (_film, *i)); + _sndfile_decoders.push_back (d); + d->connect_audio (shared_from_this ()); + } + } +} + +void +Playlist::disable_video_sync () +{ + _video_sync = false; +} diff --git a/src/lib/playlist.h b/src/lib/playlist.h index b42d46036..d374dc98c 100644 --- a/src/lib/playlist.h +++ b/src/lib/playlist.h @@ -48,16 +48,25 @@ public: float video_frame_rate () const; libdcp::Size video_size () const; + ContentVideoFrame video_length () const; void disable_video (); + void disable_audio (); + void disable_subtitles (); + void disable_video_sync (); bool pass (); void set_progress (boost::shared_ptr); + bool seek (double); + bool seek_to_last (); private: void process_video (boost::shared_ptr i, bool same, boost::shared_ptr s); void process_audio (boost::shared_ptr); + void setup_decoders (); + boost::shared_ptr _film; + enum { VIDEO_NONE, VIDEO_FFMPEG, @@ -74,9 +83,12 @@ private: std::list > _imagemagick; std::list > _sndfile; + bool _have_setup_decoders; boost::shared_ptr _ffmpeg_decoder; bool _ffmpeg_decoder_done; std::list > _imagemagick_decoders; std::list >::iterator _imagemagick_decoder; std::list > _sndfile_decoders; + + bool _video_sync; }; diff --git a/src/lib/sndfile_decoder.cc b/src/lib/sndfile_decoder.cc index 8848ff4f8..daa363c5e 100644 --- a/src/lib/sndfile_decoder.cc +++ b/src/lib/sndfile_decoder.cc @@ -36,9 +36,9 @@ using boost::optional; /* XXX */ -SndfileDecoder::SndfileDecoder (shared_ptr f, shared_ptr c, DecodeOptions o) - : Decoder (f, o) - , AudioDecoder (f, c, o) +SndfileDecoder::SndfileDecoder (shared_ptr f, shared_ptr c) + : Decoder (f) + , AudioDecoder (f, c) { sf_count_t frames; SNDFILE* sf = open_file (frames); diff --git a/src/lib/sndfile_decoder.h b/src/lib/sndfile_decoder.h index c06b97a60..9a3ef49b0 100644 --- a/src/lib/sndfile_decoder.h +++ b/src/lib/sndfile_decoder.h @@ -26,7 +26,7 @@ class SndfileContent; class SndfileDecoder : public AudioDecoder { public: - SndfileDecoder (boost::shared_ptr, boost::shared_ptr, DecodeOptions); + SndfileDecoder (boost::shared_ptr, boost::shared_ptr); bool pass (); diff --git a/src/lib/transcode_job.cc b/src/lib/transcode_job.cc index f8810975b..8b74f7766 100644 --- a/src/lib/transcode_job.cc +++ b/src/lib/transcode_job.cc @@ -39,11 +39,9 @@ using std::setprecision; using boost::shared_ptr; /** @param s Film to use. - * @param o Decode options. */ -TranscodeJob::TranscodeJob (shared_ptr f, DecodeOptions o) +TranscodeJob::TranscodeJob (shared_ptr f) : Job (f) - , _decode_opt (o) { } @@ -62,7 +60,7 @@ TranscodeJob::run () _film->log()->log (N_("Transcode job starting")); _film->log()->log (String::compose (N_("Audio delay is %1ms"), _film->audio_delay())); - Transcoder w (_film, _decode_opt, shared_from_this ()); + Transcoder w (_film, shared_from_this ()); w.go (); set_progress (1); set_state (FINISHED_OK); diff --git a/src/lib/transcode_job.h b/src/lib/transcode_job.h index a409ec97e..def545958 100644 --- a/src/lib/transcode_job.h +++ b/src/lib/transcode_job.h @@ -23,7 +23,6 @@ #include #include "job.h" -#include "options.h" class Encoder; @@ -33,7 +32,7 @@ class Encoder; class TranscodeJob : public Job { public: - TranscodeJob (boost::shared_ptr f, DecodeOptions od); + TranscodeJob (boost::shared_ptr f); std::string name () const; void run (); @@ -41,7 +40,4 @@ public: protected: int remaining_time () const; - -private: - DecodeOptions _decode_opt; }; diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc index 19d067149..070258008 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -32,7 +32,6 @@ #include "film.h" #include "matcher.h" #include "delay_line.h" -#include "options.h" #include "gain.h" #include "video_decoder.h" #include "audio_decoder.h" @@ -44,11 +43,10 @@ using boost::dynamic_pointer_cast; /** Construct a transcoder using a Decoder that we create and a supplied Encoder. * @param f Film that we are transcoding. - * @param o Decode options. * @param j Job that we are running under, or 0. * @param e Encoder to use. */ -Transcoder::Transcoder (shared_ptr f, DecodeOptions o, shared_ptr j) +Transcoder::Transcoder (shared_ptr f, shared_ptr j) : _job (j) , _playlist (f->playlist ()) , _encoder (new Encoder (f, _playlist)) diff --git a/src/lib/transcoder.h b/src/lib/transcoder.h index 8d34af948..3c47b0c7e 100644 --- a/src/lib/transcoder.h +++ b/src/lib/transcoder.h @@ -18,7 +18,6 @@ */ /** @file src/transcoder.h - * @brief A class which takes a Film and some Options, then uses those to transcode the film. * * A decoder is selected according to the content type, and the encoder can be specified * as a parameter to the constructor. @@ -36,7 +35,6 @@ class DelayLine; class Playlist; /** @class Transcoder - * @brief A class which takes a Film and some Options, then uses those to transcode the film. * * A decoder is selected according to the content type, and the encoder can be specified * as a parameter to the constructor. @@ -46,7 +44,6 @@ class Transcoder public: Transcoder ( boost::shared_ptr f, - DecodeOptions o, boost::shared_ptr j ); diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc index ca1e7ab56..33dd433ea 100644 --- a/src/lib/video_decoder.cc +++ b/src/lib/video_decoder.cc @@ -22,7 +22,6 @@ #include "film.h" #include "image.h" #include "log.h" -#include "options.h" #include "job.h" #include "i18n.h" @@ -30,8 +29,8 @@ using boost::shared_ptr; using boost::optional; -VideoDecoder::VideoDecoder (shared_ptr f, shared_ptr c, DecodeOptions o) - : Decoder (f, o) +VideoDecoder::VideoDecoder (shared_ptr f, shared_ptr c) + : Decoder (f) , _video_frame (0) , _last_source_time (0) { diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h index a52e5448a..03dc4777a 100644 --- a/src/lib/video_decoder.h +++ b/src/lib/video_decoder.h @@ -28,7 +28,7 @@ class VideoContent; class VideoDecoder : public VideoSource, public virtual Decoder { public: - VideoDecoder (boost::shared_ptr, boost::shared_ptr, DecodeOptions); + VideoDecoder (boost::shared_ptr, boost::shared_ptr); /** @return video frames per second, or 0 if unknown */ virtual float frames_per_second () const = 0; diff --git a/src/tools/servomatictest.cc b/src/tools/servomatictest.cc index f5756c693..d08fefa90 100644 --- a/src/tools/servomatictest.cc +++ b/src/tools/servomatictest.cc @@ -28,7 +28,6 @@ #include "scaler.h" #include "server.h" #include "dcp_video_frame.h" -#include "options.h" #include "decoder.h" #include "exceptions.h" #include "scaler.h" @@ -151,12 +150,12 @@ main (int argc, char* argv[]) server = new ServerDescription (server_host, 1); shared_ptr film (new Film (film_dir, true)); - DecodeOptions opt; - opt.decode_audio = false; - opt.decode_subtitles = true; - opt.video_sync = true; + /* XXX */ +// opt.decode_audio = false; +// opt.decode_subtitles = true; +// opt.video_sync = true; - Decoders decoders = decoder_factory (film, opt); + Decoders decoders = decoder_factory (film); try { decoders.video->Video.connect (boost::bind (process_video, _1, _2, _3)); bool done = false; diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index ce1c1abe8..f9a91f8fa 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -347,6 +347,7 @@ FilmEditor::make_content_panel () s->Add (_content, 1, wxEXPAND | wxTOP | wxBOTTOM, 6); _content->InsertColumn (0, ""); + _content->SetColumnWidth (0, 512); wxBoxSizer* b = new wxBoxSizer (wxVERTICAL); _content_add = new wxButton (_content_panel, wxID_ANY, _("Add...")); diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 1e2a74be9..42af4b3c0 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -28,13 +28,13 @@ #include "lib/format.h" #include "lib/util.h" #include "lib/job_manager.h" -#include "lib/options.h" #include "lib/subtitle.h" #include "lib/image.h" #include "lib/scaler.h" #include "lib/exceptions.h" #include "lib/examine_content_job.h" #include "lib/filter.h" +#include "lib/playlist.h" #include "film_viewer.h" #include "wx_util.h" #include "video_decoder.h" @@ -97,24 +97,13 @@ FilmViewer::film_changed (Film::Property p) break; case Film::CONTENT: { - DecodeOptions o; - o.decode_audio = false; - o.decode_subtitles = true; - o.video_sync = false; - - try { - _decoders = decoder_factory (_film, o); - } catch (StringError& e) { - error_dialog (this, wxString::Format (_("Could not open content file (%s)"), std_to_wx(e.what()).data())); - return; - } - - if (_decoders.video == 0) { - break; - } - _decoders.video->Video.connect (bind (&FilmViewer::process_video, this, _1, _2, _3)); - _decoders.video->OutputChanged.connect (boost::bind (&FilmViewer::decoder_changed, this)); -// _decoders.video->set_subtitle_stream (_film->subtitle_stream()); + _playlist = _film->playlist (); + _playlist->disable_audio (); + _playlist->disable_subtitles (); + _playlist->disable_video_sync (); + + _playlist->Video.connect (bind (&FilmViewer::process_video, this, _1, _2, _3)); +// _playlist->OutputChanged.connect (boost::bind (&FilmViewer::decoder_changed, this)); calculate_sizes (); get_frame (); _panel->Refresh (); @@ -129,9 +118,9 @@ FilmViewer::film_changed (Film::Property p) update_from_raw (); break; case Film::SUBTITLE_STREAM: - if (_decoders.video) { +// if (_decoders.video) { // _decoders.video->set_subtitle_stream (_film->subtitle_stream ()); - } +// } break; default: break; @@ -164,7 +153,7 @@ FilmViewer::set_film (shared_ptr f) void FilmViewer::decoder_changed () { - if (_decoders.video == 0 || _decoders.video->seek_to_last ()) { + if (!_playlist == 0 || _playlist->seek_to_last ()) { return; } @@ -176,7 +165,7 @@ FilmViewer::decoder_changed () void FilmViewer::timer (wxTimerEvent &) { - if (!_film || !_decoders.video) { + if (!_playlist) { return; } @@ -185,8 +174,8 @@ FilmViewer::timer (wxTimerEvent &) get_frame (); -// if (_film->length()) { -// int const new_slider_position = 4096 * _decoders.video->last_source_time() / (_film->length().get() / _film->source_frame_rate()); +// if (_playlist->video_length()) { +// int const new_slider_position = 4096 * _playlist->last_source_time() / (_film->length().get() / _film->source_frame_rate()); // if (new_slider_position != _slider->GetValue()) { // _slider->SetValue (new_slider_position); // } @@ -231,13 +220,13 @@ FilmViewer::paint_panel (wxPaintEvent &) void FilmViewer::slider_moved (wxScrollEvent &) { -// if (!_film || !_film->length() || !_decoders.video) { -// return; -// } + if (!_film || !_playlist) { + return; + } -// if (_decoders.video->seek (_slider->GetValue() * _film->length().get() / (4096 * _film->source_frame_rate()))) { -// return; -// } + if (_playlist->seek (_slider->GetValue() * _playlist->video_length() / (4096 * _playlist->video_frame_rate()))) { + return; + } get_frame (); _panel->Refresh (); @@ -319,7 +308,7 @@ FilmViewer::raw_to_display () void FilmViewer::calculate_sizes () { - if (!_film) { + if (!_film || !_playlist) { return; } @@ -342,9 +331,9 @@ FilmViewer::calculate_sizes () of our _display_frame. */ _display_frame_x = 0; -// if (format) { -// _display_frame_x = static_cast (format->dcp_padding (_film)) * _out_size.width / format->dcp_size().width; -// } + if (format) { + _display_frame_x = static_cast (format->dcp_padding (_playlist)) * _out_size.width / format->dcp_size().width; + } _film_size = _out_size; _film_size.width -= _display_frame_x * 2; @@ -392,7 +381,7 @@ FilmViewer::get_frame () /* Clear our raw frame in case we don't get a new one */ _raw_frame.reset (); - if (_decoders.video == 0) { + if (!_playlist) { _display_frame.reset (); return; } @@ -400,7 +389,7 @@ FilmViewer::get_frame () try { _got_frame = false; while (!_got_frame) { - if (_decoders.video->pass ()) { + if (_playlist->pass ()) { /* We didn't get a frame before the decoder gave up, so clear our display frame. */ diff --git a/src/wx/film_viewer.h b/src/wx/film_viewer.h index 456301eb4..b552a3dbc 100644 --- a/src/wx/film_viewer.h +++ b/src/wx/film_viewer.h @@ -58,6 +58,7 @@ private: void active_jobs_changed (bool); boost::shared_ptr _film; + boost::shared_ptr _playlist; wxSizer* _v_sizer; wxPanel* _panel; @@ -65,7 +66,6 @@ private: wxToggleButton* _play_button; wxTimer _timer; - Decoders _decoders; boost::shared_ptr _raw_frame; boost::shared_ptr _raw_sub; boost::shared_ptr _display_frame; -- cgit v1.2.3 From 42e66495a93a04804e9a5373cf673dc8c7a438a6 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 31 Mar 2013 16:16:20 +0100 Subject: Content button sensitivity. --- src/wx/film_editor.cc | 23 +++++++++++++++++++---- src/wx/film_editor.h | 3 +++ 2 files changed, 22 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index f9a91f8fa..100d3a93d 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -203,6 +203,7 @@ FilmEditor::connect_to_widgets () _edit_dci_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::edit_dci_button_clicked), 0, this); _format->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::format_changed), 0, this); _trust_content_header->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::trust_content_header_changed), 0, this); + _content->Connect (wxID_ANY, wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler (FilmEditor::content_item_selected), 0, this); _content_add->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_add_clicked), 0, this); _content_remove->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_add_clicked), 0, this); _content_earlier->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_add_clicked), 0, this); @@ -842,10 +843,6 @@ FilmEditor::set_things_sensitive (bool s) _content->Enable (s); _trust_content_header->Enable (s); _content->Enable (s); - _content_add->Enable (s); - _content_remove->Enable (s); - _content_earlier->Enable (s); - _content_later->Enable (s); _left_crop->Enable (s); _right_crop->Enable (s); _top_crop->Enable (s); @@ -867,6 +864,7 @@ FilmEditor::set_things_sensitive (bool s) setup_subtitle_control_sensitivity (); setup_show_audio_sensitivity (); + setup_content_button_sensitivity (); } /** Called when the `Edit filters' button has been clicked */ @@ -1202,3 +1200,20 @@ FilmEditor::content_later_clicked (wxCommandEvent &) { } + +void +FilmEditor::content_item_selected (wxListEvent &) +{ + setup_content_button_sensitivity (); +} + +void +FilmEditor::setup_content_button_sensitivity () +{ + _content_add->Enable (_generally_sensitive); + + bool const have_selection = _content->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED) != -1; + _content_remove->Enable (have_selection && _generally_sensitive); + _content_earlier->Enable (have_selection && _generally_sensitive); + _content_later->Enable (have_selection && _generally_sensitive); +} diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index 52854b894..4048cd587 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -30,6 +30,7 @@ class wxNotebook; class wxListCtrl; +class wxListEvent; class Film; class AudioDialog; @@ -62,6 +63,7 @@ private: void top_crop_changed (wxCommandEvent &); void bottom_crop_changed (wxCommandEvent &); void trust_content_header_changed (wxCommandEvent &); + void content_item_selected (wxListEvent &); void content_add_clicked (wxCommandEvent &); void content_remove_clicked (wxCommandEvent &); void content_earlier_clicked (wxCommandEvent &); @@ -100,6 +102,7 @@ private: void setup_dcp_name (); void setup_show_audio_sensitivity (); void setup_content (); + void setup_content_button_sensitivity (); void active_jobs_changed (bool); -- cgit v1.2.3 From d5a4d9632b352192027700dbb1f59827216b16e8 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 31 Mar 2013 16:18:28 +0100 Subject: Stub to make still image content work. --- src/lib/imagemagick_content.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/imagemagick_content.cc b/src/lib/imagemagick_content.cc index 806c8ac5d..d096bff84 100644 --- a/src/lib/imagemagick_content.cc +++ b/src/lib/imagemagick_content.cc @@ -9,7 +9,8 @@ ImageMagickContent::ImageMagickContent (boost::filesystem::path f) : Content (f) , VideoContent (f) { - + /* XXX */ + _video_length = 10 * 24; } string -- cgit v1.2.3 From 640c53f0a5f178a894ff2718bf6d74e9e977eb80 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 31 Mar 2013 16:23:01 +0100 Subject: A little tidying up. --- src/lib/film.cc | 20 ++++++++++---------- src/lib/film.h | 14 +++++--------- src/wx/film_editor.cc | 23 +++++++++-------------- src/wx/film_editor.h | 5 ++--- 4 files changed, 26 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/lib/film.cc b/src/lib/film.cc index 0e57cf8eb..d22f67e67 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -87,7 +87,7 @@ int const Film::state_version = 4; Film::Film (string d, bool must_exist) : _use_dci_name (true) - , _trust_content_header (true) + , _trust_content_headers (true) , _dcp_content_type (0) , _format (0) , _scaler (Scaler::from_id ("bicubic")) @@ -149,7 +149,7 @@ Film::Film (Film const & o) , _directory (o._directory) , _name (o._name) , _use_dci_name (o._use_dci_name) - , _trust_content_header (o._trust_content_header) + , _trust_content_headers (o._trust_content_headers) , _dcp_content_type (o._dcp_content_type) , _format (o._format) , _crop (o._crop) @@ -321,7 +321,7 @@ Film::analyse_audio () void Film::examine_content (shared_ptr c) { - shared_ptr j (new ExamineContentJob (shared_from_this(), c, trust_content_header ())); + shared_ptr j (new ExamineContentJob (shared_from_this(), c, trust_content_headers ())); j->Finished.connect (bind (&Film::examine_content_finished, this)); JobManager::instance()->add (j); } @@ -391,7 +391,7 @@ Film::write_metadata () const f << "name " << _name << endl; f << "use_dci_name " << _use_dci_name << endl; // f << "content " << _content << endl; - f << "trust_content_header " << (_trust_content_header ? "1" : "0") << endl; + f << "trust_content_headers " << (_trust_content_headers ? "1" : "0") << endl; if (_dcp_content_type) { f << "dcp_content_type " << _dcp_content_type->dci_name () << endl; } @@ -495,8 +495,8 @@ Film::read_metadata () _use_dci_name = (v == "1"); } else if (k == "content") { // _content = v; - } else if (k == "trust_content_header") { - _trust_content_header = (v == "1"); + } else if (k == "trust_content_headers") { + _trust_content_headers = (v == "1"); } else if (k == "dcp_content_type") { if (version < 3) { _dcp_content_type = DCPContentType::from_pretty_name (v); @@ -792,16 +792,16 @@ Film::set_use_dci_name (bool u) } void -Film::set_trust_content_header (bool t) +Film::set_trust_content_headers (bool t) { { boost::mutex::scoped_lock lm (_state_mutex); - _trust_content_header = t; + _trust_content_headers = t; } - signal_changed (TRUST_CONTENT_HEADER); + signal_changed (TRUST_CONTENT_HEADERS); - if (!_trust_content_header && !content().empty()) { + if (!_trust_content_headers && !content().empty()) { /* We just said that we don't trust the content's header */ /* XXX */ // examine_content (); diff --git a/src/lib/film.h b/src/lib/film.h index afd57b7c2..928866161 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -114,7 +114,7 @@ public: NONE, NAME, USE_DCI_NAME, - TRUST_CONTENT_HEADER, + TRUST_CONTENT_HEADERS, CONTENT, DCP_CONTENT_TYPE, FORMAT, @@ -155,9 +155,9 @@ public: return _use_dci_name; } - bool trust_content_header () const { + bool trust_content_headers () const { boost::mutex::scoped_lock lm (_state_mutex); - return _trust_content_header; + return _trust_content_headers; } std::list > content () const { @@ -255,7 +255,7 @@ public: void set_directory (std::string); void set_name (std::string); void set_use_dci_name (bool); - void set_trust_content_header (bool); + void set_trust_content_headers (bool); void add_content (boost::shared_ptr); void set_dcp_content_type (DCPContentType const *); void set_format (Format const *); @@ -314,11 +314,7 @@ private: bool _use_dci_name; typedef std::list > ContentList; ContentList _content; - /** If this is true, we will believe the length specified by the content - * file's header; if false, we will run through the whole content file - * the first time we see it in order to obtain the length. - */ - bool _trust_content_header; + bool _trust_content_headers; /** The type of content that this Film represents (feature, trailer etc.) */ DCPContentType const * _dcp_content_type; /** The format to present this Film in (flat, scope, etc.) */ diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 100d3a93d..40f4f0362 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -122,8 +122,8 @@ FilmEditor::make_film_panel () grid->Add (_edit_dci_button, wxGBPosition (r, 1), wxDefaultSpan); ++r; - _trust_content_header = new wxCheckBox (_film_panel, wxID_ANY, _("Trust content's header")); - grid->Add (_trust_content_header, wxGBPosition (r, 0), wxGBSpan(1, 2)); + _trust_content_headers = new wxCheckBox (_film_panel, wxID_ANY, _("Trust content's header")); + grid->Add (_trust_content_headers, wxGBPosition (r, 0), wxGBSpan(1, 2)); ++r; add_label_to_grid_bag_sizer (grid, _film_panel, _("Content Type"), wxGBPosition (r, 0)); @@ -131,11 +131,6 @@ FilmEditor::make_film_panel () grid->Add (_dcp_content_type, wxGBPosition (r, 1)); ++r; - add_label_to_grid_bag_sizer (grid, _film_panel, _("Original Frame Rate"), wxGBPosition (r, 0)); - _source_frame_rate = new wxStaticText (_film_panel, wxID_ANY, wxT ("")); - grid->Add (_source_frame_rate, wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); - ++r; - { add_label_to_grid_bag_sizer (grid, _film_panel, _("DCP Frame Rate"), wxGBPosition (r, 0)); wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); @@ -202,7 +197,7 @@ FilmEditor::connect_to_widgets () _use_dci_name->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::use_dci_name_toggled), 0, this); _edit_dci_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::edit_dci_button_clicked), 0, this); _format->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::format_changed), 0, this); - _trust_content_header->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::trust_content_header_changed), 0, this); + _trust_content_headers->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::trust_content_headers_changed), 0, this); _content->Connect (wxID_ANY, wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler (FilmEditor::content_item_selected), 0, this); _content_add->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_add_clicked), 0, this); _content_remove->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_add_clicked), 0, this); @@ -483,13 +478,13 @@ FilmEditor::bottom_crop_changed (wxCommandEvent &) } void -FilmEditor::trust_content_header_changed (wxCommandEvent &) +FilmEditor::trust_content_headers_changed (wxCommandEvent &) { if (!_film) { return; } - _film->set_trust_content_header (_trust_content_header->GetValue ()); + _film->set_trust_content_headers (_trust_content_headers->GetValue ()); } /** Called when the DCP A/B switch has been toggled */ @@ -594,8 +589,8 @@ FilmEditor::film_changed (Film::Property p) setup_streams (); setup_show_audio_sensitivity (); break; - case Film::TRUST_CONTENT_HEADER: - checked_set (_trust_content_header, _film->trust_content_header ()); + case Film::TRUST_CONTENT_HEADERS: + checked_set (_trust_content_headers, _film->trust_content_headers ()); break; // case Film::SUBTITLE_STREAMS: // setup_subtitle_control_sensitivity (); @@ -808,7 +803,7 @@ FilmEditor::set_film (shared_ptr f) film_changed (Film::NAME); film_changed (Film::USE_DCI_NAME); film_changed (Film::CONTENT); - film_changed (Film::TRUST_CONTENT_HEADER); + film_changed (Film::TRUST_CONTENT_HEADERS); film_changed (Film::DCP_CONTENT_TYPE); film_changed (Film::FORMAT); film_changed (Film::CROP); @@ -841,7 +836,7 @@ FilmEditor::set_things_sensitive (bool s) _edit_dci_button->Enable (s); _format->Enable (s); _content->Enable (s); - _trust_content_header->Enable (s); + _trust_content_headers->Enable (s); _content->Enable (s); _left_crop->Enable (s); _right_crop->Enable (s); diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index 4048cd587..50457bdce 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -62,7 +62,7 @@ private: void right_crop_changed (wxCommandEvent &); void top_crop_changed (wxCommandEvent &); void bottom_crop_changed (wxCommandEvent &); - void trust_content_header_changed (wxCommandEvent &); + void trust_content_headers_changed (wxCommandEvent &); void content_item_selected (wxListEvent &); void content_add_clicked (wxCommandEvent &); void content_remove_clicked (wxCommandEvent &); @@ -132,7 +132,7 @@ private: wxButton* _edit_dci_button; wxChoice* _format; wxStaticText* _format_description; - wxCheckBox* _trust_content_header; + wxCheckBox* _trust_content_headers; wxSpinCtrl* _left_crop; wxSpinCtrl* _right_crop; wxSpinCtrl* _top_crop; @@ -151,7 +151,6 @@ private: wxChoice* _colour_lut; wxSpinCtrl* _j2k_bandwidth; wxChoice* _dcp_content_type; - wxStaticText* _source_frame_rate; wxChoice* _dcp_frame_rate; wxButton* _best_dcp_frame_rate; wxStaticText* _frame_rate_description; -- cgit v1.2.3 From b468ccabdb13fca86ae8a324239d83490ef5832e Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 1 Apr 2013 02:25:02 +0100 Subject: XML metadata and some other bits. --- src/lib/ab_transcoder.h | 1 - src/lib/audio_content.cc | 9 ++ src/lib/audio_content.h | 5 + src/lib/config.cc | 89 ++++++++++--- src/lib/config.h | 3 +- src/lib/content.cc | 16 +++ src/lib/content.h | 7 + src/lib/dci_metadata.cc | 33 +++-- src/lib/dci_metadata.h | 12 +- src/lib/decoder_factory.cc | 43 ------ src/lib/decoder_factory.h | 47 ------- src/lib/ffmpeg_content.cc | 86 ++++++++++++ src/lib/ffmpeg_content.h | 10 ++ src/lib/film.cc | 293 +++++++++++++++-------------------------- src/lib/film.h | 10 +- src/lib/imagemagick_content.cc | 9 ++ src/lib/imagemagick_content.h | 5 + src/lib/server.cc | 23 ++-- src/lib/server.h | 9 +- src/lib/sndfile_content.cc | 11 +- src/lib/sndfile_content.h | 5 + src/lib/transcoder.cc | 1 - src/lib/transcoder.h | 2 - src/lib/video_content.cc | 22 ++++ src/lib/video_content.h | 3 + src/lib/wscript | 3 +- src/tools/makedcp.cc | 2 +- src/tools/servomatictest.cc | 13 +- src/wx/audio_plot.cc | 1 - src/wx/film_editor.cc | 18 +-- src/wx/film_editor.h | 4 +- src/wx/film_viewer.h | 1 - test/test.cc | 4 +- 33 files changed, 443 insertions(+), 357 deletions(-) delete mode 100644 src/lib/decoder_factory.cc delete mode 100644 src/lib/decoder_factory.h (limited to 'src') diff --git a/src/lib/ab_transcoder.h b/src/lib/ab_transcoder.h index 090c26fb7..5ce4a03da 100644 --- a/src/lib/ab_transcoder.h +++ b/src/lib/ab_transcoder.h @@ -25,7 +25,6 @@ #include #include #include "util.h" -#include "decoder_factory.h" class Job; class Encoder; diff --git a/src/lib/audio_content.cc b/src/lib/audio_content.cc index e9eacfd79..74b8ea2ce 100644 --- a/src/lib/audio_content.cc +++ b/src/lib/audio_content.cc @@ -1,7 +1,16 @@ +#include #include "audio_content.h" +using boost::shared_ptr; + AudioContent::AudioContent (boost::filesystem::path f) : Content (f) { } + +AudioContent::AudioContent (shared_ptr node) + : Content (node) +{ + +} diff --git a/src/lib/audio_content.h b/src/lib/audio_content.h index e18d1082e..f3dd81efb 100644 --- a/src/lib/audio_content.h +++ b/src/lib/audio_content.h @@ -4,10 +4,15 @@ #include "content.h" #include "util.h" +namespace cxml { + class Node; +} + class AudioContent : public virtual Content { public: AudioContent (boost::filesystem::path); + AudioContent (boost::shared_ptr); virtual int audio_channels () const = 0; virtual ContentAudioFrame audio_length () const = 0; diff --git a/src/lib/config.cc b/src/lib/config.cc index 5dce3748d..2defa0539 100644 --- a/src/lib/config.cc +++ b/src/lib/config.cc @@ -22,6 +22,7 @@ #include #include #include +#include #include "config.h" #include "server.h" #include "scaler.h" @@ -34,7 +35,9 @@ using std::vector; using std::ifstream; using std::string; using std::ofstream; +using std::list; using boost::shared_ptr; +using boost::optional; Config* Config::_instance = 0; @@ -52,8 +55,51 @@ Config::Config () _allowed_dcp_frame_rates.push_back (48); _allowed_dcp_frame_rates.push_back (50); _allowed_dcp_frame_rates.push_back (60); + + if (!boost::filesystem::exists (file (false))) { + read_old_metadata (); + return; + } + + cxml::File f (file (false), "Config"); + optional c; + + _num_local_encoding_threads = f.number_child ("NumLocalEncodingThreads"); + _default_directory = f.string_child ("DefaultDirectory"); + _server_port = f.number_child ("ServerPort"); + c = f.optional_string_child ("ReferenceScaler"); + if (c) { + _reference_scaler = Scaler::from_id (c.get ()); + } + + list > filters = f.node_children ("ReferenceFilter"); + for (list >::iterator i = filters.begin(); i != filters.end(); ++i) { + _reference_filters.push_back (Filter::from_id ((*i)->content ())); + } - ifstream f (file().c_str ()); + list > servers = f.node_children ("Server"); + for (list >::iterator i = servers.begin(); i != servers.end(); ++i) { + _servers.push_back (new ServerDescription (*i)); + } + + _tms_ip = f.string_child ("TMSIP"); + _tms_path = f.string_child ("TMSPath"); + _tms_user = f.string_child ("TMSUser"); + _tms_password = f.string_child ("TMSPassword"); + + c = f.optional_string_child ("SoundProcessor"); + if (c) { + _sound_processor = SoundProcessor::from_id (c.get ()); + } + + _language = f.optional_string_child ("Language"); + _default_dci_metadata = DCIMetadata (f.node_child ("DCIMetadata")); +} + +void +Config::read_old_metadata () +{ + ifstream f (file(true).c_str ()); string line; while (getline (f, line)) { if (line.empty ()) { @@ -98,17 +144,21 @@ Config::Config () _language = v; } - _default_dci_metadata.read (k, v); + _default_dci_metadata.read_old_metadata (k, v); } } /** @return Filename to write configuration to */ string -Config::file () const +Config::file (bool old) const { boost::filesystem::path p; p /= g_get_user_config_dir (); - p /= N_(".dvdomatic"); + if (old) { + p /= ".dvdomatic"; + } else { + p /= ".dvdomatic.xml"; + } return p.string (); } @@ -127,35 +177,38 @@ Config::instance () void Config::write () const { - ofstream f (file().c_str ()); - f << N_("num_local_encoding_threads ") << _num_local_encoding_threads << N_("\n") - << N_("default_directory ") << _default_directory << N_("\n") - << N_("server_port ") << _server_port << N_("\n"); + xmlpp::Document doc; + xmlpp::Element* root = doc.create_root_node ("Config"); + root->add_child("NumLocalEncodingThreads")->add_child_text (boost::lexical_cast (_num_local_encoding_threads)); + root->add_child("DefaultDirectory")->add_child_text (_default_directory); + root->add_child("ServerPort")->add_child_text (boost::lexical_cast (_server_port)); if (_reference_scaler) { - f << "reference_scaler " << _reference_scaler->id () << "\n"; + root->add_child("ReferenceScaler")->add_child_text (_reference_scaler->id ()); } for (vector::const_iterator i = _reference_filters.begin(); i != _reference_filters.end(); ++i) { - f << N_("reference_filter ") << (*i)->id () << N_("\n"); + root->add_child("ReferenceFilter")->add_child_text ((*i)->id ()); } for (vector::const_iterator i = _servers.begin(); i != _servers.end(); ++i) { - f << N_("server ") << (*i)->as_metadata () << N_("\n"); + (*i)->as_xml (root->add_child ("Server")); } - f << N_("tms_ip ") << _tms_ip << N_("\n"); - f << N_("tms_path ") << _tms_path << N_("\n"); - f << N_("tms_user ") << _tms_user << N_("\n"); - f << N_("tms_password ") << _tms_password << N_("\n"); + root->add_child("TMSIP")->add_child_text (_tms_ip); + root->add_child("TMSPath")->add_child_text (_tms_path); + root->add_child("TMSUser")->add_child_text (_tms_user); + root->add_child("TMSPassword")->add_child_text (_tms_password); if (_sound_processor) { - f << "sound_processor " << _sound_processor->id () << "\n"; + root->add_child("SoundProcessor")->add_child_text (_sound_processor->id ()); } if (_language) { - f << "language " << _language.get() << "\n"; + root->add_child("Language")->add_child_text (_language.get()); } - _default_dci_metadata.write (f); + _default_dci_metadata.as_xml (root->add_child ("DCIMetadata")); + + doc.write_to_file_formatted (file (false)); } string diff --git a/src/lib/config.h b/src/lib/config.h index 011ca716f..13d36d236 100644 --- a/src/lib/config.h +++ b/src/lib/config.h @@ -177,7 +177,8 @@ public: private: Config (); - std::string file () const; + std::string file (bool) const; + void read_old_metadata (); /** number of threads to use for J2K encoding on the local machine */ int _num_local_encoding_threads; diff --git a/src/lib/content.cc b/src/lib/content.cc index 2fb94e959..977f2e2a7 100644 --- a/src/lib/content.cc +++ b/src/lib/content.cc @@ -1,4 +1,6 @@ #include +#include +#include #include "content.h" #include "util.h" @@ -11,6 +13,20 @@ Content::Content (boost::filesystem::path f) } +Content::Content (shared_ptr node) +{ + _file = node->string_child ("File"); + _digest = node->string_child ("Digest"); +} + +void +Content::as_xml (xmlpp::Node* node) const +{ + boost::mutex::scoped_lock lm (_mutex); + node->add_child("File")->add_child_text (_file.string()); + node->add_child("Digest")->add_child_text (_digest); +} + void Content::examine (shared_ptr, shared_ptr, bool) { diff --git a/src/lib/content.h b/src/lib/content.h index 25c097424..3a94d2297 100644 --- a/src/lib/content.h +++ b/src/lib/content.h @@ -4,6 +4,11 @@ #include #include #include +#include + +namespace cxml { + class Node; +} class Job; class Film; @@ -12,9 +17,11 @@ class Content { public: Content (boost::filesystem::path); + Content (boost::shared_ptr); virtual void examine (boost::shared_ptr, boost::shared_ptr, bool); virtual std::string summary () const = 0; + virtual void as_xml (xmlpp::Node *) const; boost::filesystem::path file () const { boost::mutex::scoped_lock lm (_mutex); diff --git a/src/lib/dci_metadata.cc b/src/lib/dci_metadata.cc index 758886db4..f25b3ddb0 100644 --- a/src/lib/dci_metadata.cc +++ b/src/lib/dci_metadata.cc @@ -18,26 +18,39 @@ */ #include +#include #include "dci_metadata.h" #include "i18n.h" -using namespace std; +using std::string; +using boost::shared_ptr; + +DCIMetadata::DCIMetadata (shared_ptr node) +{ + audio_language = node->string_child ("AudioLanguage"); + subtitle_language = node->string_child ("SubtitleLanguage"); + territory = node->string_child ("Territory"); + rating = node->string_child ("Rating"); + studio = node->string_child ("Studio"); + facility = node->string_child ("Facility"); + package_type = node->string_child ("PackageType"); +} void -DCIMetadata::write (ostream& f) const +DCIMetadata::as_xml (xmlpp::Node* root) const { - f << N_("audio_language ") << audio_language << N_("\n"); - f << N_("subtitle_language ") << subtitle_language << N_("\n"); - f << N_("territory ") << territory << N_("\n"); - f << N_("rating ") << rating << N_("\n"); - f << N_("studio ") << studio << N_("\n"); - f << N_("facility ") << facility << N_("\n"); - f << N_("package_type ") << package_type << N_("\n"); + root->add_child("AudioLanguage")->add_child_text (audio_language); + root->add_child("SubtitleLanguage")->add_child_text (subtitle_language); + root->add_child("Territory")->add_child_text (territory); + root->add_child("Rating")->add_child_text (rating); + root->add_child("Studio")->add_child_text (studio); + root->add_child("Facility")->add_child_text (facility); + root->add_child("PackageType")->add_child_text (package_type); } void -DCIMetadata::read (string k, string v) +DCIMetadata::read_old_metadata (string k, string v) { if (k == N_("audio_language")) { audio_language = v; diff --git a/src/lib/dci_metadata.h b/src/lib/dci_metadata.h index eecdc7655..f61dae5a8 100644 --- a/src/lib/dci_metadata.h +++ b/src/lib/dci_metadata.h @@ -21,12 +21,20 @@ #define DVDOMATIC_DCI_METADATA_H #include +#include + +namespace cxml { + class Node; +} class DCIMetadata { public: - void read (std::string, std::string); - void write (std::ostream &) const; + DCIMetadata () {} + DCIMetadata (boost::shared_ptr); + + void as_xml (xmlpp::Node *) const; + void read_old_metadata (std::string, std::string); std::string audio_language; std::string subtitle_language; diff --git a/src/lib/decoder_factory.cc b/src/lib/decoder_factory.cc deleted file mode 100644 index 7940edc2e..000000000 --- a/src/lib/decoder_factory.cc +++ /dev/null @@ -1,43 +0,0 @@ -/* - Copyright (C) 2012 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -/** @file src/decoder_factory.cc - * @brief A method to create an appropriate decoder for some content. - */ - -#include -#include "ffmpeg_decoder.h" -#include "imagemagick_decoder.h" -#include "film.h" -#include "sndfile_decoder.h" -#include "decoder_factory.h" - -using std::string; -using std::pair; -using std::make_pair; -using boost::shared_ptr; -using boost::dynamic_pointer_cast; - -Decoders -decoder_factory ( - shared_ptr f - ) -{ - return Decoders (); -} diff --git a/src/lib/decoder_factory.h b/src/lib/decoder_factory.h deleted file mode 100644 index 3fd91f876..000000000 --- a/src/lib/decoder_factory.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - Copyright (C) 2012 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef DVDOMATIC_DECODER_FACTORY_H -#define DVDOMATIC_DECODER_FACTORY_H - -/** @file src/decoder_factory.h - * @brief A method to create appropriate decoders for some content. - */ - -class Film; -class VideoDecoder; -class AudioDecoder; - -struct Decoders { - Decoders () {} - - Decoders (boost::shared_ptr v, boost::shared_ptr a) - : video (v) - , audio (a) - {} - - boost::shared_ptr video; - boost::shared_ptr audio; -}; - -extern Decoders decoder_factory ( - boost::shared_ptr - ); - -#endif diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index 6109b7212..42e04e838 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -1,3 +1,4 @@ +#include #include "ffmpeg_content.h" #include "ffmpeg_decoder.h" #include "compose.hpp" @@ -8,7 +9,10 @@ #include "i18n.h" using std::string; +using std::vector; +using std::list; using boost::shared_ptr; +using boost::lexical_cast; int const FFmpegContentProperty::SUBTITLE_STREAMS = 100; int const FFmpegContentProperty::SUBTITLE_STREAM = 101; @@ -23,6 +27,54 @@ FFmpegContent::FFmpegContent (boost::filesystem::path f) } +FFmpegContent::FFmpegContent (shared_ptr node) + : Content (node) + , VideoContent (node) + , AudioContent (node) +{ + list > c = node->node_children ("SubtitleStream"); + for (list >::const_iterator i = c.begin(); i != c.end(); ++i) { + _subtitle_streams.push_back (FFmpegSubtitleStream (*i)); + if ((*i)->optional_number_child ("Selected")) { + _subtitle_stream = _subtitle_streams.back (); + } + } + + c = node->node_children ("AudioStream"); + for (list >::const_iterator i = c.begin(); i != c.end(); ++i) { + _audio_streams.push_back (FFmpegAudioStream (*i)); + if ((*i)->optional_number_child ("Selected")) { + _audio_stream = _audio_streams.back (); + } + } +} + +void +FFmpegContent::as_xml (xmlpp::Node* node) const +{ + node->add_child("Type")->add_child_text ("FFmpeg"); + Content::as_xml (node); + VideoContent::as_xml (node); + + boost::mutex::scoped_lock lm (_mutex); + + for (vector::const_iterator i = _subtitle_streams.begin(); i != _subtitle_streams.end(); ++i) { + xmlpp::Node* t = node->add_child("SubtitleStream"); + if (_subtitle_stream && *i == _subtitle_stream.get()) { + t->add_child("Selected")->add_child_text("1"); + } + i->as_xml (t); + } + + for (vector::const_iterator i = _audio_streams.begin(); i != _audio_streams.end(); ++i) { + xmlpp::Node* t = node->add_child("AudioStream"); + if (_audio_stream && *i == _audio_stream.get()) { + t->add_child("Selected")->add_child_text("1"); + } + i->as_xml (t); + } +} + void FFmpegContent::examine (shared_ptr film, shared_ptr job, bool quick) { @@ -151,3 +203,37 @@ operator== (FFmpegAudioStream const & a, FFmpegAudioStream const & b) { return a.id == b.id; } + +FFmpegAudioStream::FFmpegAudioStream (shared_ptr node) +{ + name = node->string_child ("Name"); + id = node->number_child ("Id"); + frame_rate = node->number_child ("FrameRate"); + channel_layout = node->number_child ("ChannelLayout"); +} + +void +FFmpegAudioStream::as_xml (xmlpp::Node* root) const +{ + root->add_child("Name")->add_child_text (name); + root->add_child("Id")->add_child_text (lexical_cast (id)); + root->add_child("FrameRate")->add_child_text (lexical_cast (frame_rate)); + root->add_child("ChannelLayout")->add_child_text (lexical_cast (channel_layout)); +} + +/** Construct a SubtitleStream from a value returned from to_string(). + * @param t String returned from to_string(). + * @param v State file version. + */ +FFmpegSubtitleStream::FFmpegSubtitleStream (shared_ptr node) +{ + name = node->string_child ("Name"); + id = node->number_child ("Id"); +} + +void +FFmpegSubtitleStream::as_xml (xmlpp::Node* root) const +{ + root->add_child("Name")->add_child_text (name); + root->add_child("Id")->add_child_text (lexical_cast (id)); +} diff --git a/src/lib/ffmpeg_content.h b/src/lib/ffmpeg_content.h index 83474ea66..95e24b7b3 100644 --- a/src/lib/ffmpeg_content.h +++ b/src/lib/ffmpeg_content.h @@ -15,6 +15,10 @@ public: , channel_layout (c) {} + FFmpegAudioStream (boost::shared_ptr); + + void as_xml (xmlpp::Node *) const; + int channels () const { return av_get_channel_layout_nb_channels (channel_layout); } @@ -35,6 +39,10 @@ public: , id (i) {} + FFmpegSubtitleStream (boost::shared_ptr); + + void as_xml (xmlpp::Node *) const; + std::string name; int id; }; @@ -54,9 +62,11 @@ class FFmpegContent : public VideoContent, public AudioContent, public boost::en { public: FFmpegContent (boost::filesystem::path); + FFmpegContent (boost::shared_ptr); void examine (boost::shared_ptr, boost::shared_ptr, bool); std::string summary () const; + void as_xml (xmlpp::Node *) const; /* AudioContent */ int audio_channels () const; diff --git a/src/lib/film.cc b/src/lib/film.cc index d22f67e67..a6a53b3fc 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -29,6 +29,8 @@ #include #include #include +#include +#include #include "film.h" #include "format.h" #include "job.h" @@ -43,7 +45,6 @@ #include "exceptions.h" #include "examine_content_job.h" #include "scaler.h" -#include "decoder_factory.h" #include "config.h" #include "version.h" #include "ui_signaller.h" @@ -52,6 +53,9 @@ #include "sndfile_decoder.h" #include "analyse_audio_job.h" #include "playlist.h" +#include "ffmpeg_content.h" +#include "imagemagick_content.h" +#include "sndfile_content.h" #include "i18n.h" @@ -67,6 +71,7 @@ using std::setfill; using std::min; using std::make_pair; using std::endl; +using std::list; using boost::shared_ptr; using boost::lexical_cast; using boost::to_upper_copy; @@ -93,7 +98,7 @@ Film::Film (string d, bool must_exist) , _scaler (Scaler::from_id ("bicubic")) , _trim_start (0) , _trim_end (0) - , _dcp_ab (false) + , _ab (false) , _audio_gain (0) , _audio_delay (0) , _with_subtitles (false) @@ -157,7 +162,7 @@ Film::Film (Film const & o) , _scaler (o._scaler) , _trim_start (o._trim_start) , _trim_end (o._trim_end) - , _dcp_ab (o._dcp_ab) + , _ab (o._ab) , _audio_gain (o._audio_gain) , _audio_delay (o._audio_delay) , _with_subtitles (o._with_subtitles) @@ -199,7 +204,7 @@ Film::video_state_identifier () const << "_" << j2k_bandwidth() << "_" << boost::lexical_cast (colour_lut()); - if (dcp_ab()) { + if (ab()) { pair fa = Filter::ffmpeg_strings (Config::instance()->reference_filters()); s << "ab_" << Config::instance()->reference_scaler()->id() << "_" << fa.first << "_" << fa.second; } @@ -297,7 +302,7 @@ Film::make_dcp () shared_ptr r; - if (dcp_ab()) { + if (ab()) { r = JobManager::instance()->add (shared_ptr (new ABTranscodeJob (shared_from_this()))); } else { r = JobManager::instance()->add (shared_ptr (new TranscodeJob (shared_from_this()))); @@ -375,77 +380,54 @@ Film::encoded_frames () const void Film::write_metadata () const { + ContentList the_content = content (); + boost::mutex::scoped_lock lm (_state_mutex); boost::filesystem::create_directories (directory()); - string const m = file ("metadata"); - ofstream f (m.c_str ()); - if (!f.good ()) { - throw CreateFileError (m); - } - - f << "version " << state_version << endl; + xmlpp::Document doc; + xmlpp::Element* root = doc.create_root_node ("Metadata"); - /* User stuff */ - f << "name " << _name << endl; - f << "use_dci_name " << _use_dci_name << endl; -// f << "content " << _content << endl; - f << "trust_content_headers " << (_trust_content_headers ? "1" : "0") << endl; + root->add_child("Version")->add_child_text (boost::lexical_cast (state_version)); + root->add_child("Name")->add_child_text (_name); + root->add_child("UseDCIName")->add_child_text (_use_dci_name ? "1" : "0"); + root->add_child("TrustContentHeaders")->add_child_text (_trust_content_headers ? "1" : "0"); if (_dcp_content_type) { - f << "dcp_content_type " << _dcp_content_type->dci_name () << endl; + root->add_child("DCPContentType")->add_child_text (_dcp_content_type->dci_name ()); } if (_format) { - f << "format " << _format->as_metadata () << endl; + root->add_child("Format")->add_child_text (_format->id ()); } - f << "left_crop " << _crop.left << endl; - f << "right_crop " << _crop.right << endl; - f << "top_crop " << _crop.top << endl; - f << "bottom_crop " << _crop.bottom << endl; - for (vector::const_iterator i = _filters.begin(); i != _filters.end(); ++i) { - f << "filter " << (*i)->id () << endl; - } - f << "scaler " << _scaler->id () << endl; - f << "trim_start " << _trim_start << endl; - f << "trim_end " << _trim_end << endl; - f << "dcp_ab " << (_dcp_ab ? "1" : "0") << endl; -// if (_content_audio_stream) { -// f << "selected_content_audio_stream " << _content_audio_stream->to_string() << endl; -// } -// for (vector::const_iterator i = _external_audio.begin(); i != _external_audio.end(); ++i) { -// f << "external_audio " << *i << endl; -// } -// f << "use_content_audio " << (_use_content_audio ? "1" : "0") << endl; - f << "audio_gain " << _audio_gain << endl; - f << "audio_delay " << _audio_delay << endl; -// f << "still_duration " << _still_duration << endl; -// if (_subtitle_stream) { -// f << "selected_subtitle_stream " << _subtitle_stream->to_string() << endl; -// } - f << "with_subtitles " << _with_subtitles << endl; - f << "subtitle_offset " << _subtitle_offset << endl; - f << "subtitle_scale " << _subtitle_scale << endl; - f << "colour_lut " << _colour_lut << endl; - f << "j2k_bandwidth " << _j2k_bandwidth << endl; - _dci_metadata.write (f); - f << "dci_date " << boost::gregorian::to_iso_string (_dci_date) << endl; - f << "dcp_frame_rate " << _dcp_frame_rate << endl; -// f << "width " << _size.width << endl; -// f << "height " << _size.height << endl; -// f << "length " << _length.get_value_or(0) << endl; -// f << "content_digest " << _content_digest << endl; - -// for (vector >::const_iterator i = _content_audio_streams.begin(); i != _content_audio_streams.end(); ++i) { -// f << "content_audio_stream " << (*i)->to_string () << endl; -// } - -// f << "external_audio_stream " << _sndfile_stream->to_string() << endl; + root->add_child("LeftCrop")->add_child_text (boost::lexical_cast (_crop.left)); + root->add_child("RightCrop")->add_child_text (boost::lexical_cast (_crop.right)); + root->add_child("TopCrop")->add_child_text (boost::lexical_cast (_crop.top)); + root->add_child("BottomCrop")->add_child_text (boost::lexical_cast (_crop.bottom)); -// for (vector >::const_iterator i = _subtitle_streams.begin(); i != _subtitle_streams.end(); ++i) { -// f << "subtitle_stream " << (*i)->to_string () << endl; -// } - -// f << "source_frame_rate " << _source_frame_rate << endl; + for (vector::const_iterator i = _filters.begin(); i != _filters.end(); ++i) { + root->add_child("Filter")->add_child_text ((*i)->id ()); + } + + root->add_child("Scaler")->add_child_text (_scaler->id ()); + root->add_child("TrimStart")->add_child_text (boost::lexical_cast (_trim_start)); + root->add_child("TrimEnd")->add_child_text (boost::lexical_cast (_trim_end)); + root->add_child("AB")->add_child_text (_ab ? "1" : "0"); + root->add_child("AudioGain")->add_child_text (boost::lexical_cast (_audio_gain)); + root->add_child("AudioDelay")->add_child_text (boost::lexical_cast (_audio_delay)); + root->add_child("WithSubtitles")->add_child_text (_with_subtitles ? "1" : "0"); + root->add_child("SubtitleOffset")->add_child_text (boost::lexical_cast (_subtitle_offset)); + root->add_child("SubtitleScale")->add_child_text (boost::lexical_cast (_subtitle_scale)); + root->add_child("ColourLUT")->add_child_text (boost::lexical_cast (_colour_lut)); + root->add_child("J2KBandwidth")->add_child_text (boost::lexical_cast (_j2k_bandwidth)); + _dci_metadata.as_xml (root->add_child ("DCIMetadata")); + root->add_child("DCIDate")->add_child_text (boost::gregorian::to_iso_string (_dci_date)); + root->add_child("DCPFrameRate")->add_child_text (boost::lexical_cast (_dcp_frame_rate)); + + for (ContentList::iterator i = the_content.begin(); i != the_content.end(); ++i) { + (*i)->as_xml (root->add_child ("Content")); + } + + doc.write_to_file_formatted (file ("metadata.xml")); _dirty = false; } @@ -456,137 +438,68 @@ Film::read_metadata () { boost::mutex::scoped_lock lm (_state_mutex); -// _external_audio.clear (); -// _content_audio_streams.clear (); -// _subtitle_streams.clear (); - - boost::optional version; - - /* Backward compatibility things */ - boost::optional audio_sample_rate; - boost::optional audio_stream_index; - boost::optional subtitle_stream_index; - - ifstream f (file ("metadata").c_str()); - if (!f.good()) { - throw OpenFileError (file ("metadata")); + if (boost::filesystem::exists (file ("metadata")) && !boost::filesystem::exists (file ("metadata.xml"))) { + throw StringError (_("This film was created with an older version of DVD-o-matic, and unfortunately it cannot be loaded into this version. You will need to create a new Film, re-add your content and set it up again. Sorry!")); } + + cxml::File f (file ("metadata.xml"), "Metadata"); - multimap kv = read_key_value (f); + _name = f.string_child ("Name"); + _use_dci_name = f.bool_child ("UseDCIName"); + _trust_content_headers = f.bool_child ("TrustContentHeaders"); - /* We need version before anything else */ - multimap::iterator v = kv.find ("version"); - if (v != kv.end ()) { - version = atoi (v->second.c_str()); + { + optional c = f.optional_string_child ("DCPContentType"); + if (c) { + _dcp_content_type = DCPContentType::from_dci_name (c.get ()); + } } - - for (multimap::const_iterator i = kv.begin(); i != kv.end(); ++i) { - string const k = i->first; - string const v = i->second; - if (k == "audio_sample_rate") { - audio_sample_rate = atoi (v.c_str()); + { + optional c = f.optional_string_child ("Format"); + if (c) { + _format = Format::from_id (c.get ()); } + } - /* User-specified stuff */ - if (k == "name") { - _name = v; - } else if (k == "use_dci_name") { - _use_dci_name = (v == "1"); - } else if (k == "content") { -// _content = v; - } else if (k == "trust_content_headers") { - _trust_content_headers = (v == "1"); - } else if (k == "dcp_content_type") { - if (version < 3) { - _dcp_content_type = DCPContentType::from_pretty_name (v); - } else { - _dcp_content_type = DCPContentType::from_dci_name (v); - } - } else if (k == "format") { - _format = Format::from_metadata (v); - } else if (k == "left_crop") { - _crop.left = atoi (v.c_str ()); - } else if (k == "right_crop") { - _crop.right = atoi (v.c_str ()); - } else if (k == "top_crop") { - _crop.top = atoi (v.c_str ()); - } else if (k == "bottom_crop") { - _crop.bottom = atoi (v.c_str ()); - } else if (k == "filter") { - _filters.push_back (Filter::from_id (v)); - } else if (k == "scaler") { - _scaler = Scaler::from_id (v); - } else if ( ((!version || version < 2) && k == "dcp_trim_start") || k == "trim_start") { - _trim_start = atoi (v.c_str ()); - } else if ( ((!version || version < 2) && k == "dcp_trim_end") || k == "trim_end") { - _trim_end = atoi (v.c_str ()); - } else if (k == "dcp_ab") { - _dcp_ab = (v == "1"); - } else if (k == "selected_content_audio_stream" || (!version && k == "selected_audio_stream")) { - if (!version) { - audio_stream_index = atoi (v.c_str ()); - } else { -// _content_audio_stream = audio_stream_factory (v, version); - } - } else if (k == "external_audio") { -// _external_audio.push_back (v); - } else if (k == "use_content_audio") { -// _use_content_audio = (v == "1"); - } else if (k == "audio_gain") { - _audio_gain = atof (v.c_str ()); - } else if (k == "audio_delay") { - _audio_delay = atoi (v.c_str ()); - } else if (k == "still_duration") { -// _still_duration = atoi (v.c_str ()); - } else if (k == "selected_subtitle_stream") { - if (!version) { - subtitle_stream_index = atoi (v.c_str ()); - } else { -// _subtitle_stream = subtitle_stream_factory (v, version); - } - } else if (k == "with_subtitles") { - _with_subtitles = (v == "1"); - } else if (k == "subtitle_offset") { - _subtitle_offset = atoi (v.c_str ()); - } else if (k == "subtitle_scale") { - _subtitle_scale = atof (v.c_str ()); - } else if (k == "colour_lut") { - _colour_lut = atoi (v.c_str ()); - } else if (k == "j2k_bandwidth") { - _j2k_bandwidth = atoi (v.c_str ()); - } else if (k == "dci_date") { - _dci_date = boost::gregorian::from_undelimited_string (v); - } else if (k == "dcp_frame_rate") { - _dcp_frame_rate = atoi (v.c_str ()); + _crop.left = f.number_child ("CropLeft"); + _crop.right = f.number_child ("CropRight"); + _crop.top = f.number_child ("CropTop"); + _crop.bottom = f.number_child ("CropBottom"); + + { + list > c = f.node_children ("Filter"); + for (list >::iterator i = c.begin(); i != c.end(); ++i) { + _filters.push_back (Filter::from_id ((*i)->content ())); } + } - _dci_metadata.read (k, v); + _scaler = Scaler::from_id (f.string_child ("Scaler")); + _trim_start = f.number_child ("TrimStart"); + _trim_end = f.number_child ("TrimEnd"); + _ab = f.bool_child ("AB"); + _audio_gain = f.number_child ("AudioGain"); + _audio_delay = f.number_child ("AudioDelay"); + _with_subtitles = f.bool_child ("WithSubtitles"); + _subtitle_offset = f.number_child ("SubtitleOffset"); + _subtitle_scale = f.number_child ("SubtitleScale"); + _colour_lut = f.number_child ("ColourLUT"); + _j2k_bandwidth = f.number_child ("J2KBandwidth"); + _dci_metadata = DCIMetadata (f.node_child ("DCIMetadata")); + _dci_date = boost::gregorian::from_undelimited_string (f.string_child ("DCIDate")); + _dcp_frame_rate = f.number_child ("DCPFrameRate"); + + list > c = f.node_children ("Content"); + for (list >::iterator i = c.begin(); i != c.end(); ++i) { + + string const type = (*i)->string_child ("Type"); - /* Cached stuff */ - if (k == "width") { -// _size.width = atoi (v.c_str ()); - } else if (k == "height") { -// _size.height = atoi (v.c_str ()); - } else if (k == "length") { - int const vv = atoi (v.c_str ()); - if (vv) { -// _length = vv; - } - } else if (k == "content_digest") { -// _content_digest = v; - } else if (k == "content_audio_stream" || (!version && k == "audio_stream")) { -// _content_audio_streams.push_back (audio_stream_factory (v, version)); - } else if (k == "external_audio_stream") { -// _sndfile_stream = audio_stream_factory (v, version); - } else if (k == "subtitle_stream") { -// _subtitle_streams.push_back (subtitle_stream_factory (v, version)); - } else if (k == "source_frame_rate") { -// _source_frame_rate = atof (v.c_str ()); - } else if (version < 4 && k == "frames_per_second") { -// _source_frame_rate = atof (v.c_str ()); - /* Fill in what would have been used for DCP frame rate by the older version */ -// _dcp_frame_rate = best_dcp_frame_rate (_source_frame_rate); + if (type == "FFmpeg") { + _content.push_back (shared_ptr (new FFmpegContent (*i))); + } else if (type == "ImageMagick") { + _content.push_back (shared_ptr (new ImageMagickContent (*i))); + } else if (type == "Sndfile") { + _content.push_back (shared_ptr (new SndfileContent (*i))); } } @@ -936,13 +849,13 @@ Film::set_trim_end (int t) } void -Film::set_dcp_ab (bool a) +Film::set_ab (bool a) { { boost::mutex::scoped_lock lm (_state_mutex); - _dcp_ab = a; + _ab = a; } - signal_changed (DCP_AB); + signal_changed (AB); } void diff --git a/src/lib/film.h b/src/lib/film.h index 928866161..f5f944409 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -123,7 +123,7 @@ public: SCALER, TRIM_START, TRIM_END, - DCP_AB, + AB, AUDIO_GAIN, AUDIO_DELAY, STILL_DURATION, @@ -200,9 +200,9 @@ public: return _trim_end; } - bool dcp_ab () const { + bool ab () const { boost::mutex::scoped_lock lm (_state_mutex); - return _dcp_ab; + return _ab; } float audio_gain () const { @@ -268,7 +268,7 @@ public: void set_scaler (Scaler const *); void set_trim_start (int); void set_trim_end (int); - void set_dcp_ab (bool); + void set_ab (bool); void set_audio_gain (float); void set_audio_delay (int); void set_still_duration (int); @@ -333,7 +333,7 @@ private: is the video without any filters or post-processing, and the right half has the specified filters and post-processing. */ - bool _dcp_ab; + bool _ab; /** Gain to apply to audio in dB */ float _audio_gain; /** Delay to apply to audio (positive moves audio later) in milliseconds */ diff --git a/src/lib/imagemagick_content.cc b/src/lib/imagemagick_content.cc index d096bff84..cb712b417 100644 --- a/src/lib/imagemagick_content.cc +++ b/src/lib/imagemagick_content.cc @@ -1,9 +1,11 @@ +#include #include "imagemagick_content.h" #include "compose.hpp" #include "i18n.h" using std::string; +using boost::shared_ptr; ImageMagickContent::ImageMagickContent (boost::filesystem::path f) : Content (f) @@ -13,6 +15,13 @@ ImageMagickContent::ImageMagickContent (boost::filesystem::path f) _video_length = 10 * 24; } +ImageMagickContent::ImageMagickContent (shared_ptr node) + : Content (node) + , VideoContent (node) +{ + +} + string ImageMagickContent::summary () const { diff --git a/src/lib/imagemagick_content.h b/src/lib/imagemagick_content.h index 0dd5baba8..99b614512 100644 --- a/src/lib/imagemagick_content.h +++ b/src/lib/imagemagick_content.h @@ -1,9 +1,14 @@ #include "video_content.h" +namespace cxml { + class Node; +} + class ImageMagickContent : public VideoContent { public: ImageMagickContent (boost::filesystem::path); + ImageMagickContent (boost::shared_ptr); std::string summary () const; diff --git a/src/lib/server.cc b/src/lib/server.cc index 9c5a77f68..ca0bec580 100644 --- a/src/lib/server.cc +++ b/src/lib/server.cc @@ -29,6 +29,7 @@ #include #include #include +#include #include "server.h" #include "util.h" #include "scaler.h" @@ -51,6 +52,19 @@ using boost::bind; using boost::scoped_array; using libdcp::Size; +ServerDescription::ServerDescription (shared_ptr node) +{ + _host_name = node->string_child ("HostName"); + _threads = node->number_child ("Threads"); +} + +void +ServerDescription::as_xml (xmlpp::Node* root) const +{ + root->add_child("HostName")->add_child_text (_host_name); + root->add_child("Threads")->add_child_text (boost::lexical_cast (_threads)); +} + /** Create a server description from a string of metadata returned from as_metadata(). * @param v Metadata. * @return ServerDescription, or 0. @@ -68,15 +82,6 @@ ServerDescription::create_from_metadata (string v) return new ServerDescription (b[0], atoi (b[1].c_str ())); } -/** @return Description of this server as text */ -string -ServerDescription::as_metadata () const -{ - stringstream s; - s << _host_name << N_(" ") << _threads; - return s.str (); -} - Server::Server (shared_ptr log) : _log (log) { diff --git a/src/lib/server.h b/src/lib/server.h index 89aeca626..398401a55 100644 --- a/src/lib/server.h +++ b/src/lib/server.h @@ -26,10 +26,15 @@ #include #include #include +#include #include "log.h" class Socket; +namespace cxml { + class Node; +} + /** @class ServerDescription * @brief Class to describe a server to which we can send encoding work. */ @@ -44,6 +49,8 @@ public: , _threads (t) {} + ServerDescription (boost::shared_ptr); + /** @return server's host name or IP address in string form */ std::string host_name () const { return _host_name; @@ -62,7 +69,7 @@ public: _threads = t; } - std::string as_metadata () const; + void as_xml (xmlpp::Node *) const; static ServerDescription * create_from_metadata (std::string v); diff --git a/src/lib/sndfile_content.cc b/src/lib/sndfile_content.cc index 53df4deea..4794e4d31 100644 --- a/src/lib/sndfile_content.cc +++ b/src/lib/sndfile_content.cc @@ -3,7 +3,8 @@ #include "i18n.h" -using namespace std; +using std::string; +using boost::shared_ptr; SndfileContent::SndfileContent (boost::filesystem::path f) : Content (f) @@ -12,6 +13,14 @@ SndfileContent::SndfileContent (boost::filesystem::path f) } +SndfileContent::SndfileContent (shared_ptr node) + : Content (node) + , AudioContent (node) + +{ + +} + string SndfileContent::summary () const { diff --git a/src/lib/sndfile_content.h b/src/lib/sndfile_content.h index 10cb428a1..b9a500c88 100644 --- a/src/lib/sndfile_content.h +++ b/src/lib/sndfile_content.h @@ -1,9 +1,14 @@ #include "audio_content.h" +namespace cxml { + class Node; +} + class SndfileContent : public AudioContent { public: SndfileContent (boost::filesystem::path); + SndfileContent (boost::shared_ptr); std::string summary () const; diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc index 070258008..21944c5fc 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -28,7 +28,6 @@ #include #include "transcoder.h" #include "encoder.h" -#include "decoder_factory.h" #include "film.h" #include "matcher.h" #include "delay_line.h" diff --git a/src/lib/transcoder.h b/src/lib/transcoder.h index 3c47b0c7e..856b10f3a 100644 --- a/src/lib/transcoder.h +++ b/src/lib/transcoder.h @@ -23,8 +23,6 @@ * as a parameter to the constructor. */ -#include "decoder_factory.h" - class Film; class Job; class Encoder; diff --git a/src/lib/video_content.cc b/src/lib/video_content.cc index 9fc5cf1a2..8a4414c18 100644 --- a/src/lib/video_content.cc +++ b/src/lib/video_content.cc @@ -1,3 +1,4 @@ +#include #include "video_content.h" #include "video_decoder.h" @@ -5,7 +6,9 @@ int const VideoContentProperty::VIDEO_LENGTH = 0; int const VideoContentProperty::VIDEO_SIZE = 1; int const VideoContentProperty::VIDEO_FRAME_RATE = 2; +using std::string; using boost::shared_ptr; +using boost::lexical_cast; VideoContent::VideoContent (boost::filesystem::path f) : Content (f) @@ -14,6 +17,25 @@ VideoContent::VideoContent (boost::filesystem::path f) } +VideoContent::VideoContent (shared_ptr node) + : Content (node) +{ + _video_length = node->number_child ("VideoLength"); + _video_size.width = node->number_child ("VideoWidth"); + _video_size.height = node->number_child ("VideoHeight"); + _video_frame_rate = node->number_child ("VideoFrameRate"); +} + +void +VideoContent::as_xml (xmlpp::Node* node) const +{ + boost::mutex::scoped_lock lm (_mutex); + node->add_child("VideoLength")->add_child_text (lexical_cast (_video_length)); + node->add_child("VideoWidth")->add_child_text (lexical_cast (_video_size.width)); + node->add_child("VideoHeight")->add_child_text (lexical_cast (_video_size.height)); + node->add_child("VideoFrameRate")->add_child_text (lexical_cast (_video_frame_rate)); +} + void VideoContent::take_from_video_decoder (shared_ptr d) { diff --git a/src/lib/video_content.h b/src/lib/video_content.h index 219130668..7c9db890a 100644 --- a/src/lib/video_content.h +++ b/src/lib/video_content.h @@ -18,6 +18,9 @@ class VideoContent : public virtual Content { public: VideoContent (boost::filesystem::path); + VideoContent (boost::shared_ptr); + + void as_xml (xmlpp::Node *) const; ContentVideoFrame video_length () const { boost::mutex::scoped_lock lm (_mutex); diff --git a/src/lib/wscript b/src/lib/wscript index 5510d48a8..303a9951f 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -17,7 +17,6 @@ sources = """ dcp_content_type.cc dcp_video_frame.cc decoder.cc - decoder_factory.cc delay_line.cc dolby_cp750.cc encoder.cc @@ -70,7 +69,7 @@ def build(bld): obj.uselib = """ AVCODEC AVUTIL AVFORMAT AVFILTER SWSCALE SWRESAMPLE BOOST_FILESYSTEM BOOST_THREAD BOOST_DATETIME BOOST_SIGNALS2 - SNDFILE OPENJPEG POSTPROC TIFF MAGICK SSH DCP GLIB LZMA + SNDFILE OPENJPEG POSTPROC TIFF MAGICK SSH DCP CXML GLIB LZMA """ if bld.env.TARGET_WINDOWS: obj.uselib += ' WINSOCK2' diff --git a/src/tools/makedcp.cc b/src/tools/makedcp.cc index 226cde113..85134b3c5 100644 --- a/src/tools/makedcp.cc +++ b/src/tools/makedcp.cc @@ -146,7 +146,7 @@ main (int argc, char* argv[]) film->log()->set_level ((Log::Level) log_level); cout << "\nMaking "; - if (film->dcp_ab()) { + if (film->ab()) { cout << "A/B "; } cout << "DCP for " << film->name() << "\n"; diff --git a/src/tools/servomatictest.cc b/src/tools/servomatictest.cc index d08fefa90..3d847d690 100644 --- a/src/tools/servomatictest.cc +++ b/src/tools/servomatictest.cc @@ -32,8 +32,8 @@ #include "exceptions.h" #include "scaler.h" #include "log.h" -#include "decoder_factory.h" #include "video_decoder.h" +#include "playlist.h" using std::cout; using std::cerr; @@ -150,17 +150,14 @@ main (int argc, char* argv[]) server = new ServerDescription (server_host, 1); shared_ptr film (new Film (film_dir, true)); - /* XXX */ -// opt.decode_audio = false; -// opt.decode_subtitles = true; -// opt.video_sync = true; + shared_ptr playlist = film->playlist (); + playlist->disable_audio (); - Decoders decoders = decoder_factory (film); try { - decoders.video->Video.connect (boost::bind (process_video, _1, _2, _3)); + playlist->Video.connect (boost::bind (process_video, _1, _2, _3)); bool done = false; while (!done) { - done = decoders.video->pass (); + done = playlist->pass (); } } catch (std::exception& e) { cerr << "Error: " << e.what() << "\n"; diff --git a/src/wx/audio_plot.cc b/src/wx/audio_plot.cc index cf44eb69f..2a6210164 100644 --- a/src/wx/audio_plot.cc +++ b/src/wx/audio_plot.cc @@ -21,7 +21,6 @@ #include #include #include "audio_plot.h" -#include "lib/decoder_factory.h" #include "lib/audio_decoder.h" #include "lib/audio_analysis.h" #include "wx/wx_util.h" diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 40f4f0362..560c4ef27 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -175,8 +175,8 @@ FilmEditor::make_film_panel () } ++r; - _dcp_ab = new wxCheckBox (_film_panel, wxID_ANY, _("A/B")); - grid->Add (_dcp_ab, wxGBPosition (r, 0)); + _ab = new wxCheckBox (_film_panel, wxID_ANY, _("A/B")); + grid->Add (_ab, wxGBPosition (r, 0)); ++r; vector const ct = DCPContentType::all (); @@ -212,7 +212,7 @@ FilmEditor::connect_to_widgets () _dcp_content_type->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::dcp_content_type_changed), 0, this); _dcp_frame_rate->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::dcp_frame_rate_changed), 0, this); _best_dcp_frame_rate->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::best_dcp_frame_rate_clicked), 0, this); - _dcp_ab->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::dcp_ab_toggled), 0, this); + _ab->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::ab_toggled), 0, this); _trim_start->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::trim_start_changed), 0, this); _trim_end->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::trim_end_changed), 0, this); _with_subtitles->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::with_subtitles_toggled), 0, this); @@ -489,13 +489,13 @@ FilmEditor::trust_content_headers_changed (wxCommandEvent &) /** Called when the DCP A/B switch has been toggled */ void -FilmEditor::dcp_ab_toggled (wxCommandEvent &) +FilmEditor::ab_toggled (wxCommandEvent &) { if (!_film) { return; } - _film->set_dcp_ab (_dcp_ab->GetValue ()); + _film->set_ab (_ab->GetValue ()); } /** Called when the name widget has been changed */ @@ -674,8 +674,8 @@ FilmEditor::film_changed (Film::Property p) checked_set (_dcp_content_type, DCPContentType::as_index (_film->dcp_content_type ())); setup_dcp_name (); break; - case Film::DCP_AB: - checked_set (_dcp_ab, _film->dcp_ab ()); + case Film::AB: + checked_set (_ab, _film->ab ()); break; case Film::SCALER: checked_set (_scaler, Scaler::as_index (_film->scaler ())); @@ -811,7 +811,7 @@ FilmEditor::set_film (shared_ptr f) film_changed (Film::SCALER); film_changed (Film::TRIM_START); film_changed (Film::TRIM_END); - film_changed (Film::DCP_AB); + film_changed (Film::AB); film_changed (Film::AUDIO_GAIN); film_changed (Film::AUDIO_DELAY); film_changed (Film::WITH_SUBTITLES); @@ -849,7 +849,7 @@ FilmEditor::set_things_sensitive (bool s) _dcp_frame_rate->Enable (s); _trim_start->Enable (s); _trim_end->Enable (s); - _dcp_ab->Enable (s); + _ab->Enable (s); _colour_lut->Enable (s); _j2k_bandwidth->Enable (s); _audio_gain->Enable (s); diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index 50457bdce..80072d48a 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -72,7 +72,7 @@ private: void trim_start_changed (wxCommandEvent &); void trim_end_changed (wxCommandEvent &); void dcp_content_type_changed (wxCommandEvent &); - void dcp_ab_toggled (wxCommandEvent &); + void ab_toggled (wxCommandEvent &); void scaler_changed (wxCommandEvent &); void audio_gain_changed (wxCommandEvent &); void audio_gain_calculate_button_clicked (wxCommandEvent &); @@ -162,7 +162,7 @@ private: wxSpinCtrl* _trim_start; wxSpinCtrl* _trim_end; /** Selector to generate an A/B comparison DCP */ - wxCheckBox* _dcp_ab; + wxCheckBox* _ab; std::vector _formats; diff --git a/src/wx/film_viewer.h b/src/wx/film_viewer.h index b552a3dbc..74ab9798c 100644 --- a/src/wx/film_viewer.h +++ b/src/wx/film_viewer.h @@ -23,7 +23,6 @@ #include #include "lib/film.h" -#include "lib/decoder_factory.h" class wxToggleButton; class FFmpegPlayer; diff --git a/test/test.cc b/test/test.cc index efa4848f6..5cf3dc56d 100644 --- a/test/test.cc +++ b/test/test.cc @@ -155,7 +155,7 @@ BOOST_AUTO_TEST_CASE (film_metadata_test) f->set_filters (f_filters); f->set_trim_start (42); f->set_trim_end (99); - f->set_dcp_ab (true); + f->set_ab (true); f->write_metadata (); stringstream s; @@ -177,7 +177,7 @@ BOOST_AUTO_TEST_CASE (film_metadata_test) BOOST_CHECK_EQUAL (g_filters.back(), Filter::from_id ("unsharp")); BOOST_CHECK_EQUAL (g->trim_start(), 42); BOOST_CHECK_EQUAL (g->trim_end(), 99); - BOOST_CHECK_EQUAL (g->dcp_ab(), true); + BOOST_CHECK_EQUAL (g->ab(), true); g->write_metadata (); BOOST_CHECK_EQUAL (::system (s.str().c_str ()), 0); -- cgit v1.2.3 From 623845efac0831aa1e2df6b79c4e879a7b901c69 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 1 Apr 2013 02:28:37 +0100 Subject: Fix XML tags. --- src/lib/film.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/lib/film.cc b/src/lib/film.cc index a6a53b3fc..f2c7a654a 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -462,10 +462,10 @@ Film::read_metadata () } } - _crop.left = f.number_child ("CropLeft"); - _crop.right = f.number_child ("CropRight"); - _crop.top = f.number_child ("CropTop"); - _crop.bottom = f.number_child ("CropBottom"); + _crop.left = f.number_child ("LeftCrop"); + _crop.right = f.number_child ("RightCrop"); + _crop.top = f.number_child ("TopCrop"); + _crop.bottom = f.number_child ("BottomCrop"); { list > c = f.node_children ("Filter"); -- cgit v1.2.3 From a1a8a90d422531182b9ee0baa06c618ff4ce5813 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 1 Apr 2013 21:16:54 +0100 Subject: Updated sv_SE translation from Adam Klotblixt. --- src/lib/po/sv_SE.po | 115 +++++++++++++++++++++----------------------------- src/tools/po/sv_SE.po | 30 ++++++------- src/wx/po/sv_SE.po | 69 ++++++++++++++++-------------- 3 files changed, 99 insertions(+), 115 deletions(-) (limited to 'src') diff --git a/src/lib/po/sv_SE.po b/src/lib/po/sv_SE.po index 151e3ef58..fca09a98c 100644 --- a/src/lib/po/sv_SE.po +++ b/src/lib/po/sv_SE.po @@ -7,11 +7,10 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-28 10:35+0000\n" -"PO-Revision-Date: 2013-03-28 10:40+0100\n" +"POT-Creation-Date: 2013-03-26 14:07+0000\n" +"PO-Revision-Date: 2013-04-01 18:29+0100\n" "Last-Translator: Adam Klotblixt \n" "Language-Team: \n" -"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -99,12 +98,7 @@ msgstr "Kan inte hantera pixelformat %1 under %2" #: src/lib/encoder.cc:101 msgid "Cannot resample audio as libswresample is not present" -msgstr "" -"Kan inte omsampla ljudet eftersom libswresample inte finns tillgängligt" - -#: src/lib/util.cc:931 -msgid "Centre" -msgstr "" +msgstr "Kan inte omsampla ljudet eftersom libswresample inte finns tillgängligt" #: src/lib/scp_dcp_job.cc:109 msgid "Copy DCP to TMS" @@ -134,26 +128,36 @@ msgstr "Kunde inte skriva till fjärrfil (%1)" msgid "Cubic interpolating deinterlacer" msgstr "Kubiskt interpolerande avflätare" -#: src/lib/util.cc:1006 +#: src/lib/util.cc:997 msgid "DCP and source have the same rate.\n" msgstr "DCP och källa har samma bildfrekvens.\n" -#: src/lib/util.cc:1016 +#: src/lib/util.cc:1007 msgid "DCP will run at %1%% of the source speed." msgstr "DCP kommer att köras på %1%% av källans hastighet." -#: src/lib/util.cc:1009 +#: src/lib/util.cc:1000 msgid "DCP will use every other frame of the source.\n" msgstr "DCP kommer att använda varannan bild från källan.\n" -#: src/lib/filter.cc:68 src/lib/filter.cc:69 src/lib/filter.cc:70 -#: src/lib/filter.cc:71 src/lib/filter.cc:72 src/lib/filter.cc:73 +#: src/lib/filter.cc:68 +#: src/lib/filter.cc:69 +#: src/lib/filter.cc:70 +#: src/lib/filter.cc:71 +#: src/lib/filter.cc:72 +#: src/lib/filter.cc:73 msgid "De-blocking" msgstr "Kantighetsutjämning" -#: src/lib/filter.cc:75 src/lib/filter.cc:76 src/lib/filter.cc:77 -#: src/lib/filter.cc:78 src/lib/filter.cc:79 src/lib/filter.cc:80 -#: src/lib/filter.cc:81 src/lib/filter.cc:82 src/lib/filter.cc:83 +#: src/lib/filter.cc:75 +#: src/lib/filter.cc:76 +#: src/lib/filter.cc:77 +#: src/lib/filter.cc:78 +#: src/lib/filter.cc:79 +#: src/lib/filter.cc:80 +#: src/lib/filter.cc:81 +#: src/lib/filter.cc:82 +#: src/lib/filter.cc:83 msgid "De-interlacing" msgstr "Avflätning" @@ -167,7 +171,7 @@ msgstr "Avringningsfilter" msgid "Dolby CP750" msgstr "Dolby CP750" -#: src/lib/util.cc:1011 +#: src/lib/util.cc:1002 msgid "Each source frame will be doubled in the DCP.\n" msgstr "Varje bild från källan kommer att användas två gånger i DCPn.\n" @@ -209,7 +213,7 @@ msgstr "Snabb bilinjär" #: src/lib/dcp_content_type.cc:44 msgid "Feature" -msgstr "Egenskap" +msgstr "Spelfilm" #: src/lib/format.cc:120 msgid "Flat" @@ -243,13 +247,10 @@ msgstr "Filter för horisontal kantighetsutjämning" msgid "Horizontal deblocking filter A" msgstr "Filter för horisontal kantighetsutjämning A" -#: src/lib/job.cc:92 src/lib/job.cc:101 -msgid "" -"It is not known what caused this error. The best idea is to report the " -"problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" -msgstr "" -"Det är inte känt vad som orsakade detta fel. Bästa sättet att rapportera " -"problemet är till DVD-o-matics mejl-lista (dvdomatic@carlh.net)" +#: src/lib/job.cc:92 +#: src/lib/job.cc:101 +msgid "It is not known what caused this error. The best idea is to report the problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" +msgstr "Det är inte känt vad som orsakade detta fel. Bästa sättet att rapportera problemet är till DVD-o-matics mejl-lista (dvdomatic@carlh.net)" #: src/lib/filter.cc:82 msgid "Kernel deinterlacer" @@ -259,18 +260,6 @@ msgstr "Kernel-avflätare" msgid "Lanczos" msgstr "Lanczos" -#: src/lib/util.cc:929 -msgid "Left" -msgstr "" - -#: src/lib/util.cc:933 -msgid "Left surround" -msgstr "" - -#: src/lib/util.cc:932 -msgid "Lfe (sub)" -msgstr "" - #: src/lib/filter.cc:75 msgid "Linear blend deinterlacer" msgstr "Linjär blandningsavflätare" @@ -283,8 +272,11 @@ msgstr "Linjär interpolationsavflätare" msgid "Median deinterlacer" msgstr "Median-avflätare" -#: src/lib/filter.cc:74 src/lib/filter.cc:85 src/lib/filter.cc:86 -#: src/lib/filter.cc:87 src/lib/filter.cc:90 +#: src/lib/filter.cc:74 +#: src/lib/filter.cc:85 +#: src/lib/filter.cc:86 +#: src/lib/filter.cc:87 +#: src/lib/filter.cc:90 msgid "Misc" msgstr "Diverse" @@ -292,7 +284,9 @@ msgstr "Diverse" msgid "Motion compensating deinterlacer" msgstr "Rörelsekompenserande avflätare" -#: src/lib/filter.cc:84 src/lib/filter.cc:88 src/lib/filter.cc:89 +#: src/lib/filter.cc:84 +#: src/lib/filter.cc:88 +#: src/lib/filter.cc:89 #: src/lib/filter.cc:91 msgid "Noise reduction" msgstr "Brusreducering" @@ -317,18 +311,10 @@ msgstr "Offentligt Servicemeddelande" msgid "Rating" msgstr "Klassificering" -#: src/lib/util.cc:499 +#: src/lib/util.cc:490 msgid "Rec 709" msgstr "Rec 709" -#: src/lib/util.cc:930 -msgid "Right" -msgstr "" - -#: src/lib/util.cc:934 -msgid "Right surround" -msgstr "" - #: src/lib/scp_dcp_job.cc:133 msgid "SSH error (%1)" msgstr "SSH fel (%1)" @@ -399,16 +385,13 @@ msgstr "Källan skalad för att rymmas inom Flat utan att ändra bildförhållan #: src/lib/format.cc:136 msgid "Source scaled to fit Scope preserving its aspect ratio" -msgstr "" -"Källan skalad för att rymmas inom Scope utan att ändra bildförhållandet" +msgstr "Källan skalad för att rymmas inom Scope utan att ändra bildförhållandet" #: src/lib/scaler.cc:68 msgid "Spline" msgstr "Spline" -# Möjligen "Aptitretare" #: src/lib/dcp_content_type.cc:50 -#, fuzzy msgid "Teaser" msgstr "Teaser" @@ -425,12 +408,8 @@ msgid "Test" msgstr "Test" #: src/lib/job.cc:77 -msgid "" -"The drive that the film is stored on is low in disc space. Free some more " -"space and try again." -msgstr "" -"Enheten som filmen lagras på har för lite ledigt utrymme. Frigör utrymme och " -"försök igen." +msgid "The drive that the film is stored on is low in disc space. Free some more space and try again." +msgstr "Enheten som filmen lagras på har för lite ledigt utrymme. Frigör utrymme och försök igen." #: src/lib/dcp_content_type.cc:46 msgid "Trailer" @@ -485,7 +464,7 @@ msgid "cannot contain slashes" msgstr "får inte innehålla snedstreck" # mer svengelska -#: src/lib/util.cc:540 +#: src/lib/util.cc:531 #, fuzzy msgid "connect timed out" msgstr "uppkopplingen tajmade ur" @@ -542,7 +521,8 @@ msgstr "kunde inte öppna fil för läsning" msgid "could not read from file %1 (%2)" msgstr "kunde inte läsa från fil %1 (%2)" -#: src/lib/encoder.cc:137 src/lib/encoder.cc:314 +#: src/lib/encoder.cc:137 +#: src/lib/encoder.cc:314 msgid "could not run sample-rate converter" msgstr "kunde inte köra sampelhastighetskonverteraren" @@ -578,7 +558,8 @@ msgstr "bilder per sekund" msgid "hour" msgstr "timme" -#: src/lib/util.cc:112 src/lib/util.cc:117 +#: src/lib/util.cc:112 +#: src/lib/util.cc:117 msgid "hours" msgstr "timmar" @@ -590,7 +571,7 @@ msgstr "minut" msgid "minutes" msgstr "minuter" -#: src/lib/util.cc:683 +#: src/lib/util.cc:674 msgid "missing key %1 in key-value set" msgstr "saknad nyckel %1 i nyckel-värde grupp" @@ -602,7 +583,8 @@ msgstr "saknad nödvändig inställning %1" msgid "multi-part subtitles not yet supported" msgstr "undertexter i flera delar stöds inte ännu" -#: src/lib/film.cc:263 src/lib/film.cc:308 +#: src/lib/film.cc:263 +#: src/lib/film.cc:308 msgid "name" msgstr "namn" @@ -620,7 +602,7 @@ msgstr "icke-rastergrafiska undertexter stöds inte ännu" msgid "remaining" msgstr "återstående tid" -#: src/lib/util.cc:497 +#: src/lib/util.cc:488 msgid "sRGB" msgstr "sRGB" @@ -635,3 +617,4 @@ msgstr "stillbild" #: src/lib/film.cc:274 msgid "video" msgstr "video" + diff --git a/src/tools/po/sv_SE.po b/src/tools/po/sv_SE.po index 7c1383549..be12a2b76 100644 --- a/src/tools/po/sv_SE.po +++ b/src/tools/po/sv_SE.po @@ -7,11 +7,10 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-28 10:35+0000\n" -"PO-Revision-Date: 2013-03-28 10:43+0100\n" +"POT-Creation-Date: 2013-03-26 14:07+0000\n" +"PO-Revision-Date: 2013-04-01 18:29+0100\n" "Last-Translator: Adam Klotblixt \n" "Language-Team: \n" -"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -66,16 +65,14 @@ msgid "&Send DCP to TMS" msgstr "&Skicka DCP till TMS" #: src/tools/dvdomatic.cc:409 -msgid "" -"(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" -msgstr "" -"(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" +msgid "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" +msgstr "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" #: src/tools/dvdomatic.cc:180 msgid "About" msgstr "Om" -#: src/tools/dvdomatic.cc:517 +#: src/tools/dvdomatic.cc:516 msgid "Could not load film %1 (%2)" msgstr "Kunde inte öppna filmen %1 (%2)" @@ -85,8 +82,9 @@ msgstr "Kunde inte öppna filmen %1 (%2)" msgid "Could not open film at %s (%s)" msgstr "Kunde inte öppna filmen vid %s (%s)" -#: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:402 -#: src/tools/dvdomatic.cc:521 +#: src/tools/dvdomatic.cc:287 +#: src/tools/dvdomatic.cc:402 +#: src/tools/dvdomatic.cc:520 msgid "DVD-o-matic" msgstr "DVD-o-matic" @@ -98,8 +96,7 @@ msgstr "Film ändrad" #: src/tools/dvdomatic.cc:408 msgid "Free, open-source DCP generation from almost anything." -msgstr "" -"Fri, öppen-källkodsprogramvara för DCP-generering från nästan vad som helst." +msgstr "Fri, öppen-källkodsprogramvara för DCP-generering från nästan vad som helst." # Ny? #: src/tools/dvdomatic.cc:160 @@ -111,15 +108,12 @@ msgstr "Skapa..." msgid "S&how DCP" msgstr "&Visa DCP" -#: src/tools/dvdomatic.cc:74 -msgid "Save changes to film \"%1\" before closing?" -msgstr "" - #: src/tools/dvdomatic.cc:319 msgid "Select film to open" msgstr "Välj film att öppna" #: src/tools/dvdomatic.cc:303 -#, fuzzy -msgid "The directory %1 already exists." +#, c-format +msgid "The directory %s already exists." msgstr "Katalogen %s finns redan." + diff --git a/src/wx/po/sv_SE.po b/src/wx/po/sv_SE.po index 9be9e150d..e1a5db638 100644 --- a/src/wx/po/sv_SE.po +++ b/src/wx/po/sv_SE.po @@ -7,11 +7,10 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-28 10:35+0000\n" -"PO-Revision-Date: 2013-03-28 10:44+0100\n" +"POT-Creation-Date: 2013-03-26 14:07+0000\n" +"PO-Revision-Date: 2013-04-01 18:40+0100\n" "Last-Translator: Adam Klotblixt \n" "Language-Team: \n" -"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -21,7 +20,7 @@ msgstr "" msgid "%" msgstr "%" -#: src/wx/config_dialog.cc:61 +#: src/wx/config_dialog.cc:60 msgid "(restart DVD-o-matic to see language changes)" msgstr "(starta om DVD-o-matic för att se språkändringar)" @@ -33,11 +32,12 @@ msgstr "1 kanal" msgid "A/B" msgstr "A/B" -#: src/wx/config_dialog.cc:143 +#: src/wx/config_dialog.cc:142 msgid "Add" msgstr "Lägg till" -#: src/wx/audio_dialog.cc:32 src/wx/film_editor.cc:77 +#: src/wx/audio_dialog.cc:32 +#: src/wx/film_editor.cc:77 msgid "Audio" msgstr "Audio" @@ -47,7 +47,7 @@ msgstr "Audio Fördröjning" #: src/wx/film_editor.cc:369 msgid "Audio Gain" -msgstr "Audio Volym" +msgstr "Audio Förstärkning" #: src/wx/dci_metadata_dialog.cc:33 msgid "Audio Language (e.g. EN)" @@ -141,19 +141,19 @@ msgid "DVD-o-matic Preferences" msgstr "DVD-o-matic Inställningar" #: src/wx/audio_dialog.cc:101 -#, fuzzy, c-format -msgid "DVD-o-matic audio - %s" +msgid "DVD-o-matic audio - %1" msgstr "DVD-o-matic audio - %1" -#: src/wx/config_dialog.cc:102 +#: src/wx/config_dialog.cc:101 msgid "Default DCI name details" msgstr "Detaljer om förvalda DCI-namn" -#: src/wx/config_dialog.cc:93 +#: src/wx/config_dialog.cc:92 msgid "Default directory for new films" msgstr "Förvald katalog för nya filmer" -#: src/wx/film_editor.cc:116 src/wx/job_manager_view.cc:92 +#: src/wx/film_editor.cc:116 +#: src/wx/job_manager_view.cc:92 msgid "Details..." msgstr "Detaljer..." @@ -165,16 +165,17 @@ msgstr "Diskutrymme som krävs" msgid "Duration" msgstr "Längd" -#: src/wx/config_dialog.cc:145 +#: src/wx/config_dialog.cc:144 msgid "Edit" msgstr "Redigera" -#: src/wx/config_dialog.cc:103 src/wx/config_dialog.cc:122 +#: src/wx/config_dialog.cc:102 +#: src/wx/config_dialog.cc:121 #: src/wx/film_editor.cc:308 msgid "Edit..." msgstr "Redigera..." -#: src/wx/config_dialog.cc:128 +#: src/wx/config_dialog.cc:127 msgid "Encoding Servers" msgstr "Kodningsservrar" @@ -200,7 +201,8 @@ msgstr "Film Egenskaper" msgid "Film name" msgstr "film namn" -#: src/wx/film_editor.cc:303 src/wx/filter_dialog.cc:32 +#: src/wx/film_editor.cc:303 +#: src/wx/filter_dialog.cc:32 msgid "Filters" msgstr "Filter" @@ -238,7 +240,7 @@ msgstr "Hz" msgid "I want to play this back at fader" msgstr "Jag vill spela upp detta med toning" -#: src/wx/config_dialog.cc:132 +#: src/wx/config_dialog.cc:131 msgid "IP address" msgstr "IP-adress" @@ -270,7 +272,8 @@ msgstr "Namn" msgid "New Film" msgstr "Ny Film" -#: src/wx/film_editor.cc:305 src/wx/film_editor.cc:664 +#: src/wx/film_editor.cc:305 +#: src/wx/film_editor.cc:664 msgid "None" msgstr "Inget" @@ -308,15 +311,15 @@ msgstr "RMS" msgid "Rating (e.g. 15)" msgstr "Klassificering (ex. 15)" -#: src/wx/config_dialog.cc:118 +#: src/wx/config_dialog.cc:117 msgid "Reference filters for A/B" msgstr "Referensfilter för A/B" -#: src/wx/config_dialog.cc:107 +#: src/wx/config_dialog.cc:106 msgid "Reference scaler for A/B" msgstr "Referensomskalare för A/B" -#: src/wx/config_dialog.cc:147 +#: src/wx/config_dialog.cc:146 msgid "Remove" msgstr "Ta bort" @@ -380,19 +383,19 @@ msgstr "Undertext Skalning" msgid "Subtitles" msgstr "Undertexter" -#: src/wx/config_dialog.cc:68 +#: src/wx/config_dialog.cc:67 msgid "TMS IP address" msgstr "TMS IP-adress" -#: src/wx/config_dialog.cc:83 +#: src/wx/config_dialog.cc:82 msgid "TMS password" msgstr "TMS lösenord" -#: src/wx/config_dialog.cc:73 +#: src/wx/config_dialog.cc:72 msgid "TMS target path" msgstr "TMS målsökväg" -#: src/wx/config_dialog.cc:78 +#: src/wx/config_dialog.cc:77 msgid "TMS user name" msgstr "TMS användarnamn" @@ -400,7 +403,7 @@ msgstr "TMS användarnamn" msgid "Territory (e.g. UK)" msgstr "Område (ex. SV)" -#: src/wx/config_dialog.cc:136 +#: src/wx/config_dialog.cc:135 msgid "Threads" msgstr "Trådar" @@ -408,7 +411,7 @@ msgstr "Trådar" msgid "Threads to use" msgstr "Antal trådar att använda" -#: src/wx/config_dialog.cc:88 +#: src/wx/config_dialog.cc:87 msgid "Threads to use for encoding on this host" msgstr "Antal trådar att använda vid kodning på denna maskin" @@ -420,14 +423,15 @@ msgstr "Tid" msgid "Top crop" msgstr "Övre beskärning" +# "välj bilder att koda"? #: src/wx/film_editor.cc:171 +#, fuzzy msgid "Trim frames" msgstr "Beskära bilder" #: src/wx/film_editor.cc:125 -#, fuzzy msgid "Trust content's header" -msgstr "Lita på innehållets information" +msgstr "Lita på källans information" #: src/wx/audio_dialog.cc:55 msgid "Type" @@ -469,7 +473,8 @@ msgstr "räknar..." msgid "dB" msgstr "dB" -#: src/wx/film_editor.cc:691 src/wx/film_editor.cc:694 +#: src/wx/film_editor.cc:691 +#: src/wx/film_editor.cc:694 msgid "frames" msgstr "bilder" @@ -483,6 +488,8 @@ msgstr "ms" msgid "s" msgstr "s" -#: src/wx/properties_dialog.cc:62 src/wx/properties_dialog.cc:63 +#: src/wx/properties_dialog.cc:62 +#: src/wx/properties_dialog.cc:63 msgid "unknown" msgstr "okänt" + -- cgit v1.2.3 From 9da001a06516b7a0b54f5f4c341a35d2605cdc88 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 1 Apr 2013 21:21:25 +0100 Subject: Merge pot files. --- src/lib/po/es_ES.po | 2 +- src/lib/po/fr_FR.po | 2 +- src/lib/po/it_IT.po | 2 +- src/lib/po/sv_SE.po | 109 ++++++++++++++++++++++++++++---------------------- src/tools/po/es_ES.po | 2 +- src/tools/po/fr_FR.po | 2 +- src/tools/po/it_IT.po | 2 +- src/tools/po/sv_SE.po | 28 ++++++++----- src/wx/po/es_ES.po | 2 +- src/wx/po/fr_FR.po | 2 +- src/wx/po/it_IT.po | 2 +- src/wx/po/sv_SE.po | 60 +++++++++++++-------------- 12 files changed, 115 insertions(+), 100 deletions(-) (limited to 'src') diff --git a/src/lib/po/es_ES.po b/src/lib/po/es_ES.po index 22a70f813..abf75d4ba 100644 --- a/src/lib/po/es_ES.po +++ b/src/lib/po/es_ES.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: LIBDVDOMATIC\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-28 10:35+0000\n" +"POT-Creation-Date: 2013-04-01 21:21+0100\n" "PO-Revision-Date: 2013-03-23 22:42-0500\n" "Last-Translator: Manuel AC \n" "Language-Team: Manuel AC \n" diff --git a/src/lib/po/fr_FR.po b/src/lib/po/fr_FR.po index f14cdafa1..7bd003c08 100644 --- a/src/lib/po/fr_FR.po +++ b/src/lib/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-28 10:35+0000\n" +"POT-Creation-Date: 2013-04-01 21:21+0100\n" "PO-Revision-Date: 2013-03-20 00:39+0100\n" "Last-Translator: FreeDCP.net \n" "Language-Team: \n" diff --git a/src/lib/po/it_IT.po b/src/lib/po/it_IT.po index 6de01e576..b4278d93c 100644 --- a/src/lib/po/it_IT.po +++ b/src/lib/po/it_IT.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-28 10:35+0000\n" +"POT-Creation-Date: 2013-04-01 21:21+0100\n" "PO-Revision-Date: 2013-03-20 11:45+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" diff --git a/src/lib/po/sv_SE.po b/src/lib/po/sv_SE.po index fca09a98c..292129f1c 100644 --- a/src/lib/po/sv_SE.po +++ b/src/lib/po/sv_SE.po @@ -7,10 +7,11 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-26 14:07+0000\n" +"POT-Creation-Date: 2013-04-01 21:21+0100\n" "PO-Revision-Date: 2013-04-01 18:29+0100\n" "Last-Translator: Adam Klotblixt \n" "Language-Team: \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -98,7 +99,12 @@ msgstr "Kan inte hantera pixelformat %1 under %2" #: src/lib/encoder.cc:101 msgid "Cannot resample audio as libswresample is not present" -msgstr "Kan inte omsampla ljudet eftersom libswresample inte finns tillgängligt" +msgstr "" +"Kan inte omsampla ljudet eftersom libswresample inte finns tillgängligt" + +#: src/lib/util.cc:931 +msgid "Centre" +msgstr "" #: src/lib/scp_dcp_job.cc:109 msgid "Copy DCP to TMS" @@ -128,36 +134,26 @@ msgstr "Kunde inte skriva till fjärrfil (%1)" msgid "Cubic interpolating deinterlacer" msgstr "Kubiskt interpolerande avflätare" -#: src/lib/util.cc:997 +#: src/lib/util.cc:1006 msgid "DCP and source have the same rate.\n" msgstr "DCP och källa har samma bildfrekvens.\n" -#: src/lib/util.cc:1007 +#: src/lib/util.cc:1016 msgid "DCP will run at %1%% of the source speed." msgstr "DCP kommer att köras på %1%% av källans hastighet." -#: src/lib/util.cc:1000 +#: src/lib/util.cc:1009 msgid "DCP will use every other frame of the source.\n" msgstr "DCP kommer att använda varannan bild från källan.\n" -#: src/lib/filter.cc:68 -#: src/lib/filter.cc:69 -#: src/lib/filter.cc:70 -#: src/lib/filter.cc:71 -#: src/lib/filter.cc:72 -#: src/lib/filter.cc:73 +#: src/lib/filter.cc:68 src/lib/filter.cc:69 src/lib/filter.cc:70 +#: src/lib/filter.cc:71 src/lib/filter.cc:72 src/lib/filter.cc:73 msgid "De-blocking" msgstr "Kantighetsutjämning" -#: src/lib/filter.cc:75 -#: src/lib/filter.cc:76 -#: src/lib/filter.cc:77 -#: src/lib/filter.cc:78 -#: src/lib/filter.cc:79 -#: src/lib/filter.cc:80 -#: src/lib/filter.cc:81 -#: src/lib/filter.cc:82 -#: src/lib/filter.cc:83 +#: src/lib/filter.cc:75 src/lib/filter.cc:76 src/lib/filter.cc:77 +#: src/lib/filter.cc:78 src/lib/filter.cc:79 src/lib/filter.cc:80 +#: src/lib/filter.cc:81 src/lib/filter.cc:82 src/lib/filter.cc:83 msgid "De-interlacing" msgstr "Avflätning" @@ -171,7 +167,7 @@ msgstr "Avringningsfilter" msgid "Dolby CP750" msgstr "Dolby CP750" -#: src/lib/util.cc:1002 +#: src/lib/util.cc:1011 msgid "Each source frame will be doubled in the DCP.\n" msgstr "Varje bild från källan kommer att användas två gånger i DCPn.\n" @@ -247,10 +243,13 @@ msgstr "Filter för horisontal kantighetsutjämning" msgid "Horizontal deblocking filter A" msgstr "Filter för horisontal kantighetsutjämning A" -#: src/lib/job.cc:92 -#: src/lib/job.cc:101 -msgid "It is not known what caused this error. The best idea is to report the problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" -msgstr "Det är inte känt vad som orsakade detta fel. Bästa sättet att rapportera problemet är till DVD-o-matics mejl-lista (dvdomatic@carlh.net)" +#: src/lib/job.cc:92 src/lib/job.cc:101 +msgid "" +"It is not known what caused this error. The best idea is to report the " +"problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" +msgstr "" +"Det är inte känt vad som orsakade detta fel. Bästa sättet att rapportera " +"problemet är till DVD-o-matics mejl-lista (dvdomatic@carlh.net)" #: src/lib/filter.cc:82 msgid "Kernel deinterlacer" @@ -260,6 +259,18 @@ msgstr "Kernel-avflätare" msgid "Lanczos" msgstr "Lanczos" +#: src/lib/util.cc:929 +msgid "Left" +msgstr "" + +#: src/lib/util.cc:933 +msgid "Left surround" +msgstr "" + +#: src/lib/util.cc:932 +msgid "Lfe (sub)" +msgstr "" + #: src/lib/filter.cc:75 msgid "Linear blend deinterlacer" msgstr "Linjär blandningsavflätare" @@ -272,11 +283,8 @@ msgstr "Linjär interpolationsavflätare" msgid "Median deinterlacer" msgstr "Median-avflätare" -#: src/lib/filter.cc:74 -#: src/lib/filter.cc:85 -#: src/lib/filter.cc:86 -#: src/lib/filter.cc:87 -#: src/lib/filter.cc:90 +#: src/lib/filter.cc:74 src/lib/filter.cc:85 src/lib/filter.cc:86 +#: src/lib/filter.cc:87 src/lib/filter.cc:90 msgid "Misc" msgstr "Diverse" @@ -284,9 +292,7 @@ msgstr "Diverse" msgid "Motion compensating deinterlacer" msgstr "Rörelsekompenserande avflätare" -#: src/lib/filter.cc:84 -#: src/lib/filter.cc:88 -#: src/lib/filter.cc:89 +#: src/lib/filter.cc:84 src/lib/filter.cc:88 src/lib/filter.cc:89 #: src/lib/filter.cc:91 msgid "Noise reduction" msgstr "Brusreducering" @@ -311,10 +317,18 @@ msgstr "Offentligt Servicemeddelande" msgid "Rating" msgstr "Klassificering" -#: src/lib/util.cc:490 +#: src/lib/util.cc:499 msgid "Rec 709" msgstr "Rec 709" +#: src/lib/util.cc:930 +msgid "Right" +msgstr "" + +#: src/lib/util.cc:934 +msgid "Right surround" +msgstr "" + #: src/lib/scp_dcp_job.cc:133 msgid "SSH error (%1)" msgstr "SSH fel (%1)" @@ -385,7 +399,8 @@ msgstr "Källan skalad för att rymmas inom Flat utan att ändra bildförhållan #: src/lib/format.cc:136 msgid "Source scaled to fit Scope preserving its aspect ratio" -msgstr "Källan skalad för att rymmas inom Scope utan att ändra bildförhållandet" +msgstr "" +"Källan skalad för att rymmas inom Scope utan att ändra bildförhållandet" #: src/lib/scaler.cc:68 msgid "Spline" @@ -408,8 +423,12 @@ msgid "Test" msgstr "Test" #: src/lib/job.cc:77 -msgid "The drive that the film is stored on is low in disc space. Free some more space and try again." -msgstr "Enheten som filmen lagras på har för lite ledigt utrymme. Frigör utrymme och försök igen." +msgid "" +"The drive that the film is stored on is low in disc space. Free some more " +"space and try again." +msgstr "" +"Enheten som filmen lagras på har för lite ledigt utrymme. Frigör utrymme och " +"försök igen." #: src/lib/dcp_content_type.cc:46 msgid "Trailer" @@ -464,7 +483,7 @@ msgid "cannot contain slashes" msgstr "får inte innehålla snedstreck" # mer svengelska -#: src/lib/util.cc:531 +#: src/lib/util.cc:540 #, fuzzy msgid "connect timed out" msgstr "uppkopplingen tajmade ur" @@ -521,8 +540,7 @@ msgstr "kunde inte öppna fil för läsning" msgid "could not read from file %1 (%2)" msgstr "kunde inte läsa från fil %1 (%2)" -#: src/lib/encoder.cc:137 -#: src/lib/encoder.cc:314 +#: src/lib/encoder.cc:137 src/lib/encoder.cc:314 msgid "could not run sample-rate converter" msgstr "kunde inte köra sampelhastighetskonverteraren" @@ -558,8 +576,7 @@ msgstr "bilder per sekund" msgid "hour" msgstr "timme" -#: src/lib/util.cc:112 -#: src/lib/util.cc:117 +#: src/lib/util.cc:112 src/lib/util.cc:117 msgid "hours" msgstr "timmar" @@ -571,7 +588,7 @@ msgstr "minut" msgid "minutes" msgstr "minuter" -#: src/lib/util.cc:674 +#: src/lib/util.cc:683 msgid "missing key %1 in key-value set" msgstr "saknad nyckel %1 i nyckel-värde grupp" @@ -583,8 +600,7 @@ msgstr "saknad nödvändig inställning %1" msgid "multi-part subtitles not yet supported" msgstr "undertexter i flera delar stöds inte ännu" -#: src/lib/film.cc:263 -#: src/lib/film.cc:308 +#: src/lib/film.cc:263 src/lib/film.cc:308 msgid "name" msgstr "namn" @@ -602,7 +618,7 @@ msgstr "icke-rastergrafiska undertexter stöds inte ännu" msgid "remaining" msgstr "återstående tid" -#: src/lib/util.cc:488 +#: src/lib/util.cc:497 msgid "sRGB" msgstr "sRGB" @@ -617,4 +633,3 @@ msgstr "stillbild" #: src/lib/film.cc:274 msgid "video" msgstr "video" - diff --git a/src/tools/po/es_ES.po b/src/tools/po/es_ES.po index cf6f2b889..777a86519 100644 --- a/src/tools/po/es_ES.po +++ b/src/tools/po/es_ES.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVDOMATIC\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-28 10:35+0000\n" +"POT-Creation-Date: 2013-04-01 21:21+0100\n" "PO-Revision-Date: 2013-03-23 21:08-0500\n" "Last-Translator: Manuel AC \n" "Language-Team: Manuel AC \n" diff --git a/src/tools/po/fr_FR.po b/src/tools/po/fr_FR.po index a9a4a2ae7..fc9c670fc 100644 --- a/src/tools/po/fr_FR.po +++ b/src/tools/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-28 10:35+0000\n" +"POT-Creation-Date: 2013-04-01 21:21+0100\n" "PO-Revision-Date: 2013-03-13 22:33+0100\n" "Last-Translator: \n" "Language-Team: \n" diff --git a/src/tools/po/it_IT.po b/src/tools/po/it_IT.po index a1fc9e403..0f9de5e36 100644 --- a/src/tools/po/it_IT.po +++ b/src/tools/po/it_IT.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-28 10:35+0000\n" +"POT-Creation-Date: 2013-04-01 21:21+0100\n" "PO-Revision-Date: 2013-03-22 18:03+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" diff --git a/src/tools/po/sv_SE.po b/src/tools/po/sv_SE.po index be12a2b76..a9e82a8bb 100644 --- a/src/tools/po/sv_SE.po +++ b/src/tools/po/sv_SE.po @@ -7,10 +7,11 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-26 14:07+0000\n" +"POT-Creation-Date: 2013-04-01 21:21+0100\n" "PO-Revision-Date: 2013-04-01 18:29+0100\n" "Last-Translator: Adam Klotblixt \n" "Language-Team: \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -65,14 +66,16 @@ msgid "&Send DCP to TMS" msgstr "&Skicka DCP till TMS" #: src/tools/dvdomatic.cc:409 -msgid "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" -msgstr "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" +msgid "" +"(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" +msgstr "" +"(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" #: src/tools/dvdomatic.cc:180 msgid "About" msgstr "Om" -#: src/tools/dvdomatic.cc:516 +#: src/tools/dvdomatic.cc:517 msgid "Could not load film %1 (%2)" msgstr "Kunde inte öppna filmen %1 (%2)" @@ -82,9 +85,8 @@ msgstr "Kunde inte öppna filmen %1 (%2)" msgid "Could not open film at %s (%s)" msgstr "Kunde inte öppna filmen vid %s (%s)" -#: src/tools/dvdomatic.cc:287 -#: src/tools/dvdomatic.cc:402 -#: src/tools/dvdomatic.cc:520 +#: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:402 +#: src/tools/dvdomatic.cc:521 msgid "DVD-o-matic" msgstr "DVD-o-matic" @@ -96,7 +98,8 @@ msgstr "Film ändrad" #: src/tools/dvdomatic.cc:408 msgid "Free, open-source DCP generation from almost anything." -msgstr "Fri, öppen-källkodsprogramvara för DCP-generering från nästan vad som helst." +msgstr "" +"Fri, öppen-källkodsprogramvara för DCP-generering från nästan vad som helst." # Ny? #: src/tools/dvdomatic.cc:160 @@ -108,12 +111,15 @@ msgstr "Skapa..." msgid "S&how DCP" msgstr "&Visa DCP" +#: src/tools/dvdomatic.cc:74 +msgid "Save changes to film \"%1\" before closing?" +msgstr "" + #: src/tools/dvdomatic.cc:319 msgid "Select film to open" msgstr "Välj film att öppna" #: src/tools/dvdomatic.cc:303 -#, c-format -msgid "The directory %s already exists." +#, fuzzy +msgid "The directory %1 already exists." msgstr "Katalogen %s finns redan." - diff --git a/src/wx/po/es_ES.po b/src/wx/po/es_ES.po index 217175db1..6c2c550cb 100644 --- a/src/wx/po/es_ES.po +++ b/src/wx/po/es_ES.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: libdvdomatic-wx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-28 10:35+0000\n" +"POT-Creation-Date: 2013-04-01 21:21+0100\n" "PO-Revision-Date: 2013-03-23 21:20-0500\n" "Last-Translator: Manuel AC \n" "Language-Team: Manuel AC \n" diff --git a/src/wx/po/fr_FR.po b/src/wx/po/fr_FR.po index 2bf923b24..03da04610 100644 --- a/src/wx/po/fr_FR.po +++ b/src/wx/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-28 10:35+0000\n" +"POT-Creation-Date: 2013-04-01 21:21+0100\n" "PO-Revision-Date: 2013-03-20 00:34+0100\n" "Last-Translator: FreeDCP.net \n" "Language-Team: \n" diff --git a/src/wx/po/it_IT.po b/src/wx/po/it_IT.po index 9bc7b638a..3de3816f6 100644 --- a/src/wx/po/it_IT.po +++ b/src/wx/po/it_IT.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-28 10:35+0000\n" +"POT-Creation-Date: 2013-04-01 21:21+0100\n" "PO-Revision-Date: 2013-03-22 18:10+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" diff --git a/src/wx/po/sv_SE.po b/src/wx/po/sv_SE.po index e1a5db638..0e97d5dda 100644 --- a/src/wx/po/sv_SE.po +++ b/src/wx/po/sv_SE.po @@ -7,10 +7,11 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-26 14:07+0000\n" +"POT-Creation-Date: 2013-04-01 21:21+0100\n" "PO-Revision-Date: 2013-04-01 18:40+0100\n" "Last-Translator: Adam Klotblixt \n" "Language-Team: \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -20,7 +21,7 @@ msgstr "" msgid "%" msgstr "%" -#: src/wx/config_dialog.cc:60 +#: src/wx/config_dialog.cc:61 msgid "(restart DVD-o-matic to see language changes)" msgstr "(starta om DVD-o-matic för att se språkändringar)" @@ -32,12 +33,11 @@ msgstr "1 kanal" msgid "A/B" msgstr "A/B" -#: src/wx/config_dialog.cc:142 +#: src/wx/config_dialog.cc:143 msgid "Add" msgstr "Lägg till" -#: src/wx/audio_dialog.cc:32 -#: src/wx/film_editor.cc:77 +#: src/wx/audio_dialog.cc:32 src/wx/film_editor.cc:77 msgid "Audio" msgstr "Audio" @@ -141,19 +141,19 @@ msgid "DVD-o-matic Preferences" msgstr "DVD-o-matic Inställningar" #: src/wx/audio_dialog.cc:101 -msgid "DVD-o-matic audio - %1" +#, fuzzy, c-format +msgid "DVD-o-matic audio - %s" msgstr "DVD-o-matic audio - %1" -#: src/wx/config_dialog.cc:101 +#: src/wx/config_dialog.cc:102 msgid "Default DCI name details" msgstr "Detaljer om förvalda DCI-namn" -#: src/wx/config_dialog.cc:92 +#: src/wx/config_dialog.cc:93 msgid "Default directory for new films" msgstr "Förvald katalog för nya filmer" -#: src/wx/film_editor.cc:116 -#: src/wx/job_manager_view.cc:92 +#: src/wx/film_editor.cc:116 src/wx/job_manager_view.cc:92 msgid "Details..." msgstr "Detaljer..." @@ -165,17 +165,16 @@ msgstr "Diskutrymme som krävs" msgid "Duration" msgstr "Längd" -#: src/wx/config_dialog.cc:144 +#: src/wx/config_dialog.cc:145 msgid "Edit" msgstr "Redigera" -#: src/wx/config_dialog.cc:102 -#: src/wx/config_dialog.cc:121 +#: src/wx/config_dialog.cc:103 src/wx/config_dialog.cc:122 #: src/wx/film_editor.cc:308 msgid "Edit..." msgstr "Redigera..." -#: src/wx/config_dialog.cc:127 +#: src/wx/config_dialog.cc:128 msgid "Encoding Servers" msgstr "Kodningsservrar" @@ -201,8 +200,7 @@ msgstr "Film Egenskaper" msgid "Film name" msgstr "film namn" -#: src/wx/film_editor.cc:303 -#: src/wx/filter_dialog.cc:32 +#: src/wx/film_editor.cc:303 src/wx/filter_dialog.cc:32 msgid "Filters" msgstr "Filter" @@ -240,7 +238,7 @@ msgstr "Hz" msgid "I want to play this back at fader" msgstr "Jag vill spela upp detta med toning" -#: src/wx/config_dialog.cc:131 +#: src/wx/config_dialog.cc:132 msgid "IP address" msgstr "IP-adress" @@ -272,8 +270,7 @@ msgstr "Namn" msgid "New Film" msgstr "Ny Film" -#: src/wx/film_editor.cc:305 -#: src/wx/film_editor.cc:664 +#: src/wx/film_editor.cc:305 src/wx/film_editor.cc:664 msgid "None" msgstr "Inget" @@ -311,15 +308,15 @@ msgstr "RMS" msgid "Rating (e.g. 15)" msgstr "Klassificering (ex. 15)" -#: src/wx/config_dialog.cc:117 +#: src/wx/config_dialog.cc:118 msgid "Reference filters for A/B" msgstr "Referensfilter för A/B" -#: src/wx/config_dialog.cc:106 +#: src/wx/config_dialog.cc:107 msgid "Reference scaler for A/B" msgstr "Referensomskalare för A/B" -#: src/wx/config_dialog.cc:146 +#: src/wx/config_dialog.cc:147 msgid "Remove" msgstr "Ta bort" @@ -383,19 +380,19 @@ msgstr "Undertext Skalning" msgid "Subtitles" msgstr "Undertexter" -#: src/wx/config_dialog.cc:67 +#: src/wx/config_dialog.cc:68 msgid "TMS IP address" msgstr "TMS IP-adress" -#: src/wx/config_dialog.cc:82 +#: src/wx/config_dialog.cc:83 msgid "TMS password" msgstr "TMS lösenord" -#: src/wx/config_dialog.cc:72 +#: src/wx/config_dialog.cc:73 msgid "TMS target path" msgstr "TMS målsökväg" -#: src/wx/config_dialog.cc:77 +#: src/wx/config_dialog.cc:78 msgid "TMS user name" msgstr "TMS användarnamn" @@ -403,7 +400,7 @@ msgstr "TMS användarnamn" msgid "Territory (e.g. UK)" msgstr "Område (ex. SV)" -#: src/wx/config_dialog.cc:135 +#: src/wx/config_dialog.cc:136 msgid "Threads" msgstr "Trådar" @@ -411,7 +408,7 @@ msgstr "Trådar" msgid "Threads to use" msgstr "Antal trådar att använda" -#: src/wx/config_dialog.cc:87 +#: src/wx/config_dialog.cc:88 msgid "Threads to use for encoding on this host" msgstr "Antal trådar att använda vid kodning på denna maskin" @@ -473,8 +470,7 @@ msgstr "räknar..." msgid "dB" msgstr "dB" -#: src/wx/film_editor.cc:691 -#: src/wx/film_editor.cc:694 +#: src/wx/film_editor.cc:691 src/wx/film_editor.cc:694 msgid "frames" msgstr "bilder" @@ -488,8 +484,6 @@ msgstr "ms" msgid "s" msgstr "s" -#: src/wx/properties_dialog.cc:62 -#: src/wx/properties_dialog.cc:63 +#: src/wx/properties_dialog.cc:62 src/wx/properties_dialog.cc:63 msgid "unknown" msgstr "okänt" - -- cgit v1.2.3 From 51054a02d57e46479ceee34f3c9ab538c0fef091 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 1 Apr 2013 21:27:28 +0100 Subject: Don't try to extract i18n strings from version.cc --- src/lib/wscript | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/lib/wscript b/src/lib/wscript index 5d9f5626a..8e9d34706 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -47,7 +47,6 @@ sources = """ transcoder.cc ui_signaller.cc util.cc - version.cc video_decoder.cc video_source.cc writer.cc @@ -68,7 +67,7 @@ def build(bld): """ if bld.env.TARGET_WINDOWS: obj.uselib += ' WINSOCK2' - obj.source = sources + obj.source = sources + " version.cc" obj.target = 'dvdomatic' i18n.po_to_mo(os.path.join('src', 'lib'), 'libdvdomatic', bld) -- cgit v1.2.3 From 58303084ef7a2e67b692c2abdce623986df74488 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 1 Apr 2013 21:45:04 +0100 Subject: Fix %1 / %s marker in sv_SE. --- src/tools/po/sv_SE.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/tools/po/sv_SE.po b/src/tools/po/sv_SE.po index a9e82a8bb..42b417ba4 100644 --- a/src/tools/po/sv_SE.po +++ b/src/tools/po/sv_SE.po @@ -122,4 +122,4 @@ msgstr "Välj film att öppna" #: src/tools/dvdomatic.cc:303 #, fuzzy msgid "The directory %1 already exists." -msgstr "Katalogen %s finns redan." +msgstr "Katalogen %1 finns redan." -- cgit v1.2.3 From 9c1f9a4bc879c17f01d32265fe1b810e4cecfb65 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 1 Apr 2013 22:18:59 +0100 Subject: Try bind_textdomain_codeset on Windows. --- src/lib/util.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/lib/util.cc b/src/lib/util.cc index 48cb17c26..5b2038cde 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -283,6 +283,7 @@ dvdomatic_setup_i18n (string lang) #ifdef DVDOMATIC_WINDOWS bindtextdomain ("libdvdomatic", mo_path().string().c_str()); + bind_textdomain_codeset ("libdvdomatic", "UTF8"); #endif #ifdef DVDOMATIC_POSIX -- cgit v1.2.3 From db468a15e50c8491d4b8462ad0676be905f49065 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 1 Apr 2013 22:49:31 +0100 Subject: Various bits. --- src/lib/ab_transcoder.cc | 24 ++++---- src/lib/ab_transcoder.h | 6 +- src/lib/analyse_audio_job.cc | 16 +++--- src/lib/audio_decoder.cc | 2 +- src/lib/audio_decoder.h | 2 +- src/lib/encoder.cc | 31 +++++------ src/lib/encoder.h | 4 +- src/lib/ffmpeg_decoder.cc | 6 +- src/lib/ffmpeg_decoder.h | 4 +- src/lib/film.cc | 73 ++++++++++++++++++++---- src/lib/film.h | 15 ++++- src/lib/format.cc | 12 ++-- src/lib/format.h | 16 +++--- src/lib/imagemagick_decoder.cc | 4 +- src/lib/imagemagick_decoder.h | 4 +- src/lib/playlist.cc | 124 +++++++++++++++++++++++++++-------------- src/lib/playlist.h | 77 ++++++++++++++++++------- src/lib/sndfile_decoder.cc | 4 +- src/lib/sndfile_decoder.h | 4 +- src/lib/transcoder.cc | 22 ++++---- src/lib/transcoder.h | 4 +- src/lib/video_decoder.cc | 9 +-- src/lib/video_decoder.h | 2 +- src/lib/writer.cc | 7 +-- src/lib/writer.h | 4 +- src/tools/servomatictest.cc | 8 +-- src/wx/audio_dialog.cc | 11 ++-- src/wx/audio_dialog.h | 2 - src/wx/film_viewer.cc | 40 ++++++------- src/wx/film_viewer.h | 2 +- wscript | 3 + 31 files changed, 336 insertions(+), 206 deletions(-) (limited to 'src') diff --git a/src/lib/ab_transcoder.cc b/src/lib/ab_transcoder.cc index 6fc438ee8..6bf092fee 100644 --- a/src/lib/ab_transcoder.cc +++ b/src/lib/ab_transcoder.cc @@ -49,20 +49,20 @@ using boost::dynamic_pointer_cast; ABTranscoder::ABTranscoder (shared_ptr a, shared_ptr b, shared_ptr j) : _film_a (a) , _film_b (b) - , _playlist_a (_film_a->playlist ()) - , _playlist_b (_film_b->playlist ()) + , _player_a (_film_a->player ()) + , _player_b (_film_b->player ()) , _job (j) - , _encoder (new Encoder (_film_a, _playlist_a)) + , _encoder (new Encoder (_film_a)) , _combiner (new Combiner (a->log())) { - if (_playlist_a->has_audio ()) { - _matcher.reset (new Matcher (_film_a->log(), _playlist_a->audio_frame_rate(), _playlist_a->video_frame_rate())); - _delay_line.reset (new DelayLine (_film_a->log(), _playlist_a->audio_channels(), _film_a->audio_delay() * _playlist_a->audio_frame_rate() / 1000)); + if (_film_a->has_audio ()) { + _matcher.reset (new Matcher (_film_a->log(), _film_a->audio_frame_rate(), _film_a->video_frame_rate())); + _delay_line.reset (new DelayLine (_film_a->log(), _film_a->audio_channels(), _film_a->audio_delay() * _film_a->audio_frame_rate() / 1000)); _gain.reset (new Gain (_film_a->log(), _film_a->audio_gain())); } - _playlist_a->Video.connect (bind (&Combiner::process_video, _combiner, _1, _2, _3)); - _playlist_b->Video.connect (bind (&Combiner::process_video_b, _combiner, _1, _2, _3)); + _player_a->Video.connect (bind (&Combiner::process_video, _combiner, _1, _2, _3)); + _player_b->Video.connect (bind (&Combiner::process_video_b, _combiner, _1, _2, _3)); if (_matcher) { _combiner->connect_video (_matcher); @@ -72,7 +72,7 @@ ABTranscoder::ABTranscoder (shared_ptr a, shared_ptr b, shared_ptrconnect_audio (_delay_line); + _player_a->connect_audio (_delay_line); _delay_line->connect_audio (_matcher); _matcher->connect_audio (_gain); _gain->connect_audio (_encoder); @@ -87,11 +87,11 @@ ABTranscoder::go () bool done[2] = { false, false }; while (1) { - done[0] = _playlist_a->pass (); - done[1] = _playlist_b->pass (); + done[0] = _player_a->pass (); + done[1] = _player_b->pass (); if (_job) { - _playlist_a->set_progress (_job); + _player_a->set_progress (_job); } if (done[0] && done[1]) { diff --git a/src/lib/ab_transcoder.h b/src/lib/ab_transcoder.h index 5ce4a03da..b1b01d724 100644 --- a/src/lib/ab_transcoder.h +++ b/src/lib/ab_transcoder.h @@ -35,7 +35,7 @@ class Matcher; class DelayLine; class Gain; class Combiner; -class Playlist; +class Player; /** @class ABTranscoder * @brief A transcoder which uses one Film for the left half of the screen, and a different one @@ -55,8 +55,8 @@ public: private: boost::shared_ptr _film_a; boost::shared_ptr _film_b; - boost::shared_ptr _playlist_a; - boost::shared_ptr _playlist_b; + boost::shared_ptr _player_a; + boost::shared_ptr _player_b; boost::shared_ptr _job; boost::shared_ptr _encoder; boost::shared_ptr _combiner; diff --git a/src/lib/analyse_audio_job.cc b/src/lib/analyse_audio_job.cc index 6e6dda886..e2c9c5b18 100644 --- a/src/lib/analyse_audio_job.cc +++ b/src/lib/analyse_audio_job.cc @@ -50,18 +50,18 @@ AnalyseAudioJob::name () const void AnalyseAudioJob::run () { - shared_ptr playlist = _film->playlist (); - playlist->disable_video (); + shared_ptr player = _film->player (); + player->disable_video (); - playlist->Audio.connect (bind (&AnalyseAudioJob::audio, this, _1)); + player->Audio.connect (bind (&AnalyseAudioJob::audio, this, _1)); - _samples_per_point = max (int64_t (1), playlist->audio_length() / _num_points); + _samples_per_point = max (int64_t (1), _film->audio_length() / _num_points); - _current.resize (playlist->audio_channels ()); - _analysis.reset (new AudioAnalysis (playlist->audio_channels())); + _current.resize (_film->audio_channels ()); + _analysis.reset (new AudioAnalysis (_film->audio_channels())); - while (!playlist->pass()) { - set_progress (float (_done) / playlist->audio_length ()); + while (!player->pass()) { + set_progress (float (_done) / _film->audio_length ()); } _analysis->write (_film->audio_analysis_path ()); diff --git a/src/lib/audio_decoder.cc b/src/lib/audio_decoder.cc index e2006a795..df13a984a 100644 --- a/src/lib/audio_decoder.cc +++ b/src/lib/audio_decoder.cc @@ -22,7 +22,7 @@ using boost::optional; using boost::shared_ptr; -AudioDecoder::AudioDecoder (shared_ptr f, shared_ptr c) +AudioDecoder::AudioDecoder (shared_ptr f) : Decoder (f) { diff --git a/src/lib/audio_decoder.h b/src/lib/audio_decoder.h index cbb84b52d..24e2796ae 100644 --- a/src/lib/audio_decoder.h +++ b/src/lib/audio_decoder.h @@ -35,7 +35,7 @@ class AudioContent; class AudioDecoder : public AudioSource, public virtual Decoder { public: - AudioDecoder (boost::shared_ptr, boost::shared_ptr); + AudioDecoder (boost::shared_ptr); }; #endif diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 00807f863..5c3e56709 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -53,9 +53,8 @@ using namespace boost; int const Encoder::_history_size = 25; /** @param f Film that we are encoding */ -Encoder::Encoder (shared_ptr f, shared_ptr p) +Encoder::Encoder (shared_ptr f) : _film (f) - , _playlist (p) , _video_frames_in (0) , _video_frames_out (0) #ifdef HAVE_SWRESAMPLE @@ -78,22 +77,22 @@ Encoder::~Encoder () void Encoder::process_begin () { - if (_playlist->has_audio() && _playlist->audio_frame_rate() != _film->target_audio_sample_rate()) { + if (_film->has_audio() && _film->audio_frame_rate() != _film->target_audio_sample_rate()) { #ifdef HAVE_SWRESAMPLE stringstream s; - s << String::compose (N_("Will resample audio from %1 to %2"), _playlist->audio_frame_rate(), _film->target_audio_sample_rate()); + s << String::compose (N_("Will resample audio from %1 to %2"), _film->audio_frame_rate(), _film->target_audio_sample_rate()); _film->log()->log (s.str ()); /* We will be using planar float data when we call the resampler */ _swr_context = swr_alloc_set_opts ( 0, - _playlist->audio_channel_layout(), + _film->audio_channel_layout(), AV_SAMPLE_FMT_FLTP, _film->target_audio_sample_rate(), - _playlist->audio_channel_layout(), + _film->audio_channel_layout(), AV_SAMPLE_FMT_FLTP, - _playlist->audio_frame_rate(), + _film->audio_frame_rate(), 0, 0 ); @@ -119,7 +118,7 @@ Encoder::process_begin () } } - _writer.reset (new Writer (_film, _playlist)); + _writer.reset (new Writer (_film)); } @@ -127,9 +126,9 @@ void Encoder::process_end () { #if HAVE_SWRESAMPLE - if (_playlist->has_audio() && _playlist->audio_channels() && _swr_context) { + if (_film->has_audio() && _film->audio_channels() && _swr_context) { - shared_ptr out (new AudioBuffers (_playlist->audio_channels(), 256)); + shared_ptr out (new AudioBuffers (_film->audio_channels(), 256)); while (1) { int const frames = swr_convert (_swr_context, (uint8_t **) out->data(), 256, 0, 0); @@ -234,7 +233,7 @@ Encoder::frame_done () void Encoder::process_video (shared_ptr image, bool same, boost::shared_ptr sub) { - FrameRateConversion frc (_playlist->video_frame_rate(), _film->dcp_frame_rate()); + FrameRateConversion frc (_film->video_frame_rate(), _film->dcp_frame_rate()); if (frc.skip && (_video_frames_in % 2)) { ++_video_frames_in; @@ -272,7 +271,7 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptr ( new DCPVideoFrame ( - image, sub, _film->format()->dcp_size(), _film->format()->dcp_padding (_playlist), + image, sub, _film->format()->dcp_size(), _film->format()->dcp_padding (_film), _film->subtitle_offset(), _film->subtitle_scale(), _film->scaler(), _video_frames_out, _film->dcp_frame_rate(), s.second, _film->colour_lut(), _film->j2k_bandwidth(), @@ -302,9 +301,9 @@ Encoder::process_audio (shared_ptr data) if (_swr_context) { /* Compute the resampled frames count and add 32 for luck */ - int const max_resampled_frames = ceil ((int64_t) data->frames() * _film->target_audio_sample_rate() / _playlist->audio_frame_rate()) + 32; + int const max_resampled_frames = ceil ((int64_t) data->frames() * _film->target_audio_sample_rate() / _film->audio_frame_rate()) + 32; - shared_ptr resampled (new AudioBuffers (_playlist->audio_channels(), max_resampled_frames)); + shared_ptr resampled (new AudioBuffers (_film->audio_channels(), max_resampled_frames)); /* Resample audio */ int const resampled_frames = swr_convert ( @@ -426,8 +425,8 @@ Encoder::encoder_thread (ServerDescription* server) void Encoder::write_audio (shared_ptr data) { - AudioMapping m (_playlist->audio_channels ()); - if (m.dcp_channels() != _playlist->audio_channels()) { + AudioMapping m (_film->audio_channels ()); + if (m.dcp_channels() != _film->audio_channels()) { /* Remap (currently just for mono -> 5.1) */ diff --git a/src/lib/encoder.h b/src/lib/encoder.h index c84ee027a..86880bc34 100644 --- a/src/lib/encoder.h +++ b/src/lib/encoder.h @@ -51,7 +51,6 @@ class ServerDescription; class DCPVideoFrame; class EncodedData; class Writer; -class Playlist; /** @class Encoder * @brief Encoder to J2K and WAV for DCP. @@ -63,7 +62,7 @@ class Playlist; class Encoder : public VideoSink, public AudioSink { public: - Encoder (boost::shared_ptr f, boost::shared_ptr); + Encoder (boost::shared_ptr f); virtual ~Encoder (); /** Called to indicate that a processing run is about to begin */ @@ -96,7 +95,6 @@ private: /** Film that we are encoding */ boost::shared_ptr _film; - boost::shared_ptr _playlist; /** Mutex for _time_history and _last_frame */ mutable boost::mutex _history_mutex; diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 7b56a5971..25ca9bb88 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -61,10 +61,10 @@ using boost::optional; using boost::dynamic_pointer_cast; using libdcp::Size; -FFmpegDecoder::FFmpegDecoder (shared_ptr f, shared_ptr c, bool video, bool audio, bool subtitles, bool video_sync) +FFmpegDecoder::FFmpegDecoder (shared_ptr f, shared_ptr c, bool video, bool audio, bool subtitles, bool video_sync) : Decoder (f) - , VideoDecoder (f, c) - , AudioDecoder (f, c) + , VideoDecoder (f) + , AudioDecoder (f) , _ffmpeg_content (c) , _format_context (0) , _video_stream (-1) diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h index ef66f09d9..71ecf7906 100644 --- a/src/lib/ffmpeg_decoder.h +++ b/src/lib/ffmpeg_decoder.h @@ -57,7 +57,7 @@ class Log; class FFmpegDecoder : public VideoDecoder, public AudioDecoder { public: - FFmpegDecoder (boost::shared_ptr, boost::shared_ptr, bool video, bool audio, bool subtitles, bool video_sync); + FFmpegDecoder (boost::shared_ptr, boost::shared_ptr, bool video, bool audio, bool subtitles, bool video_sync); ~FFmpegDecoder (); float frames_per_second () const; @@ -105,7 +105,7 @@ private: std::string stream_name (AVStream* s) const; - boost::shared_ptr _ffmpeg_content; + boost::shared_ptr _ffmpeg_content; AVFormatContext* _format_context; int _video_stream; diff --git a/src/lib/film.cc b/src/lib/film.cc index f2c7a654a..fe16a65fa 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -91,7 +91,8 @@ int const Film::state_version = 4; */ Film::Film (string d, bool must_exist) - : _use_dci_name (true) + : _playlist (new Playlist) + , _use_dci_name (true) , _trust_content_headers (true) , _dcp_content_type (0) , _format (0) @@ -151,6 +152,7 @@ Film::Film (Film const & o) : boost::enable_shared_from_this (o) /* note: the copied film shares the original's log */ , _log (o._log) + , _playlist (new Playlist) , _directory (o._directory) , _name (o._name) , _use_dci_name (o._use_dci_name) @@ -175,7 +177,7 @@ Film::Film (Film const & o) , _dcp_frame_rate (o._dcp_frame_rate) , _dirty (o._dirty) { - + _playlist->setup (_content); } Film::~Film () @@ -554,17 +556,14 @@ Film::file (string f) const int Film::target_audio_sample_rate () const { - /* XXX: how often is this method called? */ - - boost::shared_ptr p = playlist (); - if (p->has_audio ()) { + if (has_audio ()) { return 0; } /* Resample to a DCI-approved sample rate */ - double t = dcp_audio_sample_rate (p->audio_frame_rate()); + double t = dcp_audio_sample_rate (audio_frame_rate()); - FrameRateConversion frc (p->video_frame_rate(), dcp_frame_rate()); + FrameRateConversion frc (video_frame_rate(), dcp_frame_rate()); /* Compensate if the DCP is being run at a different frame rate to the source; that is, if the video is run such that it will @@ -573,7 +572,7 @@ Film::target_audio_sample_rate () const */ if (frc.change_speed) { - t *= p->video_frame_rate() * frc.factor() / dcp_frame_rate(); + t *= video_frame_rate() * frc.factor() / dcp_frame_rate(); } return rint (t); @@ -1023,11 +1022,11 @@ Film::have_dcp () const return true; } -shared_ptr -Film::playlist () const +shared_ptr +Film::player () const { boost::mutex::scoped_lock lm (_state_mutex); - return shared_ptr (new Playlist (shared_from_this (), _content)); + return shared_ptr (new Player (shared_from_this (), _playlist)); } void @@ -1036,9 +1035,59 @@ Film::add_content (shared_ptr c) { boost::mutex::scoped_lock lm (_state_mutex); _content.push_back (c); + _playlist->setup (_content); } signal_changed (CONTENT); examine_content (c); } + +ContentAudioFrame +Film::audio_length () const +{ + return _playlist->audio_length (); +} + +int +Film::audio_channels () const +{ + return _playlist->audio_channels (); +} + +int +Film::audio_frame_rate () const +{ + return _playlist->audio_frame_rate (); +} + +int64_t +Film::audio_channel_layout () const +{ + return _playlist->audio_channel_layout (); +} + +bool +Film::has_audio () const +{ + return _playlist->has_audio (); +} + +float +Film::video_frame_rate () const +{ + return _playlist->video_frame_rate (); +} + +libdcp::Size +Film::video_size () const +{ + return _playlist->video_size (); +} + +ContentVideoFrame +Film::video_length () const +{ + return _playlist->video_length (); +} + diff --git a/src/lib/film.h b/src/lib/film.h index f5f944409..6e097d44e 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -47,6 +47,7 @@ class ExamineContentJob; class AnalyseAudioJob; class ExternalAudioStream; class Content; +class Player; class Playlist; /** @class Film @@ -105,7 +106,17 @@ public: bool have_dcp () const; - boost::shared_ptr playlist () const; + boost::shared_ptr player () const; + + ContentAudioFrame audio_length () const; + int audio_channels () const; + int audio_frame_rate () const; + int64_t audio_channel_layout () const; + bool has_audio () const; + + float video_frame_rate () const; + libdcp::Size video_size () const; + ContentVideoFrame video_length () const; /** Identifiers for the parts of our state; used for signalling changes. @@ -301,6 +312,8 @@ private: void analyse_audio_finished (); std::string video_state_identifier () const; + boost::shared_ptr _playlist; + /** Complete path to directory containing the film metadata; * must not be relative. */ diff --git a/src/lib/format.cc b/src/lib/format.cc index 05b71f2e5..538bf7953 100644 --- a/src/lib/format.cc +++ b/src/lib/format.cc @@ -207,9 +207,9 @@ FixedFormat::FixedFormat (int r, libdcp::Size dcp, string id, string n, string d * (so there are dcp_padding() pixels on the left and dcp_padding() on the right) */ int -Format::dcp_padding (shared_ptr p) const +Format::dcp_padding (shared_ptr f) const { - int pad = rint ((_dcp_size.width - (_dcp_size.height * ratio_as_integer(p) / 100.0)) / 2.0); + int pad = rint ((_dcp_size.width - (_dcp_size.height * ratio_as_integer(f) / 100.0)) / 2.0); /* This comes out -ve for Scope; bodge it */ if (pad < 0) { @@ -232,15 +232,15 @@ VariableFormat::VariableFormat (libdcp::Size dcp, string id, string n, string d, } int -VariableFormat::ratio_as_integer (shared_ptr p) const +VariableFormat::ratio_as_integer (shared_ptr f) const { - return rint (ratio_as_float (p) * 100); + return rint (ratio_as_float (f) * 100); } float -VariableFormat::ratio_as_float (shared_ptr p) const +VariableFormat::ratio_as_float (shared_ptr f) const { - return float (p->video_size().width) / p->video_size().height; + return float (f->video_size().width) / f->video_size().height; } /** @return A name to be presented to the user */ diff --git a/src/lib/format.h b/src/lib/format.h index 94c2253de..cc7502893 100644 --- a/src/lib/format.h +++ b/src/lib/format.h @@ -26,7 +26,7 @@ #include #include "util.h" -class Playlist; +class Film; class Format { @@ -42,15 +42,15 @@ public: /** @return the aspect ratio multiplied by 100 * (e.g. 239 for Cinemascope 2.39:1) */ - virtual int ratio_as_integer (boost::shared_ptr f) const = 0; + virtual int ratio_as_integer (boost::shared_ptr f) const = 0; /** @return the ratio as a floating point number */ - virtual float ratio_as_float (boost::shared_ptr f) const = 0; + virtual float ratio_as_float (boost::shared_ptr f) const = 0; /** @return the ratio of the container (including any padding) as a floating point number */ float container_ratio_as_float () const; - int dcp_padding (boost::shared_ptr) const; + int dcp_padding (boost::shared_ptr) const; /** @return size in pixels of the images that we should * put in a DCP for this ratio. This size will not correspond @@ -115,11 +115,11 @@ class FixedFormat : public Format public: FixedFormat (int, libdcp::Size, std::string, std::string, std::string, std::string); - int ratio_as_integer (boost::shared_ptr) const { + int ratio_as_integer (boost::shared_ptr) const { return _ratio; } - float ratio_as_float (boost::shared_ptr) const { + float ratio_as_float (boost::shared_ptr) const { return _ratio / 100.0; } @@ -136,8 +136,8 @@ class VariableFormat : public Format public: VariableFormat (libdcp::Size, std::string, std::string, std::string, std::string); - int ratio_as_integer (boost::shared_ptr f) const; - float ratio_as_float (boost::shared_ptr f) const; + int ratio_as_integer (boost::shared_ptr f) const; + float ratio_as_float (boost::shared_ptr f) const; std::string name () const; }; diff --git a/src/lib/imagemagick_decoder.cc b/src/lib/imagemagick_decoder.cc index c3723f610..279c8bf32 100644 --- a/src/lib/imagemagick_decoder.cc +++ b/src/lib/imagemagick_decoder.cc @@ -32,9 +32,9 @@ using std::cout; using boost::shared_ptr; using libdcp::Size; -ImageMagickDecoder::ImageMagickDecoder (shared_ptr f, shared_ptr c) +ImageMagickDecoder::ImageMagickDecoder (shared_ptr f, shared_ptr c) : Decoder (f) - , VideoDecoder (f, c) + , VideoDecoder (f) , _imagemagick_content (c) , _position (0) { diff --git a/src/lib/imagemagick_decoder.h b/src/lib/imagemagick_decoder.h index a26e283c0..7ad08df03 100644 --- a/src/lib/imagemagick_decoder.h +++ b/src/lib/imagemagick_decoder.h @@ -28,7 +28,7 @@ class ImageMagickContent; class ImageMagickDecoder : public VideoDecoder { public: - ImageMagickDecoder (boost::shared_ptr, boost::shared_ptr); + ImageMagickDecoder (boost::shared_ptr, boost::shared_ptr); float frames_per_second () const { /* We don't know */ @@ -82,6 +82,6 @@ protected: private: void film_changed (Film::Property); - boost::shared_ptr _imagemagick_content; + boost::shared_ptr _imagemagick_content; ContentVideoFrame _position; }; diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index fc9edac48..d9bf8ac36 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -30,15 +30,20 @@ using std::list; using boost::shared_ptr; using boost::dynamic_pointer_cast; -Playlist::Playlist (shared_ptr f, list > c) - : _film (f) - , _video_from (VIDEO_NONE) +Playlist::Playlist () + : _video_from (VIDEO_NONE) , _audio_from (AUDIO_NONE) - , _have_setup_decoders (false) - , _ffmpeg_decoder_done (false) - , _video_sync (true) { - for (list >::const_iterator i = c.begin(); i != c.end(); ++i) { + +} + +void +Playlist::setup (list > content) +{ + _video_from = VIDEO_NONE; + _audio_from = AUDIO_NONE; + + for (list >::const_iterator i = content.begin(); i != content.end(); ++i) { shared_ptr fc = dynamic_pointer_cast (*i); if (fc) { assert (!_ffmpeg); @@ -76,7 +81,7 @@ Playlist::audio_length () const case AUDIO_SNDFILE: { ContentAudioFrame l = 0; - for (list >::const_iterator i = _sndfile.begin(); i != _sndfile.end(); ++i) { + for (list >::const_iterator i = _sndfile.begin(); i != _sndfile.end(); ++i) { l += (*i)->audio_length (); } return l; @@ -97,7 +102,7 @@ Playlist::audio_channels () const case AUDIO_SNDFILE: { int c = 0; - for (list >::const_iterator i = _sndfile.begin(); i != _sndfile.end(); ++i) { + for (list >::const_iterator i = _sndfile.begin(); i != _sndfile.end(); ++i) { c += (*i)->audio_channels (); } return c; @@ -180,7 +185,7 @@ Playlist::video_length () const case VIDEO_IMAGEMAGICK: { ContentVideoFrame l = 0; - for (list >::const_iterator i = _imagemagick.begin(); i != _imagemagick.end(); ++i) { + for (list >::const_iterator i = _imagemagick.begin(); i != _imagemagick.end(); ++i) { l += (*i)->video_length (); } return l; @@ -195,27 +200,40 @@ Playlist::has_audio () const { return _audio_from != AUDIO_NONE; } + +Player::Player (boost::shared_ptr f, boost::shared_ptr p) + : _film (f) + , _playlist (p) + , _video (true) + , _audio (true) + , _subtitles (true) + , _have_setup_decoders (false) + , _ffmpeg_decoder_done (false) + , _video_sync (true) +{ + +} void -Playlist::disable_video () +Player::disable_video () { - _video_from = VIDEO_NONE; + _video = false; } void -Playlist::disable_audio () +Player::disable_audio () { - _audio_from = AUDIO_NONE; + _audio = false; } void -Playlist::disable_subtitles () +Player::disable_subtitles () { - /* XXX */ + _subtitles = false; } bool -Playlist::pass () +Player::pass () { if (!_have_setup_decoders) { setup_decoders (); @@ -224,7 +242,7 @@ Playlist::pass () bool done = true; - if (_video_from == VIDEO_FFMPEG || _audio_from == AUDIO_FFMPEG) { + if (_playlist->video_from() == Playlist::VIDEO_FFMPEG || _playlist->audio_from() == Playlist::AUDIO_FFMPEG) { if (!_ffmpeg_decoder_done) { if (_ffmpeg_decoder->pass ()) { _ffmpeg_decoder_done = true; @@ -234,7 +252,7 @@ Playlist::pass () } } - if (_video_from == VIDEO_IMAGEMAGICK) { + if (_playlist->video_from() == Playlist::VIDEO_IMAGEMAGICK) { if (_imagemagick_decoder != _imagemagick_decoders.end ()) { if ((*_imagemagick_decoder)->pass ()) { _imagemagick_decoder++; @@ -252,37 +270,37 @@ Playlist::pass () } void -Playlist::set_progress (shared_ptr job) +Player::set_progress (shared_ptr job) { /* XXX */ } void -Playlist::process_video (shared_ptr i, bool same, shared_ptr s) +Player::process_video (shared_ptr i, bool same, shared_ptr s) { Video (i, same, s); } void -Playlist::process_audio (shared_ptr b) +Player::process_audio (shared_ptr b) { Audio (b); } bool -Playlist::seek (double t) +Player::seek (double t) { bool r = false; - switch (_video_from) { - case VIDEO_NONE: + switch (_playlist->video_from()) { + case Playlist::VIDEO_NONE: break; - case VIDEO_FFMPEG: + case Playlist::VIDEO_FFMPEG: if (_ffmpeg_decoder->seek (t)) { r = true; } break; - case VIDEO_IMAGEMAGICK: + case Playlist::VIDEO_IMAGEMAGICK: if ((*_imagemagick_decoder)->seek (t)) { r = true; } @@ -295,19 +313,19 @@ Playlist::seek (double t) } bool -Playlist::seek_to_last () +Player::seek_to_last () { bool r = false; - switch (_video_from) { - case VIDEO_NONE: + switch (_playlist->video_from ()) { + case Playlist::VIDEO_NONE: break; - case VIDEO_FFMPEG: + case Playlist::VIDEO_FFMPEG: if (_ffmpeg_decoder->seek_to_last ()) { r = true; } break; - case VIDEO_IMAGEMAGICK: + case Playlist::VIDEO_IMAGEMAGICK: if ((*_imagemagick_decoder)->seek_to_last ()) { r = true; } @@ -320,26 +338,32 @@ Playlist::seek_to_last () } void -Playlist::setup_decoders () +Player::setup_decoders () { - if (_video_from == VIDEO_FFMPEG || _audio_from == AUDIO_FFMPEG) { + if ((_video && _playlist->video_from() == Playlist::VIDEO_FFMPEG) || (_audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG)) { _ffmpeg_decoder.reset ( new FFmpegDecoder ( - _film, _ffmpeg, _video_from == VIDEO_FFMPEG, _audio_from == AUDIO_FFMPEG, _film->with_subtitles(), _video_sync + _film, + _playlist->ffmpeg(), + _video && _playlist->video_from() == Playlist::VIDEO_FFMPEG, + _audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG, + _subtitles && _film->with_subtitles(), + _video_sync ) ); } - if (_video_from == VIDEO_FFMPEG) { + if (_video && _playlist->video_from() == Playlist::VIDEO_FFMPEG) { _ffmpeg_decoder->connect_video (shared_from_this ()); } - if (_audio_from == AUDIO_FFMPEG) { + if (_audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG) { _ffmpeg_decoder->connect_audio (shared_from_this ()); } - if (_video_from == VIDEO_IMAGEMAGICK) { - for (list >::iterator i = _imagemagick.begin(); i != _imagemagick.end(); ++i) { + if (_video && _playlist->video_from() == Playlist::VIDEO_IMAGEMAGICK) { + list > ic = _playlist->imagemagick (); + for (list >::iterator i = ic.begin(); i != ic.end(); ++i) { shared_ptr d (new ImageMagickDecoder (_film, *i)); _imagemagick_decoders.push_back (d); d->connect_video (shared_from_this ()); @@ -348,8 +372,9 @@ Playlist::setup_decoders () _imagemagick_decoder = _imagemagick_decoders.begin (); } - if (_audio_from == AUDIO_SNDFILE) { - for (list >::iterator i = _sndfile.begin(); i != _sndfile.end(); ++i) { + if (_audio && _playlist->audio_from() == Playlist::AUDIO_SNDFILE) { + list > sc = _playlist->sndfile (); + for (list >::iterator i = sc.begin(); i != sc.end(); ++i) { shared_ptr d (new SndfileDecoder (_film, *i)); _sndfile_decoders.push_back (d); d->connect_audio (shared_from_this ()); @@ -358,7 +383,22 @@ Playlist::setup_decoders () } void -Playlist::disable_video_sync () +Player::disable_video_sync () { _video_sync = false; } + +double +Player::last_video_time () const +{ + switch (_playlist->video_from ()) { + case Playlist::VIDEO_NONE: + return 0; + case Playlist::VIDEO_FFMPEG: + return _ffmpeg_decoder->last_source_time (); + case Playlist::VIDEO_IMAGEMAGICK: + return (*_imagemagick_decoder)->last_source_time (); + } + + return 0; +} diff --git a/src/lib/playlist.h b/src/lib/playlist.h index d374dc98c..827849049 100644 --- a/src/lib/playlist.h +++ b/src/lib/playlist.h @@ -35,10 +35,12 @@ class SndfileDecoder; class Job; class Film; -class Playlist : public VideoSource, public AudioSource, public VideoSink, public AudioSink, public boost::enable_shared_from_this +class Playlist { public: - Playlist (boost::shared_ptr, std::list >); + Playlist (); + + void setup (std::list >); ContentAudioFrame audio_length () const; int audio_channels () const; @@ -50,6 +52,52 @@ public: libdcp::Size video_size () const; ContentVideoFrame video_length () const; + enum VideoFrom { + VIDEO_NONE, + VIDEO_FFMPEG, + VIDEO_IMAGEMAGICK + }; + + enum AudioFrom { + AUDIO_NONE, + AUDIO_FFMPEG, + AUDIO_SNDFILE + }; + + VideoFrom video_from () const { + return _video_from; + } + + AudioFrom audio_from () const { + return _audio_from; + } + + boost::shared_ptr ffmpeg () const { + return _ffmpeg; + } + + std::list > imagemagick () const { + return _imagemagick; + } + + std::list > sndfile () const { + return _sndfile; + } + +private: + VideoFrom _video_from; + AudioFrom _audio_from; + + boost::shared_ptr _ffmpeg; + std::list > _imagemagick; + std::list > _sndfile; +}; + +class Player : public VideoSource, public AudioSource, public VideoSink, public AudioSink, public boost::enable_shared_from_this +{ +public: + Player (boost::shared_ptr, boost::shared_ptr); + void disable_video (); void disable_audio (); void disable_subtitles (); @@ -60,29 +108,20 @@ public: bool seek (double); bool seek_to_last (); + double last_video_time () const; + private: void process_video (boost::shared_ptr i, bool same, boost::shared_ptr s); void process_audio (boost::shared_ptr); void setup_decoders (); - - boost::shared_ptr _film; - enum { - VIDEO_NONE, - VIDEO_FFMPEG, - VIDEO_IMAGEMAGICK - } _video_from; + boost::shared_ptr _film; + boost::shared_ptr _playlist; + + bool _video; + bool _audio; + bool _subtitles; - enum { - AUDIO_NONE, - AUDIO_FFMPEG, - AUDIO_SNDFILE - } _audio_from; - - boost::shared_ptr _ffmpeg; - std::list > _imagemagick; - std::list > _sndfile; - bool _have_setup_decoders; boost::shared_ptr _ffmpeg_decoder; bool _ffmpeg_decoder_done; diff --git a/src/lib/sndfile_decoder.cc b/src/lib/sndfile_decoder.cc index daa363c5e..1f97e5c41 100644 --- a/src/lib/sndfile_decoder.cc +++ b/src/lib/sndfile_decoder.cc @@ -36,9 +36,9 @@ using boost::optional; /* XXX */ -SndfileDecoder::SndfileDecoder (shared_ptr f, shared_ptr c) +SndfileDecoder::SndfileDecoder (shared_ptr f, shared_ptr c) : Decoder (f) - , AudioDecoder (f, c) + , AudioDecoder (f) { sf_count_t frames; SNDFILE* sf = open_file (frames); diff --git a/src/lib/sndfile_decoder.h b/src/lib/sndfile_decoder.h index 9a3ef49b0..56fc3a9f0 100644 --- a/src/lib/sndfile_decoder.h +++ b/src/lib/sndfile_decoder.h @@ -26,7 +26,7 @@ class SndfileContent; class SndfileDecoder : public AudioDecoder { public: - SndfileDecoder (boost::shared_ptr, boost::shared_ptr); + SndfileDecoder (boost::shared_ptr, boost::shared_ptr); bool pass (); @@ -34,5 +34,5 @@ private: SNDFILE* open_file (sf_count_t &); void close_file (SNDFILE*); - boost::shared_ptr _sndfile_content; + boost::shared_ptr _sndfile_content; }; diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc index 21944c5fc..0ee6f523f 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -47,24 +47,24 @@ using boost::dynamic_pointer_cast; */ Transcoder::Transcoder (shared_ptr f, shared_ptr j) : _job (j) - , _playlist (f->playlist ()) - , _encoder (new Encoder (f, _playlist)) + , _player (f->player ()) + , _encoder (new Encoder (f)) { - if (_playlist->has_audio ()) { - _matcher.reset (new Matcher (f->log(), _playlist->audio_frame_rate(), _playlist->video_frame_rate())); - _delay_line.reset (new DelayLine (f->log(), _playlist->audio_channels(), f->audio_delay() * _playlist->audio_frame_rate() / 1000)); + if (f->has_audio ()) { + _matcher.reset (new Matcher (f->log(), f->audio_frame_rate(), f->video_frame_rate())); + _delay_line.reset (new DelayLine (f->log(), f->audio_channels(), f->audio_delay() * f->audio_frame_rate() / 1000)); _gain.reset (new Gain (f->log(), f->audio_gain())); } if (_matcher) { - _playlist->connect_video (_matcher); + _player->connect_video (_matcher); _matcher->connect_video (_encoder); } else { - _playlist->connect_video (_encoder); + _player->connect_video (_encoder); } - if (_matcher && _delay_line && _playlist->has_audio ()) { - _playlist->connect_audio (_delay_line); + if (_matcher && _delay_line && f->has_audio ()) { + _player->connect_audio (_delay_line); _delay_line->connect_audio (_matcher); _matcher->connect_audio (_gain); _gain->connect_audio (_encoder); @@ -77,10 +77,10 @@ Transcoder::go () _encoder->process_begin (); try { while (1) { - if (_playlist->pass ()) { + if (_player->pass ()) { break; } - _playlist->set_progress (_job); + _player->set_progress (_job); } } catch (...) { diff --git a/src/lib/transcoder.h b/src/lib/transcoder.h index 856b10f3a..2d032fcf6 100644 --- a/src/lib/transcoder.h +++ b/src/lib/transcoder.h @@ -30,7 +30,7 @@ class Matcher; class VideoFilter; class Gain; class DelayLine; -class Playlist; +class Player; /** @class Transcoder * @@ -50,7 +50,7 @@ public: protected: /** A Job that is running this Transcoder, or 0 */ boost::shared_ptr _job; - boost::shared_ptr _playlist; + boost::shared_ptr _player; boost::shared_ptr _encoder; boost::shared_ptr _matcher; boost::shared_ptr _delay_line; diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc index 33dd433ea..32b06085f 100644 --- a/src/lib/video_decoder.cc +++ b/src/lib/video_decoder.cc @@ -29,7 +29,7 @@ using boost::shared_ptr; using boost::optional; -VideoDecoder::VideoDecoder (shared_ptr f, shared_ptr c) +VideoDecoder::VideoDecoder (shared_ptr f) : Decoder (f) , _video_frame (0) , _last_source_time (0) @@ -106,10 +106,7 @@ VideoDecoder::set_progress (Job* j) const { assert (j); -#if 0 - XXX - if (_film->length()) { - j->set_progress (float (_video_frame) / _film->length().get()); + if (_film->video_length()) { + j->set_progress (float (_video_frame) / _film->video_length()); } -#endif } diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h index 03dc4777a..a2fd5b651 100644 --- a/src/lib/video_decoder.h +++ b/src/lib/video_decoder.h @@ -28,7 +28,7 @@ class VideoContent; class VideoDecoder : public VideoSource, public virtual Decoder { public: - VideoDecoder (boost::shared_ptr, boost::shared_ptr); + VideoDecoder (boost::shared_ptr); /** @return video frames per second, or 0 if unknown */ virtual float frames_per_second () const = 0; diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 5f5dae98f..b08b9caf1 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -42,9 +42,8 @@ using boost::shared_ptr; int const Writer::_maximum_frames_in_memory = 8; -Writer::Writer (shared_ptr f, shared_ptr p) +Writer::Writer (shared_ptr f) : _film (f) - , _playlist (p) , _first_nonexistant_frame (0) , _thread (0) , _finish (false) @@ -76,7 +75,7 @@ Writer::Writer (shared_ptr f, shared_ptr p) _picture_asset_writer = _picture_asset->start_write (_first_nonexistant_frame > 0); - AudioMapping m (_playlist->audio_channels ()); + AudioMapping m (_film->audio_channels ()); if (m.dcp_channels() > 0) { _sound_asset.reset ( @@ -85,7 +84,7 @@ Writer::Writer (shared_ptr f, shared_ptr p) N_("audio.mxf"), _film->dcp_frame_rate (), m.dcp_channels (), - dcp_audio_sample_rate (_playlist->audio_frame_rate()) + dcp_audio_sample_rate (_film->audio_frame_rate()) ) ); diff --git a/src/lib/writer.h b/src/lib/writer.h index 920f592b6..beb16c7b9 100644 --- a/src/lib/writer.h +++ b/src/lib/writer.h @@ -26,7 +26,6 @@ class Film; class EncodedData; class AudioBuffers; -class Playlist; namespace libdcp { class MonoPictureAsset; @@ -64,7 +63,7 @@ bool operator== (QueueItem const & a, QueueItem const & b); class Writer : public ExceptionStore { public: - Writer (boost::shared_ptr, boost::shared_ptr); + Writer (boost::shared_ptr); bool can_fake_write (int) const; @@ -81,7 +80,6 @@ private: /** our Film */ boost::shared_ptr _film; - boost::shared_ptr _playlist; /** the first frame index that does not already exist in our MXF */ int _first_nonexistant_frame; diff --git a/src/tools/servomatictest.cc b/src/tools/servomatictest.cc index 3d847d690..d7e8bbb0e 100644 --- a/src/tools/servomatictest.cc +++ b/src/tools/servomatictest.cc @@ -150,14 +150,14 @@ main (int argc, char* argv[]) server = new ServerDescription (server_host, 1); shared_ptr film (new Film (film_dir, true)); - shared_ptr playlist = film->playlist (); - playlist->disable_audio (); + shared_ptr player = film->player (); + player->disable_audio (); try { - playlist->Video.connect (boost::bind (process_video, _1, _2, _3)); + player->Video.connect (boost::bind (process_video, _1, _2, _3)); bool done = false; while (!done) { - done = playlist->pass (); + done = player->pass (); } } catch (std::exception& e) { cerr << "Error: " << e.what() << "\n"; diff --git a/src/wx/audio_dialog.cc b/src/wx/audio_dialog.cc index b7384fd14..242d37b1e 100644 --- a/src/wx/audio_dialog.cc +++ b/src/wx/audio_dialog.cc @@ -20,7 +20,6 @@ #include #include "lib/audio_analysis.h" #include "lib/film.h" -#include "lib/playlist.h" #include "audio_dialog.h" #include "audio_plot.h" #include "wx_util.h" @@ -91,7 +90,6 @@ AudioDialog::set_film (boost::shared_ptr f) _film_audio_analysis_succeeded_connection.disconnect (); _film = f; - _playlist = _film->playlist (); try_to_load_analysis (); setup_channels (); @@ -106,11 +104,11 @@ AudioDialog::set_film (boost::shared_ptr f) void AudioDialog::setup_channels () { - if (!_playlist->has_audio()) { + if (!_film->has_audio()) { return; } - AudioMapping m (_playlist->audio_channels ()); + AudioMapping m (_film->audio_channels ()); for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) { if (m.dcp_to_source(static_cast(i))) { @@ -136,7 +134,7 @@ AudioDialog::try_to_load_analysis () _plot->set_analysis (a); - AudioMapping m (_playlist->audio_channels ()); + AudioMapping m (_film->audio_channels ()); optional c = m.source_to_dcp (0); if (c) { _channel_checkbox[c.get()]->SetValue (true); @@ -159,7 +157,7 @@ AudioDialog::channel_clicked (wxCommandEvent& ev) assert (c < MAX_AUDIO_CHANNELS); - AudioMapping m (_playlist->audio_channels ()); + AudioMapping m (_film->audio_channels ()); optional s = m.dcp_to_source (static_cast (c)); if (s) { _plot->set_channel_visible (s.get(), _channel_checkbox[c]->GetValue ()); @@ -174,7 +172,6 @@ AudioDialog::film_changed (Film::Property p) _plot->set_gain (_film->audio_gain ()); break; case Film::CONTENT: - _playlist = _film->playlist (); setup_channels (); break; default: diff --git a/src/wx/audio_dialog.h b/src/wx/audio_dialog.h index 3cb9c1726..514faeea0 100644 --- a/src/wx/audio_dialog.h +++ b/src/wx/audio_dialog.h @@ -25,7 +25,6 @@ class AudioPlot; class Film; -class Playlist; class AudioDialog : public wxDialog { @@ -43,7 +42,6 @@ private: void setup_channels (); boost::shared_ptr _film; - boost::shared_ptr _playlist; AudioPlot* _plot; wxCheckBox* _channel_checkbox[MAX_AUDIO_CHANNELS]; wxCheckBox* _type_checkbox[AudioPoint::COUNT]; diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 42af4b3c0..79b3d982f 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -97,13 +97,13 @@ FilmViewer::film_changed (Film::Property p) break; case Film::CONTENT: { - _playlist = _film->playlist (); - _playlist->disable_audio (); - _playlist->disable_subtitles (); - _playlist->disable_video_sync (); + _player = _film->player (); + _player->disable_audio (); + _player->disable_subtitles (); + _player->disable_video_sync (); - _playlist->Video.connect (bind (&FilmViewer::process_video, this, _1, _2, _3)); -// _playlist->OutputChanged.connect (boost::bind (&FilmViewer::decoder_changed, this)); + _player->Video.connect (bind (&FilmViewer::process_video, this, _1, _2, _3)); +// _player->OutputChanged.connect (boost::bind (&FilmViewer::decoder_changed, this)); calculate_sizes (); get_frame (); _panel->Refresh (); @@ -153,7 +153,7 @@ FilmViewer::set_film (shared_ptr f) void FilmViewer::decoder_changed () { - if (!_playlist == 0 || _playlist->seek_to_last ()) { + if (!_player || _player->seek_to_last ()) { return; } @@ -165,7 +165,7 @@ FilmViewer::decoder_changed () void FilmViewer::timer (wxTimerEvent &) { - if (!_playlist) { + if (!_player) { return; } @@ -174,12 +174,12 @@ FilmViewer::timer (wxTimerEvent &) get_frame (); -// if (_playlist->video_length()) { -// int const new_slider_position = 4096 * _playlist->last_source_time() / (_film->length().get() / _film->source_frame_rate()); -// if (new_slider_position != _slider->GetValue()) { -// _slider->SetValue (new_slider_position); -// } -// } + if (_film->video_length()) { + int const new_slider_position = 4096 * _player->last_video_time() / (_film->video_length() / _film->video_frame_rate()); + if (new_slider_position != _slider->GetValue()) { + _slider->SetValue (new_slider_position); + } + } } @@ -220,11 +220,11 @@ FilmViewer::paint_panel (wxPaintEvent &) void FilmViewer::slider_moved (wxScrollEvent &) { - if (!_film || !_playlist) { + if (!_film || !_player) { return; } - if (_playlist->seek (_slider->GetValue() * _playlist->video_length() / (4096 * _playlist->video_frame_rate()))) { + if (_player->seek (_slider->GetValue() * _film->video_length() / (4096 * _film->video_frame_rate()))) { return; } @@ -308,7 +308,7 @@ FilmViewer::raw_to_display () void FilmViewer::calculate_sizes () { - if (!_film || !_playlist) { + if (!_film || !_player) { return; } @@ -332,7 +332,7 @@ FilmViewer::calculate_sizes () */ _display_frame_x = 0; if (format) { - _display_frame_x = static_cast (format->dcp_padding (_playlist)) * _out_size.width / format->dcp_size().width; + _display_frame_x = static_cast (format->dcp_padding (_film)) * _out_size.width / format->dcp_size().width; } _film_size = _out_size; @@ -381,7 +381,7 @@ FilmViewer::get_frame () /* Clear our raw frame in case we don't get a new one */ _raw_frame.reset (); - if (!_playlist) { + if (!_player) { _display_frame.reset (); return; } @@ -389,7 +389,7 @@ FilmViewer::get_frame () try { _got_frame = false; while (!_got_frame) { - if (_playlist->pass ()) { + if (_player->pass ()) { /* We didn't get a frame before the decoder gave up, so clear our display frame. */ diff --git a/src/wx/film_viewer.h b/src/wx/film_viewer.h index 74ab9798c..1e75045ac 100644 --- a/src/wx/film_viewer.h +++ b/src/wx/film_viewer.h @@ -57,7 +57,7 @@ private: void active_jobs_changed (bool); boost::shared_ptr _film; - boost::shared_ptr _playlist; + boost::shared_ptr _player; wxSizer* _v_sizer; wxPanel* _panel; diff --git a/wscript b/wscript index fb728ec40..9040738fb 100644 --- a/wscript +++ b/wscript @@ -55,6 +55,7 @@ def configure(conf): if not conf.options.static: conf.check_cfg(package = 'libdcp', atleast_version = '0.41', args = '--cflags --libs', uselib_store = 'DCP', mandatory = True) + conf.check_cfg(package = 'libcxml', atleast_version = '0.01', args = '--cflags --libs', uselib_store = 'CXML', mandatory = True) conf.check_cfg(package = 'libavformat', args = '--cflags --libs', uselib_store = 'AVFORMAT', mandatory = True) conf.check_cfg(package = 'libavfilter', args = '--cflags --libs', uselib_store = 'AVFILTER', mandatory = True) conf.check_cfg(package = 'libavcodec', args = '--cflags --libs', uselib_store = 'AVCODEC', mandatory = True) @@ -71,6 +72,8 @@ def configure(conf): conf.env.HAVE_DCP = 1 conf.env.STLIB_DCP = ['dcp', 'asdcp-libdcp', 'kumu-libdcp'] conf.env.LIB_DCP = ['glibmm-2.4', 'xml++-2.6', 'ssl', 'crypto', 'bz2'] + conf.env.HAVE_CXML = 1 + conf.env.STLIB_CXML = ['cxml'] conf.env.HAVE_AVFORMAT = 1 conf.env.STLIB_AVFORMAT = ['avformat'] conf.env.HAVE_AVFILTER = 1 -- cgit v1.2.3 From fff7a8232b18ce6191e60ba911c29b64b9063d4d Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 2 Apr 2013 00:03:45 +0100 Subject: Various bits. --- src/lib/content.h | 19 ++++++++++ src/lib/decoder.h | 2 - src/lib/encoder.h | 2 +- src/lib/ffmpeg_content.cc | 19 ++++++++++ src/lib/ffmpeg_content.h | 19 ++++++++++ src/lib/ffmpeg_decoder.cc | 1 - src/lib/film.cc | 56 ++++++++++++++++++++++++++++ src/lib/film.h | 7 +++- src/lib/imagemagick_content.cc | 46 ++++++++++++++++++++++- src/lib/imagemagick_content.h | 24 +++++++++++- src/lib/imagemagick_decoder.cc | 14 +++---- src/lib/imagemagick_decoder.h | 11 +----- src/lib/playlist.cc | 23 ++++++++++-- src/lib/playlist.h | 2 +- src/lib/util.cc | 14 +------ src/lib/util.h | 83 +----------------------------------------- src/lib/video_content.cc | 8 +++- src/lib/wscript | 1 + src/wx/film_editor.cc | 35 ++++++++++++++---- src/wx/film_viewer.cc | 16 ++++---- src/wx/film_viewer.h | 2 +- 21 files changed, 261 insertions(+), 143 deletions(-) (limited to 'src') diff --git a/src/lib/content.h b/src/lib/content.h index 3a94d2297..87ef46581 100644 --- a/src/lib/content.h +++ b/src/lib/content.h @@ -1,3 +1,22 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + #ifndef DVDOMATIC_CONTENT_H #define DVDOMATIC_CONTENT_H diff --git a/src/lib/decoder.h b/src/lib/decoder.h index 4ccdc046f..34accf6c7 100644 --- a/src/lib/decoder.h +++ b/src/lib/decoder.h @@ -58,8 +58,6 @@ public: virtual bool seek (double); virtual bool seek_to_last (); - boost::signals2::signal OutputChanged; - protected: boost::shared_ptr _film; diff --git a/src/lib/encoder.h b/src/lib/encoder.h index 86880bc34..2cbd498e8 100644 --- a/src/lib/encoder.h +++ b/src/lib/encoder.h @@ -106,7 +106,7 @@ private: static int const _history_size; /** Number of video frames received so far */ - SourceFrame _video_frames_in; + ContentVideoFrame _video_frames_in; /** Number of video frames written for the DCP so far */ int _video_frames_out; diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index 42e04e838..50a69ae7b 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -1,3 +1,22 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + #include #include "ffmpeg_content.h" #include "ffmpeg_decoder.h" diff --git a/src/lib/ffmpeg_content.h b/src/lib/ffmpeg_content.h index 95e24b7b3..c56dc0a61 100644 --- a/src/lib/ffmpeg_content.h +++ b/src/lib/ffmpeg_content.h @@ -1,3 +1,22 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + #ifndef DVDOMATIC_FFMPEG_CONTENT_H #define DVDOMATIC_FFMPEG_CONTENT_H diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 25ca9bb88..ced9b95e9 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -592,7 +592,6 @@ FFmpegDecoder::film_changed (Film::Property p) boost::mutex::scoped_lock lm (_filter_graphs_mutex); _filter_graphs.clear (); } - OutputChanged (); break; default: diff --git a/src/lib/film.cc b/src/lib/film.cc index fe16a65fa..19e900784 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -1043,6 +1043,62 @@ Film::add_content (shared_ptr c) examine_content (c); } +void +Film::remove_content (shared_ptr c) +{ + { + boost::mutex::scoped_lock lm (_state_mutex); + ContentList::iterator i = find (_content.begin(), _content.end(), c); + if (i != _content.end ()) { + _content.erase (i); + } + } + + signal_changed (CONTENT); +} + +void +Film::move_content_earlier (shared_ptr c) +{ + { + boost::mutex::scoped_lock lm (_state_mutex); + ContentList::iterator i = find (_content.begin(), _content.end(), c); + if (i == _content.begin () || i == _content.end()) { + return; + } + + ContentList::iterator j = i; + --j; + + swap (*i, *j); + } + + signal_changed (CONTENT); +} + +void +Film::move_content_later (shared_ptr c) +{ + { + boost::mutex::scoped_lock lm (_state_mutex); + ContentList::iterator i = find (_content.begin(), _content.end(), c); + if (i == _content.end()) { + return; + } + + ContentList::iterator j = i; + ++j; + if (j == _content.end ()) { + return; + } + + swap (*i, *j); + } + + signal_changed (CONTENT); + +} + ContentAudioFrame Film::audio_length () const { diff --git a/src/lib/film.h b/src/lib/film.h index 6e097d44e..9682a37d7 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -38,6 +38,7 @@ extern "C" { #include "dcp_content_type.h" #include "util.h" #include "dci_metadata.h" +#include "types.h" class Format; class Job; @@ -171,7 +172,7 @@ public: return _trust_content_headers; } - std::list > content () const { + ContentList content () const { boost::mutex::scoped_lock lm (_state_mutex); return _content; } @@ -268,6 +269,9 @@ public: void set_use_dci_name (bool); void set_trust_content_headers (bool); void add_content (boost::shared_ptr); + void remove_content (boost::shared_ptr); + void move_content_earlier (boost::shared_ptr); + void move_content_later (boost::shared_ptr); void set_dcp_content_type (DCPContentType const *); void set_format (Format const *); void set_crop (Crop); @@ -325,7 +329,6 @@ private: std::string _name; /** True if a auto-generated DCI-compliant name should be used for our DCP */ bool _use_dci_name; - typedef std::list > ContentList; ContentList _content; bool _trust_content_headers; /** The type of content that this Film represents (feature, trailer etc.) */ diff --git a/src/lib/imagemagick_content.cc b/src/lib/imagemagick_content.cc index cb712b417..f9572b518 100644 --- a/src/lib/imagemagick_content.cc +++ b/src/lib/imagemagick_content.cc @@ -1,5 +1,25 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + #include #include "imagemagick_content.h" +#include "imagemagick_decoder.h" #include "compose.hpp" #include "i18n.h" @@ -11,8 +31,7 @@ ImageMagickContent::ImageMagickContent (boost::filesystem::path f) : Content (f) , VideoContent (f) { - /* XXX */ - _video_length = 10 * 24; + } ImageMagickContent::ImageMagickContent (shared_ptr node) @@ -35,3 +54,26 @@ ImageMagickContent::valid_file (boost::filesystem::path f) transform (ext.begin(), ext.end(), ext.begin(), ::tolower); return (ext == ".tif" || ext == ".tiff" || ext == ".jpg" || ext == ".jpeg" || ext == ".png" || ext == ".bmp"); } + +void +ImageMagickContent::as_xml (xmlpp::Node* node) const +{ + node->add_child("Type")->add_child_text ("ImageMagick"); + Content::as_xml (node); + VideoContent::as_xml (node); +} + +void +ImageMagickContent::examine (shared_ptr film, shared_ptr job, bool quick) +{ + Content::examine (film, job, quick); + shared_ptr decoder (new ImageMagickDecoder (film, shared_from_this())); + + { + boost::mutex::scoped_lock lm (_mutex); + /* XXX */ + _video_length = 10 * 24; + } + + take_from_video_decoder (decoder); +} diff --git a/src/lib/imagemagick_content.h b/src/lib/imagemagick_content.h index 99b614512..5820bd807 100644 --- a/src/lib/imagemagick_content.h +++ b/src/lib/imagemagick_content.h @@ -1,16 +1,38 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include #include "video_content.h" namespace cxml { class Node; } -class ImageMagickContent : public VideoContent +class ImageMagickContent : public VideoContent, public boost::enable_shared_from_this { public: ImageMagickContent (boost::filesystem::path); ImageMagickContent (boost::shared_ptr); + void examine (boost::shared_ptr, boost::shared_ptr, bool); std::string summary () const; + void as_xml (xmlpp::Node *) const; static bool valid_file (boost::filesystem::path); }; diff --git a/src/lib/imagemagick_decoder.cc b/src/lib/imagemagick_decoder.cc index 279c8bf32..508863e3e 100644 --- a/src/lib/imagemagick_decoder.cc +++ b/src/lib/imagemagick_decoder.cc @@ -52,6 +52,12 @@ ImageMagickDecoder::native_size () const return s; } +int +ImageMagickDecoder::video_length () const +{ + return _imagemagick_content->video_length (); +} + bool ImageMagickDecoder::pass () { @@ -120,11 +126,3 @@ ImageMagickDecoder::seek (double t) _position = f; return false; } - -void -ImageMagickDecoder::film_changed (Film::Property p) -{ - if (p == Film::CROP) { - OutputChanged (); - } -} diff --git a/src/lib/imagemagick_decoder.h b/src/lib/imagemagick_decoder.h index 7ad08df03..424cefe08 100644 --- a/src/lib/imagemagick_decoder.h +++ b/src/lib/imagemagick_decoder.h @@ -31,16 +31,11 @@ public: ImageMagickDecoder (boost::shared_ptr, boost::shared_ptr); float frames_per_second () const { - /* We don't know */ - return 0; + return 24; } libdcp::Size native_size () const; - - ContentVideoFrame video_length () const { - /* We don't know */ - return 0; - } + ContentVideoFrame video_length () const; int audio_channels () const { return 0; @@ -80,8 +75,6 @@ protected: } private: - void film_changed (Film::Property); - boost::shared_ptr _imagemagick_content; ContentVideoFrame _position; }; diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index d9bf8ac36..609d4096c 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -27,6 +27,7 @@ #include "imagemagick_decoder.h" using std::list; +using std::cout; using boost::shared_ptr; using boost::dynamic_pointer_cast; @@ -38,12 +39,12 @@ Playlist::Playlist () } void -Playlist::setup (list > content) +Playlist::setup (ContentList content) { _video_from = VIDEO_NONE; _audio_from = AUDIO_NONE; - for (list >::const_iterator i = content.begin(); i != content.end(); ++i) { + for (ContentList::const_iterator i = content.begin(); i != content.end(); ++i) { shared_ptr fc = dynamic_pointer_cast (*i); if (fc) { assert (!_ffmpeg); @@ -287,11 +288,12 @@ Player::process_audio (shared_ptr b) Audio (b); } +/** @return true on error */ bool Player::seek (double t) { bool r = false; - + switch (_playlist->video_from()) { case Playlist::VIDEO_NONE: break; @@ -301,7 +303,20 @@ Player::seek (double t) } break; case Playlist::VIDEO_IMAGEMAGICK: - if ((*_imagemagick_decoder)->seek (t)) { + /* Find the decoder that contains this position */ + _imagemagick_decoder = _imagemagick_decoders.begin (); + while (_imagemagick_decoder != _imagemagick_decoders.end ()) { + double const this_length = (*_imagemagick_decoder)->video_length() / _film->video_frame_rate (); + if (this_length < t) { + break; + } + t -= this_length; + ++_imagemagick_decoder; + } + + if (_imagemagick_decoder != _imagemagick_decoders.end()) { + (*_imagemagick_decoder)->seek (t); + } else { r = true; } break; diff --git a/src/lib/playlist.h b/src/lib/playlist.h index 827849049..403fb58d4 100644 --- a/src/lib/playlist.h +++ b/src/lib/playlist.h @@ -40,7 +40,7 @@ class Playlist public: Playlist (); - void setup (std::list >); + void setup (ContentList); ContentAudioFrame audio_length () const; int audio_channels () const; diff --git a/src/lib/util.cc b/src/lib/util.cc index 1c020875a..e0de82c64 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -476,16 +476,6 @@ dcp_audio_sample_rate (int fs) return 96000; } -bool operator== (Crop const & a, Crop const & b) -{ - return (a.left == b.left && a.right == b.right && a.top == b.top && a.bottom == b.bottom); -} - -bool operator!= (Crop const & a, Crop const & b) -{ - return !(a == b); -} - /** @param index Colour LUT index. * @return Human-readable name. */ @@ -867,13 +857,13 @@ ensure_ui_thread () assert (this_thread::get_id() == ui_thread); } -/** @param v Source video frame. +/** @param v Content video frame. * @param audio_sample_rate Source audio sample rate. * @param frames_per_second Number of video frames per second. * @return Equivalent number of audio frames for `v'. */ int64_t -video_frames_to_audio_frames (SourceFrame v, float audio_sample_rate, float frames_per_second) +video_frames_to_audio_frames (ContentVideoFrame v, float audio_sample_rate, float frames_per_second) { return ((int64_t) v * audio_sample_rate / frames_per_second); } diff --git a/src/lib/util.h b/src/lib/util.h index b8c1e3116..23ebd52bc 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -37,6 +37,7 @@ extern "C" { #include } #include "compose.hpp" +#include "types.h" #ifdef DVDOMATIC_DEBUG #define TIMING(...) _film->log()->microsecond_log (String::compose (__VA_ARGS__), Log::TIMING); @@ -65,10 +66,6 @@ extern std::string audio_channel_name (int); extern boost::filesystem::path mo_path (); #endif -typedef int SourceFrame; -typedef int64_t ContentAudioFrame; -typedef int ContentVideoFrame; - struct FrameRateConversion { FrameRateConversion (float, int); @@ -106,82 +103,6 @@ struct FrameRateConversion int best_dcp_frame_rate (float); -/** @struct Crop - * @brief A description of the crop of an image or video. - */ -struct Crop -{ - Crop () : left (0), right (0), top (0), bottom (0) {} - - /** Number of pixels to remove from the left-hand side */ - int left; - /** Number of pixels to remove from the right-hand side */ - int right; - /** Number of pixels to remove from the top */ - int top; - /** Number of pixels to remove from the bottom */ - int bottom; -}; - -extern bool operator== (Crop const & a, Crop const & b); -extern bool operator!= (Crop const & a, Crop const & b); - -/** @struct Position - * @brief A position. - */ -struct Position -{ - Position () - : x (0) - , y (0) - {} - - Position (int x_, int y_) - : x (x_) - , y (y_) - {} - - /** x coordinate */ - int x; - /** y coordinate */ - int y; -}; - -/** @struct Rect - * @brief A rectangle. - */ -struct Rect -{ - Rect () - : x (0) - , y (0) - , width (0) - , height (0) - {} - - Rect (int x_, int y_, int w_, int h_) - : x (x_) - , y (y_) - , width (w_) - , height (h_) - {} - - int x; - int y; - int width; - int height; - - Position position () const { - return Position (x, y); - } - - libdcp::Size size () const { - return libdcp::Size (width, height); - } - - Rect intersection (Rect const & other) const; -}; - extern std::string crop_string (Position, libdcp::Size); extern int dcp_audio_sample_rate (int); extern std::string colour_lut_index_to_name (int index); @@ -286,7 +207,7 @@ private: int _source_channels; }; -extern int64_t video_frames_to_audio_frames (SourceFrame v, float audio_sample_rate, float frames_per_second); +extern int64_t video_frames_to_audio_frames (ContentVideoFrame v, float audio_sample_rate, float frames_per_second); extern std::pair cpu_info (); #endif diff --git a/src/lib/video_content.cc b/src/lib/video_content.cc index 8a4414c18..e697a281d 100644 --- a/src/lib/video_content.cc +++ b/src/lib/video_content.cc @@ -39,10 +39,14 @@ VideoContent::as_xml (xmlpp::Node* node) const void VideoContent::take_from_video_decoder (shared_ptr d) { + /* These decoder calls could call other content methods which take a lock on the mutex */ + libdcp::Size const vs = d->native_size (); + float const vfr = d->frames_per_second (); + { boost::mutex::scoped_lock lm (_mutex); - _video_size = d->native_size (); - _video_frame_rate = d->frames_per_second (); + _video_size = vs; + _video_frame_rate = vfr; } Changed (VideoContentProperty::VIDEO_SIZE); diff --git a/src/lib/wscript b/src/lib/wscript index 303a9951f..f2bb678aa 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -49,6 +49,7 @@ sources = """ timer.cc transcode_job.cc transcoder.cc + types.cc ui_signaller.cc util.cc version.cc diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 560c4ef27..7930d86ce 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -200,9 +200,9 @@ FilmEditor::connect_to_widgets () _trust_content_headers->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::trust_content_headers_changed), 0, this); _content->Connect (wxID_ANY, wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler (FilmEditor::content_item_selected), 0, this); _content_add->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_add_clicked), 0, this); - _content_remove->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_add_clicked), 0, this); - _content_earlier->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_add_clicked), 0, this); - _content_later->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_add_clicked), 0, this); + _content_remove->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_remove_clicked), 0, this); + _content_earlier->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_earlier_clicked), 0, this); + _content_later->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_later_clicked), 0, this); _left_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::left_crop_changed), 0, this); _right_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::right_crop_changed), 0, this); _top_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::top_crop_changed), 0, this); @@ -1135,13 +1135,13 @@ FilmEditor::best_dcp_frame_rate_clicked (wxCommandEvent &) return; } -// _film->set_dcp_frame_rate (best_dcp_frame_rate (_film->source_frame_rate ())); + _film->set_dcp_frame_rate (best_dcp_frame_rate (_film->video_frame_rate ())); } void FilmEditor::setup_show_audio_sensitivity () { -// _show_audio->Enable (_film && _film->has_audio ()); + _show_audio->Enable (_film && _film->has_audio ()); } void @@ -1149,8 +1149,8 @@ FilmEditor::setup_content () { _content->DeleteAllItems (); - list > content = _film->content (); - for (list >::iterator i = content.begin(); i != content.end(); ++i) { + ContentList content = _film->content (); + for (ContentList::iterator i = content.begin(); i != content.end(); ++i) { _content->InsertItem (_content->GetItemCount(), std_to_wx ((*i)->summary ())); } } @@ -1181,19 +1181,40 @@ FilmEditor::content_add_clicked (wxCommandEvent &) void FilmEditor::content_remove_clicked (wxCommandEvent &) { + int const s = _content->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (s == -1) { + return; + } + ContentList c = _film->content (); + assert (s >= 0 && size_t (s) < c.size ()); + _film->remove_content (c[s]); } void FilmEditor::content_earlier_clicked (wxCommandEvent &) { + int const s = _content->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (s == -1) { + return; + } + ContentList c = _film->content (); + assert (s >= 0 && size_t (s) < c.size ()); + _film->move_content_earlier (c[s]); } void FilmEditor::content_later_clicked (wxCommandEvent &) { + int const s = _content->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (s == -1) { + return; + } + ContentList c = _film->content (); + assert (s >= 0 && size_t (s) < c.size ()); + _film->move_content_later (c[s]); } void diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 79b3d982f..e45f79a87 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -103,7 +103,6 @@ FilmViewer::film_changed (Film::Property p) _player->disable_video_sync (); _player->Video.connect (bind (&FilmViewer::process_video, this, _1, _2, _3)); -// _player->OutputChanged.connect (boost::bind (&FilmViewer::decoder_changed, this)); calculate_sizes (); get_frame (); _panel->Refresh (); @@ -115,12 +114,8 @@ FilmViewer::film_changed (Film::Property p) case Film::SUBTITLE_SCALE: case Film::SCALER: case Film::FILTERS: - update_from_raw (); - break; - case Film::SUBTITLE_STREAM: -// if (_decoders.video) { -// _decoders.video->set_subtitle_stream (_film->subtitle_stream ()); -// } + case Film::CROP: + update_from_decoder (); break; default: break; @@ -151,7 +146,7 @@ FilmViewer::set_film (shared_ptr f) } void -FilmViewer::decoder_changed () +FilmViewer::update_from_decoder () { if (!_player || _player->seek_to_last ()) { return; @@ -223,7 +218,7 @@ FilmViewer::slider_moved (wxScrollEvent &) if (!_film || !_player) { return; } - + if (_player->seek (_slider->GetValue() * _film->video_length() / (4096 * _film->video_frame_rate()))) { return; } @@ -375,6 +370,9 @@ FilmViewer::process_video (shared_ptr image, bool, shared_ptr s _got_frame = true; } +/** Get a new _raw_frame from the decoder and then do + * raw_to_display (). + */ void FilmViewer::get_frame () { diff --git a/src/wx/film_viewer.h b/src/wx/film_viewer.h index 1e75045ac..f557d69b8 100644 --- a/src/wx/film_viewer.h +++ b/src/wx/film_viewer.h @@ -51,7 +51,7 @@ private: void calculate_sizes (); void check_play_state (); void update_from_raw (); - void decoder_changed (); + void update_from_decoder (); void raw_to_display (); void get_frame (); void active_jobs_changed (bool); -- cgit v1.2.3 From 68b63467e29476c74b2e27780cd3047091c5cb07 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 2 Apr 2013 10:28:54 +0100 Subject: Updated sv_SE from Adam. --- src/lib/po/sv_SE.po | 15 +++++++-------- src/tools/po/sv_SE.po | 5 ++--- src/wx/po/sv_SE.po | 7 +++---- 3 files changed, 12 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/lib/po/sv_SE.po b/src/lib/po/sv_SE.po index 292129f1c..1e9c40550 100644 --- a/src/lib/po/sv_SE.po +++ b/src/lib/po/sv_SE.po @@ -8,10 +8,9 @@ msgstr "" "Project-Id-Version: DVD-o-matic\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-04-01 21:21+0100\n" -"PO-Revision-Date: 2013-04-01 18:29+0100\n" +"PO-Revision-Date: 2013-04-02 08:13+0100\n" "Last-Translator: Adam Klotblixt \n" "Language-Team: \n" -"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -104,7 +103,7 @@ msgstr "" #: src/lib/util.cc:931 msgid "Centre" -msgstr "" +msgstr "Mitt" #: src/lib/scp_dcp_job.cc:109 msgid "Copy DCP to TMS" @@ -261,15 +260,15 @@ msgstr "Lanczos" #: src/lib/util.cc:929 msgid "Left" -msgstr "" +msgstr "Vänster" #: src/lib/util.cc:933 msgid "Left surround" -msgstr "" +msgstr "Vänster surround" #: src/lib/util.cc:932 msgid "Lfe (sub)" -msgstr "" +msgstr "Lfe (sub)" #: src/lib/filter.cc:75 msgid "Linear blend deinterlacer" @@ -323,11 +322,11 @@ msgstr "Rec 709" #: src/lib/util.cc:930 msgid "Right" -msgstr "" +msgstr "Höger" #: src/lib/util.cc:934 msgid "Right surround" -msgstr "" +msgstr "Höger surround" #: src/lib/scp_dcp_job.cc:133 msgid "SSH error (%1)" diff --git a/src/tools/po/sv_SE.po b/src/tools/po/sv_SE.po index 42b417ba4..6e2efb490 100644 --- a/src/tools/po/sv_SE.po +++ b/src/tools/po/sv_SE.po @@ -8,10 +8,9 @@ msgstr "" "Project-Id-Version: DVD-o-matic\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-04-01 21:21+0100\n" -"PO-Revision-Date: 2013-04-01 18:29+0100\n" +"PO-Revision-Date: 2013-04-02 08:50+0100\n" "Last-Translator: Adam Klotblixt \n" "Language-Team: \n" -"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -113,7 +112,7 @@ msgstr "&Visa DCP" #: src/tools/dvdomatic.cc:74 msgid "Save changes to film \"%1\" before closing?" -msgstr "" +msgstr "Spara ändringarna till filmen \"%1\" före avslut?" #: src/tools/dvdomatic.cc:319 msgid "Select film to open" diff --git a/src/wx/po/sv_SE.po b/src/wx/po/sv_SE.po index 0e97d5dda..41f97a846 100644 --- a/src/wx/po/sv_SE.po +++ b/src/wx/po/sv_SE.po @@ -8,10 +8,9 @@ msgstr "" "Project-Id-Version: DVD-o-matic\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-04-01 21:21+0100\n" -"PO-Revision-Date: 2013-04-01 18:40+0100\n" +"PO-Revision-Date: 2013-04-02 08:50+0100\n" "Last-Translator: Adam Klotblixt \n" "Language-Team: \n" -"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -141,9 +140,9 @@ msgid "DVD-o-matic Preferences" msgstr "DVD-o-matic Inställningar" #: src/wx/audio_dialog.cc:101 -#, fuzzy, c-format +#, c-format msgid "DVD-o-matic audio - %s" -msgstr "DVD-o-matic audio - %1" +msgstr "DVD-o-matic audio - %s" #: src/wx/config_dialog.cc:102 msgid "Default DCI name details" -- cgit v1.2.3 From bda2f7642709ca3aec35de9965a0e952e34f7dd1 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 2 Apr 2013 17:01:09 +0100 Subject: A little tidying up. --- src/lib/film.cc | 32 +++++++++++++------------------- src/lib/film.h | 44 ++++++++++++++++++++------------------------ 2 files changed, 33 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/src/lib/film.cc b/src/lib/film.cc index 19e900784..d82dce297 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -173,18 +173,17 @@ Film::Film (Film const & o) , _colour_lut (o._colour_lut) , _j2k_bandwidth (o._j2k_bandwidth) , _dci_metadata (o._dci_metadata) - , _dci_date (o._dci_date) , _dcp_frame_rate (o._dcp_frame_rate) + , _dci_date (o._dci_date) , _dirty (o._dirty) { + for (ContentList::iterator i = o._content.begin(); i != o._content.end(); ++i) { + _content.push_back ((*i)->clone ()); + } + _playlist->setup (_content); } -Film::~Film () -{ - -} - string Film::video_state_identifier () const { @@ -311,7 +310,7 @@ Film::make_dcp () } } -/** Start a job to analyse the audio of our content file */ +/** Start a job to analyse the audio in our Playlist */ void Film::analyse_audio () { @@ -345,12 +344,6 @@ Film::analyse_audio_finished () _analyse_audio_job.reset (); } -void -Film::examine_content_finished () -{ - /* XXX */ -} - /** Start a job to send our DCP to the configured TMS */ void Film::send_dcp_to_tms () @@ -422,8 +415,8 @@ Film::write_metadata () const root->add_child("ColourLUT")->add_child_text (boost::lexical_cast (_colour_lut)); root->add_child("J2KBandwidth")->add_child_text (boost::lexical_cast (_j2k_bandwidth)); _dci_metadata.as_xml (root->add_child ("DCIMetadata")); - root->add_child("DCIDate")->add_child_text (boost::gregorian::to_iso_string (_dci_date)); root->add_child("DCPFrameRate")->add_child_text (boost::lexical_cast (_dcp_frame_rate)); + root->add_child("DCIDate")->add_child_text (boost::gregorian::to_iso_string (_dci_date)); for (ContentList::iterator i = the_content.begin(); i != the_content.end(); ++i) { (*i)->as_xml (root->add_child ("Content")); @@ -488,8 +481,8 @@ Film::read_metadata () _colour_lut = f.number_child ("ColourLUT"); _j2k_bandwidth = f.number_child ("J2KBandwidth"); _dci_metadata = DCIMetadata (f.node_child ("DCIMetadata")); - _dci_date = boost::gregorian::from_undelimited_string (f.string_child ("DCIDate")); _dcp_frame_rate = f.number_child ("DCPFrameRate"); + _dci_date = boost::gregorian::from_undelimited_string (f.string_child ("DCIDate")); list > c = f.node_children ("Content"); for (list >::iterator i = c.begin(); i != c.end(); ++i) { @@ -624,8 +617,7 @@ Film::dci_name (bool if_created_now) const } } - /* XXX */ - switch (2) { + switch (audio_channels ()) { case 1: d << "_10"; break; @@ -715,8 +707,10 @@ Film::set_trust_content_headers (bool t) if (!_trust_content_headers && !content().empty()) { /* We just said that we don't trust the content's header */ - /* XXX */ -// examine_content (); + ContentList c = content (); + for (ContentList::iterator i = c.begin(); i != c.end(); ++i) { + examine_content (*i); + } } } diff --git a/src/lib/film.h b/src/lib/film.h index 9682a37d7..e1084e1ca 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -18,8 +18,8 @@ */ /** @file src/film.h - * @brief A representation of a piece of video (with sound), including naming, - * the source content file, and how it should be presented in a DCP. + * @brief A representation of some audio and video content, and details of + * how they should be presented in a DCP. */ #ifndef DVDOMATIC_FILM_H @@ -52,17 +52,14 @@ class Player; class Playlist; /** @class Film - * @brief A representation of a video, maybe with sound. - * - * A representation of a piece of video (maybe with sound), including naming, - * the source content file, and how it should be presented in a DCP. + * @brief A representation of some audio and video content, and details of + * how they should be presented in a DCP. */ class Film : public boost::enable_shared_from_this { public: Film (std::string d, bool must_exist = true); Film (Film const &); - ~Film (); std::string info_dir () const; std::string j2c_path (int f, bool t) const; @@ -74,7 +71,6 @@ public: void examine_content (boost::shared_ptr); void analyse_audio (); void send_dcp_to_tms (); - void make_dcp (); /** @return Logger. @@ -92,7 +88,6 @@ public: int target_audio_sample_rate () const; void write_metadata () const; - void read_metadata (); libdcp::Size cropped_size (libdcp::Size) const; std::string dci_name (bool if_created_now) const; @@ -103,12 +98,12 @@ public: return _dirty; } - void set_dci_date_today (); - bool have_dcp () const; boost::shared_ptr player () const; + /* Proxies for some Playlist methods */ + ContentAudioFrame audio_length () const; int audio_channels () const; int audio_frame_rate () const; @@ -127,6 +122,7 @@ public: NAME, USE_DCI_NAME, TRUST_CONTENT_HEADERS, + /** The content list has changed (i.e. content has been added, moved around or removed) */ CONTENT, DCP_CONTENT_TYPE, FORMAT, @@ -286,7 +282,6 @@ public: void set_ab (bool); void set_audio_gain (float); void set_audio_delay (int); - void set_still_duration (int); void set_with_subtitles (bool); void set_subtitle_offset (int); void set_subtitle_scale (float); @@ -294,10 +289,14 @@ public: void set_j2k_bandwidth (int); void set_dci_metadata (DCIMetadata); void set_dcp_frame_rate (int); + void set_dci_date_today (); - /** Emitted when some property has changed */ + /** Emitted when some property has of the Film has changed */ mutable boost::signals2::signal Changed; + /** Emitted when some property of our content has changed */ + mutable boost::signals2::signal ContentChanged; + boost::signals2::signal AudioAnalysisSucceeded; /** Current version number of the state file */ @@ -305,17 +304,15 @@ public: private: - /** Log to write to */ - boost::shared_ptr _log; - - /** Any running AnalyseAudioJob, or 0 */ - boost::shared_ptr _analyse_audio_job; - void signal_changed (Property); - void examine_content_finished (); void analyse_audio_finished (); std::string video_state_identifier () const; + void read_metadata (); + /** Log to write to */ + boost::shared_ptr _log; + /** Any running AnalyseAudioJob, or 0 */ + boost::shared_ptr _analyse_audio_job; boost::shared_ptr _playlist; /** Complete path to directory containing the film metadata; @@ -329,8 +326,8 @@ private: std::string _name; /** True if a auto-generated DCI-compliant name should be used for our DCP */ bool _use_dci_name; - ContentList _content; bool _trust_content_headers; + ContentList _content; /** The type of content that this Film represents (feature, trailer etc.) */ DCPContentType const * _dcp_content_type; /** The format to present this Film in (flat, scope, etc.) */ @@ -369,13 +366,12 @@ private: int _colour_lut; /** bandwidth for J2K files in bits per second */ int _j2k_bandwidth; - /** DCI naming stuff */ DCIMetadata _dci_metadata; - /** The date that we should use in a DCI name */ - boost::gregorian::date _dci_date; /** Frames per second to run our DCP at */ int _dcp_frame_rate; + /** The date that we should use in a DCI name */ + boost::gregorian::date _dci_date; /** true if our state has changed since we last saved it */ mutable bool _dirty; -- cgit v1.2.3 From d5eb7198e71c94f2756331aa2f0452c6b6c9398d Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 2 Apr 2013 19:19:46 +0100 Subject: Missing files. --- src/lib/types.cc | 31 ++++++++++++++++ src/lib/types.h | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100644 src/lib/types.cc create mode 100644 src/lib/types.h (limited to 'src') diff --git a/src/lib/types.cc b/src/lib/types.cc new file mode 100644 index 000000000..1e0f48327 --- /dev/null +++ b/src/lib/types.cc @@ -0,0 +1,31 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "types.h" + +bool operator== (Crop const & a, Crop const & b) +{ + return (a.left == b.left && a.right == b.right && a.top == b.top && a.bottom == b.bottom); +} + +bool operator!= (Crop const & a, Crop const & b) +{ + return !(a == b); +} + diff --git a/src/lib/types.h b/src/lib/types.h new file mode 100644 index 000000000..f821a74ac --- /dev/null +++ b/src/lib/types.h @@ -0,0 +1,109 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef DVDOMATIC_TYPES_H +#define DVDOMATIC_TYPES_H + +#include +#include +#include + +class Content; + +typedef std::vector > ContentList; +typedef int64_t ContentAudioFrame; +typedef int ContentVideoFrame; + +/** @struct Crop + * @brief A description of the crop of an image or video. + */ +struct Crop +{ + Crop () : left (0), right (0), top (0), bottom (0) {} + + /** Number of pixels to remove from the left-hand side */ + int left; + /** Number of pixels to remove from the right-hand side */ + int right; + /** Number of pixels to remove from the top */ + int top; + /** Number of pixels to remove from the bottom */ + int bottom; +}; + +extern bool operator== (Crop const & a, Crop const & b); +extern bool operator!= (Crop const & a, Crop const & b); + +/** @struct Position + * @brief A position. + */ +struct Position +{ + Position () + : x (0) + , y (0) + {} + + Position (int x_, int y_) + : x (x_) + , y (y_) + {} + + /** x coordinate */ + int x; + /** y coordinate */ + int y; +}; + +/** @struct Rect + * @brief A rectangle. + */ +struct Rect +{ + Rect () + : x (0) + , y (0) + , width (0) + , height (0) + {} + + Rect (int x_, int y_, int w_, int h_) + : x (x_) + , y (y_) + , width (w_) + , height (h_) + {} + + int x; + int y; + int width; + int height; + + Position position () const { + return Position (x, y); + } + + libdcp::Size size () const { + return libdcp::Size (width, height); + } + + Rect intersection (Rect const & other) const; +}; + +#endif -- cgit v1.2.3 From 956da4b106e14c49b179176acf6484c479c21094 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 2 Apr 2013 21:20:35 +0100 Subject: Various fixes. --- src/lib/audio_content.cc | 6 ++++++ src/lib/audio_content.h | 1 + src/lib/content.cc | 7 +++++++ src/lib/content.h | 2 ++ src/lib/ffmpeg_content.cc | 19 +++++++++++++++++++ src/lib/ffmpeg_content.h | 2 ++ src/lib/film.cc | 19 +++++++++++++++++-- src/lib/film.h | 3 ++- src/lib/imagemagick_content.cc | 8 ++++++++ src/lib/imagemagick_content.h | 1 + src/lib/imagemagick_decoder.cc | 8 +++++--- src/lib/playlist.cc | 6 +++++- src/lib/sndfile_content.cc | 6 ++++++ src/lib/sndfile_content.h | 1 + src/lib/video_content.cc | 9 +++++++++ src/lib/video_content.h | 1 + src/lib/video_decoder.cc | 6 ++++++ src/lib/video_decoder.h | 1 + src/wx/film_viewer.cc | 37 +++++++++++++++++++++++++++---------- src/wx/film_viewer.h | 2 ++ 20 files changed, 128 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/lib/audio_content.cc b/src/lib/audio_content.cc index 74b8ea2ce..b5419a058 100644 --- a/src/lib/audio_content.cc +++ b/src/lib/audio_content.cc @@ -14,3 +14,9 @@ AudioContent::AudioContent (shared_ptr node) { } + +AudioContent::AudioContent (AudioContent const & o) + : Content (o) +{ + +} diff --git a/src/lib/audio_content.h b/src/lib/audio_content.h index f3dd81efb..24391b01c 100644 --- a/src/lib/audio_content.h +++ b/src/lib/audio_content.h @@ -13,6 +13,7 @@ class AudioContent : public virtual Content public: AudioContent (boost::filesystem::path); AudioContent (boost::shared_ptr); + AudioContent (AudioContent const &); virtual int audio_channels () const = 0; virtual ContentAudioFrame audio_length () const = 0; diff --git a/src/lib/content.cc b/src/lib/content.cc index 977f2e2a7..0c21822cb 100644 --- a/src/lib/content.cc +++ b/src/lib/content.cc @@ -19,6 +19,13 @@ Content::Content (shared_ptr node) _digest = node->string_child ("Digest"); } +Content::Content (Content const & o) + : _file (o._file) + , _digest (o._digest) +{ + +} + void Content::as_xml (xmlpp::Node* node) const { diff --git a/src/lib/content.h b/src/lib/content.h index 87ef46581..3f348ca91 100644 --- a/src/lib/content.h +++ b/src/lib/content.h @@ -37,10 +37,12 @@ class Content public: Content (boost::filesystem::path); Content (boost::shared_ptr); + Content (Content const &); virtual void examine (boost::shared_ptr, boost::shared_ptr, bool); virtual std::string summary () const = 0; virtual void as_xml (xmlpp::Node *) const; + virtual boost::shared_ptr clone () const = 0; boost::filesystem::path file () const { boost::mutex::scoped_lock lm (_mutex); diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index 50a69ae7b..5bff1cecc 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -68,6 +68,19 @@ FFmpegContent::FFmpegContent (shared_ptr node) } } +FFmpegContent::FFmpegContent (FFmpegContent const & o) + : Content (o) + , VideoContent (o) + , AudioContent (o) + , boost::enable_shared_from_this (o) + , _subtitle_streams (o._subtitle_streams) + , _subtitle_stream (o._subtitle_stream) + , _audio_streams (o._audio_streams) + , _audio_stream (o._audio_stream) +{ + +} + void FFmpegContent::as_xml (xmlpp::Node* node) const { @@ -256,3 +269,9 @@ FFmpegSubtitleStream::as_xml (xmlpp::Node* root) const root->add_child("Name")->add_child_text (name); root->add_child("Id")->add_child_text (lexical_cast (id)); } + +shared_ptr +FFmpegContent::clone () const +{ + return shared_ptr (new FFmpegContent (*this)); +} diff --git a/src/lib/ffmpeg_content.h b/src/lib/ffmpeg_content.h index c56dc0a61..598ebf484 100644 --- a/src/lib/ffmpeg_content.h +++ b/src/lib/ffmpeg_content.h @@ -82,10 +82,12 @@ class FFmpegContent : public VideoContent, public AudioContent, public boost::en public: FFmpegContent (boost::filesystem::path); FFmpegContent (boost::shared_ptr); + FFmpegContent (FFmpegContent const &); void examine (boost::shared_ptr, boost::shared_ptr, bool); std::string summary () const; void as_xml (xmlpp::Node *) const; + boost::shared_ptr clone () const; /* AudioContent */ int audio_channels () const; diff --git a/src/lib/film.cc b/src/lib/film.cc index d82dce297..20a7ee49b 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -177,7 +177,7 @@ Film::Film (Film const & o) , _dci_date (o._dci_date) , _dirty (o._dirty) { - for (ContentList::iterator i = o._content.begin(); i != o._content.end(); ++i) { + for (ContentList::const_iterator i = o._content.begin(); i != o._content.end(); ++i) { _content.push_back ((*i)->clone ()); } @@ -328,7 +328,6 @@ void Film::examine_content (shared_ptr c) { shared_ptr j (new ExamineContentJob (shared_from_this(), c, trust_content_headers ())); - j->Finished.connect (bind (&Film::examine_content_finished, this)); JobManager::instance()->add (j); } @@ -1029,6 +1028,7 @@ Film::add_content (shared_ptr c) { boost::mutex::scoped_lock lm (_state_mutex); _content.push_back (c); + _content_connections.push_back (c->Changed.connect (bind (&Film::content_changed, this, _1))); _playlist->setup (_content); } @@ -1046,6 +1046,14 @@ Film::remove_content (shared_ptr c) if (i != _content.end ()) { _content.erase (i); } + + for (list::iterator i = _content_connections.begin(); i != _content_connections.end(); ++i) { + i->disconnect (); + } + + for (ContentList::iterator i = _content.begin(); i != _content.end(); ++i) { + _content_connections.push_back (c->Changed.connect (bind (&Film::content_changed, this, _1))); + } } signal_changed (CONTENT); @@ -1141,3 +1149,10 @@ Film::video_length () const return _playlist->video_length (); } +void +Film::content_changed (int p) +{ + if (ui_signaller) { + ui_signaller->emit (boost::bind (boost::ref (ContentChanged), p)); + } +} diff --git a/src/lib/film.h b/src/lib/film.h index e1084e1ca..f0a85fbf3 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -134,7 +134,6 @@ public: AB, AUDIO_GAIN, AUDIO_DELAY, - STILL_DURATION, SUBTITLE_STREAM, WITH_SUBTITLES, SUBTITLE_OFFSET, @@ -308,6 +307,7 @@ private: void analyse_audio_finished (); std::string video_state_identifier () const; void read_metadata (); + void content_changed (int); /** Log to write to */ boost::shared_ptr _log; @@ -328,6 +328,7 @@ private: bool _use_dci_name; bool _trust_content_headers; ContentList _content; + std::list _content_connections; /** The type of content that this Film represents (feature, trailer etc.) */ DCPContentType const * _dcp_content_type; /** The format to present this Film in (flat, scope, etc.) */ diff --git a/src/lib/imagemagick_content.cc b/src/lib/imagemagick_content.cc index f9572b518..5ad94db45 100644 --- a/src/lib/imagemagick_content.cc +++ b/src/lib/imagemagick_content.cc @@ -76,4 +76,12 @@ ImageMagickContent::examine (shared_ptr film, shared_ptr job, bool qu } take_from_video_decoder (decoder); + + Changed (VideoContentProperty::VIDEO_LENGTH); +} + +shared_ptr +ImageMagickContent::clone () const +{ + return shared_ptr (new ImageMagickContent (*this)); } diff --git a/src/lib/imagemagick_content.h b/src/lib/imagemagick_content.h index 5820bd807..2ca58f255 100644 --- a/src/lib/imagemagick_content.h +++ b/src/lib/imagemagick_content.h @@ -33,6 +33,7 @@ public: void examine (boost::shared_ptr, boost::shared_ptr, bool); std::string summary () const; void as_xml (xmlpp::Node *) const; + boost::shared_ptr clone () const; static bool valid_file (boost::filesystem::path); }; diff --git a/src/lib/imagemagick_decoder.cc b/src/lib/imagemagick_decoder.cc index 508863e3e..dff177548 100644 --- a/src/lib/imagemagick_decoder.cc +++ b/src/lib/imagemagick_decoder.cc @@ -61,12 +61,14 @@ ImageMagickDecoder::video_length () const bool ImageMagickDecoder::pass () { - if (_position > 0 && _position < _imagemagick_content->video_length ()) { + if (_position < 0 || _position >= _imagemagick_content->video_length ()) { + return true; + } + + if (have_last_video ()) { repeat_last_video (); _position++; return false; - } else if (_position >= _imagemagick_content->video_length ()) { - return true; } Magick::Image* magick_image = new Magick::Image (_imagemagick_content->file().string ()); diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index 609d4096c..3822420da 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -43,6 +43,10 @@ Playlist::setup (ContentList content) { _video_from = VIDEO_NONE; _audio_from = AUDIO_NONE; + + _ffmpeg.reset (); + _imagemagick.clear (); + _sndfile.clear (); for (ContentList::const_iterator i = content.begin(); i != content.end(); ++i) { shared_ptr fc = dynamic_pointer_cast (*i); @@ -307,7 +311,7 @@ Player::seek (double t) _imagemagick_decoder = _imagemagick_decoders.begin (); while (_imagemagick_decoder != _imagemagick_decoders.end ()) { double const this_length = (*_imagemagick_decoder)->video_length() / _film->video_frame_rate (); - if (this_length < t) { + if (t < this_length) { break; } t -= this_length; diff --git a/src/lib/sndfile_content.cc b/src/lib/sndfile_content.cc index 4794e4d31..657e7d519 100644 --- a/src/lib/sndfile_content.cc +++ b/src/lib/sndfile_content.cc @@ -64,3 +64,9 @@ SndfileContent::valid_file (boost::filesystem::path f) transform (ext.begin(), ext.end(), ext.begin(), ::tolower); return (ext == ".wav" || ext == ".aif" || ext == ".aiff"); } + +shared_ptr +SndfileContent::clone () const +{ + return shared_ptr (new SndfileContent (*this)); +} diff --git a/src/lib/sndfile_content.h b/src/lib/sndfile_content.h index b9a500c88..81a964ec8 100644 --- a/src/lib/sndfile_content.h +++ b/src/lib/sndfile_content.h @@ -11,6 +11,7 @@ public: SndfileContent (boost::shared_ptr); std::string summary () const; + boost::shared_ptr clone () const; /* AudioContent */ int audio_channels () const; diff --git a/src/lib/video_content.cc b/src/lib/video_content.cc index e697a281d..f48813f60 100644 --- a/src/lib/video_content.cc +++ b/src/lib/video_content.cc @@ -26,6 +26,15 @@ VideoContent::VideoContent (shared_ptr node) _video_frame_rate = node->number_child ("VideoFrameRate"); } +VideoContent::VideoContent (VideoContent const & o) + : Content (o) + , _video_length (o._video_length) + , _video_size (o._video_size) + , _video_frame_rate (o._video_frame_rate) +{ + +} + void VideoContent::as_xml (xmlpp::Node* node) const { diff --git a/src/lib/video_content.h b/src/lib/video_content.h index 7c9db890a..25cb28938 100644 --- a/src/lib/video_content.h +++ b/src/lib/video_content.h @@ -19,6 +19,7 @@ class VideoContent : public virtual Content public: VideoContent (boost::filesystem::path); VideoContent (boost::shared_ptr); + VideoContent (VideoContent const &); void as_xml (xmlpp::Node *) const; diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc index 32b06085f..47385cc61 100644 --- a/src/lib/video_decoder.cc +++ b/src/lib/video_decoder.cc @@ -54,6 +54,12 @@ VideoDecoder::emit_video (shared_ptr image, double t) _last_source_time = t; } +bool +VideoDecoder::have_last_video () const +{ + return _last_image; +} + /** Called by subclasses to repeat the last video frame that we * passed to emit_video(). If emit_video hasn't yet been called, * we will generate a black frame. diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h index a2fd5b651..74343e856 100644 --- a/src/lib/video_decoder.h +++ b/src/lib/video_decoder.h @@ -58,6 +58,7 @@ protected: void emit_video (boost::shared_ptr, double); void emit_subtitle (boost::shared_ptr); + bool have_last_video () const; void repeat_last_video (); private: diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index e45f79a87..9cf479508 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -35,6 +35,7 @@ #include "lib/examine_content_job.h" #include "lib/filter.h" #include "lib/playlist.h" +#include "lib/video_content.h" #include "film_viewer.h" #include "wx_util.h" #include "video_decoder.h" @@ -97,12 +98,7 @@ FilmViewer::film_changed (Film::Property p) break; case Film::CONTENT: { - _player = _film->player (); - _player->disable_audio (); - _player->disable_subtitles (); - _player->disable_video_sync (); - - _player->Video.connect (bind (&FilmViewer::process_video, this, _1, _2, _3)); + setup_player (); calculate_sizes (); get_frame (); _panel->Refresh (); @@ -122,6 +118,28 @@ FilmViewer::film_changed (Film::Property p) } } +void +FilmViewer::setup_player () +{ + _player = _film->player (); + _player->disable_audio (); + _player->disable_subtitles (); + _player->disable_video_sync (); + _player->Video.connect (bind (&FilmViewer::process_video, this, _1, _2, _3)); +} + +void +FilmViewer::film_content_changed (int p) +{ + if (p == VideoContentProperty::VIDEO_LENGTH || p == VideoContentProperty::VIDEO_SIZE) { + setup_player (); + calculate_sizes (); + get_frame (); + _panel->Refresh (); + _v_sizer->Layout (); + } +} + void FilmViewer::set_film (shared_ptr f) { @@ -136,6 +154,7 @@ FilmViewer::set_film (shared_ptr f) } _film->Changed.connect (boost::bind (&FilmViewer::film_changed, this, _1)); + _film->ContentChanged.connect (boost::bind (&FilmViewer::film_content_changed, this, _1)); film_changed (Film::CONTENT); film_changed (Film::FORMAT); @@ -276,14 +295,13 @@ FilmViewer::raw_to_display () _clear_required = true; } -#if 0 if (_raw_sub) { /* Our output is already cropped by the decoder, so we need to account for that when working out the scale that we are applying. */ - Size const cropped_size = _film->cropped_size (_film->size ()); + Size const cropped_size = _film->cropped_size (_film->video_size ()); Rect tx = subtitle_transformed_area ( float (_film_size.width) / cropped_size.width, @@ -297,7 +315,6 @@ FilmViewer::raw_to_display () } else { _display_sub.reset (); } -#endif } void @@ -353,7 +370,7 @@ FilmViewer::check_play_state () } if (_play_button->GetValue()) { -// _timer.Start (1000 / _film->source_frame_rate()); + _timer.Start (1000 / _film->video_frame_rate()); } else { _timer.Stop (); } diff --git a/src/wx/film_viewer.h b/src/wx/film_viewer.h index f557d69b8..e28703fdd 100644 --- a/src/wx/film_viewer.h +++ b/src/wx/film_viewer.h @@ -42,6 +42,7 @@ public: private: void film_changed (Film::Property); + void film_content_changed (int); void paint_panel (wxPaintEvent &); void panel_sized (wxSizeEvent &); void slider_moved (wxScrollEvent &); @@ -55,6 +56,7 @@ private: void raw_to_display (); void get_frame (); void active_jobs_changed (bool); + void setup_player (); boost::shared_ptr _film; boost::shared_ptr _player; -- cgit v1.2.3 From 7f203e4df9ca94a44099c26158c6c81b5299567f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 2 Apr 2013 21:29:07 +0100 Subject: A few more fixes; set up Playlist as required. --- src/lib/film.cc | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/lib/film.cc b/src/lib/film.cc index 20a7ee49b..9c4e8b50e 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -498,6 +498,8 @@ Film::read_metadata () } _dirty = false; + + _playlist->setup (_content); } libdcp::Size @@ -1054,6 +1056,8 @@ Film::remove_content (shared_ptr c) for (ContentList::iterator i = _content.begin(); i != _content.end(); ++i) { _content_connections.push_back (c->Changed.connect (bind (&Film::content_changed, this, _1))); } + + _playlist->setup (_content); } signal_changed (CONTENT); @@ -1073,6 +1077,7 @@ Film::move_content_earlier (shared_ptr c) --j; swap (*i, *j); + _playlist->setup (_content); } signal_changed (CONTENT); @@ -1095,6 +1100,7 @@ Film::move_content_later (shared_ptr c) } swap (*i, *j); + _playlist->setup (_content); } signal_changed (CONTENT); -- cgit v1.2.3 From 2343509c75673d3fad82a5d0eab9622a4d6902e3 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 2 Apr 2013 22:36:38 +0100 Subject: Fix a few more things. --- src/lib/film.cc | 16 ++++++++-- src/lib/film.h | 1 - src/wx/film_editor.cc | 84 +++++++++++++++++++++++++++------------------------ src/wx/film_editor.h | 1 + src/wx/film_viewer.cc | 3 +- 5 files changed, 61 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/lib/film.cc b/src/lib/film.cc index 9c4e8b50e..d58f7fd53 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -951,6 +951,15 @@ Film::signal_changed (Property p) _dirty = true; } + switch (p) { + case Film::CONTENT: + _playlist->setup (content ()); + set_dcp_frame_rate (best_dcp_frame_rate (video_frame_rate ())); + break; + default: + break; + } + if (ui_signaller) { ui_signaller->emit (boost::bind (boost::ref (Changed), p)); } @@ -1031,7 +1040,6 @@ Film::add_content (shared_ptr c) boost::mutex::scoped_lock lm (_state_mutex); _content.push_back (c); _content_connections.push_back (c->Changed.connect (bind (&Film::content_changed, this, _1))); - _playlist->setup (_content); } signal_changed (CONTENT); @@ -1056,8 +1064,6 @@ Film::remove_content (shared_ptr c) for (ContentList::iterator i = _content.begin(); i != _content.end(); ++i) { _content_connections.push_back (c->Changed.connect (bind (&Film::content_changed, this, _1))); } - - _playlist->setup (_content); } signal_changed (CONTENT); @@ -1158,6 +1164,10 @@ Film::video_length () const void Film::content_changed (int p) { + if (p == VideoContentProperty::VIDEO_FRAME_RATE) { + set_dcp_frame_rate (best_dcp_frame_rate (video_frame_rate ())); + } + if (ui_signaller) { ui_signaller->emit (boost::bind (boost::ref (ContentChanged), p)); } diff --git a/src/lib/film.h b/src/lib/film.h index f0a85fbf3..63a86bc43 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -134,7 +134,6 @@ public: AB, AUDIO_GAIN, AUDIO_DELAY, - SUBTITLE_STREAM, WITH_SUBTITLES, SUBTITLE_OFFSET, SUBTITLE_SCALE, diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 7930d86ce..67ebf49d0 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -592,14 +592,6 @@ FilmEditor::film_changed (Film::Property p) case Film::TRUST_CONTENT_HEADERS: checked_set (_trust_content_headers, _film->trust_content_headers ()); break; -// case Film::SUBTITLE_STREAMS: -// setup_subtitle_control_sensitivity (); -// setup_streams (); -// break; -// case Film::CONTENT_AUDIO_STREAMS: -// setup_streams (); -// setup_show_audio_sensitivity (); -// break; case Film::FORMAT: { int n = 0; @@ -648,27 +640,13 @@ FilmEditor::film_changed (Film::Property p) // s << fixed << setprecision(2) << _film->source_frame_rate(); // _source_frame_rate->SetLabel (std_to_wx (s.str ())); // break; -// case Film::SIZE: +// case Film::VIDEO_SIZE: // if (_film->size().width == 0 && _film->size().height == 0) { // _original_size->SetLabel (wxT ("")); // } else { // s << _film->size().width << " x " << _film->size().height; // _original_size->SetLabel (std_to_wx (s.str ())); // } -// break; -// case Film::LENGTH: -// if (_film->source_frame_rate() > 0 && _film->length()) { -// s << _film->length().get() << " " -// << wx_to_std (_("frames")) << "; " << seconds_to_hms (_film->length().get() / _film->source_frame_rate()); -// } else if (_film->length()) { -// s << _film->length().get() << " " -// << wx_to_std (_("frames")); -// } -// _length->SetLabel (std_to_wx (s.str ())); -// if (_film->length()) { -// _trim_start->SetRange (0, _film->length().get()); -// _trim_end->SetRange (0, _film->length().get()); -// } // break; case Film::DCP_CONTENT_TYPE: checked_set (_dcp_content_type, DCPContentType::as_index (_film->dcp_content_type ())); @@ -729,26 +707,53 @@ FilmEditor::film_changed (Film::Property p) // checked_set (_subtitle_stream, _film->subtitle_stream()->to_string()); // } // break; -// case Film::DCP_FRAME_RATE: -// for (unsigned int i = 0; i < _dcp_frame_rate->GetCount(); ++i) { -// if (wx_to_std (_dcp_frame_rate->GetString(i)) == boost::lexical_cast (_film->dcp_frame_rate())) { -// if (_dcp_frame_rate->GetSelection() != int(i)) { -// _dcp_frame_rate->SetSelection (i); -// break; -// } -// } -// } + case Film::DCP_FRAME_RATE: + for (unsigned int i = 0; i < _dcp_frame_rate->GetCount(); ++i) { + if (wx_to_std (_dcp_frame_rate->GetString(i)) == boost::lexical_cast (_film->dcp_frame_rate())) { + if (_dcp_frame_rate->GetSelection() != int(i)) { + _dcp_frame_rate->SetSelection (i); + break; + } + } + } -// if (_film->source_frame_rate()) { -// _frame_rate_description->SetLabel (std_to_wx (FrameRateConversion (_film->source_frame_rate(), _film->dcp_frame_rate()).description)); -// _best_dcp_frame_rate->Enable (best_dcp_frame_rate (_film->source_frame_rate ()) != _film->dcp_frame_rate ()); -// } else { -// _frame_rate_description->SetLabel (wxT ("")); -// _best_dcp_frame_rate->Disable (); -// } + if (_film->video_frame_rate()) { + _frame_rate_description->SetLabel (std_to_wx (FrameRateConversion (_film->video_frame_rate(), _film->dcp_frame_rate()).description)); + _best_dcp_frame_rate->Enable (best_dcp_frame_rate (_film->video_frame_rate ()) != _film->dcp_frame_rate ()); + } else { + _frame_rate_description->SetLabel (wxT ("")); + _best_dcp_frame_rate->Disable (); + } } } +void +FilmEditor::film_content_changed (int p) +{ + if (p == FFmpegContentProperty::SUBTITLE_STREAMS) { + setup_subtitle_control_sensitivity (); + setup_streams (); + } else if (p == FFmpegContentProperty::AUDIO_STREAMS) { + setup_streams (); + setup_show_audio_sensitivity (); + } else if (p == VideoContentProperty::VIDEO_LENGTH) { + stringstream s; + if (_film->video_frame_rate() > 0 && _film->video_length()) { + s << _film->video_length() << " " + << wx_to_std (_("frames")) << "; " << seconds_to_hms (_film->video_length() / _film->video_frame_rate()); + } else if (_film->video_length()) { + s << _film->video_length() << " " + << wx_to_std (_("frames")); + } + _length->SetLabel (std_to_wx (s.str ())); + if (_film->video_length()) { + _trim_start->SetRange (0, _film->video_length()); + _trim_end->SetRange (0, _film->video_length()); + } + } +} + + /** Called when the format widget has been changed */ void FilmEditor::format_changed (wxCommandEvent &) @@ -788,6 +793,7 @@ FilmEditor::set_film (shared_ptr f) if (_film) { _film->Changed.connect (bind (&FilmEditor::film_changed, this, _1)); + _film->ContentChanged.connect (bind (&FilmEditor::film_content_changed, this, _1)); } if (_film) { diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index 80072d48a..e01ab8ccc 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -90,6 +90,7 @@ private: /* Handle changes to the model */ void film_changed (Film::Property); + void film_content_changed (int); /* Button clicks */ void edit_filters_clicked (wxCommandEvent &); diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 9cf479508..0c03a9998 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -36,6 +36,7 @@ #include "lib/filter.h" #include "lib/playlist.h" #include "lib/video_content.h" +#include "lib/ffmpeg_content.h" #include "film_viewer.h" #include "wx_util.h" #include "video_decoder.h" @@ -161,7 +162,7 @@ FilmViewer::set_film (shared_ptr f) film_changed (Film::WITH_SUBTITLES); film_changed (Film::SUBTITLE_OFFSET); film_changed (Film::SUBTITLE_SCALE); - film_changed (Film::SUBTITLE_STREAM); + film_content_changed (FFmpegContentProperty::SUBTITLE_STREAM); } void -- cgit v1.2.3 From 7ebb57db2013c9e929d44d0e547ab1f27c59cc7f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 2 Apr 2013 23:33:46 +0100 Subject: Add basic content information, and some other bits. --- src/lib/content.h | 1 + src/lib/ffmpeg_content.cc | 12 +++++ src/lib/ffmpeg_content.h | 1 + src/lib/film.cc | 2 +- src/lib/imagemagick_content.cc | 1 + src/lib/sndfile_content.cc | 6 +++ src/lib/sndfile_content.h | 1 + src/lib/video_content.cc | 20 +++++++++ src/lib/video_content.h | 1 + src/wx/film_editor.cc | 99 +++++++++++++++++++++++++----------------- src/wx/film_editor.h | 3 ++ 11 files changed, 106 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/lib/content.h b/src/lib/content.h index 3f348ca91..11c7438a6 100644 --- a/src/lib/content.h +++ b/src/lib/content.h @@ -41,6 +41,7 @@ public: virtual void examine (boost::shared_ptr, boost::shared_ptr, bool); virtual std::string summary () const = 0; + virtual std::string information () const = 0; virtual void as_xml (xmlpp::Node *) const; virtual boost::shared_ptr clone () const = 0; diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index 5bff1cecc..c6344d567 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -28,6 +28,7 @@ #include "i18n.h" using std::string; +using std::stringstream; using std::vector; using std::list; using boost::shared_ptr; @@ -162,6 +163,17 @@ FFmpegContent::summary () const return String::compose (_("Movie: %1"), file().filename ()); } +string +FFmpegContent::information () const +{ + stringstream s; + + s << String::compose (_("%1 frames; %2 frames per second"), video_length(), video_frame_rate()) << "\n"; + s << VideoContent::information (); + + return s.str (); +} + void FFmpegContent::set_subtitle_stream (FFmpegSubtitleStream s) { diff --git a/src/lib/ffmpeg_content.h b/src/lib/ffmpeg_content.h index 598ebf484..3d69a2f99 100644 --- a/src/lib/ffmpeg_content.h +++ b/src/lib/ffmpeg_content.h @@ -86,6 +86,7 @@ public: void examine (boost::shared_ptr, boost::shared_ptr, bool); std::string summary () const; + std::string information () const; void as_xml (xmlpp::Node *) const; boost::shared_ptr clone () const; diff --git a/src/lib/film.cc b/src/lib/film.cc index d58f7fd53..f71180157 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -95,7 +95,7 @@ Film::Film (string d, bool must_exist) , _use_dci_name (true) , _trust_content_headers (true) , _dcp_content_type (0) - , _format (0) + , _format (Format::from_id ("185")) , _scaler (Scaler::from_id ("bicubic")) , _trim_start (0) , _trim_end (0) diff --git a/src/lib/imagemagick_content.cc b/src/lib/imagemagick_content.cc index 5ad94db45..f7c76a34d 100644 --- a/src/lib/imagemagick_content.cc +++ b/src/lib/imagemagick_content.cc @@ -25,6 +25,7 @@ #include "i18n.h" using std::string; +using std::stringstream; using boost::shared_ptr; ImageMagickContent::ImageMagickContent (boost::filesystem::path f) diff --git a/src/lib/sndfile_content.cc b/src/lib/sndfile_content.cc index 657e7d519..cf7921a93 100644 --- a/src/lib/sndfile_content.cc +++ b/src/lib/sndfile_content.cc @@ -27,6 +27,12 @@ SndfileContent::summary () const return String::compose (_("Sound file: %1"), file().filename ()); } +string +SndfileContent::information () const +{ + return ""; +} + int SndfileContent::audio_channels () const { diff --git a/src/lib/sndfile_content.h b/src/lib/sndfile_content.h index 81a964ec8..ab8a04e4d 100644 --- a/src/lib/sndfile_content.h +++ b/src/lib/sndfile_content.h @@ -11,6 +11,7 @@ public: SndfileContent (boost::shared_ptr); std::string summary () const; + std::string information () const; boost::shared_ptr clone () const; /* AudioContent */ diff --git a/src/lib/video_content.cc b/src/lib/video_content.cc index f48813f60..edb713466 100644 --- a/src/lib/video_content.cc +++ b/src/lib/video_content.cc @@ -2,11 +2,15 @@ #include "video_content.h" #include "video_decoder.h" +#include "i18n.h" + int const VideoContentProperty::VIDEO_LENGTH = 0; int const VideoContentProperty::VIDEO_SIZE = 1; int const VideoContentProperty::VIDEO_FRAME_RATE = 2; using std::string; +using std::stringstream; +using std::setprecision; using boost::shared_ptr; using boost::lexical_cast; @@ -61,3 +65,19 @@ VideoContent::take_from_video_decoder (shared_ptr d) Changed (VideoContentProperty::VIDEO_SIZE); Changed (VideoContentProperty::VIDEO_FRAME_RATE); } + + +string +VideoContent::information () const +{ + stringstream s; + + s << String::compose ( + _("%1x%2 pixels (%3:1)"), + video_size().width, + video_size().height, + setprecision (3), float (video_size().width) / video_size().height + ); + + return s.str (); +} diff --git a/src/lib/video_content.h b/src/lib/video_content.h index 25cb28938..19b49e926 100644 --- a/src/lib/video_content.h +++ b/src/lib/video_content.h @@ -22,6 +22,7 @@ public: VideoContent (VideoContent const &); void as_xml (xmlpp::Node *) const; + virtual std::string information () const; ContentVideoFrame video_length () const { boost::mutex::scoped_lock lm (_mutex); diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 67ebf49d0..d354e6e5a 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -331,11 +331,6 @@ FilmEditor::make_content_panel () _content_sizer = new wxBoxSizer (wxVERTICAL); _content_panel->SetSizer (_content_sizer); - wxGridBagSizer* grid = new wxGridBagSizer (4, 4); - _content_sizer->Add (grid, 0, wxALL, 8); - - int r = 0; - { wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); @@ -357,9 +352,11 @@ FilmEditor::make_content_panel () s->Add (b, 0, wxALL, 4); - grid->Add (s, wxGBPosition (r, 0), wxGBSpan (1, 2), wxEXPAND); - ++r; + _content_sizer->Add (s, 1, wxEXPAND | wxALL, 6); } + + _content_information = new wxTextCtrl (_content_panel, wxID_ANY, wxT ("\n\n\n\n"), wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxTE_MULTILINE); + _content_sizer->Add (_content_information, 1, wxEXPAND | wxALL, 6); } void @@ -585,35 +582,18 @@ FilmEditor::film_changed (Film::Property p) case Film::CONTENT: setup_content (); setup_formats (); + setup_format (); setup_subtitle_control_sensitivity (); setup_streams (); setup_show_audio_sensitivity (); + setup_length (); break; case Film::TRUST_CONTENT_HEADERS: checked_set (_trust_content_headers, _film->trust_content_headers ()); break; case Film::FORMAT: - { - int n = 0; - vector::iterator i = _formats.begin (); - while (i != _formats.end() && *i != _film->format ()) { - ++i; - ++n; - } - if (i == _formats.end()) { - checked_set (_format, -1); - } else { - checked_set (_format, n); - } - setup_dcp_name (); - - if (_film->format ()) { - _format_description->SetLabel (std_to_wx (_film->format()->description ())); - } else { - _format_description->SetLabel (wxT ("")); - } + setup_format (); break; - } case Film::CROP: checked_set (_left_crop, _film->crop().left); checked_set (_right_crop, _film->crop().right); @@ -737,22 +717,51 @@ FilmEditor::film_content_changed (int p) setup_streams (); setup_show_audio_sensitivity (); } else if (p == VideoContentProperty::VIDEO_LENGTH) { - stringstream s; - if (_film->video_frame_rate() > 0 && _film->video_length()) { - s << _film->video_length() << " " - << wx_to_std (_("frames")) << "; " << seconds_to_hms (_film->video_length() / _film->video_frame_rate()); - } else if (_film->video_length()) { - s << _film->video_length() << " " - << wx_to_std (_("frames")); - } - _length->SetLabel (std_to_wx (s.str ())); - if (_film->video_length()) { - _trim_start->SetRange (0, _film->video_length()); - _trim_end->SetRange (0, _film->video_length()); - } + setup_length (); } } +void +FilmEditor::setup_format () +{ + int n = 0; + vector::iterator i = _formats.begin (); + while (i != _formats.end() && *i != _film->format ()) { + ++i; + ++n; + } + if (i == _formats.end()) { + checked_set (_format, -1); + } else { + checked_set (_format, n); + } + setup_dcp_name (); + + if (_film->format ()) { + _format_description->SetLabel (std_to_wx (_film->format()->description ())); + } else { + _format_description->SetLabel (wxT ("")); + } +} + +void +FilmEditor::setup_length () +{ + stringstream s; + if (_film->video_frame_rate() > 0 && _film->video_length()) { + s << _film->video_length() << " " + << wx_to_std (_("frames")) << "; " << seconds_to_hms (_film->video_length() / _film->video_frame_rate()); + } else if (_film->video_length()) { + s << _film->video_length() << " " + << wx_to_std (_("frames")); + } + _length->SetLabel (std_to_wx (s.str ())); + if (_film->video_length()) { + _trim_start->SetRange (0, _film->video_length()); + _trim_end->SetRange (0, _film->video_length()); + } +} + /** Called when the format widget has been changed */ void @@ -1227,6 +1236,16 @@ void FilmEditor::content_item_selected (wxListEvent &) { setup_content_button_sensitivity (); + + int const s = _content->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (s == -1) { + _content_information->SetValue (""); + return; + } + + ContentList c = _film->content (); + assert (s >= 0 && size_t (s) < c.size ()); + _content_information->SetValue (std_to_wx (c[s]->information ())); } void diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index e01ab8ccc..311f8ceaa 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -104,6 +104,8 @@ private: void setup_show_audio_sensitivity (); void setup_content (); void setup_content_button_sensitivity (); + void setup_length (); + void setup_format (); void active_jobs_changed (bool); @@ -130,6 +132,7 @@ private: wxButton* _content_remove; wxButton* _content_earlier; wxButton* _content_later; + wxTextCtrl* _content_information; wxButton* _edit_dci_button; wxChoice* _format; wxStaticText* _format_description; -- cgit v1.2.3 From 9c3e4462d32c726a6c257b0a40e642ab23d9526a Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 3 Apr 2013 00:27:09 +0100 Subject: Make subs work again (sort of). --- src/lib/ffmpeg_decoder.cc | 2 +- src/lib/film.cc | 24 ++++++++++++ src/lib/film.h | 6 +++ src/lib/playlist.cc | 57 +++++++++++++++++++++++++-- src/lib/playlist.h | 6 +++ src/wx/film_editor.cc | 99 +++++++++++++++++++++++------------------------ src/wx/film_editor.h | 2 +- src/wx/film_viewer.cc | 6 ++- 8 files changed, 145 insertions(+), 57 deletions(-) (limited to 'src') diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index ced9b95e9..3a185bd6a 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -122,7 +122,7 @@ FFmpegDecoder::setup_general () throw DecodeError (_("could not find stream information")); } - /* Find video, audio and subtitle streams and choose the first of each */ + /* Find video, audio and subtitle streams */ for (uint32_t i = 0; i < _format_context->nb_streams; ++i) { AVStream* s = _format_context->streams[i]; diff --git a/src/lib/film.cc b/src/lib/film.cc index f71180157..091b35d47 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -1161,6 +1161,30 @@ Film::video_length () const return _playlist->video_length (); } +vector +Film::ffmpeg_subtitle_streams () const +{ + return _playlist->ffmpeg_subtitle_streams (); +} + +boost::optional +Film::ffmpeg_subtitle_stream () const +{ + return _playlist->ffmpeg_subtitle_stream (); +} + +vector +Film::ffmpeg_audio_streams () const +{ + return _playlist->ffmpeg_audio_streams (); +} + +boost::optional +Film::ffmpeg_audio_stream () const +{ + return _playlist->ffmpeg_audio_stream (); +} + void Film::content_changed (int p) { diff --git a/src/lib/film.h b/src/lib/film.h index 63a86bc43..e71fe2606 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -39,6 +39,7 @@ extern "C" { #include "util.h" #include "dci_metadata.h" #include "types.h" +#include "ffmpeg_content.h" class Format; class Job; @@ -114,6 +115,11 @@ public: libdcp::Size video_size () const; ContentVideoFrame video_length () const; + std::vector ffmpeg_subtitle_streams () const; + boost::optional ffmpeg_subtitle_stream () const; + std::vector ffmpeg_audio_streams () const; + boost::optional ffmpeg_audio_stream () const; + /** Identifiers for the parts of our state; used for signalling changes. */ diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index 3822420da..0c29650b6 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -28,6 +28,7 @@ using std::list; using std::cout; +using std::vector; using boost::shared_ptr; using boost::dynamic_pointer_cast; @@ -47,7 +48,7 @@ Playlist::setup (ContentList content) _ffmpeg.reset (); _imagemagick.clear (); _sndfile.clear (); - + for (ContentList::const_iterator i = content.begin(); i != content.end(); ++i) { shared_ptr fc = dynamic_pointer_cast (*i); if (fc) { @@ -206,6 +207,46 @@ Playlist::has_audio () const return _audio_from != AUDIO_NONE; } +vector +Playlist::ffmpeg_subtitle_streams () const +{ + if (_video_from != VIDEO_FFMPEG || !_ffmpeg) { + return vector (); + } + + return _ffmpeg->subtitle_streams (); +} + +boost::optional +Playlist::ffmpeg_subtitle_stream () const +{ + if (_video_from != VIDEO_FFMPEG || !_ffmpeg) { + return boost::none; + } + + return _ffmpeg->subtitle_stream (); +} + +vector +Playlist::ffmpeg_audio_streams () const +{ + if (_video_from != VIDEO_FFMPEG || !_ffmpeg) { + return vector (); + } + + return _ffmpeg->audio_streams (); +} + +boost::optional +Playlist::ffmpeg_audio_stream () const +{ + if (_video_from != VIDEO_FFMPEG || !_ffmpeg) { + return boost::none; + } + + return _ffmpeg->audio_stream (); +} + Player::Player (boost::shared_ptr f, boost::shared_ptr p) : _film (f) , _playlist (p) @@ -296,13 +337,18 @@ Player::process_audio (shared_ptr b) bool Player::seek (double t) { + if (!_have_setup_decoders) { + setup_decoders (); + _have_setup_decoders = true; + } + bool r = false; switch (_playlist->video_from()) { case Playlist::VIDEO_NONE: break; case Playlist::VIDEO_FFMPEG: - if (_ffmpeg_decoder->seek (t)) { + if (!_ffmpeg_decoder || _ffmpeg_decoder->seek (t)) { r = true; } break; @@ -334,13 +380,18 @@ Player::seek (double t) bool Player::seek_to_last () { + if (!_have_setup_decoders) { + setup_decoders (); + _have_setup_decoders = true; + } + bool r = false; switch (_playlist->video_from ()) { case Playlist::VIDEO_NONE: break; case Playlist::VIDEO_FFMPEG: - if (_ffmpeg_decoder->seek_to_last ()) { + if (!_ffmpeg_decoder || _ffmpeg_decoder->seek_to_last ()) { r = true; } break; diff --git a/src/lib/playlist.h b/src/lib/playlist.h index 403fb58d4..c461151d4 100644 --- a/src/lib/playlist.h +++ b/src/lib/playlist.h @@ -24,6 +24,7 @@ #include "audio_source.h" #include "video_sink.h" #include "audio_sink.h" +#include "ffmpeg_content.h" class Content; class FFmpegContent; @@ -52,6 +53,11 @@ public: libdcp::Size video_size () const; ContentVideoFrame video_length () const; + std::vector ffmpeg_subtitle_streams () const; + boost::optional ffmpeg_subtitle_stream () const; + std::vector ffmpeg_audio_streams () const; + boost::optional ffmpeg_audio_stream () const; + enum VideoFrom { VIDEO_NONE, VIDEO_FFMPEG, diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index d354e6e5a..5143bd370 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -150,11 +150,6 @@ FilmEditor::make_film_panel () _frame_rate_description->SetFont(font); ++r; - add_label_to_grid_bag_sizer (grid, _film_panel, _("Original Size"), wxGBPosition (r, 0)); - _original_size = new wxStaticText (_film_panel, wxID_ANY, wxT ("")); - grid->Add (_original_size, wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); - ++r; - add_label_to_grid_bag_sizer (grid, _film_panel, _("Length"), wxGBPosition (r, 0)); _length = new wxStaticText (_film_panel, wxID_ANY, wxT ("")); grid->Add (_length, wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); @@ -220,8 +215,8 @@ FilmEditor::connect_to_widgets () _subtitle_scale->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::subtitle_scale_changed), 0, this); _colour_lut->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::colour_lut_changed), 0, this); _j2k_bandwidth->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::j2k_bandwidth_changed), 0, this); -// _ffmpeg_subtitle_stream->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::ffmpeg_subtitle_stream_changed), 0, this); -// _ffmpeg_audio_stream->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::ffmpeg_audio_stream_changed), 0, this); + _ffmpeg_subtitle_stream->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::ffmpeg_subtitle_stream_changed), 0, this); + _ffmpeg_audio_stream->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::ffmpeg_audio_stream_changed), 0, this); _audio_gain->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::audio_gain_changed), 0, this); _audio_gain_calculate_button->Connect ( wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::audio_gain_calculate_button_clicked), 0, this @@ -394,6 +389,16 @@ FilmEditor::make_audio_panel () grid->Add (s); } + { + add_label_to_sizer (grid, _audio_panel, _("Audio Stream")); + wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); + _ffmpeg_audio_stream = new wxChoice (_audio_panel, wxID_ANY); + s->Add (_ffmpeg_audio_stream, 1); + _audio = new wxStaticText (_audio_panel, wxID_ANY, wxT ("")); + s->Add (_audio, 1, wxALIGN_CENTER_VERTICAL | wxLEFT, 8); + grid->Add (s, 1, wxEXPAND); + } + _audio_gain->SetRange (-60, 60); _audio_delay->SetRange (-1000, 1000); } @@ -616,18 +621,6 @@ FilmEditor::film_changed (Film::Property p) checked_set (_name, _film->name()); setup_dcp_name (); break; -// case Film::SOURCE_FRAME_RATE: -// s << fixed << setprecision(2) << _film->source_frame_rate(); -// _source_frame_rate->SetLabel (std_to_wx (s.str ())); -// break; -// case Film::VIDEO_SIZE: -// if (_film->size().width == 0 && _film->size().height == 0) { -// _original_size->SetLabel (wxT ("")); -// } else { -// s << _film->size().width << " x " << _film->size().height; -// _original_size->SetLabel (std_to_wx (s.str ())); -// } -// break; case Film::DCP_CONTENT_TYPE: checked_set (_dcp_content_type, DCPContentType::as_index (_film->dcp_content_type ())); setup_dcp_name (); @@ -674,19 +667,6 @@ FilmEditor::film_changed (Film::Property p) case Film::DCI_METADATA: setup_dcp_name (); break; -// case Film::CONTENT_AUDIO_STREAM: -// if (_film->content_audio_stream()) { -// checked_set (_audio_stream, _film->content_audio_stream()->to_string()); -// } -// setup_dcp_name (); -// setup_audio_details (); -// setup_show_audio_sensitivity (); -// break; -// case Film::SUBTITLE_STREAM: -// if (_film->subtitle_stream()) { -// checked_set (_subtitle_stream, _film->subtitle_stream()->to_string()); -// } -// break; case Film::DCP_FRAME_RATE: for (unsigned int i = 0; i < _dcp_frame_rate->GetCount(); ++i) { if (wx_to_std (_dcp_frame_rate->GetString(i)) == boost::lexical_cast (_film->dcp_frame_rate())) { @@ -718,6 +698,17 @@ FilmEditor::film_content_changed (int p) setup_show_audio_sensitivity (); } else if (p == VideoContentProperty::VIDEO_LENGTH) { setup_length (); + } else if (p == FFmpegContentProperty::AUDIO_STREAM) { + if (_film->ffmpeg_audio_stream()) { + checked_set (_ffmpeg_audio_stream, _film->ffmpeg_audio_stream()->id); + } + setup_dcp_name (); + setup_audio_details (); + setup_show_audio_sensitivity (); + } else if (p == FFmpegContentProperty::SUBTITLE_STREAM) { + if (_film->ffmpeg_subtitle_stream()) { + checked_set (_ffmpeg_subtitle_stream, _film->ffmpeg_subtitle_stream()->id); + } } } @@ -836,6 +827,11 @@ FilmEditor::set_film (shared_ptr f) film_changed (Film::J2K_BANDWIDTH); film_changed (Film::DCI_METADATA); film_changed (Film::DCP_FRAME_RATE); + + film_content_changed (FFmpegContentProperty::SUBTITLE_STREAMS); + film_content_changed (FFmpegContentProperty::SUBTITLE_STREAM); + film_content_changed (FFmpegContentProperty::AUDIO_STREAMS); + film_content_changed (FFmpegContentProperty::AUDIO_STREAM); } /** Updates the sensitivity of lots of widgets to a given value. @@ -859,7 +855,7 @@ FilmEditor::set_things_sensitive (bool s) _bottom_crop->Enable (s); _filters_button->Enable (s); _scaler->Enable (s); -// _ffmpeg_audio_stream->Enable (s); + _ffmpeg_audio_stream->Enable (s); _dcp_content_type->Enable (s); _dcp_frame_rate->Enable (s); _trim_start->Enable (s); @@ -996,7 +992,7 @@ FilmEditor::setup_subtitle_control_sensitivity () { bool h = false; if (_generally_sensitive && _film) { -// h = !_film->subtitle_streams().empty(); + h = !_film->ffmpeg_subtitle_streams().empty(); } _with_subtitles->Enable (h); @@ -1037,26 +1033,27 @@ FilmEditor::edit_dci_button_clicked (wxCommandEvent &) void FilmEditor::setup_streams () { -// _ffmpeg_audio_stream->Clear (); - vector a;// = _film->content_audio_streams (); -// for (vector::iterator i = a.begin(); i != a.end(); ++i) { -// _audio_stream->Append (std_to_wx (ffa->name()), new wxStringClientData (std_to_wx (i->to_string ()))); -// } + _ffmpeg_audio_stream->Clear (); + vector a = _film->ffmpeg_audio_streams (); + for (vector::iterator i = a.begin(); i != a.end(); ++i) { + _ffmpeg_audio_stream->Append (std_to_wx (i->name), new wxStringClientData (std_to_wx (boost::lexical_cast (i->id)))); + } -// if (_film->use_content_audio() && _film->audio_stream()) { -// checked_set (_audio_stream, _film->audio_stream()->to_string()); -// } + if (_film->ffmpeg_audio_stream()) { + checked_set (_ffmpeg_audio_stream, boost::lexical_cast (_film->ffmpeg_audio_stream()->id)); + } _ffmpeg_subtitle_stream->Clear (); -// vector > s = _film->subtitle_streams (); -// for (vector >::iterator i = s.begin(); i != s.end(); ++i) { -// _subtitle_stream->Append (std_to_wx ((*i)->name()), new wxStringClientData (std_to_wx ((*i)->to_string ()))); -// } -// if (_film->subtitle_stream()) { -// checked_set (_subtitle_stream, _film->subtitle_stream()->to_string()); -// } else { -// _subtitle_stream->SetSelection (wxNOT_FOUND); -// } + vector s = _film->ffmpeg_subtitle_streams (); + for (vector::iterator i = s.begin(); i != s.end(); ++i) { + _ffmpeg_subtitle_stream->Append (std_to_wx (i->name), new wxStringClientData (std_to_wx (boost::lexical_cast (i->id)))); + } + + if (_film->ffmpeg_subtitle_stream()) { + checked_set (_ffmpeg_subtitle_stream, boost::lexical_cast (_film->ffmpeg_subtitle_stream()->id)); + } else { + _ffmpeg_subtitle_stream->SetSelection (wxNOT_FOUND); + } } void diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index 311f8ceaa..60da2de4d 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -148,6 +148,7 @@ private: wxButton* _audio_gain_calculate_button; wxButton* _show_audio; wxSpinCtrl* _audio_delay; + wxChoice* _ffmpeg_audio_stream; wxCheckBox* _with_subtitles; wxChoice* _ffmpeg_subtitle_stream; wxSpinCtrl* _subtitle_offset; @@ -158,7 +159,6 @@ private: wxChoice* _dcp_frame_rate; wxButton* _best_dcp_frame_rate; wxStaticText* _frame_rate_description; - wxStaticText* _original_size; wxStaticText* _length; /** The Film's audio details */ wxStaticText* _audio; diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 0c03a9998..54ef28ff0 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -107,6 +107,8 @@ FilmViewer::film_changed (Film::Property p) break; } case Film::WITH_SUBTITLES: + setup_player (); + /* fall through */ case Film::SUBTITLE_OFFSET: case Film::SUBTITLE_SCALE: case Film::SCALER: @@ -124,7 +126,9 @@ FilmViewer::setup_player () { _player = _film->player (); _player->disable_audio (); - _player->disable_subtitles (); + if (!_film->with_subtitles ()) { + _player->disable_subtitles (); + } _player->disable_video_sync (); _player->Video.connect (bind (&FilmViewer::process_video, this, _1, _2, _3)); } -- cgit v1.2.3 From 62a37b990ee713935169a0e05f8e8c20c466c2b1 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 3 Apr 2013 00:51:22 +0100 Subject: es_ES updates from Manuel. --- src/lib/po/es_ES.po | 155 +++++++++++++++++------------------------------- src/wx/po/es_ES.po | 165 ++++++++++++++++++++++++---------------------------- 2 files changed, 130 insertions(+), 190 deletions(-) (limited to 'src') diff --git a/src/lib/po/es_ES.po b/src/lib/po/es_ES.po index abf75d4ba..153a90085 100644 --- a/src/lib/po/es_ES.po +++ b/src/lib/po/es_ES.po @@ -7,15 +7,15 @@ msgid "" msgstr "" "Project-Id-Version: LIBDVDOMATIC\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-01 21:21+0100\n" -"PO-Revision-Date: 2013-03-23 22:42-0500\n" +"POT-Creation-Date: 2013-03-15 08:39+0000\n" +"PO-Revision-Date: 2013-04-02 19:10-0500\n" "Last-Translator: Manuel AC \n" "Language-Team: Manuel AC \n" -"Language: es-ES\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" +"Language: es-ES\n" #: src/lib/transcode_job.cc:87 msgid "0%" @@ -69,7 +69,7 @@ msgstr "Academy" msgid "Advertisement" msgstr "Publicidad" -#: src/lib/job.cc:72 +#: src/lib/job.cc:71 msgid "An error occurred whilst handling the file %1." msgstr "Ha ocurrido un error con el fichero %1." @@ -89,23 +89,11 @@ msgstr "Bicúbico" msgid "Bilinear" msgstr "Bilineal" -#: src/lib/job.cc:302 -msgid "Cancelled" -msgstr "" - -#: src/lib/exceptions.cc:60 -msgid "Cannot handle pixel format %1 during %2" -msgstr "" - #: src/lib/encoder.cc:101 msgid "Cannot resample audio as libswresample is not present" msgstr "" "No se puede redimensionar el sonido porque no se encuentra libswresample" -#: src/lib/util.cc:931 -msgid "Centre" -msgstr "" - #: src/lib/scp_dcp_job.cc:109 msgid "Copy DCP to TMS" msgstr "Copiar DCP al TMS" @@ -134,22 +122,22 @@ msgstr "No se pudo escribir el fichero remoto (%1)" msgid "Cubic interpolating deinterlacer" msgstr "Desentrelazado por interpolación cúbica" -#: src/lib/util.cc:1006 +#: src/lib/util.cc:965 msgid "DCP and source have the same rate.\n" msgstr "La fuente y el DCP tienen la misma velocidad.\n" -#: src/lib/util.cc:1016 +#: src/lib/util.cc:975 msgid "DCP will run at %1%% of the source speed." msgstr "El DCP se reproducirá al %1%% de la velocidad de la fuente." -#: src/lib/util.cc:1009 +#: src/lib/util.cc:968 msgid "DCP will use every other frame of the source.\n" msgstr "El DCP usará fotogramas alternos de la fuente.\n" #: src/lib/filter.cc:68 src/lib/filter.cc:69 src/lib/filter.cc:70 #: src/lib/filter.cc:71 src/lib/filter.cc:72 src/lib/filter.cc:73 msgid "De-blocking" -msgstr "" +msgstr "De-blocking" #: src/lib/filter.cc:75 src/lib/filter.cc:76 src/lib/filter.cc:77 #: src/lib/filter.cc:78 src/lib/filter.cc:79 src/lib/filter.cc:80 @@ -159,17 +147,17 @@ msgstr "Desentrelazado" #: src/lib/filter.cc:74 msgid "Deringing filter" -msgstr "" +msgstr "Deringing filter" #: src/lib/dolby_cp750.cc:27 msgid "Dolby CP750" msgstr "Dolby CP750" -#: src/lib/util.cc:1011 +#: src/lib/util.cc:970 msgid "Each source frame will be doubled in the DCP.\n" msgstr "Se doblará cada fotograma de la fuente en el DCP.\n" -#: src/lib/job.cc:300 +#: src/lib/job.cc:287 msgid "Error (%1)" msgstr "Error (%1)" @@ -183,11 +171,11 @@ msgstr "Examinar contenido de %1" #: src/lib/filter.cc:72 msgid "Experimental horizontal deblocking filter 1" -msgstr "" +msgstr "Experimental horizontal deblocking filter 1" #: src/lib/filter.cc:73 msgid "Experimental vertical deblocking filter 1" -msgstr "" +msgstr "Experimental vertical deblocking filter 1" #: src/lib/filter.cc:79 msgid "FFMPEG deinterlacer" @@ -219,7 +207,7 @@ msgstr "Flat sin deformación" #: src/lib/filter.cc:85 msgid "Force quantizer" -msgstr "" +msgstr "Force quantizer" #: src/lib/scaler.cc:65 msgid "Gaussian" @@ -227,7 +215,7 @@ msgstr "Gaussiano" #: src/lib/filter.cc:86 msgid "Gradient debander" -msgstr "" +msgstr "Gradient debander" #: src/lib/filter.cc:89 msgid "High quality 3D denoiser" @@ -235,13 +223,13 @@ msgstr "Reductor de ruido 3D de alta calidad" #: src/lib/filter.cc:68 msgid "Horizontal deblocking filter" -msgstr "" +msgstr "Horizontal deblocking filter" #: src/lib/filter.cc:70 msgid "Horizontal deblocking filter A" -msgstr "" +msgstr "Horizontal deblocking filter A" -#: src/lib/job.cc:92 src/lib/job.cc:101 +#: src/lib/job.cc:87 src/lib/job.cc:96 msgid "" "It is not known what caused this error. The best idea is to report the " "problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" @@ -251,35 +239,23 @@ msgstr "" #: src/lib/filter.cc:82 msgid "Kernel deinterlacer" -msgstr "" +msgstr "Kernel deinterlacer" #: src/lib/scaler.cc:66 msgid "Lanczos" msgstr "Lanczos" -#: src/lib/util.cc:929 -msgid "Left" -msgstr "" - -#: src/lib/util.cc:933 -msgid "Left surround" -msgstr "" - -#: src/lib/util.cc:932 -msgid "Lfe (sub)" -msgstr "" - #: src/lib/filter.cc:75 msgid "Linear blend deinterlacer" -msgstr "" +msgstr "Linear blend deinterlacer" #: src/lib/filter.cc:76 msgid "Linear interpolating deinterlacer" -msgstr "" +msgstr "Linear interpolating deinterlacer" #: src/lib/filter.cc:78 msgid "Median deinterlacer" -msgstr "" +msgstr "Median deinterlacer" #: src/lib/filter.cc:74 src/lib/filter.cc:85 src/lib/filter.cc:86 #: src/lib/filter.cc:87 src/lib/filter.cc:90 @@ -288,24 +264,24 @@ msgstr "Miscelánea" #: src/lib/filter.cc:81 msgid "Motion compensating deinterlacer" -msgstr "" +msgstr "Motion compensating deinterlacer" #: src/lib/filter.cc:84 src/lib/filter.cc:88 src/lib/filter.cc:89 #: src/lib/filter.cc:91 msgid "Noise reduction" msgstr "Reducción de ruido" -#: src/lib/job.cc:298 +#: src/lib/job.cc:285 msgid "OK (ran for %1)" msgstr "OK (ejecución %1)" #: src/lib/filter.cc:91 msgid "Overcomplete wavelet denoiser" -msgstr "" +msgstr "Overcomplete wavelet denoiser" #: src/lib/dcp_content_type.cc:51 msgid "Policy" -msgstr "" +msgstr "Policy" #: src/lib/dcp_content_type.cc:52 msgid "Public Service Announcement" @@ -315,18 +291,10 @@ msgstr "Anuncio de servicio público" msgid "Rating" msgstr "Clasificación" -#: src/lib/util.cc:499 +#: src/lib/util.cc:458 msgid "Rec 709" msgstr "Rec 709" -#: src/lib/util.cc:930 -msgid "Right" -msgstr "" - -#: src/lib/util.cc:934 -msgid "Right surround" -msgstr "" - #: src/lib/scp_dcp_job.cc:133 msgid "SSH error (%1)" msgstr "error SSH (%1)" @@ -345,7 +313,7 @@ msgstr "Cortometraje" #: src/lib/scaler.cc:67 msgid "Sinc" -msgstr "" +msgstr "Sinc" #: src/lib/format.cc:76 msgid "Source scaled to 1.19:1" @@ -401,7 +369,7 @@ msgstr "Fuente escalada a Scope conservando el ratio de aspecto" #: src/lib/scaler.cc:68 msgid "Spline" -msgstr "" +msgstr "Spline" #: src/lib/dcp_content_type.cc:50 msgid "Teaser" @@ -413,13 +381,13 @@ msgstr "Filtro telecine" #: src/lib/filter.cc:84 msgid "Temporal noise reducer" -msgstr "" +msgstr "Temporal noise reducer" #: src/lib/dcp_content_type.cc:47 msgid "Test" msgstr "Test" -#: src/lib/job.cc:77 +#: src/lib/job.cc:76 msgid "" "The drive that the film is stored on is low in disc space. Free some more " "space and try again." @@ -439,7 +407,7 @@ msgstr "Codificar %1" msgid "Transitional" msgstr "Transitional" -#: src/lib/job.cc:100 +#: src/lib/job.cc:95 msgid "Unknown error" msgstr "Error desconocido" @@ -449,15 +417,15 @@ msgstr "Formato de audio desconocido (%1)" #: src/lib/filter.cc:87 msgid "Unsharp mask and Gaussian blur" -msgstr "" +msgstr "Máscara de desenfoque Gaussiano" #: src/lib/filter.cc:69 msgid "Vertical deblocking filter" -msgstr "" +msgstr "Vertical deblocking filter" #: src/lib/filter.cc:71 msgid "Vertical deblocking filter A" -msgstr "" +msgstr "Vertical deblocking filter A" #: src/lib/scp_dcp_job.cc:101 msgid "Waiting" @@ -469,13 +437,17 @@ msgstr "X" #: src/lib/filter.cc:83 msgid "Yet Another Deinterlacing Filter" -msgstr "" +msgstr "Yet Another Deinterlacing Filter" + +#: src/lib/encoder.cc:271 +msgid "adding to queue of %1" +msgstr "añadiendo a la cola de %1" #: src/lib/film.cc:263 msgid "cannot contain slashes" msgstr "no puede contener barras" -#: src/lib/util.cc:540 +#: src/lib/util.cc:499 msgid "connect timed out" msgstr "tiempo de conexión agotado" @@ -495,11 +467,6 @@ msgstr "tipo de contenido" msgid "copying %1" msgstr "copiando %1" -#: src/lib/exceptions.cc:36 -#, fuzzy -msgid "could not create file %1" -msgstr "No se pudo escribir el fichero remoto (%1)" - #: src/lib/ffmpeg_decoder.cc:191 msgid "could not find audio decoder" msgstr "no se encontró el decodificador de audio" @@ -516,24 +483,14 @@ msgstr "no se pudo encontrar decodificador de subtítutlos" msgid "could not find video decoder" msgstr "no se pudo encontrar decodificador de vídeo" -#: src/lib/sndfile_decoder.cc:72 +#: src/lib/external_audio_decoder.cc:72 msgid "could not open external audio file for reading" msgstr "no se pudo leer el fichero externo de audio" -#: src/lib/exceptions.cc:29 -#, fuzzy -msgid "could not open file %1" -msgstr "no se pudo abrir el fichero para lectura" - #: src/lib/dcp_video_frame.cc:388 msgid "could not open file for reading" msgstr "no se pudo abrir el fichero para lectura" -#: src/lib/exceptions.cc:44 -#, fuzzy -msgid "could not read from file %1 (%2)" -msgstr "No se pudo crear la carpeta remota %1 (%2)" - #: src/lib/encoder.cc:137 src/lib/encoder.cc:314 msgid "could not run sample-rate converter" msgstr "no se pudo ejecutar el conversor de velocidad" @@ -546,16 +503,19 @@ msgstr "no se pudo abrir la sesión SCP (%1)" msgid "could not start SSH session" msgstr "no se pudo abrir la sesión SSH" -#: src/lib/exceptions.cc:50 -#, fuzzy -msgid "could not write to file %1 (%2)" -msgstr "No se pudo escribir el fichero remoto (%1)" +#: src/lib/encoder.cc:247 +msgid "decoder sleeps with queue of %1" +msgstr "" + +#: src/lib/encoder.cc:249 +msgid "decoder wakes with queue of %1" +msgstr "" -#: src/lib/sndfile_decoder.cc:94 +#: src/lib/external_audio_decoder.cc:94 msgid "external audio files have differing lengths" msgstr "los ficheros externos de sonido tienen duraciones diferentes" -#: src/lib/sndfile_decoder.cc:76 +#: src/lib/external_audio_decoder.cc:76 msgid "external audio files must be mono" msgstr "los ficheros externos de sonido deben ser mono" @@ -583,14 +543,10 @@ msgstr "minuto" msgid "minutes" msgstr "minutos" -#: src/lib/util.cc:683 +#: src/lib/util.cc:642 msgid "missing key %1 in key-value set" msgstr "falta la clave %1 en el par clave-valor" -#: src/lib/exceptions.cc:54 -msgid "missing required setting %1" -msgstr "" - #: src/lib/subtitle.cc:52 msgid "multi-part subtitles not yet supported" msgstr "todavía no se soportan subtítulos en múltiples partes" @@ -609,11 +565,11 @@ msgstr "todavía no se soportan subtítulos que no son en mapas de bits" #. / TRANSLATORS: remaining here follows an amount of time that is remaining #. / on an operation. -#: src/lib/job.cc:295 +#: src/lib/job.cc:282 msgid "remaining" msgstr "pendiente" -#: src/lib/util.cc:497 +#: src/lib/util.cc:456 msgid "sRGB" msgstr "sRGB" @@ -628,6 +584,3 @@ msgstr "imagen fija" #: src/lib/film.cc:274 msgid "video" msgstr "vídeo" - -#~ msgid "adding to queue of %1" -#~ msgstr "añadiendo a la cola de %1" diff --git a/src/wx/po/es_ES.po b/src/wx/po/es_ES.po index 6c2c550cb..de0f93024 100644 --- a/src/wx/po/es_ES.po +++ b/src/wx/po/es_ES.po @@ -7,45 +7,41 @@ msgid "" msgstr "" "Project-Id-Version: libdvdomatic-wx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-01 21:21+0100\n" -"PO-Revision-Date: 2013-03-23 21:20-0500\n" +"POT-Creation-Date: 2013-03-15 08:39+0000\n" +"PO-Revision-Date: 2013-04-02 19:08-0500\n" "Last-Translator: Manuel AC \n" "Language-Team: Manuel AC \n" -"Language: es-ES\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" +"Language: es-ES\n" -#: src/wx/film_editor.cc:440 +#: src/wx/film_editor.cc:441 msgid "%" msgstr "%" -#: src/wx/config_dialog.cc:61 -msgid "(restart DVD-o-matic to see language changes)" -msgstr "" - -#: src/wx/film_editor.cc:1231 +#: src/wx/film_editor.cc:1230 msgid "1 channel" msgstr "1 canal" -#: src/wx/film_editor.cc:184 +#: src/wx/film_editor.cc:185 msgid "A/B" msgstr "A/B" -#: src/wx/config_dialog.cc:143 +#: src/wx/config_dialog.cc:124 msgid "Add" msgstr "Añadir" -#: src/wx/audio_dialog.cc:32 src/wx/film_editor.cc:77 +#: src/wx/audio_dialog.cc:32 src/wx/film_editor.cc:78 msgid "Audio" msgstr "Audio" -#: src/wx/film_editor.cc:381 +#: src/wx/film_editor.cc:382 msgid "Audio Delay" msgstr "Retardo del audio" -#: src/wx/film_editor.cc:369 +#: src/wx/film_editor.cc:370 msgid "Audio Gain" msgstr "Ganancia del audio" @@ -58,7 +54,7 @@ msgstr "Idioma del audio (ej. ES)" msgid "Bad setting for %s (%s)" msgstr "Configuración erronea para %s (%s)" -#: src/wx/film_editor.cc:296 +#: src/wx/film_editor.cc:297 msgid "Bottom crop" msgstr "Recortar abajo" @@ -70,27 +66,23 @@ msgstr "Explorar..." msgid "But I have to use fader" msgstr "pero tengo que usar el fader a" -#: src/wx/film_editor.cc:374 +#: src/wx/film_editor.cc:375 msgid "Calculate..." msgstr "Calcular..." -#: src/wx/job_manager_view.cc:88 -msgid "Cancel" -msgstr "" - #: src/wx/audio_dialog.cc:43 msgid "Channels" msgstr "Canales" -#: src/wx/film_editor.cc:325 +#: src/wx/film_editor.cc:326 msgid "Colour look-up table" msgstr "Tabla de referencia de colores" -#: src/wx/film_editor.cc:120 +#: src/wx/film_editor.cc:121 msgid "Content" msgstr "Contenido" -#: src/wx/film_editor.cc:130 +#: src/wx/film_editor.cc:131 msgid "Content Type" msgstr "Tipo de contenido" @@ -109,7 +101,7 @@ msgstr "No se pudo crear el DCP: %s" msgid "Could not open content file (%s)" msgstr "No se pudo abrir el fichero (%s)" -#: src/wx/film_editor.cc:504 +#: src/wx/film_editor.cc:505 #, c-format msgid "Could not set content: %s" msgstr "No se pudo establecer el contenido: %s" @@ -122,11 +114,11 @@ msgstr "Crear en carpeta" msgid "DCI name" msgstr "Nombre DCI" -#: src/wx/film_editor.cc:141 +#: src/wx/film_editor.cc:142 msgid "DCP Frame Rate" msgstr "Velocidad DCP" -#: src/wx/film_editor.cc:109 +#: src/wx/film_editor.cc:110 msgid "DCP Name" msgstr "Nombre DCP" @@ -139,19 +131,18 @@ msgid "DVD-o-matic Preferences" msgstr "Preferencias DVD-o-matic" #: src/wx/audio_dialog.cc:101 -#, c-format -msgid "DVD-o-matic audio - %s" -msgstr "Audio DVD-o-matic - %s" +msgid "DVD-o-matic audio - %1" +msgstr "Audio DVD-o-matic - %1" -#: src/wx/config_dialog.cc:102 +#: src/wx/config_dialog.cc:83 msgid "Default DCI name details" msgstr "Detalles por defecto del nombre DCI" -#: src/wx/config_dialog.cc:93 +#: src/wx/config_dialog.cc:74 msgid "Default directory for new films" msgstr "Carpeta por defecto para nuevas películas" -#: src/wx/film_editor.cc:116 src/wx/job_manager_view.cc:92 +#: src/wx/film_editor.cc:117 src/wx/job_manager_view.cc:88 msgid "Details..." msgstr "Detalles..." @@ -159,24 +150,24 @@ msgstr "Detalles..." msgid "Disk space required" msgstr "Espacio requerido en disco" -#: src/wx/film_editor.cc:191 +#: src/wx/film_editor.cc:192 msgid "Duration" msgstr "Duración" -#: src/wx/config_dialog.cc:145 +#: src/wx/config_dialog.cc:126 msgid "Edit" msgstr "Editar" -#: src/wx/config_dialog.cc:103 src/wx/config_dialog.cc:122 -#: src/wx/film_editor.cc:308 +#: src/wx/config_dialog.cc:84 src/wx/config_dialog.cc:103 +#: src/wx/film_editor.cc:309 msgid "Edit..." msgstr "Editar..." -#: src/wx/config_dialog.cc:128 +#: src/wx/config_dialog.cc:109 msgid "Encoding Servers" msgstr "Servidores de codificación" -#: src/wx/film_editor.cc:176 +#: src/wx/film_editor.cc:177 msgid "End" msgstr "Fin" @@ -184,7 +175,7 @@ msgstr "Fin" msgid "Facility (e.g. DLA)" msgstr "Compañía (ej. DLA)" -#: src/wx/film_editor.cc:73 +#: src/wx/film_editor.cc:74 msgid "Film" msgstr "Película" @@ -196,11 +187,11 @@ msgstr "Propiedades de la película" msgid "Film name" msgstr "Nombre de la película" -#: src/wx/film_editor.cc:303 src/wx/filter_dialog.cc:32 +#: src/wx/film_editor.cc:304 src/wx/filter_dialog.cc:32 msgid "Filters" msgstr "Filtros" -#: src/wx/film_editor.cc:268 +#: src/wx/film_editor.cc:269 msgid "Format" msgstr "Formato" @@ -224,7 +215,7 @@ msgstr "Gb" msgid "Host name or IP address" msgstr "Nombre o dirección IP" -#: src/wx/film_editor.cc:1235 +#: src/wx/film_editor.cc:1234 msgid "Hz" msgstr "Hz" @@ -232,23 +223,23 @@ msgstr "Hz" msgid "I want to play this back at fader" msgstr "Quiero reproducir con el fader a" -#: src/wx/config_dialog.cc:132 +#: src/wx/config_dialog.cc:113 msgid "IP address" msgstr "Dirección IP" -#: src/wx/film_editor.cc:335 +#: src/wx/film_editor.cc:336 msgid "JPEG2000 bandwidth" msgstr "Ancho de banda JPEG2000" -#: src/wx/film_editor.cc:281 +#: src/wx/film_editor.cc:282 msgid "Left crop" msgstr "Recorte izquierda" -#: src/wx/film_editor.cc:164 +#: src/wx/film_editor.cc:165 msgid "Length" msgstr "Longitud" -#: src/wx/film_editor.cc:339 +#: src/wx/film_editor.cc:340 msgid "MBps" msgstr "MBps" @@ -256,7 +247,7 @@ msgstr "MBps" msgid "My Documents" msgstr "Mis documentos" -#: src/wx/film_editor.cc:104 +#: src/wx/film_editor.cc:105 msgid "Name" msgstr "Nombre" @@ -264,15 +255,15 @@ msgstr "Nombre" msgid "New Film" msgstr "Nueva película" -#: src/wx/film_editor.cc:305 src/wx/film_editor.cc:664 +#: src/wx/film_editor.cc:306 src/wx/film_editor.cc:665 msgid "None" msgstr "Ninguno" -#: src/wx/film_editor.cc:135 +#: src/wx/film_editor.cc:136 msgid "Original Frame Rate" msgstr "Velocidad original" -#: src/wx/film_editor.cc:159 +#: src/wx/film_editor.cc:160 msgid "Original Size" msgstr "Tamaño original" @@ -300,35 +291,35 @@ msgstr "RMS" msgid "Rating (e.g. 15)" msgstr "Clasificación (ej. 16)" -#: src/wx/config_dialog.cc:118 +#: src/wx/config_dialog.cc:99 msgid "Reference filters for A/B" msgstr "Filtros de referencia para A/B" -#: src/wx/config_dialog.cc:107 +#: src/wx/config_dialog.cc:88 msgid "Reference scaler for A/B" msgstr "Escalador de referencia para A/B" -#: src/wx/config_dialog.cc:147 +#: src/wx/config_dialog.cc:128 msgid "Remove" msgstr "Quitar" -#: src/wx/film_editor.cc:286 +#: src/wx/film_editor.cc:287 msgid "Right crop" msgstr "Recorte derecha" -#: src/wx/job_manager_view.cc:108 +#: src/wx/job_manager_view.cc:104 msgid "Running" msgstr "Ejecutando" -#: src/wx/film_editor.cc:315 +#: src/wx/film_editor.cc:316 msgid "Scaler" msgstr "Escalador" -#: src/wx/film_editor.cc:407 +#: src/wx/film_editor.cc:408 msgid "Select Audio File" msgstr "Seleccionar fichero de audio" -#: src/wx/film_editor.cc:121 +#: src/wx/film_editor.cc:122 msgid "Select Content File" msgstr "Seleccionar fichero de contenido" @@ -336,11 +327,7 @@ msgstr "Seleccionar fichero de contenido" msgid "Server" msgstr "Servidor" -#: src/wx/config_dialog.cc:49 -msgid "Set language" -msgstr "" - -#: src/wx/film_editor.cc:364 +#: src/wx/film_editor.cc:365 msgid "Show Audio..." msgstr "Mostrar audio..." @@ -348,7 +335,7 @@ msgstr "Mostrar audio..." msgid "Smoothing" msgstr "Suavizado" -#: src/wx/film_editor.cc:173 +#: src/wx/film_editor.cc:174 msgid "Start" msgstr "Inicio" @@ -360,31 +347,31 @@ msgstr "Estudio (ej. TCF)" msgid "Subtitle Language (e.g. FR)" msgstr "Idioma del subtítulo (ej. EN)" -#: src/wx/film_editor.cc:431 +#: src/wx/film_editor.cc:432 msgid "Subtitle Offset" msgstr "Desplazamiento del subtítulo" -#: src/wx/film_editor.cc:436 +#: src/wx/film_editor.cc:437 msgid "Subtitle Scale" msgstr "Escala del subtítulo" -#: src/wx/film_editor.cc:79 +#: src/wx/film_editor.cc:80 msgid "Subtitles" msgstr "Subtítulos" -#: src/wx/config_dialog.cc:68 +#: src/wx/config_dialog.cc:49 msgid "TMS IP address" msgstr "Dirección IP del TMS" -#: src/wx/config_dialog.cc:83 +#: src/wx/config_dialog.cc:64 msgid "TMS password" msgstr "Clave del TMS" -#: src/wx/config_dialog.cc:73 +#: src/wx/config_dialog.cc:54 msgid "TMS target path" msgstr "Ruta en el TMS" -#: src/wx/config_dialog.cc:78 +#: src/wx/config_dialog.cc:59 msgid "TMS user name" msgstr "Usuario del TMS" @@ -392,7 +379,7 @@ msgstr "Usuario del TMS" msgid "Territory (e.g. UK)" msgstr "Territorio (ej. ES)" -#: src/wx/config_dialog.cc:136 +#: src/wx/config_dialog.cc:117 msgid "Threads" msgstr "Hilos" @@ -400,7 +387,7 @@ msgstr "Hilos" msgid "Threads to use" msgstr "Hilos a utilizar" -#: src/wx/config_dialog.cc:88 +#: src/wx/config_dialog.cc:69 msgid "Threads to use for encoding on this host" msgstr "Hilos a utilizar para la codificación en esta máquina" @@ -408,15 +395,15 @@ msgstr "Hilos a utilizar para la codificación en esta máquina" msgid "Time" msgstr "Tiempo" -#: src/wx/film_editor.cc:291 +#: src/wx/film_editor.cc:292 msgid "Top crop" msgstr "Recortar arriba" -#: src/wx/film_editor.cc:171 +#: src/wx/film_editor.cc:172 msgid "Trim frames" msgstr "Recortar fotogramas" -#: src/wx/film_editor.cc:125 +#: src/wx/film_editor.cc:126 msgid "Trust content's header" msgstr "Confiar en la cabecera del contenido" @@ -424,31 +411,31 @@ msgstr "Confiar en la cabecera del contenido" msgid "Type" msgstr "Tipo" -#: src/wx/film_editor.cc:114 +#: src/wx/film_editor.cc:115 msgid "Use DCI name" msgstr "Usar el nombre DCI" -#: src/wx/film_editor.cc:145 +#: src/wx/film_editor.cc:146 msgid "Use best" -msgstr "Usar el mejor" +msgstr "Usar la mejor" -#: src/wx/film_editor.cc:391 +#: src/wx/film_editor.cc:392 msgid "Use content's audio" msgstr "Usar el audio del contenido" -#: src/wx/film_editor.cc:401 +#: src/wx/film_editor.cc:402 msgid "Use external audio" msgstr "Usar audio externo" -#: src/wx/film_editor.cc:75 +#: src/wx/film_editor.cc:76 msgid "Video" msgstr "Vídeo" -#: src/wx/film_editor.cc:424 +#: src/wx/film_editor.cc:425 msgid "With Subtitles" msgstr "Con subtítulos" -#: src/wx/film_editor.cc:1233 +#: src/wx/film_editor.cc:1232 msgid "channels" msgstr "canales" @@ -456,21 +443,21 @@ msgstr "canales" msgid "counting..." msgstr "contando..." -#: src/wx/film_editor.cc:373 +#: src/wx/film_editor.cc:374 msgid "dB" msgstr "dB" -#: src/wx/film_editor.cc:691 src/wx/film_editor.cc:694 +#: src/wx/film_editor.cc:691 src/wx/film_editor.cc:693 msgid "frames" msgstr "fotogramas" #. / TRANSLATORS: this is an abbreviation for milliseconds, the unit of time -#: src/wx/film_editor.cc:386 +#: src/wx/film_editor.cc:387 msgid "ms" msgstr "ms" #. / TRANSLATORS: `s' here is an abbreviation for seconds, the unit of time -#: src/wx/film_editor.cc:197 +#: src/wx/film_editor.cc:198 msgid "s" msgstr "s" -- cgit v1.2.3 From 6198597b190c3c730057bee54e0421fcd7bcb795 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 3 Apr 2013 19:23:20 +0100 Subject: Film viewer kind of working. --- src/tools/dvdomatic.cc | 4 +++- src/wx/film_editor.cc | 11 +++++++++++ src/wx/film_viewer.cc | 14 +++++++++----- src/wx/film_viewer.h | 19 +++++++++++++++++++ 4 files changed, 42 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index a78d03794..a0e7f0de8 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -449,7 +449,9 @@ setup_i18n () if (Config::instance()->language()) { wxLanguageInfo const * li = wxLocale::FindLanguageInfo (std_to_wx (Config::instance()->language().get())); - language = li->Language; + if (li) { + language = li->Language; + } } if (wxLocale::IsAvailable (language)) { diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 5143bd370..33919d946 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -690,6 +690,13 @@ FilmEditor::film_changed (Film::Property p) void FilmEditor::film_content_changed (int p) { + if (!_film) { + /* We call this method ourselves (as well as using it as a signal handler) + so _film can be 0. + */ + return; + } + if (p == FFmpegContentProperty::SUBTITLE_STREAMS) { setup_subtitle_control_sensitivity (); setup_streams (); @@ -1033,6 +1040,10 @@ FilmEditor::edit_dci_button_clicked (wxCommandEvent &) void FilmEditor::setup_streams () { + if (!_film) { + return; + } + _ffmpeg_audio_stream->Clear (); vector a = _film->ffmpeg_audio_streams (); for (vector::iterator i = a.begin(); i != a.end(); ++i) { diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 54ef28ff0..76cff3f65 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -107,10 +107,12 @@ FilmViewer::film_changed (Film::Property p) break; } case Film::WITH_SUBTITLES: - setup_player (); - /* fall through */ case Film::SUBTITLE_OFFSET: case Film::SUBTITLE_SCALE: + raw_to_display (); + _panel->Refresh (); + _panel->Update (); + break; case Film::SCALER: case Film::FILTERS: case Film::CROP: @@ -126,10 +128,12 @@ FilmViewer::setup_player () { _player = _film->player (); _player->disable_audio (); - if (!_film->with_subtitles ()) { - _player->disable_subtitles (); - } _player->disable_video_sync (); + + /* Don't disable subtitles here as we may need them, and it's nice to be able to turn them + on and off without needing obtain a new Player. + */ + _player->Video.connect (bind (&FilmViewer::process_video, this, _1, _2, _3)); } diff --git a/src/wx/film_viewer.h b/src/wx/film_viewer.h index e28703fdd..bf956ef95 100644 --- a/src/wx/film_viewer.h +++ b/src/wx/film_viewer.h @@ -32,6 +32,25 @@ class Subtitle; /** @class FilmViewer * @brief A wx widget to view a preview of a Film. + * + * The film takes the following path through the viewer: + * + * 1. get_frame() asks our _player to decode some data. If it does, process_video() + * will be called. + * + * 2. process_video() takes the image and subtitle from the decoder (_raw_frame and _raw_sub) + * and calls raw_to_display(). + * + * 3. raw_to_display() copies _raw_frame to _display_frame, processing it and scaling it. + * + * 4. calling _panel->Refresh() and _panel->Update() results in paint_panel() being called; + * this creates frame_bitmap from _display_frame and blits it to the display. It also + * blits the subtitle, if required. + * + * update_from_decoder() asks the player to re-emit its current frame on the next pass(), and then + * starts from step #1. + * + * update_from_raw() starts at step #3, then calls _panel->Refresh and _panel->Update. */ class FilmViewer : public wxPanel { -- cgit v1.2.3 From 675e849d19812f5ed2d63b3bc0e34f142e6abb89 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 3 Apr 2013 20:44:02 +0100 Subject: Allow UI to set up FFmpeg streams again. --- src/lib/film.cc | 62 +++++++++++++++++++++++++++++++++++++++++++++++---- src/lib/film.h | 4 ++++ src/lib/playlist.cc | 40 --------------------------------- src/lib/playlist.h | 5 ----- src/wx/film_editor.cc | 46 ++++++++++++++++++++------------------ 5 files changed, 86 insertions(+), 71 deletions(-) (limited to 'src') diff --git a/src/lib/film.cc b/src/lib/film.cc index 091b35d47..fd72aa1d5 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -1161,28 +1161,82 @@ Film::video_length () const return _playlist->video_length (); } +/** Unfortunately this is needed as the GUI has FFmpeg-specific controls */ +shared_ptr +Film::ffmpeg () const +{ + boost::mutex::scoped_lock lm (_state_mutex); + + for (ContentList::const_iterator i = _content.begin (); i != _content.end(); ++i) { + shared_ptr f = boost::dynamic_pointer_cast (*i); + if (f) { + return f; + } + } + + return shared_ptr (); +} + vector Film::ffmpeg_subtitle_streams () const { - return _playlist->ffmpeg_subtitle_streams (); + boost::shared_ptr f = ffmpeg (); + if (f) { + return f->subtitle_streams (); + } + + return vector (); } boost::optional Film::ffmpeg_subtitle_stream () const { - return _playlist->ffmpeg_subtitle_stream (); + boost::shared_ptr f = ffmpeg (); + if (f) { + return f->subtitle_stream (); + } + + return boost::none; } vector Film::ffmpeg_audio_streams () const { - return _playlist->ffmpeg_audio_streams (); + boost::shared_ptr f = ffmpeg (); + if (f) { + return f->audio_streams (); + } + + return vector (); } boost::optional Film::ffmpeg_audio_stream () const { - return _playlist->ffmpeg_audio_stream (); + boost::shared_ptr f = ffmpeg (); + if (f) { + return f->audio_stream (); + } + + return boost::none; +} + +void +Film::set_ffmpeg_subtitle_stream (FFmpegSubtitleStream s) +{ + boost::shared_ptr f = ffmpeg (); + if (f) { + f->set_subtitle_stream (s); + } +} + +void +Film::set_ffmpeg_audio_stream (FFmpegAudioStream s) +{ + boost::shared_ptr f = ffmpeg (); + if (f) { + f->set_audio_stream (s); + } } void diff --git a/src/lib/film.h b/src/lib/film.h index e71fe2606..a03fd5d97 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -119,6 +119,9 @@ public: boost::optional ffmpeg_subtitle_stream () const; std::vector ffmpeg_audio_streams () const; boost::optional ffmpeg_audio_stream () const; + + void set_ffmpeg_subtitle_stream (FFmpegSubtitleStream); + void set_ffmpeg_audio_stream (FFmpegAudioStream); /** Identifiers for the parts of our state; used for signalling changes. @@ -313,6 +316,7 @@ private: std::string video_state_identifier () const; void read_metadata (); void content_changed (int); + boost::shared_ptr ffmpeg () const; /** Log to write to */ boost::shared_ptr _log; diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index 0c29650b6..3da7f938b 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -207,46 +207,6 @@ Playlist::has_audio () const return _audio_from != AUDIO_NONE; } -vector -Playlist::ffmpeg_subtitle_streams () const -{ - if (_video_from != VIDEO_FFMPEG || !_ffmpeg) { - return vector (); - } - - return _ffmpeg->subtitle_streams (); -} - -boost::optional -Playlist::ffmpeg_subtitle_stream () const -{ - if (_video_from != VIDEO_FFMPEG || !_ffmpeg) { - return boost::none; - } - - return _ffmpeg->subtitle_stream (); -} - -vector -Playlist::ffmpeg_audio_streams () const -{ - if (_video_from != VIDEO_FFMPEG || !_ffmpeg) { - return vector (); - } - - return _ffmpeg->audio_streams (); -} - -boost::optional -Playlist::ffmpeg_audio_stream () const -{ - if (_video_from != VIDEO_FFMPEG || !_ffmpeg) { - return boost::none; - } - - return _ffmpeg->audio_stream (); -} - Player::Player (boost::shared_ptr f, boost::shared_ptr p) : _film (f) , _playlist (p) diff --git a/src/lib/playlist.h b/src/lib/playlist.h index c461151d4..480f1b2ed 100644 --- a/src/lib/playlist.h +++ b/src/lib/playlist.h @@ -53,11 +53,6 @@ public: libdcp::Size video_size () const; ContentVideoFrame video_length () const; - std::vector ffmpeg_subtitle_streams () const; - boost::optional ffmpeg_subtitle_stream () const; - std::vector ffmpeg_audio_streams () const; - boost::optional ffmpeg_audio_stream () const; - enum VideoFrom { VIDEO_NONE, VIDEO_FFMPEG, diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 33919d946..d55104a95 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -1074,14 +1074,16 @@ FilmEditor::ffmpeg_audio_stream_changed (wxCommandEvent &) return; } -#if 0 - _film->set_content_audio_stream ( - audio_stream_factory ( - string_client_data (_audio_stream->GetClientObject (_audio_stream->GetSelection ())), - Film::state_version - ) - ); -#endif + vector a = _film->ffmpeg_audio_streams (); + vector::iterator i = a.begin (); + string const s = string_client_data (_ffmpeg_audio_stream->GetClientObject (_ffmpeg_audio_stream->GetSelection ())); + while (i != a.end() && i->id != s) { + ++i; + } + + if (i != a.end ()) { + _film->set_ffmpeg_audio_stream (*i); + } } void @@ -1091,33 +1093,33 @@ FilmEditor::ffmpeg_subtitle_stream_changed (wxCommandEvent &) return; } -#if 0 - _film->set_subtitle_stream ( - subtitle_stream_factory ( - string_client_data (_subtitle_stream->GetClientObject (_subtitle_stream->GetSelection ())), - Film::state_version - ) - ); -#endif + vector a = _film->ffmpeg_subtitle_streams (); + vector::iterator i = a.begin (); + string const s = string_client_data (_ffmpeg_subtitle_stream->GetClientObject (_ffmpeg_subtitle_stream->GetSelection ())); + while (i != a.end() && i->id != s) { + ++i; + } + + if (i != a.end ()) { + _film->set_ffmpeg_subtitle_stream (*i); + } } void FilmEditor::setup_audio_details () { -#if 0 - if (!_film->content_audio_stream()) { + if (!_film->ffmpeg_audio_stream()) { _audio->SetLabel (wxT ("")); } else { stringstream s; - if (_film->audio_stream()->channels() == 1) { + if (_film->audio_channels() == 1) { s << wx_to_std (_("1 channel")); } else { - s << _film->audio_stream()->channels () << " " << wx_to_std (_("channels")); + s << _film->audio_channels() << " " << wx_to_std (_("channels")); } - s << ", " << _film->audio_stream()->sample_rate() << wx_to_std (_("Hz")); + s << ", " << _film->audio_channels() << wx_to_std (_("Hz")); _audio->SetLabel (std_to_wx (s.str ())); } -#endif } void -- cgit v1.2.3 From 190c074cc1508c0aa429452ea920f8f94ef0d0f2 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 4 Apr 2013 00:13:27 +0100 Subject: More various bits. --- src/lib/audio_source.cc | 12 +++++++++++- src/lib/encoder.cc | 2 +- src/lib/encoder.h | 2 +- src/lib/ffmpeg_content.cc | 10 ++++++---- src/lib/ffmpeg_decoder.cc | 12 +++++++++++- src/lib/ffmpeg_decoder.h | 10 ++++++++++ src/lib/film.cc | 2 +- src/lib/playlist.cc | 25 +++++++++++++++++++++++-- src/lib/transcode_job.cc | 34 ++++++++++++++++------------------ src/lib/transcode_job.h | 6 ++++-- src/lib/transcoder.cc | 12 ++++++++++++ src/lib/transcoder.h | 3 +++ src/lib/video_source.cc | 15 ++++++++++++++- src/wx/film_editor.cc | 29 +++++++++++++++++++++++++---- src/wx/film_editor.h | 1 + 15 files changed, 139 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/lib/audio_source.cc b/src/lib/audio_source.cc index 53b0dda15..99b59759d 100644 --- a/src/lib/audio_source.cc +++ b/src/lib/audio_source.cc @@ -21,10 +21,20 @@ #include "audio_sink.h" using boost::shared_ptr; +using boost::weak_ptr; using boost::bind; +static void +process_audio_proxy (weak_ptr sink, shared_ptr audio) +{ + shared_ptr p = sink.lock (); + if (p) { + p->process_audio (audio); + } +} + void AudioSource::connect_audio (shared_ptr s) { - Audio.connect (bind (&AudioSink::process_audio, s, _1)); + Audio.connect (bind (process_audio_proxy, weak_ptr (s), _1)); } diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 5c3e56709..a41ebec51 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -193,7 +193,7 @@ Encoder::process_end () * or 0 if not known. */ float -Encoder::current_frames_per_second () const +Encoder::current_encoding_rate () const { boost::mutex::scoped_lock lock (_history_mutex); if (int (_time_history.size()) < _history_size) { diff --git a/src/lib/encoder.h b/src/lib/encoder.h index 2cbd498e8..b85132b72 100644 --- a/src/lib/encoder.h +++ b/src/lib/encoder.h @@ -81,7 +81,7 @@ public: /** Called when a processing run has finished */ virtual void process_end (); - float current_frames_per_second () const; + float current_encoding_rate () const; int video_frames_out () const; private: diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index c6344d567..7834cb76e 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -111,12 +111,10 @@ FFmpegContent::as_xml (xmlpp::Node* node) const void FFmpegContent::examine (shared_ptr film, shared_ptr job, bool quick) { - job->descend (0.5); - Content::examine (film, job, quick); - job->ascend (); - job->set_progress_unknown (); + Content::examine (film, job, quick); + shared_ptr decoder (new FFmpegDecoder (film, shared_from_this (), true, false, false, true)); ContentVideoFrame video_length = 0; @@ -166,6 +164,10 @@ FFmpegContent::summary () const string FFmpegContent::information () const { + if (video_length() == 0 || video_frame_rate() == 0) { + return ""; + } + stringstream s; s << String::compose (_("%1 frames; %2 frames per second"), video_length(), video_frame_rate()) << "\n"; diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 3a185bd6a..fdc5189a6 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -61,6 +61,8 @@ using boost::optional; using boost::dynamic_pointer_cast; using libdcp::Size; +boost::mutex FFmpegDecoder::_mutex; + FFmpegDecoder::FFmpegDecoder (shared_ptr f, shared_ptr c, bool video, bool audio, bool subtitles, bool video_sync) : Decoder (f) , VideoDecoder (f) @@ -92,10 +94,12 @@ FFmpegDecoder::FFmpegDecoder (shared_ptr f, shared_ptrstreams[_video_stream]->codec; _video_codec = avcodec_find_decoder (_video_codec_context->codec_id); @@ -175,6 +181,8 @@ FFmpegDecoder::setup_video () void FFmpegDecoder::setup_audio () { + boost::mutex::scoped_lock lm (_mutex); + if (!_ffmpeg_content->audio_stream ()) { return; } @@ -194,6 +202,8 @@ FFmpegDecoder::setup_audio () void FFmpegDecoder::setup_subtitle () { + boost::mutex::scoped_lock lm (_mutex); + if (!_ffmpeg_content->subtitle_stream() || _ffmpeg_content->subtitle_stream()->id >= int (_format_context->nb_streams)) { return; } diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h index 71ecf7906..5023ac56c 100644 --- a/src/lib/ffmpeg_decoder.h +++ b/src/lib/ffmpeg_decoder.h @@ -82,6 +82,10 @@ public: private: + /* No copy construction */ + FFmpegDecoder (FFmpegDecoder const &); + FFmpegDecoder& operator= (FFmpegDecoder const &); + bool do_seek (double p, bool); PixelFormat pixel_format () const; AVSampleFormat audio_sample_format () const; @@ -134,4 +138,10 @@ private: bool _decode_audio; bool _decode_subtitles; bool _video_sync; + + /* It would appear (though not completely verified) that one must have + a mutex around calls to avcodec_open* and avcodec_close... and here + it is. + */ + static boost::mutex _mutex; }; diff --git a/src/lib/film.cc b/src/lib/film.cc index fd72aa1d5..b21b3454d 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -550,7 +550,7 @@ Film::file (string f) const int Film::target_audio_sample_rate () const { - if (has_audio ()) { + if (!has_audio ()) { return 0; } diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index 3da7f938b..dc8ad1ef7 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -25,6 +25,7 @@ #include "ffmpeg_decoder.h" #include "imagemagick_content.h" #include "imagemagick_decoder.h" +#include "job.h" using std::list; using std::cout; @@ -219,7 +220,7 @@ Player::Player (boost::shared_ptr f, boost::shared_ptr job) { - /* XXX */ + /* Assume progress can be divined from how far through the video we are */ + switch (_playlist->video_from ()) { + case Playlist::VIDEO_NONE: + break; + case Playlist::VIDEO_FFMPEG: + if (_playlist->video_length ()) { + job->set_progress (float(_ffmpeg_decoder->video_frame()) / _playlist->video_length ()); + } + break; + case Playlist::VIDEO_IMAGEMAGICK: + { + int n = 0; + for (std::list >::iterator i = _imagemagick_decoders.begin(); i != _imagemagick_decoders.end(); ++i) { + if (_imagemagick_decoder == i) { + job->set_progress (float (n) / _imagemagick_decoders.size ()); + } + ++n; + } + break; + } + } } void diff --git a/src/lib/transcode_job.cc b/src/lib/transcode_job.cc index 8b74f7766..0c3b8c37b 100644 --- a/src/lib/transcode_job.cc +++ b/src/lib/transcode_job.cc @@ -60,8 +60,8 @@ TranscodeJob::run () _film->log()->log (N_("Transcode job starting")); _film->log()->log (String::compose (N_("Audio delay is %1ms"), _film->audio_delay())); - Transcoder w (_film, shared_from_this ()); - w.go (); + _transcoder.reset (new Transcoder (_film, shared_from_this ())); + _transcoder->go (); set_progress (1); set_state (FINISHED_OK); @@ -80,13 +80,11 @@ TranscodeJob::run () string TranscodeJob::status () const { -// if (!_encoder) { -// return _("0%"); -// } + if (!_transcoder) { + return _("0%"); + } - /* XXX */ -// float const fps = _encoder->current_frames_per_second (); - float const fps = 0; + float const fps = _transcoder->current_encoding_rate (); if (fps == 0) { return Job::status (); } @@ -105,28 +103,28 @@ TranscodeJob::status () const int TranscodeJob::remaining_time () const { - return 0; -#if 0 - XXX - float fps = _encoder->current_frames_per_second (); + if (!_transcoder) { + return 0; + } + + float fps = _transcoder->current_encoding_rate (); + if (fps == 0) { return 0; } - if (!_video->length()) { + if (!_film->video_length()) { return 0; } /* Compute approximate proposed length here, as it's only here that we need it */ - int length = _film->length().get(); - FrameRateConversion const frc (_film->source_frame_rate(), _film->dcp_frame_rate()); + int length = _film->video_length(); + FrameRateConversion const frc (_film->video_frame_rate(), _film->dcp_frame_rate()); if (frc.skip) { length /= 2; } /* If we are repeating it shouldn't affect transcode time, so don't take it into account */ - /* We assume that dcp_length() is valid, if it is set */ - int const left = length - _encoder->video_frames_out(); + int const left = length - _transcoder->video_frames_out(); return left / fps; -#endif } diff --git a/src/lib/transcode_job.h b/src/lib/transcode_job.h index def545958..7880a925e 100644 --- a/src/lib/transcode_job.h +++ b/src/lib/transcode_job.h @@ -24,7 +24,7 @@ #include #include "job.h" -class Encoder; +class Transcoder; /** @class TranscodeJob * @brief A job which transcodes from one format to another. @@ -38,6 +38,8 @@ public: void run (); std::string status () const; -protected: +private: int remaining_time () const; + + boost::shared_ptr _transcoder; }; diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc index 0ee6f523f..ef3a0e8c1 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -99,3 +99,15 @@ Transcoder::go () } _encoder->process_end (); } + +float +Transcoder::current_encoding_rate () const +{ + return _encoder->current_encoding_rate (); +} + +int +Transcoder::video_frames_out () const +{ + return _encoder->video_frames_out (); +} diff --git a/src/lib/transcoder.h b/src/lib/transcoder.h index 2d032fcf6..ecc8ebf62 100644 --- a/src/lib/transcoder.h +++ b/src/lib/transcoder.h @@ -47,6 +47,9 @@ public: void go (); + float current_encoding_rate () const; + int video_frames_out () const; + protected: /** A Job that is running this Transcoder, or 0 */ boost::shared_ptr _job; diff --git a/src/lib/video_source.cc b/src/lib/video_source.cc index 56742e2b4..8101a6d36 100644 --- a/src/lib/video_source.cc +++ b/src/lib/video_source.cc @@ -21,10 +21,23 @@ #include "video_sink.h" using boost::shared_ptr; +using boost::weak_ptr; using boost::bind; +static void +process_video_proxy (weak_ptr sink, shared_ptr i, bool same, shared_ptr s) +{ + boost::shared_ptr p = sink.lock (); + if (p) { + p->process_video (i, same, s); + } +} + void VideoSource::connect_video (shared_ptr s) { - Video.connect (bind (&VideoSink::process_video, s, _1, _2, _3)); + /* If we bind, say, a Playlist (as the VideoSink) to a Decoder (which is owned + by the Playlist) we create a cycle. Use a weak_ptr to break it. + */ + Video.connect (bind (process_video_proxy, boost::weak_ptr (s), _1, _2, _3)); } diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index d55104a95..10cb41df0 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -705,16 +705,17 @@ FilmEditor::film_content_changed (int p) setup_show_audio_sensitivity (); } else if (p == VideoContentProperty::VIDEO_LENGTH) { setup_length (); + setup_content_information (); } else if (p == FFmpegContentProperty::AUDIO_STREAM) { if (_film->ffmpeg_audio_stream()) { - checked_set (_ffmpeg_audio_stream, _film->ffmpeg_audio_stream()->id); + checked_set (_ffmpeg_audio_stream, boost::lexical_cast (_film->ffmpeg_audio_stream()->id)); } setup_dcp_name (); setup_audio_details (); setup_show_audio_sensitivity (); } else if (p == FFmpegContentProperty::SUBTITLE_STREAM) { if (_film->ffmpeg_subtitle_stream()) { - checked_set (_ffmpeg_subtitle_stream, _film->ffmpeg_subtitle_stream()->id); + checked_set (_ffmpeg_subtitle_stream, boost::lexical_cast (_film->ffmpeg_subtitle_stream()->id)); } } } @@ -1117,7 +1118,7 @@ FilmEditor::setup_audio_details () } else { s << _film->audio_channels() << " " << wx_to_std (_("channels")); } - s << ", " << _film->audio_channels() << wx_to_std (_("Hz")); + s << ", " << _film->audio_frame_rate() << wx_to_std (_("Hz")); _audio->SetLabel (std_to_wx (s.str ())); } } @@ -1172,11 +1173,26 @@ FilmEditor::setup_show_audio_sensitivity () void FilmEditor::setup_content () { + string selected_summary; + int const s = _content->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (s != -1) { + selected_summary = wx_to_std (_content->GetItemText (s)); + } + _content->DeleteAllItems (); ContentList content = _film->content (); for (ContentList::iterator i = content.begin(); i != content.end(); ++i) { - _content->InsertItem (_content->GetItemCount(), std_to_wx ((*i)->summary ())); + int const t = _content->GetItemCount (); + _content->InsertItem (t, std_to_wx ((*i)->summary ())); + if ((*i)->summary() == selected_summary) { + _content->SetItemState (t, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED); + } + } + + if (selected_summary.empty () && !content.empty ()) { + /* Select the first item of content if non was selected before */ + _content->SetItemState (0, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED); } } @@ -1246,7 +1262,12 @@ void FilmEditor::content_item_selected (wxListEvent &) { setup_content_button_sensitivity (); + setup_content_information (); +} +void +FilmEditor::setup_content_information () +{ int const s = _content->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); if (s == -1) { _content_information->SetValue (""); diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index 60da2de4d..97d1e0dd3 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -106,6 +106,7 @@ private: void setup_content_button_sensitivity (); void setup_length (); void setup_format (); + void setup_content_information (); void active_jobs_changed (bool); -- cgit v1.2.3 From d0c2e5d14224e0d1058a9b7058f88e6b32dc8e6f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 4 Apr 2013 00:22:46 +0100 Subject: Fix blank display if we read off the end. --- src/lib/playlist.cc | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index dc8ad1ef7..a7862f116 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -332,6 +332,8 @@ Player::seek (double t) if (!_ffmpeg_decoder || _ffmpeg_decoder->seek (t)) { r = true; } + /* We're seeking, so all `all done' bets are off */ + _ffmpeg_decoder_done = false; break; case Playlist::VIDEO_IMAGEMAGICK: /* Find the decoder that contains this position */ @@ -375,6 +377,9 @@ Player::seek_to_last () if (!_ffmpeg_decoder || _ffmpeg_decoder->seek_to_last ()) { r = true; } + + /* We're seeking, so all `all done' bets are off */ + _ffmpeg_decoder_done = false; break; case Playlist::VIDEO_IMAGEMAGICK: if ((*_imagemagick_decoder)->seek_to_last ()) { -- cgit v1.2.3 From 6bc12a2eeb9c84a539688f2f7eb876e3ea278a9f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 4 Apr 2013 10:13:41 +0100 Subject: Split playlist files up; fix build. --- src/lib/ab_transcoder.cc | 2 +- src/lib/analyse_audio_job.cc | 2 +- src/lib/encoder.cc | 2 +- src/lib/film.cc | 1 + src/lib/player.cc | 280 +++++++++++++++++++++++++++++++++++++++++++ src/lib/player.h | 77 ++++++++++++ src/lib/playlist.cc | 250 -------------------------------------- src/lib/playlist.h | 39 ------ src/lib/transcoder.cc | 2 +- src/lib/writer.cc | 2 +- src/lib/wscript | 1 + src/tools/servomatictest.cc | 2 +- src/wx/film_editor.cc | 9 +- src/wx/film_viewer.cc | 2 +- 14 files changed, 371 insertions(+), 300 deletions(-) create mode 100644 src/lib/player.cc create mode 100644 src/lib/player.h (limited to 'src') diff --git a/src/lib/ab_transcoder.cc b/src/lib/ab_transcoder.cc index 6bf092fee..81aa5a4ba 100644 --- a/src/lib/ab_transcoder.cc +++ b/src/lib/ab_transcoder.cc @@ -24,7 +24,7 @@ #include "encoder.h" #include "job.h" #include "image.h" -#include "playlist.h" +#include "player.h" #include "matcher.h" #include "delay_line.h" #include "gain.h" diff --git a/src/lib/analyse_audio_job.cc b/src/lib/analyse_audio_job.cc index e2c9c5b18..5ef6515dd 100644 --- a/src/lib/analyse_audio_job.cc +++ b/src/lib/analyse_audio_job.cc @@ -21,7 +21,7 @@ #include "analyse_audio_job.h" #include "compose.hpp" #include "film.h" -#include "playlist.h" +#include "player.h" #include "i18n.h" diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index a41ebec51..2a8d8cc16 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -37,7 +37,7 @@ #include "format.h" #include "cross.h" #include "writer.h" -#include "playlist.h" +#include "player.h" #include "i18n.h" diff --git a/src/lib/film.cc b/src/lib/film.cc index b21b3454d..42f4b1c3d 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -53,6 +53,7 @@ #include "sndfile_decoder.h" #include "analyse_audio_job.h" #include "playlist.h" +#include "player.h" #include "ffmpeg_content.h" #include "imagemagick_content.h" #include "sndfile_content.h" diff --git a/src/lib/player.cc b/src/lib/player.cc new file mode 100644 index 000000000..6e2e7ed14 --- /dev/null +++ b/src/lib/player.cc @@ -0,0 +1,280 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "player.h" +#include "film.h" +#include "ffmpeg_decoder.h" +#include "imagemagick_decoder.h" +#include "sndfile_decoder.h" +#include "playlist.h" +#include "job.h" + +using std::list; +using boost::shared_ptr; + +Player::Player (shared_ptr f, shared_ptr p) + : _film (f) + , _playlist (p) + , _video (true) + , _audio (true) + , _subtitles (true) + , _have_setup_decoders (false) + , _ffmpeg_decoder_done (false) + , _video_sync (true) +{ + +} + +void +Player::disable_video () +{ + _video = false; +} + +void +Player::disable_audio () +{ + _audio = false; +} + +void +Player::disable_subtitles () +{ + _subtitles = false; +} + +bool +Player::pass () +{ + if (!_have_setup_decoders) { + setup_decoders (); + _have_setup_decoders = true; + } + + bool done = true; + + if (_playlist->video_from() == Playlist::VIDEO_FFMPEG || _playlist->audio_from() == Playlist::AUDIO_FFMPEG) { + if (!_ffmpeg_decoder_done) { + if (_ffmpeg_decoder->pass ()) { + _ffmpeg_decoder_done = true; + } else { + done = false; + } + } + } + + if (_playlist->video_from() == Playlist::VIDEO_IMAGEMAGICK) { + if (_imagemagick_decoder != _imagemagick_decoders.end ()) { + if ((*_imagemagick_decoder)->pass ()) { + _imagemagick_decoder++; + } + + if (_imagemagick_decoder != _imagemagick_decoders.end ()) { + done = false; + } + } + } + + /* XXX: sndfile */ + + return done; +} + +void +Player::set_progress (shared_ptr job) +{ + /* Assume progress can be divined from how far through the video we are */ + switch (_playlist->video_from ()) { + case Playlist::VIDEO_NONE: + break; + case Playlist::VIDEO_FFMPEG: + if (_playlist->video_length ()) { + job->set_progress (float(_ffmpeg_decoder->video_frame()) / _playlist->video_length ()); + } + break; + case Playlist::VIDEO_IMAGEMAGICK: + { + int n = 0; + for (list >::iterator i = _imagemagick_decoders.begin(); i != _imagemagick_decoders.end(); ++i) { + if (_imagemagick_decoder == i) { + job->set_progress (float (n) / _imagemagick_decoders.size ()); + } + ++n; + } + break; + } + } +} + +void +Player::process_video (shared_ptr i, bool same, shared_ptr s) +{ + Video (i, same, s); +} + +void +Player::process_audio (shared_ptr b) +{ + Audio (b); +} + +/** @return true on error */ +bool +Player::seek (double t) +{ + if (!_have_setup_decoders) { + setup_decoders (); + _have_setup_decoders = true; + } + + bool r = false; + + switch (_playlist->video_from()) { + case Playlist::VIDEO_NONE: + break; + case Playlist::VIDEO_FFMPEG: + if (!_ffmpeg_decoder || _ffmpeg_decoder->seek (t)) { + r = true; + } + /* We're seeking, so all `all done' bets are off */ + _ffmpeg_decoder_done = false; + break; + case Playlist::VIDEO_IMAGEMAGICK: + /* Find the decoder that contains this position */ + _imagemagick_decoder = _imagemagick_decoders.begin (); + while (_imagemagick_decoder != _imagemagick_decoders.end ()) { + double const this_length = (*_imagemagick_decoder)->video_length() / _film->video_frame_rate (); + if (t < this_length) { + break; + } + t -= this_length; + ++_imagemagick_decoder; + } + + if (_imagemagick_decoder != _imagemagick_decoders.end()) { + (*_imagemagick_decoder)->seek (t); + } else { + r = true; + } + break; + } + + /* XXX: don't seek audio because we don't need to... */ + + return r; +} + +bool +Player::seek_to_last () +{ + if (!_have_setup_decoders) { + setup_decoders (); + _have_setup_decoders = true; + } + + bool r = false; + + switch (_playlist->video_from ()) { + case Playlist::VIDEO_NONE: + break; + case Playlist::VIDEO_FFMPEG: + if (!_ffmpeg_decoder || _ffmpeg_decoder->seek_to_last ()) { + r = true; + } + + /* We're seeking, so all `all done' bets are off */ + _ffmpeg_decoder_done = false; + break; + case Playlist::VIDEO_IMAGEMAGICK: + if ((*_imagemagick_decoder)->seek_to_last ()) { + r = true; + } + break; + } + + /* XXX: don't seek audio because we don't need to... */ + + return r; +} + +void +Player::setup_decoders () +{ + if ((_video && _playlist->video_from() == Playlist::VIDEO_FFMPEG) || (_audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG)) { + _ffmpeg_decoder.reset ( + new FFmpegDecoder ( + _film, + _playlist->ffmpeg(), + _video && _playlist->video_from() == Playlist::VIDEO_FFMPEG, + _audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG, + _subtitles && _film->with_subtitles(), + _video_sync + ) + ); + } + + if (_video && _playlist->video_from() == Playlist::VIDEO_FFMPEG) { + _ffmpeg_decoder->connect_video (shared_from_this ()); + } + + if (_audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG) { + _ffmpeg_decoder->connect_audio (shared_from_this ()); + } + + if (_video && _playlist->video_from() == Playlist::VIDEO_IMAGEMAGICK) { + list > ic = _playlist->imagemagick (); + for (list >::iterator i = ic.begin(); i != ic.end(); ++i) { + shared_ptr d (new ImageMagickDecoder (_film, *i)); + _imagemagick_decoders.push_back (d); + d->connect_video (shared_from_this ()); + } + + _imagemagick_decoder = _imagemagick_decoders.begin (); + } + + if (_audio && _playlist->audio_from() == Playlist::AUDIO_SNDFILE) { + list > sc = _playlist->sndfile (); + for (list >::iterator i = sc.begin(); i != sc.end(); ++i) { + shared_ptr d (new SndfileDecoder (_film, *i)); + _sndfile_decoders.push_back (d); + d->connect_audio (shared_from_this ()); + } + } +} + +void +Player::disable_video_sync () +{ + _video_sync = false; +} + +double +Player::last_video_time () const +{ + switch (_playlist->video_from ()) { + case Playlist::VIDEO_NONE: + return 0; + case Playlist::VIDEO_FFMPEG: + return _ffmpeg_decoder->last_source_time (); + case Playlist::VIDEO_IMAGEMAGICK: + return (*_imagemagick_decoder)->last_source_time (); + } + + return 0; +} diff --git a/src/lib/player.h b/src/lib/player.h new file mode 100644 index 000000000..bc728d8f2 --- /dev/null +++ b/src/lib/player.h @@ -0,0 +1,77 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef DVDOMATIC_PLAYER_H +#define DVDOMATIC_PLAYER_H + +#include +#include +#include +#include "video_source.h" +#include "audio_source.h" +#include "video_sink.h" +#include "audio_sink.h" + +class FFmpegDecoder; +class ImageMagickDecoder; +class SndfileDecoder; +class Job; +class Film; +class Playlist; + +class Player : public VideoSource, public AudioSource, public VideoSink, public AudioSink, public boost::enable_shared_from_this +{ +public: + Player (boost::shared_ptr, boost::shared_ptr); + + void disable_video (); + void disable_audio (); + void disable_subtitles (); + void disable_video_sync (); + + bool pass (); + void set_progress (boost::shared_ptr); + bool seek (double); + bool seek_to_last (); + + double last_video_time () const; + +private: + void process_video (boost::shared_ptr i, bool same, boost::shared_ptr s); + void process_audio (boost::shared_ptr); + void setup_decoders (); + + boost::shared_ptr _film; + boost::shared_ptr _playlist; + + bool _video; + bool _audio; + bool _subtitles; + + bool _have_setup_decoders; + boost::shared_ptr _ffmpeg_decoder; + bool _ffmpeg_decoder_done; + std::list > _imagemagick_decoders; + std::list >::iterator _imagemagick_decoder; + std::list > _sndfile_decoders; + + bool _video_sync; +}; + +#endif diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index a7862f116..0a4803f6e 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -208,253 +208,3 @@ Playlist::has_audio () const return _audio_from != AUDIO_NONE; } -Player::Player (boost::shared_ptr f, boost::shared_ptr p) - : _film (f) - , _playlist (p) - , _video (true) - , _audio (true) - , _subtitles (true) - , _have_setup_decoders (false) - , _ffmpeg_decoder_done (false) - , _video_sync (true) -{ - -} - -void -Player::disable_video () -{ - _video = false; -} - -void -Player::disable_audio () -{ - _audio = false; -} - -void -Player::disable_subtitles () -{ - _subtitles = false; -} - -bool -Player::pass () -{ - if (!_have_setup_decoders) { - setup_decoders (); - _have_setup_decoders = true; - } - - bool done = true; - - if (_playlist->video_from() == Playlist::VIDEO_FFMPEG || _playlist->audio_from() == Playlist::AUDIO_FFMPEG) { - if (!_ffmpeg_decoder_done) { - if (_ffmpeg_decoder->pass ()) { - _ffmpeg_decoder_done = true; - } else { - done = false; - } - } - } - - if (_playlist->video_from() == Playlist::VIDEO_IMAGEMAGICK) { - if (_imagemagick_decoder != _imagemagick_decoders.end ()) { - if ((*_imagemagick_decoder)->pass ()) { - _imagemagick_decoder++; - } - - if (_imagemagick_decoder != _imagemagick_decoders.end ()) { - done = false; - } - } - } - - /* XXX: sndfile */ - - return done; -} - -void -Player::set_progress (shared_ptr job) -{ - /* Assume progress can be divined from how far through the video we are */ - switch (_playlist->video_from ()) { - case Playlist::VIDEO_NONE: - break; - case Playlist::VIDEO_FFMPEG: - if (_playlist->video_length ()) { - job->set_progress (float(_ffmpeg_decoder->video_frame()) / _playlist->video_length ()); - } - break; - case Playlist::VIDEO_IMAGEMAGICK: - { - int n = 0; - for (std::list >::iterator i = _imagemagick_decoders.begin(); i != _imagemagick_decoders.end(); ++i) { - if (_imagemagick_decoder == i) { - job->set_progress (float (n) / _imagemagick_decoders.size ()); - } - ++n; - } - break; - } - } -} - -void -Player::process_video (shared_ptr i, bool same, shared_ptr s) -{ - Video (i, same, s); -} - -void -Player::process_audio (shared_ptr b) -{ - Audio (b); -} - -/** @return true on error */ -bool -Player::seek (double t) -{ - if (!_have_setup_decoders) { - setup_decoders (); - _have_setup_decoders = true; - } - - bool r = false; - - switch (_playlist->video_from()) { - case Playlist::VIDEO_NONE: - break; - case Playlist::VIDEO_FFMPEG: - if (!_ffmpeg_decoder || _ffmpeg_decoder->seek (t)) { - r = true; - } - /* We're seeking, so all `all done' bets are off */ - _ffmpeg_decoder_done = false; - break; - case Playlist::VIDEO_IMAGEMAGICK: - /* Find the decoder that contains this position */ - _imagemagick_decoder = _imagemagick_decoders.begin (); - while (_imagemagick_decoder != _imagemagick_decoders.end ()) { - double const this_length = (*_imagemagick_decoder)->video_length() / _film->video_frame_rate (); - if (t < this_length) { - break; - } - t -= this_length; - ++_imagemagick_decoder; - } - - if (_imagemagick_decoder != _imagemagick_decoders.end()) { - (*_imagemagick_decoder)->seek (t); - } else { - r = true; - } - break; - } - - /* XXX: don't seek audio because we don't need to... */ - - return r; -} - -bool -Player::seek_to_last () -{ - if (!_have_setup_decoders) { - setup_decoders (); - _have_setup_decoders = true; - } - - bool r = false; - - switch (_playlist->video_from ()) { - case Playlist::VIDEO_NONE: - break; - case Playlist::VIDEO_FFMPEG: - if (!_ffmpeg_decoder || _ffmpeg_decoder->seek_to_last ()) { - r = true; - } - - /* We're seeking, so all `all done' bets are off */ - _ffmpeg_decoder_done = false; - break; - case Playlist::VIDEO_IMAGEMAGICK: - if ((*_imagemagick_decoder)->seek_to_last ()) { - r = true; - } - break; - } - - /* XXX: don't seek audio because we don't need to... */ - - return r; -} - -void -Player::setup_decoders () -{ - if ((_video && _playlist->video_from() == Playlist::VIDEO_FFMPEG) || (_audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG)) { - _ffmpeg_decoder.reset ( - new FFmpegDecoder ( - _film, - _playlist->ffmpeg(), - _video && _playlist->video_from() == Playlist::VIDEO_FFMPEG, - _audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG, - _subtitles && _film->with_subtitles(), - _video_sync - ) - ); - } - - if (_video && _playlist->video_from() == Playlist::VIDEO_FFMPEG) { - _ffmpeg_decoder->connect_video (shared_from_this ()); - } - - if (_audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG) { - _ffmpeg_decoder->connect_audio (shared_from_this ()); - } - - if (_video && _playlist->video_from() == Playlist::VIDEO_IMAGEMAGICK) { - list > ic = _playlist->imagemagick (); - for (list >::iterator i = ic.begin(); i != ic.end(); ++i) { - shared_ptr d (new ImageMagickDecoder (_film, *i)); - _imagemagick_decoders.push_back (d); - d->connect_video (shared_from_this ()); - } - - _imagemagick_decoder = _imagemagick_decoders.begin (); - } - - if (_audio && _playlist->audio_from() == Playlist::AUDIO_SNDFILE) { - list > sc = _playlist->sndfile (); - for (list >::iterator i = sc.begin(); i != sc.end(); ++i) { - shared_ptr d (new SndfileDecoder (_film, *i)); - _sndfile_decoders.push_back (d); - d->connect_audio (shared_from_this ()); - } - } -} - -void -Player::disable_video_sync () -{ - _video_sync = false; -} - -double -Player::last_video_time () const -{ - switch (_playlist->video_from ()) { - case Playlist::VIDEO_NONE: - return 0; - case Playlist::VIDEO_FFMPEG: - return _ffmpeg_decoder->last_source_time (); - case Playlist::VIDEO_IMAGEMAGICK: - return (*_imagemagick_decoder)->last_source_time (); - } - - return 0; -} diff --git a/src/lib/playlist.h b/src/lib/playlist.h index 480f1b2ed..29a52d433 100644 --- a/src/lib/playlist.h +++ b/src/lib/playlist.h @@ -93,42 +93,3 @@ private: std::list > _imagemagick; std::list > _sndfile; }; - -class Player : public VideoSource, public AudioSource, public VideoSink, public AudioSink, public boost::enable_shared_from_this -{ -public: - Player (boost::shared_ptr, boost::shared_ptr); - - void disable_video (); - void disable_audio (); - void disable_subtitles (); - void disable_video_sync (); - - bool pass (); - void set_progress (boost::shared_ptr); - bool seek (double); - bool seek_to_last (); - - double last_video_time () const; - -private: - void process_video (boost::shared_ptr i, bool same, boost::shared_ptr s); - void process_audio (boost::shared_ptr); - void setup_decoders (); - - boost::shared_ptr _film; - boost::shared_ptr _playlist; - - bool _video; - bool _audio; - bool _subtitles; - - bool _have_setup_decoders; - boost::shared_ptr _ffmpeg_decoder; - bool _ffmpeg_decoder_done; - std::list > _imagemagick_decoders; - std::list >::iterator _imagemagick_decoder; - std::list > _sndfile_decoders; - - bool _video_sync; -}; diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc index ef3a0e8c1..6744e9193 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -34,7 +34,7 @@ #include "gain.h" #include "video_decoder.h" #include "audio_decoder.h" -#include "playlist.h" +#include "player.h" using std::string; using boost::shared_ptr; diff --git a/src/lib/writer.cc b/src/lib/writer.cc index b08b9caf1..d413d33f3 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -28,7 +28,7 @@ #include "format.h" #include "log.h" #include "dcp_video_frame.h" -#include "playlist.h" +#include "player.h" #include "i18n.h" diff --git a/src/lib/wscript b/src/lib/wscript index f2bb678aa..32a2cde23 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -38,6 +38,7 @@ sources = """ log.cc lut.cc matcher.cc + player.cc playlist.cc scp_dcp_job.cc scaler.cc diff --git a/src/tools/servomatictest.cc b/src/tools/servomatictest.cc index d7e8bbb0e..d3222faa3 100644 --- a/src/tools/servomatictest.cc +++ b/src/tools/servomatictest.cc @@ -33,7 +33,7 @@ #include "scaler.h" #include "log.h" #include "video_decoder.h" -#include "playlist.h" +#include "player.h" using std::cout; using std::cerr; diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 10cb41df0..ab1fe86ce 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -59,6 +59,7 @@ using std::list; using std::vector; using boost::shared_ptr; using boost::dynamic_pointer_cast; +using boost::lexical_cast; /** @param f Film to edit */ FilmEditor::FilmEditor (shared_ptr f, wxWindow* parent) @@ -332,7 +333,7 @@ FilmEditor::make_content_panel () _content = new wxListCtrl (_content_panel, wxID_ANY, wxDefaultPosition, wxSize (320, 160), wxLC_REPORT | wxLC_NO_HEADER | wxLC_SINGLE_SEL); s->Add (_content, 1, wxEXPAND | wxTOP | wxBOTTOM, 6); - _content->InsertColumn (0, ""); + _content->InsertColumn (0, wxT("")); _content->SetColumnWidth (0, 512); wxBoxSizer* b = new wxBoxSizer (wxVERTICAL); @@ -1078,7 +1079,7 @@ FilmEditor::ffmpeg_audio_stream_changed (wxCommandEvent &) vector a = _film->ffmpeg_audio_streams (); vector::iterator i = a.begin (); string const s = string_client_data (_ffmpeg_audio_stream->GetClientObject (_ffmpeg_audio_stream->GetSelection ())); - while (i != a.end() && i->id != s) { + while (i != a.end() && lexical_cast (i->id) != s) { ++i; } @@ -1097,7 +1098,7 @@ FilmEditor::ffmpeg_subtitle_stream_changed (wxCommandEvent &) vector a = _film->ffmpeg_subtitle_streams (); vector::iterator i = a.begin (); string const s = string_client_data (_ffmpeg_subtitle_stream->GetClientObject (_ffmpeg_subtitle_stream->GetSelection ())); - while (i != a.end() && i->id != s) { + while (i != a.end() && lexical_cast (i->id) != s) { ++i; } @@ -1270,7 +1271,7 @@ FilmEditor::setup_content_information () { int const s = _content->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); if (s == -1) { - _content_information->SetValue (""); + _content_information->SetValue (wxT ("")); return; } diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 76cff3f65..f6d0f77dc 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -34,7 +34,7 @@ #include "lib/exceptions.h" #include "lib/examine_content_job.h" #include "lib/filter.h" -#include "lib/playlist.h" +#include "lib/player.h" #include "lib/video_content.h" #include "lib/ffmpeg_content.h" #include "film_viewer.h" -- cgit v1.2.3 From 7fee459e6466354a49d51f61d3e53845fd82ecc7 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 4 Apr 2013 10:20:55 +0100 Subject: GPL boilerplates. --- src/lib/audio_content.cc | 19 +++++++++++++++++++ src/lib/audio_content.h | 19 +++++++++++++++++++ src/lib/content.cc | 19 +++++++++++++++++++ src/lib/sndfile_content.cc | 19 +++++++++++++++++++ src/lib/sndfile_content.h | 19 +++++++++++++++++++ src/lib/video_content.cc | 19 +++++++++++++++++++ src/lib/video_content.h | 19 +++++++++++++++++++ 7 files changed, 133 insertions(+) (limited to 'src') diff --git a/src/lib/audio_content.cc b/src/lib/audio_content.cc index b5419a058..8ca1e83c9 100644 --- a/src/lib/audio_content.cc +++ b/src/lib/audio_content.cc @@ -1,3 +1,22 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + #include #include "audio_content.h" diff --git a/src/lib/audio_content.h b/src/lib/audio_content.h index 24391b01c..2bfc20656 100644 --- a/src/lib/audio_content.h +++ b/src/lib/audio_content.h @@ -1,3 +1,22 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + #ifndef DVDOMATIC_AUDIO_CONTENT_H #define DVDOMATIC_AUDIO_CONTENT_H diff --git a/src/lib/content.cc b/src/lib/content.cc index 0c21822cb..786b5fb09 100644 --- a/src/lib/content.cc +++ b/src/lib/content.cc @@ -1,3 +1,22 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + #include #include #include diff --git a/src/lib/sndfile_content.cc b/src/lib/sndfile_content.cc index cf7921a93..684405efb 100644 --- a/src/lib/sndfile_content.cc +++ b/src/lib/sndfile_content.cc @@ -1,3 +1,22 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + #include "sndfile_content.h" #include "compose.hpp" diff --git a/src/lib/sndfile_content.h b/src/lib/sndfile_content.h index ab8a04e4d..90845ba08 100644 --- a/src/lib/sndfile_content.h +++ b/src/lib/sndfile_content.h @@ -1,3 +1,22 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + #include "audio_content.h" namespace cxml { diff --git a/src/lib/video_content.cc b/src/lib/video_content.cc index edb713466..14897c570 100644 --- a/src/lib/video_content.cc +++ b/src/lib/video_content.cc @@ -1,3 +1,22 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + #include #include "video_content.h" #include "video_decoder.h" diff --git a/src/lib/video_content.h b/src/lib/video_content.h index 19b49e926..3d2c4cab2 100644 --- a/src/lib/video_content.h +++ b/src/lib/video_content.h @@ -1,3 +1,22 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + #ifndef DVDOMATIC_VIDEO_CONTENT_H #define DVDOMATIC_VIDEO_CONTENT_H -- cgit v1.2.3 From 5efb969c83dce8fc94b2e7184e424578fee772d1 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 4 Apr 2013 10:32:08 +0100 Subject: A little #include trimming. --- src/lib/film.cc | 5 +---- src/lib/film.h | 5 +---- src/lib/writer.cc | 2 ++ src/wx/film_editor.cc | 1 + test/test.cc | 1 + 5 files changed, 6 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/lib/film.cc b/src/lib/film.cc index 42f4b1c3d..a9d7b7381 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -35,7 +35,6 @@ #include "format.h" #include "job.h" #include "filter.h" -#include "transcoder.h" #include "util.h" #include "job_manager.h" #include "ab_transcode_job.h" @@ -48,15 +47,13 @@ #include "config.h" #include "version.h" #include "ui_signaller.h" -#include "video_decoder.h" -#include "audio_decoder.h" -#include "sndfile_decoder.h" #include "analyse_audio_job.h" #include "playlist.h" #include "player.h" #include "ffmpeg_content.h" #include "imagemagick_content.h" #include "sndfile_content.h" +#include "dcp_content_type.h" #include "i18n.h" diff --git a/src/lib/film.h b/src/lib/film.h index a03fd5d97..091ac4f97 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -32,15 +32,12 @@ #include #include #include -extern "C" { -#include -} -#include "dcp_content_type.h" #include "util.h" #include "dci_metadata.h" #include "types.h" #include "ffmpeg_content.h" +class DCPContentType; class Format; class Job; class Filter; diff --git a/src/lib/writer.cc b/src/lib/writer.cc index d413d33f3..5d38860e7 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -22,12 +22,14 @@ #include #include #include +#include #include "writer.h" #include "compose.hpp" #include "film.h" #include "format.h" #include "log.h" #include "dcp_video_frame.h" +#include "dcp_content_type.h" #include "player.h" #include "i18n.h" diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index ab1fe86ce..efbf212d0 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -40,6 +40,7 @@ #include "lib/ffmpeg_decoder.h" #include "lib/imagemagick_content.h" #include "lib/sndfile_content.h" +#include "lib/dcp_content_type.h" #include "filter_dialog.h" #include "wx_util.h" #include "film_editor.h" diff --git a/test/test.cc b/test/test.cc index 5cf3dc56d..592bad836 100644 --- a/test/test.cc +++ b/test/test.cc @@ -40,6 +40,7 @@ #include "scaler.h" #include "ffmpeg_decoder.h" #include "sndfile_decoder.h" +#include "dcp_content_type.h" #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MODULE dvdomatic_test #include -- cgit v1.2.3 From 3429cf48ff2ce056413588be4151be82c8114861 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 4 Apr 2013 10:37:32 +0100 Subject: Some unnecessary boost:: removal. --- src/lib/encoder.cc | 9 +++++---- src/lib/film.cc | 12 ++++++------ src/lib/matcher.cc | 4 ++-- src/lib/video_source.cc | 2 +- src/wx/audio_dialog.cc | 2 +- src/wx/film_viewer.cc | 2 +- src/wx/job_manager_view.cc | 4 ++-- 7 files changed, 18 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 2a8d8cc16..568307462 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -48,7 +48,8 @@ using std::vector; using std::list; using std::cout; using std::make_pair; -using namespace boost; +using boost::shared_ptr; +using boost::optional; int const Encoder::_history_size = 25; @@ -231,7 +232,7 @@ Encoder::frame_done () } void -Encoder::process_video (shared_ptr image, bool same, boost::shared_ptr sub) +Encoder::process_video (shared_ptr image, bool same, shared_ptr sub) { FrameRateConversion frc (_film->video_frame_rate(), _film->dcp_frame_rate()); @@ -269,7 +270,7 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptr const s = Filter::ffmpeg_strings (_film->filters()); TIMING ("adding to queue of %1", _queue.size ()); - _queue.push_back (boost::shared_ptr ( + _queue.push_back (shared_ptr ( new DCPVideoFrame ( image, sub, _film->format()->dcp_size(), _film->format()->dcp_padding (_film), _film->subtitle_offset(), _film->subtitle_scale(), @@ -360,7 +361,7 @@ Encoder::encoder_thread (ServerDescription* server) } TIMING ("encoder thread %1 wakes with queue of %2", boost::this_thread::get_id(), _queue.size()); - boost::shared_ptr vf = _queue.front (); + shared_ptr vf = _queue.front (); _film->log()->log (String::compose (N_("Encoder thread %1 pops frame %2 from queue"), boost::this_thread::get_id(), vf->frame()), Log::VERBOSE); _queue.pop_front (); diff --git a/src/lib/film.cc b/src/lib/film.cc index a9d7b7381..976f65313 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -1178,7 +1178,7 @@ Film::ffmpeg () const vector Film::ffmpeg_subtitle_streams () const { - boost::shared_ptr f = ffmpeg (); + shared_ptr f = ffmpeg (); if (f) { return f->subtitle_streams (); } @@ -1189,7 +1189,7 @@ Film::ffmpeg_subtitle_streams () const boost::optional Film::ffmpeg_subtitle_stream () const { - boost::shared_ptr f = ffmpeg (); + shared_ptr f = ffmpeg (); if (f) { return f->subtitle_stream (); } @@ -1200,7 +1200,7 @@ Film::ffmpeg_subtitle_stream () const vector Film::ffmpeg_audio_streams () const { - boost::shared_ptr f = ffmpeg (); + shared_ptr f = ffmpeg (); if (f) { return f->audio_streams (); } @@ -1211,7 +1211,7 @@ Film::ffmpeg_audio_streams () const boost::optional Film::ffmpeg_audio_stream () const { - boost::shared_ptr f = ffmpeg (); + shared_ptr f = ffmpeg (); if (f) { return f->audio_stream (); } @@ -1222,7 +1222,7 @@ Film::ffmpeg_audio_stream () const void Film::set_ffmpeg_subtitle_stream (FFmpegSubtitleStream s) { - boost::shared_ptr f = ffmpeg (); + shared_ptr f = ffmpeg (); if (f) { f->set_subtitle_stream (s); } @@ -1231,7 +1231,7 @@ Film::set_ffmpeg_subtitle_stream (FFmpegSubtitleStream s) void Film::set_ffmpeg_audio_stream (FFmpegAudioStream s) { - boost::shared_ptr f = ffmpeg (); + shared_ptr f = ffmpeg (); if (f) { f->set_audio_stream (s); } diff --git a/src/lib/matcher.cc b/src/lib/matcher.cc index 48f6ed912..77ed9b651 100644 --- a/src/lib/matcher.cc +++ b/src/lib/matcher.cc @@ -37,7 +37,7 @@ Matcher::Matcher (shared_ptr log, int sample_rate, float frames_per_second) } void -Matcher::process_video (boost::shared_ptr i, bool same, boost::shared_ptr s) +Matcher::process_video (shared_ptr i, bool same, shared_ptr s) { Video (i, same, s); _video_frames++; @@ -47,7 +47,7 @@ Matcher::process_video (boost::shared_ptr i, bool same, boost::shared_ptr } void -Matcher::process_audio (boost::shared_ptr b) +Matcher::process_audio (shared_ptr b) { Audio (b); _audio_frames += b->frames (); diff --git a/src/lib/video_source.cc b/src/lib/video_source.cc index 8101a6d36..1c4d6466c 100644 --- a/src/lib/video_source.cc +++ b/src/lib/video_source.cc @@ -27,7 +27,7 @@ using boost::bind; static void process_video_proxy (weak_ptr sink, shared_ptr i, bool same, shared_ptr s) { - boost::shared_ptr p = sink.lock (); + shared_ptr p = sink.lock (); if (p) { p->process_video (i, same, s); } diff --git a/src/wx/audio_dialog.cc b/src/wx/audio_dialog.cc index 242d37b1e..1241c2e76 100644 --- a/src/wx/audio_dialog.cc +++ b/src/wx/audio_dialog.cc @@ -84,7 +84,7 @@ AudioDialog::AudioDialog (wxWindow* parent) } void -AudioDialog::set_film (boost::shared_ptr f) +AudioDialog::set_film (shared_ptr f) { _film_changed_connection.disconnect (); _film_audio_analysis_succeeded_connection.disconnect (); diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index f6d0f77dc..316a42a66 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -290,7 +290,7 @@ FilmViewer::raw_to_display () old_size = _display_frame->size(); } - boost::shared_ptr input = _raw_frame; + shared_ptr input = _raw_frame; pair const s = Filter::ffmpeg_strings (_film->filters()); if (!s.second.empty ()) { diff --git a/src/wx/job_manager_view.cc b/src/wx/job_manager_view.cc index f7d2315cc..a7788ddd0 100644 --- a/src/wx/job_manager_view.cc +++ b/src/wx/job_manager_view.cc @@ -135,7 +135,7 @@ JobManagerView::details_clicked (wxCommandEvent& ev) { wxObject* o = ev.GetEventObject (); - for (map, JobRecord>::iterator i = _job_records.begin(); i != _job_records.end(); ++i) { + for (map, JobRecord>::iterator i = _job_records.begin(); i != _job_records.end(); ++i) { if (i->second.details == o) { string s = i->first->error_summary(); s[0] = toupper (s[0]); @@ -149,7 +149,7 @@ JobManagerView::cancel_clicked (wxCommandEvent& ev) { wxObject* o = ev.GetEventObject (); - for (map, JobRecord>::iterator i = _job_records.begin(); i != _job_records.end(); ++i) { + for (map, JobRecord>::iterator i = _job_records.begin(); i != _job_records.end(); ++i) { if (i->second.cancel == o) { i->first->cancel (); } -- cgit v1.2.3 From 26a7e35765ae09606ce16365acd5d9a7f2876a3f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 5 Apr 2013 10:07:06 +0100 Subject: Updated sv_SE translation from Adam Klotblixt. --- src/lib/po/sv_SE.po | 17 +++++++---------- src/tools/po/sv_SE.po | 12 +++--------- src/wx/po/sv_SE.po | 20 +++++--------------- 3 files changed, 15 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/lib/po/sv_SE.po b/src/lib/po/sv_SE.po index 1e9c40550..9af19206f 100644 --- a/src/lib/po/sv_SE.po +++ b/src/lib/po/sv_SE.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: DVD-o-matic\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-04-01 21:21+0100\n" -"PO-Revision-Date: 2013-04-02 08:13+0100\n" +"PO-Revision-Date: 2013-04-04 10:22+0100\n" "Last-Translator: Adam Klotblixt \n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -156,9 +156,7 @@ msgstr "Kantighetsutjämning" msgid "De-interlacing" msgstr "Avflätning" -# Ja vad heter "dering" på svenska? #: src/lib/filter.cc:74 -#, fuzzy msgid "Deringing filter" msgstr "Avringningsfilter" @@ -208,7 +206,7 @@ msgstr "Snabb bilinjär" #: src/lib/dcp_content_type.cc:44 msgid "Feature" -msgstr "Spelfilm" +msgstr "Långfilm" #: src/lib/format.cc:120 msgid "Flat" @@ -314,7 +312,7 @@ msgstr "Offentligt Servicemeddelande" #: src/lib/dcp_content_type.cc:49 msgid "Rating" -msgstr "Klassificering" +msgstr "Klassificeringsklipp" #: src/lib/util.cc:499 msgid "Rec 709" @@ -439,13 +437,13 @@ msgstr "Konvertera %1" #: src/lib/dcp_content_type.cc:48 msgid "Transitional" -msgstr "Övergångs-" +msgstr "Övergångsklipp" #: src/lib/job.cc:100 msgid "Unknown error" msgstr "Okänt fel" -# Ganska svengelskt... +# Svengelska #: src/lib/ffmpeg_decoder.cc:396 #, fuzzy msgid "Unrecognised audio sample format (%1)" @@ -471,9 +469,8 @@ msgstr "Väntar" msgid "X" msgstr "X" -# Filtret heter så, ska ej översättas? +# Filtret heter så, ska ej översättas #: src/lib/filter.cc:83 -#, fuzzy msgid "Yet Another Deinterlacing Filter" msgstr "Yet Another Deinterlacing Filter" @@ -481,7 +478,7 @@ msgstr "Yet Another Deinterlacing Filter" msgid "cannot contain slashes" msgstr "får inte innehålla snedstreck" -# mer svengelska +# Svengelska #: src/lib/util.cc:540 #, fuzzy msgid "connect timed out" diff --git a/src/tools/po/sv_SE.po b/src/tools/po/sv_SE.po index 6e2efb490..c007785f3 100644 --- a/src/tools/po/sv_SE.po +++ b/src/tools/po/sv_SE.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: DVD-o-matic\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-04-01 21:21+0100\n" -"PO-Revision-Date: 2013-04-02 08:50+0100\n" +"PO-Revision-Date: 2013-04-04 10:11+0100\n" "Last-Translator: Adam Klotblixt \n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -78,9 +78,8 @@ msgstr "Om" msgid "Could not load film %1 (%2)" msgstr "Kunde inte öppna filmen %1 (%2)" -# "vid" eller nåt annat? #: src/tools/dvdomatic.cc:331 -#, fuzzy, c-format +#, c-format msgid "Could not open film at %s (%s)" msgstr "Kunde inte öppna filmen vid %s (%s)" @@ -89,9 +88,7 @@ msgstr "Kunde inte öppna filmen vid %s (%s)" msgid "DVD-o-matic" msgstr "DVD-o-matic" -# Film bytt? #: src/tools/dvdomatic.cc:75 -#, fuzzy msgid "Film changed" msgstr "Film ändrad" @@ -100,11 +97,9 @@ msgid "Free, open-source DCP generation from almost anything." msgstr "" "Fri, öppen-källkodsprogramvara för DCP-generering från nästan vad som helst." -# Ny? #: src/tools/dvdomatic.cc:160 -#, fuzzy msgid "New..." -msgstr "Skapa..." +msgstr "Ny..." #: src/tools/dvdomatic.cc:175 msgid "S&how DCP" @@ -119,6 +114,5 @@ msgid "Select film to open" msgstr "Välj film att öppna" #: src/tools/dvdomatic.cc:303 -#, fuzzy msgid "The directory %1 already exists." msgstr "Katalogen %1 finns redan." diff --git a/src/wx/po/sv_SE.po b/src/wx/po/sv_SE.po index 41f97a846..24a6060de 100644 --- a/src/wx/po/sv_SE.po +++ b/src/wx/po/sv_SE.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: DVD-o-matic\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-04-01 21:21+0100\n" -"PO-Revision-Date: 2013-04-02 08:50+0100\n" +"PO-Revision-Date: 2013-04-04 10:18+0100\n" "Last-Translator: Adam Klotblixt \n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -65,11 +65,9 @@ msgstr "Nedre beskärning" msgid "Browse..." msgstr "Bläddra..." -# vad åsyftas med "fader"? #: src/wx/gain_calculator_dialog.cc:36 -#, fuzzy msgid "But I have to use fader" -msgstr "Men jag måste använda toning" +msgstr "Men jag måste använda mixervolym" #: src/wx/film_editor.cc:374 msgid "Calculate..." @@ -181,11 +179,9 @@ msgstr "Kodningsservrar" msgid "End" msgstr "Slut" -# vad betyder "facility" i detta sammanhang? #: src/wx/dci_metadata_dialog.cc:53 -#, fuzzy msgid "Facility (e.g. DLA)" -msgstr "Enhet (ex. DLA)" +msgstr "Företag (ex. DLA)" #: src/wx/film_editor.cc:73 msgid "Film" @@ -231,11 +227,9 @@ msgstr "Värd-namn eller IP-adress" msgid "Hz" msgstr "Hz" -# vad åsyftas med "fader"? #: src/wx/gain_calculator_dialog.cc:32 -#, fuzzy msgid "I want to play this back at fader" -msgstr "Jag vill spela upp detta med toning" +msgstr "Jag vill spela upp detta med mixervolym" #: src/wx/config_dialog.cc:132 msgid "IP address" @@ -301,9 +295,7 @@ msgstr "Vänligen vänta; audio analyseras..." msgid "RMS" msgstr "RMS" -# Är det censurklassning som åsyftas? #: src/wx/dci_metadata_dialog.cc:45 -#, fuzzy msgid "Rating (e.g. 15)" msgstr "Klassificering (ex. 15)" @@ -419,11 +411,9 @@ msgstr "Tid" msgid "Top crop" msgstr "Övre beskärning" -# "välj bilder att koda"? #: src/wx/film_editor.cc:171 -#, fuzzy msgid "Trim frames" -msgstr "Beskära bilder" +msgstr "Skippa bilder" #: src/wx/film_editor.cc:125 msgid "Trust content's header" -- cgit v1.2.3 From 1bff0990433ab0ce588acaef7c589fa623bd998b Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 6 Apr 2013 12:26:12 +0100 Subject: Add interface to set up still image lengths. --- src/lib/content.cc | 9 ++- src/lib/content.h | 7 ++- src/lib/ffmpeg_content.cc | 15 +++-- src/lib/ffmpeg_content.h | 6 +- src/lib/film.cc | 26 ++++---- src/lib/film.h | 7 +-- src/lib/imagemagick_content.cc | 15 ++++- src/lib/imagemagick_content.h | 8 ++- src/lib/player.cc | 40 ++++++++++--- src/lib/player.h | 4 +- src/lib/playlist.cc | 16 +++++ src/lib/playlist.h | 7 +++ src/lib/sndfile_content.h | 4 ++ src/lib/video_content.cc | 8 ++- src/wx/film_editor.cc | 132 ++++++++++++++++++++++++++++------------- src/wx/film_editor.h | 9 +-- src/wx/film_viewer.cc | 41 ++++--------- src/wx/film_viewer.h | 2 - 18 files changed, 237 insertions(+), 119 deletions(-) (limited to 'src') diff --git a/src/lib/content.cc b/src/lib/content.cc index 786b5fb09..9c3bcd39d 100644 --- a/src/lib/content.cc +++ b/src/lib/content.cc @@ -39,7 +39,8 @@ Content::Content (shared_ptr node) } Content::Content (Content const & o) - : _file (o._file) + : boost::enable_shared_from_this (o) + , _file (o._file) , _digest (o._digest) { @@ -60,3 +61,9 @@ Content::examine (shared_ptr, shared_ptr, bool) boost::mutex::scoped_lock lm (_mutex); _digest = d; } + +void +Content::signal_changed (int p) +{ + Changed (shared_from_this (), p); +} diff --git a/src/lib/content.h b/src/lib/content.h index 11c7438a6..fc2672c95 100644 --- a/src/lib/content.h +++ b/src/lib/content.h @@ -23,6 +23,7 @@ #include #include #include +#include #include namespace cxml { @@ -32,7 +33,7 @@ namespace cxml { class Job; class Film; -class Content +class Content : public boost::enable_shared_from_this { public: Content (boost::filesystem::path); @@ -50,9 +51,11 @@ public: return _file; } - boost::signals2::signal Changed; + boost::signals2::signal, int)> Changed; protected: + void signal_changed (int); + mutable boost::mutex _mutex; private: diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index 7834cb76e..cc95105e5 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -73,7 +73,6 @@ FFmpegContent::FFmpegContent (FFmpegContent const & o) : Content (o) , VideoContent (o) , AudioContent (o) - , boost::enable_shared_from_this (o) , _subtitle_streams (o._subtitle_streams) , _subtitle_stream (o._subtitle_stream) , _audio_streams (o._audio_streams) @@ -148,11 +147,11 @@ FFmpegContent::examine (shared_ptr film, shared_ptr job, bool quick) take_from_video_decoder (decoder); - Changed (VideoContentProperty::VIDEO_LENGTH); - Changed (FFmpegContentProperty::SUBTITLE_STREAMS); - Changed (FFmpegContentProperty::SUBTITLE_STREAM); - Changed (FFmpegContentProperty::AUDIO_STREAMS); - Changed (FFmpegContentProperty::AUDIO_STREAM); + signal_changed (VideoContentProperty::VIDEO_LENGTH); + signal_changed (FFmpegContentProperty::SUBTITLE_STREAMS); + signal_changed (FFmpegContentProperty::SUBTITLE_STREAM); + signal_changed (FFmpegContentProperty::AUDIO_STREAMS); + signal_changed (FFmpegContentProperty::AUDIO_STREAM); } string @@ -184,7 +183,7 @@ FFmpegContent::set_subtitle_stream (FFmpegSubtitleStream s) _subtitle_stream = s; } - Changed (FFmpegContentProperty::SUBTITLE_STREAM); + signal_changed (FFmpegContentProperty::SUBTITLE_STREAM); } void @@ -195,7 +194,7 @@ FFmpegContent::set_audio_stream (FFmpegAudioStream s) _audio_stream = s; } - Changed (FFmpegContentProperty::AUDIO_STREAM); + signal_changed (FFmpegContentProperty::AUDIO_STREAM); } ContentAudioFrame diff --git a/src/lib/ffmpeg_content.h b/src/lib/ffmpeg_content.h index 3d69a2f99..cc603e680 100644 --- a/src/lib/ffmpeg_content.h +++ b/src/lib/ffmpeg_content.h @@ -77,12 +77,16 @@ public: static int const AUDIO_STREAM; }; -class FFmpegContent : public VideoContent, public AudioContent, public boost::enable_shared_from_this +class FFmpegContent : public VideoContent, public AudioContent { public: FFmpegContent (boost::filesystem::path); FFmpegContent (boost::shared_ptr); FFmpegContent (FFmpegContent const &); + + boost::shared_ptr shared_from_this () { + return boost::dynamic_pointer_cast (Content::shared_from_this ()); + } void examine (boost::shared_ptr, boost::shared_ptr, bool); std::string summary () const; diff --git a/src/lib/film.cc b/src/lib/film.cc index 976f65313..69d2a28e2 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -110,6 +110,8 @@ Film::Film (string d, bool must_exist) , _dirty (false) { set_dci_date_today (); + + _playlist->ContentChanged.connect (bind (&Film::content_changed, this, _1, _2)); /* Make state.directory a complete path without ..s (where possible) (Code swiped from Adam Bowen on stackoverflow) @@ -179,6 +181,8 @@ Film::Film (Film const & o) _content.push_back ((*i)->clone ()); } + _playlist->ContentChanged.connect (bind (&Film::content_changed, this, _1, _2)); + _playlist->setup (_content); } @@ -485,14 +489,17 @@ Film::read_metadata () for (list >::iterator i = c.begin(); i != c.end(); ++i) { string const type = (*i)->string_child ("Type"); + boost::shared_ptr c; if (type == "FFmpeg") { - _content.push_back (shared_ptr (new FFmpegContent (*i))); + c.reset (new FFmpegContent (*i)); } else if (type == "ImageMagick") { - _content.push_back (shared_ptr (new ImageMagickContent (*i))); + c.reset (new ImageMagickContent (*i)); } else if (type == "Sndfile") { - _content.push_back (shared_ptr (new SndfileContent (*i))); + c.reset (new SndfileContent (*i)); } + + _content.push_back (c); } _dirty = false; @@ -1037,7 +1044,6 @@ Film::add_content (shared_ptr c) { boost::mutex::scoped_lock lm (_state_mutex); _content.push_back (c); - _content_connections.push_back (c->Changed.connect (bind (&Film::content_changed, this, _1))); } signal_changed (CONTENT); @@ -1054,14 +1060,6 @@ Film::remove_content (shared_ptr c) if (i != _content.end ()) { _content.erase (i); } - - for (list::iterator i = _content_connections.begin(); i != _content_connections.end(); ++i) { - i->disconnect (); - } - - for (ContentList::iterator i = _content.begin(); i != _content.end(); ++i) { - _content_connections.push_back (c->Changed.connect (bind (&Film::content_changed, this, _1))); - } } signal_changed (CONTENT); @@ -1238,13 +1236,13 @@ Film::set_ffmpeg_audio_stream (FFmpegAudioStream s) } void -Film::content_changed (int p) +Film::content_changed (boost::weak_ptr c, int p) { if (p == VideoContentProperty::VIDEO_FRAME_RATE) { set_dcp_frame_rate (best_dcp_frame_rate (video_frame_rate ())); } if (ui_signaller) { - ui_signaller->emit (boost::bind (boost::ref (ContentChanged), p)); + ui_signaller->emit (boost::bind (boost::ref (ContentChanged), c, p)); } } diff --git a/src/lib/film.h b/src/lib/film.h index 091ac4f97..9c5f561e6 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -119,7 +119,7 @@ public: void set_ffmpeg_subtitle_stream (FFmpegSubtitleStream); void set_ffmpeg_audio_stream (FFmpegAudioStream); - + /** Identifiers for the parts of our state; used for signalling changes. */ @@ -299,7 +299,7 @@ public: mutable boost::signals2::signal Changed; /** Emitted when some property of our content has changed */ - mutable boost::signals2::signal ContentChanged; + mutable boost::signals2::signal, int)> ContentChanged; boost::signals2::signal AudioAnalysisSucceeded; @@ -312,7 +312,7 @@ private: void analyse_audio_finished (); std::string video_state_identifier () const; void read_metadata (); - void content_changed (int); + void content_changed (boost::weak_ptr, int); boost::shared_ptr ffmpeg () const; /** Log to write to */ @@ -334,7 +334,6 @@ private: bool _use_dci_name; bool _trust_content_headers; ContentList _content; - std::list _content_connections; /** The type of content that this Film represents (feature, trailer etc.) */ DCPContentType const * _dcp_content_type; /** The format to present this Film in (flat, scope, etc.) */ diff --git a/src/lib/imagemagick_content.cc b/src/lib/imagemagick_content.cc index f7c76a34d..912c180a8 100644 --- a/src/lib/imagemagick_content.cc +++ b/src/lib/imagemagick_content.cc @@ -72,13 +72,13 @@ ImageMagickContent::examine (shared_ptr film, shared_ptr job, bool qu { boost::mutex::scoped_lock lm (_mutex); - /* XXX */ + /* Initial length */ _video_length = 10 * 24; } take_from_video_decoder (decoder); - Changed (VideoContentProperty::VIDEO_LENGTH); + signal_changed (VideoContentProperty::VIDEO_LENGTH); } shared_ptr @@ -86,3 +86,14 @@ ImageMagickContent::clone () const { return shared_ptr (new ImageMagickContent (*this)); } + +void +ImageMagickContent::set_video_length (ContentVideoFrame len) +{ + { + boost::mutex::scoped_lock lm (_mutex); + _video_length = len; + } + + signal_changed (VideoContentProperty::VIDEO_LENGTH); +} diff --git a/src/lib/imagemagick_content.h b/src/lib/imagemagick_content.h index 2ca58f255..b1e7f9495 100644 --- a/src/lib/imagemagick_content.h +++ b/src/lib/imagemagick_content.h @@ -24,16 +24,22 @@ namespace cxml { class Node; } -class ImageMagickContent : public VideoContent, public boost::enable_shared_from_this +class ImageMagickContent : public VideoContent { public: ImageMagickContent (boost::filesystem::path); ImageMagickContent (boost::shared_ptr); + boost::shared_ptr shared_from_this () { + return boost::dynamic_pointer_cast (Content::shared_from_this ()); + }; + void examine (boost::shared_ptr, boost::shared_ptr, bool); std::string summary () const; void as_xml (xmlpp::Node *) const; boost::shared_ptr clone () const; + void set_video_length (ContentVideoFrame); + static bool valid_file (boost::filesystem::path); }; diff --git a/src/lib/player.cc b/src/lib/player.cc index 6e2e7ed14..60917ba09 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -27,6 +27,8 @@ using std::list; using boost::shared_ptr; +using boost::weak_ptr; +using boost::dynamic_pointer_cast; Player::Player (shared_ptr f, shared_ptr p) : _film (f) @@ -34,11 +36,12 @@ Player::Player (shared_ptr f, shared_ptr p) , _video (true) , _audio (true) , _subtitles (true) - , _have_setup_decoders (false) + , _have_valid_decoders (false) , _ffmpeg_decoder_done (false) , _video_sync (true) { - + _playlist->Changed.connect (bind (&Player::playlist_changed, this)); + _playlist->ContentChanged.connect (bind (&Player::content_changed, this, _1, _2)); } void @@ -62,9 +65,9 @@ Player::disable_subtitles () bool Player::pass () { - if (!_have_setup_decoders) { + if (!_have_valid_decoders) { setup_decoders (); - _have_setup_decoders = true; + _have_valid_decoders = true; } bool done = true; @@ -138,9 +141,9 @@ Player::process_audio (shared_ptr b) bool Player::seek (double t) { - if (!_have_setup_decoders) { + if (!_have_valid_decoders) { setup_decoders (); - _have_setup_decoders = true; + _have_valid_decoders = true; } bool r = false; @@ -183,9 +186,9 @@ Player::seek (double t) bool Player::seek_to_last () { - if (!_have_setup_decoders) { + if (!_have_valid_decoders) { setup_decoders (); - _have_setup_decoders = true; + _have_valid_decoders = true; } bool r = false; @@ -278,3 +281,24 @@ Player::last_video_time () const return 0; } + +void +Player::content_changed (weak_ptr w, int p) +{ + shared_ptr c = w.lock (); + if (!c) { + return; + } + + if (p == VideoContentProperty::VIDEO_LENGTH) { + if (dynamic_pointer_cast (c)) { + _have_valid_decoders = false; + } + } +} + +void +Player::playlist_changed () +{ + _have_valid_decoders = false; +} diff --git a/src/lib/player.h b/src/lib/player.h index bc728d8f2..79203692e 100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@ -56,6 +56,8 @@ private: void process_video (boost::shared_ptr i, bool same, boost::shared_ptr s); void process_audio (boost::shared_ptr); void setup_decoders (); + void playlist_changed (); + void content_changed (boost::weak_ptr, int); boost::shared_ptr _film; boost::shared_ptr _playlist; @@ -64,7 +66,7 @@ private: bool _audio; bool _subtitles; - bool _have_setup_decoders; + bool _have_valid_decoders; boost::shared_ptr _ffmpeg_decoder; bool _ffmpeg_decoder_done; std::list > _imagemagick_decoders; diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index 0a4803f6e..e0220ef6f 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -31,6 +31,7 @@ using std::list; using std::cout; using std::vector; using boost::shared_ptr; +using boost::weak_ptr; using boost::dynamic_pointer_cast; Playlist::Playlist () @@ -50,6 +51,12 @@ Playlist::setup (ContentList content) _imagemagick.clear (); _sndfile.clear (); + for (list::iterator i = _content_connections.begin(); i != _content_connections.end(); ++i) { + i->disconnect (); + } + + _content_connections.clear (); + for (ContentList::const_iterator i = content.begin(); i != content.end(); ++i) { shared_ptr fc = dynamic_pointer_cast (*i); if (fc) { @@ -74,7 +81,11 @@ Playlist::setup (ContentList content) _sndfile.push_back (sc); _audio_from = AUDIO_SNDFILE; } + + _content_connections.push_back ((*i)->Changed.connect (bind (&Playlist::content_changed, this, _1, _2))); } + + Changed (); } ContentAudioFrame @@ -208,3 +219,8 @@ Playlist::has_audio () const return _audio_from != AUDIO_NONE; } +void +Playlist::content_changed (weak_ptr c, int p) +{ + ContentChanged (c, p); +} diff --git a/src/lib/playlist.h b/src/lib/playlist.h index 29a52d433..1a24a0227 100644 --- a/src/lib/playlist.h +++ b/src/lib/playlist.h @@ -84,12 +84,19 @@ public: std::list > sndfile () const { return _sndfile; } + + mutable boost::signals2::signal Changed; + mutable boost::signals2::signal, int)> ContentChanged; private: + void content_changed (boost::weak_ptr, int); + VideoFrom _video_from; AudioFrom _audio_from; boost::shared_ptr _ffmpeg; std::list > _imagemagick; std::list > _sndfile; + + std::list _content_connections; }; diff --git a/src/lib/sndfile_content.h b/src/lib/sndfile_content.h index 90845ba08..b696b57a5 100644 --- a/src/lib/sndfile_content.h +++ b/src/lib/sndfile_content.h @@ -28,6 +28,10 @@ class SndfileContent : public AudioContent public: SndfileContent (boost::filesystem::path); SndfileContent (boost::shared_ptr); + + boost::shared_ptr shared_from_this () { + return boost::dynamic_pointer_cast (Content::shared_from_this ()); + } std::string summary () const; std::string information () const; diff --git a/src/lib/video_content.cc b/src/lib/video_content.cc index 14897c570..8176c5c41 100644 --- a/src/lib/video_content.cc +++ b/src/lib/video_content.cc @@ -81,14 +81,18 @@ VideoContent::take_from_video_decoder (shared_ptr d) _video_frame_rate = vfr; } - Changed (VideoContentProperty::VIDEO_SIZE); - Changed (VideoContentProperty::VIDEO_FRAME_RATE); + signal_changed (VideoContentProperty::VIDEO_SIZE); + signal_changed (VideoContentProperty::VIDEO_FRAME_RATE); } string VideoContent::information () const { + if (video_size().width == 0 || video_size().height == 0) { + return ""; + } + stringstream s; s << String::compose ( diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index efbf212d0..58fc077a3 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -59,13 +59,13 @@ using std::setprecision; using std::list; using std::vector; using boost::shared_ptr; +using boost::weak_ptr; using boost::dynamic_pointer_cast; using boost::lexical_cast; /** @param f Film to edit */ FilmEditor::FilmEditor (shared_ptr f, wxWindow* parent) : wxPanel (parent) - , _film (f) , _generally_sensitive (true) , _audio_dialog (0) { @@ -84,7 +84,7 @@ FilmEditor::FilmEditor (shared_ptr f, wxWindow* parent) make_subtitle_panel (); _notebook->AddPage (_subtitle_panel, _("Subtitles"), false); - set_film (_film); + set_film (f); connect_to_widgets (); JobManager::instance()->ActiveJobsChanged.connect ( @@ -200,6 +200,7 @@ FilmEditor::connect_to_widgets () _content_remove->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_remove_clicked), 0, this); _content_earlier->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_earlier_clicked), 0, this); _content_later->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_later_clicked), 0, this); + _imagemagick_video_length->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::imagemagick_video_length_changed), 0, this); _left_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::left_crop_changed), 0, this); _right_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::right_crop_changed), 0, this); _top_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::top_crop_changed), 0, this); @@ -354,6 +355,21 @@ FilmEditor::make_content_panel () _content_information = new wxTextCtrl (_content_panel, wxID_ANY, wxT ("\n\n\n\n"), wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxTE_MULTILINE); _content_sizer->Add (_content_information, 1, wxEXPAND | wxALL, 6); + + wxFlexGridSizer* grid = new wxFlexGridSizer (2, 4, 4); + _content_sizer->Add (grid, 0, wxEXPAND | wxALL, 6); + + { + add_label_to_sizer (grid, _content_panel, (_("Duration"))); + wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); + _imagemagick_video_length = new wxSpinCtrl (_content_panel); + s->Add (_imagemagick_video_length); + /// TRANSLATORS: this is an abbreviation for seconds, the unit of time + add_label_to_sizer (s, _content_panel, _("s")); + grid->Add (s); + } + + _imagemagick_video_length->SetRange (1, 3600); } void @@ -690,7 +706,7 @@ FilmEditor::film_changed (Film::Property p) } void -FilmEditor::film_content_changed (int p) +FilmEditor::film_content_changed (weak_ptr content, int property) { if (!_film) { /* We call this method ourselves (as well as using it as a signal handler) @@ -699,23 +715,31 @@ FilmEditor::film_content_changed (int p) return; } - if (p == FFmpegContentProperty::SUBTITLE_STREAMS) { + if (property == FFmpegContentProperty::SUBTITLE_STREAMS) { setup_subtitle_control_sensitivity (); setup_streams (); - } else if (p == FFmpegContentProperty::AUDIO_STREAMS) { + } else if (property == FFmpegContentProperty::AUDIO_STREAMS) { setup_streams (); setup_show_audio_sensitivity (); - } else if (p == VideoContentProperty::VIDEO_LENGTH) { + } else if (property == VideoContentProperty::VIDEO_LENGTH) { setup_length (); - setup_content_information (); - } else if (p == FFmpegContentProperty::AUDIO_STREAM) { + + boost::shared_ptr c = content.lock (); + if (c && c == selected_content()) { + setup_content_information (); + shared_ptr im = dynamic_pointer_cast (c); + if (im) { + checked_set (_imagemagick_video_length, im->video_length() / 24); + } + } + } else if (property == FFmpegContentProperty::AUDIO_STREAM) { if (_film->ffmpeg_audio_stream()) { checked_set (_ffmpeg_audio_stream, boost::lexical_cast (_film->ffmpeg_audio_stream()->id)); } setup_dcp_name (); setup_audio_details (); setup_show_audio_sensitivity (); - } else if (p == FFmpegContentProperty::SUBTITLE_STREAM) { + } else if (property == FFmpegContentProperty::SUBTITLE_STREAM) { if (_film->ffmpeg_subtitle_stream()) { checked_set (_ffmpeg_subtitle_stream, boost::lexical_cast (_film->ffmpeg_subtitle_stream()->id)); } @@ -797,13 +821,17 @@ FilmEditor::dcp_content_type_changed (wxCommandEvent &) void FilmEditor::set_film (shared_ptr f) { + if (_film == f) { + return; + } + _film = f; set_things_sensitive (_film != 0); if (_film) { _film->Changed.connect (bind (&FilmEditor::film_changed, this, _1)); - _film->ContentChanged.connect (bind (&FilmEditor::film_content_changed, this, _1)); + _film->ContentChanged.connect (bind (&FilmEditor::film_content_changed, this, _1, _2)); } if (_film) { @@ -838,10 +866,10 @@ FilmEditor::set_film (shared_ptr f) film_changed (Film::DCI_METADATA); film_changed (Film::DCP_FRAME_RATE); - film_content_changed (FFmpegContentProperty::SUBTITLE_STREAMS); - film_content_changed (FFmpegContentProperty::SUBTITLE_STREAM); - film_content_changed (FFmpegContentProperty::AUDIO_STREAMS); - film_content_changed (FFmpegContentProperty::AUDIO_STREAM); + film_content_changed (boost::shared_ptr (), FFmpegContentProperty::SUBTITLE_STREAMS); + film_content_changed (boost::shared_ptr (), FFmpegContentProperty::SUBTITLE_STREAM); + film_content_changed (boost::shared_ptr (), FFmpegContentProperty::AUDIO_STREAMS); + film_content_changed (boost::shared_ptr (), FFmpegContentProperty::AUDIO_STREAM); } /** Updates the sensitivity of lots of widgets to a given value. @@ -1224,40 +1252,28 @@ FilmEditor::content_add_clicked (wxCommandEvent &) void FilmEditor::content_remove_clicked (wxCommandEvent &) { - int const s = _content->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - if (s == -1) { - return; + shared_ptr c = selected_content (); + if (c) { + _film->remove_content (c); } - - ContentList c = _film->content (); - assert (s >= 0 && size_t (s) < c.size ()); - _film->remove_content (c[s]); } void FilmEditor::content_earlier_clicked (wxCommandEvent &) { - int const s = _content->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - if (s == -1) { - return; + shared_ptr c = selected_content (); + if (c) { + _film->move_content_earlier (c); } - - ContentList c = _film->content (); - assert (s >= 0 && size_t (s) < c.size ()); - _film->move_content_earlier (c[s]); } void FilmEditor::content_later_clicked (wxCommandEvent &) { - int const s = _content->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - if (s == -1) { - return; + shared_ptr c = selected_content (); + if (c) { + _film->move_content_later (c); } - - ContentList c = _film->content (); - assert (s >= 0 && size_t (s) < c.size ()); - _film->move_content_later (c[s]); } void @@ -1265,20 +1281,27 @@ FilmEditor::content_item_selected (wxListEvent &) { setup_content_button_sensitivity (); setup_content_information (); + + shared_ptr c = selected_content (); + if (c) { + shared_ptr im = dynamic_pointer_cast (c); + _imagemagick_video_length->Enable (im); + if (im) { + checked_set (_imagemagick_video_length, im->video_length() / 24); + } + } } void FilmEditor::setup_content_information () { - int const s = _content->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - if (s == -1) { + shared_ptr c = selected_content (); + if (!c) { _content_information->SetValue (wxT ("")); return; } - ContentList c = _film->content (); - assert (s >= 0 && size_t (s) < c.size ()); - _content_information->SetValue (std_to_wx (c[s]->information ())); + _content_information->SetValue (std_to_wx (c->information ())); } void @@ -1291,3 +1314,32 @@ FilmEditor::setup_content_button_sensitivity () _content_earlier->Enable (have_selection && _generally_sensitive); _content_later->Enable (have_selection && _generally_sensitive); } + +void +FilmEditor::imagemagick_video_length_changed (wxCommandEvent &) +{ + shared_ptr c = selected_content (); + if (!c) { + return; + } + + shared_ptr im = dynamic_pointer_cast (c); + if (!im) { + return; + } + + im->set_video_length (_imagemagick_video_length->GetValue() * 24); +} + +shared_ptr +FilmEditor::selected_content () +{ + int const s = _content->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (s == -1) { + return shared_ptr (); + } + + ContentList c = _film->content (); + assert (s >= 0 && size_t (s) < c.size ()); + return c[s]; +} diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index 97d1e0dd3..2870714f9 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -68,6 +68,7 @@ private: void content_remove_clicked (wxCommandEvent &); void content_earlier_clicked (wxCommandEvent &); void content_later_clicked (wxCommandEvent &); + void imagemagick_video_length_changed (wxCommandEvent &); void format_changed (wxCommandEvent &); void trim_start_changed (wxCommandEvent &); void trim_end_changed (wxCommandEvent &); @@ -87,13 +88,11 @@ private: void ffmpeg_subtitle_stream_changed (wxCommandEvent &); void dcp_frame_rate_changed (wxCommandEvent &); void best_dcp_frame_rate_clicked (wxCommandEvent &); + void edit_filters_clicked (wxCommandEvent &); /* Handle changes to the model */ void film_changed (Film::Property); - void film_content_changed (int); - - /* Button clicks */ - void edit_filters_clicked (wxCommandEvent &); + void film_content_changed (boost::weak_ptr, int); void set_things_sensitive (bool); void setup_formats (); @@ -109,6 +108,7 @@ private: void setup_content_information (); void active_jobs_changed (bool); + boost::shared_ptr selected_content (); wxNotebook* _notebook; wxPanel* _film_panel; @@ -134,6 +134,7 @@ private: wxButton* _content_earlier; wxButton* _content_later; wxTextCtrl* _content_information; + wxSpinCtrl* _imagemagick_video_length; wxButton* _edit_dci_button; wxChoice* _format; wxStaticText* _format_description; diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 316a42a66..08358c519 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -37,6 +37,7 @@ #include "lib/player.h" #include "lib/video_content.h" #include "lib/ffmpeg_content.h" +#include "lib/imagemagick_content.h" #include "film_viewer.h" #include "wx_util.h" #include "video_decoder.h" @@ -47,6 +48,7 @@ using std::max; using std::cout; using std::list; using boost::shared_ptr; +using boost::dynamic_pointer_cast; using libdcp::Size; FilmViewer::FilmViewer (shared_ptr f, wxWindow* p) @@ -84,6 +86,16 @@ FilmViewer::FilmViewer (shared_ptr f, wxWindow* p) set_film (f); + _player = _film->player (); + _player->disable_audio (); + _player->disable_video_sync (); + + /* Don't disable subtitles here as we may need them, and it's nice to be able to turn them + on and off without needing obtain a new Player. + */ + + _player->Video.connect (bind (&FilmViewer::process_video, this, _1, _2, _3)); + JobManager::instance()->ActiveJobsChanged.connect ( bind (&FilmViewer::active_jobs_changed, this, _1) ); @@ -99,7 +111,6 @@ FilmViewer::film_changed (Film::Property p) break; case Film::CONTENT: { - setup_player (); calculate_sizes (); get_frame (); _panel->Refresh (); @@ -123,32 +134,6 @@ FilmViewer::film_changed (Film::Property p) } } -void -FilmViewer::setup_player () -{ - _player = _film->player (); - _player->disable_audio (); - _player->disable_video_sync (); - - /* Don't disable subtitles here as we may need them, and it's nice to be able to turn them - on and off without needing obtain a new Player. - */ - - _player->Video.connect (bind (&FilmViewer::process_video, this, _1, _2, _3)); -} - -void -FilmViewer::film_content_changed (int p) -{ - if (p == VideoContentProperty::VIDEO_LENGTH || p == VideoContentProperty::VIDEO_SIZE) { - setup_player (); - calculate_sizes (); - get_frame (); - _panel->Refresh (); - _v_sizer->Layout (); - } -} - void FilmViewer::set_film (shared_ptr f) { @@ -163,14 +148,12 @@ FilmViewer::set_film (shared_ptr f) } _film->Changed.connect (boost::bind (&FilmViewer::film_changed, this, _1)); - _film->ContentChanged.connect (boost::bind (&FilmViewer::film_content_changed, this, _1)); film_changed (Film::CONTENT); film_changed (Film::FORMAT); film_changed (Film::WITH_SUBTITLES); film_changed (Film::SUBTITLE_OFFSET); film_changed (Film::SUBTITLE_SCALE); - film_content_changed (FFmpegContentProperty::SUBTITLE_STREAM); } void diff --git a/src/wx/film_viewer.h b/src/wx/film_viewer.h index bf956ef95..22f443703 100644 --- a/src/wx/film_viewer.h +++ b/src/wx/film_viewer.h @@ -61,7 +61,6 @@ public: private: void film_changed (Film::Property); - void film_content_changed (int); void paint_panel (wxPaintEvent &); void panel_sized (wxSizeEvent &); void slider_moved (wxScrollEvent &); @@ -75,7 +74,6 @@ private: void raw_to_display (); void get_frame (); void active_jobs_changed (bool); - void setup_player (); boost::shared_ptr _film; boost::shared_ptr _player; -- cgit v1.2.3 From 8750efb9e072cf3b42e6c3c29521c7031c0b5dfd Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 6 Apr 2013 14:42:08 +0100 Subject: Basics of content dialogs. --- src/lib/audio_content.cc | 4 ++ src/lib/audio_content.h | 8 +++ src/lib/audio_mapping.cc | 103 +++++++++++++++++++++++++++++++++++ src/lib/audio_mapping.h | 53 ++++++++++++++++++ src/lib/encoder.cc | 3 +- src/lib/sndfile_content.cc | 84 +++++++++++++++++----------- src/lib/sndfile_content.h | 32 +++++++++-- src/lib/sndfile_decoder.cc | 65 +++++++++++----------- src/lib/sndfile_decoder.h | 8 +++ src/lib/util.cc | 52 ------------------ src/lib/util.h | 13 ----- src/lib/writer.cc | 3 +- src/lib/wscript | 1 + src/wx/audio_dialog.cc | 7 ++- src/wx/film_editor.cc | 79 +++++++++++---------------- src/wx/film_editor.h | 5 +- src/wx/imagemagick_content_dialog.cc | 62 +++++++++++++++++++++ src/wx/imagemagick_content_dialog.h | 34 ++++++++++++ src/wx/sndfile_content_dialog.cc | 67 +++++++++++++++++++++++ src/wx/sndfile_content_dialog.h | 36 ++++++++++++ src/wx/wscript | 2 + 21 files changed, 536 insertions(+), 185 deletions(-) create mode 100644 src/lib/audio_mapping.cc create mode 100644 src/lib/audio_mapping.h create mode 100644 src/wx/imagemagick_content_dialog.cc create mode 100644 src/wx/imagemagick_content_dialog.h create mode 100644 src/wx/sndfile_content_dialog.cc create mode 100644 src/wx/sndfile_content_dialog.h (limited to 'src') diff --git a/src/lib/audio_content.cc b/src/lib/audio_content.cc index 8ca1e83c9..9968f4725 100644 --- a/src/lib/audio_content.cc +++ b/src/lib/audio_content.cc @@ -22,6 +22,10 @@ using boost::shared_ptr; +int const AudioContentProperty::AUDIO_CHANNELS = 200; +int const AudioContentProperty::AUDIO_LENGTH = 201; +int const AudioContentProperty::AUDIO_FRAME_RATE = 202; + AudioContent::AudioContent (boost::filesystem::path f) : Content (f) { diff --git a/src/lib/audio_content.h b/src/lib/audio_content.h index 2bfc20656..d5dbf266b 100644 --- a/src/lib/audio_content.h +++ b/src/lib/audio_content.h @@ -27,6 +27,14 @@ namespace cxml { class Node; } +class AudioContentProperty +{ +public: + static int const AUDIO_CHANNELS; + static int const AUDIO_LENGTH; + static int const AUDIO_FRAME_RATE; +}; + class AudioContent : public virtual Content { public: diff --git a/src/lib/audio_mapping.cc b/src/lib/audio_mapping.cc new file mode 100644 index 000000000..3fc423e10 --- /dev/null +++ b/src/lib/audio_mapping.cc @@ -0,0 +1,103 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "audio_mapping.h" + +using std::map; +using boost::optional; + +AutomaticAudioMapping::AutomaticAudioMapping (int c) + : _source_channels (c) +{ + +} + +optional +AutomaticAudioMapping::source_to_dcp (int c) const +{ + if (c >= _source_channels) { + return optional (); + } + + if (_source_channels == 1) { + /* mono sources to centre */ + return libdcp::CENTRE; + } + + return static_cast (c); +} + +optional +AutomaticAudioMapping::dcp_to_source (libdcp::Channel c) const +{ + if (_source_channels == 1) { + if (c == libdcp::CENTRE) { + return 0; + } else { + return optional (); + } + } + + if (static_cast (c) >= _source_channels) { + return optional (); + } + + return static_cast (c); +} + +int +AutomaticAudioMapping::dcp_channels () const +{ + if (_source_channels == 1) { + /* The source is mono, so to put the mono channel into + the centre we need to generate a 5.1 soundtrack. + */ + return 6; + } + + return _source_channels; +} + +optional +ConfiguredAudioMapping::dcp_to_source (libdcp::Channel c) const +{ + map::const_iterator i = _source_to_dcp.begin (); + while (i != _source_to_dcp.end() && i->second != c) { + ++i; + } + + if (i == _source_to_dcp.end ()) { + return boost::none; + } + + return i->first; +} + +optional +ConfiguredAudioMapping::source_to_dcp (int c) const +{ + map::const_iterator i = _source_to_dcp.find (c); + if (i == _source_to_dcp.end ()) { + return boost::none; + } + + return i->second; +} + + diff --git a/src/lib/audio_mapping.h b/src/lib/audio_mapping.h new file mode 100644 index 000000000..8804bde06 --- /dev/null +++ b/src/lib/audio_mapping.h @@ -0,0 +1,53 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include +#include +#include + +class AudioMapping +{ +public: + virtual boost::optional source_to_dcp (int c) const = 0; + virtual boost::optional dcp_to_source (libdcp::Channel c) const = 0; +}; + +class AutomaticAudioMapping : public AudioMapping +{ +public: + AutomaticAudioMapping (int); + + boost::optional source_to_dcp (int c) const; + boost::optional dcp_to_source (libdcp::Channel c) const; + int dcp_channels () const; + +private: + int _source_channels; +}; + +class ConfiguredAudioMapping : public AudioMapping +{ +public: + boost::optional source_to_dcp (int c) const; + boost::optional dcp_to_source (libdcp::Channel c) const; + +private: + std::map _source_to_dcp; +}; diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 568307462..a0b88e33e 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -38,6 +38,7 @@ #include "cross.h" #include "writer.h" #include "player.h" +#include "audio_mapping.h" #include "i18n.h" @@ -426,7 +427,7 @@ Encoder::encoder_thread (ServerDescription* server) void Encoder::write_audio (shared_ptr data) { - AudioMapping m (_film->audio_channels ()); + AutomaticAudioMapping m (_film->audio_channels ()); if (m.dcp_channels() != _film->audio_channels()) { /* Remap (currently just for mono -> 5.1) */ diff --git a/src/lib/sndfile_content.cc b/src/lib/sndfile_content.cc index 684405efb..ee4f21eef 100644 --- a/src/lib/sndfile_content.cc +++ b/src/lib/sndfile_content.cc @@ -17,13 +17,18 @@ */ +#include #include "sndfile_content.h" +#include "sndfile_decoder.h" #include "compose.hpp" +#include "job.h" #include "i18n.h" using std::string; +using std::stringstream; using boost::shared_ptr; +using boost::lexical_cast; SndfileContent::SndfileContent (boost::filesystem::path f) : Content (f) @@ -35,9 +40,10 @@ SndfileContent::SndfileContent (boost::filesystem::path f) SndfileContent::SndfileContent (shared_ptr node) : Content (node) , AudioContent (node) - { - + _audio_channels = node->number_child ("AudioChannels"); + _audio_length = node->number_child ("AudioLength"); + _audio_frame_rate = node->number_child ("AudioFrameRate"); } string @@ -49,37 +55,21 @@ SndfileContent::summary () const string SndfileContent::information () const { - return ""; -} - -int -SndfileContent::audio_channels () const -{ - /* XXX */ - return 0; -} - -ContentAudioFrame -SndfileContent::audio_length () const -{ - /* XXX */ - return 0; -} - -int -SndfileContent::audio_frame_rate () const -{ - /* XXX */ - return 0; -} - -int64_t -SndfileContent::audio_channel_layout () const -{ - /* XXX */ - return 0; -} + if (_audio_frame_rate == 0) { + return ""; + } + + stringstream s; + + s << String::compose ( + _("%1 channels, %2kHz, %3 samples"), + audio_channels(), + audio_frame_rate() / 1000.0, + audio_length() + ); + return s.str (); +} bool SndfileContent::valid_file (boost::filesystem::path f) @@ -95,3 +85,33 @@ SndfileContent::clone () const { return shared_ptr (new SndfileContent (*this)); } + +void +SndfileContent::examine (shared_ptr film, shared_ptr job, bool quick) +{ + job->set_progress_unknown (); + Content::examine (film, job, quick); + + SndfileDecoder dec (film, shared_from_this()); + + { + boost::mutex::scoped_lock lm (_mutex); + _audio_channels = dec.audio_channels (); + _audio_length = dec.audio_length (); + _audio_frame_rate = dec.audio_frame_rate (); + } + + signal_changed (AudioContentProperty::AUDIO_CHANNELS); + signal_changed (AudioContentProperty::AUDIO_LENGTH); + signal_changed (AudioContentProperty::AUDIO_FRAME_RATE); +} + +void +SndfileContent::as_xml (xmlpp::Node* node) const +{ + node->add_child("Type")->add_child_text ("Sndfile"); + Content::as_xml (node); + node->add_child("AudioChannels")->add_child_text (lexical_cast (_audio_channels)); + node->add_child("AudioLength")->add_child_text (lexical_cast (_audio_length)); + node->add_child("AudioFrameRate")->add_child_text (lexical_cast (_audio_frame_rate)); +} diff --git a/src/lib/sndfile_content.h b/src/lib/sndfile_content.h index b696b57a5..27c5f3615 100644 --- a/src/lib/sndfile_content.h +++ b/src/lib/sndfile_content.h @@ -17,6 +17,9 @@ */ +extern "C" { +#include +} #include "audio_content.h" namespace cxml { @@ -33,15 +36,36 @@ public: return boost::dynamic_pointer_cast (Content::shared_from_this ()); } + void examine (boost::shared_ptr, boost::shared_ptr, bool); std::string summary () const; std::string information () const; + void as_xml (xmlpp::Node *) const; boost::shared_ptr clone () const; /* AudioContent */ - int audio_channels () const; - ContentAudioFrame audio_length () const; - int audio_frame_rate () const; - int64_t audio_channel_layout () const; + int audio_channels () const { + boost::mutex::scoped_lock lm (_mutex); + return _audio_channels; + } + + ContentAudioFrame audio_length () const { + boost::mutex::scoped_lock lm (_mutex); + return _audio_length; + } + + int audio_frame_rate () const { + boost::mutex::scoped_lock lm (_mutex); + return _audio_frame_rate; + } + + int64_t audio_channel_layout () const { + return av_get_default_channel_layout (audio_channels ()); + } static bool valid_file (boost::filesystem::path); + +private: + int _audio_channels; + ContentAudioFrame _audio_length; + int _audio_frame_rate; }; diff --git a/src/lib/sndfile_decoder.cc b/src/lib/sndfile_decoder.cc index 1f97e5c41..c7311112a 100644 --- a/src/lib/sndfile_decoder.cc +++ b/src/lib/sndfile_decoder.cc @@ -28,59 +28,62 @@ using std::vector; using std::string; -using std::stringstream; using std::min; using std::cout; using boost::shared_ptr; -using boost::optional; - -/* XXX */ SndfileDecoder::SndfileDecoder (shared_ptr f, shared_ptr c) : Decoder (f) , AudioDecoder (f) + , _sndfile_content (c) { - sf_count_t frames; - SNDFILE* sf = open_file (frames); - sf_close (sf); + _sndfile = sf_open (_sndfile_content->file().string().c_str(), SFM_READ, &_info); + if (!_sndfile) { + throw DecodeError (_("could not open audio file for reading")); + } + + _remaining = _info.frames; } -SNDFILE* -SndfileDecoder::open_file (sf_count_t & frames) +SndfileDecoder::~SndfileDecoder () { - frames = 0; - - SF_INFO info; - SNDFILE* s = sf_open (_sndfile_content->file().string().c_str(), SFM_READ, &info); - if (!s) { - throw DecodeError (_("could not open external audio file for reading")); + if (_sndfile) { + sf_close (_sndfile); } - - frames = info.frames; - return s; } bool SndfileDecoder::pass () { - sf_count_t frames; - SNDFILE* sndfile = open_file (frames); - /* Do things in half second blocks as I think there may be limits to what FFmpeg (and in particular the resampler) can cope with. */ sf_count_t const block = _sndfile_content->audio_frame_rate() / 2; + sf_count_t const this_time = min (block, _remaining); + + shared_ptr audio (new AudioBuffers (_sndfile_content->audio_channels(), this_time)); + sf_read_float (_sndfile, audio->data(0), this_time); + audio->set_frames (this_time); + Audio (audio); + _remaining -= this_time; - shared_ptr audio (new AudioBuffers (_sndfile_content->audio_channels(), block)); - while (frames > 0) { - sf_count_t const this_time = min (block, frames); - sf_read_float (sndfile, audio->data(0), this_time); - audio->set_frames (this_time); - Audio (audio); - frames -= this_time; - } + return (_remaining == 0); +} - sf_close (sndfile); +int +SndfileDecoder::audio_channels () const +{ + return _info.channels; +} - return true; +ContentAudioFrame +SndfileDecoder::audio_length () const +{ + return _info.frames; +} + +int +SndfileDecoder::audio_frame_rate () const +{ + return _info.samplerate; } diff --git a/src/lib/sndfile_decoder.h b/src/lib/sndfile_decoder.h index 56fc3a9f0..2900afea0 100644 --- a/src/lib/sndfile_decoder.h +++ b/src/lib/sndfile_decoder.h @@ -27,12 +27,20 @@ class SndfileDecoder : public AudioDecoder { public: SndfileDecoder (boost::shared_ptr, boost::shared_ptr); + ~SndfileDecoder (); bool pass (); + int audio_channels () const; + ContentAudioFrame audio_length () const; + int audio_frame_rate () const; + private: SNDFILE* open_file (sf_count_t &); void close_file (SNDFILE*); boost::shared_ptr _sndfile_content; + SNDFILE* _sndfile; + SF_INFO _info; + ContentAudioFrame _remaining; }; diff --git a/src/lib/util.cc b/src/lib/util.cc index e0de82c64..1e60b43fc 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -914,58 +914,6 @@ audio_channel_name (int c) return channels[c]; } -AudioMapping::AudioMapping (int c) - : _source_channels (c) -{ - -} - -optional -AudioMapping::source_to_dcp (int c) const -{ - if (c >= _source_channels) { - return optional (); - } - - if (_source_channels == 1) { - /* mono sources to centre */ - return libdcp::CENTRE; - } - - return static_cast (c); -} - -optional -AudioMapping::dcp_to_source (libdcp::Channel c) const -{ - if (_source_channels == 1) { - if (c == libdcp::CENTRE) { - return 0; - } else { - return optional (); - } - } - - if (static_cast (c) >= _source_channels) { - return optional (); - } - - return static_cast (c); -} - -int -AudioMapping::dcp_channels () const -{ - if (_source_channels == 1) { - /* The source is mono, so to put the mono channel into - the centre we need to generate a 5.1 soundtrack. - */ - return 6; - } - - return _source_channels; -} - FrameRateConversion::FrameRateConversion (float source, int dcp) : skip (false) , repeat (false) diff --git a/src/lib/util.h b/src/lib/util.h index 23ebd52bc..1fe6212e4 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -194,19 +194,6 @@ private: float** _data; }; -class AudioMapping -{ -public: - AudioMapping (int); - - boost::optional source_to_dcp (int c) const; - boost::optional dcp_to_source (libdcp::Channel c) const; - int dcp_channels () const; - -private: - int _source_channels; -}; - extern int64_t video_frames_to_audio_frames (ContentVideoFrame v, float audio_sample_rate, float frames_per_second); extern std::pair cpu_info (); diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 5d38860e7..6df1a1f21 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -31,6 +31,7 @@ #include "dcp_video_frame.h" #include "dcp_content_type.h" #include "player.h" +#include "audio_mapping.h" #include "i18n.h" @@ -77,7 +78,7 @@ Writer::Writer (shared_ptr f) _picture_asset_writer = _picture_asset->start_write (_first_nonexistant_frame > 0); - AudioMapping m (_film->audio_channels ()); + AutomaticAudioMapping m (_film->audio_channels ()); if (m.dcp_channels() > 0) { _sound_asset.reset ( diff --git a/src/lib/wscript b/src/lib/wscript index 32a2cde23..896598a0e 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -8,6 +8,7 @@ sources = """ audio_analysis.cc audio_content.cc audio_decoder.cc + audio_mapping.cc audio_source.cc config.cc combiner.cc diff --git a/src/wx/audio_dialog.cc b/src/wx/audio_dialog.cc index 1241c2e76..f53ea7c19 100644 --- a/src/wx/audio_dialog.cc +++ b/src/wx/audio_dialog.cc @@ -20,6 +20,7 @@ #include #include "lib/audio_analysis.h" #include "lib/film.h" +#include "lib/audio_mapping.h" #include "audio_dialog.h" #include "audio_plot.h" #include "wx_util.h" @@ -108,7 +109,7 @@ AudioDialog::setup_channels () return; } - AudioMapping m (_film->audio_channels ()); + AutomaticAudioMapping m (_film->audio_channels ()); for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) { if (m.dcp_to_source(static_cast(i))) { @@ -134,7 +135,7 @@ AudioDialog::try_to_load_analysis () _plot->set_analysis (a); - AudioMapping m (_film->audio_channels ()); + AutomaticAudioMapping m (_film->audio_channels ()); optional c = m.source_to_dcp (0); if (c) { _channel_checkbox[c.get()]->SetValue (true); @@ -157,7 +158,7 @@ AudioDialog::channel_clicked (wxCommandEvent& ev) assert (c < MAX_AUDIO_CHANNELS); - AudioMapping m (_film->audio_channels ()); + AutomaticAudioMapping m (_film->audio_channels ()); optional s = m.dcp_to_source (static_cast (c)); if (s) { _plot->set_channel_visible (s.get(), _channel_checkbox[c]->GetValue ()); diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 58fc077a3..6c42359fb 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -49,6 +49,8 @@ #include "dci_metadata_dialog.h" #include "scaler.h" #include "audio_dialog.h" +#include "imagemagick_content_dialog.h" +#include "sndfile_content_dialog.h" using std::string; using std::cout; @@ -198,9 +200,9 @@ FilmEditor::connect_to_widgets () _content->Connect (wxID_ANY, wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler (FilmEditor::content_item_selected), 0, this); _content_add->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_add_clicked), 0, this); _content_remove->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_remove_clicked), 0, this); + _content_edit->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_edit_clicked), 0, this); _content_earlier->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_earlier_clicked), 0, this); _content_later->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_later_clicked), 0, this); - _imagemagick_video_length->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::imagemagick_video_length_changed), 0, this); _left_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::left_crop_changed), 0, this); _right_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::right_crop_changed), 0, this); _top_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::top_crop_changed), 0, this); @@ -343,6 +345,8 @@ FilmEditor::make_content_panel () b->Add (_content_add); _content_remove = new wxButton (_content_panel, wxID_ANY, _("Remove")); b->Add (_content_remove); + _content_edit = new wxButton (_content_panel, wxID_ANY, _("Edit...")); + b->Add (_content_edit); _content_earlier = new wxButton (_content_panel, wxID_ANY, _("Earlier")); b->Add (_content_earlier); _content_later = new wxButton (_content_panel, wxID_ANY, _("Later")); @@ -355,21 +359,6 @@ FilmEditor::make_content_panel () _content_information = new wxTextCtrl (_content_panel, wxID_ANY, wxT ("\n\n\n\n"), wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxTE_MULTILINE); _content_sizer->Add (_content_information, 1, wxEXPAND | wxALL, 6); - - wxFlexGridSizer* grid = new wxFlexGridSizer (2, 4, 4); - _content_sizer->Add (grid, 0, wxEXPAND | wxALL, 6); - - { - add_label_to_sizer (grid, _content_panel, (_("Duration"))); - wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); - _imagemagick_video_length = new wxSpinCtrl (_content_panel); - s->Add (_imagemagick_video_length); - /// TRANSLATORS: this is an abbreviation for seconds, the unit of time - add_label_to_sizer (s, _content_panel, _("s")); - grid->Add (s); - } - - _imagemagick_video_length->SetRange (1, 3600); } void @@ -723,14 +712,9 @@ FilmEditor::film_content_changed (weak_ptr content, int property) setup_show_audio_sensitivity (); } else if (property == VideoContentProperty::VIDEO_LENGTH) { setup_length (); - boost::shared_ptr c = content.lock (); if (c && c == selected_content()) { setup_content_information (); - shared_ptr im = dynamic_pointer_cast (c); - if (im) { - checked_set (_imagemagick_video_length, im->video_length() / 24); - } } } else if (property == FFmpegContentProperty::AUDIO_STREAM) { if (_film->ffmpeg_audio_stream()) { @@ -1258,6 +1242,33 @@ FilmEditor::content_remove_clicked (wxCommandEvent &) } } +void +FilmEditor::content_edit_clicked (wxCommandEvent &) +{ + shared_ptr c = selected_content (); + if (!c) { + return; + } + + shared_ptr im = dynamic_pointer_cast (c); + if (im) { + ImageMagickContentDialog* d = new ImageMagickContentDialog (this, im); + int const r = d->ShowModal (); + d->Destroy (); + + if (r == wxID_OK) { + im->set_video_length (d->video_length() * 24); + } + } + + shared_ptr sf = dynamic_pointer_cast (c); + if (sf) { + SndfileContentDialog* d = new SndfileContentDialog (this, sf); + d->ShowModal (); + d->Destroy (); + } +} + void FilmEditor::content_earlier_clicked (wxCommandEvent &) { @@ -1281,15 +1292,6 @@ FilmEditor::content_item_selected (wxListEvent &) { setup_content_button_sensitivity (); setup_content_information (); - - shared_ptr c = selected_content (); - if (c) { - shared_ptr im = dynamic_pointer_cast (c); - _imagemagick_video_length->Enable (im); - if (im) { - checked_set (_imagemagick_video_length, im->video_length() / 24); - } - } } void @@ -1310,27 +1312,12 @@ FilmEditor::setup_content_button_sensitivity () _content_add->Enable (_generally_sensitive); bool const have_selection = _content->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED) != -1; + _content_edit->Enable (have_selection && _generally_sensitive); _content_remove->Enable (have_selection && _generally_sensitive); _content_earlier->Enable (have_selection && _generally_sensitive); _content_later->Enable (have_selection && _generally_sensitive); } -void -FilmEditor::imagemagick_video_length_changed (wxCommandEvent &) -{ - shared_ptr c = selected_content (); - if (!c) { - return; - } - - shared_ptr im = dynamic_pointer_cast (c); - if (!im) { - return; - } - - im->set_video_length (_imagemagick_video_length->GetValue() * 24); -} - shared_ptr FilmEditor::selected_content () { diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index 2870714f9..b6f6a24ee 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -16,7 +16,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - + /** @file src/film_editor.h * @brief A wx widget to edit a film's metadata, and perform various functions. */ @@ -66,6 +66,7 @@ private: void content_item_selected (wxListEvent &); void content_add_clicked (wxCommandEvent &); void content_remove_clicked (wxCommandEvent &); + void content_edit_clicked (wxCommandEvent &); void content_earlier_clicked (wxCommandEvent &); void content_later_clicked (wxCommandEvent &); void imagemagick_video_length_changed (wxCommandEvent &); @@ -131,10 +132,10 @@ private: wxListCtrl* _content; wxButton* _content_add; wxButton* _content_remove; + wxButton* _content_edit; wxButton* _content_earlier; wxButton* _content_later; wxTextCtrl* _content_information; - wxSpinCtrl* _imagemagick_video_length; wxButton* _edit_dci_button; wxChoice* _format; wxStaticText* _format_description; diff --git a/src/wx/imagemagick_content_dialog.cc b/src/wx/imagemagick_content_dialog.cc new file mode 100644 index 000000000..726e4b8e2 --- /dev/null +++ b/src/wx/imagemagick_content_dialog.cc @@ -0,0 +1,62 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include "lib/imagemagick_content.h" +#include "imagemagick_content_dialog.h" +#include "wx_util.h" + +using boost::shared_ptr; + +ImageMagickContentDialog::ImageMagickContentDialog (wxWindow* parent, shared_ptr content) + : wxDialog (parent, wxID_ANY, _("Image")) +{ + wxFlexGridSizer* grid = new wxFlexGridSizer (3, 6, 6); + grid->AddGrowableCol (1, 1); + + { + add_label_to_sizer (grid, this, (_("Duration"))); + wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); + _video_length = new wxSpinCtrl (this); + s->Add (_video_length); + /// TRANSLATORS: this is an abbreviation for seconds, the unit of time + add_label_to_sizer (s, this, _("s")); + grid->Add (s); + } + + wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL); + overall_sizer->Add (grid, 1, wxEXPAND | wxALL, 6); + + wxSizer* buttons = CreateSeparatedButtonSizer (wxOK); + if (buttons) { + overall_sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder()); + } + + SetSizer (overall_sizer); + overall_sizer->Layout (); + overall_sizer->SetSizeHints (this); + + checked_set (_video_length, content->video_length () / 24); +} + +int +ImageMagickContentDialog::video_length () const +{ + return _video_length->GetValue (); +} diff --git a/src/wx/imagemagick_content_dialog.h b/src/wx/imagemagick_content_dialog.h new file mode 100644 index 000000000..2fa955929 --- /dev/null +++ b/src/wx/imagemagick_content_dialog.h @@ -0,0 +1,34 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include + +class wxSpinCtrl; +class ImageMagickContent; + +class ImageMagickContentDialog : public wxDialog +{ +public: + ImageMagickContentDialog (wxWindow *, boost::shared_ptr); + + int video_length () const; + +private: + wxSpinCtrl* _video_length; +}; diff --git a/src/wx/sndfile_content_dialog.cc b/src/wx/sndfile_content_dialog.cc new file mode 100644 index 000000000..f305b158c --- /dev/null +++ b/src/wx/sndfile_content_dialog.cc @@ -0,0 +1,67 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "lib/util.h" +#include "lib/sndfile_content.h" +#include "sndfile_content_dialog.h" +#include "wx_util.h" + +using boost::shared_ptr; + +SndfileContentDialog::SndfileContentDialog (wxWindow* parent, shared_ptr content) + : wxDialog (parent, wxID_ANY, _("Sound file")) +{ + wxFlexGridSizer* grid = new wxFlexGridSizer (7, 6, 0); + + add_label_to_sizer (grid, this, wxT ("")); + add_label_to_sizer (grid, this, _("L")); + add_label_to_sizer (grid, this, _("R")); + add_label_to_sizer (grid, this, _("C")); + add_label_to_sizer (grid, this, _("Lfe")); + add_label_to_sizer (grid, this, _("Ls")); + add_label_to_sizer (grid, this, _("Rs")); + + _buttons.resize (content->audio_channels ()); + for (int i = 0; i < content->audio_channels(); ++i) { + + if (content->audio_channels() == 1) { + add_label_to_sizer (grid, this, _("Source")); + } else { + add_label_to_sizer (grid, this, wxString::Format (_("Source %d"), i + 1)); + } + + for (int j = 0; j < MAX_AUDIO_CHANNELS; ++j) { + wxRadioButton* b = new wxRadioButton (this, wxID_ANY, wxT (""), wxDefaultPosition, wxDefaultSize, j ? 0 : wxRB_GROUP); + _buttons[i].push_back (b); + grid->Add (b, wxSHRINK); + } + } + + wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL); + overall_sizer->Add (grid, 1, wxEXPAND | wxALL, 6); + + wxSizer* buttons = CreateSeparatedButtonSizer (wxOK); + if (buttons) { + overall_sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder()); + } + + SetSizer (overall_sizer); + overall_sizer->Layout (); + overall_sizer->SetSizeHints (this); +} diff --git a/src/wx/sndfile_content_dialog.h b/src/wx/sndfile_content_dialog.h new file mode 100644 index 000000000..5a328892a --- /dev/null +++ b/src/wx/sndfile_content_dialog.h @@ -0,0 +1,36 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include +#include +#include "lib/audio_mapping.h" + +class SndfileContent; + +class SndfileContentDialog : public wxDialog +{ +public: + SndfileContentDialog (wxWindow *, boost::shared_ptr); + + ConfiguredAudioMapping audio_mapping () const; + +private: + std::vector > _buttons; +}; diff --git a/src/wx/wscript b/src/wx/wscript index 42bb8ca88..bd21af6ce 100644 --- a/src/wx/wscript +++ b/src/wx/wscript @@ -14,11 +14,13 @@ sources = """ filter_dialog.cc filter_view.cc gain_calculator_dialog.cc + imagemagick_content_dialog.cc job_manager_view.cc job_wrapper.cc new_film_dialog.cc properties_dialog.cc server_dialog.cc + sndfile_content_dialog.cc wx_util.cc wx_ui_signaller.cc """ -- cgit v1.2.3 From c921cfe23b593d7c367ad76094308c5f08037374 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 6 Apr 2013 23:57:46 +0100 Subject: Various work on audio channel mapping. --- src/lib/analyse_audio_job.cc | 4 +- src/lib/audio_mapping.cc | 100 ++++++++++++------------- src/lib/audio_mapping.h | 52 +++++++------ src/lib/encoder.cc | 3 + src/lib/ffmpeg_content.cc | 3 +- src/lib/film.cc | 16 +++- src/lib/film.h | 12 ++- src/lib/imagemagick_content.cc | 2 +- src/lib/playlist.cc | 45 +++++++++++ src/lib/playlist.h | 3 + src/lib/sndfile_content.cc | 7 +- src/lib/writer.cc | 6 +- src/wx/audio_dialog.cc | 36 +-------- src/wx/audio_dialog.h | 1 - src/wx/audio_mapping_view.cc | 156 +++++++++++++++++++++++++++++++++++++++ src/wx/audio_mapping_view.h | 35 +++++++++ src/wx/film_editor.cc | 55 +++++++++----- src/wx/film_editor.h | 6 +- src/wx/sndfile_content_dialog.cc | 67 ----------------- src/wx/sndfile_content_dialog.h | 36 --------- src/wx/wscript | 2 +- 21 files changed, 401 insertions(+), 246 deletions(-) create mode 100644 src/wx/audio_mapping_view.cc create mode 100644 src/wx/audio_mapping_view.h delete mode 100644 src/wx/sndfile_content_dialog.cc delete mode 100644 src/wx/sndfile_content_dialog.h (limited to 'src') diff --git a/src/lib/analyse_audio_job.cc b/src/lib/analyse_audio_job.cc index 5ef6515dd..50096d7c1 100644 --- a/src/lib/analyse_audio_job.cc +++ b/src/lib/analyse_audio_job.cc @@ -57,8 +57,8 @@ AnalyseAudioJob::run () _samples_per_point = max (int64_t (1), _film->audio_length() / _num_points); - _current.resize (_film->audio_channels ()); - _analysis.reset (new AudioAnalysis (_film->audio_channels())); + _current.resize (MAX_AUDIO_CHANNELS); + _analysis.reset (new AudioAnalysis (MAX_AUDIO_CHANNELS)); while (!player->pass()) { set_progress (float (_done) / _film->audio_length ()); diff --git a/src/lib/audio_mapping.cc b/src/lib/audio_mapping.cc index 3fc423e10..48cc23307 100644 --- a/src/lib/audio_mapping.cc +++ b/src/lib/audio_mapping.cc @@ -19,85 +19,77 @@ #include "audio_mapping.h" -using std::map; -using boost::optional; - -AutomaticAudioMapping::AutomaticAudioMapping (int c) - : _source_channels (c) +using std::list; +using std::cout; +using std::make_pair; +using std::pair; +using boost::shared_ptr; + +void +AudioMapping::add (Channel c, libdcp::Channel d) { - + _content_to_dcp.push_back (make_pair (c, d)); } -optional -AutomaticAudioMapping::source_to_dcp (int c) const +/* XXX: this is grotty */ +int +AudioMapping::dcp_channels () const { - if (c >= _source_channels) { - return optional (); + for (list >::const_iterator i = _content_to_dcp.begin(); i != _content_to_dcp.end(); ++i) { + if (((int) i->second) > 2) { + return 6; + } } - if (_source_channels == 1) { - /* mono sources to centre */ - return libdcp::CENTRE; - } - - return static_cast (c); + return 2; } -optional -AutomaticAudioMapping::dcp_to_source (libdcp::Channel c) const +list +AudioMapping::dcp_to_content (libdcp::Channel d) const { - if (_source_channels == 1) { - if (c == libdcp::CENTRE) { - return 0; - } else { - return optional (); + list c; + for (list >::const_iterator i = _content_to_dcp.begin(); i != _content_to_dcp.end(); ++i) { + if (i->second == d) { + c.push_back (i->first); } } - if (static_cast (c) >= _source_channels) { - return optional (); - } - - return static_cast (c); + return c; } -int -AutomaticAudioMapping::dcp_channels () const +list +AudioMapping::content_channels () const { - if (_source_channels == 1) { - /* The source is mono, so to put the mono channel into - the centre we need to generate a 5.1 soundtrack. - */ - return 6; + list c; + for (list >::const_iterator i = _content_to_dcp.begin(); i != _content_to_dcp.end(); ++i) { + if (find (c.begin(), c.end(), i->first) == c.end ()) { + c.push_back (i->first); + } } - return _source_channels; + return c; } -optional -ConfiguredAudioMapping::dcp_to_source (libdcp::Channel c) const +list +AudioMapping::content_to_dcp (Channel c) const { - map::const_iterator i = _source_to_dcp.begin (); - while (i != _source_to_dcp.end() && i->second != c) { - ++i; - } - - if (i == _source_to_dcp.end ()) { - return boost::none; + list d; + for (list >::const_iterator i = _content_to_dcp.begin(); i != _content_to_dcp.end(); ++i) { + if (i->first == c) { + d.push_back (i->second); + } } - return i->first; + return d; } -optional -ConfiguredAudioMapping::source_to_dcp (int c) const +bool +operator== (AudioMapping::Channel const & a, AudioMapping::Channel const & b) { - map::const_iterator i = _source_to_dcp.find (c); - if (i == _source_to_dcp.end ()) { - return boost::none; - } - - return i->second; + shared_ptr sa = a.content.lock (); + shared_ptr sb = b.content.lock (); + return sa == sb && a.index == b.index; } + diff --git a/src/lib/audio_mapping.h b/src/lib/audio_mapping.h index 8804bde06..10ac20b48 100644 --- a/src/lib/audio_mapping.h +++ b/src/lib/audio_mapping.h @@ -17,37 +17,43 @@ */ -#include -#include -#include +#ifndef DVDOMATIC_AUDIO_MAPPING_H +#define DVDOMATIC_AUDIO_MAPPING_H + +#include +#include #include +#include +#include "audio_content.h" class AudioMapping { public: - virtual boost::optional source_to_dcp (int c) const = 0; - virtual boost::optional dcp_to_source (libdcp::Channel c) const = 0; -}; - -class AutomaticAudioMapping : public AudioMapping -{ -public: - AutomaticAudioMapping (int); + struct Channel { + Channel (boost::weak_ptr c, int i) + : content (c) + , index (i) + {} + + boost::weak_ptr content; + int index; + }; + + void add (Channel, libdcp::Channel); - boost::optional source_to_dcp (int c) const; - boost::optional dcp_to_source (libdcp::Channel c) const; int dcp_channels () const; - -private: - int _source_channels; -}; + std::list dcp_to_content (libdcp::Channel) const; + std::list > content_to_dcp () const { + return _content_to_dcp; + } -class ConfiguredAudioMapping : public AudioMapping -{ -public: - boost::optional source_to_dcp (int c) const; - boost::optional dcp_to_source (libdcp::Channel c) const; + std::list content_channels () const; + std::list content_to_dcp (Channel) const; private: - std::map _source_to_dcp; + std::list > _content_to_dcp; }; + +extern bool operator== (AudioMapping::Channel const &, AudioMapping::Channel const &); + +#endif diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index a0b88e33e..0542587a0 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -427,6 +427,8 @@ Encoder::encoder_thread (ServerDescription* server) void Encoder::write_audio (shared_ptr data) { +#if 0 + XXX AutomaticAudioMapping m (_film->audio_channels ()); if (m.dcp_channels() != _film->audio_channels()) { @@ -444,6 +446,7 @@ Encoder::write_audio (shared_ptr data) data = b; } +#endif _writer->write (data); } diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index cc95105e5..d36abe2c3 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -152,12 +152,13 @@ FFmpegContent::examine (shared_ptr film, shared_ptr job, bool quick) signal_changed (FFmpegContentProperty::SUBTITLE_STREAM); signal_changed (FFmpegContentProperty::AUDIO_STREAMS); signal_changed (FFmpegContentProperty::AUDIO_STREAM); + signal_changed (AudioContentProperty::AUDIO_CHANNELS); } string FFmpegContent::summary () const { - return String::compose (_("Movie: %1"), file().filename ()); + return String::compose (_("Movie: %1"), file().filename().string()); } string diff --git a/src/lib/film.cc b/src/lib/film.cc index 69d2a28e2..b1f740ec2 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -960,6 +960,7 @@ Film::signal_changed (Property p) case Film::CONTENT: _playlist->setup (content ()); set_dcp_frame_rate (best_dcp_frame_rate (video_frame_rate ())); + set_audio_mapping (_playlist->default_audio_mapping ()); break; default: break; @@ -1235,12 +1236,25 @@ Film::set_ffmpeg_audio_stream (FFmpegAudioStream s) } } +void +Film::set_audio_mapping (AudioMapping m) +{ + { + boost::mutex::scoped_lock lm (_state_mutex); + _audio_mapping = m; + } + + signal_changed (AUDIO_MAPPING); +} + void Film::content_changed (boost::weak_ptr c, int p) { if (p == VideoContentProperty::VIDEO_FRAME_RATE) { set_dcp_frame_rate (best_dcp_frame_rate (video_frame_rate ())); - } + } else if (p == AudioContentProperty::AUDIO_CHANNELS) { + set_audio_mapping (_playlist->default_audio_mapping ()); + } if (ui_signaller) { ui_signaller->emit (boost::bind (boost::ref (ContentChanged), c, p)); diff --git a/src/lib/film.h b/src/lib/film.h index 9c5f561e6..532d32bdc 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -36,6 +36,7 @@ #include "dci_metadata.h" #include "types.h" #include "ffmpeg_content.h" +#include "audio_mapping.h" class DCPContentType; class Format; @@ -146,7 +147,8 @@ public: COLOUR_LUT, J2K_BANDWIDTH, DCI_METADATA, - DCP_FRAME_RATE + DCP_FRAME_RATE, + AUDIO_MAPPING }; @@ -262,6 +264,11 @@ public: return _dcp_frame_rate; } + AudioMapping audio_mapping () const { + boost::mutex::scoped_lock lm (_state_mutex); + return _audio_mapping; + } + /* SET */ void set_directory (std::string); @@ -294,6 +301,7 @@ public: void set_dci_metadata (DCIMetadata); void set_dcp_frame_rate (int); void set_dci_date_today (); + void set_audio_mapping (AudioMapping); /** Emitted when some property has of the Film has changed */ mutable boost::signals2::signal Changed; @@ -314,6 +322,7 @@ private: void read_metadata (); void content_changed (boost::weak_ptr, int); boost::shared_ptr ffmpeg () const; + void setup_default_audio_mapping (); /** Log to write to */ boost::shared_ptr _log; @@ -378,6 +387,7 @@ private: int _dcp_frame_rate; /** The date that we should use in a DCI name */ boost::gregorian::date _dci_date; + AudioMapping _audio_mapping; /** true if our state has changed since we last saved it */ mutable bool _dirty; diff --git a/src/lib/imagemagick_content.cc b/src/lib/imagemagick_content.cc index 912c180a8..59fde40bb 100644 --- a/src/lib/imagemagick_content.cc +++ b/src/lib/imagemagick_content.cc @@ -45,7 +45,7 @@ ImageMagickContent::ImageMagickContent (shared_ptr node) string ImageMagickContent::summary () const { - return String::compose (_("Image: %1"), file().filename ()); + return String::compose (_("Image: %1"), file().filename().string()); } bool diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index e0220ef6f..3f7905fa9 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -30,6 +30,7 @@ using std::list; using std::cout; using std::vector; +using std::min; using boost::shared_ptr; using boost::weak_ptr; using boost::dynamic_pointer_cast; @@ -224,3 +225,47 @@ Playlist::content_changed (weak_ptr c, int p) { ContentChanged (c, p); } + +AudioMapping +Playlist::default_audio_mapping () const +{ + AudioMapping m; + + switch (_audio_from) { + case AUDIO_NONE: + break; + case AUDIO_FFMPEG: + if (_ffmpeg->audio_channels() == 1) { + /* Map mono sources to centre */ + m.add (AudioMapping::Channel (_ffmpeg, 0), libdcp::CENTRE); + } else { + int const N = min (_ffmpeg->audio_channels (), MAX_AUDIO_CHANNELS); + /* Otherwise just start with a 1:1 mapping */ + for (int i = 0; i < N; ++i) { + m.add (AudioMapping::Channel (_ffmpeg, i), (libdcp::Channel) i); + } + } + break; + + case AUDIO_SNDFILE: + { + int n = 0; + for (list >::const_iterator i = _sndfile.begin(); i != _sndfile.end(); ++i) { + cout << "sndfile " << (*i)->audio_channels() << "\n"; + for (int j = 0; j < (*i)->audio_channels(); ++j) { + m.add (AudioMapping::Channel (*i, j), (libdcp::Channel) n); + ++n; + if (n >= MAX_AUDIO_CHANNELS) { + break; + } + } + if (n >= MAX_AUDIO_CHANNELS) { + break; + } + } + break; + } + } + + return m; +} diff --git a/src/lib/playlist.h b/src/lib/playlist.h index 1a24a0227..1d189cb07 100644 --- a/src/lib/playlist.h +++ b/src/lib/playlist.h @@ -25,6 +25,7 @@ #include "video_sink.h" #include "audio_sink.h" #include "ffmpeg_content.h" +#include "audio_mapping.h" class Content; class FFmpegContent; @@ -53,6 +54,8 @@ public: libdcp::Size video_size () const; ContentVideoFrame video_length () const; + AudioMapping default_audio_mapping () const; + enum VideoFrom { VIDEO_NONE, VIDEO_FFMPEG, diff --git a/src/lib/sndfile_content.cc b/src/lib/sndfile_content.cc index ee4f21eef..539b0dfb5 100644 --- a/src/lib/sndfile_content.cc +++ b/src/lib/sndfile_content.cc @@ -27,12 +27,16 @@ using std::string; using std::stringstream; +using std::cout; using boost::shared_ptr; using boost::lexical_cast; SndfileContent::SndfileContent (boost::filesystem::path f) : Content (f) , AudioContent (f) + , _audio_channels (0) + , _audio_length (0) + , _audio_frame_rate (0) { } @@ -49,7 +53,7 @@ SndfileContent::SndfileContent (shared_ptr node) string SndfileContent::summary () const { - return String::compose (_("Sound file: %1"), file().filename ()); + return String::compose (_("Sound file: %1"), file().filename().string()); } string @@ -115,3 +119,4 @@ SndfileContent::as_xml (xmlpp::Node* node) const node->add_child("AudioLength")->add_child_text (lexical_cast (_audio_length)); node->add_child("AudioFrameRate")->add_child_text (lexical_cast (_audio_frame_rate)); } + diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 6df1a1f21..7258826ba 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -78,15 +78,13 @@ Writer::Writer (shared_ptr f) _picture_asset_writer = _picture_asset->start_write (_first_nonexistant_frame > 0); - AutomaticAudioMapping m (_film->audio_channels ()); - - if (m.dcp_channels() > 0) { + if (_film->audio_channels() > 0) { _sound_asset.reset ( new libdcp::SoundAsset ( _film->dir (_film->dcp_name()), N_("audio.mxf"), _film->dcp_frame_rate (), - m.dcp_channels (), + _film->audio_mapping().dcp_channels (), dcp_audio_sample_rate (_film->audio_frame_rate()) ) ); diff --git a/src/wx/audio_dialog.cc b/src/wx/audio_dialog.cc index f53ea7c19..4c50260fa 100644 --- a/src/wx/audio_dialog.cc +++ b/src/wx/audio_dialog.cc @@ -20,7 +20,6 @@ #include #include "lib/audio_analysis.h" #include "lib/film.h" -#include "lib/audio_mapping.h" #include "audio_dialog.h" #include "audio_plot.h" #include "wx_util.h" @@ -93,7 +92,6 @@ AudioDialog::set_film (shared_ptr f) _film = f; try_to_load_analysis (); - setup_channels (); _plot->set_gain (_film->audio_gain ()); _film_changed_connection = _film->Changed.connect (bind (&AudioDialog::film_changed, this, _1)); @@ -102,23 +100,6 @@ AudioDialog::set_film (shared_ptr f) SetTitle (wxString::Format (_("DVD-o-matic audio - %s"), std_to_wx(_film->name()).data())); } -void -AudioDialog::setup_channels () -{ - if (!_film->has_audio()) { - return; - } - - AutomaticAudioMapping m (_film->audio_channels ()); - - for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) { - if (m.dcp_to_source(static_cast(i))) { - _channel_checkbox[i]->Show (); - } else { - _channel_checkbox[i]->Hide (); - } - } -} void AudioDialog::try_to_load_analysis () @@ -135,12 +116,8 @@ AudioDialog::try_to_load_analysis () _plot->set_analysis (a); - AutomaticAudioMapping m (_film->audio_channels ()); - optional c = m.source_to_dcp (0); - if (c) { - _channel_checkbox[c.get()]->SetValue (true); - _plot->set_channel_visible (0, true); - } + _channel_checkbox[0]->SetValue (true); + _plot->set_channel_visible (0, true); for (int i = 0; i < AudioPoint::COUNT; ++i) { _type_checkbox[i]->SetValue (true); @@ -158,11 +135,7 @@ AudioDialog::channel_clicked (wxCommandEvent& ev) assert (c < MAX_AUDIO_CHANNELS); - AutomaticAudioMapping m (_film->audio_channels ()); - optional s = m.dcp_to_source (static_cast (c)); - if (s) { - _plot->set_channel_visible (s.get(), _channel_checkbox[c]->GetValue ()); - } + _plot->set_channel_visible (c, _channel_checkbox[c]->GetValue ()); } void @@ -172,9 +145,6 @@ AudioDialog::film_changed (Film::Property p) case Film::AUDIO_GAIN: _plot->set_gain (_film->audio_gain ()); break; - case Film::CONTENT: - setup_channels (); - break; default: break; } diff --git a/src/wx/audio_dialog.h b/src/wx/audio_dialog.h index 514faeea0..db1d74f30 100644 --- a/src/wx/audio_dialog.h +++ b/src/wx/audio_dialog.h @@ -39,7 +39,6 @@ private: void type_clicked (wxCommandEvent &); void smoothing_changed (wxScrollEvent &); void try_to_load_analysis (); - void setup_channels (); boost::shared_ptr _film; AudioPlot* _plot; diff --git a/src/wx/audio_mapping_view.cc b/src/wx/audio_mapping_view.cc new file mode 100644 index 000000000..d62609d22 --- /dev/null +++ b/src/wx/audio_mapping_view.cc @@ -0,0 +1,156 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include +#include +#include +#include "lib/audio_mapping.h" +#include "audio_mapping_view.h" +#include "wx_util.h" + +using std::cout; +using std::list; +using boost::shared_ptr; + +/* This could go away with wxWidgets 2.9, which has an API call + to find these values. +*/ + +#ifdef __WXMSW__ +#define CHECKBOX_WIDTH 16 +#define CHECKBOX_HEIGHT 16 +#endif + +#ifdef __WXGTK__ +#define CHECKBOX_WIDTH 20 +#define CHECKBOX_HEIGHT 20 +#endif + + +class NoSelectionStringRenderer : public wxGridCellStringRenderer +{ +public: + void Draw (wxGrid& grid, wxGridCellAttr& attr, wxDC& dc, const wxRect& rect, int row, int col, bool) + { + wxGridCellStringRenderer::Draw (grid, attr, dc, rect, row, col, false); + } +}; + +class CheckBoxRenderer : public wxGridCellRenderer +{ +public: + + void Draw (wxGrid& grid, wxGridCellAttr &, wxDC& dc, const wxRect& rect, int row, int col, bool) + { + wxRendererNative::Get().DrawCheckBox ( + &grid, + dc, rect, + grid.GetCellValue (row, col) == "1" ? static_cast(wxCONTROL_CHECKED) : 0 + ); + } + + wxSize GetBestSize (wxGrid &, wxGridCellAttr &, wxDC &, int, int) + { + return wxSize (CHECKBOX_WIDTH + 4, CHECKBOX_HEIGHT + 4); + } + + wxGridCellRenderer* Clone () const + { + return new CheckBoxRenderer; + } +}; + + +AudioMappingView::AudioMappingView (wxWindow* parent) + : wxPanel (parent, wxID_ANY) +{ + _grid = new wxGrid (this, wxID_ANY); + + _grid->CreateGrid (0, 7); + _grid->HideRowLabels (); + _grid->DisableDragRowSize (); + _grid->DisableDragColSize (); + _grid->EnableEditing (false); + _grid->SetCellHighlightPenWidth (0); + _grid->SetDefaultRenderer (new NoSelectionStringRenderer); + + _grid->SetColLabelValue (0, _("Content channel")); + _grid->SetColLabelValue (1, _("L")); + _grid->SetColLabelValue (2, _("R")); + _grid->SetColLabelValue (3, _("C")); + _grid->SetColLabelValue (4, _("Lfe")); + _grid->SetColLabelValue (5, _("Ls")); + _grid->SetColLabelValue (6, _("Rs")); + + _grid->AutoSize (); + + wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); + s->Add (_grid, 1, wxEXPAND); + SetSizerAndFit (s); + + Connect (wxID_ANY, wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler (AudioMappingView::left_click), 0, this); +} + +void +AudioMappingView::left_click (wxGridEvent& ev) +{ + if (ev.GetCol() == 0) { + return; + } + + if (_grid->GetCellValue (ev.GetRow(), ev.GetCol()) == "1") { + _grid->SetCellValue (ev.GetRow(), ev.GetCol(), "0"); + } else { + _grid->SetCellValue (ev.GetRow(), ev.GetCol(), "1"); + } +} + +void +AudioMappingView::set_mapping (AudioMapping map) +{ + if (_grid->GetNumberRows ()) { + _grid->DeleteRows (0, _grid->GetNumberRows ()); + } + + list content_channels = map.content_channels (); + _grid->InsertRows (0, content_channels.size ()); + + for (size_t r = 0; r < content_channels.size(); ++r) { + for (int c = 1; c < 7; ++c) { + _grid->SetCellRenderer (r, c, new CheckBoxRenderer); + } + } + + int n = 0; + for (list::iterator i = content_channels.begin(); i != content_channels.end(); ++i) { + shared_ptr ac = i->content.lock (); + assert (ac); + _grid->SetCellValue (n, 0, wxString::Format ("%s %d", std_to_wx (ac->file().filename().string()), i->index + 1)); + + list const d = map.content_to_dcp (*i); + for (list::const_iterator j = d.begin(); j != d.end(); ++j) { + _grid->SetCellValue (n, static_cast (*j) + 1, "1"); + } + ++n; + } + + _grid->AutoSize (); +} + diff --git a/src/wx/audio_mapping_view.h b/src/wx/audio_mapping_view.h new file mode 100644 index 000000000..36429412f --- /dev/null +++ b/src/wx/audio_mapping_view.h @@ -0,0 +1,35 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include +#include + +class AudioMappingView : public wxPanel +{ +public: + AudioMappingView (wxWindow *); + + void set_mapping (AudioMapping); + +private: + void left_click (wxGridEvent &); + + wxGrid* _grid; +}; diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 6c42359fb..6f08b6567 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -50,7 +50,7 @@ #include "scaler.h" #include "audio_dialog.h" #include "imagemagick_content_dialog.h" -#include "sndfile_content_dialog.h" +#include "audio_mapping_view.h" using std::string; using std::cout; @@ -197,7 +197,9 @@ FilmEditor::connect_to_widgets () _edit_dci_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::edit_dci_button_clicked), 0, this); _format->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::format_changed), 0, this); _trust_content_headers->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::trust_content_headers_changed), 0, this); - _content->Connect (wxID_ANY, wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler (FilmEditor::content_item_selected), 0, this); + _content->Connect (wxID_ANY, wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler (FilmEditor::content_selection_changed), 0, this); + _content->Connect (wxID_ANY, wxEVT_COMMAND_LIST_ITEM_DESELECTED, wxListEventHandler (FilmEditor::content_selection_changed), 0, this); + _content->Connect (wxID_ANY, wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler (FilmEditor::content_activated), 0, this); _content_add->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_add_clicked), 0, this); _content_remove->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_remove_clicked), 0, this); _content_edit->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_edit_clicked), 0, this); @@ -406,6 +408,9 @@ FilmEditor::make_audio_panel () grid->Add (s, 1, wxEXPAND); } + _audio_mapping = new AudioMappingView (_audio_panel); + _audio_sizer->Add (_audio_mapping, 1, wxEXPAND | wxALL, 6); + _audio_gain->SetRange (-60, 60); _audio_delay->SetRange (-1000, 1000); } @@ -691,6 +696,10 @@ FilmEditor::film_changed (Film::Property p) _frame_rate_description->SetLabel (wxT ("")); _best_dcp_frame_rate->Disable (); } + break; + case Film::AUDIO_MAPPING: + _audio_mapping->set_mapping (_film->audio_mapping ()); + break; } } @@ -849,6 +858,7 @@ FilmEditor::set_film (shared_ptr f) film_changed (Film::J2K_BANDWIDTH); film_changed (Film::DCI_METADATA); film_changed (Film::DCP_FRAME_RATE); + film_changed (Film::AUDIO_MAPPING); film_content_changed (boost::shared_ptr (), FFmpegContentProperty::SUBTITLE_STREAMS); film_content_changed (boost::shared_ptr (), FFmpegContentProperty::SUBTITLE_STREAM); @@ -1242,6 +1252,15 @@ FilmEditor::content_remove_clicked (wxCommandEvent &) } } +void +FilmEditor::content_activated (wxListEvent& ev) +{ + ContentList c = _film->content (); + assert (ev.GetIndex() >= 0 && size_t (ev.GetIndex()) < c.size ()); + + edit_content (c[ev.GetIndex()]); +} + void FilmEditor::content_edit_clicked (wxCommandEvent &) { @@ -1250,22 +1269,19 @@ FilmEditor::content_edit_clicked (wxCommandEvent &) return; } + edit_content (c); +} + +void +FilmEditor::edit_content (shared_ptr c) +{ shared_ptr im = dynamic_pointer_cast (c); if (im) { ImageMagickContentDialog* d = new ImageMagickContentDialog (this, im); - int const r = d->ShowModal (); - d->Destroy (); - - if (r == wxID_OK) { - im->set_video_length (d->video_length() * 24); - } - } - - shared_ptr sf = dynamic_pointer_cast (c); - if (sf) { - SndfileContentDialog* d = new SndfileContentDialog (this, sf); d->ShowModal (); d->Destroy (); + + im->set_video_length (d->video_length() * 24); } } @@ -1288,7 +1304,7 @@ FilmEditor::content_later_clicked (wxCommandEvent &) } void -FilmEditor::content_item_selected (wxListEvent &) +FilmEditor::content_selection_changed (wxListEvent &) { setup_content_button_sensitivity (); setup_content_information (); @@ -1311,11 +1327,12 @@ FilmEditor::setup_content_button_sensitivity () { _content_add->Enable (_generally_sensitive); - bool const have_selection = _content->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED) != -1; - _content_edit->Enable (have_selection && _generally_sensitive); - _content_remove->Enable (have_selection && _generally_sensitive); - _content_earlier->Enable (have_selection && _generally_sensitive); - _content_later->Enable (have_selection && _generally_sensitive); + shared_ptr selection = selected_content (); + + _content_edit->Enable (selection && _generally_sensitive && dynamic_pointer_cast (selection)); + _content_remove->Enable (selection && _generally_sensitive); + _content_earlier->Enable (selection && _generally_sensitive); + _content_later->Enable (selection && _generally_sensitive); } shared_ptr diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index b6f6a24ee..bc6b045c4 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -33,6 +33,7 @@ class wxListCtrl; class wxListEvent; class Film; class AudioDialog; +class AudioMappingView; /** @class FilmEditor * @brief A wx widget to edit a film's metadata, and perform various functions. @@ -63,7 +64,8 @@ private: void top_crop_changed (wxCommandEvent &); void bottom_crop_changed (wxCommandEvent &); void trust_content_headers_changed (wxCommandEvent &); - void content_item_selected (wxListEvent &); + void content_selection_changed (wxListEvent &); + void content_activated (wxListEvent &); void content_add_clicked (wxCommandEvent &); void content_remove_clicked (wxCommandEvent &); void content_edit_clicked (wxCommandEvent &); @@ -110,6 +112,7 @@ private: void active_jobs_changed (bool); boost::shared_ptr selected_content (); + void edit_content (boost::shared_ptr); wxNotebook* _notebook; wxPanel* _film_panel; @@ -152,6 +155,7 @@ private: wxButton* _show_audio; wxSpinCtrl* _audio_delay; wxChoice* _ffmpeg_audio_stream; + AudioMappingView* _audio_mapping; wxCheckBox* _with_subtitles; wxChoice* _ffmpeg_subtitle_stream; wxSpinCtrl* _subtitle_offset; diff --git a/src/wx/sndfile_content_dialog.cc b/src/wx/sndfile_content_dialog.cc deleted file mode 100644 index f305b158c..000000000 --- a/src/wx/sndfile_content_dialog.cc +++ /dev/null @@ -1,67 +0,0 @@ -/* - Copyright (C) 2013 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include "lib/util.h" -#include "lib/sndfile_content.h" -#include "sndfile_content_dialog.h" -#include "wx_util.h" - -using boost::shared_ptr; - -SndfileContentDialog::SndfileContentDialog (wxWindow* parent, shared_ptr content) - : wxDialog (parent, wxID_ANY, _("Sound file")) -{ - wxFlexGridSizer* grid = new wxFlexGridSizer (7, 6, 0); - - add_label_to_sizer (grid, this, wxT ("")); - add_label_to_sizer (grid, this, _("L")); - add_label_to_sizer (grid, this, _("R")); - add_label_to_sizer (grid, this, _("C")); - add_label_to_sizer (grid, this, _("Lfe")); - add_label_to_sizer (grid, this, _("Ls")); - add_label_to_sizer (grid, this, _("Rs")); - - _buttons.resize (content->audio_channels ()); - for (int i = 0; i < content->audio_channels(); ++i) { - - if (content->audio_channels() == 1) { - add_label_to_sizer (grid, this, _("Source")); - } else { - add_label_to_sizer (grid, this, wxString::Format (_("Source %d"), i + 1)); - } - - for (int j = 0; j < MAX_AUDIO_CHANNELS; ++j) { - wxRadioButton* b = new wxRadioButton (this, wxID_ANY, wxT (""), wxDefaultPosition, wxDefaultSize, j ? 0 : wxRB_GROUP); - _buttons[i].push_back (b); - grid->Add (b, wxSHRINK); - } - } - - wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL); - overall_sizer->Add (grid, 1, wxEXPAND | wxALL, 6); - - wxSizer* buttons = CreateSeparatedButtonSizer (wxOK); - if (buttons) { - overall_sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder()); - } - - SetSizer (overall_sizer); - overall_sizer->Layout (); - overall_sizer->SetSizeHints (this); -} diff --git a/src/wx/sndfile_content_dialog.h b/src/wx/sndfile_content_dialog.h deleted file mode 100644 index 5a328892a..000000000 --- a/src/wx/sndfile_content_dialog.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - Copyright (C) 2013 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include -#include -#include -#include "lib/audio_mapping.h" - -class SndfileContent; - -class SndfileContentDialog : public wxDialog -{ -public: - SndfileContentDialog (wxWindow *, boost::shared_ptr); - - ConfiguredAudioMapping audio_mapping () const; - -private: - std::vector > _buttons; -}; diff --git a/src/wx/wscript b/src/wx/wscript index bd21af6ce..7f9cde9ac 100644 --- a/src/wx/wscript +++ b/src/wx/wscript @@ -5,6 +5,7 @@ import i18n sources = """ audio_dialog.cc + audio_mapping_view.cc audio_plot.cc config_dialog.cc dci_metadata_dialog.cc @@ -20,7 +21,6 @@ sources = """ new_film_dialog.cc properties_dialog.cc server_dialog.cc - sndfile_content_dialog.cc wx_util.cc wx_ui_signaller.cc """ -- cgit v1.2.3 From 3cc96e5cc65456f4aeb4625f56087da33da47b48 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 7 Apr 2013 00:39:34 +0100 Subject: Save audio mapping to XML; fix initial video display. --- src/lib/audio_mapping.cc | 42 +++++++++++++++++++++++++++++++++++++++--- src/lib/audio_mapping.h | 3 +++ src/lib/film.cc | 4 ++++ src/lib/player.cc | 1 + src/wx/film_viewer.cc | 10 +++++----- 5 files changed, 52 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/lib/audio_mapping.cc b/src/lib/audio_mapping.cc index 48cc23307..b85ea7314 100644 --- a/src/lib/audio_mapping.cc +++ b/src/lib/audio_mapping.cc @@ -17,13 +17,18 @@ */ +#include +#include #include "audio_mapping.h" using std::list; using std::cout; using std::make_pair; using std::pair; +using std::string; using boost::shared_ptr; +using boost::lexical_cast; +using boost::dynamic_pointer_cast; void AudioMapping::add (Channel c, libdcp::Channel d) @@ -83,6 +88,40 @@ AudioMapping::content_to_dcp (Channel c) const return d; } +void +AudioMapping::as_xml (xmlpp::Node* node) const +{ + for (list >::const_iterator i = _content_to_dcp.begin(); i != _content_to_dcp.end(); ++i) { + xmlpp::Node* t = node->add_child ("Map"); + shared_ptr c = i->first.content.lock (); + t->add_child ("Content")->add_child_text (c->file().string ()); + t->add_child ("ContentIndex")->add_child_text (lexical_cast (i->first.index)); + t->add_child ("DCP")->add_child_text (lexical_cast (i->second)); + } +} + +void +AudioMapping::set_from_xml (ContentList const & content, shared_ptr node) +{ + list > const c = node->node_children ("Map"); + for (list >::const_iterator i = c.begin(); i != c.end(); ++i) { + string const c = (*i)->string_child ("Content"); + ContentList::const_iterator j = content.begin (); + while (j != content.end() && (*j)->file().string() != c) { + ++j; + } + + if (j == content.end ()) { + continue; + } + + shared_ptr ac = dynamic_pointer_cast (*j); + assert (ac); + + add (AudioMapping::Channel (ac, (*i)->number_child ("ContentIndex")), static_cast ((*i)->number_child ("DCP"))); + } +} + bool operator== (AudioMapping::Channel const & a, AudioMapping::Channel const & b) { @@ -90,6 +129,3 @@ operator== (AudioMapping::Channel const & a, AudioMapping::Channel const & b) shared_ptr sb = b.content.lock (); return sa == sb && a.index == b.index; } - - - diff --git a/src/lib/audio_mapping.h b/src/lib/audio_mapping.h index 10ac20b48..4f2cdb7f8 100644 --- a/src/lib/audio_mapping.h +++ b/src/lib/audio_mapping.h @@ -29,6 +29,9 @@ class AudioMapping { public: + void as_xml (xmlpp::Node *) const; + void set_from_xml (ContentList const &, boost::shared_ptr); + struct Channel { Channel (boost::weak_ptr c, int i) : content (c) diff --git a/src/lib/film.cc b/src/lib/film.cc index b1f740ec2..b36dc8f9c 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -418,6 +418,7 @@ Film::write_metadata () const _dci_metadata.as_xml (root->add_child ("DCIMetadata")); root->add_child("DCPFrameRate")->add_child_text (boost::lexical_cast (_dcp_frame_rate)); root->add_child("DCIDate")->add_child_text (boost::gregorian::to_iso_string (_dci_date)); + _audio_mapping.as_xml (root->add_child("AudioMapping")); for (ContentList::iterator i = the_content.begin(); i != the_content.end(); ++i) { (*i)->as_xml (root->add_child ("Content")); @@ -502,6 +503,9 @@ Film::read_metadata () _content.push_back (c); } + /* This must come after we've loaded the content, as we're looking things up in _content */ + _audio_mapping.set_from_xml (_content, f.node_child ("AudioMapping")); + _dirty = false; _playlist->setup (_content); diff --git a/src/lib/player.cc b/src/lib/player.cc index 60917ba09..d1f047851 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -26,6 +26,7 @@ #include "job.h" using std::list; +using std::cout; using boost::shared_ptr; using boost::weak_ptr; using boost::dynamic_pointer_cast; diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 08358c519..4bc5466bc 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -84,18 +84,18 @@ FilmViewer::FilmViewer (shared_ptr f, wxWindow* p) _play_button->Connect (wxID_ANY, wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler (FilmViewer::play_clicked), 0, this); _timer.Connect (wxID_ANY, wxEVT_TIMER, wxTimerEventHandler (FilmViewer::timer), 0, this); - set_film (f); - - _player = _film->player (); + /* We need a player before we set_film() so that the first frame will be displayed */ + _player = f->player (); _player->disable_audio (); _player->disable_video_sync (); - /* Don't disable subtitles here as we may need them, and it's nice to be able to turn them on and off without needing obtain a new Player. */ _player->Video.connect (bind (&FilmViewer::process_video, this, _1, _2, _3)); + set_film (f); + JobManager::instance()->ActiveJobsChanged.connect ( bind (&FilmViewer::active_jobs_changed, this, _1) ); @@ -392,7 +392,7 @@ FilmViewer::get_frame () _display_frame.reset (); return; } - + try { _got_frame = false; while (!_got_frame) { -- cgit v1.2.3 From 21ae33095a251da25b3c5a85bc52fad63e04db0b Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 7 Apr 2013 01:25:12 +0100 Subject: Fix still video playback. --- src/lib/ffmpeg_decoder.cc | 12 ++++++------ src/lib/ffmpeg_decoder.h | 2 +- src/lib/imagemagick_decoder.cc | 4 ++-- src/lib/imagemagick_decoder.h | 2 +- src/lib/player.cc | 9 ++++++++- src/lib/video_content.cc | 2 +- src/lib/video_decoder.cc | 10 +++++----- src/lib/video_decoder.h | 8 ++++---- 8 files changed, 28 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index fdc5189a6..a0949f635 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -400,7 +400,7 @@ FFmpegDecoder::deinterleave_audio (uint8_t** data, int size) } float -FFmpegDecoder::frames_per_second () const +FFmpegDecoder::video_frame_rate () const { AVStream* s = _format_context->streams[_video_stream]; @@ -550,7 +550,7 @@ void FFmpegDecoder::out_with_sync () { /* Where we are in the output, in seconds */ - double const out_pts_seconds = video_frame() / frames_per_second(); + double const out_pts_seconds = video_frame() / video_frame_rate(); /* Where we are in the source, in seconds */ double const source_pts_seconds = av_q2d (_format_context->streams[_packet.stream_index]->time_base) @@ -567,17 +567,17 @@ FFmpegDecoder::out_with_sync () /* Difference between where we are and where we should be */ double const delta = source_pts_seconds - _first_video.get() - out_pts_seconds; - double const one_frame = 1 / frames_per_second(); + double const one_frame = 1 / video_frame_rate(); /* Insert frames if required to get out_pts_seconds up to pts_seconds */ if (delta > one_frame) { int const extra = rint (delta / one_frame); for (int i = 0; i < extra; ++i) { - repeat_last_video (); + repeat_last_video (frame_time ()); _film->log()->log ( String::compose ( N_("Extra video frame inserted at %1s; source frame %2, source PTS %3 (at %4 fps)"), - out_pts_seconds, video_frame(), source_pts_seconds, frames_per_second() + out_pts_seconds, video_frame(), source_pts_seconds, video_frame_rate() ) ); } @@ -613,7 +613,7 @@ FFmpegDecoder::film_changed (Film::Property p) ContentVideoFrame FFmpegDecoder::video_length () const { - return (double(_format_context->duration) / AV_TIME_BASE) * frames_per_second(); + return (double(_format_context->duration) / AV_TIME_BASE) * video_frame_rate(); } double diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h index 5023ac56c..cd37d20c6 100644 --- a/src/lib/ffmpeg_decoder.h +++ b/src/lib/ffmpeg_decoder.h @@ -60,7 +60,7 @@ public: FFmpegDecoder (boost::shared_ptr, boost::shared_ptr, bool video, bool audio, bool subtitles, bool video_sync); ~FFmpegDecoder (); - float frames_per_second () const; + float video_frame_rate () const; libdcp::Size native_size () const; ContentVideoFrame video_length () const; int time_base_numerator () const; diff --git a/src/lib/imagemagick_decoder.cc b/src/lib/imagemagick_decoder.cc index dff177548..6a2be1a7c 100644 --- a/src/lib/imagemagick_decoder.cc +++ b/src/lib/imagemagick_decoder.cc @@ -66,7 +66,7 @@ ImageMagickDecoder::pass () } if (have_last_video ()) { - repeat_last_video (); + repeat_last_video (double (_position) / 24); _position++; return false; } @@ -92,7 +92,7 @@ ImageMagickDecoder::pass () image = image->crop (_film->crop(), true); - emit_video (image, 0); + emit_video (image, double (_position) / 24); ++_position; return false; diff --git a/src/lib/imagemagick_decoder.h b/src/lib/imagemagick_decoder.h index 424cefe08..cb524b44b 100644 --- a/src/lib/imagemagick_decoder.h +++ b/src/lib/imagemagick_decoder.h @@ -30,7 +30,7 @@ class ImageMagickDecoder : public VideoDecoder public: ImageMagickDecoder (boost::shared_ptr, boost::shared_ptr); - float frames_per_second () const { + float video_frame_rate () const { return 24; } diff --git a/src/lib/player.cc b/src/lib/player.cc index d1f047851..ac046fcc0 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -277,7 +277,14 @@ Player::last_video_time () const case Playlist::VIDEO_FFMPEG: return _ffmpeg_decoder->last_source_time (); case Playlist::VIDEO_IMAGEMAGICK: - return (*_imagemagick_decoder)->last_source_time (); + { + double t = 0; + for (list >::const_iterator i = _imagemagick_decoders.begin(); i != _imagemagick_decoder; ++i) { + t += (*i)->video_length() / (*i)->video_frame_rate (); + } + + return t + (*_imagemagick_decoder)->last_source_time (); + } } return 0; diff --git a/src/lib/video_content.cc b/src/lib/video_content.cc index 8176c5c41..9fb2b9bce 100644 --- a/src/lib/video_content.cc +++ b/src/lib/video_content.cc @@ -73,7 +73,7 @@ VideoContent::take_from_video_decoder (shared_ptr d) { /* These decoder calls could call other content methods which take a lock on the mutex */ libdcp::Size const vs = d->native_size (); - float const vfr = d->frames_per_second (); + float const vfr = d->video_frame_rate (); { boost::mutex::scoped_lock lm (_mutex); diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc index 47385cc61..fd2b28d7f 100644 --- a/src/lib/video_decoder.cc +++ b/src/lib/video_decoder.cc @@ -50,8 +50,7 @@ VideoDecoder::emit_video (shared_ptr image, double t) sub = _timed_subtitle->subtitle (); } - signal_video (image, false, sub); - _last_source_time = t; + signal_video (image, false, sub, t); } bool @@ -65,14 +64,14 @@ VideoDecoder::have_last_video () const * we will generate a black frame. */ void -VideoDecoder::repeat_last_video () +VideoDecoder::repeat_last_video (double t) { if (!_last_image) { _last_image.reset (new SimpleImage (pixel_format(), native_size(), true)); _last_image->make_black (); } - signal_video (_last_image, true, _last_subtitle); + signal_video (_last_image, true, _last_subtitle, t); } /** Emit our signal to say that some video data is ready. @@ -81,7 +80,7 @@ VideoDecoder::repeat_last_video () * @param sub Subtitle for this frame, or 0. */ void -VideoDecoder::signal_video (shared_ptr image, bool same, shared_ptr sub) +VideoDecoder::signal_video (shared_ptr image, bool same, shared_ptr sub, double t) { TIMING (N_("Decoder emits %1"), _video_frame); Video (image, same, sub); @@ -89,6 +88,7 @@ VideoDecoder::signal_video (shared_ptr image, bool same, shared_ptr); - /** @return video frames per second, or 0 if unknown */ - virtual float frames_per_second () const = 0; + /** @return video frame rate second, or 0 if unknown */ + virtual float video_frame_rate () const = 0; /** @return native size in pixels */ virtual libdcp::Size native_size () const = 0; /** @return length according to our content's header */ @@ -59,10 +59,10 @@ protected: void emit_video (boost::shared_ptr, double); void emit_subtitle (boost::shared_ptr); bool have_last_video () const; - void repeat_last_video (); + void repeat_last_video (double); private: - void signal_video (boost::shared_ptr, bool, boost::shared_ptr); + void signal_video (boost::shared_ptr, bool, boost::shared_ptr, double); int _video_frame; double _last_source_time; -- cgit v1.2.3 From 74519cfb5e325d6f95a1b583dc471bb970f98ef6 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 7 Apr 2013 11:35:48 +0100 Subject: Fix crash. --- src/wx/film_viewer.cc | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 4bc5466bc..4d8685dd0 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -84,15 +84,17 @@ FilmViewer::FilmViewer (shared_ptr f, wxWindow* p) _play_button->Connect (wxID_ANY, wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler (FilmViewer::play_clicked), 0, this); _timer.Connect (wxID_ANY, wxEVT_TIMER, wxTimerEventHandler (FilmViewer::timer), 0, this); - /* We need a player before we set_film() so that the first frame will be displayed */ - _player = f->player (); - _player->disable_audio (); - _player->disable_video_sync (); - /* Don't disable subtitles here as we may need them, and it's nice to be able to turn them - on and off without needing obtain a new Player. - */ - - _player->Video.connect (bind (&FilmViewer::process_video, this, _1, _2, _3)); + if (f) { + /* We need a player before we set_film() so that the first frame will be displayed */ + _player = f->player (); + _player->disable_audio (); + _player->disable_video_sync (); + /* Don't disable subtitles here as we may need them, and it's nice to be able to turn them + on and off without needing obtain a new Player. + */ + + _player->Video.connect (bind (&FilmViewer::process_video, this, _1, _2, _3)); + } set_film (f); -- cgit v1.2.3 From 263eee639546964aaa57f5d2d3b24008ecfe8adb Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 7 Apr 2013 12:45:46 +0100 Subject: A few fixes; try to support sndfile audio in player. --- src/lib/encoder.cc | 31 ++-------------------- src/lib/encoder.h | 2 -- src/lib/player.cc | 36 +++++++++++++++++++++---- src/lib/player.h | 7 +++-- src/lib/util.cc | 73 +++++++++++++++++++++++++++++++++++++-------------- src/lib/util.h | 1 + src/wx/film_editor.cc | 5 +++- src/wx/film_viewer.cc | 23 +++++++--------- 8 files changed, 106 insertions(+), 72 deletions(-) (limited to 'src') diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 0542587a0..46d11c556 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -144,7 +144,7 @@ Encoder::process_end () } out->set_frames (frames); - write_audio (out); + _writer->write (out); } swr_free (&_swr_context); @@ -323,7 +323,7 @@ Encoder::process_audio (shared_ptr data) } #endif - write_audio (data); + _writer->write (data); } void @@ -423,30 +423,3 @@ Encoder::encoder_thread (ServerDescription* server) _condition.notify_all (); } } - -void -Encoder::write_audio (shared_ptr data) -{ -#if 0 - XXX - AutomaticAudioMapping m (_film->audio_channels ()); - if (m.dcp_channels() != _film->audio_channels()) { - - /* Remap (currently just for mono -> 5.1) */ - - shared_ptr b (new AudioBuffers (m.dcp_channels(), data->frames ())); - for (int i = 0; i < m.dcp_channels(); ++i) { - optional s = m.dcp_to_source (static_cast (i)); - if (!s) { - b->make_silent (i); - } else { - memcpy (b->data()[i], data->data()[s.get()], data->frames() * sizeof(float)); - } - } - - data = b; - } -#endif - - _writer->write (data); -} diff --git a/src/lib/encoder.h b/src/lib/encoder.h index b85132b72..70e6eea9a 100644 --- a/src/lib/encoder.h +++ b/src/lib/encoder.h @@ -88,8 +88,6 @@ private: void frame_done (); - void write_audio (boost::shared_ptr data); - void encoder_thread (ServerDescription *); void terminate_threads (); diff --git a/src/lib/player.cc b/src/lib/player.cc index ac046fcc0..756c3b854 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -22,6 +22,7 @@ #include "ffmpeg_decoder.h" #include "imagemagick_decoder.h" #include "sndfile_decoder.h" +#include "sndfile_content.h" #include "playlist.h" #include "job.h" @@ -95,7 +96,16 @@ Player::pass () } } - /* XXX: sndfile */ + if (_playlist->audio_from() == Playlist::AUDIO_SNDFILE) { + for (list >::iterator i = _sndfile_decoders.begin(); i != _sndfile_decoders.end(); ++i) { + if (!(*i)->pass ()) { + done = false; + } + } + + Audio (_sndfile_buffers); + _sndfile_buffers.reset (); + } return done; } @@ -133,9 +143,25 @@ Player::process_video (shared_ptr i, bool same, shared_ptr s) } void -Player::process_audio (shared_ptr b) +Player::process_audio (weak_ptr c, shared_ptr b) { - Audio (b); + if (_playlist->audio_from() == Playlist::AUDIO_SNDFILE) { + AudioMapping mapping = _film->audio_mapping (); + if (!_sndfile_buffers) { + _sndfile_buffers.reset (new AudioBuffers (mapping.dcp_channels(), b->frames ())); + _sndfile_buffers->make_silent (); + } + + for (int i = 0; i < b->channels(); ++i) { + list dcp = mapping.content_to_dcp (AudioMapping::Channel (c, i)); + for (list::iterator j = dcp.begin(); j != dcp.end(); ++j) { + _sndfile_buffers->accumulate (b, i, static_cast (*j)); + } + } + + } else { + Audio (b); + } } /** @return true on error */ @@ -238,7 +264,7 @@ Player::setup_decoders () } if (_audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG) { - _ffmpeg_decoder->connect_audio (shared_from_this ()); + _ffmpeg_decoder->Audio.connect (bind (&Player::process_audio, this, _playlist->ffmpeg (), _1)); } if (_video && _playlist->video_from() == Playlist::VIDEO_IMAGEMAGICK) { @@ -257,7 +283,7 @@ Player::setup_decoders () for (list >::iterator i = sc.begin(); i != sc.end(); ++i) { shared_ptr d (new SndfileDecoder (_film, *i)); _sndfile_decoders.push_back (d); - d->connect_audio (shared_from_this ()); + d->Audio.connect (bind (&Player::process_audio, this, *i, _1)); } } } diff --git a/src/lib/player.h b/src/lib/player.h index 79203692e..afc856316 100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@ -34,8 +34,9 @@ class SndfileDecoder; class Job; class Film; class Playlist; +class AudioContent; -class Player : public VideoSource, public AudioSource, public VideoSink, public AudioSink, public boost::enable_shared_from_this +class Player : public VideoSource, public AudioSource, public VideoSink, public boost::enable_shared_from_this { public: Player (boost::shared_ptr, boost::shared_ptr); @@ -54,7 +55,7 @@ public: private: void process_video (boost::shared_ptr i, bool same, boost::shared_ptr s); - void process_audio (boost::shared_ptr); + void process_audio (boost::weak_ptr, boost::shared_ptr); void setup_decoders (); void playlist_changed (); void content_changed (boost::weak_ptr, int); @@ -73,6 +74,8 @@ private: std::list >::iterator _imagemagick_decoder; std::list > _sndfile_decoders; + boost::shared_ptr _sndfile_buffers; + bool _video_sync; }; diff --git a/src/lib/util.cc b/src/lib/util.cc index 1e60b43fc..760b826c7 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -63,8 +63,26 @@ extern "C" { #include "i18n.h" -using namespace std; -using namespace boost; +using std::string; +using std::stringstream; +using std::setfill; +using std::ostream; +using std::endl; +using std::vector; +using std::hex; +using std::setw; +using std::ifstream; +using std::ios; +using std::min; +using std::max; +using std::list; +using std::multimap; +using std::istream; +using std::numeric_limits; +using std::pair; +using boost::shared_ptr; +using boost::thread; +using boost::lexical_cast; using libdcp::Size; thread::id ui_thread; @@ -243,7 +261,7 @@ dvdomatic_setup () Filter::setup_filters (); SoundProcessor::setup_sound_processors (); - ui_thread = this_thread::get_id (); + ui_thread = boost::this_thread::get_id (); } #ifdef DVDOMATIC_WINDOWS @@ -498,16 +516,16 @@ Socket::Socket (int timeout) , _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)); @@ -517,14 +535,14 @@ Socket::check () * @param endpoint End-point to connect to. */ void -Socket::connect (asio::ip::basic_resolver_entry const & endpoint) +Socket::connect (boost::asio::ip::basic_resolver_entry 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")); @@ -538,14 +556,14 @@ Socket::connect (asio::ip::basic_resolver_entry const & endpoint) 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 ()); @@ -566,14 +584,14 @@ Socket::write (uint32_t v) 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 ()); @@ -850,11 +868,26 @@ AudioBuffers::move (int from, int to, int frames) } } +/** Add data from from `from', `from_channel' to our channel `to_channel' */ +void +AudioBuffers::accumulate (shared_ptr from, int from_channel, int to_channel) +{ + int const N = frames (); + assert (from->frames() == N); + + float* s = from->data (from_channel); + float* d = _data[to_channel]; + + for (int i = 0; i < N; ++i) { + *d++ += *s++; + } +} + /** Trip an assert if the caller is not in the UI thread */ void ensure_ui_thread () { - assert (this_thread::get_id() == ui_thread); + assert (boost::this_thread::get_id() == ui_thread); } /** @param v Content video frame. diff --git a/src/lib/util.h b/src/lib/util.h index 1fe6212e4..f4af7c22b 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -182,6 +182,7 @@ public: void copy_from (AudioBuffers* from, int frames_to_copy, int read_offset, int write_offset); void move (int from, int to, int frames); + void accumulate (boost::shared_ptr, int, int); private: /** Number of channels */ diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 6f08b6567..071393139 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -1344,6 +1344,9 @@ FilmEditor::selected_content () } ContentList c = _film->content (); - assert (s >= 0 && size_t (s) < c.size ()); + if (s < 0 || size_t (s) >= c.size ()) { + return shared_ptr (); + } + return c[s]; } diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 4d8685dd0..bd56efd57 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -84,18 +84,6 @@ FilmViewer::FilmViewer (shared_ptr f, wxWindow* p) _play_button->Connect (wxID_ANY, wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler (FilmViewer::play_clicked), 0, this); _timer.Connect (wxID_ANY, wxEVT_TIMER, wxTimerEventHandler (FilmViewer::timer), 0, this); - if (f) { - /* We need a player before we set_film() so that the first frame will be displayed */ - _player = f->player (); - _player->disable_audio (); - _player->disable_video_sync (); - /* Don't disable subtitles here as we may need them, and it's nice to be able to turn them - on and off without needing obtain a new Player. - */ - - _player->Video.connect (bind (&FilmViewer::process_video, this, _1, _2, _3)); - } - set_film (f); JobManager::instance()->ActiveJobsChanged.connect ( @@ -142,13 +130,22 @@ FilmViewer::set_film (shared_ptr f) if (_film == f) { return; } - + _film = f; if (!_film) { return; } + _player = f->player (); + _player->disable_audio (); + _player->disable_video_sync (); + /* Don't disable subtitles here as we may need them, and it's nice to be able to turn them + on and off without needing obtain a new Player. + */ + + _player->Video.connect (bind (&FilmViewer::process_video, this, _1, _2, _3)); + _film->Changed.connect (boost::bind (&FilmViewer::film_changed, this, _1)); film_changed (Film::CONTENT); -- cgit v1.2.3 From 4725a493ed1fc6886b36553bd4600261aa644800 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 7 Apr 2013 14:25:18 +0100 Subject: Make the audio plot expand in height when its window is enlarged. --- ChangeLog | 5 +++++ src/wx/audio_dialog.cc | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/ChangeLog b/ChangeLog index f8ddd967d..de24ad89b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-04-07 Carl Hetherington + + * Make the audio plot expand in height when its + window is enlarged. + 2013-04-01 Carl Hetherington * Version 0.79 released. diff --git a/src/wx/audio_dialog.cc b/src/wx/audio_dialog.cc index 3d17988b6..39650d157 100644 --- a/src/wx/audio_dialog.cc +++ b/src/wx/audio_dialog.cc @@ -35,7 +35,7 @@ AudioDialog::AudioDialog (wxWindow* parent) wxBoxSizer* sizer = new wxBoxSizer (wxHORIZONTAL); _plot = new AudioPlot (this); - sizer->Add (_plot, 1, wxALL, 12); + sizer->Add (_plot, 1, wxALL | wxEXPAND, 12); wxBoxSizer* side = new wxBoxSizer (wxVERTICAL); -- cgit v1.2.3 From 59f5ab7320ba4911452d56f0a4e1603165da93f4 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 7 Apr 2013 14:27:15 +0100 Subject: Label subtitle offset with pixels (#101). --- src/wx/film_editor.cc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index c1d679665..79a174901 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -428,9 +428,14 @@ FilmEditor::make_subtitle_panel () _subtitle_stream = new wxChoice (_subtitle_panel, wxID_ANY); grid->Add (video_control (_subtitle_stream)); - video_control (add_label_to_sizer (grid, _subtitle_panel, _("Subtitle Offset"))); - _subtitle_offset = new wxSpinCtrl (_subtitle_panel); - grid->Add (video_control (_subtitle_offset), 1); + { + video_control (add_label_to_sizer (grid, _subtitle_panel, _("Subtitle Offset"))); + wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); + _subtitle_offset = new wxSpinCtrl (_subtitle_panel); + s->Add (_subtitle_offset); + video_control (add_label_to_sizer (s, _subtitle_panel, _("pixels"))); + grid->Add (s); + } { video_control (add_label_to_sizer (grid, _subtitle_panel, _("Subtitle Scale"))); -- cgit v1.2.3 From 0b245da3bcc5465f29cb709b459ae8b170c6d205 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 7 Apr 2013 14:28:49 +0100 Subject: Speculative fix for error on forcing language to English (#103). --- ChangeLog | 5 +++++ src/tools/dvdomatic.cc | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/ChangeLog b/ChangeLog index de24ad89b..edce0136f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,11 @@ * Make the audio plot expand in height when its window is enlarged. + * Label subtitle offset with "pixels" (#101). + + * Speculative fix for error on forcing language + to English (#103). + 2013-04-01 Carl Hetherington * Version 0.79 released. diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 87c079bee..b408ef505 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -452,7 +452,9 @@ setup_i18n () if (Config::instance()->language()) { wxLanguageInfo const * li = wxLocale::FindLanguageInfo (std_to_wx (Config::instance()->language().get())); - language = li->Language; + if (li) { + language = li->Language; + } } if (wxLocale::IsAvailable (language)) { -- cgit v1.2.3 From ec5ff2e9bf1c81f9a11ff22ede039c83c2163885 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 7 Apr 2013 15:09:20 +0100 Subject: Add more explanatory text for what is going on with scaling etc. (#106). --- ChangeLog | 3 ++ src/lib/format.cc | 47 +++++++++++------------------- src/lib/format.h | 12 ++------ src/wx/film_editor.cc | 80 ++++++++++++++++++++++++++++++++++++++++++--------- src/wx/film_editor.h | 3 +- 5 files changed, 91 insertions(+), 54 deletions(-) (limited to 'src') diff --git a/ChangeLog b/ChangeLog index edce0136f..ece1117b0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,9 @@ * Speculative fix for error on forcing language to English (#103). + * Add more explanatory text to describe what is + happening with scaling, cropping and padding (#106). + 2013-04-01 Carl Hetherington * Version 0.79 released. diff --git a/src/lib/format.cc b/src/lib/format.cc index b506c7000..21f8fb9a2 100644 --- a/src/lib/format.cc +++ b/src/lib/format.cc @@ -72,68 +72,55 @@ Format::setup_formats () { /// TRANSLATORS: these are film picture aspect ratios; "Academy" means 1.37, "Flat" 1.85 and "Scope" 2.39. _formats.push_back ( - new FixedFormat (119, libdcp::Size (1285, 1080), N_("119"), _("1.19"), N_("F"), - _("Source scaled to 1.19:1") + new FixedFormat (119, libdcp::Size (1285, 1080), N_("119"), _("1.19"), N_("F") )); _formats.push_back ( - new FixedFormat (133, libdcp::Size (1436, 1080), N_("133"), _("1.33"), N_("F"), - _("Source scaled to 1.33:1") + new FixedFormat (133, libdcp::Size (1436, 1080), N_("133"), _("1.33"), N_("F") )); _formats.push_back ( - new FixedFormat (138, libdcp::Size (1485, 1080), N_("138"), _("1.375"), N_("F"), - _("Source scaled to 1.375:1") + new FixedFormat (138, libdcp::Size (1485, 1080), N_("138"), _("1.375"), N_("F") )); _formats.push_back ( - new FixedFormat (133, libdcp::Size (1998, 1080), N_("133-in-flat"), _("4:3 within Flat"), N_("F"), - _("Source scaled to 1.33:1 then pillarboxed to Flat") + new FixedFormat (133, libdcp::Size (1998, 1080), N_("133-in-flat"), _("4:3 within Flat"), N_("F") )); _formats.push_back ( - new FixedFormat (137, libdcp::Size (1480, 1080), N_("137"), _("Academy"), N_("F"), - _("Source scaled to 1.37:1 (Academy ratio)") + new FixedFormat (137, libdcp::Size (1480, 1080), N_("137"), _("Academy"), N_("F") )); _formats.push_back ( - new FixedFormat (166, libdcp::Size (1793, 1080), N_("166"), _("1.66"), N_("F"), - _("Source scaled to 1.66:1") + new FixedFormat (166, libdcp::Size (1793, 1080), N_("166"), _("1.66"), N_("F") )); _formats.push_back ( - new FixedFormat (166, libdcp::Size (1998, 1080), N_("166-in-flat"), _("1.66 within Flat"), N_("F"), - _("Source scaled to 1.66:1 then pillarboxed to Flat") + new FixedFormat (166, libdcp::Size (1998, 1080), N_("166-in-flat"), _("1.66 within Flat"), N_("F") )); _formats.push_back ( - new FixedFormat (178, libdcp::Size (1998, 1080), N_("178-in-flat"), _("16:9 within Flat"), N_("F"), - _("Source scaled to 1.78:1 then pillarboxed to Flat") + new FixedFormat (178, libdcp::Size (1998, 1080), N_("178-in-flat"), _("16:9 within Flat"), N_("F") )); _formats.push_back ( - new FixedFormat (178, libdcp::Size (1920, 1080), N_("178"), _("16:9"), N_("F"), - _("Source scaled to 1.78:1") + new FixedFormat (178, libdcp::Size (1920, 1080), N_("178"), _("16:9"), N_("F") )); _formats.push_back ( - new FixedFormat (185, libdcp::Size (1998, 1080), N_("185"), _("Flat"), N_("F"), - _("Source scaled to Flat (1.85:1)") + new FixedFormat (185, libdcp::Size (1998, 1080), N_("185"), _("Flat"), N_("F") )); _formats.push_back ( - new FixedFormat (239, libdcp::Size (2048, 858), N_("239"), _("Scope"), N_("S"), - _("Source scaled to Scope (2.39:1)") + new FixedFormat (239, libdcp::Size (2048, 858), N_("239"), _("Scope"), N_("S") )); _formats.push_back ( - new VariableFormat (libdcp::Size (1998, 1080), N_("var-185"), _("Flat without stretch"), N_("F"), - _("Source scaled to fit Flat preserving its aspect ratio") + new VariableFormat (libdcp::Size (1998, 1080), N_("var-185"), _("Flat without stretch"), N_("F") )); _formats.push_back ( - new VariableFormat (libdcp::Size (2048, 858), N_("var-239"), _("Scope without stretch"), N_("S"), - _("Source scaled to fit Scope preserving its aspect ratio") + new VariableFormat (libdcp::Size (2048, 858), N_("var-239"), _("Scope without stretch"), N_("S") )); } @@ -195,8 +182,8 @@ Format::all () * @param id ID (e.g. 185) * @param n Nick name (e.g. Flat) */ -FixedFormat::FixedFormat (int r, libdcp::Size dcp, string id, string n, string d, string e) - : Format (dcp, id, n, d, e) +FixedFormat::FixedFormat (int r, libdcp::Size dcp, string id, string n, string d) + : Format (dcp, id, n, d) , _ratio (r) { @@ -224,8 +211,8 @@ Format::container_ratio_as_float () const return static_cast (_dcp_size.width) / _dcp_size.height; } -VariableFormat::VariableFormat (libdcp::Size dcp, string id, string n, string d, string e) - : Format (dcp, id, n, d, e) +VariableFormat::VariableFormat (libdcp::Size dcp, string id, string n, string d) + : Format (dcp, id, n, d) { } diff --git a/src/lib/format.h b/src/lib/format.h index 305524628..783ff25ce 100644 --- a/src/lib/format.h +++ b/src/lib/format.h @@ -31,12 +31,11 @@ class Film; class Format { public: - Format (libdcp::Size dcp, std::string id, std::string n, std::string d, std::string e) + Format (libdcp::Size dcp, std::string id, std::string n, std::string d) : _dcp_size (dcp) , _id (id) , _nickname (n) , _dci_name (d) - , _description (e) {} /** @return the aspect ratio multiplied by 100 @@ -76,10 +75,6 @@ public: return _dci_name; } - std::string description () const { - return _description; - } - std::string as_metadata () const; static Format const * from_nickname (std::string n); @@ -99,7 +94,6 @@ protected: /** nickname (e.g. Flat, Scope) */ std::string _nickname; std::string _dci_name; - std::string _description; private: /** all available formats */ @@ -113,7 +107,7 @@ private: class FixedFormat : public Format { public: - FixedFormat (int, libdcp::Size, std::string, std::string, std::string, std::string); + FixedFormat (int, libdcp::Size, std::string, std::string, std::string); int ratio_as_integer (boost::shared_ptr) const { return _ratio; @@ -134,7 +128,7 @@ private: class VariableFormat : public Format { public: - VariableFormat (libdcp::Size, std::string, std::string, std::string, std::string); + VariableFormat (libdcp::Size, std::string, std::string, std::string); int ratio_as_integer (boost::shared_ptr f) const; float ratio_as_float (boost::shared_ptr f) const; diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 79a174901..916d86cc0 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -270,14 +270,6 @@ FilmEditor::make_video_panel () grid->Add (_format, wxGBPosition (r, 1)); ++r; - _format_description = new wxStaticText (_video_panel, wxID_ANY, wxT (""), wxDefaultPosition, wxDefaultSize); - grid->Add (_format_description, wxGBPosition (r, 0), wxGBSpan (1, 2), wxEXPAND | wxALIGN_CENTER_VERTICAL | wxALL, 6); - wxFont font = _format_description->GetFont(); - font.SetStyle(wxFONTSTYLE_ITALIC); - font.SetPointSize(font.GetPointSize() - 1); - _format_description->SetFont(font); - ++r; - add_label_to_grid_bag_sizer (grid, _video_panel, _("Left crop"), wxGBPosition (r, 0)); _left_crop = new wxSpinCtrl (_video_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)); grid->Add (_left_crop, wxGBPosition (r, 1)); @@ -298,6 +290,14 @@ FilmEditor::make_video_panel () grid->Add (_bottom_crop, wxGBPosition (r, 1)); ++r; + _scaling_description = new wxStaticText (_video_panel, wxID_ANY, wxT ("\n \n \n \n"), wxDefaultPosition, wxDefaultSize); + grid->Add (_scaling_description, wxGBPosition (r, 0), wxGBSpan (1, 2), wxEXPAND | wxALIGN_CENTER_VERTICAL | wxALL, 6); + wxFont font = _scaling_description->GetFont(); + font.SetStyle(wxFONTSTYLE_ITALIC); + font.SetPointSize(font.GetPointSize() - 1); + _scaling_description->SetFont(font); + ++r; + /* VIDEO-only stuff */ { video_control (add_label_to_grid_bag_sizer (grid, _video_panel, _("Filters"), wxGBPosition (r, 0))); @@ -648,12 +648,7 @@ FilmEditor::film_changed (Film::Property p) checked_set (_format, n); } setup_dcp_name (); - - if (_film->format ()) { - _format_description->SetLabel (std_to_wx (_film->format()->description ())); - } else { - _format_description->SetLabel (wxT ("")); - } + setup_scaling_description (); break; } case Film::CROP: @@ -661,6 +656,7 @@ FilmEditor::film_changed (Film::Property p) checked_set (_right_crop, _film->crop().right); checked_set (_top_crop, _film->crop().top); checked_set (_bottom_crop, _film->crop().bottom); + setup_scaling_description (); break; case Film::FILTERS: { @@ -689,6 +685,7 @@ FilmEditor::film_changed (Film::Property p) s << _film->size().width << " x " << _film->size().height; _original_size->SetLabel (std_to_wx (s.str ())); } + setup_scaling_description (); break; case Film::LENGTH: if (_film->source_frame_rate() > 0 && _film->length()) { @@ -1305,3 +1302,58 @@ FilmEditor::setup_show_audio_sensitivity () { _show_audio->Enable (_film && _film->has_audio ()); } + +void +FilmEditor::setup_scaling_description () +{ + wxString d; + + int lines = 0; + + d << wxString::Format ( + _("Original video is %dx%d (%.2f:1)\n"), + _film->size().width, _film->size().height, + float (_film->size().width) / _film->size().height + ); + + ++lines; + + Crop const crop = _film->crop (); + if (crop.left || crop.right || crop.top || crop.bottom) { + libdcp::Size const cropped = _film->cropped_size (_film->size ()); + d << wxString::Format ( + _("Cropped to %dx%d (%.2f:1)\n"), + cropped.width, cropped.height, + float (cropped.width) / cropped.height + ); + ++lines; + } + + Format const * format = _film->format (); + if (format) { + int const padding = format->dcp_padding (_film); + libdcp::Size scaled = format->dcp_size (); + scaled.width -= padding * 2; + d << wxString::Format ( + _("Scaled to %dx%d (%.2f:1)\n"), + scaled.width, scaled.height, + float (scaled.width) / scaled.height + ); + ++lines; + + if (padding) { + d << wxString::Format ( + _("Padded with black to %dx%d (%.2f:1)\n"), + format->dcp_size().width, format->dcp_size().height, + float (format->dcp_size().width) / format->dcp_size().height + ); + ++lines; + } + } + + for (int i = lines; i < 4; ++i) { + d << " \n"; + } + + _scaling_description->SetLabel (d); +} diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index e5b619886..7de63014e 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -99,6 +99,7 @@ private: void setup_audio_details (); void setup_dcp_name (); void setup_show_audio_sensitivity (); + void setup_scaling_description (); wxControl* video_control (wxControl *); wxControl* still_control (wxControl *); @@ -124,7 +125,7 @@ private: wxButton* _edit_dci_button; /** The Film's format */ wxChoice* _format; - wxStaticText* _format_description; + wxStaticText* _scaling_description; /** The Film's content file */ wxFilePickerCtrl* _content; wxCheckBox* _trust_content_header; -- cgit v1.2.3 From fea8c3743fd0710c2716fc6de5a283d378338800 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 7 Apr 2013 15:20:47 +0100 Subject: Give a hopefully helpful message when clicking Open without selecting a folder (#99). --- ChangeLog | 3 +++ src/tools/dvdomatic.cc | 12 ++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/ChangeLog b/ChangeLog index ece1117b0..1235944df 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,6 +11,9 @@ * Add more explanatory text to describe what is happening with scaling, cropping and padding (#106). + * Give a hopefully helpful message when clicking Open + without selecting a folder (#99). + 2013-04-01 Carl Hetherington * Version 0.79 released. diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index b408ef505..80a33efef 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -317,8 +317,16 @@ private: void file_open (wxCommandEvent &) { wxDirDialog* c = new wxDirDialog (this, _("Select film to open"), wxStandardPaths::Get().GetDocumentsDir(), wxDEFAULT_DIALOG_STYLE | wxDD_DIR_MUST_EXIST); - int const r = c->ShowModal (); - + int r; + while (1) { + r = c->ShowModal (); + if (r == wxID_OK && c->GetPath() == wxStandardPaths::Get().GetDocumentsDir()) { + error_dialog (this, _("You did not select a folder. Make sure that you select a folder before clicking Open.")); + } else { + break; + } + } + if (r == wxID_OK) { maybe_save_then_delete_film (); try { -- cgit v1.2.3 From e7aad9759e44ff3e1aa17ad8d5548a02646a67c5 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 7 Apr 2013 16:22:04 +0100 Subject: Fix servomatic_gui start-up on Linux (#98). --- icons/taskbar_icon.png | Bin 0 -> 141 bytes src/tools/servomatic_gui.cc | 24 ++++++++++++++++++++++-- wscript | 4 ++++ 3 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 icons/taskbar_icon.png (limited to 'src') diff --git a/icons/taskbar_icon.png b/icons/taskbar_icon.png new file mode 100644 index 000000000..fd6b6e968 Binary files /dev/null and b/icons/taskbar_icon.png differ diff --git a/src/tools/servomatic_gui.cc b/src/tools/servomatic_gui.cc index dd169725f..52ec0a3a3 100644 --- a/src/tools/servomatic_gui.cc +++ b/src/tools/servomatic_gui.cc @@ -94,7 +94,15 @@ class TaskBarIcon : public wxTaskBarIcon public: TaskBarIcon () { +#ifdef __WXMSW__ wxIcon icon (std_to_wx ("taskbar_icon")); +#endif +#ifdef __WXGTK__ + wxInitAllImageHandlers(); + wxBitmap bitmap (wxString::Format ("%s/taskbar_icon.png", POSIX_ICON_PREFIX), wxBITMAP_TYPE_PNG); + wxIcon icon; + icon.CopyFromBitmap (bitmap); +#endif SetIcon (icon, std_to_wx ("DVD-o-matic encode server")); Connect (ID_status, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (TaskBarIcon::status)); @@ -128,20 +136,31 @@ public: App () : wxApp () , _thread (0) + , _icon (0) {} private: bool OnInit () { + if (!wxApp::OnInit ()) { + return false; + } + dvdomatic_setup (); - new TaskBarIcon; - + _icon = new TaskBarIcon; _thread = new thread (bind (&App::main_thread, this)); + return true; } + int OnExit () + { + delete _icon; + return wxApp::OnExit (); + } + void main_thread () { Server server (memory_log); @@ -149,6 +168,7 @@ private: } boost::thread* _thread; + TaskBarIcon* _icon; }; IMPLEMENT_APP (App) diff --git a/wscript b/wscript index 7ee3899e7..f7c696433 100644 --- a/wscript +++ b/wscript @@ -37,6 +37,7 @@ def configure(conf): else: conf.env.append_value('CXXFLAGS', '-DDVDOMATIC_POSIX') conf.env.append_value('CXXFLAGS', '-DPOSIX_LOCALE_PREFIX="%s/share/locale"' % conf.env['PREFIX']) + conf.env.append_value('CXXFLAGS', '-DPOSIX_ICON_PREFIX="%s/share/dvdomatic"' % conf.env['PREFIX']) boost_lib_suffix = '' boost_thread = 'boost_thread' conf.env.append_value('LINKFLAGS', '-pthread') @@ -231,6 +232,9 @@ def build(bld): for r in ['22x22', '32x32', '48x48', '64x64', '128x128']: bld.install_files('${PREFIX}/share/icons/hicolor/%s/apps' % r, 'icons/%s/dvdomatic.png' % r) + if not bld.env.TARGET_WINDOWS: + bld.install_files('${PREFIX}/share/dvdomatic', 'icons/taskbar_icon.png') + bld.add_post_fun(post) def dist(ctx): -- cgit v1.2.3 From 588ddc8856b5188c5c666280da1b2c962e64dedb Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 7 Apr 2013 17:12:37 +0100 Subject: Add note about audio resampling (#96). --- src/lib/util.cc | 2 +- src/wx/film_editor.cc | 52 ++++++++++++++++++++++++++++++++++++++++++++------- src/wx/film_editor.h | 2 ++ 3 files changed, 48 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/lib/util.cc b/src/lib/util.cc index 5b2038cde..557e9a34b 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -1014,7 +1014,7 @@ FrameRateConversion::FrameRateConversion (float source, int dcp) if (change_speed) { float const pc = dcp * 100 / (source * factor()); - description += String::compose (_("DCP will run at %1%% of the source speed."), pc); + description += String::compose (_("DCP will run at %1%% of the source speed.\n"), pc); } } } diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 916d86cc0..69f09c880 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -622,6 +622,7 @@ FilmEditor::film_changed (Film::Property p) setup_subtitle_control_sensitivity (); setup_streams (); setup_show_audio_sensitivity (); + setup_frame_rate_description (); break; case Film::TRUST_CONTENT_HEADER: checked_set (_trust_content_header, _film->trust_content_header ()); @@ -633,6 +634,7 @@ FilmEditor::film_changed (Film::Property p) case Film::CONTENT_AUDIO_STREAMS: setup_streams (); setup_show_audio_sensitivity (); + setup_frame_rate_description (); break; case Film::FORMAT: { @@ -677,6 +679,7 @@ FilmEditor::film_changed (Film::Property p) case Film::SOURCE_FRAME_RATE: s << fixed << setprecision(2) << _film->source_frame_rate(); _source_frame_rate->SetLabel (std_to_wx (s.str ())); + setup_frame_rate_description (); break; case Film::SIZE: if (_film->size().width == 0 && _film->size().height == 0) { @@ -758,6 +761,7 @@ FilmEditor::film_changed (Film::Property p) setup_audio_details (); setup_audio_control_sensitivity (); setup_show_audio_sensitivity (); + setup_frame_rate_description (); break; case Film::USE_CONTENT_AUDIO: checked_set (_use_content_audio, _film->use_content_audio()); @@ -766,6 +770,7 @@ FilmEditor::film_changed (Film::Property p) setup_audio_details (); setup_audio_control_sensitivity (); setup_show_audio_sensitivity (); + setup_frame_rate_description (); break; case Film::SUBTITLE_STREAM: if (_film->subtitle_stream()) { @@ -780,6 +785,7 @@ FilmEditor::film_changed (Film::Property p) } setup_audio_details (); setup_show_audio_sensitivity (); + setup_frame_rate_description (); break; } case Film::DCP_FRAME_RATE: @@ -793,15 +799,39 @@ FilmEditor::film_changed (Film::Property p) } if (_film->source_frame_rate()) { - _frame_rate_description->SetLabel (std_to_wx (FrameRateConversion (_film->source_frame_rate(), _film->dcp_frame_rate()).description)); _best_dcp_frame_rate->Enable (best_dcp_frame_rate (_film->source_frame_rate ()) != _film->dcp_frame_rate ()); } else { - _frame_rate_description->SetLabel (wxT ("")); _best_dcp_frame_rate->Disable (); } + + setup_frame_rate_description (); } } +void +FilmEditor::setup_frame_rate_description () +{ + wxString d; + if (_film->source_frame_rate()) { + d << std_to_wx (FrameRateConversion (_film->source_frame_rate(), _film->dcp_frame_rate()).description); +#ifdef HAVE_SWRESAMPLE + if (_film->audio_stream() && _film->audio_stream()->sample_rate() != _film->target_audio_sample_rate ()) { + d << wxString::Format ( + _("Audio will be resampled from %dHz to %dHz\n"), + _film->audio_stream()->sample_rate(), + _film->target_audio_sample_rate() + ); + } else { + d << "\n"; + } +#else + d << "\n"; +#endif + } + + _frame_rate_description->SetLabel (d); +} + /** Called when the format widget has been changed */ void FilmEditor::format_changed (wxCommandEvent &) @@ -999,6 +1029,12 @@ FilmEditor::setup_visibility () (*i)->Show (c == STILL); } + setup_notebook_size (); +} + +void +FilmEditor::setup_notebook_size () +{ _notebook->InvalidateBestSize (); _film_sizer->Layout (); @@ -1228,15 +1264,17 @@ FilmEditor::setup_audio_details () if (!_film->content_audio_stream()) { _audio->SetLabel (wxT ("")); } else { - stringstream s; + wxString s; if (_film->audio_stream()->channels() == 1) { - s << wx_to_std (_("1 channel")); + s << _("1 channel"); } else { - s << _film->audio_stream()->channels () << " " << wx_to_std (_("channels")); + s << _film->audio_stream()->channels () << " " << _("channels"); } - s << ", " << _film->audio_stream()->sample_rate() << wx_to_std (_("Hz")); - _audio->SetLabel (std_to_wx (s.str ())); + s << ", " << _film->audio_stream()->sample_rate() << _("Hz"); + _audio->SetLabel (s); } + + setup_notebook_size (); } void diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index 7de63014e..7123620d3 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -100,6 +100,8 @@ private: void setup_dcp_name (); void setup_show_audio_sensitivity (); void setup_scaling_description (); + void setup_notebook_size (); + void setup_frame_rate_description (); wxControl* video_control (wxControl *); wxControl* still_control (wxControl *); -- cgit v1.2.3 From fb55f810414893a1bad62abd03e5202aa42028c1 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 7 Apr 2013 17:50:35 +0100 Subject: Hopefully fix lack of background redraw of film viewer on Windows (#86). --- src/wx/film_editor.cc | 2 +- src/wx/film_viewer.cc | 31 ++++++++++++++++--------------- src/wx/film_viewer.h | 2 -- 3 files changed, 17 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 69f09c880..eb36ce1ff 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -148,7 +148,7 @@ FilmEditor::make_film_panel () } ++r; - _frame_rate_description = new wxStaticText (_film_panel, wxID_ANY, wxT (" \n "), wxDefaultPosition, wxDefaultSize); + _frame_rate_description = new wxStaticText (_film_panel, wxID_ANY, wxT (" \n \n "), wxDefaultPosition, wxDefaultSize); grid->Add (video_control (_frame_rate_description), wxGBPosition (r, 0), wxGBSpan (1, 2), wxEXPAND | wxALIGN_CENTER_VERTICAL | wxALL, 6); wxFont font = _frame_rate_description->GetFont(); font.SetStyle(wxFONTSTYLE_ITALIC); diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 08eade4d0..4dca5cad8 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -54,7 +54,6 @@ FilmViewer::FilmViewer (shared_ptr f, wxWindow* p) , _play_button (new wxToggleButton (this, wxID_ANY, _("Play"))) , _display_frame_x (0) , _got_frame (false) - , _clear_required (false) { _panel->SetDoubleBuffered (true); #if wxMAJOR_VERSION == 2 && wxMINOR_VERSION >= 9 @@ -201,11 +200,6 @@ FilmViewer::paint_panel (wxPaintEvent &) { wxPaintDC dc (_panel); - if (_clear_required) { - dc.Clear (); - _clear_required = false; - } - if (!_display_frame || !_film || !_out_size.width || !_out_size.height) { dc.Clear (); return; @@ -227,6 +221,22 @@ FilmViewer::paint_panel (wxPaintEvent &) wxBitmap sub_bitmap (sub); dc.DrawBitmap (sub_bitmap, _display_sub_position.x, _display_sub_position.y); } + + if (_film_size.width < _panel_size.width) { + wxPen p (GetBackgroundColour ()); + wxBrush b (GetBackgroundColour ()); + dc.SetPen (p); + dc.SetBrush (b); + dc.DrawRectangle (_film_size.width, 0, _panel_size.width - _film_size.width, _panel_size.height); + } + + if (_film_size.height < _panel_size.height) { + wxPen p (GetBackgroundColour ()); + wxBrush b (GetBackgroundColour ()); + dc.SetPen (p); + dc.SetBrush (b); + dc.DrawRectangle (0, _film_size.height, _panel_size.width, _panel_size.height - _film_size.height); + } } @@ -275,11 +285,6 @@ FilmViewer::raw_to_display () return; } - libdcp::Size old_size; - if (_display_frame) { - old_size = _display_frame->size(); - } - boost::shared_ptr input = _raw_frame; pair const s = Filter::ffmpeg_strings (_film->filters()); @@ -290,10 +295,6 @@ FilmViewer::raw_to_display () /* Get a compacted image as we have to feed it to wxWidgets */ _display_frame = input->scale_and_convert_to_rgb (_film_size, 0, _film->scaler(), false); - if (old_size != _display_frame->size()) { - _clear_required = true; - } - if (_raw_sub) { /* Our output is already cropped by the decoder, so we need to account for that diff --git a/src/wx/film_viewer.h b/src/wx/film_viewer.h index 456301eb4..f89269d2b 100644 --- a/src/wx/film_viewer.h +++ b/src/wx/film_viewer.h @@ -80,6 +80,4 @@ private: libdcp::Size _film_size; /** Size of the panel that we have available */ libdcp::Size _panel_size; - - bool _clear_required; }; -- cgit v1.2.3 From fa3ed3149bd2464d920f54c92b99f57ce9b4d75f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 7 Apr 2013 18:17:31 +0100 Subject: Merge .po files. --- src/lib/po/es_ES.po | 227 +++++++++++++++++++++++++++++--------------------- src/lib/po/fr_FR.po | 148 +++++++++++++++----------------- src/lib/po/it_IT.po | 150 ++++++++++++++++----------------- src/lib/po/sv_SE.po | 152 ++++++++++++++++----------------- src/tools/po/es_ES.po | 20 +++-- src/tools/po/fr_FR.po | 20 +++-- src/tools/po/it_IT.po | 20 +++-- src/tools/po/sv_SE.po | 21 +++-- src/wx/po/es_ES.po | 190 ++++++++++++++++++++++++++---------------- src/wx/po/fr_FR.po | 61 ++++++++++---- src/wx/po/it_IT.po | 61 ++++++++++---- src/wx/po/sv_SE.po | 62 ++++++++++---- 12 files changed, 645 insertions(+), 487 deletions(-) (limited to 'src') diff --git a/src/lib/po/es_ES.po b/src/lib/po/es_ES.po index 153a90085..73c304348 100644 --- a/src/lib/po/es_ES.po +++ b/src/lib/po/es_ES.po @@ -7,15 +7,15 @@ msgid "" msgstr "" "Project-Id-Version: LIBDVDOMATIC\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-15 08:39+0000\n" +"POT-Creation-Date: 2013-04-07 18:17+0100\n" "PO-Revision-Date: 2013-04-02 19:10-0500\n" "Last-Translator: Manuel AC \n" "Language-Team: Manuel AC \n" +"Language: es-ES\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" -"Language: es-ES\n" #: src/lib/transcode_job.cc:87 msgid "0%" @@ -25,27 +25,27 @@ msgstr "0%" msgid "1.19" msgstr "1.19" -#: src/lib/format.cc:80 +#: src/lib/format.cc:79 msgid "1.33" msgstr "1.33" -#: src/lib/format.cc:85 +#: src/lib/format.cc:83 msgid "1.375" msgstr "1.375" -#: src/lib/format.cc:100 +#: src/lib/format.cc:95 msgid "1.66" msgstr "1.66" -#: src/lib/format.cc:105 +#: src/lib/format.cc:99 msgid "1.66 within Flat" msgstr "1.66 en Flat" -#: src/lib/format.cc:115 +#: src/lib/format.cc:107 msgid "16:9" msgstr "16:9" -#: src/lib/format.cc:110 +#: src/lib/format.cc:103 msgid "16:9 within Flat" msgstr "16:9 en Flat" @@ -53,7 +53,7 @@ msgstr "16:9 en Flat" msgid "3D denoiser" msgstr "reducción de ruido 3D" -#: src/lib/format.cc:90 +#: src/lib/format.cc:87 msgid "4:3 within Flat" msgstr "4:3 en Flat" @@ -61,7 +61,7 @@ msgstr "4:3 en Flat" msgid "A/B transcode %1" msgstr "Codificación A/B %1" -#: src/lib/format.cc:95 +#: src/lib/format.cc:91 msgid "Academy" msgstr "Academy" @@ -69,7 +69,7 @@ msgstr "Academy" msgid "Advertisement" msgstr "Publicidad" -#: src/lib/job.cc:71 +#: src/lib/job.cc:72 msgid "An error occurred whilst handling the file %1." msgstr "Ha ocurrido un error con el fichero %1." @@ -89,11 +89,23 @@ msgstr "Bicúbico" msgid "Bilinear" msgstr "Bilineal" +#: src/lib/job.cc:302 +msgid "Cancelled" +msgstr "" + +#: src/lib/exceptions.cc:60 +msgid "Cannot handle pixel format %1 during %2" +msgstr "" + #: src/lib/encoder.cc:101 msgid "Cannot resample audio as libswresample is not present" msgstr "" "No se puede redimensionar el sonido porque no se encuentra libswresample" +#: src/lib/util.cc:932 +msgid "Centre" +msgstr "" + #: src/lib/scp_dcp_job.cc:109 msgid "Copy DCP to TMS" msgstr "Copiar DCP al TMS" @@ -122,15 +134,16 @@ msgstr "No se pudo escribir el fichero remoto (%1)" msgid "Cubic interpolating deinterlacer" msgstr "Desentrelazado por interpolación cúbica" -#: src/lib/util.cc:965 +#: src/lib/util.cc:1007 msgid "DCP and source have the same rate.\n" msgstr "La fuente y el DCP tienen la misma velocidad.\n" -#: src/lib/util.cc:975 -msgid "DCP will run at %1%% of the source speed." +#: src/lib/util.cc:1017 +#, fuzzy +msgid "DCP will run at %1%% of the source speed.\n" msgstr "El DCP se reproducirá al %1%% de la velocidad de la fuente." -#: src/lib/util.cc:968 +#: src/lib/util.cc:1010 msgid "DCP will use every other frame of the source.\n" msgstr "El DCP usará fotogramas alternos de la fuente.\n" @@ -153,11 +166,11 @@ msgstr "Deringing filter" msgid "Dolby CP750" msgstr "Dolby CP750" -#: src/lib/util.cc:970 +#: src/lib/util.cc:1012 msgid "Each source frame will be doubled in the DCP.\n" msgstr "Se doblará cada fotograma de la fuente en el DCP.\n" -#: src/lib/job.cc:287 +#: src/lib/job.cc:300 msgid "Error (%1)" msgstr "Error (%1)" @@ -197,11 +210,11 @@ msgstr "Bilineal rápido" msgid "Feature" msgstr "Película" -#: src/lib/format.cc:120 +#: src/lib/format.cc:111 msgid "Flat" msgstr "Flat" -#: src/lib/format.cc:130 +#: src/lib/format.cc:119 msgid "Flat without stretch" msgstr "Flat sin deformación" @@ -229,7 +242,7 @@ msgstr "Horizontal deblocking filter" msgid "Horizontal deblocking filter A" msgstr "Horizontal deblocking filter A" -#: src/lib/job.cc:87 src/lib/job.cc:96 +#: src/lib/job.cc:92 src/lib/job.cc:101 msgid "" "It is not known what caused this error. The best idea is to report the " "problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" @@ -245,6 +258,18 @@ msgstr "Kernel deinterlacer" msgid "Lanczos" msgstr "Lanczos" +#: src/lib/util.cc:930 +msgid "Left" +msgstr "" + +#: src/lib/util.cc:934 +msgid "Left surround" +msgstr "" + +#: src/lib/util.cc:933 +msgid "Lfe (sub)" +msgstr "" + #: src/lib/filter.cc:75 msgid "Linear blend deinterlacer" msgstr "Linear blend deinterlacer" @@ -271,7 +296,7 @@ msgstr "Motion compensating deinterlacer" msgid "Noise reduction" msgstr "Reducción de ruido" -#: src/lib/job.cc:285 +#: src/lib/job.cc:298 msgid "OK (ran for %1)" msgstr "OK (ejecución %1)" @@ -291,19 +316,27 @@ msgstr "Anuncio de servicio público" msgid "Rating" msgstr "Clasificación" -#: src/lib/util.cc:458 +#: src/lib/util.cc:500 msgid "Rec 709" msgstr "Rec 709" +#: src/lib/util.cc:931 +msgid "Right" +msgstr "" + +#: src/lib/util.cc:935 +msgid "Right surround" +msgstr "" + #: src/lib/scp_dcp_job.cc:133 msgid "SSH error (%1)" msgstr "error SSH (%1)" -#: src/lib/format.cc:125 +#: src/lib/format.cc:115 msgid "Scope" msgstr "Scope" -#: src/lib/format.cc:135 +#: src/lib/format.cc:123 msgid "Scope without stretch" msgstr "Scope sin deformación" @@ -315,58 +348,6 @@ msgstr "Cortometraje" msgid "Sinc" msgstr "Sinc" -#: src/lib/format.cc:76 -msgid "Source scaled to 1.19:1" -msgstr "Fuente escalada a 1.19:1" - -#: src/lib/format.cc:81 -msgid "Source scaled to 1.33:1" -msgstr "Fuente escalada a 1.33:1" - -#: src/lib/format.cc:91 -msgid "Source scaled to 1.33:1 then pillarboxed to Flat" -msgstr "Fuente escalada a 1.33:1 con bandas hasta Flat" - -#: src/lib/format.cc:86 -msgid "Source scaled to 1.375:1" -msgstr "Fuente escalada a 1.375:1" - -#: src/lib/format.cc:96 -msgid "Source scaled to 1.37:1 (Academy ratio)" -msgstr "Fuente escalada a 1.37:1 (Academy)" - -#: src/lib/format.cc:101 -msgid "Source scaled to 1.66:1" -msgstr "Fuente escalada a 1.66:1" - -#: src/lib/format.cc:106 -msgid "Source scaled to 1.66:1 then pillarboxed to Flat" -msgstr "Fuente escalada a 1.66:1 con bandas hasta Flat" - -#: src/lib/format.cc:116 -msgid "Source scaled to 1.78:1" -msgstr "Fuente escalada a 1.78:1" - -#: src/lib/format.cc:111 -msgid "Source scaled to 1.78:1 then pillarboxed to Flat" -msgstr "Fuente escalada a 1.78:1 con bandas hasta Flat" - -#: src/lib/format.cc:121 -msgid "Source scaled to Flat (1.85:1)" -msgstr "Fuente escalada a Flat (1.85:1)" - -#: src/lib/format.cc:126 -msgid "Source scaled to Scope (2.39:1)" -msgstr "Fuente escalada a Scope (2.39:1)" - -#: src/lib/format.cc:131 -msgid "Source scaled to fit Flat preserving its aspect ratio" -msgstr "Fuente escalada a Flat conservando el ratio de aspecto" - -#: src/lib/format.cc:136 -msgid "Source scaled to fit Scope preserving its aspect ratio" -msgstr "Fuente escalada a Scope conservando el ratio de aspecto" - #: src/lib/scaler.cc:68 msgid "Spline" msgstr "Spline" @@ -387,7 +368,7 @@ msgstr "Temporal noise reducer" msgid "Test" msgstr "Test" -#: src/lib/job.cc:76 +#: src/lib/job.cc:77 msgid "" "The drive that the film is stored on is low in disc space. Free some more " "space and try again." @@ -407,7 +388,7 @@ msgstr "Codificar %1" msgid "Transitional" msgstr "Transitional" -#: src/lib/job.cc:95 +#: src/lib/job.cc:100 msgid "Unknown error" msgstr "Error desconocido" @@ -439,15 +420,11 @@ msgstr "X" msgid "Yet Another Deinterlacing Filter" msgstr "Yet Another Deinterlacing Filter" -#: src/lib/encoder.cc:271 -msgid "adding to queue of %1" -msgstr "añadiendo a la cola de %1" - #: src/lib/film.cc:263 msgid "cannot contain slashes" msgstr "no puede contener barras" -#: src/lib/util.cc:499 +#: src/lib/util.cc:541 msgid "connect timed out" msgstr "tiempo de conexión agotado" @@ -467,6 +444,11 @@ msgstr "tipo de contenido" msgid "copying %1" msgstr "copiando %1" +#: src/lib/exceptions.cc:36 +#, fuzzy +msgid "could not create file %1" +msgstr "No se pudo escribir el fichero remoto (%1)" + #: src/lib/ffmpeg_decoder.cc:191 msgid "could not find audio decoder" msgstr "no se encontró el decodificador de audio" @@ -483,14 +465,24 @@ msgstr "no se pudo encontrar decodificador de subtítutlos" msgid "could not find video decoder" msgstr "no se pudo encontrar decodificador de vídeo" -#: src/lib/external_audio_decoder.cc:72 +#: src/lib/sndfile_decoder.cc:72 msgid "could not open external audio file for reading" msgstr "no se pudo leer el fichero externo de audio" +#: src/lib/exceptions.cc:29 +#, fuzzy +msgid "could not open file %1" +msgstr "no se pudo abrir el fichero para lectura" + #: src/lib/dcp_video_frame.cc:388 msgid "could not open file for reading" msgstr "no se pudo abrir el fichero para lectura" +#: src/lib/exceptions.cc:44 +#, fuzzy +msgid "could not read from file %1 (%2)" +msgstr "No se pudo crear la carpeta remota %1 (%2)" + #: src/lib/encoder.cc:137 src/lib/encoder.cc:314 msgid "could not run sample-rate converter" msgstr "no se pudo ejecutar el conversor de velocidad" @@ -503,19 +495,16 @@ msgstr "no se pudo abrir la sesión SCP (%1)" msgid "could not start SSH session" msgstr "no se pudo abrir la sesión SSH" -#: src/lib/encoder.cc:247 -msgid "decoder sleeps with queue of %1" -msgstr "" - -#: src/lib/encoder.cc:249 -msgid "decoder wakes with queue of %1" -msgstr "" +#: src/lib/exceptions.cc:50 +#, fuzzy +msgid "could not write to file %1 (%2)" +msgstr "No se pudo escribir el fichero remoto (%1)" -#: src/lib/external_audio_decoder.cc:94 +#: src/lib/sndfile_decoder.cc:94 msgid "external audio files have differing lengths" msgstr "los ficheros externos de sonido tienen duraciones diferentes" -#: src/lib/external_audio_decoder.cc:76 +#: src/lib/sndfile_decoder.cc:76 msgid "external audio files must be mono" msgstr "los ficheros externos de sonido deben ser mono" @@ -543,10 +532,14 @@ msgstr "minuto" msgid "minutes" msgstr "minutos" -#: src/lib/util.cc:642 +#: src/lib/util.cc:684 msgid "missing key %1 in key-value set" msgstr "falta la clave %1 en el par clave-valor" +#: src/lib/exceptions.cc:54 +msgid "missing required setting %1" +msgstr "" + #: src/lib/subtitle.cc:52 msgid "multi-part subtitles not yet supported" msgstr "todavía no se soportan subtítulos en múltiples partes" @@ -565,11 +558,11 @@ msgstr "todavía no se soportan subtítulos que no son en mapas de bits" #. / TRANSLATORS: remaining here follows an amount of time that is remaining #. / on an operation. -#: src/lib/job.cc:282 +#: src/lib/job.cc:295 msgid "remaining" msgstr "pendiente" -#: src/lib/util.cc:456 +#: src/lib/util.cc:498 msgid "sRGB" msgstr "sRGB" @@ -584,3 +577,45 @@ msgstr "imagen fija" #: src/lib/film.cc:274 msgid "video" msgstr "vídeo" + +#~ msgid "Source scaled to 1.19:1" +#~ msgstr "Fuente escalada a 1.19:1" + +#~ msgid "Source scaled to 1.33:1" +#~ msgstr "Fuente escalada a 1.33:1" + +#~ msgid "Source scaled to 1.33:1 then pillarboxed to Flat" +#~ msgstr "Fuente escalada a 1.33:1 con bandas hasta Flat" + +#~ msgid "Source scaled to 1.375:1" +#~ msgstr "Fuente escalada a 1.375:1" + +#~ msgid "Source scaled to 1.37:1 (Academy ratio)" +#~ msgstr "Fuente escalada a 1.37:1 (Academy)" + +#~ msgid "Source scaled to 1.66:1" +#~ msgstr "Fuente escalada a 1.66:1" + +#~ msgid "Source scaled to 1.66:1 then pillarboxed to Flat" +#~ msgstr "Fuente escalada a 1.66:1 con bandas hasta Flat" + +#~ msgid "Source scaled to 1.78:1" +#~ msgstr "Fuente escalada a 1.78:1" + +#~ msgid "Source scaled to 1.78:1 then pillarboxed to Flat" +#~ msgstr "Fuente escalada a 1.78:1 con bandas hasta Flat" + +#~ msgid "Source scaled to Flat (1.85:1)" +#~ msgstr "Fuente escalada a Flat (1.85:1)" + +#~ msgid "Source scaled to Scope (2.39:1)" +#~ msgstr "Fuente escalada a Scope (2.39:1)" + +#~ msgid "Source scaled to fit Flat preserving its aspect ratio" +#~ msgstr "Fuente escalada a Flat conservando el ratio de aspecto" + +#~ msgid "Source scaled to fit Scope preserving its aspect ratio" +#~ msgstr "Fuente escalada a Scope conservando el ratio de aspecto" + +#~ msgid "adding to queue of %1" +#~ msgstr "añadiendo a la cola de %1" diff --git a/src/lib/po/fr_FR.po b/src/lib/po/fr_FR.po index 7bd003c08..138d073c2 100644 --- a/src/lib/po/fr_FR.po +++ b/src/lib/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-01 21:21+0100\n" +"POT-Creation-Date: 2013-04-07 18:17+0100\n" "PO-Revision-Date: 2013-03-20 00:39+0100\n" "Last-Translator: FreeDCP.net \n" "Language-Team: \n" @@ -24,27 +24,27 @@ msgstr "0%" msgid "1.19" msgstr "1.19" -#: src/lib/format.cc:80 +#: src/lib/format.cc:79 msgid "1.33" msgstr "1.33" -#: src/lib/format.cc:85 +#: src/lib/format.cc:83 msgid "1.375" msgstr "1.375" -#: src/lib/format.cc:100 +#: src/lib/format.cc:95 msgid "1.66" msgstr "1.66" -#: src/lib/format.cc:105 +#: src/lib/format.cc:99 msgid "1.66 within Flat" msgstr "1.66 dans Flat" -#: src/lib/format.cc:115 +#: src/lib/format.cc:107 msgid "16:9" msgstr "16:9" -#: src/lib/format.cc:110 +#: src/lib/format.cc:103 msgid "16:9 within Flat" msgstr "16:9 dans Flat" @@ -52,7 +52,7 @@ msgstr "16:9 dans Flat" msgid "3D denoiser" msgstr "Débruitage 3D" -#: src/lib/format.cc:90 +#: src/lib/format.cc:87 msgid "4:3 within Flat" msgstr "4:3 dans Flat" @@ -60,7 +60,7 @@ msgstr "4:3 dans Flat" msgid "A/B transcode %1" msgstr "Transcodage A/B %1" -#: src/lib/format.cc:95 +#: src/lib/format.cc:91 msgid "Academy" msgstr "Academy" @@ -100,7 +100,7 @@ msgstr "" msgid "Cannot resample audio as libswresample is not present" msgstr "Ré-échantillonnage du son impossible : libswresample est absent" -#: src/lib/util.cc:931 +#: src/lib/util.cc:932 msgid "Centre" msgstr "" @@ -132,15 +132,16 @@ msgstr "Écriture vers fichier distant (%1) impossible" msgid "Cubic interpolating deinterlacer" msgstr "Désentrelacement cubique interpolé" -#: src/lib/util.cc:1006 +#: src/lib/util.cc:1007 msgid "DCP and source have the same rate.\n" msgstr "Le DCP et la source ont les mêmes cadences.\n" -#: src/lib/util.cc:1016 -msgid "DCP will run at %1%% of the source speed." +#: src/lib/util.cc:1017 +#, fuzzy +msgid "DCP will run at %1%% of the source speed.\n" msgstr "La cadence du DCP sera %1%% par rapport à la source" -#: src/lib/util.cc:1009 +#: src/lib/util.cc:1010 msgid "DCP will use every other frame of the source.\n" msgstr "Le DCP utilisera une image sur deux de la source.\n" @@ -163,7 +164,7 @@ msgstr "Filtre anti bourdonnement" msgid "Dolby CP750" msgstr "Dolby CP750" -#: src/lib/util.cc:1011 +#: src/lib/util.cc:1012 msgid "Each source frame will be doubled in the DCP.\n" msgstr "Chaque image source sera dupliquée dans le DCP.\n" @@ -207,11 +208,11 @@ msgstr "Bilinéaire rapide" msgid "Feature" msgstr "Feature" -#: src/lib/format.cc:120 +#: src/lib/format.cc:111 msgid "Flat" msgstr "Flat" -#: src/lib/format.cc:130 +#: src/lib/format.cc:119 msgid "Flat without stretch" msgstr "Flat sans déformation" @@ -255,15 +256,15 @@ msgstr "Désentrelaceur noyau" msgid "Lanczos" msgstr "Lanczos" -#: src/lib/util.cc:929 +#: src/lib/util.cc:930 msgid "Left" msgstr "Gauche" -#: src/lib/util.cc:933 +#: src/lib/util.cc:934 msgid "Left surround" msgstr "Arrière gauche" -#: src/lib/util.cc:932 +#: src/lib/util.cc:933 msgid "Lfe (sub)" msgstr "Basses fréquences" @@ -313,15 +314,15 @@ msgstr "Public Service Announcement" msgid "Rating" msgstr "Classification" -#: src/lib/util.cc:499 +#: src/lib/util.cc:500 msgid "Rec 709" msgstr "Rec 709" -#: src/lib/util.cc:930 +#: src/lib/util.cc:931 msgid "Right" msgstr "Droite" -#: src/lib/util.cc:934 +#: src/lib/util.cc:935 msgid "Right surround" msgstr "Arrière droite" @@ -329,11 +330,11 @@ msgstr "Arrière droite" msgid "SSH error (%1)" msgstr "Erreur SSH (%1)" -#: src/lib/format.cc:125 +#: src/lib/format.cc:115 msgid "Scope" msgstr "Scope" -#: src/lib/format.cc:135 +#: src/lib/format.cc:123 msgid "Scope without stretch" msgstr "Scope sans déformation" @@ -345,58 +346,6 @@ msgstr "Short" msgid "Sinc" msgstr "Sinc" -#: src/lib/format.cc:76 -msgid "Source scaled to 1.19:1" -msgstr "Source mise à l'échelle en 1.19:1" - -#: src/lib/format.cc:81 -msgid "Source scaled to 1.33:1" -msgstr "Source mise à l'échelle en 1.33:1" - -#: src/lib/format.cc:91 -msgid "Source scaled to 1.33:1 then pillarboxed to Flat" -msgstr "Source mise à l'échelle en 1.33:1 puis contenue dans Flat" - -#: src/lib/format.cc:86 -msgid "Source scaled to 1.375:1" -msgstr "Source mise à l'échelle en 1.375:1" - -#: src/lib/format.cc:96 -msgid "Source scaled to 1.37:1 (Academy ratio)" -msgstr "Source mise à l'échelle en 1.37:1 (ratio \"academy\")" - -#: src/lib/format.cc:101 -msgid "Source scaled to 1.66:1" -msgstr "Source mise à l'échelle en 1.66:1" - -#: src/lib/format.cc:106 -msgid "Source scaled to 1.66:1 then pillarboxed to Flat" -msgstr "Source mise à l'échelle en 1.66:1 puis contenue dans Flat" - -#: src/lib/format.cc:116 -msgid "Source scaled to 1.78:1" -msgstr "Source mise à l'échelle en 1.78:1" - -#: src/lib/format.cc:111 -msgid "Source scaled to 1.78:1 then pillarboxed to Flat" -msgstr "Source mise à l'échelle en 1.78:1 puis contenue dans Flat" - -#: src/lib/format.cc:121 -msgid "Source scaled to Flat (1.85:1)" -msgstr "Source mise à l'échelle en Flat (1.85:1)" - -#: src/lib/format.cc:126 -msgid "Source scaled to Scope (2.39:1)" -msgstr "Source mise à l'échelle en Scope (2.39:1)" - -#: src/lib/format.cc:131 -msgid "Source scaled to fit Flat preserving its aspect ratio" -msgstr "Source réduite en Flat afin de préserver ses dimensions" - -#: src/lib/format.cc:136 -msgid "Source scaled to fit Scope preserving its aspect ratio" -msgstr "Source réduite en Scope afin de préserver ses dimensions" - #: src/lib/scaler.cc:68 msgid "Spline" msgstr "Spline" @@ -473,7 +422,7 @@ msgstr "Un autre filtre de désentrelacement" msgid "cannot contain slashes" msgstr "slash interdit" -#: src/lib/util.cc:540 +#: src/lib/util.cc:541 msgid "connect timed out" msgstr "temps de connexion expiré" @@ -577,7 +526,7 @@ msgstr "minute" msgid "minutes" msgstr "minutes" -#: src/lib/util.cc:683 +#: src/lib/util.cc:684 msgid "missing key %1 in key-value set" msgstr "clé %1 non sélectionnée" @@ -607,7 +556,7 @@ msgstr "sous-titres non-bitmap non supportés actuellement" msgid "remaining" msgstr "restant" -#: src/lib/util.cc:497 +#: src/lib/util.cc:498 msgid "sRGB" msgstr "sRGB" @@ -623,6 +572,45 @@ msgstr "fixe" msgid "video" msgstr "vidéo" +#~ msgid "Source scaled to 1.19:1" +#~ msgstr "Source mise à l'échelle en 1.19:1" + +#~ msgid "Source scaled to 1.33:1" +#~ msgstr "Source mise à l'échelle en 1.33:1" + +#~ msgid "Source scaled to 1.33:1 then pillarboxed to Flat" +#~ msgstr "Source mise à l'échelle en 1.33:1 puis contenue dans Flat" + +#~ msgid "Source scaled to 1.375:1" +#~ msgstr "Source mise à l'échelle en 1.375:1" + +#~ msgid "Source scaled to 1.37:1 (Academy ratio)" +#~ msgstr "Source mise à l'échelle en 1.37:1 (ratio \"academy\")" + +#~ msgid "Source scaled to 1.66:1" +#~ msgstr "Source mise à l'échelle en 1.66:1" + +#~ msgid "Source scaled to 1.66:1 then pillarboxed to Flat" +#~ msgstr "Source mise à l'échelle en 1.66:1 puis contenue dans Flat" + +#~ msgid "Source scaled to 1.78:1" +#~ msgstr "Source mise à l'échelle en 1.78:1" + +#~ msgid "Source scaled to 1.78:1 then pillarboxed to Flat" +#~ msgstr "Source mise à l'échelle en 1.78:1 puis contenue dans Flat" + +#~ msgid "Source scaled to Flat (1.85:1)" +#~ msgstr "Source mise à l'échelle en Flat (1.85:1)" + +#~ msgid "Source scaled to Scope (2.39:1)" +#~ msgstr "Source mise à l'échelle en Scope (2.39:1)" + +#~ msgid "Source scaled to fit Flat preserving its aspect ratio" +#~ msgstr "Source réduite en Flat afin de préserver ses dimensions" + +#~ msgid "Source scaled to fit Scope preserving its aspect ratio" +#~ msgstr "Source réduite en Scope afin de préserver ses dimensions" + #~ msgid "adding to queue of %1" #~ msgstr "Mise en file d'attente de %1" diff --git a/src/lib/po/it_IT.po b/src/lib/po/it_IT.po index b4278d93c..c184a3932 100644 --- a/src/lib/po/it_IT.po +++ b/src/lib/po/it_IT.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-01 21:21+0100\n" +"POT-Creation-Date: 2013-04-07 18:17+0100\n" "PO-Revision-Date: 2013-03-20 11:45+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" @@ -25,27 +25,27 @@ msgstr "0%" msgid "1.19" msgstr "1.19" -#: src/lib/format.cc:80 +#: src/lib/format.cc:79 msgid "1.33" msgstr "1.33" -#: src/lib/format.cc:85 +#: src/lib/format.cc:83 msgid "1.375" msgstr "1.375" -#: src/lib/format.cc:100 +#: src/lib/format.cc:95 msgid "1.66" msgstr "1.66" -#: src/lib/format.cc:105 +#: src/lib/format.cc:99 msgid "1.66 within Flat" msgstr "1.66 all'interno di Flat" -#: src/lib/format.cc:115 +#: src/lib/format.cc:107 msgid "16:9" msgstr "16:9" -#: src/lib/format.cc:110 +#: src/lib/format.cc:103 msgid "16:9 within Flat" msgstr "16:9 all'interno di Flat" @@ -53,7 +53,7 @@ msgstr "16:9 all'interno di Flat" msgid "3D denoiser" msgstr "Riduttore di rumore 3D" -#: src/lib/format.cc:90 +#: src/lib/format.cc:87 msgid "4:3 within Flat" msgstr "4:3 all'interno di Flat" @@ -61,7 +61,7 @@ msgstr "4:3 all'interno di Flat" msgid "A/B transcode %1" msgstr "Transcodifica A/B %1" -#: src/lib/format.cc:95 +#: src/lib/format.cc:91 msgid "Academy" msgstr "Academy" @@ -101,7 +101,7 @@ msgstr "" msgid "Cannot resample audio as libswresample is not present" msgstr "Non posso ricampionare l'audio perchè libswresample non è presente" -#: src/lib/util.cc:931 +#: src/lib/util.cc:932 msgid "Centre" msgstr "" @@ -133,15 +133,16 @@ msgstr "Non posso scrivere il file remoto (%1)" msgid "Cubic interpolating deinterlacer" msgstr "Deinterlacciatore cubico interpolato" -#: src/lib/util.cc:1006 +#: src/lib/util.cc:1007 msgid "DCP and source have the same rate.\n" msgstr "Il DCP e il sorgente hanno la stessa frequenza.\n" -#: src/lib/util.cc:1016 -msgid "DCP will run at %1%% of the source speed." +#: src/lib/util.cc:1017 +#, fuzzy +msgid "DCP will run at %1%% of the source speed.\n" msgstr "Il DCP andrà al %1%% della velocità del sorgente." -#: src/lib/util.cc:1009 +#: src/lib/util.cc:1010 msgid "DCP will use every other frame of the source.\n" msgstr "Il DCP userà ogni altro fotogramma del sorgente.\n" @@ -164,7 +165,7 @@ msgstr "Filtro deringing" msgid "Dolby CP750" msgstr "Dolby CP750" -#: src/lib/util.cc:1011 +#: src/lib/util.cc:1012 msgid "Each source frame will be doubled in the DCP.\n" msgstr "Ogni fotogramma del sorgente sarà raddoppiato nel DCP.\n" @@ -208,11 +209,11 @@ msgstr "Bilineare rapida" msgid "Feature" msgstr "Caratteristica" -#: src/lib/format.cc:120 +#: src/lib/format.cc:111 msgid "Flat" msgstr "Flat" -#: src/lib/format.cc:130 +#: src/lib/format.cc:119 msgid "Flat without stretch" msgstr "Flat senza stiramento" @@ -256,15 +257,15 @@ msgstr "Deinterlacciatore Kernel" msgid "Lanczos" msgstr "Lanczos" -#: src/lib/util.cc:929 +#: src/lib/util.cc:930 msgid "Left" msgstr "" -#: src/lib/util.cc:933 +#: src/lib/util.cc:934 msgid "Left surround" msgstr "" -#: src/lib/util.cc:932 +#: src/lib/util.cc:933 msgid "Lfe (sub)" msgstr "" @@ -314,15 +315,15 @@ msgstr "Annuncio di pubblico servizio" msgid "Rating" msgstr "Punteggio" -#: src/lib/util.cc:499 +#: src/lib/util.cc:500 msgid "Rec 709" msgstr "Rec 709" -#: src/lib/util.cc:930 +#: src/lib/util.cc:931 msgid "Right" msgstr "" -#: src/lib/util.cc:934 +#: src/lib/util.cc:935 msgid "Right surround" msgstr "" @@ -330,11 +331,11 @@ msgstr "" msgid "SSH error (%1)" msgstr "Errore SSH (%1)" -#: src/lib/format.cc:125 +#: src/lib/format.cc:115 msgid "Scope" msgstr "Scope" -#: src/lib/format.cc:135 +#: src/lib/format.cc:123 msgid "Scope without stretch" msgstr "Scope senza stiramento" @@ -346,58 +347,6 @@ msgstr "Corto" msgid "Sinc" msgstr "Sinc" -#: src/lib/format.cc:76 -msgid "Source scaled to 1.19:1" -msgstr "Sorgente scalato a 1.19:1" - -#: src/lib/format.cc:81 -msgid "Source scaled to 1.33:1" -msgstr "Sorgente scalato a 1.33:1" - -#: src/lib/format.cc:91 -msgid "Source scaled to 1.33:1 then pillarboxed to Flat" -msgstr "Sorgente scalato a 1.33:1 e poi inviato come Flat" - -#: src/lib/format.cc:86 -msgid "Source scaled to 1.375:1" -msgstr "Sorgente scalato a 1.375:1" - -#: src/lib/format.cc:96 -msgid "Source scaled to 1.37:1 (Academy ratio)" -msgstr "Sorgente scalato a 1.37:1 (Academy ratio)" - -#: src/lib/format.cc:101 -msgid "Source scaled to 1.66:1" -msgstr "Sorgente scalato a 1.66:1" - -#: src/lib/format.cc:106 -msgid "Source scaled to 1.66:1 then pillarboxed to Flat" -msgstr "Sorgente scalato a 1.66:1 e poi inviato come Flat" - -#: src/lib/format.cc:116 -msgid "Source scaled to 1.78:1" -msgstr "Sorgente scalato a 1.78:1" - -#: src/lib/format.cc:111 -msgid "Source scaled to 1.78:1 then pillarboxed to Flat" -msgstr "Sorgente scalato a 1.78:1 e poi inviato come Flat" - -#: src/lib/format.cc:121 -msgid "Source scaled to Flat (1.85:1)" -msgstr "Sorgente scalato a Flat (1.85:1)" - -#: src/lib/format.cc:126 -msgid "Source scaled to Scope (2.39:1)" -msgstr "Sorgente scalato a Scope (2.39:1)" - -#: src/lib/format.cc:131 -msgid "Source scaled to fit Flat preserving its aspect ratio" -msgstr "Sorgente scalato per adattarsi a Flat mantentendo le sue proporzioni" - -#: src/lib/format.cc:136 -msgid "Source scaled to fit Scope preserving its aspect ratio" -msgstr "Sorgente scalato per adattarsi a Scope mantentendo le sue proporzioni" - #: src/lib/scaler.cc:68 msgid "Spline" msgstr "Spline" @@ -474,7 +423,7 @@ msgstr "Ancora un altro filtro di deinterlacciamento" msgid "cannot contain slashes" msgstr "non può contenere barre" -#: src/lib/util.cc:540 +#: src/lib/util.cc:541 msgid "connect timed out" msgstr "connessione scaduta" @@ -582,7 +531,7 @@ msgstr "minuto" msgid "minutes" msgstr "minuti" -#: src/lib/util.cc:683 +#: src/lib/util.cc:684 msgid "missing key %1 in key-value set" msgstr "persa la chiave %1 tra i valori chiave" @@ -612,7 +561,7 @@ msgstr "sottotitoli non-bitmap non ancora supportati" msgid "remaining" msgstr "restano" -#: src/lib/util.cc:497 +#: src/lib/util.cc:498 msgid "sRGB" msgstr "sRGB" @@ -628,6 +577,47 @@ msgstr "ancora" msgid "video" msgstr "video" +#~ msgid "Source scaled to 1.19:1" +#~ msgstr "Sorgente scalato a 1.19:1" + +#~ msgid "Source scaled to 1.33:1" +#~ msgstr "Sorgente scalato a 1.33:1" + +#~ msgid "Source scaled to 1.33:1 then pillarboxed to Flat" +#~ msgstr "Sorgente scalato a 1.33:1 e poi inviato come Flat" + +#~ msgid "Source scaled to 1.375:1" +#~ msgstr "Sorgente scalato a 1.375:1" + +#~ msgid "Source scaled to 1.37:1 (Academy ratio)" +#~ msgstr "Sorgente scalato a 1.37:1 (Academy ratio)" + +#~ msgid "Source scaled to 1.66:1" +#~ msgstr "Sorgente scalato a 1.66:1" + +#~ msgid "Source scaled to 1.66:1 then pillarboxed to Flat" +#~ msgstr "Sorgente scalato a 1.66:1 e poi inviato come Flat" + +#~ msgid "Source scaled to 1.78:1" +#~ msgstr "Sorgente scalato a 1.78:1" + +#~ msgid "Source scaled to 1.78:1 then pillarboxed to Flat" +#~ msgstr "Sorgente scalato a 1.78:1 e poi inviato come Flat" + +#~ msgid "Source scaled to Flat (1.85:1)" +#~ msgstr "Sorgente scalato a Flat (1.85:1)" + +#~ msgid "Source scaled to Scope (2.39:1)" +#~ msgstr "Sorgente scalato a Scope (2.39:1)" + +#~ msgid "Source scaled to fit Flat preserving its aspect ratio" +#~ msgstr "" +#~ "Sorgente scalato per adattarsi a Flat mantentendo le sue proporzioni" + +#~ msgid "Source scaled to fit Scope preserving its aspect ratio" +#~ msgstr "" +#~ "Sorgente scalato per adattarsi a Scope mantentendo le sue proporzioni" + #~ msgid "adding to queue of %1" #~ msgstr "aggiungo alla coda %1" diff --git a/src/lib/po/sv_SE.po b/src/lib/po/sv_SE.po index 9af19206f..9f74e1e2a 100644 --- a/src/lib/po/sv_SE.po +++ b/src/lib/po/sv_SE.po @@ -7,10 +7,11 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-01 21:21+0100\n" +"POT-Creation-Date: 2013-04-07 18:17+0100\n" "PO-Revision-Date: 2013-04-04 10:22+0100\n" "Last-Translator: Adam Klotblixt \n" "Language-Team: \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -24,27 +25,27 @@ msgstr "0%" msgid "1.19" msgstr "1,19" -#: src/lib/format.cc:80 +#: src/lib/format.cc:79 msgid "1.33" msgstr "1,33" -#: src/lib/format.cc:85 +#: src/lib/format.cc:83 msgid "1.375" msgstr "1,375" -#: src/lib/format.cc:100 +#: src/lib/format.cc:95 msgid "1.66" msgstr "1,66" -#: src/lib/format.cc:105 +#: src/lib/format.cc:99 msgid "1.66 within Flat" msgstr "1,66 innanför Flat" -#: src/lib/format.cc:115 +#: src/lib/format.cc:107 msgid "16:9" msgstr "16:9" -#: src/lib/format.cc:110 +#: src/lib/format.cc:103 msgid "16:9 within Flat" msgstr "16:9 innanför Flat" @@ -52,7 +53,7 @@ msgstr "16:9 innanför Flat" msgid "3D denoiser" msgstr "3D brusreducering" -#: src/lib/format.cc:90 +#: src/lib/format.cc:87 msgid "4:3 within Flat" msgstr "4:3 innanför Flat" @@ -60,7 +61,7 @@ msgstr "4:3 innanför Flat" msgid "A/B transcode %1" msgstr "A/B konvertera %1" -#: src/lib/format.cc:95 +#: src/lib/format.cc:91 msgid "Academy" msgstr "Academy" @@ -101,7 +102,7 @@ msgid "Cannot resample audio as libswresample is not present" msgstr "" "Kan inte omsampla ljudet eftersom libswresample inte finns tillgängligt" -#: src/lib/util.cc:931 +#: src/lib/util.cc:932 msgid "Centre" msgstr "Mitt" @@ -133,15 +134,16 @@ msgstr "Kunde inte skriva till fjärrfil (%1)" msgid "Cubic interpolating deinterlacer" msgstr "Kubiskt interpolerande avflätare" -#: src/lib/util.cc:1006 +#: src/lib/util.cc:1007 msgid "DCP and source have the same rate.\n" msgstr "DCP och källa har samma bildfrekvens.\n" -#: src/lib/util.cc:1016 -msgid "DCP will run at %1%% of the source speed." +#: src/lib/util.cc:1017 +#, fuzzy +msgid "DCP will run at %1%% of the source speed.\n" msgstr "DCP kommer att köras på %1%% av källans hastighet." -#: src/lib/util.cc:1009 +#: src/lib/util.cc:1010 msgid "DCP will use every other frame of the source.\n" msgstr "DCP kommer att använda varannan bild från källan.\n" @@ -164,7 +166,7 @@ msgstr "Avringningsfilter" msgid "Dolby CP750" msgstr "Dolby CP750" -#: src/lib/util.cc:1011 +#: src/lib/util.cc:1012 msgid "Each source frame will be doubled in the DCP.\n" msgstr "Varje bild från källan kommer att användas två gånger i DCPn.\n" @@ -208,11 +210,11 @@ msgstr "Snabb bilinjär" msgid "Feature" msgstr "Långfilm" -#: src/lib/format.cc:120 +#: src/lib/format.cc:111 msgid "Flat" msgstr "Flat" -#: src/lib/format.cc:130 +#: src/lib/format.cc:119 msgid "Flat without stretch" msgstr "Flat utan utsträckning" @@ -256,15 +258,15 @@ msgstr "Kernel-avflätare" msgid "Lanczos" msgstr "Lanczos" -#: src/lib/util.cc:929 +#: src/lib/util.cc:930 msgid "Left" msgstr "Vänster" -#: src/lib/util.cc:933 +#: src/lib/util.cc:934 msgid "Left surround" msgstr "Vänster surround" -#: src/lib/util.cc:932 +#: src/lib/util.cc:933 msgid "Lfe (sub)" msgstr "Lfe (sub)" @@ -314,15 +316,15 @@ msgstr "Offentligt Servicemeddelande" msgid "Rating" msgstr "Klassificeringsklipp" -#: src/lib/util.cc:499 +#: src/lib/util.cc:500 msgid "Rec 709" msgstr "Rec 709" -#: src/lib/util.cc:930 +#: src/lib/util.cc:931 msgid "Right" msgstr "Höger" -#: src/lib/util.cc:934 +#: src/lib/util.cc:935 msgid "Right surround" msgstr "Höger surround" @@ -330,11 +332,11 @@ msgstr "Höger surround" msgid "SSH error (%1)" msgstr "SSH fel (%1)" -#: src/lib/format.cc:125 +#: src/lib/format.cc:115 msgid "Scope" msgstr "Scope" -#: src/lib/format.cc:135 +#: src/lib/format.cc:123 msgid "Scope without stretch" msgstr "Scope utan utsträckning" @@ -346,59 +348,6 @@ msgstr "Kortfilm" msgid "Sinc" msgstr "Sinc" -#: src/lib/format.cc:76 -msgid "Source scaled to 1.19:1" -msgstr "Källan skalad till 1,19:1" - -#: src/lib/format.cc:81 -msgid "Source scaled to 1.33:1" -msgstr "Källan skalad till 1,33:1" - -#: src/lib/format.cc:91 -msgid "Source scaled to 1.33:1 then pillarboxed to Flat" -msgstr "Källan skalad till 1,33:1, med sorgkanter innanför Flat" - -#: src/lib/format.cc:86 -msgid "Source scaled to 1.375:1" -msgstr "Källan skalad till 1,375:1" - -#: src/lib/format.cc:96 -msgid "Source scaled to 1.37:1 (Academy ratio)" -msgstr "Källan skalad till 1,37:1 (Academy-förhållande)" - -#: src/lib/format.cc:101 -msgid "Source scaled to 1.66:1" -msgstr "Källan skalad till 1,66:1" - -#: src/lib/format.cc:106 -msgid "Source scaled to 1.66:1 then pillarboxed to Flat" -msgstr "Källan skalad till 1,66:1, med sorgkanter innanför Flat" - -#: src/lib/format.cc:116 -msgid "Source scaled to 1.78:1" -msgstr "Källan skalad till 1,78:1" - -#: src/lib/format.cc:111 -msgid "Source scaled to 1.78:1 then pillarboxed to Flat" -msgstr "Källan skalad till 1,78:1, med sorgkanter innanför Flat" - -#: src/lib/format.cc:121 -msgid "Source scaled to Flat (1.85:1)" -msgstr "Källan skalad till Flat (1,85:1)" - -#: src/lib/format.cc:126 -msgid "Source scaled to Scope (2.39:1)" -msgstr "Källan skalad till Scope (2,39:1)" - -#: src/lib/format.cc:131 -msgid "Source scaled to fit Flat preserving its aspect ratio" -msgstr "Källan skalad för att rymmas inom Flat utan att ändra bildförhållandet" - -#: src/lib/format.cc:136 -msgid "Source scaled to fit Scope preserving its aspect ratio" -msgstr "" -"Källan skalad för att rymmas inom Scope utan att ändra bildförhållandet" - #: src/lib/scaler.cc:68 msgid "Spline" msgstr "Spline" @@ -479,7 +428,7 @@ msgid "cannot contain slashes" msgstr "får inte innehålla snedstreck" # Svengelska -#: src/lib/util.cc:540 +#: src/lib/util.cc:541 #, fuzzy msgid "connect timed out" msgstr "uppkopplingen tajmade ur" @@ -584,7 +533,7 @@ msgstr "minut" msgid "minutes" msgstr "minuter" -#: src/lib/util.cc:683 +#: src/lib/util.cc:684 msgid "missing key %1 in key-value set" msgstr "saknad nyckel %1 i nyckel-värde grupp" @@ -614,7 +563,7 @@ msgstr "icke-rastergrafiska undertexter stöds inte ännu" msgid "remaining" msgstr "återstående tid" -#: src/lib/util.cc:497 +#: src/lib/util.cc:498 msgid "sRGB" msgstr "sRGB" @@ -629,3 +578,44 @@ msgstr "stillbild" #: src/lib/film.cc:274 msgid "video" msgstr "video" + +#~ msgid "Source scaled to 1.19:1" +#~ msgstr "Källan skalad till 1,19:1" + +#~ msgid "Source scaled to 1.33:1" +#~ msgstr "Källan skalad till 1,33:1" + +#~ msgid "Source scaled to 1.33:1 then pillarboxed to Flat" +#~ msgstr "Källan skalad till 1,33:1, med sorgkanter innanför Flat" + +#~ msgid "Source scaled to 1.375:1" +#~ msgstr "Källan skalad till 1,375:1" + +#~ msgid "Source scaled to 1.37:1 (Academy ratio)" +#~ msgstr "Källan skalad till 1,37:1 (Academy-förhållande)" + +#~ msgid "Source scaled to 1.66:1" +#~ msgstr "Källan skalad till 1,66:1" + +#~ msgid "Source scaled to 1.66:1 then pillarboxed to Flat" +#~ msgstr "Källan skalad till 1,66:1, med sorgkanter innanför Flat" + +#~ msgid "Source scaled to 1.78:1" +#~ msgstr "Källan skalad till 1,78:1" + +#~ msgid "Source scaled to 1.78:1 then pillarboxed to Flat" +#~ msgstr "Källan skalad till 1,78:1, med sorgkanter innanför Flat" + +#~ msgid "Source scaled to Flat (1.85:1)" +#~ msgstr "Källan skalad till Flat (1,85:1)" + +#~ msgid "Source scaled to Scope (2.39:1)" +#~ msgstr "Källan skalad till Scope (2,39:1)" + +#~ msgid "Source scaled to fit Flat preserving its aspect ratio" +#~ msgstr "" +#~ "Källan skalad för att rymmas inom Flat utan att ändra bildförhållandet" + +#~ msgid "Source scaled to fit Scope preserving its aspect ratio" +#~ msgstr "" +#~ "Källan skalad för att rymmas inom Scope utan att ändra bildförhållandet" diff --git a/src/tools/po/es_ES.po b/src/tools/po/es_ES.po index 777a86519..4a3710eb8 100644 --- a/src/tools/po/es_ES.po +++ b/src/tools/po/es_ES.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVDOMATIC\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-01 21:21+0100\n" +"POT-Creation-Date: 2013-04-07 18:17+0100\n" "PO-Revision-Date: 2013-03-23 21:08-0500\n" "Last-Translator: Manuel AC \n" "Language-Team: Manuel AC \n" @@ -65,7 +65,7 @@ msgstr "&Guardar" msgid "&Send DCP to TMS" msgstr "&Enviar DCP al TMS" -#: src/tools/dvdomatic.cc:409 +#: src/tools/dvdomatic.cc:417 msgid "" "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" msgstr "" @@ -75,18 +75,18 @@ msgstr "" msgid "About" msgstr "Acerca de" -#: src/tools/dvdomatic.cc:517 +#: src/tools/dvdomatic.cc:527 #, fuzzy msgid "Could not load film %1 (%2)" msgstr "No se pudo cargar la película %s (%s)" -#: src/tools/dvdomatic.cc:331 +#: src/tools/dvdomatic.cc:339 #, c-format msgid "Could not open film at %s (%s)" msgstr "No se pudo cargar la película en %s (%s)" -#: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:402 -#: src/tools/dvdomatic.cc:521 +#: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:410 +#: src/tools/dvdomatic.cc:531 msgid "DVD-o-matic" msgstr "DVD-o-matic" @@ -94,7 +94,7 @@ msgstr "DVD-o-matic" msgid "Film changed" msgstr "Película cambiada" -#: src/tools/dvdomatic.cc:408 +#: src/tools/dvdomatic.cc:416 msgid "Free, open-source DCP generation from almost anything." msgstr "" "Generación de DCP a partir de casi cualquier fuente, libre y de código " @@ -120,3 +120,9 @@ msgstr "Selecciona la película a abrir" #, fuzzy msgid "The directory %1 already exists." msgstr "La carpeta %s ya existe." + +#: src/tools/dvdomatic.cc:324 +msgid "" +"You did not select a folder. Make sure that you select a folder before " +"clicking Open." +msgstr "" diff --git a/src/tools/po/fr_FR.po b/src/tools/po/fr_FR.po index fc9c670fc..3c4cc79c5 100644 --- a/src/tools/po/fr_FR.po +++ b/src/tools/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-01 21:21+0100\n" +"POT-Creation-Date: 2013-04-07 18:17+0100\n" "PO-Revision-Date: 2013-03-13 22:33+0100\n" "Last-Translator: \n" "Language-Team: \n" @@ -64,7 +64,7 @@ msgstr "&Enregistrer" msgid "&Send DCP to TMS" msgstr "&Envoyer le DCP dans le TMS" -#: src/tools/dvdomatic.cc:409 +#: src/tools/dvdomatic.cc:417 msgid "" "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" msgstr "" @@ -74,18 +74,18 @@ msgstr "" msgid "About" msgstr "A Propos" -#: src/tools/dvdomatic.cc:517 +#: src/tools/dvdomatic.cc:527 #, fuzzy msgid "Could not load film %1 (%2)" msgstr "Impossible de charger le film %s (%s)" -#: src/tools/dvdomatic.cc:331 +#: src/tools/dvdomatic.cc:339 #, c-format msgid "Could not open film at %s (%s)" msgstr "Impossible d'ouvrir le film à %s (%s)" -#: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:402 -#: src/tools/dvdomatic.cc:521 +#: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:410 +#: src/tools/dvdomatic.cc:531 msgid "DVD-o-matic" msgstr "DVD-o-matic" @@ -93,7 +93,7 @@ msgstr "DVD-o-matic" msgid "Film changed" msgstr "Film changé" -#: src/tools/dvdomatic.cc:408 +#: src/tools/dvdomatic.cc:416 msgid "Free, open-source DCP generation from almost anything." msgstr "Création de DCP libre et open-source à partir de presque tout." @@ -117,3 +117,9 @@ msgstr "Sélectionner le film à ouvrir" #, fuzzy msgid "The directory %1 already exists." msgstr "Le dossier %s existe déjà." + +#: src/tools/dvdomatic.cc:324 +msgid "" +"You did not select a folder. Make sure that you select a folder before " +"clicking Open." +msgstr "" diff --git a/src/tools/po/it_IT.po b/src/tools/po/it_IT.po index 0f9de5e36..850fd9b1f 100644 --- a/src/tools/po/it_IT.po +++ b/src/tools/po/it_IT.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-01 21:21+0100\n" +"POT-Creation-Date: 2013-04-07 18:17+0100\n" "PO-Revision-Date: 2013-03-22 18:03+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" @@ -65,7 +65,7 @@ msgstr "&Salva" msgid "&Send DCP to TMS" msgstr "&Invia DCP a TMS" -#: src/tools/dvdomatic.cc:409 +#: src/tools/dvdomatic.cc:417 msgid "" "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" msgstr "" @@ -75,18 +75,18 @@ msgstr "" msgid "About" msgstr "Informazioni" -#: src/tools/dvdomatic.cc:517 +#: src/tools/dvdomatic.cc:527 #, fuzzy msgid "Could not load film %1 (%2)" msgstr "Non posso caricare il film %s (%s)" -#: src/tools/dvdomatic.cc:331 +#: src/tools/dvdomatic.cc:339 #, c-format msgid "Could not open film at %s (%s)" msgstr "Non posso aprire il film in %s (%s)" -#: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:402 -#: src/tools/dvdomatic.cc:521 +#: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:410 +#: src/tools/dvdomatic.cc:531 msgid "DVD-o-matic" msgstr "DVD-o-matic" @@ -94,7 +94,7 @@ msgstr "DVD-o-matic" msgid "Film changed" msgstr "Film modificato" -#: src/tools/dvdomatic.cc:408 +#: src/tools/dvdomatic.cc:416 msgid "Free, open-source DCP generation from almost anything." msgstr "Genera DCP da quasi tutto, free e open-source." @@ -118,3 +118,9 @@ msgstr "Seleziona il film da aprire" #, fuzzy msgid "The directory %1 already exists." msgstr "La directory %s esiste gia'." + +#: src/tools/dvdomatic.cc:324 +msgid "" +"You did not select a folder. Make sure that you select a folder before " +"clicking Open." +msgstr "" diff --git a/src/tools/po/sv_SE.po b/src/tools/po/sv_SE.po index c007785f3..dd45c3baa 100644 --- a/src/tools/po/sv_SE.po +++ b/src/tools/po/sv_SE.po @@ -7,10 +7,11 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-01 21:21+0100\n" +"POT-Creation-Date: 2013-04-07 18:17+0100\n" "PO-Revision-Date: 2013-04-04 10:11+0100\n" "Last-Translator: Adam Klotblixt \n" "Language-Team: \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -64,7 +65,7 @@ msgstr "&Spara" msgid "&Send DCP to TMS" msgstr "&Skicka DCP till TMS" -#: src/tools/dvdomatic.cc:409 +#: src/tools/dvdomatic.cc:417 msgid "" "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" msgstr "" @@ -74,17 +75,17 @@ msgstr "" msgid "About" msgstr "Om" -#: src/tools/dvdomatic.cc:517 +#: src/tools/dvdomatic.cc:527 msgid "Could not load film %1 (%2)" msgstr "Kunde inte öppna filmen %1 (%2)" -#: src/tools/dvdomatic.cc:331 +#: src/tools/dvdomatic.cc:339 #, c-format msgid "Could not open film at %s (%s)" msgstr "Kunde inte öppna filmen vid %s (%s)" -#: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:402 -#: src/tools/dvdomatic.cc:521 +#: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:410 +#: src/tools/dvdomatic.cc:531 msgid "DVD-o-matic" msgstr "DVD-o-matic" @@ -92,7 +93,7 @@ msgstr "DVD-o-matic" msgid "Film changed" msgstr "Film ändrad" -#: src/tools/dvdomatic.cc:408 +#: src/tools/dvdomatic.cc:416 msgid "Free, open-source DCP generation from almost anything." msgstr "" "Fri, öppen-källkodsprogramvara för DCP-generering från nästan vad som helst." @@ -116,3 +117,9 @@ msgstr "Välj film att öppna" #: src/tools/dvdomatic.cc:303 msgid "The directory %1 already exists." msgstr "Katalogen %1 finns redan." + +#: src/tools/dvdomatic.cc:324 +msgid "" +"You did not select a folder. Make sure that you select a folder before " +"clicking Open." +msgstr "" diff --git a/src/wx/po/es_ES.po b/src/wx/po/es_ES.po index de0f93024..9f96fceff 100644 --- a/src/wx/po/es_ES.po +++ b/src/wx/po/es_ES.po @@ -7,41 +7,45 @@ msgid "" msgstr "" "Project-Id-Version: libdvdomatic-wx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-03-15 08:39+0000\n" +"POT-Creation-Date: 2013-04-07 18:17+0100\n" "PO-Revision-Date: 2013-04-02 19:08-0500\n" "Last-Translator: Manuel AC \n" "Language-Team: Manuel AC \n" +"Language: es-ES\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" -"Language: es-ES\n" -#: src/wx/film_editor.cc:441 +#: src/wx/film_editor.cc:445 msgid "%" msgstr "%" -#: src/wx/film_editor.cc:1230 +#: src/wx/config_dialog.cc:61 +msgid "(restart DVD-o-matic to see language changes)" +msgstr "" + +#: src/wx/film_editor.cc:1269 msgid "1 channel" msgstr "1 canal" -#: src/wx/film_editor.cc:185 +#: src/wx/film_editor.cc:184 msgid "A/B" msgstr "A/B" -#: src/wx/config_dialog.cc:124 +#: src/wx/config_dialog.cc:143 msgid "Add" msgstr "Añadir" -#: src/wx/audio_dialog.cc:32 src/wx/film_editor.cc:78 +#: src/wx/audio_dialog.cc:32 src/wx/film_editor.cc:77 msgid "Audio" msgstr "Audio" -#: src/wx/film_editor.cc:382 +#: src/wx/film_editor.cc:381 msgid "Audio Delay" msgstr "Retardo del audio" -#: src/wx/film_editor.cc:370 +#: src/wx/film_editor.cc:369 msgid "Audio Gain" msgstr "Ganancia del audio" @@ -49,12 +53,17 @@ msgstr "Ganancia del audio" msgid "Audio Language (e.g. EN)" msgstr "Idioma del audio (ej. ES)" +#: src/wx/film_editor.cc:820 +#, c-format +msgid "Audio will be resampled from %dHz to %dHz\n" +msgstr "" + #: src/wx/job_wrapper.cc:38 #, c-format msgid "Bad setting for %s (%s)" msgstr "Configuración erronea para %s (%s)" -#: src/wx/film_editor.cc:297 +#: src/wx/film_editor.cc:288 msgid "Bottom crop" msgstr "Recortar abajo" @@ -66,27 +75,31 @@ msgstr "Explorar..." msgid "But I have to use fader" msgstr "pero tengo que usar el fader a" -#: src/wx/film_editor.cc:375 +#: src/wx/film_editor.cc:374 msgid "Calculate..." msgstr "Calcular..." +#: src/wx/job_manager_view.cc:88 +msgid "Cancel" +msgstr "" + #: src/wx/audio_dialog.cc:43 msgid "Channels" msgstr "Canales" -#: src/wx/film_editor.cc:326 +#: src/wx/film_editor.cc:325 msgid "Colour look-up table" msgstr "Tabla de referencia de colores" -#: src/wx/film_editor.cc:121 +#: src/wx/film_editor.cc:120 msgid "Content" msgstr "Contenido" -#: src/wx/film_editor.cc:131 +#: src/wx/film_editor.cc:130 msgid "Content Type" msgstr "Tipo de contenido" -#: src/wx/film_viewer.cc:414 +#: src/wx/film_viewer.cc:415 #, c-format msgid "Could not decode video for view (%s)" msgstr "No se pudo decodificar el vídeo para mostrarlo (%s)" @@ -96,12 +109,12 @@ msgstr "No se pudo decodificar el vídeo para mostrarlo (%s)" msgid "Could not make DCP: %s" msgstr "No se pudo crear el DCP: %s" -#: src/wx/film_viewer.cc:108 +#: src/wx/film_viewer.cc:107 #, c-format msgid "Could not open content file (%s)" msgstr "No se pudo abrir el fichero (%s)" -#: src/wx/film_editor.cc:505 +#: src/wx/film_editor.cc:509 #, c-format msgid "Could not set content: %s" msgstr "No se pudo establecer el contenido: %s" @@ -110,15 +123,20 @@ msgstr "No se pudo establecer el contenido: %s" msgid "Create in folder" msgstr "Crear en carpeta" +#: src/wx/film_editor.cc:1363 +#, c-format +msgid "Cropped to %dx%d (%.2f:1)\n" +msgstr "" + #: src/wx/dci_metadata_dialog.cc:28 msgid "DCI name" msgstr "Nombre DCI" -#: src/wx/film_editor.cc:142 +#: src/wx/film_editor.cc:141 msgid "DCP Frame Rate" msgstr "Velocidad DCP" -#: src/wx/film_editor.cc:110 +#: src/wx/film_editor.cc:109 msgid "DCP Name" msgstr "Nombre DCP" @@ -131,18 +149,19 @@ msgid "DVD-o-matic Preferences" msgstr "Preferencias DVD-o-matic" #: src/wx/audio_dialog.cc:101 -msgid "DVD-o-matic audio - %1" +#, fuzzy, c-format +msgid "DVD-o-matic audio - %s" msgstr "Audio DVD-o-matic - %1" -#: src/wx/config_dialog.cc:83 +#: src/wx/config_dialog.cc:102 msgid "Default DCI name details" msgstr "Detalles por defecto del nombre DCI" -#: src/wx/config_dialog.cc:74 +#: src/wx/config_dialog.cc:93 msgid "Default directory for new films" msgstr "Carpeta por defecto para nuevas películas" -#: src/wx/film_editor.cc:117 src/wx/job_manager_view.cc:88 +#: src/wx/film_editor.cc:116 src/wx/job_manager_view.cc:92 msgid "Details..." msgstr "Detalles..." @@ -150,24 +169,24 @@ msgstr "Detalles..." msgid "Disk space required" msgstr "Espacio requerido en disco" -#: src/wx/film_editor.cc:192 +#: src/wx/film_editor.cc:191 msgid "Duration" msgstr "Duración" -#: src/wx/config_dialog.cc:126 +#: src/wx/config_dialog.cc:145 msgid "Edit" msgstr "Editar" -#: src/wx/config_dialog.cc:84 src/wx/config_dialog.cc:103 -#: src/wx/film_editor.cc:309 +#: src/wx/config_dialog.cc:103 src/wx/config_dialog.cc:122 +#: src/wx/film_editor.cc:308 msgid "Edit..." msgstr "Editar..." -#: src/wx/config_dialog.cc:109 +#: src/wx/config_dialog.cc:128 msgid "Encoding Servers" msgstr "Servidores de codificación" -#: src/wx/film_editor.cc:177 +#: src/wx/film_editor.cc:176 msgid "End" msgstr "Fin" @@ -175,7 +194,7 @@ msgstr "Fin" msgid "Facility (e.g. DLA)" msgstr "Compañía (ej. DLA)" -#: src/wx/film_editor.cc:74 +#: src/wx/film_editor.cc:73 msgid "Film" msgstr "Película" @@ -187,11 +206,11 @@ msgstr "Propiedades de la película" msgid "Film name" msgstr "Nombre de la película" -#: src/wx/film_editor.cc:304 src/wx/filter_dialog.cc:32 +#: src/wx/film_editor.cc:303 src/wx/filter_dialog.cc:32 msgid "Filters" msgstr "Filtros" -#: src/wx/film_editor.cc:269 +#: src/wx/film_editor.cc:268 msgid "Format" msgstr "Formato" @@ -215,7 +234,7 @@ msgstr "Gb" msgid "Host name or IP address" msgstr "Nombre o dirección IP" -#: src/wx/film_editor.cc:1234 +#: src/wx/film_editor.cc:1273 msgid "Hz" msgstr "Hz" @@ -223,23 +242,23 @@ msgstr "Hz" msgid "I want to play this back at fader" msgstr "Quiero reproducir con el fader a" -#: src/wx/config_dialog.cc:113 +#: src/wx/config_dialog.cc:132 msgid "IP address" msgstr "Dirección IP" -#: src/wx/film_editor.cc:336 +#: src/wx/film_editor.cc:335 msgid "JPEG2000 bandwidth" msgstr "Ancho de banda JPEG2000" -#: src/wx/film_editor.cc:282 +#: src/wx/film_editor.cc:273 msgid "Left crop" msgstr "Recorte izquierda" -#: src/wx/film_editor.cc:165 +#: src/wx/film_editor.cc:164 msgid "Length" msgstr "Longitud" -#: src/wx/film_editor.cc:340 +#: src/wx/film_editor.cc:339 msgid "MBps" msgstr "MBps" @@ -247,7 +266,7 @@ msgstr "MBps" msgid "My Documents" msgstr "Mis documentos" -#: src/wx/film_editor.cc:105 +#: src/wx/film_editor.cc:104 msgid "Name" msgstr "Nombre" @@ -255,22 +274,32 @@ msgstr "Nombre" msgid "New Film" msgstr "Nueva película" -#: src/wx/film_editor.cc:306 src/wx/film_editor.cc:665 +#: src/wx/film_editor.cc:305 src/wx/film_editor.cc:667 msgid "None" msgstr "Ninguno" -#: src/wx/film_editor.cc:136 +#: src/wx/film_editor.cc:135 msgid "Original Frame Rate" msgstr "Velocidad original" -#: src/wx/film_editor.cc:160 +#: src/wx/film_editor.cc:159 msgid "Original Size" msgstr "Tamaño original" +#: src/wx/film_editor.cc:1352 +#, c-format +msgid "Original video is %dx%d (%.2f:1)\n" +msgstr "" + #: src/wx/dci_metadata_dialog.cc:57 msgid "Package Type (e.g. OV)" msgstr "Tipo de paquete (ej. OV)" +#: src/wx/film_editor.cc:1384 +#, c-format +msgid "Padded with black to %dx%d (%.2f:1)\n" +msgstr "" + #: src/wx/audio_dialog.cc:60 msgid "Peak" msgstr "Pico" @@ -291,35 +320,40 @@ msgstr "RMS" msgid "Rating (e.g. 15)" msgstr "Clasificación (ej. 16)" -#: src/wx/config_dialog.cc:99 +#: src/wx/config_dialog.cc:118 msgid "Reference filters for A/B" msgstr "Filtros de referencia para A/B" -#: src/wx/config_dialog.cc:88 +#: src/wx/config_dialog.cc:107 msgid "Reference scaler for A/B" msgstr "Escalador de referencia para A/B" -#: src/wx/config_dialog.cc:128 +#: src/wx/config_dialog.cc:147 msgid "Remove" msgstr "Quitar" -#: src/wx/film_editor.cc:287 +#: src/wx/film_editor.cc:278 msgid "Right crop" msgstr "Recorte derecha" -#: src/wx/job_manager_view.cc:104 +#: src/wx/job_manager_view.cc:108 msgid "Running" msgstr "Ejecutando" -#: src/wx/film_editor.cc:316 +#: src/wx/film_editor.cc:1376 +#, c-format +msgid "Scaled to %dx%d (%.2f:1)\n" +msgstr "" + +#: src/wx/film_editor.cc:315 msgid "Scaler" msgstr "Escalador" -#: src/wx/film_editor.cc:408 +#: src/wx/film_editor.cc:407 msgid "Select Audio File" msgstr "Seleccionar fichero de audio" -#: src/wx/film_editor.cc:122 +#: src/wx/film_editor.cc:121 msgid "Select Content File" msgstr "Seleccionar fichero de contenido" @@ -327,7 +361,11 @@ msgstr "Seleccionar fichero de contenido" msgid "Server" msgstr "Servidor" -#: src/wx/film_editor.cc:365 +#: src/wx/config_dialog.cc:49 +msgid "Set language" +msgstr "" + +#: src/wx/film_editor.cc:364 msgid "Show Audio..." msgstr "Mostrar audio..." @@ -335,7 +373,7 @@ msgstr "Mostrar audio..." msgid "Smoothing" msgstr "Suavizado" -#: src/wx/film_editor.cc:174 +#: src/wx/film_editor.cc:173 msgid "Start" msgstr "Inicio" @@ -351,27 +389,27 @@ msgstr "Idioma del subtítulo (ej. EN)" msgid "Subtitle Offset" msgstr "Desplazamiento del subtítulo" -#: src/wx/film_editor.cc:437 +#: src/wx/film_editor.cc:441 msgid "Subtitle Scale" msgstr "Escala del subtítulo" -#: src/wx/film_editor.cc:80 +#: src/wx/film_editor.cc:79 msgid "Subtitles" msgstr "Subtítulos" -#: src/wx/config_dialog.cc:49 +#: src/wx/config_dialog.cc:68 msgid "TMS IP address" msgstr "Dirección IP del TMS" -#: src/wx/config_dialog.cc:64 +#: src/wx/config_dialog.cc:83 msgid "TMS password" msgstr "Clave del TMS" -#: src/wx/config_dialog.cc:54 +#: src/wx/config_dialog.cc:73 msgid "TMS target path" msgstr "Ruta en el TMS" -#: src/wx/config_dialog.cc:59 +#: src/wx/config_dialog.cc:78 msgid "TMS user name" msgstr "Usuario del TMS" @@ -379,7 +417,7 @@ msgstr "Usuario del TMS" msgid "Territory (e.g. UK)" msgstr "Territorio (ej. ES)" -#: src/wx/config_dialog.cc:117 +#: src/wx/config_dialog.cc:136 msgid "Threads" msgstr "Hilos" @@ -387,7 +425,7 @@ msgstr "Hilos" msgid "Threads to use" msgstr "Hilos a utilizar" -#: src/wx/config_dialog.cc:69 +#: src/wx/config_dialog.cc:88 msgid "Threads to use for encoding on this host" msgstr "Hilos a utilizar para la codificación en esta máquina" @@ -395,15 +433,15 @@ msgstr "Hilos a utilizar para la codificación en esta máquina" msgid "Time" msgstr "Tiempo" -#: src/wx/film_editor.cc:292 +#: src/wx/film_editor.cc:283 msgid "Top crop" msgstr "Recortar arriba" -#: src/wx/film_editor.cc:172 +#: src/wx/film_editor.cc:171 msgid "Trim frames" msgstr "Recortar fotogramas" -#: src/wx/film_editor.cc:126 +#: src/wx/film_editor.cc:125 msgid "Trust content's header" msgstr "Confiar en la cabecera del contenido" @@ -411,31 +449,31 @@ msgstr "Confiar en la cabecera del contenido" msgid "Type" msgstr "Tipo" -#: src/wx/film_editor.cc:115 +#: src/wx/film_editor.cc:114 msgid "Use DCI name" msgstr "Usar el nombre DCI" -#: src/wx/film_editor.cc:146 +#: src/wx/film_editor.cc:145 msgid "Use best" msgstr "Usar la mejor" -#: src/wx/film_editor.cc:392 +#: src/wx/film_editor.cc:391 msgid "Use content's audio" msgstr "Usar el audio del contenido" -#: src/wx/film_editor.cc:402 +#: src/wx/film_editor.cc:401 msgid "Use external audio" msgstr "Usar audio externo" -#: src/wx/film_editor.cc:76 +#: src/wx/film_editor.cc:75 msgid "Video" msgstr "Vídeo" -#: src/wx/film_editor.cc:425 +#: src/wx/film_editor.cc:424 msgid "With Subtitles" msgstr "Con subtítulos" -#: src/wx/film_editor.cc:1232 +#: src/wx/film_editor.cc:1271 msgid "channels" msgstr "canales" @@ -443,21 +481,25 @@ msgstr "canales" msgid "counting..." msgstr "contando..." -#: src/wx/film_editor.cc:374 +#: src/wx/film_editor.cc:373 msgid "dB" msgstr "dB" -#: src/wx/film_editor.cc:691 src/wx/film_editor.cc:693 +#: src/wx/film_editor.cc:696 src/wx/film_editor.cc:699 msgid "frames" msgstr "fotogramas" #. / TRANSLATORS: this is an abbreviation for milliseconds, the unit of time -#: src/wx/film_editor.cc:387 +#: src/wx/film_editor.cc:386 msgid "ms" msgstr "ms" +#: src/wx/film_editor.cc:436 +msgid "pixels" +msgstr "" + #. / TRANSLATORS: `s' here is an abbreviation for seconds, the unit of time -#: src/wx/film_editor.cc:198 +#: src/wx/film_editor.cc:197 msgid "s" msgstr "s" diff --git a/src/wx/po/fr_FR.po b/src/wx/po/fr_FR.po index 03da04610..37cd6d8ab 100644 --- a/src/wx/po/fr_FR.po +++ b/src/wx/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-01 21:21+0100\n" +"POT-Creation-Date: 2013-04-07 18:17+0100\n" "PO-Revision-Date: 2013-03-20 00:34+0100\n" "Last-Translator: FreeDCP.net \n" "Language-Team: \n" @@ -16,7 +16,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: src/wx/film_editor.cc:440 +#: src/wx/film_editor.cc:445 msgid "%" msgstr "%" @@ -24,7 +24,7 @@ msgstr "%" msgid "(restart DVD-o-matic to see language changes)" msgstr "" -#: src/wx/film_editor.cc:1231 +#: src/wx/film_editor.cc:1269 msgid "1 channel" msgstr "1 canal" @@ -52,12 +52,17 @@ msgstr "Gain audio" msgid "Audio Language (e.g. EN)" msgstr "Langue audio (ex. FR)" +#: src/wx/film_editor.cc:820 +#, c-format +msgid "Audio will be resampled from %dHz to %dHz\n" +msgstr "" + #: src/wx/job_wrapper.cc:38 #, c-format msgid "Bad setting for %s (%s)" msgstr "Mauvais paramètre pour %s (%s)" -#: src/wx/film_editor.cc:296 +#: src/wx/film_editor.cc:288 msgid "Bottom crop" msgstr "Découpe bas" @@ -93,7 +98,7 @@ msgstr "Contenu" msgid "Content Type" msgstr "Type de Contenu" -#: src/wx/film_viewer.cc:414 +#: src/wx/film_viewer.cc:415 #, c-format msgid "Could not decode video for view (%s)" msgstr "Décodage de la vidéo pour visualisation impossible (%s)" @@ -103,12 +108,12 @@ msgstr "Décodage de la vidéo pour visualisation impossible (%s)" msgid "Could not make DCP: %s" msgstr "Impossible de créer le DCP : %s" -#: src/wx/film_viewer.cc:108 +#: src/wx/film_viewer.cc:107 #, c-format msgid "Could not open content file (%s)" msgstr "Ouverture du contenu impossible (%s)" -#: src/wx/film_editor.cc:504 +#: src/wx/film_editor.cc:509 #, c-format msgid "Could not set content: %s" msgstr "Sélectionner du contenu impossible : %s" @@ -117,6 +122,11 @@ msgstr "Sélectionner du contenu impossible : %s" msgid "Create in folder" msgstr "Créer dans le dossier" +#: src/wx/film_editor.cc:1363 +#, c-format +msgid "Cropped to %dx%d (%.2f:1)\n" +msgstr "" + #: src/wx/dci_metadata_dialog.cc:28 msgid "DCI name" msgstr "Nom DCI" @@ -223,7 +233,7 @@ msgstr "Gb" msgid "Host name or IP address" msgstr "Nom de l'hôte ou adresse IP" -#: src/wx/film_editor.cc:1235 +#: src/wx/film_editor.cc:1273 msgid "Hz" msgstr "Hz" @@ -239,7 +249,7 @@ msgstr "Adresse IP" msgid "JPEG2000 bandwidth" msgstr "Qualité JPEG2000" -#: src/wx/film_editor.cc:281 +#: src/wx/film_editor.cc:273 msgid "Left crop" msgstr "Découpe gauche" @@ -263,7 +273,7 @@ msgstr "Nom" msgid "New Film" msgstr "Nouveau Film" -#: src/wx/film_editor.cc:305 src/wx/film_editor.cc:664 +#: src/wx/film_editor.cc:305 src/wx/film_editor.cc:667 msgid "None" msgstr "Aucun" @@ -275,10 +285,20 @@ msgstr "Cadence d'images originale" msgid "Original Size" msgstr "Taille Originale" +#: src/wx/film_editor.cc:1352 +#, c-format +msgid "Original video is %dx%d (%.2f:1)\n" +msgstr "" + #: src/wx/dci_metadata_dialog.cc:57 msgid "Package Type (e.g. OV)" msgstr "Type de paquet (ex. OV)" +#: src/wx/film_editor.cc:1384 +#, c-format +msgid "Padded with black to %dx%d (%.2f:1)\n" +msgstr "" + #: src/wx/audio_dialog.cc:60 msgid "Peak" msgstr "Crête" @@ -311,7 +331,7 @@ msgstr "Échelle de référence pour A/B" msgid "Remove" msgstr "Supprimer" -#: src/wx/film_editor.cc:286 +#: src/wx/film_editor.cc:278 msgid "Right crop" msgstr "Découpe droite" @@ -319,6 +339,11 @@ msgstr "Découpe droite" msgid "Running" msgstr "Progression" +#: src/wx/film_editor.cc:1376 +#, c-format +msgid "Scaled to %dx%d (%.2f:1)\n" +msgstr "" + #: src/wx/film_editor.cc:315 msgid "Scaler" msgstr "Mise à l'échelle" @@ -359,11 +384,11 @@ msgstr "Studio (ex. TCF)" msgid "Subtitle Language (e.g. FR)" msgstr "Langue de sous-titres (ex. FR)" -#: src/wx/film_editor.cc:431 +#: src/wx/film_editor.cc:432 msgid "Subtitle Offset" msgstr "Décalage du sous-titre" -#: src/wx/film_editor.cc:436 +#: src/wx/film_editor.cc:441 msgid "Subtitle Scale" msgstr "Taille du sous-titre" @@ -407,7 +432,7 @@ msgstr "Nombre de processus à utiliser sur cet hôte" msgid "Time" msgstr "Durée" -#: src/wx/film_editor.cc:291 +#: src/wx/film_editor.cc:283 msgid "Top crop" msgstr "Découpe haut" @@ -447,7 +472,7 @@ msgstr "Vidéo" msgid "With Subtitles" msgstr "Avec sous-titres" -#: src/wx/film_editor.cc:1233 +#: src/wx/film_editor.cc:1271 msgid "channels" msgstr "canaux" @@ -459,7 +484,7 @@ msgstr "calcul..." msgid "dB" msgstr "dB" -#: src/wx/film_editor.cc:691 src/wx/film_editor.cc:694 +#: src/wx/film_editor.cc:696 src/wx/film_editor.cc:699 msgid "frames" msgstr "images" @@ -468,6 +493,10 @@ msgstr "images" msgid "ms" msgstr "ms" +#: src/wx/film_editor.cc:436 +msgid "pixels" +msgstr "" + #. / TRANSLATORS: `s' here is an abbreviation for seconds, the unit of time #: src/wx/film_editor.cc:197 msgid "s" diff --git a/src/wx/po/it_IT.po b/src/wx/po/it_IT.po index 3de3816f6..9a0f13d2e 100644 --- a/src/wx/po/it_IT.po +++ b/src/wx/po/it_IT.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-01 21:21+0100\n" +"POT-Creation-Date: 2013-04-07 18:17+0100\n" "PO-Revision-Date: 2013-03-22 18:10+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" @@ -17,7 +17,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" -#: src/wx/film_editor.cc:440 +#: src/wx/film_editor.cc:445 msgid "%" msgstr "%" @@ -25,7 +25,7 @@ msgstr "%" msgid "(restart DVD-o-matic to see language changes)" msgstr "" -#: src/wx/film_editor.cc:1231 +#: src/wx/film_editor.cc:1269 msgid "1 channel" msgstr "Canale 1" @@ -53,12 +53,17 @@ msgstr "Guadagno dell'audio" msgid "Audio Language (e.g. EN)" msgstr "Lingua dell'audio (es. EN)" +#: src/wx/film_editor.cc:820 +#, c-format +msgid "Audio will be resampled from %dHz to %dHz\n" +msgstr "" + #: src/wx/job_wrapper.cc:38 #, c-format msgid "Bad setting for %s (%s)" msgstr "Valore sbagliato per %s (%s)" -#: src/wx/film_editor.cc:296 +#: src/wx/film_editor.cc:288 msgid "Bottom crop" msgstr "Taglio in basso" @@ -94,7 +99,7 @@ msgstr "Contenuto" msgid "Content Type" msgstr "Tipo di contenuto" -#: src/wx/film_viewer.cc:414 +#: src/wx/film_viewer.cc:415 #, c-format msgid "Could not decode video for view (%s)" msgstr "Non posso decodificare il video per guardarlo (%s)" @@ -104,12 +109,12 @@ msgstr "Non posso decodificare il video per guardarlo (%s)" msgid "Could not make DCP: %s" msgstr "Non posso creare il DCP: %s" -#: src/wx/film_viewer.cc:108 +#: src/wx/film_viewer.cc:107 #, c-format msgid "Could not open content file (%s)" msgstr "Non posso aprire il file del contenuto (%s)" -#: src/wx/film_editor.cc:504 +#: src/wx/film_editor.cc:509 #, c-format msgid "Could not set content: %s" msgstr "Non posso regolare il contenuto: %s" @@ -118,6 +123,11 @@ msgstr "Non posso regolare il contenuto: %s" msgid "Create in folder" msgstr "Crea nella cartella" +#: src/wx/film_editor.cc:1363 +#, c-format +msgid "Cropped to %dx%d (%.2f:1)\n" +msgstr "" + #: src/wx/dci_metadata_dialog.cc:28 msgid "DCI name" msgstr "Nome del DCP" @@ -224,7 +234,7 @@ msgstr "Gb" msgid "Host name or IP address" msgstr "Nome dell'Host o indirizzo IP" -#: src/wx/film_editor.cc:1235 +#: src/wx/film_editor.cc:1273 msgid "Hz" msgstr "Hz" @@ -240,7 +250,7 @@ msgstr "Indirizzo IP" msgid "JPEG2000 bandwidth" msgstr "Banda passante JPEG2000" -#: src/wx/film_editor.cc:281 +#: src/wx/film_editor.cc:273 msgid "Left crop" msgstr "Taglio a sinistra" @@ -264,7 +274,7 @@ msgstr "Nome" msgid "New Film" msgstr "Nuovo Film" -#: src/wx/film_editor.cc:305 src/wx/film_editor.cc:664 +#: src/wx/film_editor.cc:305 src/wx/film_editor.cc:667 msgid "None" msgstr "Nessuno" @@ -276,10 +286,20 @@ msgstr "Frequenza fotogrammi originale" msgid "Original Size" msgstr "Dimensione Originale" +#: src/wx/film_editor.cc:1352 +#, c-format +msgid "Original video is %dx%d (%.2f:1)\n" +msgstr "" + #: src/wx/dci_metadata_dialog.cc:57 msgid "Package Type (e.g. OV)" msgstr "Tipo di Package (es. OV)" +#: src/wx/film_editor.cc:1384 +#, c-format +msgid "Padded with black to %dx%d (%.2f:1)\n" +msgstr "" + #: src/wx/audio_dialog.cc:60 msgid "Peak" msgstr "Picco" @@ -312,7 +332,7 @@ msgstr "Scalatura di riferimento A/B" msgid "Remove" msgstr "Rimuovi" -#: src/wx/film_editor.cc:286 +#: src/wx/film_editor.cc:278 msgid "Right crop" msgstr "Taglio a destra" @@ -320,6 +340,11 @@ msgstr "Taglio a destra" msgid "Running" msgstr "In corso" +#: src/wx/film_editor.cc:1376 +#, c-format +msgid "Scaled to %dx%d (%.2f:1)\n" +msgstr "" + #: src/wx/film_editor.cc:315 msgid "Scaler" msgstr "Scaler" @@ -360,11 +385,11 @@ msgstr "Studio (es. TCF)" msgid "Subtitle Language (e.g. FR)" msgstr "Lingua dei Sottotitoli (es. FR)" -#: src/wx/film_editor.cc:431 +#: src/wx/film_editor.cc:432 msgid "Subtitle Offset" msgstr "Sfalsamento dei Sottotitoli" -#: src/wx/film_editor.cc:436 +#: src/wx/film_editor.cc:441 msgid "Subtitle Scale" msgstr "Scala dei Sottotitoli" @@ -408,7 +433,7 @@ msgstr "Threads da usare per codificare su questo host" msgid "Time" msgstr "Tempo" -#: src/wx/film_editor.cc:291 +#: src/wx/film_editor.cc:283 msgid "Top crop" msgstr "Taglio in alto" @@ -448,7 +473,7 @@ msgstr "Video" msgid "With Subtitles" msgstr "Con Sottotitoli" -#: src/wx/film_editor.cc:1233 +#: src/wx/film_editor.cc:1271 msgid "channels" msgstr "canali" @@ -460,7 +485,7 @@ msgstr "conteggio..." msgid "dB" msgstr "dB" -#: src/wx/film_editor.cc:691 src/wx/film_editor.cc:694 +#: src/wx/film_editor.cc:696 src/wx/film_editor.cc:699 msgid "frames" msgstr "fotogrammi" @@ -469,6 +494,10 @@ msgstr "fotogrammi" msgid "ms" msgstr "ms" +#: src/wx/film_editor.cc:436 +msgid "pixels" +msgstr "" + #. / TRANSLATORS: `s' here is an abbreviation for seconds, the unit of time #: src/wx/film_editor.cc:197 msgid "s" diff --git a/src/wx/po/sv_SE.po b/src/wx/po/sv_SE.po index 24a6060de..ab9873877 100644 --- a/src/wx/po/sv_SE.po +++ b/src/wx/po/sv_SE.po @@ -7,16 +7,17 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-01 21:21+0100\n" +"POT-Creation-Date: 2013-04-07 18:17+0100\n" "PO-Revision-Date: 2013-04-04 10:18+0100\n" "Last-Translator: Adam Klotblixt \n" "Language-Team: \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" -#: src/wx/film_editor.cc:440 +#: src/wx/film_editor.cc:445 msgid "%" msgstr "%" @@ -24,7 +25,7 @@ msgstr "%" msgid "(restart DVD-o-matic to see language changes)" msgstr "(starta om DVD-o-matic för att se språkändringar)" -#: src/wx/film_editor.cc:1231 +#: src/wx/film_editor.cc:1269 msgid "1 channel" msgstr "1 kanal" @@ -52,12 +53,17 @@ msgstr "Audio Förstärkning" msgid "Audio Language (e.g. EN)" msgstr "Audio Språk (ex. SV)" +#: src/wx/film_editor.cc:820 +#, c-format +msgid "Audio will be resampled from %dHz to %dHz\n" +msgstr "" + #: src/wx/job_wrapper.cc:38 #, c-format msgid "Bad setting for %s (%s)" msgstr "Felaktig inställning för %s (%s)" -#: src/wx/film_editor.cc:296 +#: src/wx/film_editor.cc:288 msgid "Bottom crop" msgstr "Nedre beskärning" @@ -93,7 +99,7 @@ msgstr "Innehåll" msgid "Content Type" msgstr "Innehållstyp" -#: src/wx/film_viewer.cc:414 +#: src/wx/film_viewer.cc:415 #, c-format msgid "Could not decode video for view (%s)" msgstr "Kunde inte avkoda video för visning (%s)" @@ -103,12 +109,12 @@ msgstr "Kunde inte avkoda video för visning (%s)" msgid "Could not make DCP: %s" msgstr "Kunde inte skapa DCP: %s" -#: src/wx/film_viewer.cc:108 +#: src/wx/film_viewer.cc:107 #, c-format msgid "Could not open content file (%s)" msgstr "Kunde inte öppna innehållsfilen (%s)" -#: src/wx/film_editor.cc:504 +#: src/wx/film_editor.cc:509 #, c-format msgid "Could not set content: %s" msgstr "Kunde inte fastställa innehåll: %s" @@ -117,6 +123,11 @@ msgstr "Kunde inte fastställa innehåll: %s" msgid "Create in folder" msgstr "Skapa i katalog" +#: src/wx/film_editor.cc:1363 +#, c-format +msgid "Cropped to %dx%d (%.2f:1)\n" +msgstr "" + #: src/wx/dci_metadata_dialog.cc:28 msgid "DCI name" msgstr "DCI namn" @@ -223,7 +234,7 @@ msgstr "Gb" msgid "Host name or IP address" msgstr "Värd-namn eller IP-adress" -#: src/wx/film_editor.cc:1235 +#: src/wx/film_editor.cc:1273 msgid "Hz" msgstr "Hz" @@ -239,7 +250,7 @@ msgstr "IP-adress" msgid "JPEG2000 bandwidth" msgstr "JPEG2000 bandbredd" -#: src/wx/film_editor.cc:281 +#: src/wx/film_editor.cc:273 msgid "Left crop" msgstr "Vänster beskärning" @@ -263,7 +274,7 @@ msgstr "Namn" msgid "New Film" msgstr "Ny Film" -#: src/wx/film_editor.cc:305 src/wx/film_editor.cc:664 +#: src/wx/film_editor.cc:305 src/wx/film_editor.cc:667 msgid "None" msgstr "Inget" @@ -275,10 +286,20 @@ msgstr "Ursprunglig bildhastighet" msgid "Original Size" msgstr "Ursprunglig Storlek" +#: src/wx/film_editor.cc:1352 +#, c-format +msgid "Original video is %dx%d (%.2f:1)\n" +msgstr "" + #: src/wx/dci_metadata_dialog.cc:57 msgid "Package Type (e.g. OV)" msgstr "Förpackningstyp (ex. OV)" +#: src/wx/film_editor.cc:1384 +#, c-format +msgid "Padded with black to %dx%d (%.2f:1)\n" +msgstr "" + #: src/wx/audio_dialog.cc:60 msgid "Peak" msgstr "Topp" @@ -311,7 +332,7 @@ msgstr "Referensomskalare för A/B" msgid "Remove" msgstr "Ta bort" -#: src/wx/film_editor.cc:286 +#: src/wx/film_editor.cc:278 msgid "Right crop" msgstr "Höger beskärning" @@ -319,6 +340,11 @@ msgstr "Höger beskärning" msgid "Running" msgstr "Körs" +#: src/wx/film_editor.cc:1376 +#, c-format +msgid "Scaled to %dx%d (%.2f:1)\n" +msgstr "" + #: src/wx/film_editor.cc:315 msgid "Scaler" msgstr "Omskalare" @@ -359,11 +385,11 @@ msgstr "Studio (ex. TCF)" msgid "Subtitle Language (e.g. FR)" msgstr "Undertextspråk (ex. SV)" -#: src/wx/film_editor.cc:431 +#: src/wx/film_editor.cc:432 msgid "Subtitle Offset" msgstr "Undertext Förskjutning" -#: src/wx/film_editor.cc:436 +#: src/wx/film_editor.cc:441 msgid "Subtitle Scale" msgstr "Undertext Skalning" @@ -407,7 +433,7 @@ msgstr "Antal trådar att använda vid kodning på denna maskin" msgid "Time" msgstr "Tid" -#: src/wx/film_editor.cc:291 +#: src/wx/film_editor.cc:283 msgid "Top crop" msgstr "Övre beskärning" @@ -447,7 +473,7 @@ msgstr "Video" msgid "With Subtitles" msgstr "Med Undertexter" -#: src/wx/film_editor.cc:1233 +#: src/wx/film_editor.cc:1271 msgid "channels" msgstr "kanaler" @@ -459,7 +485,7 @@ msgstr "räknar..." msgid "dB" msgstr "dB" -#: src/wx/film_editor.cc:691 src/wx/film_editor.cc:694 +#: src/wx/film_editor.cc:696 src/wx/film_editor.cc:699 msgid "frames" msgstr "bilder" @@ -468,6 +494,10 @@ msgstr "bilder" msgid "ms" msgstr "ms" +#: src/wx/film_editor.cc:436 +msgid "pixels" +msgstr "" + #. / TRANSLATORS: `s' here is an abbreviation for seconds, the unit of time #: src/wx/film_editor.cc:197 msgid "s" -- cgit v1.2.3 From ddff3cef5e0c03700ad238dc25968d548651a426 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 7 Apr 2013 22:41:31 +0100 Subject: Fix some newlines in .po files. --- src/lib/po/es_ES.po | 2 +- src/lib/po/fr_FR.po | 2 +- src/lib/po/it_IT.po | 2 +- src/lib/po/sv_SE.po | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/lib/po/es_ES.po b/src/lib/po/es_ES.po index 73c304348..8f6a06563 100644 --- a/src/lib/po/es_ES.po +++ b/src/lib/po/es_ES.po @@ -141,7 +141,7 @@ msgstr "La fuente y el DCP tienen la misma velocidad.\n" #: src/lib/util.cc:1017 #, fuzzy msgid "DCP will run at %1%% of the source speed.\n" -msgstr "El DCP se reproducirá al %1%% de la velocidad de la fuente." +msgstr "El DCP se reproducirá al %1%% de la velocidad de la fuente.\n" #: src/lib/util.cc:1010 msgid "DCP will use every other frame of the source.\n" diff --git a/src/lib/po/fr_FR.po b/src/lib/po/fr_FR.po index 138d073c2..b9c382c0a 100644 --- a/src/lib/po/fr_FR.po +++ b/src/lib/po/fr_FR.po @@ -139,7 +139,7 @@ msgstr "Le DCP et la source ont les mêmes cadences.\n" #: src/lib/util.cc:1017 #, fuzzy msgid "DCP will run at %1%% of the source speed.\n" -msgstr "La cadence du DCP sera %1%% par rapport à la source" +msgstr "La cadence du DCP sera %1%% par rapport à la source.\n" #: src/lib/util.cc:1010 msgid "DCP will use every other frame of the source.\n" diff --git a/src/lib/po/it_IT.po b/src/lib/po/it_IT.po index c184a3932..8e9b7166b 100644 --- a/src/lib/po/it_IT.po +++ b/src/lib/po/it_IT.po @@ -140,7 +140,7 @@ msgstr "Il DCP e il sorgente hanno la stessa frequenza.\n" #: src/lib/util.cc:1017 #, fuzzy msgid "DCP will run at %1%% of the source speed.\n" -msgstr "Il DCP andrà al %1%% della velocità del sorgente." +msgstr "Il DCP andrà al %1%% della velocità del sorgente.\n" #: src/lib/util.cc:1010 msgid "DCP will use every other frame of the source.\n" diff --git a/src/lib/po/sv_SE.po b/src/lib/po/sv_SE.po index 9f74e1e2a..a155771a7 100644 --- a/src/lib/po/sv_SE.po +++ b/src/lib/po/sv_SE.po @@ -141,7 +141,7 @@ msgstr "DCP och källa har samma bildfrekvens.\n" #: src/lib/util.cc:1017 #, fuzzy msgid "DCP will run at %1%% of the source speed.\n" -msgstr "DCP kommer att köras på %1%% av källans hastighet." +msgstr "DCP kommer att köras på %1%% av källans hastighet.\n" #: src/lib/util.cc:1010 msgid "DCP will use every other frame of the source.\n" -- cgit v1.2.3 From d0702ff32eace9f49676600fef22f935a4e5e16a Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 7 Apr 2013 23:08:38 +0100 Subject: wx2.8 fixes. --- src/tools/servomatic_gui.cc | 2 +- src/wx/film_editor.cc | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/tools/servomatic_gui.cc b/src/tools/servomatic_gui.cc index 52ec0a3a3..5e36660eb 100644 --- a/src/tools/servomatic_gui.cc +++ b/src/tools/servomatic_gui.cc @@ -99,7 +99,7 @@ public: #endif #ifdef __WXGTK__ wxInitAllImageHandlers(); - wxBitmap bitmap (wxString::Format ("%s/taskbar_icon.png", POSIX_ICON_PREFIX), wxBITMAP_TYPE_PNG); + wxBitmap bitmap (wxString::Format (wxT ("%s/taskbar_icon.png"), POSIX_ICON_PREFIX), wxBITMAP_TYPE_PNG); wxIcon icon; icon.CopyFromBitmap (bitmap); #endif diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index eb36ce1ff..5e597ac30 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -822,10 +822,10 @@ FilmEditor::setup_frame_rate_description () _film->target_audio_sample_rate() ); } else { - d << "\n"; + d << wxT ("\n"); } #else - d << "\n"; + d << wxT ("\n"); #endif } @@ -1268,9 +1268,9 @@ FilmEditor::setup_audio_details () if (_film->audio_stream()->channels() == 1) { s << _("1 channel"); } else { - s << _film->audio_stream()->channels () << " " << _("channels"); + s << _film->audio_stream()->channels () << wxT (" ") << _("channels"); } - s << ", " << _film->audio_stream()->sample_rate() << _("Hz"); + s << wxT (", ") << _film->audio_stream()->sample_rate() << _("Hz"); _audio->SetLabel (s); } @@ -1390,7 +1390,7 @@ FilmEditor::setup_scaling_description () } for (int i = lines; i < 4; ++i) { - d << " \n"; + d << wxT (" \n"); } _scaling_description->SetLabel (d); -- cgit v1.2.3 From 546c1c3a19d79968b414fb61a9ab10989d942ae1 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 8 Apr 2013 10:16:41 +0100 Subject: Add 16:9-within-Scope format. --- src/lib/format.cc | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/lib/format.cc b/src/lib/format.cc index 21f8fb9a2..0ca97303e 100644 --- a/src/lib/format.cc +++ b/src/lib/format.cc @@ -111,6 +111,10 @@ Format::setup_formats () new FixedFormat (185, libdcp::Size (1998, 1080), N_("185"), _("Flat"), N_("F") )); + _formats.push_back ( + new FixedFormat (178, libdcp::Size (2048, 858), N_("178-in-scope"), _("16:9 within Scope"), N_("S") + )); + _formats.push_back ( new FixedFormat (239, libdcp::Size (2048, 858), N_("239"), _("Scope"), N_("S") )); -- cgit v1.2.3 From d18c3144c4e3c6a5748c6e5ccaeee841af95a83e Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 9 Apr 2013 10:19:36 +0100 Subject: Updated sv_SE from Adam. --- src/lib/po/sv_SE.po | 4 +--- src/tools/po/sv_SE.po | 5 +++-- src/wx/po/sv_SE.po | 15 +++++++-------- 3 files changed, 11 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/lib/po/sv_SE.po b/src/lib/po/sv_SE.po index a155771a7..b79d9d652 100644 --- a/src/lib/po/sv_SE.po +++ b/src/lib/po/sv_SE.po @@ -8,10 +8,9 @@ msgstr "" "Project-Id-Version: DVD-o-matic\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-04-07 18:17+0100\n" -"PO-Revision-Date: 2013-04-04 10:22+0100\n" +"PO-Revision-Date: 2013-04-09 10:13+0100\n" "Last-Translator: Adam Klotblixt \n" "Language-Team: \n" -"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -139,7 +138,6 @@ msgid "DCP and source have the same rate.\n" msgstr "DCP och källa har samma bildfrekvens.\n" #: src/lib/util.cc:1017 -#, fuzzy msgid "DCP will run at %1%% of the source speed.\n" msgstr "DCP kommer att köras på %1%% av källans hastighet.\n" diff --git a/src/tools/po/sv_SE.po b/src/tools/po/sv_SE.po index dd45c3baa..a5a4be9fe 100644 --- a/src/tools/po/sv_SE.po +++ b/src/tools/po/sv_SE.po @@ -8,10 +8,9 @@ msgstr "" "Project-Id-Version: DVD-o-matic\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-04-07 18:17+0100\n" -"PO-Revision-Date: 2013-04-04 10:11+0100\n" +"PO-Revision-Date: 2013-04-09 10:12+0100\n" "Last-Translator: Adam Klotblixt \n" "Language-Team: \n" -"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -123,3 +122,5 @@ msgid "" "You did not select a folder. Make sure that you select a folder before " "clicking Open." msgstr "" +"Du har inte valt en folder. Se till att välja en folder innan du klickar på " +"Öppna." diff --git a/src/wx/po/sv_SE.po b/src/wx/po/sv_SE.po index ab9873877..b739c735f 100644 --- a/src/wx/po/sv_SE.po +++ b/src/wx/po/sv_SE.po @@ -8,10 +8,9 @@ msgstr "" "Project-Id-Version: DVD-o-matic\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-04-07 18:17+0100\n" -"PO-Revision-Date: 2013-04-04 10:18+0100\n" +"PO-Revision-Date: 2013-04-09 10:13+0100\n" "Last-Translator: Adam Klotblixt \n" "Language-Team: \n" -"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -56,7 +55,7 @@ msgstr "Audio Språk (ex. SV)" #: src/wx/film_editor.cc:820 #, c-format msgid "Audio will be resampled from %dHz to %dHz\n" -msgstr "" +msgstr "Audio kommer att samplas om från %dHz till %dHz\n" #: src/wx/job_wrapper.cc:38 #, c-format @@ -126,7 +125,7 @@ msgstr "Skapa i katalog" #: src/wx/film_editor.cc:1363 #, c-format msgid "Cropped to %dx%d (%.2f:1)\n" -msgstr "" +msgstr "Beskuren till %dx%d (%.2f:1)\n" #: src/wx/dci_metadata_dialog.cc:28 msgid "DCI name" @@ -289,7 +288,7 @@ msgstr "Ursprunglig Storlek" #: src/wx/film_editor.cc:1352 #, c-format msgid "Original video is %dx%d (%.2f:1)\n" -msgstr "" +msgstr "Original-videon är %dx%d (%.2f:1)\n" #: src/wx/dci_metadata_dialog.cc:57 msgid "Package Type (e.g. OV)" @@ -298,7 +297,7 @@ msgstr "Förpackningstyp (ex. OV)" #: src/wx/film_editor.cc:1384 #, c-format msgid "Padded with black to %dx%d (%.2f:1)\n" -msgstr "" +msgstr "Svarta kanter tillagda för %dx%d (%.2f:1)\n" #: src/wx/audio_dialog.cc:60 msgid "Peak" @@ -343,7 +342,7 @@ msgstr "Körs" #: src/wx/film_editor.cc:1376 #, c-format msgid "Scaled to %dx%d (%.2f:1)\n" -msgstr "" +msgstr "Skalad till %dx%d (%.2f:1)\n" #: src/wx/film_editor.cc:315 msgid "Scaler" @@ -496,7 +495,7 @@ msgstr "ms" #: src/wx/film_editor.cc:436 msgid "pixels" -msgstr "" +msgstr "pixlar" #. / TRANSLATORS: `s' here is an abbreviation for seconds, the unit of time #: src/wx/film_editor.cc:197 -- cgit v1.2.3 From cc54826d23621e695cbb680d89d313c264090392 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 9 Apr 2013 11:14:10 +0100 Subject: Updated it_IT from Massimiliano. --- src/lib/po/it_IT.po | 174 ++++++++++++++++++++++++++------------------------ src/tools/po/it_IT.po | 25 +++----- src/wx/po/it_IT.po | 69 ++++++-------------- 3 files changed, 119 insertions(+), 149 deletions(-) (limited to 'src') diff --git a/src/lib/po/it_IT.po b/src/lib/po/it_IT.po index 8e9b7166b..aa2129321 100644 --- a/src/lib/po/it_IT.po +++ b/src/lib/po/it_IT.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-07 18:17+0100\n" -"PO-Revision-Date: 2013-03-20 11:45+0100\n" +"POT-Creation-Date: 2013-04-01 21:21+0100\n" +"PO-Revision-Date: 2013-04-03 15:04+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" "Language: Italiano\n" @@ -25,27 +25,27 @@ msgstr "0%" msgid "1.19" msgstr "1.19" -#: src/lib/format.cc:79 +#: src/lib/format.cc:80 msgid "1.33" msgstr "1.33" -#: src/lib/format.cc:83 +#: src/lib/format.cc:85 msgid "1.375" msgstr "1.375" -#: src/lib/format.cc:95 +#: src/lib/format.cc:100 msgid "1.66" msgstr "1.66" -#: src/lib/format.cc:99 +#: src/lib/format.cc:105 msgid "1.66 within Flat" msgstr "1.66 all'interno di Flat" -#: src/lib/format.cc:107 +#: src/lib/format.cc:115 msgid "16:9" msgstr "16:9" -#: src/lib/format.cc:103 +#: src/lib/format.cc:110 msgid "16:9 within Flat" msgstr "16:9 all'interno di Flat" @@ -53,7 +53,7 @@ msgstr "16:9 all'interno di Flat" msgid "3D denoiser" msgstr "Riduttore di rumore 3D" -#: src/lib/format.cc:87 +#: src/lib/format.cc:90 msgid "4:3 within Flat" msgstr "4:3 all'interno di Flat" @@ -61,7 +61,7 @@ msgstr "4:3 all'interno di Flat" msgid "A/B transcode %1" msgstr "Transcodifica A/B %1" -#: src/lib/format.cc:91 +#: src/lib/format.cc:95 msgid "Academy" msgstr "Academy" @@ -91,19 +91,19 @@ msgstr "Bilineare" #: src/lib/job.cc:302 msgid "Cancelled" -msgstr "" +msgstr "Cancellato" #: src/lib/exceptions.cc:60 msgid "Cannot handle pixel format %1 during %2" -msgstr "" +msgstr "Non posso gestire il formato di pixel %1 durante %2" #: src/lib/encoder.cc:101 msgid "Cannot resample audio as libswresample is not present" msgstr "Non posso ricampionare l'audio perchè libswresample non è presente" -#: src/lib/util.cc:932 +#: src/lib/util.cc:931 msgid "Centre" -msgstr "" +msgstr "Centro" #: src/lib/scp_dcp_job.cc:109 msgid "Copy DCP to TMS" @@ -133,16 +133,15 @@ msgstr "Non posso scrivere il file remoto (%1)" msgid "Cubic interpolating deinterlacer" msgstr "Deinterlacciatore cubico interpolato" -#: src/lib/util.cc:1007 +#: src/lib/util.cc:1006 msgid "DCP and source have the same rate.\n" msgstr "Il DCP e il sorgente hanno la stessa frequenza.\n" -#: src/lib/util.cc:1017 -#, fuzzy +#: src/lib/util.cc:1016 msgid "DCP will run at %1%% of the source speed.\n" msgstr "Il DCP andrà al %1%% della velocità del sorgente.\n" -#: src/lib/util.cc:1010 +#: src/lib/util.cc:1009 msgid "DCP will use every other frame of the source.\n" msgstr "Il DCP userà ogni altro fotogramma del sorgente.\n" @@ -165,7 +164,7 @@ msgstr "Filtro deringing" msgid "Dolby CP750" msgstr "Dolby CP750" -#: src/lib/util.cc:1012 +#: src/lib/util.cc:1011 msgid "Each source frame will be doubled in the DCP.\n" msgstr "Ogni fotogramma del sorgente sarà raddoppiato nel DCP.\n" @@ -209,11 +208,11 @@ msgstr "Bilineare rapida" msgid "Feature" msgstr "Caratteristica" -#: src/lib/format.cc:111 +#: src/lib/format.cc:120 msgid "Flat" msgstr "Flat" -#: src/lib/format.cc:119 +#: src/lib/format.cc:130 msgid "Flat without stretch" msgstr "Flat senza stiramento" @@ -257,17 +256,17 @@ msgstr "Deinterlacciatore Kernel" msgid "Lanczos" msgstr "Lanczos" -#: src/lib/util.cc:930 +#: src/lib/util.cc:929 msgid "Left" -msgstr "" +msgstr "Sinistro" -#: src/lib/util.cc:934 +#: src/lib/util.cc:933 msgid "Left surround" -msgstr "" +msgstr "Surround sinistro" -#: src/lib/util.cc:933 +#: src/lib/util.cc:932 msgid "Lfe (sub)" -msgstr "" +msgstr "Lfe(sub)" #: src/lib/filter.cc:75 msgid "Linear blend deinterlacer" @@ -315,27 +314,27 @@ msgstr "Annuncio di pubblico servizio" msgid "Rating" msgstr "Punteggio" -#: src/lib/util.cc:500 +#: src/lib/util.cc:499 msgid "Rec 709" msgstr "Rec 709" -#: src/lib/util.cc:931 +#: src/lib/util.cc:930 msgid "Right" -msgstr "" +msgstr "Destro" -#: src/lib/util.cc:935 +#: src/lib/util.cc:934 msgid "Right surround" -msgstr "" +msgstr "Surround destro" #: src/lib/scp_dcp_job.cc:133 msgid "SSH error (%1)" msgstr "Errore SSH (%1)" -#: src/lib/format.cc:115 +#: src/lib/format.cc:125 msgid "Scope" msgstr "Scope" -#: src/lib/format.cc:123 +#: src/lib/format.cc:135 msgid "Scope without stretch" msgstr "Scope senza stiramento" @@ -347,6 +346,58 @@ msgstr "Corto" msgid "Sinc" msgstr "Sinc" +#: src/lib/format.cc:76 +msgid "Source scaled to 1.19:1" +msgstr "Sorgente scalato a 1.19:1" + +#: src/lib/format.cc:81 +msgid "Source scaled to 1.33:1" +msgstr "Sorgente scalato a 1.33:1" + +#: src/lib/format.cc:91 +msgid "Source scaled to 1.33:1 then pillarboxed to Flat" +msgstr "Sorgente scalato a 1.33:1 e poi inviato come Flat" + +#: src/lib/format.cc:86 +msgid "Source scaled to 1.375:1" +msgstr "Sorgente scalato a 1.375:1" + +#: src/lib/format.cc:96 +msgid "Source scaled to 1.37:1 (Academy ratio)" +msgstr "Sorgente scalato a 1.37:1 (Academy ratio)" + +#: src/lib/format.cc:101 +msgid "Source scaled to 1.66:1" +msgstr "Sorgente scalato a 1.66:1" + +#: src/lib/format.cc:106 +msgid "Source scaled to 1.66:1 then pillarboxed to Flat" +msgstr "Sorgente scalato a 1.66:1 e poi inviato come Flat" + +#: src/lib/format.cc:116 +msgid "Source scaled to 1.78:1" +msgstr "Sorgente scalato a 1.78:1" + +#: src/lib/format.cc:111 +msgid "Source scaled to 1.78:1 then pillarboxed to Flat" +msgstr "Sorgente scalato a 1.78:1 e poi inviato come Flat" + +#: src/lib/format.cc:121 +msgid "Source scaled to Flat (1.85:1)" +msgstr "Sorgente scalato a Flat (1.85:1)" + +#: src/lib/format.cc:126 +msgid "Source scaled to Scope (2.39:1)" +msgstr "Sorgente scalato a Scope (2.39:1)" + +#: src/lib/format.cc:131 +msgid "Source scaled to fit Flat preserving its aspect ratio" +msgstr "Sorgente scalato per adattarsi a Flat mantentendo le sue proporzioni" + +#: src/lib/format.cc:136 +msgid "Source scaled to fit Scope preserving its aspect ratio" +msgstr "Sorgente scalato per adattarsi a Scope mantentendo le sue proporzioni" + #: src/lib/scaler.cc:68 msgid "Spline" msgstr "Spline" @@ -417,13 +468,13 @@ msgstr "X" #: src/lib/filter.cc:83 msgid "Yet Another Deinterlacing Filter" -msgstr "Ancora un altro filtro di deinterlacciamento" +msgstr "Altro filtro di deinterlacciamento" #: src/lib/film.cc:263 msgid "cannot contain slashes" msgstr "non può contenere barre" -#: src/lib/util.cc:541 +#: src/lib/util.cc:540 msgid "connect timed out" msgstr "connessione scaduta" @@ -444,7 +495,6 @@ msgid "copying %1" msgstr "copia %1" #: src/lib/exceptions.cc:36 -#, fuzzy msgid "could not create file %1" msgstr "Non posso scrivere il file remoto (%1)" @@ -469,7 +519,6 @@ msgid "could not open external audio file for reading" msgstr "non riesco ad aprire il file dell'audio esterno per leggerlo" #: src/lib/exceptions.cc:29 -#, fuzzy msgid "could not open file %1" msgstr "non riesco ad aprire il file per leggerlo" @@ -478,7 +527,6 @@ msgid "could not open file for reading" msgstr "non riesco ad aprire il file per leggerlo" #: src/lib/exceptions.cc:44 -#, fuzzy msgid "could not read from file %1 (%2)" msgstr "Non posso creare la directory remota %1 (%2)" @@ -495,7 +543,6 @@ msgid "could not start SSH session" msgstr "non posso avviare la sessione SSH" #: src/lib/exceptions.cc:50 -#, fuzzy msgid "could not write to file %1 (%2)" msgstr "Non posso scrivere il file remoto (%1)" @@ -531,13 +578,13 @@ msgstr "minuto" msgid "minutes" msgstr "minuti" -#: src/lib/util.cc:684 +#: src/lib/util.cc:683 msgid "missing key %1 in key-value set" msgstr "persa la chiave %1 tra i valori chiave" #: src/lib/exceptions.cc:54 msgid "missing required setting %1" -msgstr "" +msgstr "persa la regolazione richiesta %1" #: src/lib/subtitle.cc:52 msgid "multi-part subtitles not yet supported" @@ -561,7 +608,7 @@ msgstr "sottotitoli non-bitmap non ancora supportati" msgid "remaining" msgstr "restano" -#: src/lib/util.cc:498 +#: src/lib/util.cc:497 msgid "sRGB" msgstr "sRGB" @@ -577,47 +624,6 @@ msgstr "ancora" msgid "video" msgstr "video" -#~ msgid "Source scaled to 1.19:1" -#~ msgstr "Sorgente scalato a 1.19:1" - -#~ msgid "Source scaled to 1.33:1" -#~ msgstr "Sorgente scalato a 1.33:1" - -#~ msgid "Source scaled to 1.33:1 then pillarboxed to Flat" -#~ msgstr "Sorgente scalato a 1.33:1 e poi inviato come Flat" - -#~ msgid "Source scaled to 1.375:1" -#~ msgstr "Sorgente scalato a 1.375:1" - -#~ msgid "Source scaled to 1.37:1 (Academy ratio)" -#~ msgstr "Sorgente scalato a 1.37:1 (Academy ratio)" - -#~ msgid "Source scaled to 1.66:1" -#~ msgstr "Sorgente scalato a 1.66:1" - -#~ msgid "Source scaled to 1.66:1 then pillarboxed to Flat" -#~ msgstr "Sorgente scalato a 1.66:1 e poi inviato come Flat" - -#~ msgid "Source scaled to 1.78:1" -#~ msgstr "Sorgente scalato a 1.78:1" - -#~ msgid "Source scaled to 1.78:1 then pillarboxed to Flat" -#~ msgstr "Sorgente scalato a 1.78:1 e poi inviato come Flat" - -#~ msgid "Source scaled to Flat (1.85:1)" -#~ msgstr "Sorgente scalato a Flat (1.85:1)" - -#~ msgid "Source scaled to Scope (2.39:1)" -#~ msgstr "Sorgente scalato a Scope (2.39:1)" - -#~ msgid "Source scaled to fit Flat preserving its aspect ratio" -#~ msgstr "" -#~ "Sorgente scalato per adattarsi a Flat mantentendo le sue proporzioni" - -#~ msgid "Source scaled to fit Scope preserving its aspect ratio" -#~ msgstr "" -#~ "Sorgente scalato per adattarsi a Scope mantentendo le sue proporzioni" - #~ msgid "adding to queue of %1" #~ msgstr "aggiungo alla coda %1" diff --git a/src/tools/po/it_IT.po b/src/tools/po/it_IT.po index 850fd9b1f..02642915c 100644 --- a/src/tools/po/it_IT.po +++ b/src/tools/po/it_IT.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-07 18:17+0100\n" -"PO-Revision-Date: 2013-03-22 18:03+0100\n" +"POT-Creation-Date: 2013-04-01 21:21+0100\n" +"PO-Revision-Date: 2013-04-03 13:00+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" "Language: Italiano\n" @@ -65,7 +65,7 @@ msgstr "&Salva" msgid "&Send DCP to TMS" msgstr "&Invia DCP a TMS" -#: src/tools/dvdomatic.cc:417 +#: src/tools/dvdomatic.cc:409 msgid "" "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" msgstr "" @@ -75,18 +75,17 @@ msgstr "" msgid "About" msgstr "Informazioni" -#: src/tools/dvdomatic.cc:527 -#, fuzzy +#: src/tools/dvdomatic.cc:517 msgid "Could not load film %1 (%2)" msgstr "Non posso caricare il film %s (%s)" -#: src/tools/dvdomatic.cc:339 +#: src/tools/dvdomatic.cc:331 #, c-format msgid "Could not open film at %s (%s)" msgstr "Non posso aprire il film in %s (%s)" -#: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:410 -#: src/tools/dvdomatic.cc:531 +#: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:402 +#: src/tools/dvdomatic.cc:521 msgid "DVD-o-matic" msgstr "DVD-o-matic" @@ -94,7 +93,7 @@ msgstr "DVD-o-matic" msgid "Film changed" msgstr "Film modificato" -#: src/tools/dvdomatic.cc:416 +#: src/tools/dvdomatic.cc:408 msgid "Free, open-source DCP generation from almost anything." msgstr "Genera DCP da quasi tutto, free e open-source." @@ -108,19 +107,13 @@ msgstr "&Mostra DCP" #: src/tools/dvdomatic.cc:74 msgid "Save changes to film \"%1\" before closing?" -msgstr "" +msgstr "Salvare i cambiamenti del film \"%1\" prima di chiudere?" #: src/tools/dvdomatic.cc:319 msgid "Select film to open" msgstr "Seleziona il film da aprire" #: src/tools/dvdomatic.cc:303 -#, fuzzy msgid "The directory %1 already exists." msgstr "La directory %s esiste gia'." -#: src/tools/dvdomatic.cc:324 -msgid "" -"You did not select a folder. Make sure that you select a folder before " -"clicking Open." -msgstr "" diff --git a/src/wx/po/it_IT.po b/src/wx/po/it_IT.po index 9a0f13d2e..b98db3482 100644 --- a/src/wx/po/it_IT.po +++ b/src/wx/po/it_IT.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-07 18:17+0100\n" -"PO-Revision-Date: 2013-03-22 18:10+0100\n" +"POT-Creation-Date: 2013-04-01 21:21+0100\n" +"PO-Revision-Date: 2013-04-03 12:37+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" "Language: Italiano\n" @@ -17,15 +17,15 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" -#: src/wx/film_editor.cc:445 +#: src/wx/film_editor.cc:440 msgid "%" msgstr "%" #: src/wx/config_dialog.cc:61 msgid "(restart DVD-o-matic to see language changes)" -msgstr "" +msgstr "(riavviare DVD-o-matic per vedere i cambiamenti di lingua)" -#: src/wx/film_editor.cc:1269 +#: src/wx/film_editor.cc:1231 msgid "1 channel" msgstr "Canale 1" @@ -53,17 +53,12 @@ msgstr "Guadagno dell'audio" msgid "Audio Language (e.g. EN)" msgstr "Lingua dell'audio (es. EN)" -#: src/wx/film_editor.cc:820 -#, c-format -msgid "Audio will be resampled from %dHz to %dHz\n" -msgstr "" - #: src/wx/job_wrapper.cc:38 #, c-format msgid "Bad setting for %s (%s)" msgstr "Valore sbagliato per %s (%s)" -#: src/wx/film_editor.cc:288 +#: src/wx/film_editor.cc:296 msgid "Bottom crop" msgstr "Taglio in basso" @@ -81,7 +76,7 @@ msgstr "Calcola..." #: src/wx/job_manager_view.cc:88 msgid "Cancel" -msgstr "" +msgstr "Annulla" #: src/wx/audio_dialog.cc:43 msgid "Channels" @@ -99,7 +94,7 @@ msgstr "Contenuto" msgid "Content Type" msgstr "Tipo di contenuto" -#: src/wx/film_viewer.cc:415 +#: src/wx/film_viewer.cc:414 #, c-format msgid "Could not decode video for view (%s)" msgstr "Non posso decodificare il video per guardarlo (%s)" @@ -109,12 +104,12 @@ msgstr "Non posso decodificare il video per guardarlo (%s)" msgid "Could not make DCP: %s" msgstr "Non posso creare il DCP: %s" -#: src/wx/film_viewer.cc:107 +#: src/wx/film_viewer.cc:108 #, c-format msgid "Could not open content file (%s)" msgstr "Non posso aprire il file del contenuto (%s)" -#: src/wx/film_editor.cc:509 +#: src/wx/film_editor.cc:504 #, c-format msgid "Could not set content: %s" msgstr "Non posso regolare il contenuto: %s" @@ -123,11 +118,6 @@ msgstr "Non posso regolare il contenuto: %s" msgid "Create in folder" msgstr "Crea nella cartella" -#: src/wx/film_editor.cc:1363 -#, c-format -msgid "Cropped to %dx%d (%.2f:1)\n" -msgstr "" - #: src/wx/dci_metadata_dialog.cc:28 msgid "DCI name" msgstr "Nome del DCP" @@ -234,7 +224,7 @@ msgstr "Gb" msgid "Host name or IP address" msgstr "Nome dell'Host o indirizzo IP" -#: src/wx/film_editor.cc:1273 +#: src/wx/film_editor.cc:1235 msgid "Hz" msgstr "Hz" @@ -250,7 +240,7 @@ msgstr "Indirizzo IP" msgid "JPEG2000 bandwidth" msgstr "Banda passante JPEG2000" -#: src/wx/film_editor.cc:273 +#: src/wx/film_editor.cc:281 msgid "Left crop" msgstr "Taglio a sinistra" @@ -274,7 +264,7 @@ msgstr "Nome" msgid "New Film" msgstr "Nuovo Film" -#: src/wx/film_editor.cc:305 src/wx/film_editor.cc:667 +#: src/wx/film_editor.cc:305 src/wx/film_editor.cc:664 msgid "None" msgstr "Nessuno" @@ -286,20 +276,10 @@ msgstr "Frequenza fotogrammi originale" msgid "Original Size" msgstr "Dimensione Originale" -#: src/wx/film_editor.cc:1352 -#, c-format -msgid "Original video is %dx%d (%.2f:1)\n" -msgstr "" - #: src/wx/dci_metadata_dialog.cc:57 msgid "Package Type (e.g. OV)" msgstr "Tipo di Package (es. OV)" -#: src/wx/film_editor.cc:1384 -#, c-format -msgid "Padded with black to %dx%d (%.2f:1)\n" -msgstr "" - #: src/wx/audio_dialog.cc:60 msgid "Peak" msgstr "Picco" @@ -332,7 +312,7 @@ msgstr "Scalatura di riferimento A/B" msgid "Remove" msgstr "Rimuovi" -#: src/wx/film_editor.cc:278 +#: src/wx/film_editor.cc:286 msgid "Right crop" msgstr "Taglio a destra" @@ -340,11 +320,6 @@ msgstr "Taglio a destra" msgid "Running" msgstr "In corso" -#: src/wx/film_editor.cc:1376 -#, c-format -msgid "Scaled to %dx%d (%.2f:1)\n" -msgstr "" - #: src/wx/film_editor.cc:315 msgid "Scaler" msgstr "Scaler" @@ -363,7 +338,7 @@ msgstr "Server" #: src/wx/config_dialog.cc:49 msgid "Set language" -msgstr "" +msgstr "Seleziona la lingua" #: src/wx/film_editor.cc:364 msgid "Show Audio..." @@ -385,11 +360,11 @@ msgstr "Studio (es. TCF)" msgid "Subtitle Language (e.g. FR)" msgstr "Lingua dei Sottotitoli (es. FR)" -#: src/wx/film_editor.cc:432 +#: src/wx/film_editor.cc:431 msgid "Subtitle Offset" msgstr "Sfalsamento dei Sottotitoli" -#: src/wx/film_editor.cc:441 +#: src/wx/film_editor.cc:436 msgid "Subtitle Scale" msgstr "Scala dei Sottotitoli" @@ -433,7 +408,7 @@ msgstr "Threads da usare per codificare su questo host" msgid "Time" msgstr "Tempo" -#: src/wx/film_editor.cc:283 +#: src/wx/film_editor.cc:291 msgid "Top crop" msgstr "Taglio in alto" @@ -473,7 +448,7 @@ msgstr "Video" msgid "With Subtitles" msgstr "Con Sottotitoli" -#: src/wx/film_editor.cc:1271 +#: src/wx/film_editor.cc:1233 msgid "channels" msgstr "canali" @@ -485,7 +460,7 @@ msgstr "conteggio..." msgid "dB" msgstr "dB" -#: src/wx/film_editor.cc:696 src/wx/film_editor.cc:699 +#: src/wx/film_editor.cc:691 src/wx/film_editor.cc:694 msgid "frames" msgstr "fotogrammi" @@ -494,10 +469,6 @@ msgstr "fotogrammi" msgid "ms" msgstr "ms" -#: src/wx/film_editor.cc:436 -msgid "pixels" -msgstr "" - #. / TRANSLATORS: `s' here is an abbreviation for seconds, the unit of time #: src/wx/film_editor.cc:197 msgid "s" -- cgit v1.2.3 From 9d1084c6f728efa3b5a23c968320d8d86b232b40 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 9 Apr 2013 11:14:24 +0100 Subject: Merge pot files. --- src/lib/po/es_ES.po | 13 +++-- src/lib/po/fr_FR.po | 13 +++-- src/lib/po/it_IT.po | 152 ++++++++++++++++++++++++-------------------------- src/lib/po/sv_SE.po | 14 +++-- src/tools/po/es_ES.po | 2 +- src/tools/po/fr_FR.po | 2 +- src/tools/po/it_IT.po | 19 ++++--- src/tools/po/sv_SE.po | 3 +- src/wx/po/es_ES.po | 2 +- src/wx/po/fr_FR.po | 2 +- src/wx/po/it_IT.po | 61 ++++++++++++++------ src/wx/po/sv_SE.po | 3 +- 12 files changed, 166 insertions(+), 120 deletions(-) (limited to 'src') diff --git a/src/lib/po/es_ES.po b/src/lib/po/es_ES.po index 8f6a06563..17051bd98 100644 --- a/src/lib/po/es_ES.po +++ b/src/lib/po/es_ES.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: LIBDVDOMATIC\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-07 18:17+0100\n" +"POT-Creation-Date: 2013-04-09 11:14+0100\n" "PO-Revision-Date: 2013-04-02 19:10-0500\n" "Last-Translator: Manuel AC \n" "Language-Team: Manuel AC \n" @@ -49,6 +49,11 @@ msgstr "16:9" msgid "16:9 within Flat" msgstr "16:9 en Flat" +#: src/lib/format.cc:115 +#, fuzzy +msgid "16:9 within Scope" +msgstr "16:9 en Flat" + #: src/lib/filter.cc:88 msgid "3D denoiser" msgstr "reducción de ruido 3D" @@ -214,7 +219,7 @@ msgstr "Película" msgid "Flat" msgstr "Flat" -#: src/lib/format.cc:119 +#: src/lib/format.cc:123 msgid "Flat without stretch" msgstr "Flat sin deformación" @@ -332,11 +337,11 @@ msgstr "" msgid "SSH error (%1)" msgstr "error SSH (%1)" -#: src/lib/format.cc:115 +#: src/lib/format.cc:119 msgid "Scope" msgstr "Scope" -#: src/lib/format.cc:123 +#: src/lib/format.cc:127 msgid "Scope without stretch" msgstr "Scope sin deformación" diff --git a/src/lib/po/fr_FR.po b/src/lib/po/fr_FR.po index b9c382c0a..d9d945b52 100644 --- a/src/lib/po/fr_FR.po +++ b/src/lib/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-07 18:17+0100\n" +"POT-Creation-Date: 2013-04-09 11:14+0100\n" "PO-Revision-Date: 2013-03-20 00:39+0100\n" "Last-Translator: FreeDCP.net \n" "Language-Team: \n" @@ -48,6 +48,11 @@ msgstr "16:9" msgid "16:9 within Flat" msgstr "16:9 dans Flat" +#: src/lib/format.cc:115 +#, fuzzy +msgid "16:9 within Scope" +msgstr "16:9 dans Flat" + #: src/lib/filter.cc:88 msgid "3D denoiser" msgstr "Débruitage 3D" @@ -212,7 +217,7 @@ msgstr "Feature" msgid "Flat" msgstr "Flat" -#: src/lib/format.cc:119 +#: src/lib/format.cc:123 msgid "Flat without stretch" msgstr "Flat sans déformation" @@ -330,11 +335,11 @@ msgstr "Arrière droite" msgid "SSH error (%1)" msgstr "Erreur SSH (%1)" -#: src/lib/format.cc:115 +#: src/lib/format.cc:119 msgid "Scope" msgstr "Scope" -#: src/lib/format.cc:123 +#: src/lib/format.cc:127 msgid "Scope without stretch" msgstr "Scope sans déformation" diff --git a/src/lib/po/it_IT.po b/src/lib/po/it_IT.po index aa2129321..992eda107 100644 --- a/src/lib/po/it_IT.po +++ b/src/lib/po/it_IT.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-01 21:21+0100\n" +"POT-Creation-Date: 2013-04-09 11:14+0100\n" "PO-Revision-Date: 2013-04-03 15:04+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" @@ -25,35 +25,40 @@ msgstr "0%" msgid "1.19" msgstr "1.19" -#: src/lib/format.cc:80 +#: src/lib/format.cc:79 msgid "1.33" msgstr "1.33" -#: src/lib/format.cc:85 +#: src/lib/format.cc:83 msgid "1.375" msgstr "1.375" -#: src/lib/format.cc:100 +#: src/lib/format.cc:95 msgid "1.66" msgstr "1.66" -#: src/lib/format.cc:105 +#: src/lib/format.cc:99 msgid "1.66 within Flat" msgstr "1.66 all'interno di Flat" -#: src/lib/format.cc:115 +#: src/lib/format.cc:107 msgid "16:9" msgstr "16:9" -#: src/lib/format.cc:110 +#: src/lib/format.cc:103 msgid "16:9 within Flat" msgstr "16:9 all'interno di Flat" +#: src/lib/format.cc:115 +#, fuzzy +msgid "16:9 within Scope" +msgstr "16:9 all'interno di Flat" + #: src/lib/filter.cc:88 msgid "3D denoiser" msgstr "Riduttore di rumore 3D" -#: src/lib/format.cc:90 +#: src/lib/format.cc:87 msgid "4:3 within Flat" msgstr "4:3 all'interno di Flat" @@ -61,7 +66,7 @@ msgstr "4:3 all'interno di Flat" msgid "A/B transcode %1" msgstr "Transcodifica A/B %1" -#: src/lib/format.cc:95 +#: src/lib/format.cc:91 msgid "Academy" msgstr "Academy" @@ -101,7 +106,7 @@ msgstr "Non posso gestire il formato di pixel %1 durante %2" msgid "Cannot resample audio as libswresample is not present" msgstr "Non posso ricampionare l'audio perchè libswresample non è presente" -#: src/lib/util.cc:931 +#: src/lib/util.cc:932 msgid "Centre" msgstr "Centro" @@ -133,15 +138,15 @@ msgstr "Non posso scrivere il file remoto (%1)" msgid "Cubic interpolating deinterlacer" msgstr "Deinterlacciatore cubico interpolato" -#: src/lib/util.cc:1006 +#: src/lib/util.cc:1007 msgid "DCP and source have the same rate.\n" msgstr "Il DCP e il sorgente hanno la stessa frequenza.\n" -#: src/lib/util.cc:1016 +#: src/lib/util.cc:1017 msgid "DCP will run at %1%% of the source speed.\n" msgstr "Il DCP andrà al %1%% della velocità del sorgente.\n" -#: src/lib/util.cc:1009 +#: src/lib/util.cc:1010 msgid "DCP will use every other frame of the source.\n" msgstr "Il DCP userà ogni altro fotogramma del sorgente.\n" @@ -164,7 +169,7 @@ msgstr "Filtro deringing" msgid "Dolby CP750" msgstr "Dolby CP750" -#: src/lib/util.cc:1011 +#: src/lib/util.cc:1012 msgid "Each source frame will be doubled in the DCP.\n" msgstr "Ogni fotogramma del sorgente sarà raddoppiato nel DCP.\n" @@ -208,11 +213,11 @@ msgstr "Bilineare rapida" msgid "Feature" msgstr "Caratteristica" -#: src/lib/format.cc:120 +#: src/lib/format.cc:111 msgid "Flat" msgstr "Flat" -#: src/lib/format.cc:130 +#: src/lib/format.cc:123 msgid "Flat without stretch" msgstr "Flat senza stiramento" @@ -256,15 +261,15 @@ msgstr "Deinterlacciatore Kernel" msgid "Lanczos" msgstr "Lanczos" -#: src/lib/util.cc:929 +#: src/lib/util.cc:930 msgid "Left" msgstr "Sinistro" -#: src/lib/util.cc:933 +#: src/lib/util.cc:934 msgid "Left surround" msgstr "Surround sinistro" -#: src/lib/util.cc:932 +#: src/lib/util.cc:933 msgid "Lfe (sub)" msgstr "Lfe(sub)" @@ -314,15 +319,15 @@ msgstr "Annuncio di pubblico servizio" msgid "Rating" msgstr "Punteggio" -#: src/lib/util.cc:499 +#: src/lib/util.cc:500 msgid "Rec 709" msgstr "Rec 709" -#: src/lib/util.cc:930 +#: src/lib/util.cc:931 msgid "Right" msgstr "Destro" -#: src/lib/util.cc:934 +#: src/lib/util.cc:935 msgid "Right surround" msgstr "Surround destro" @@ -330,11 +335,11 @@ msgstr "Surround destro" msgid "SSH error (%1)" msgstr "Errore SSH (%1)" -#: src/lib/format.cc:125 +#: src/lib/format.cc:119 msgid "Scope" msgstr "Scope" -#: src/lib/format.cc:135 +#: src/lib/format.cc:127 msgid "Scope without stretch" msgstr "Scope senza stiramento" @@ -346,58 +351,6 @@ msgstr "Corto" msgid "Sinc" msgstr "Sinc" -#: src/lib/format.cc:76 -msgid "Source scaled to 1.19:1" -msgstr "Sorgente scalato a 1.19:1" - -#: src/lib/format.cc:81 -msgid "Source scaled to 1.33:1" -msgstr "Sorgente scalato a 1.33:1" - -#: src/lib/format.cc:91 -msgid "Source scaled to 1.33:1 then pillarboxed to Flat" -msgstr "Sorgente scalato a 1.33:1 e poi inviato come Flat" - -#: src/lib/format.cc:86 -msgid "Source scaled to 1.375:1" -msgstr "Sorgente scalato a 1.375:1" - -#: src/lib/format.cc:96 -msgid "Source scaled to 1.37:1 (Academy ratio)" -msgstr "Sorgente scalato a 1.37:1 (Academy ratio)" - -#: src/lib/format.cc:101 -msgid "Source scaled to 1.66:1" -msgstr "Sorgente scalato a 1.66:1" - -#: src/lib/format.cc:106 -msgid "Source scaled to 1.66:1 then pillarboxed to Flat" -msgstr "Sorgente scalato a 1.66:1 e poi inviato come Flat" - -#: src/lib/format.cc:116 -msgid "Source scaled to 1.78:1" -msgstr "Sorgente scalato a 1.78:1" - -#: src/lib/format.cc:111 -msgid "Source scaled to 1.78:1 then pillarboxed to Flat" -msgstr "Sorgente scalato a 1.78:1 e poi inviato come Flat" - -#: src/lib/format.cc:121 -msgid "Source scaled to Flat (1.85:1)" -msgstr "Sorgente scalato a Flat (1.85:1)" - -#: src/lib/format.cc:126 -msgid "Source scaled to Scope (2.39:1)" -msgstr "Sorgente scalato a Scope (2.39:1)" - -#: src/lib/format.cc:131 -msgid "Source scaled to fit Flat preserving its aspect ratio" -msgstr "Sorgente scalato per adattarsi a Flat mantentendo le sue proporzioni" - -#: src/lib/format.cc:136 -msgid "Source scaled to fit Scope preserving its aspect ratio" -msgstr "Sorgente scalato per adattarsi a Scope mantentendo le sue proporzioni" - #: src/lib/scaler.cc:68 msgid "Spline" msgstr "Spline" @@ -474,7 +427,7 @@ msgstr "Altro filtro di deinterlacciamento" msgid "cannot contain slashes" msgstr "non può contenere barre" -#: src/lib/util.cc:540 +#: src/lib/util.cc:541 msgid "connect timed out" msgstr "connessione scaduta" @@ -578,7 +531,7 @@ msgstr "minuto" msgid "minutes" msgstr "minuti" -#: src/lib/util.cc:683 +#: src/lib/util.cc:684 msgid "missing key %1 in key-value set" msgstr "persa la chiave %1 tra i valori chiave" @@ -608,7 +561,7 @@ msgstr "sottotitoli non-bitmap non ancora supportati" msgid "remaining" msgstr "restano" -#: src/lib/util.cc:497 +#: src/lib/util.cc:498 msgid "sRGB" msgstr "sRGB" @@ -624,6 +577,47 @@ msgstr "ancora" msgid "video" msgstr "video" +#~ msgid "Source scaled to 1.19:1" +#~ msgstr "Sorgente scalato a 1.19:1" + +#~ msgid "Source scaled to 1.33:1" +#~ msgstr "Sorgente scalato a 1.33:1" + +#~ msgid "Source scaled to 1.33:1 then pillarboxed to Flat" +#~ msgstr "Sorgente scalato a 1.33:1 e poi inviato come Flat" + +#~ msgid "Source scaled to 1.375:1" +#~ msgstr "Sorgente scalato a 1.375:1" + +#~ msgid "Source scaled to 1.37:1 (Academy ratio)" +#~ msgstr "Sorgente scalato a 1.37:1 (Academy ratio)" + +#~ msgid "Source scaled to 1.66:1" +#~ msgstr "Sorgente scalato a 1.66:1" + +#~ msgid "Source scaled to 1.66:1 then pillarboxed to Flat" +#~ msgstr "Sorgente scalato a 1.66:1 e poi inviato come Flat" + +#~ msgid "Source scaled to 1.78:1" +#~ msgstr "Sorgente scalato a 1.78:1" + +#~ msgid "Source scaled to 1.78:1 then pillarboxed to Flat" +#~ msgstr "Sorgente scalato a 1.78:1 e poi inviato come Flat" + +#~ msgid "Source scaled to Flat (1.85:1)" +#~ msgstr "Sorgente scalato a Flat (1.85:1)" + +#~ msgid "Source scaled to Scope (2.39:1)" +#~ msgstr "Sorgente scalato a Scope (2.39:1)" + +#~ msgid "Source scaled to fit Flat preserving its aspect ratio" +#~ msgstr "" +#~ "Sorgente scalato per adattarsi a Flat mantentendo le sue proporzioni" + +#~ msgid "Source scaled to fit Scope preserving its aspect ratio" +#~ msgstr "" +#~ "Sorgente scalato per adattarsi a Scope mantentendo le sue proporzioni" + #~ msgid "adding to queue of %1" #~ msgstr "aggiungo alla coda %1" diff --git a/src/lib/po/sv_SE.po b/src/lib/po/sv_SE.po index b79d9d652..d574261c8 100644 --- a/src/lib/po/sv_SE.po +++ b/src/lib/po/sv_SE.po @@ -7,10 +7,11 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-07 18:17+0100\n" +"POT-Creation-Date: 2013-04-09 11:14+0100\n" "PO-Revision-Date: 2013-04-09 10:13+0100\n" "Last-Translator: Adam Klotblixt \n" "Language-Team: \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -48,6 +49,11 @@ msgstr "16:9" msgid "16:9 within Flat" msgstr "16:9 innanför Flat" +#: src/lib/format.cc:115 +#, fuzzy +msgid "16:9 within Scope" +msgstr "16:9 innanför Flat" + #: src/lib/filter.cc:88 msgid "3D denoiser" msgstr "3D brusreducering" @@ -212,7 +218,7 @@ msgstr "Långfilm" msgid "Flat" msgstr "Flat" -#: src/lib/format.cc:119 +#: src/lib/format.cc:123 msgid "Flat without stretch" msgstr "Flat utan utsträckning" @@ -330,11 +336,11 @@ msgstr "Höger surround" msgid "SSH error (%1)" msgstr "SSH fel (%1)" -#: src/lib/format.cc:115 +#: src/lib/format.cc:119 msgid "Scope" msgstr "Scope" -#: src/lib/format.cc:123 +#: src/lib/format.cc:127 msgid "Scope without stretch" msgstr "Scope utan utsträckning" diff --git a/src/tools/po/es_ES.po b/src/tools/po/es_ES.po index 4a3710eb8..1ab1a8489 100644 --- a/src/tools/po/es_ES.po +++ b/src/tools/po/es_ES.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVDOMATIC\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-07 18:17+0100\n" +"POT-Creation-Date: 2013-04-09 11:14+0100\n" "PO-Revision-Date: 2013-03-23 21:08-0500\n" "Last-Translator: Manuel AC \n" "Language-Team: Manuel AC \n" diff --git a/src/tools/po/fr_FR.po b/src/tools/po/fr_FR.po index 3c4cc79c5..35e686f67 100644 --- a/src/tools/po/fr_FR.po +++ b/src/tools/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-07 18:17+0100\n" +"POT-Creation-Date: 2013-04-09 11:14+0100\n" "PO-Revision-Date: 2013-03-13 22:33+0100\n" "Last-Translator: \n" "Language-Team: \n" diff --git a/src/tools/po/it_IT.po b/src/tools/po/it_IT.po index 02642915c..09e3f5f34 100644 --- a/src/tools/po/it_IT.po +++ b/src/tools/po/it_IT.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-01 21:21+0100\n" +"POT-Creation-Date: 2013-04-09 11:14+0100\n" "PO-Revision-Date: 2013-04-03 13:00+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" @@ -65,7 +65,7 @@ msgstr "&Salva" msgid "&Send DCP to TMS" msgstr "&Invia DCP a TMS" -#: src/tools/dvdomatic.cc:409 +#: src/tools/dvdomatic.cc:417 msgid "" "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" msgstr "" @@ -75,17 +75,17 @@ msgstr "" msgid "About" msgstr "Informazioni" -#: src/tools/dvdomatic.cc:517 +#: src/tools/dvdomatic.cc:527 msgid "Could not load film %1 (%2)" msgstr "Non posso caricare il film %s (%s)" -#: src/tools/dvdomatic.cc:331 +#: src/tools/dvdomatic.cc:339 #, c-format msgid "Could not open film at %s (%s)" msgstr "Non posso aprire il film in %s (%s)" -#: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:402 -#: src/tools/dvdomatic.cc:521 +#: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:410 +#: src/tools/dvdomatic.cc:531 msgid "DVD-o-matic" msgstr "DVD-o-matic" @@ -93,7 +93,7 @@ msgstr "DVD-o-matic" msgid "Film changed" msgstr "Film modificato" -#: src/tools/dvdomatic.cc:408 +#: src/tools/dvdomatic.cc:416 msgid "Free, open-source DCP generation from almost anything." msgstr "Genera DCP da quasi tutto, free e open-source." @@ -117,3 +117,8 @@ msgstr "Seleziona il film da aprire" msgid "The directory %1 already exists." msgstr "La directory %s esiste gia'." +#: src/tools/dvdomatic.cc:324 +msgid "" +"You did not select a folder. Make sure that you select a folder before " +"clicking Open." +msgstr "" diff --git a/src/tools/po/sv_SE.po b/src/tools/po/sv_SE.po index a5a4be9fe..28566d876 100644 --- a/src/tools/po/sv_SE.po +++ b/src/tools/po/sv_SE.po @@ -7,10 +7,11 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-07 18:17+0100\n" +"POT-Creation-Date: 2013-04-09 11:14+0100\n" "PO-Revision-Date: 2013-04-09 10:12+0100\n" "Last-Translator: Adam Klotblixt \n" "Language-Team: \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" diff --git a/src/wx/po/es_ES.po b/src/wx/po/es_ES.po index 9f96fceff..207708589 100644 --- a/src/wx/po/es_ES.po +++ b/src/wx/po/es_ES.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: libdvdomatic-wx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-07 18:17+0100\n" +"POT-Creation-Date: 2013-04-09 11:14+0100\n" "PO-Revision-Date: 2013-04-02 19:08-0500\n" "Last-Translator: Manuel AC \n" "Language-Team: Manuel AC \n" diff --git a/src/wx/po/fr_FR.po b/src/wx/po/fr_FR.po index 37cd6d8ab..80ee5dbfd 100644 --- a/src/wx/po/fr_FR.po +++ b/src/wx/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-07 18:17+0100\n" +"POT-Creation-Date: 2013-04-09 11:14+0100\n" "PO-Revision-Date: 2013-03-20 00:34+0100\n" "Last-Translator: FreeDCP.net \n" "Language-Team: \n" diff --git a/src/wx/po/it_IT.po b/src/wx/po/it_IT.po index b98db3482..78fd0dee9 100644 --- a/src/wx/po/it_IT.po +++ b/src/wx/po/it_IT.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-01 21:21+0100\n" +"POT-Creation-Date: 2013-04-09 11:14+0100\n" "PO-Revision-Date: 2013-04-03 12:37+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" @@ -17,7 +17,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" -#: src/wx/film_editor.cc:440 +#: src/wx/film_editor.cc:445 msgid "%" msgstr "%" @@ -25,7 +25,7 @@ msgstr "%" msgid "(restart DVD-o-matic to see language changes)" msgstr "(riavviare DVD-o-matic per vedere i cambiamenti di lingua)" -#: src/wx/film_editor.cc:1231 +#: src/wx/film_editor.cc:1269 msgid "1 channel" msgstr "Canale 1" @@ -53,12 +53,17 @@ msgstr "Guadagno dell'audio" msgid "Audio Language (e.g. EN)" msgstr "Lingua dell'audio (es. EN)" +#: src/wx/film_editor.cc:820 +#, c-format +msgid "Audio will be resampled from %dHz to %dHz\n" +msgstr "" + #: src/wx/job_wrapper.cc:38 #, c-format msgid "Bad setting for %s (%s)" msgstr "Valore sbagliato per %s (%s)" -#: src/wx/film_editor.cc:296 +#: src/wx/film_editor.cc:288 msgid "Bottom crop" msgstr "Taglio in basso" @@ -94,7 +99,7 @@ msgstr "Contenuto" msgid "Content Type" msgstr "Tipo di contenuto" -#: src/wx/film_viewer.cc:414 +#: src/wx/film_viewer.cc:415 #, c-format msgid "Could not decode video for view (%s)" msgstr "Non posso decodificare il video per guardarlo (%s)" @@ -104,12 +109,12 @@ msgstr "Non posso decodificare il video per guardarlo (%s)" msgid "Could not make DCP: %s" msgstr "Non posso creare il DCP: %s" -#: src/wx/film_viewer.cc:108 +#: src/wx/film_viewer.cc:107 #, c-format msgid "Could not open content file (%s)" msgstr "Non posso aprire il file del contenuto (%s)" -#: src/wx/film_editor.cc:504 +#: src/wx/film_editor.cc:509 #, c-format msgid "Could not set content: %s" msgstr "Non posso regolare il contenuto: %s" @@ -118,6 +123,11 @@ msgstr "Non posso regolare il contenuto: %s" msgid "Create in folder" msgstr "Crea nella cartella" +#: src/wx/film_editor.cc:1363 +#, c-format +msgid "Cropped to %dx%d (%.2f:1)\n" +msgstr "" + #: src/wx/dci_metadata_dialog.cc:28 msgid "DCI name" msgstr "Nome del DCP" @@ -224,7 +234,7 @@ msgstr "Gb" msgid "Host name or IP address" msgstr "Nome dell'Host o indirizzo IP" -#: src/wx/film_editor.cc:1235 +#: src/wx/film_editor.cc:1273 msgid "Hz" msgstr "Hz" @@ -240,7 +250,7 @@ msgstr "Indirizzo IP" msgid "JPEG2000 bandwidth" msgstr "Banda passante JPEG2000" -#: src/wx/film_editor.cc:281 +#: src/wx/film_editor.cc:273 msgid "Left crop" msgstr "Taglio a sinistra" @@ -264,7 +274,7 @@ msgstr "Nome" msgid "New Film" msgstr "Nuovo Film" -#: src/wx/film_editor.cc:305 src/wx/film_editor.cc:664 +#: src/wx/film_editor.cc:305 src/wx/film_editor.cc:667 msgid "None" msgstr "Nessuno" @@ -276,10 +286,20 @@ msgstr "Frequenza fotogrammi originale" msgid "Original Size" msgstr "Dimensione Originale" +#: src/wx/film_editor.cc:1352 +#, c-format +msgid "Original video is %dx%d (%.2f:1)\n" +msgstr "" + #: src/wx/dci_metadata_dialog.cc:57 msgid "Package Type (e.g. OV)" msgstr "Tipo di Package (es. OV)" +#: src/wx/film_editor.cc:1384 +#, c-format +msgid "Padded with black to %dx%d (%.2f:1)\n" +msgstr "" + #: src/wx/audio_dialog.cc:60 msgid "Peak" msgstr "Picco" @@ -312,7 +332,7 @@ msgstr "Scalatura di riferimento A/B" msgid "Remove" msgstr "Rimuovi" -#: src/wx/film_editor.cc:286 +#: src/wx/film_editor.cc:278 msgid "Right crop" msgstr "Taglio a destra" @@ -320,6 +340,11 @@ msgstr "Taglio a destra" msgid "Running" msgstr "In corso" +#: src/wx/film_editor.cc:1376 +#, c-format +msgid "Scaled to %dx%d (%.2f:1)\n" +msgstr "" + #: src/wx/film_editor.cc:315 msgid "Scaler" msgstr "Scaler" @@ -360,11 +385,11 @@ msgstr "Studio (es. TCF)" msgid "Subtitle Language (e.g. FR)" msgstr "Lingua dei Sottotitoli (es. FR)" -#: src/wx/film_editor.cc:431 +#: src/wx/film_editor.cc:432 msgid "Subtitle Offset" msgstr "Sfalsamento dei Sottotitoli" -#: src/wx/film_editor.cc:436 +#: src/wx/film_editor.cc:441 msgid "Subtitle Scale" msgstr "Scala dei Sottotitoli" @@ -408,7 +433,7 @@ msgstr "Threads da usare per codificare su questo host" msgid "Time" msgstr "Tempo" -#: src/wx/film_editor.cc:291 +#: src/wx/film_editor.cc:283 msgid "Top crop" msgstr "Taglio in alto" @@ -448,7 +473,7 @@ msgstr "Video" msgid "With Subtitles" msgstr "Con Sottotitoli" -#: src/wx/film_editor.cc:1233 +#: src/wx/film_editor.cc:1271 msgid "channels" msgstr "canali" @@ -460,7 +485,7 @@ msgstr "conteggio..." msgid "dB" msgstr "dB" -#: src/wx/film_editor.cc:691 src/wx/film_editor.cc:694 +#: src/wx/film_editor.cc:696 src/wx/film_editor.cc:699 msgid "frames" msgstr "fotogrammi" @@ -469,6 +494,10 @@ msgstr "fotogrammi" msgid "ms" msgstr "ms" +#: src/wx/film_editor.cc:436 +msgid "pixels" +msgstr "" + #. / TRANSLATORS: `s' here is an abbreviation for seconds, the unit of time #: src/wx/film_editor.cc:197 msgid "s" diff --git a/src/wx/po/sv_SE.po b/src/wx/po/sv_SE.po index b739c735f..e52589ff0 100644 --- a/src/wx/po/sv_SE.po +++ b/src/wx/po/sv_SE.po @@ -7,10 +7,11 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-07 18:17+0100\n" +"POT-Creation-Date: 2013-04-09 11:14+0100\n" "PO-Revision-Date: 2013-04-09 10:13+0100\n" "Last-Translator: Adam Klotblixt \n" "Language-Team: \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -- cgit v1.2.3 From d7a166924028262ab307bb622da1dc85f127f944 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 9 Apr 2013 21:48:41 +0100 Subject: Fix NaN on creating a new film. --- src/wx/film_editor.cc | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 5e597ac30..d0136cfba 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -1348,13 +1348,14 @@ FilmEditor::setup_scaling_description () int lines = 0; - d << wxString::Format ( - _("Original video is %dx%d (%.2f:1)\n"), - _film->size().width, _film->size().height, - float (_film->size().width) / _film->size().height - ); - - ++lines; + if (_film->size().width && _film->size().height) { + d << wxString::Format ( + _("Original video is %dx%d (%.2f:1)\n"), + _film->size().width, _film->size().height, + float (_film->size().width) / _film->size().height + ); + ++lines; + } Crop const crop = _film->crop (); if (crop.left || crop.right || crop.top || crop.bottom) { -- cgit v1.2.3 From 767f88cb1f90fdd359e7e4e4bdf90e848d57995c Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 9 Apr 2013 23:40:36 +0100 Subject: Fix formatting a little. --- src/wx/film_editor.cc | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index d0136cfba..62eecb70c 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -148,7 +148,7 @@ FilmEditor::make_film_panel () } ++r; - _frame_rate_description = new wxStaticText (_film_panel, wxID_ANY, wxT (" \n \n "), wxDefaultPosition, wxDefaultSize); + _frame_rate_description = new wxStaticText (_film_panel, wxID_ANY, wxT ("\n \n "), wxDefaultPosition, wxDefaultSize); grid->Add (video_control (_frame_rate_description), wxGBPosition (r, 0), wxGBSpan (1, 2), wxEXPAND | wxALIGN_CENTER_VERTICAL | wxALL, 6); wxFont font = _frame_rate_description->GetFont(); font.SetStyle(wxFONTSTYLE_ITALIC); @@ -812,8 +812,11 @@ void FilmEditor::setup_frame_rate_description () { wxString d; + int lines = 0; + if (_film->source_frame_rate()) { d << std_to_wx (FrameRateConversion (_film->source_frame_rate(), _film->dcp_frame_rate()).description); + ++lines; #ifdef HAVE_SWRESAMPLE if (_film->audio_stream() && _film->audio_stream()->sample_rate() != _film->target_audio_sample_rate ()) { d << wxString::Format ( @@ -821,14 +824,15 @@ FilmEditor::setup_frame_rate_description () _film->audio_stream()->sample_rate(), _film->target_audio_sample_rate() ); - } else { - d << wxT ("\n"); + ++lines; } -#else - d << wxT ("\n"); #endif } + for (int i = lines; i < 2; ++i) { + d << wxT ("\n "); + } + _frame_rate_description->SetLabel (d); } @@ -1391,7 +1395,7 @@ FilmEditor::setup_scaling_description () } for (int i = lines; i < 4; ++i) { - d << wxT (" \n"); + d << wxT ("\n "); } _scaling_description->SetLabel (d); -- cgit v1.2.3 From b66010a281acd3e3e58ef7202bce55023fc29d7f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 9 Apr 2013 23:43:00 +0100 Subject: Merge ImageMagick and FFmpeg content into VideoContent list; remove seek_to_last hacks. --- run/dvdomatic | 4 +- src/lib/decoder.cc | 11 +-- src/lib/decoder.h | 1 - src/lib/ffmpeg_decoder.cc | 16 +--- src/lib/ffmpeg_decoder.h | 2 - src/lib/film.cc | 3 +- src/lib/imagemagick_content.cc | 2 +- src/lib/imagemagick_decoder.cc | 10 -- src/lib/imagemagick_decoder.h | 1 - src/lib/player.cc | 205 ++++++++++++++--------------------------- src/lib/player.h | 10 +- src/lib/playlist.cc | 178 ++++++++++++++++++----------------- src/lib/playlist.h | 24 +---- src/lib/video_decoder.cc | 4 +- src/lib/video_decoder.h | 6 +- src/tools/dvdomatic.cc | 21 ++++- src/wx/film_viewer.cc | 2 +- 17 files changed, 196 insertions(+), 304 deletions(-) (limited to 'src') diff --git a/run/dvdomatic b/run/dvdomatic index 147c001cd..dbc63d44a 100755 --- a/run/dvdomatic +++ b/run/dvdomatic @@ -3,7 +3,7 @@ export LD_LIBRARY_PATH=build/src/lib:build/src/wx:build/src/asdcplib/src:$LD_LIBRARY_PATH if [ "$1" == "--debug" ]; then shift - gdb --args build/src/tools/dvdomatic "$*" + gdb --args build/src/tools/dvdomatic $* elif [ "$1" == "--valgrind" ]; then shift valgrind --tool="memcheck" build/src/tools/dvdomatic $* @@ -11,5 +11,5 @@ elif [ "$1" == "--i18n" ]; then shift LANGUAGE=fr_FR.UTF8 LANG=fr_FR.UTF8 build/src/tools/dvdomatic "$*" else - build/src/tools/dvdomatic "$*" + build/src/tools/dvdomatic $* fi diff --git a/src/lib/decoder.cc b/src/lib/decoder.cc index c40446919..082ad5076 100644 --- a/src/lib/decoder.cc +++ b/src/lib/decoder.cc @@ -41,7 +41,7 @@ Decoder::Decoder (shared_ptr f) _film_connection = f->Changed.connect (bind (&Decoder::film_changed, this, _1)); } -/** Seek to a position as a source timestamp in seconds. +/** Seek to a position as a content timestamp in seconds. * @return true on error. */ bool @@ -49,12 +49,3 @@ Decoder::seek (double) { throw DecodeError (N_("decoder does not support seek")); } - -/** Seek so that the next frame we will produce is the same as the last one. - * @return true on error. - */ -bool -Decoder::seek_to_last () -{ - throw DecodeError (N_("decoder does not support seek")); -} diff --git a/src/lib/decoder.h b/src/lib/decoder.h index 34accf6c7..0fffef257 100644 --- a/src/lib/decoder.h +++ b/src/lib/decoder.h @@ -56,7 +56,6 @@ public: virtual bool pass () = 0; virtual bool seek (double); - virtual bool seek_to_last (); protected: boost::shared_ptr _film; diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index a0949f635..d0b1de748 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -518,22 +518,12 @@ FFmpegDecoder::filter_and_emit_video (AVFrame* frame) bool FFmpegDecoder::seek (double p) { - return do_seek (p, false); -} - -bool -FFmpegDecoder::seek_to_last () -{ - /* This AVSEEK_FLAG_BACKWARD in do_seek is a bit of a hack; without it, if we ask for a seek to the same place as last time + /* This use of AVSEEK_FLAG_BACKWARD is a bit of a hack; without it, if we ask for a seek to the same place as last time (used when we change decoder parameters and want to re-fetch the frame) we end up going forwards rather than staying in the same place. */ - return do_seek (last_source_time(), true); -} - -bool -FFmpegDecoder::do_seek (double p, bool backwards) -{ + bool const backwards = (p == last_content_time()); + int64_t const vt = p / av_q2d (_format_context->streams[_video_stream]->time_base); int const r = av_seek_frame (_format_context, _video_stream, vt, backwards ? AVSEEK_FLAG_BACKWARD : 0); diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h index cd37d20c6..f6a53874a 100644 --- a/src/lib/ffmpeg_decoder.h +++ b/src/lib/ffmpeg_decoder.h @@ -77,7 +77,6 @@ public: } bool seek (double); - bool seek_to_last (); bool pass (); private: @@ -86,7 +85,6 @@ private: FFmpegDecoder (FFmpegDecoder const &); FFmpegDecoder& operator= (FFmpegDecoder const &); - bool do_seek (double p, bool); PixelFormat pixel_format () const; AVSampleFormat audio_sample_format () const; int bytes_per_audio_sample () const; diff --git a/src/lib/film.cc b/src/lib/film.cc index b36dc8f9c..35a07b399 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -69,6 +69,7 @@ using std::setfill; using std::min; using std::make_pair; using std::endl; +using std::cout; using std::list; using boost::shared_ptr; using boost::lexical_cast; @@ -1084,7 +1085,6 @@ Film::move_content_earlier (shared_ptr c) --j; swap (*i, *j); - _playlist->setup (_content); } signal_changed (CONTENT); @@ -1107,7 +1107,6 @@ Film::move_content_later (shared_ptr c) } swap (*i, *j); - _playlist->setup (_content); } signal_changed (CONTENT); diff --git a/src/lib/imagemagick_content.cc b/src/lib/imagemagick_content.cc index 59fde40bb..24f6d338d 100644 --- a/src/lib/imagemagick_content.cc +++ b/src/lib/imagemagick_content.cc @@ -32,7 +32,7 @@ ImageMagickContent::ImageMagickContent (boost::filesystem::path f) : Content (f) , VideoContent (f) { - + } ImageMagickContent::ImageMagickContent (shared_ptr node) diff --git a/src/lib/imagemagick_decoder.cc b/src/lib/imagemagick_decoder.cc index 6a2be1a7c..7049b7d6e 100644 --- a/src/lib/imagemagick_decoder.cc +++ b/src/lib/imagemagick_decoder.cc @@ -105,16 +105,6 @@ ImageMagickDecoder::pixel_format () const return PIX_FMT_RGB24; } -bool -ImageMagickDecoder::seek_to_last () -{ - if (_position > 0) { - --_position; - } - - return false; -} - bool ImageMagickDecoder::seek (double t) { diff --git a/src/lib/imagemagick_decoder.h b/src/lib/imagemagick_decoder.h index cb524b44b..52c7bec18 100644 --- a/src/lib/imagemagick_decoder.h +++ b/src/lib/imagemagick_decoder.h @@ -50,7 +50,6 @@ public: } bool seek (double); - bool seek_to_last (); bool pass (); protected: diff --git a/src/lib/player.cc b/src/lib/player.cc index 756c3b854..19899f6da 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -20,7 +20,9 @@ #include "player.h" #include "film.h" #include "ffmpeg_decoder.h" +#include "ffmpeg_content.h" #include "imagemagick_decoder.h" +#include "imagemagick_content.h" #include "sndfile_decoder.h" #include "sndfile_content.h" #include "playlist.h" @@ -39,7 +41,6 @@ Player::Player (shared_ptr f, shared_ptr p) , _audio (true) , _subtitles (true) , _have_valid_decoders (false) - , _ffmpeg_decoder_done (false) , _video_sync (true) { _playlist->Changed.connect (bind (&Player::playlist_changed, this)); @@ -74,25 +75,13 @@ Player::pass () bool done = true; - if (_playlist->video_from() == Playlist::VIDEO_FFMPEG || _playlist->audio_from() == Playlist::AUDIO_FFMPEG) { - if (!_ffmpeg_decoder_done) { - if (_ffmpeg_decoder->pass ()) { - _ffmpeg_decoder_done = true; - } else { - done = false; - } + if (_video_decoder != _video_decoders.end ()) { + if ((*_video_decoder)->pass ()) { + _video_decoder++; } - } - - if (_playlist->video_from() == Playlist::VIDEO_IMAGEMAGICK) { - if (_imagemagick_decoder != _imagemagick_decoders.end ()) { - if ((*_imagemagick_decoder)->pass ()) { - _imagemagick_decoder++; - } - - if (_imagemagick_decoder != _imagemagick_decoders.end ()) { - done = false; - } + + if (_video_decoder != _video_decoders.end ()) { + done = false; } } @@ -114,26 +103,18 @@ void Player::set_progress (shared_ptr job) { /* Assume progress can be divined from how far through the video we are */ - switch (_playlist->video_from ()) { - case Playlist::VIDEO_NONE: - break; - case Playlist::VIDEO_FFMPEG: - if (_playlist->video_length ()) { - job->set_progress (float(_ffmpeg_decoder->video_frame()) / _playlist->video_length ()); - } - break; - case Playlist::VIDEO_IMAGEMAGICK: - { - int n = 0; - for (list >::iterator i = _imagemagick_decoders.begin(); i != _imagemagick_decoders.end(); ++i) { - if (_imagemagick_decoder == i) { - job->set_progress (float (n) / _imagemagick_decoders.size ()); - } - ++n; - } - break; + + if (_video_decoder == _video_decoders.end() || !_playlist->video_length()) { + return; } + + ContentVideoFrame p = 0; + list >::iterator i = _video_decoders.begin (); + while (i != _video_decoders.end() && i != _video_decoder) { + p += (*i)->video_length (); } + + job->set_progress (float ((*_video_decoder)->video_frame ()) / _playlist->video_length ()); } void @@ -173,109 +154,67 @@ Player::seek (double t) _have_valid_decoders = true; } - bool r = false; - - switch (_playlist->video_from()) { - case Playlist::VIDEO_NONE: - break; - case Playlist::VIDEO_FFMPEG: - if (!_ffmpeg_decoder || _ffmpeg_decoder->seek (t)) { - r = true; - } - /* We're seeking, so all `all done' bets are off */ - _ffmpeg_decoder_done = false; - break; - case Playlist::VIDEO_IMAGEMAGICK: - /* Find the decoder that contains this position */ - _imagemagick_decoder = _imagemagick_decoders.begin (); - while (_imagemagick_decoder != _imagemagick_decoders.end ()) { - double const this_length = (*_imagemagick_decoder)->video_length() / _film->video_frame_rate (); - if (t < this_length) { - break; - } - t -= this_length; - ++_imagemagick_decoder; + /* Find the decoder that contains this position */ + _video_decoder = _video_decoders.begin (); + while (_video_decoder != _video_decoders.end ()) { + double const this_length = (*_video_decoder)->video_length() / _film->video_frame_rate (); + if (t < this_length) { + break; } - - if (_imagemagick_decoder != _imagemagick_decoders.end()) { - (*_imagemagick_decoder)->seek (t); - } else { - r = true; - } - break; - } - - /* XXX: don't seek audio because we don't need to... */ - - return r; -} - -bool -Player::seek_to_last () -{ - if (!_have_valid_decoders) { - setup_decoders (); - _have_valid_decoders = true; + t -= this_length; + ++_video_decoder; } - - bool r = false; - switch (_playlist->video_from ()) { - case Playlist::VIDEO_NONE: - break; - case Playlist::VIDEO_FFMPEG: - if (!_ffmpeg_decoder || _ffmpeg_decoder->seek_to_last ()) { - r = true; - } - - /* We're seeking, so all `all done' bets are off */ - _ffmpeg_decoder_done = false; - break; - case Playlist::VIDEO_IMAGEMAGICK: - if ((*_imagemagick_decoder)->seek_to_last ()) { - r = true; - } - break; + if (_video_decoder != _video_decoders.end()) { + (*_video_decoder)->seek (t); + } else { + return true; } /* XXX: don't seek audio because we don't need to... */ - return r; + return false; } void Player::setup_decoders () { - if ((_video && _playlist->video_from() == Playlist::VIDEO_FFMPEG) || (_audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG)) { - _ffmpeg_decoder.reset ( - new FFmpegDecoder ( - _film, - _playlist->ffmpeg(), - _video && _playlist->video_from() == Playlist::VIDEO_FFMPEG, - _audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG, - _subtitles && _film->with_subtitles(), - _video_sync - ) - ); - } - - if (_video && _playlist->video_from() == Playlist::VIDEO_FFMPEG) { - _ffmpeg_decoder->connect_video (shared_from_this ()); - } + if (_video) { + list > vc = _playlist->video (); + for (list >::iterator i = vc.begin(); i != vc.end(); ++i) { + + shared_ptr d; + + /* XXX: into content? */ + + shared_ptr fc = dynamic_pointer_cast (*i); + if (fc) { + shared_ptr fd ( + new FFmpegDecoder ( + _film, fc, _video, + _audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG, + _subtitles && _film->with_subtitles(), + _video_sync + ) + ); + + if (_playlist->audio_from() == Playlist::AUDIO_FFMPEG) { + fd->Audio.connect (bind (&Player::process_audio, this, fc, _1)); + } + + d = fd; + } - if (_audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG) { - _ffmpeg_decoder->Audio.connect (bind (&Player::process_audio, this, _playlist->ffmpeg (), _1)); - } + shared_ptr ic = dynamic_pointer_cast (*i); + if (ic) { + d.reset (new ImageMagickDecoder (_film, ic)); + } - if (_video && _playlist->video_from() == Playlist::VIDEO_IMAGEMAGICK) { - list > ic = _playlist->imagemagick (); - for (list >::iterator i = ic.begin(); i != ic.end(); ++i) { - shared_ptr d (new ImageMagickDecoder (_film, *i)); - _imagemagick_decoders.push_back (d); d->connect_video (shared_from_this ()); + _video_decoders.push_back (d); } - _imagemagick_decoder = _imagemagick_decoders.begin (); + _video_decoder = _video_decoders.begin (); } if (_audio && _playlist->audio_from() == Playlist::AUDIO_SNDFILE) { @@ -297,23 +236,12 @@ Player::disable_video_sync () double Player::last_video_time () const { - switch (_playlist->video_from ()) { - case Playlist::VIDEO_NONE: - return 0; - case Playlist::VIDEO_FFMPEG: - return _ffmpeg_decoder->last_source_time (); - case Playlist::VIDEO_IMAGEMAGICK: - { - double t = 0; - for (list >::const_iterator i = _imagemagick_decoders.begin(); i != _imagemagick_decoder; ++i) { - t += (*i)->video_length() / (*i)->video_frame_rate (); - } - - return t + (*_imagemagick_decoder)->last_source_time (); - } + double t = 0; + for (list >::const_iterator i = _video_decoders.begin(); i != _video_decoder; ++i) { + t += (*i)->video_length() / (*i)->video_frame_rate (); } - return 0; + return t + (*_video_decoder)->last_content_time (); } void @@ -326,6 +254,7 @@ Player::content_changed (weak_ptr w, int p) if (p == VideoContentProperty::VIDEO_LENGTH) { if (dynamic_pointer_cast (c)) { + /* FFmpeg content length changes are serious; we need new decoders */ _have_valid_decoders = false; } } diff --git a/src/lib/player.h b/src/lib/player.h index afc856316..8a82ab298 100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@ -28,8 +28,7 @@ #include "video_sink.h" #include "audio_sink.h" -class FFmpegDecoder; -class ImageMagickDecoder; +class VideoDecoder; class SndfileDecoder; class Job; class Film; @@ -49,7 +48,6 @@ public: bool pass (); void set_progress (boost::shared_ptr); bool seek (double); - bool seek_to_last (); double last_video_time () const; @@ -68,10 +66,8 @@ private: bool _subtitles; bool _have_valid_decoders; - boost::shared_ptr _ffmpeg_decoder; - bool _ffmpeg_decoder_done; - std::list > _imagemagick_decoders; - std::list >::iterator _imagemagick_decoder; + std::list > _video_decoders; + std::list >::iterator _video_decoder; std::list > _sndfile_decoders; boost::shared_ptr _sndfile_buffers; diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index 3f7905fa9..d26dae730 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -21,9 +21,9 @@ #include "playlist.h" #include "sndfile_content.h" #include "sndfile_decoder.h" -#include "ffmpeg_content.h" +#include "video_content.h" #include "ffmpeg_decoder.h" -#include "imagemagick_content.h" +#include "ffmpeg_content.h" #include "imagemagick_decoder.h" #include "job.h" @@ -31,13 +31,13 @@ using std::list; using std::cout; using std::vector; using std::min; +using std::max; using boost::shared_ptr; using boost::weak_ptr; using boost::dynamic_pointer_cast; Playlist::Playlist () - : _video_from (VIDEO_NONE) - , _audio_from (AUDIO_NONE) + : _audio_from (AUDIO_FFMPEG) { } @@ -45,11 +45,9 @@ Playlist::Playlist () void Playlist::setup (ContentList content) { - _video_from = VIDEO_NONE; - _audio_from = AUDIO_NONE; + _audio_from = AUDIO_FFMPEG; - _ffmpeg.reset (); - _imagemagick.clear (); + _video.clear (); _sndfile.clear (); for (list::iterator i = _content_connections.begin(); i != _content_connections.end(); ++i) { @@ -59,24 +57,11 @@ Playlist::setup (ContentList content) _content_connections.clear (); for (ContentList::const_iterator i = content.begin(); i != content.end(); ++i) { - shared_ptr fc = dynamic_pointer_cast (*i); - if (fc) { - assert (!_ffmpeg); - _ffmpeg = fc; - _video_from = VIDEO_FFMPEG; - if (_audio_from == AUDIO_NONE) { - _audio_from = AUDIO_FFMPEG; - } + shared_ptr vc = dynamic_pointer_cast (*i); + if (vc) { + _video.push_back (vc); } - shared_ptr ic = dynamic_pointer_cast (*i); - if (ic) { - _imagemagick.push_back (ic); - if (_video_from == VIDEO_NONE) { - _video_from = VIDEO_IMAGEMAGICK; - } - } - shared_ptr sc = dynamic_pointer_cast (*i); if (sc) { _sndfile.push_back (sc); @@ -92,53 +77,65 @@ Playlist::setup (ContentList content) ContentAudioFrame Playlist::audio_length () const { + ContentAudioFrame len = 0; + switch (_audio_from) { - case AUDIO_NONE: - return 0; case AUDIO_FFMPEG: - return _ffmpeg->audio_length (); + for (list >::const_iterator i = _video.begin(); i != _video.end(); ++i) { + shared_ptr fc = dynamic_pointer_cast (*i); + if (fc) { + len += fc->audio_length (); + } + } + break; case AUDIO_SNDFILE: - { - ContentAudioFrame l = 0; for (list >::const_iterator i = _sndfile.begin(); i != _sndfile.end(); ++i) { - l += (*i)->audio_length (); + len += (*i)->audio_length (); } - return l; - } + break; } - return 0; + return len; } int Playlist::audio_channels () const { + int channels = 0; + switch (_audio_from) { - case AUDIO_NONE: - return 0; case AUDIO_FFMPEG: - return _ffmpeg->audio_channels (); + for (list >::const_iterator i = _video.begin(); i != _video.end(); ++i) { + shared_ptr fc = dynamic_pointer_cast (*i); + if (fc) { + channels = max (channels, fc->audio_channels ()); + } + } + break; case AUDIO_SNDFILE: - { - int c = 0; for (list >::const_iterator i = _sndfile.begin(); i != _sndfile.end(); ++i) { - c += (*i)->audio_channels (); + channels += (*i)->audio_channels (); } - return c; - } + break; } - return 0; + return channels; } int Playlist::audio_frame_rate () const { + /* XXX: assuming that all content has the same rate */ + switch (_audio_from) { - case AUDIO_NONE: - return 0; case AUDIO_FFMPEG: - return _ffmpeg->audio_frame_rate (); + { + shared_ptr fc = first_ffmpeg (); + if (fc) { + return fc->audio_channels (); + } + break; + } case AUDIO_SNDFILE: return _sndfile.front()->audio_frame_rate (); } @@ -149,11 +146,17 @@ Playlist::audio_frame_rate () const int64_t Playlist::audio_channel_layout () const { + /* XXX: assuming that all content has the same layout */ + switch (_audio_from) { - case AUDIO_NONE: - return 0; case AUDIO_FFMPEG: - return _ffmpeg->audio_channel_layout (); + { + shared_ptr fc = first_ffmpeg (); + if (fc) { + return fc->audio_channel_layout (); + } + break; + } case AUDIO_SNDFILE: /* XXX */ return 0; @@ -165,59 +168,41 @@ Playlist::audio_channel_layout () const float Playlist::video_frame_rate () const { - switch (_video_from) { - case VIDEO_NONE: + if (_video.empty ()) { return 0; - case VIDEO_FFMPEG: - return _ffmpeg->video_frame_rate (); - case VIDEO_IMAGEMAGICK: - return 24; } - - return 0; + + /* XXX: assuming all the same */ + return _video.front()->video_frame_rate (); } libdcp::Size Playlist::video_size () const { - switch (_video_from) { - case VIDEO_NONE: + if (_video.empty ()) { return libdcp::Size (); - case VIDEO_FFMPEG: - return _ffmpeg->video_size (); - case VIDEO_IMAGEMAGICK: - /* XXX */ - return _imagemagick.front()->video_size (); } - return libdcp::Size (); + /* XXX: assuming all the same */ + return _video.front()->video_size (); } ContentVideoFrame Playlist::video_length () const { - switch (_video_from) { - case VIDEO_NONE: - return 0; - case VIDEO_FFMPEG: - return _ffmpeg->video_length (); - case VIDEO_IMAGEMAGICK: - { - ContentVideoFrame l = 0; - for (list >::const_iterator i = _imagemagick.begin(); i != _imagemagick.end(); ++i) { - l += (*i)->video_length (); - } - return l; + ContentVideoFrame len = 0; + for (list >::const_iterator i = _video.begin(); i != _video.end(); ++i) { + len += (*i)->video_length (); } - } - - return 0; + + return len; } bool Playlist::has_audio () const { - return _audio_from != AUDIO_NONE; + /* XXX */ + return true; } void @@ -226,32 +211,51 @@ Playlist::content_changed (weak_ptr c, int p) ContentChanged (c, p); } +shared_ptr +Playlist::first_ffmpeg () const +{ + for (list >::const_iterator i = _video.begin(); i != _video.end(); ++i) { + shared_ptr fc = dynamic_pointer_cast (*i); + if (fc) { + return fc; + } + } + + return shared_ptr (); +} + + AudioMapping Playlist::default_audio_mapping () const { AudioMapping m; switch (_audio_from) { - case AUDIO_NONE: - break; case AUDIO_FFMPEG: - if (_ffmpeg->audio_channels() == 1) { + { + shared_ptr fc = first_ffmpeg (); + if (!fc) { + break; + } + + /* XXX: assumes all the same */ + if (fc->audio_channels() == 1) { /* Map mono sources to centre */ - m.add (AudioMapping::Channel (_ffmpeg, 0), libdcp::CENTRE); + m.add (AudioMapping::Channel (fc, 0), libdcp::CENTRE); } else { - int const N = min (_ffmpeg->audio_channels (), MAX_AUDIO_CHANNELS); + int const N = min (fc->audio_channels (), MAX_AUDIO_CHANNELS); /* Otherwise just start with a 1:1 mapping */ for (int i = 0; i < N; ++i) { - m.add (AudioMapping::Channel (_ffmpeg, i), (libdcp::Channel) i); + m.add (AudioMapping::Channel (fc, i), (libdcp::Channel) i); } } break; + } case AUDIO_SNDFILE: { int n = 0; for (list >::const_iterator i = _sndfile.begin(); i != _sndfile.end(); ++i) { - cout << "sndfile " << (*i)->audio_channels() << "\n"; for (int j = 0; j < (*i)->audio_channels(); ++j) { m.add (AudioMapping::Channel (*i, j), (libdcp::Channel) n); ++n; diff --git a/src/lib/playlist.h b/src/lib/playlist.h index 1d189cb07..4dd27f675 100644 --- a/src/lib/playlist.h +++ b/src/lib/playlist.h @@ -56,32 +56,17 @@ public: AudioMapping default_audio_mapping () const; - enum VideoFrom { - VIDEO_NONE, - VIDEO_FFMPEG, - VIDEO_IMAGEMAGICK - }; - enum AudioFrom { - AUDIO_NONE, AUDIO_FFMPEG, AUDIO_SNDFILE }; - VideoFrom video_from () const { - return _video_from; - } - AudioFrom audio_from () const { return _audio_from; } - boost::shared_ptr ffmpeg () const { - return _ffmpeg; - } - - std::list > imagemagick () const { - return _imagemagick; + std::list > video () const { + return _video; } std::list > sndfile () const { @@ -93,12 +78,11 @@ public: private: void content_changed (boost::weak_ptr, int); + boost::shared_ptr first_ffmpeg () const; - VideoFrom _video_from; AudioFrom _audio_from; - boost::shared_ptr _ffmpeg; - std::list > _imagemagick; + std::list > _video; std::list > _sndfile; std::list _content_connections; diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc index fd2b28d7f..99d711693 100644 --- a/src/lib/video_decoder.cc +++ b/src/lib/video_decoder.cc @@ -32,7 +32,7 @@ using boost::optional; VideoDecoder::VideoDecoder (shared_ptr f) : Decoder (f) , _video_frame (0) - , _last_source_time (0) + , _last_content_time (0) { } @@ -88,7 +88,7 @@ VideoDecoder::signal_video (shared_ptr image, bool same, shared_ptr, bool, boost::shared_ptr, double); int _video_frame; - double _last_source_time; + double _last_content_time; boost::shared_ptr _timed_subtitle; diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 6c27892b0..239b4a517 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -59,6 +59,7 @@ static FilmViewer* film_viewer = 0; static shared_ptr film; static std::string log_level; static std::string film_to_load; +static std::string film_to_create; static wxMenu* jobs_menu = 0; static wxLocale* locale = 0; @@ -439,13 +440,15 @@ private: #if wxMINOR_VERSION == 9 static const wxCmdLineEntryDesc command_line_description[] = { { wxCMD_LINE_OPTION, "l", "log", "set log level (silent, verbose or timing)", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL }, - { wxCMD_LINE_PARAM, 0, 0, "film to load", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE | wxCMD_LINE_PARAM_OPTIONAL }, + { wxCMD_LINE_SWITCH, "n", "new", "create new film", wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL }, + { wxCMD_LINE_PARAM, 0, 0, "film to load or create", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE | wxCMD_LINE_PARAM_OPTIONAL }, { wxCMD_LINE_NONE, "", "", "", wxCmdLineParamType (0), 0 } }; #else static const wxCmdLineEntryDesc command_line_description[] = { { wxCMD_LINE_OPTION, wxT("l"), wxT("log"), wxT("set log level (silent, verbose or timing)"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL }, - { wxCMD_LINE_PARAM, 0, 0, wxT("film to load"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE | wxCMD_LINE_PARAM_OPTIONAL }, + { wxCMD_LINE_SWITCH, wxT("n"), wxT("new"), wxT("create new film"), wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL }, + { wxCMD_LINE_PARAM, 0, 0, wxT("film to load or create"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE | wxCMD_LINE_PARAM_OPTIONAL }, { wxCMD_LINE_NONE, wxT(""), wxT(""), wxT(""), wxCmdLineParamType (0), 0 } }; #endif @@ -525,6 +528,12 @@ class App : public wxApp } } + if (!film_to_create.empty ()) { + film.reset (new Film (film_to_create, false)); + film->log()->set_level (log_level); + film->set_name (boost::filesystem::path (film_to_create).filename().generic_string ()); + } + Frame* f = new Frame (_("DVD-o-matic")); SetTopWindow (f); f->Maximize (); @@ -545,11 +554,15 @@ class App : public wxApp bool OnCmdLineParsed (wxCmdLineParser& parser) { if (parser.GetParamCount() > 0) { - film_to_load = wx_to_std (parser.GetParam(0)); + if (parser.FoundSwitch (wxT ("new"))) { + film_to_create = wx_to_std (parser.GetParam (0)); + } else { + film_to_load = wx_to_std (parser.GetParam(0)); + } } wxString log; - if (parser.Found(wxT("log"), &log)) { + if (parser.Found (wxT ("log"), &log)) { log_level = wx_to_std (log); } diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index f8373d3fd..8fca8f370 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -157,7 +157,7 @@ FilmViewer::set_film (shared_ptr f) void FilmViewer::update_from_decoder () { - if (!_player || _player->seek_to_last ()) { + if (!_player || _player->seek (_player->last_video_time ())) { return; } -- cgit v1.2.3 From 2984694418c8d2e3cc5f7dd4e87c2cd17e8b47f2 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 10 Apr 2013 10:24:16 +0100 Subject: Try to fix blank FilmChangedDialog under translation (#112). --- src/tools/dvdomatic.cc | 2 +- src/tools/po/es_ES.po | 2 +- src/tools/po/fr_FR.po | 2 +- src/tools/po/it_IT.po | 4 ++-- src/tools/po/sv_SE.po | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 80a33efef..212d4848e 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -71,7 +71,7 @@ public: { _dialog = new wxMessageDialog ( 0, - std_to_wx (String::compose (wx_to_std (_("Save changes to film \"%1\" before closing?")), film->name())), + wxString::Format (_("Save changes to film \"%s\" before closing?"), std_to_wx (film->name ()).data()), _("Film changed"), wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION ); diff --git a/src/tools/po/es_ES.po b/src/tools/po/es_ES.po index 1ab1a8489..abfbfef6d 100644 --- a/src/tools/po/es_ES.po +++ b/src/tools/po/es_ES.po @@ -109,7 +109,7 @@ msgid "S&how DCP" msgstr "&Mostrar DCP" #: src/tools/dvdomatic.cc:74 -msgid "Save changes to film \"%1\" before closing?" +msgid "Save changes to film \"%s\" before closing?" msgstr "" #: src/tools/dvdomatic.cc:319 diff --git a/src/tools/po/fr_FR.po b/src/tools/po/fr_FR.po index 35e686f67..b40c86877 100644 --- a/src/tools/po/fr_FR.po +++ b/src/tools/po/fr_FR.po @@ -106,7 +106,7 @@ msgid "S&how DCP" msgstr "Voir le DCP" #: src/tools/dvdomatic.cc:74 -msgid "Save changes to film \"%1\" before closing?" +msgid "Save changes to film \"%s\" before closing?" msgstr "" #: src/tools/dvdomatic.cc:319 diff --git a/src/tools/po/it_IT.po b/src/tools/po/it_IT.po index 09e3f5f34..38cbec157 100644 --- a/src/tools/po/it_IT.po +++ b/src/tools/po/it_IT.po @@ -106,8 +106,8 @@ msgid "S&how DCP" msgstr "&Mostra DCP" #: src/tools/dvdomatic.cc:74 -msgid "Save changes to film \"%1\" before closing?" -msgstr "Salvare i cambiamenti del film \"%1\" prima di chiudere?" +msgid "Save changes to film \"%s\" before closing?" +msgstr "Salvare i cambiamenti del film \"%s\" prima di chiudere?" #: src/tools/dvdomatic.cc:319 msgid "Select film to open" diff --git a/src/tools/po/sv_SE.po b/src/tools/po/sv_SE.po index 28566d876..57254770c 100644 --- a/src/tools/po/sv_SE.po +++ b/src/tools/po/sv_SE.po @@ -107,8 +107,8 @@ msgid "S&how DCP" msgstr "&Visa DCP" #: src/tools/dvdomatic.cc:74 -msgid "Save changes to film \"%1\" before closing?" -msgstr "Spara ändringarna till filmen \"%1\" före avslut?" +msgid "Save changes to film \"%s\" before closing?" +msgstr "Spara ändringarna till filmen \"%s\" före avslut?" #: src/tools/dvdomatic.cc:319 msgid "Select film to open" -- cgit v1.2.3 From 38fdfb05aec760d44137b8ca09d6dcc2f9f4111f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 10 Apr 2013 11:08:07 +0100 Subject: Fix rounding error when computing padding; add test. --- src/lib/format.cc | 2 +- test/test.cc | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/format.cc b/src/lib/format.cc index 0ca97303e..3ee11a132 100644 --- a/src/lib/format.cc +++ b/src/lib/format.cc @@ -199,7 +199,7 @@ FixedFormat::FixedFormat (int r, libdcp::Size dcp, string id, string n, string d int Format::dcp_padding (shared_ptr f) const { - int p = rint ((_dcp_size.width - (_dcp_size.height * ratio_as_integer(f) / 100.0)) / 2.0); + int p = rint ((_dcp_size.width - (_dcp_size.height * ratio_as_float(f))) / 2.0); /* This comes out -ve for Scope; bodge it */ if (p < 0) { diff --git a/test/test.cc b/test/test.cc index 61e192058..6d6841a87 100644 --- a/test/test.cc +++ b/test/test.cc @@ -229,6 +229,32 @@ BOOST_AUTO_TEST_CASE (format_test) BOOST_CHECK_EQUAL (f->ratio_as_integer(shared_ptr ()), 239); } +/* Test VariableFormat-based scaling of content */ +BOOST_AUTO_TEST_CASE (scaling_test) +{ + shared_ptr film (new Film (test_film_dir ("scaling_test").string(), false)); + + /* 4:3 ratio */ + film->set_size (libdcp::Size (320, 240)); + + /* This format should preserve aspect ratio of the source */ + Format const * format = Format::from_id ("var-185"); + + int const p = format->dcp_padding (film); + + /* We should have enough padding that the result is 4:3, + which would be 1440 pixels. + */ + BOOST_CHECK_EQUAL (p, (1998 - 1440) / 2); + + + /* This crops it to 1.291666667 */ +// f.set_left_crop (5); +// f.set_right_crop (5); + + +} + BOOST_AUTO_TEST_CASE (util_test) { string t = "Hello this is a string \"with quotes\" and indeed without them"; -- cgit v1.2.3 From 0806df40e8739b83945b62b61eaf4f18bbfa6320 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 10 Apr 2013 11:28:19 +0100 Subject: Fix variable format ratio under crop (part of #113). --- src/lib/format.cc | 3 ++- test/test.cc | 16 ++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/lib/format.cc b/src/lib/format.cc index 3ee11a132..faadcd797 100644 --- a/src/lib/format.cc +++ b/src/lib/format.cc @@ -230,7 +230,8 @@ VariableFormat::ratio_as_integer (shared_ptr f) const float VariableFormat::ratio_as_float (shared_ptr f) const { - return float (f->size().width) / f->size().height; + libdcp::Size const c = f->cropped_size (f->size ()); + return float (c.width) / c.height; } /** @return A name to be presented to the user */ diff --git a/test/test.cc b/test/test.cc index 6d6841a87..d1bb400f9 100644 --- a/test/test.cc +++ b/test/test.cc @@ -240,19 +240,19 @@ BOOST_AUTO_TEST_CASE (scaling_test) /* This format should preserve aspect ratio of the source */ Format const * format = Format::from_id ("var-185"); - int const p = format->dcp_padding (film); - /* We should have enough padding that the result is 4:3, which would be 1440 pixels. */ - BOOST_CHECK_EQUAL (p, (1998 - 1440) / 2); - + BOOST_CHECK_EQUAL (format->dcp_padding (film), (1998 - 1440) / 2); /* This crops it to 1.291666667 */ -// f.set_left_crop (5); -// f.set_right_crop (5); - - + film->set_left_crop (5); + film->set_right_crop (5); + + /* We should now have enough padding that the result is 1.29166667, + which would be 1395 pixels. + */ + BOOST_CHECK_EQUAL (format->dcp_padding (film), rint ((1998 - 1395) / 2.0)); } BOOST_AUTO_TEST_CASE (util_test) -- cgit v1.2.3 From 62f86da8d2b0daa2237e33653a3e837e6f395573 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 10 Apr 2013 11:38:05 +0100 Subject: Try to fix problems with view of padded stuff. --- src/wx/film_viewer.cc | 8 ++++---- src/wx/film_viewer.h | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 4dca5cad8..18ddf1eb2 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -222,20 +222,20 @@ FilmViewer::paint_panel (wxPaintEvent &) dc.DrawBitmap (sub_bitmap, _display_sub_position.x, _display_sub_position.y); } - if (_film_size.width < _panel_size.width) { + if (_out_size.width < _panel_size.width) { wxPen p (GetBackgroundColour ()); wxBrush b (GetBackgroundColour ()); dc.SetPen (p); dc.SetBrush (b); - dc.DrawRectangle (_film_size.width, 0, _panel_size.width - _film_size.width, _panel_size.height); + dc.DrawRectangle (_out_size.width, 0, _panel_size.width - _out_size.width, _panel_size.height); } - if (_film_size.height < _panel_size.height) { + if (_out_size.height < _panel_size.height) { wxPen p (GetBackgroundColour ()); wxBrush b (GetBackgroundColour ()); dc.SetPen (p); dc.SetBrush (b); - dc.DrawRectangle (0, _film_size.height, _panel_size.width, _panel_size.height - _film_size.height); + dc.DrawRectangle (0, _out_size.height, _panel_size.width, _panel_size.height - _out_size.height); } } diff --git a/src/wx/film_viewer.h b/src/wx/film_viewer.h index f89269d2b..784434f6b 100644 --- a/src/wx/film_viewer.h +++ b/src/wx/film_viewer.h @@ -69,6 +69,9 @@ private: boost::shared_ptr _raw_frame; boost::shared_ptr _raw_sub; boost::shared_ptr _display_frame; + /* The x offset at which we display the actual film content; this corresponds + to the film's padding converted to our coordinates. + */ int _display_frame_x; boost::shared_ptr _display_sub; Position _display_sub_position; -- cgit v1.2.3 From e32d1c52f8f8e7cad145766b9b33bb9c3470a6c0 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 10 Apr 2013 12:38:07 +0100 Subject: Try to fix left-over frame when making a new filme. --- src/wx/film_viewer.cc | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 18ddf1eb2..dbbff3713 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -148,6 +148,11 @@ FilmViewer::set_film (shared_ptr f) _film = f; + _raw_frame.reset (); + _display_frame.reset (); + _panel->Refresh (); + _panel->Update (); + if (!_film) { return; } -- cgit v1.2.3 From 9b577fb38b51ccfa1229ceabaf12088c6c9b81e0 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 10 Apr 2013 15:11:40 +0100 Subject: Updated sv_SE from Adam. --- src/lib/po/sv_SE.po | 8 +++----- src/tools/po/sv_SE.po | 4 ++-- 2 files changed, 5 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/lib/po/sv_SE.po b/src/lib/po/sv_SE.po index d574261c8..ef8109dfa 100644 --- a/src/lib/po/sv_SE.po +++ b/src/lib/po/sv_SE.po @@ -8,10 +8,9 @@ msgstr "" "Project-Id-Version: DVD-o-matic\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-04-09 11:14+0100\n" -"PO-Revision-Date: 2013-04-09 10:13+0100\n" +"PO-Revision-Date: 2013-04-10 15:35+0100\n" "Last-Translator: Adam Klotblixt \n" "Language-Team: \n" -"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -50,9 +49,8 @@ msgid "16:9 within Flat" msgstr "16:9 innanför Flat" #: src/lib/format.cc:115 -#, fuzzy msgid "16:9 within Scope" -msgstr "16:9 innanför Flat" +msgstr "16:9 innanför Scope" #: src/lib/filter.cc:88 msgid "3D denoiser" @@ -76,7 +74,7 @@ msgstr "Reklam" #: src/lib/job.cc:72 msgid "An error occurred whilst handling the file %1." -msgstr "Ett fel inträffade vid hantering av filen (%1)" +msgstr "Ett fel inträffade vid hantering av filen %1" #: src/lib/analyse_audio_job.cc:49 msgid "Analyse audio of %1" diff --git a/src/tools/po/sv_SE.po b/src/tools/po/sv_SE.po index 57254770c..28566d876 100644 --- a/src/tools/po/sv_SE.po +++ b/src/tools/po/sv_SE.po @@ -107,8 +107,8 @@ msgid "S&how DCP" msgstr "&Visa DCP" #: src/tools/dvdomatic.cc:74 -msgid "Save changes to film \"%s\" before closing?" -msgstr "Spara ändringarna till filmen \"%s\" före avslut?" +msgid "Save changes to film \"%1\" before closing?" +msgstr "Spara ändringarna till filmen \"%1\" före avslut?" #: src/tools/dvdomatic.cc:319 msgid "Select film to open" -- cgit v1.2.3 From 26c6f510ca23f1d21e41e3df65726ffa0852d745 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 10 Apr 2013 15:12:09 +0100 Subject: Try to fix rounding problems with ratios due to old unused integer ops. --- src/lib/format.cc | 40 +++++++++++++++++----------------------- src/lib/format.h | 29 +++++++++-------------------- src/wx/film_viewer.cc | 2 +- test/test.cc | 6 ++++-- 4 files changed, 31 insertions(+), 46 deletions(-) (limited to 'src') diff --git a/src/lib/format.cc b/src/lib/format.cc index faadcd797..2f9f87ba9 100644 --- a/src/lib/format.cc +++ b/src/lib/format.cc @@ -72,51 +72,51 @@ Format::setup_formats () { /// TRANSLATORS: these are film picture aspect ratios; "Academy" means 1.37, "Flat" 1.85 and "Scope" 2.39. _formats.push_back ( - new FixedFormat (119, libdcp::Size (1285, 1080), N_("119"), _("1.19"), N_("F") + new FixedFormat (1.19, libdcp::Size (1285, 1080), N_("119"), _("1.19"), N_("F") )); _formats.push_back ( - new FixedFormat (133, libdcp::Size (1436, 1080), N_("133"), _("1.33"), N_("F") + new FixedFormat (4.0 / 3.0, libdcp::Size (1436, 1080), N_("133"), _("4:3"), N_("F") )); _formats.push_back ( - new FixedFormat (138, libdcp::Size (1485, 1080), N_("138"), _("1.375"), N_("F") + new FixedFormat (1.38, libdcp::Size (1485, 1080), N_("138"), _("1.375"), N_("F") )); _formats.push_back ( - new FixedFormat (133, libdcp::Size (1998, 1080), N_("133-in-flat"), _("4:3 within Flat"), N_("F") + new FixedFormat (4.0 / 30, libdcp::Size (1998, 1080), N_("133-in-flat"), _("4:3 within Flat"), N_("F") )); _formats.push_back ( - new FixedFormat (137, libdcp::Size (1480, 1080), N_("137"), _("Academy"), N_("F") + new FixedFormat (1.37, libdcp::Size (1480, 1080), N_("137"), _("Academy"), N_("F") )); _formats.push_back ( - new FixedFormat (166, libdcp::Size (1793, 1080), N_("166"), _("1.66"), N_("F") + new FixedFormat (1.66, libdcp::Size (1793, 1080), N_("166"), _("1.66"), N_("F") )); _formats.push_back ( - new FixedFormat (166, libdcp::Size (1998, 1080), N_("166-in-flat"), _("1.66 within Flat"), N_("F") + new FixedFormat (1.66, libdcp::Size (1998, 1080), N_("166-in-flat"), _("1.66 within Flat"), N_("F") )); _formats.push_back ( - new FixedFormat (178, libdcp::Size (1998, 1080), N_("178-in-flat"), _("16:9 within Flat"), N_("F") + new FixedFormat (1.78, libdcp::Size (1998, 1080), N_("178-in-flat"), _("16:9 within Flat"), N_("F") )); _formats.push_back ( - new FixedFormat (178, libdcp::Size (1920, 1080), N_("178"), _("16:9"), N_("F") + new FixedFormat (1.78, libdcp::Size (1920, 1080), N_("178"), _("16:9"), N_("F") )); _formats.push_back ( - new FixedFormat (185, libdcp::Size (1998, 1080), N_("185"), _("Flat"), N_("F") + new FixedFormat (1.85, libdcp::Size (1998, 1080), N_("185"), _("Flat"), N_("F") )); _formats.push_back ( - new FixedFormat (178, libdcp::Size (2048, 858), N_("178-in-scope"), _("16:9 within Scope"), N_("S") + new FixedFormat (1.78, libdcp::Size (2048, 858), N_("178-in-scope"), _("16:9 within Scope"), N_("S") )); _formats.push_back ( - new FixedFormat (239, libdcp::Size (2048, 858), N_("239"), _("Scope"), N_("S") + new FixedFormat (2.39, libdcp::Size (2048, 858), N_("239"), _("Scope"), N_("S") )); _formats.push_back ( @@ -181,12 +181,12 @@ Format::all () return _formats; } -/** @param r Ratio multiplied by 100 (e.g. 185) +/** @param r Ratio * @param dcp Size (in pixels) of the images that we should put in a DCP. * @param id ID (e.g. 185) * @param n Nick name (e.g. Flat) */ -FixedFormat::FixedFormat (int r, libdcp::Size dcp, string id, string n, string d) +FixedFormat::FixedFormat (float r, libdcp::Size dcp, string id, string n, string d) : Format (dcp, id, n, d) , _ratio (r) { @@ -199,7 +199,7 @@ FixedFormat::FixedFormat (int r, libdcp::Size dcp, string id, string n, string d int Format::dcp_padding (shared_ptr f) const { - int p = rint ((_dcp_size.width - (_dcp_size.height * ratio_as_float(f))) / 2.0); + int p = rint ((_dcp_size.width - (_dcp_size.height * ratio(f))) / 2.0); /* This comes out -ve for Scope; bodge it */ if (p < 0) { @@ -210,7 +210,7 @@ Format::dcp_padding (shared_ptr f) const } float -Format::container_ratio_as_float () const +Format::container_ratio () const { return static_cast (_dcp_size.width) / _dcp_size.height; } @@ -221,14 +221,8 @@ VariableFormat::VariableFormat (libdcp::Size dcp, string id, string n, string d) } -int -VariableFormat::ratio_as_integer (shared_ptr f) const -{ - return rint (ratio_as_float (f) * 100); -} - float -VariableFormat::ratio_as_float (shared_ptr f) const +VariableFormat::ratio (shared_ptr f) const { libdcp::Size const c = f->cropped_size (f->size ()); return float (c.width) / c.height; diff --git a/src/lib/format.h b/src/lib/format.h index 783ff25ce..e95306232 100644 --- a/src/lib/format.h +++ b/src/lib/format.h @@ -38,16 +38,8 @@ public: , _dci_name (d) {} - /** @return the aspect ratio multiplied by 100 - * (e.g. 239 for Cinemascope 2.39:1) - */ - virtual int ratio_as_integer (boost::shared_ptr f) const = 0; - - /** @return the ratio as a floating point number */ - virtual float ratio_as_float (boost::shared_ptr f) const = 0; - - /** @return the ratio of the container (including any padding) as a floating point number */ - float container_ratio_as_float () const; + /** @return the ratio of the container (including any padding) */ + float container_ratio () const; int dcp_padding (boost::shared_ptr f) const; @@ -84,6 +76,9 @@ public: static void setup_formats (); protected: + /** @return the ratio */ + virtual float ratio (boost::shared_ptr f) const = 0; + /** libdcp::Size in pixels of the images that we should * put in a DCP for this ratio. This size will not correspond * to the ratio when we are doing things like 16:9 in a Flat frame. @@ -107,22 +102,17 @@ private: class FixedFormat : public Format { public: - FixedFormat (int, libdcp::Size, std::string, std::string, std::string); + FixedFormat (float, libdcp::Size, std::string, std::string, std::string); - int ratio_as_integer (boost::shared_ptr) const { + float ratio (boost::shared_ptr) const { return _ratio; } - float ratio_as_float (boost::shared_ptr) const { - return _ratio / 100.0; - } - std::string name () const; private: - /** Ratio expressed as the actual ratio multiplied by 100 */ - int _ratio; + float _ratio; }; class VariableFormat : public Format @@ -130,8 +120,7 @@ class VariableFormat : public Format public: VariableFormat (libdcp::Size, std::string, std::string, std::string); - int ratio_as_integer (boost::shared_ptr f) const; - float ratio_as_float (boost::shared_ptr f) const; + float ratio (boost::shared_ptr f) const; std::string name () const; }; diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index dbbff3713..40b74ac39 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -332,7 +332,7 @@ FilmViewer::calculate_sizes () Format const * format = _film->format (); float const panel_ratio = static_cast (_panel_size.width) / _panel_size.height; - float const film_ratio = format ? format->container_ratio_as_float () : 1.78; + float const film_ratio = format ? format->container_ratio () : 1.78; if (panel_ratio < film_ratio) { /* panel is less widscreen than the film; clamp width */ diff --git a/test/test.cc b/test/test.cc index d1bb400f9..741f36d5a 100644 --- a/test/test.cc +++ b/test/test.cc @@ -222,11 +222,13 @@ BOOST_AUTO_TEST_CASE (format_test) Format const * f = Format::from_nickname ("Flat"); BOOST_CHECK (f); - BOOST_CHECK_EQUAL (f->ratio_as_integer(shared_ptr ()), 185); + BOOST_CHECK_EQUAL (f->dcp_size().width, 1998); + BOOST_CHECK_EQUAL (f->dcp_size().height, 1080); f = Format::from_nickname ("Scope"); BOOST_CHECK (f); - BOOST_CHECK_EQUAL (f->ratio_as_integer(shared_ptr ()), 239); + BOOST_CHECK_EQUAL (f->dcp_size().width, 2048); + BOOST_CHECK_EQUAL (f->dcp_size().height, 858); } /* Test VariableFormat-based scaling of content */ -- cgit v1.2.3 From 5c620f37c8979a645a2094aa36b9af3d4f4ef5ec Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 10 Apr 2013 19:40:45 +0100 Subject: Various fix-ups. --- src/lib/player.cc | 8 ++++++-- src/wx/film_editor.cc | 2 +- src/wx/film_viewer.cc | 11 +++++++++++ src/wx/film_viewer.h | 1 + 4 files changed, 19 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/lib/player.cc b/src/lib/player.cc index 19899f6da..c66d091cf 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -153,11 +153,11 @@ Player::seek (double t) setup_decoders (); _have_valid_decoders = true; } - + /* Find the decoder that contains this position */ _video_decoder = _video_decoders.begin (); while (_video_decoder != _video_decoders.end ()) { - double const this_length = (*_video_decoder)->video_length() / _film->video_frame_rate (); + double const this_length = double ((*_video_decoder)->video_length()) / _film->video_frame_rate (); if (t < this_length) { break; } @@ -179,6 +179,10 @@ Player::seek (double t) void Player::setup_decoders () { + _video_decoders.clear (); + _video_decoder = _video_decoders.end (); + _sndfile_decoders.clear (); + if (_video) { list > vc = _playlist->video (); for (list >::iterator i = vc.begin(); i != vc.end(); ++i) { diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index a197a7490..9cd10ad61 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -788,7 +788,7 @@ FilmEditor::setup_frame_rate_description () if (_film->video_frame_rate()) { d << std_to_wx (FrameRateConversion (_film->video_frame_rate(), _film->dcp_frame_rate()).description); #ifdef HAVE_SWRESAMPLE - if (_film->audio_frame_rate() != _film->target_audio_sample_rate ()) { + if (_film->audio_frame_rate() && _film->audio_frame_rate() != _film->target_audio_sample_rate ()) { d << wxString::Format ( _("Audio will be resampled from %dHz to %dHz\n"), _film->audio_frame_rate(), diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 8fca8f370..d18083694 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -49,6 +49,7 @@ using std::cout; using std::list; using boost::shared_ptr; using boost::dynamic_pointer_cast; +using boost::weak_ptr; using libdcp::Size; FilmViewer::FilmViewer (shared_ptr f, wxWindow* p) @@ -146,6 +147,7 @@ FilmViewer::set_film (shared_ptr f) _player->Video.connect (bind (&FilmViewer::process_video, this, _1, _2, _3)); _film->Changed.connect (boost::bind (&FilmViewer::film_changed, this, _1)); + _film->ContentChanged.connect (boost::bind (&FilmViewer::film_content_changed, this, _1, _2)); film_changed (Film::CONTENT); film_changed (Film::FORMAT); @@ -431,3 +433,12 @@ FilmViewer::active_jobs_changed (bool a) _play_button->Enable (!a); } +void +FilmViewer::film_content_changed (weak_ptr, int p) +{ + if (p == VideoContentProperty::VIDEO_LENGTH) { + /* Force an update to our frame */ + wxScrollEvent ev; + slider_moved (ev); + } +} diff --git a/src/wx/film_viewer.h b/src/wx/film_viewer.h index 0f7b142b5..0ce8a526e 100644 --- a/src/wx/film_viewer.h +++ b/src/wx/film_viewer.h @@ -61,6 +61,7 @@ public: private: void film_changed (Film::Property); + void film_content_changed (boost::weak_ptr, int); void paint_panel (wxPaintEvent &); void panel_sized (wxSizeEvent &); void slider_moved (wxScrollEvent &); -- cgit v1.2.3 From bb1251a3b0abe2343962e126b690d97ebf8394c5 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 10 Apr 2013 19:52:20 +0100 Subject: Fix the merge. --- src/lib/format.cc | 2 +- test/test.cc | 26 -------------------------- 2 files changed, 1 insertion(+), 27 deletions(-) (limited to 'src') diff --git a/src/lib/format.cc b/src/lib/format.cc index cce8762bd..3d18edb3e 100644 --- a/src/lib/format.cc +++ b/src/lib/format.cc @@ -200,7 +200,7 @@ FixedFormat::FixedFormat (int r, libdcp::Size dcp, string id, string n, string d int Format::dcp_padding (shared_ptr f) const { - int p = rint ((_dcp_size.width - (_dcp_size.height * ratio(f))) / 2.0); + int p = rint ((_dcp_size.width - (_dcp_size.height * ratio_as_float(f))) / 2.0); /* This comes out -ve for Scope; bodge it */ if (p < 0) { diff --git a/test/test.cc b/test/test.cc index 4d25d50f8..592bad836 100644 --- a/test/test.cc +++ b/test/test.cc @@ -197,32 +197,6 @@ BOOST_AUTO_TEST_CASE (format_test) // BOOST_CHECK_EQUAL (f->ratio_as_integer(shared_ptr ()), 239); } -/* Test VariableFormat-based scaling of content */ -BOOST_AUTO_TEST_CASE (scaling_test) -{ - shared_ptr film (new Film (test_film_dir ("scaling_test").string(), false)); - - /* 4:3 ratio */ - film->set_size (libdcp::Size (320, 240)); - - /* This format should preserve aspect ratio of the source */ - Format const * format = Format::from_id ("var-185"); - - /* We should have enough padding that the result is 4:3, - which would be 1440 pixels. - */ - BOOST_CHECK_EQUAL (format->dcp_padding (film), (1998 - 1440) / 2); - - /* This crops it to 1.291666667 */ - film->set_left_crop (5); - film->set_right_crop (5); - - /* We should now have enough padding that the result is 1.29166667, - which would be 1395 pixels. - */ - BOOST_CHECK_EQUAL (format->dcp_padding (film), rint ((1998 - 1395) / 2.0)); -} - BOOST_AUTO_TEST_CASE (util_test) { string t = "Hello this is a string \"with quotes\" and indeed without them"; -- cgit v1.2.3 From 8f1c131a933e7695684e22eb82abba30fe119915 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 10 Apr 2013 20:17:52 +0100 Subject: Fix typo. --- src/lib/ffmpeg_content.cc | 1 + src/lib/playlist.cc | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index d36abe2c3..0424fbc33 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -31,6 +31,7 @@ using std::string; using std::stringstream; using std::vector; using std::list; +using std::cout; using boost::shared_ptr; using boost::lexical_cast; diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index d26dae730..717c1dace 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -132,7 +132,7 @@ Playlist::audio_frame_rate () const { shared_ptr fc = first_ffmpeg (); if (fc) { - return fc->audio_channels (); + return fc->audio_frame_rate (); } break; } -- cgit v1.2.3 From 4dee3db5222be7972930dbc621e9ab15a81d33d2 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 10 Apr 2013 20:45:07 +0100 Subject: Remove believed unnecessary audio channel layout stuff for resampler. --- src/lib/audio_content.h | 2 -- src/lib/encoder.cc | 13 ++++++++++--- src/lib/ffmpeg_content.cc | 16 +++------------- src/lib/ffmpeg_content.h | 11 +++-------- src/lib/ffmpeg_decoder.cc | 2 +- src/lib/film.cc | 6 ------ src/lib/film.h | 1 - src/lib/imagemagick_decoder.h | 12 ------------ src/lib/playlist.cc | 22 ---------------------- src/lib/playlist.h | 1 - src/lib/sndfile_content.h | 4 ---- 11 files changed, 17 insertions(+), 73 deletions(-) (limited to 'src') diff --git a/src/lib/audio_content.h b/src/lib/audio_content.h index d5dbf266b..dbd55943d 100644 --- a/src/lib/audio_content.h +++ b/src/lib/audio_content.h @@ -45,8 +45,6 @@ public: virtual int audio_channels () const = 0; virtual ContentAudioFrame audio_length () const = 0; virtual int audio_frame_rate () const = 0; - virtual int64_t audio_channel_layout () const = 0; - }; #endif diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 46d11c556..b897c8a31 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -86,13 +86,20 @@ Encoder::process_begin () s << String::compose (N_("Will resample audio from %1 to %2"), _film->audio_frame_rate(), _film->target_audio_sample_rate()); _film->log()->log (s.str ()); - /* We will be using planar float data when we call the resampler */ + /* We will be using planar float data when we call the + resampler. As far as I can see, the audio channel + layout is not necessary for our purposes; it seems + only to be used get the number of channels and + decide if rematrixing is needed. It won't be, since + input and output layouts are the same. + */ + _swr_context = swr_alloc_set_opts ( 0, - _film->audio_channel_layout(), + av_get_default_channel_layout (_film->audio_channels ()), AV_SAMPLE_FMT_FLTP, _film->target_audio_sample_rate(), - _film->audio_channel_layout(), + av_get_default_channel_layout (_film->audio_channels ()), AV_SAMPLE_FMT_FLTP, _film->audio_frame_rate(), 0, 0 diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index 0424fbc33..577dbd14d 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -216,7 +216,7 @@ FFmpegContent::audio_channels () const return 0; } - return _audio_stream->channels (); + return _audio_stream->channels; } int @@ -229,16 +229,6 @@ FFmpegContent::audio_frame_rate () const return _audio_stream->frame_rate; } -int64_t -FFmpegContent::audio_channel_layout () const -{ - if (!_audio_stream) { - return 0; - } - - return _audio_stream->channel_layout; -} - bool operator== (FFmpegSubtitleStream const & a, FFmpegSubtitleStream const & b) { @@ -256,7 +246,7 @@ FFmpegAudioStream::FFmpegAudioStream (shared_ptr node) name = node->string_child ("Name"); id = node->number_child ("Id"); frame_rate = node->number_child ("FrameRate"); - channel_layout = node->number_child ("ChannelLayout"); + channels = node->number_child ("Channels"); } void @@ -265,7 +255,7 @@ FFmpegAudioStream::as_xml (xmlpp::Node* root) const root->add_child("Name")->add_child_text (name); root->add_child("Id")->add_child_text (lexical_cast (id)); root->add_child("FrameRate")->add_child_text (lexical_cast (frame_rate)); - root->add_child("ChannelLayout")->add_child_text (lexical_cast (channel_layout)); + root->add_child("Channels")->add_child_text (lexical_cast (channels)); } /** Construct a SubtitleStream from a value returned from to_string(). diff --git a/src/lib/ffmpeg_content.h b/src/lib/ffmpeg_content.h index cc603e680..b49e5790e 100644 --- a/src/lib/ffmpeg_content.h +++ b/src/lib/ffmpeg_content.h @@ -27,25 +27,21 @@ class FFmpegAudioStream { public: - FFmpegAudioStream (std::string n, int i, int f, int64_t c) + FFmpegAudioStream (std::string n, int i, int f, int c) : name (n) , id (i) , frame_rate (f) - , channel_layout (c) + , channels (c) {} FFmpegAudioStream (boost::shared_ptr); void as_xml (xmlpp::Node *) const; - int channels () const { - return av_get_channel_layout_nb_channels (channel_layout); - } - std::string name; int id; int frame_rate; - int64_t channel_layout; + int channels; }; extern bool operator== (FFmpegAudioStream const & a, FFmpegAudioStream const & b); @@ -98,7 +94,6 @@ public: int audio_channels () const; ContentAudioFrame audio_length () const; int audio_frame_rate () const; - int64_t audio_channel_layout () const; std::vector subtitle_streams () const { boost::mutex::scoped_lock lm (_mutex); diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index d0b1de748..eac1d91ae 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -143,7 +143,7 @@ FFmpegDecoder::setup_general () } _audio_streams.push_back ( - FFmpegAudioStream (stream_name (s), i, s->codec->sample_rate, s->codec->channel_layout) + FFmpegAudioStream (stream_name (s), i, s->codec->sample_rate, s->codec->channels) ); } else if (s->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) { diff --git a/src/lib/film.cc b/src/lib/film.cc index 35a07b399..5f1b89d0c 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -1131,12 +1131,6 @@ Film::audio_frame_rate () const return _playlist->audio_frame_rate (); } -int64_t -Film::audio_channel_layout () const -{ - return _playlist->audio_channel_layout (); -} - bool Film::has_audio () const { diff --git a/src/lib/film.h b/src/lib/film.h index 532d32bdc..4d994996e 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -106,7 +106,6 @@ public: ContentAudioFrame audio_length () const; int audio_channels () const; int audio_frame_rate () const; - int64_t audio_channel_layout () const; bool has_audio () const; float video_frame_rate () const; diff --git a/src/lib/imagemagick_decoder.h b/src/lib/imagemagick_decoder.h index 52c7bec18..40a89bb15 100644 --- a/src/lib/imagemagick_decoder.h +++ b/src/lib/imagemagick_decoder.h @@ -37,18 +37,6 @@ public: libdcp::Size native_size () const; ContentVideoFrame video_length () const; - int audio_channels () const { - return 0; - } - - int audio_sample_rate () const { - return 0; - } - - int64_t audio_channel_layout () const { - return 0; - } - bool seek (double); bool pass (); diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index 717c1dace..f346cb6e0 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -143,28 +143,6 @@ Playlist::audio_frame_rate () const return 0; } -int64_t -Playlist::audio_channel_layout () const -{ - /* XXX: assuming that all content has the same layout */ - - switch (_audio_from) { - case AUDIO_FFMPEG: - { - shared_ptr fc = first_ffmpeg (); - if (fc) { - return fc->audio_channel_layout (); - } - break; - } - case AUDIO_SNDFILE: - /* XXX */ - return 0; - } - - return 0; -} - float Playlist::video_frame_rate () const { diff --git a/src/lib/playlist.h b/src/lib/playlist.h index 4dd27f675..6384dce1c 100644 --- a/src/lib/playlist.h +++ b/src/lib/playlist.h @@ -47,7 +47,6 @@ public: ContentAudioFrame audio_length () const; int audio_channels () const; int audio_frame_rate () const; - int64_t audio_channel_layout () const; bool has_audio () const; float video_frame_rate () const; diff --git a/src/lib/sndfile_content.h b/src/lib/sndfile_content.h index 27c5f3615..e8e86b603 100644 --- a/src/lib/sndfile_content.h +++ b/src/lib/sndfile_content.h @@ -58,10 +58,6 @@ public: return _audio_frame_rate; } - int64_t audio_channel_layout () const { - return av_get_default_channel_layout (audio_channels ()); - } - static bool valid_file (boost::filesystem::path); private: -- cgit v1.2.3 From 4461bdec05261dfc9cdd7639dad13c6ced4cbc35 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 10 Apr 2013 23:46:31 +0100 Subject: Fix thinko. --- branch-notes | 1 + src/wx/film_editor.cc | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 branch-notes (limited to 'src') diff --git a/branch-notes b/branch-notes new file mode 100644 index 000000000..05d275ffc --- /dev/null +++ b/branch-notes @@ -0,0 +1 @@ +no subs in viewer on e.g. creating new arrietty_EN-EN diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index c03a13bfe..f960abcfa 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -842,7 +842,7 @@ FilmEditor::dcp_content_type_changed (wxCommandEvent &) void FilmEditor::set_film (shared_ptr f) { - set_things_sensitive (_film != 0); + set_things_sensitive (f != 0); if (_film == f) { return; -- cgit v1.2.3 From 9e8a216241509cdd0b72ea0a35a280a9f93a3ef1 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 11 Apr 2013 12:16:27 +0100 Subject: Static / wx2.8 fixes. --- src/lib/wscript | 2 ++ src/tools/dvdomatic.cc | 2 +- src/wx/audio_mapping_view.cc | 16 ++++++++++------ wscript | 1 + 4 files changed, 14 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/lib/wscript b/src/lib/wscript index 8f0e851e3..2a26c2bfe 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -75,6 +75,8 @@ def build(bld): """ if bld.env.TARGET_WINDOWS: obj.uselib += ' WINSOCK2' + if bld.env.STATIC: + obj.uselib += ' XML++' obj.source = sources + " version.cc" obj.target = 'dvdomatic' diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 3fc19a91c..768819abc 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -554,7 +554,7 @@ class App : public wxApp bool OnCmdLineParsed (wxCmdLineParser& parser) { if (parser.GetParamCount() > 0) { - if (parser.FoundSwitch (wxT ("new"))) { + if (parser.Found (wxT ("new"))) { film_to_create = wx_to_std (parser.GetParam (0)); } else { film_to_load = wx_to_std (parser.GetParam(0)); diff --git a/src/wx/audio_mapping_view.cc b/src/wx/audio_mapping_view.cc index d62609d22..a5dacdfc2 100644 --- a/src/wx/audio_mapping_view.cc +++ b/src/wx/audio_mapping_view.cc @@ -62,7 +62,7 @@ public: wxRendererNative::Get().DrawCheckBox ( &grid, dc, rect, - grid.GetCellValue (row, col) == "1" ? static_cast(wxCONTROL_CHECKED) : 0 + grid.GetCellValue (row, col) == wxT("1") ? static_cast(wxCONTROL_CHECKED) : 0 ); } @@ -84,7 +84,11 @@ AudioMappingView::AudioMappingView (wxWindow* parent) _grid = new wxGrid (this, wxID_ANY); _grid->CreateGrid (0, 7); +#if wxMINOR_VERSION == 9 _grid->HideRowLabels (); +#else + _grid->SetRowLabelSize (0); +#endif _grid->DisableDragRowSize (); _grid->DisableDragColSize (); _grid->EnableEditing (false); @@ -115,10 +119,10 @@ AudioMappingView::left_click (wxGridEvent& ev) return; } - if (_grid->GetCellValue (ev.GetRow(), ev.GetCol()) == "1") { - _grid->SetCellValue (ev.GetRow(), ev.GetCol(), "0"); + if (_grid->GetCellValue (ev.GetRow(), ev.GetCol()) == wxT("1")) { + _grid->SetCellValue (ev.GetRow(), ev.GetCol(), wxT("0")); } else { - _grid->SetCellValue (ev.GetRow(), ev.GetCol(), "1"); + _grid->SetCellValue (ev.GetRow(), ev.GetCol(), wxT("1")); } } @@ -142,11 +146,11 @@ AudioMappingView::set_mapping (AudioMapping map) for (list::iterator i = content_channels.begin(); i != content_channels.end(); ++i) { shared_ptr ac = i->content.lock (); assert (ac); - _grid->SetCellValue (n, 0, wxString::Format ("%s %d", std_to_wx (ac->file().filename().string()), i->index + 1)); + _grid->SetCellValue (n, 0, wxString::Format (wxT("%s %d"), std_to_wx (ac->file().filename().string()).data(), i->index + 1)); list const d = map.content_to_dcp (*i); for (list::const_iterator j = d.begin(); j != d.end(); ++j) { - _grid->SetCellValue (n, static_cast (*j) + 1, "1"); + _grid->SetCellValue (n, static_cast (*j) + 1, wxT("1")); } ++n; } diff --git a/wscript b/wscript index 3f3ae2019..502f27fd1 100644 --- a/wscript +++ b/wscript @@ -75,6 +75,7 @@ def configure(conf): conf.env.LIB_DCP = ['glibmm-2.4', 'xml++-2.6', 'ssl', 'crypto', 'bz2'] conf.env.HAVE_CXML = 1 conf.env.STLIB_CXML = ['cxml'] + conf.check_cfg(package = 'libxml++-2.6', args = '--cflags --libs', uselib_store = 'XML++', mandatory = True) conf.env.HAVE_AVFORMAT = 1 conf.env.STLIB_AVFORMAT = ['avformat'] conf.env.HAVE_AVFILTER = 1 -- cgit v1.2.3 From 4be3d8475b09da7e0e0849b9e99cc0ca91e763a7 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 11 Apr 2013 12:39:51 +0100 Subject: More trying to fix static build. --- src/tools/wscript | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/tools/wscript b/src/tools/wscript index 9f0f52152..9cc7e9d1b 100644 --- a/src/tools/wscript +++ b/src/tools/wscript @@ -6,7 +6,7 @@ import i18n def build(bld): for t in ['makedcp', 'servomatic_cli', 'servomatictest']: obj = bld(features = 'cxx cxxprogram') - obj.uselib = 'BOOST_THREAD OPENJPEG DCP AVFORMAT AVFILTER AVCODEC AVUTIL SWSCALE POSTPROC' + obj.uselib = 'BOOST_THREAD OPENJPEG DCP CXML AVFORMAT AVFILTER AVCODEC AVUTIL SWSCALE POSTPROC' obj.includes = ['..'] obj.use = ['libdvdomatic'] obj.source = '%s.cc' % t @@ -15,7 +15,7 @@ def build(bld): if not bld.env.DISABLE_GUI: for t in ['dvdomatic', 'servomatic_gui']: obj = bld(features = 'cxx cxxprogram') - obj.uselib = 'DCP OPENJPEG AVFORMAT AVFILTER AVCODEC AVUTIL SWSCALE POSTPROC' + obj.uselib = 'DCP CXML OPENJPEG AVFORMAT AVFILTER AVCODEC AVUTIL SWSCALE POSTPROC' obj.includes = ['..'] obj.use = ['libdvdomatic', 'libdvdomatic-wx'] obj.source = '%s.cc' % t -- cgit v1.2.3 From 164bf3eaae49f654d609c747850b3f564fa20102 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 11 Apr 2013 14:24:52 +0100 Subject: Try to fix lack of subs in the viewer after they are turned on. --- src/lib/player.cc | 2 +- src/lib/transcoder.cc | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/player.cc b/src/lib/player.cc index c66d091cf..92c2929ac 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -197,7 +197,7 @@ Player::setup_decoders () new FFmpegDecoder ( _film, fc, _video, _audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG, - _subtitles && _film->with_subtitles(), + _subtitles, _video_sync ) ); diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc index 6744e9193..e0e127d33 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -56,6 +56,10 @@ Transcoder::Transcoder (shared_ptr f, shared_ptr j) _gain.reset (new Gain (f->log(), f->audio_gain())); } + if (!f->with_subtitles ()) { + _player->disable_subtitles (); + } + if (_matcher) { _player->connect_video (_matcher); _matcher->connect_video (_encoder); -- cgit v1.2.3 From 9b7df719c56b956e8a2aed336677550b64780c5a Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 11 Apr 2013 21:01:46 +0100 Subject: Fix audio display to only offer available channels. --- src/wx/audio_dialog.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/wx/audio_dialog.cc b/src/wx/audio_dialog.cc index bfd92f0b6..bed7aac6d 100644 --- a/src/wx/audio_dialog.cc +++ b/src/wx/audio_dialog.cc @@ -43,7 +43,6 @@ AudioDialog::AudioDialog (wxWindow* parent) wxStaticText* m = new wxStaticText (this, wxID_ANY, _("Channels")); side->Add (m, 1, wxALIGN_CENTER_VERTICAL | wxTOP, 16); } - for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) { _channel_checkbox[i] = new wxCheckBox (this, wxID_ANY, std_to_wx (audio_channel_name (i))); @@ -91,6 +90,10 @@ AudioDialog::set_film (shared_ptr f) _film = f; + for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) { + _channel_checkbox[i]->Show (!_film->audio_mapping().dcp_to_content (static_cast (i)).empty()); + } + try_to_load_analysis (); _plot->set_gain (_film->audio_gain ()); @@ -116,7 +119,9 @@ AudioDialog::try_to_load_analysis () _plot->set_analysis (a); - _channel_checkbox[0]->SetValue (true); + if (_channel_checkbox[0]) { + _channel_checkbox[0]->SetValue (true); + } _plot->set_channel_visible (0, true); for (int i = 0; i < AudioPoint::COUNT; ++i) { -- cgit v1.2.3 From eb6efc4dbae63b90a7389f9818676279945cdafa Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 12 Apr 2013 00:19:53 +0100 Subject: Restore digests for content. --- src/lib/content.h | 5 +++++ src/lib/film.cc | 9 ++------- src/lib/playlist.cc | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/lib/playlist.h | 3 +++ 4 files changed, 54 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/lib/content.h b/src/lib/content.h index fc2672c95..c8aa6b0e0 100644 --- a/src/lib/content.h +++ b/src/lib/content.h @@ -51,6 +51,11 @@ public: return _file; } + std::string digest () const { + boost::mutex::scoped_lock lm (_mutex); + return _digest; + } + boost::signals2::signal, int)> Changed; protected: diff --git a/src/lib/film.cc b/src/lib/film.cc index 5f1b89d0c..6ab6551da 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -192,15 +192,11 @@ Film::video_state_identifier () const { assert (format ()); - return "XXX"; - -#if 0 - pair f = Filter::ffmpeg_strings (filters()); stringstream s; s << format()->id() - << "_" << content_digest() + << "_" << _playlist->video_digest() << "_" << crop().left << "_" << crop().right << "_" << crop().top << "_" << crop().bottom << "_" << _dcp_frame_rate << "_" << f.first << "_" << f.second @@ -214,7 +210,6 @@ Film::video_state_identifier () const } return s.str (); -#endif } /** @return The path to the directory to write video frame info files to */ @@ -245,7 +240,7 @@ Film::audio_analysis_path () const { boost::filesystem::path p; p /= "analysis"; - p /= "XXX";//content_digest(); + p /= _playlist->audio_digest(); return file (p.string ()); } diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index f346cb6e0..58086d02b 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -18,6 +18,7 @@ */ #include +#include #include "playlist.h" #include "sndfile_content.h" #include "sndfile_decoder.h" @@ -32,9 +33,11 @@ using std::cout; using std::vector; using std::min; using std::max; +using std::string; using boost::shared_ptr; using boost::weak_ptr; using boost::dynamic_pointer_cast; +using boost::lexical_cast; Playlist::Playlist () : _audio_from (AUDIO_FFMPEG) @@ -251,3 +254,44 @@ Playlist::default_audio_mapping () const return m; } + +string +Playlist::audio_digest () const +{ + string t; + + switch (_audio_from) { + case AUDIO_FFMPEG: + for (list >::const_iterator i = _video.begin(); i != _video.end(); ++i) { + shared_ptr fc = dynamic_pointer_cast (*i); + if (fc) { + t += (*i)->digest (); + t += lexical_cast (fc->audio_stream()->id); + } + } + break; + case AUDIO_SNDFILE: + for (list >::const_iterator i = _sndfile.begin(); i != _sndfile.end(); ++i) { + t += (*i)->digest (); + } + break; + } + + return md5_digest (t.c_str(), t.length()); +} + +string +Playlist::video_digest () const +{ + string t; + + for (list >::const_iterator i = _video.begin(); i != _video.end(); ++i) { + t += (*i)->digest (); + shared_ptr fc = dynamic_pointer_cast (*i); + if (fc) { + t += fc->subtitle_stream()->id; + } + } + + return md5_digest (t.c_str(), t.length()); +} diff --git a/src/lib/playlist.h b/src/lib/playlist.h index 6384dce1c..d1f766d55 100644 --- a/src/lib/playlist.h +++ b/src/lib/playlist.h @@ -72,6 +72,9 @@ public: return _sndfile; } + std::string audio_digest () const; + std::string video_digest () const; + mutable boost::signals2::signal Changed; mutable boost::signals2::signal, int)> ContentChanged; -- cgit v1.2.3 From 6fe31ddd16a0819fe38ffb7e9520c6a049af078a Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 12 Apr 2013 00:21:30 +0100 Subject: Fix typo. --- src/lib/format.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/format.cc b/src/lib/format.cc index 2f9f87ba9..640eee167 100644 --- a/src/lib/format.cc +++ b/src/lib/format.cc @@ -84,7 +84,7 @@ Format::setup_formats () )); _formats.push_back ( - new FixedFormat (4.0 / 30, libdcp::Size (1998, 1080), N_("133-in-flat"), _("4:3 within Flat"), N_("F") + new FixedFormat (4.0 / 3.0, libdcp::Size (1998, 1080), N_("133-in-flat"), _("4:3 within Flat"), N_("F") )); _formats.push_back ( -- cgit v1.2.3 From 4ff62d6f1a2faeb5985fa5bddb9b65e6e549e825 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 12 Apr 2013 20:10:34 +0100 Subject: Fix crash on encoding with no subs. --- src/lib/playlist.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index 58086d02b..7fe4fb2a5 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -288,7 +288,7 @@ Playlist::video_digest () const for (list >::const_iterator i = _video.begin(); i != _video.end(); ++i) { t += (*i)->digest (); shared_ptr fc = dynamic_pointer_cast (*i); - if (fc) { + if (fc && fc->subtitle_stream()) { t += fc->subtitle_stream()->id; } } -- cgit v1.2.3 From 9303bb36391c2ce3c471dafffefbcbbaf3995be0 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 12 Apr 2013 20:29:17 +0100 Subject: Seems wrong to try to complete an encode if it has thrown an exception. --- src/lib/transcoder.cc | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc index e0e127d33..2a8ce5044 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -79,19 +79,13 @@ void Transcoder::go () { _encoder->process_begin (); - try { - while (1) { - if (_player->pass ()) { - break; - } - _player->set_progress (_job); + while (1) { + if (_player->pass ()) { + break; } - - } catch (...) { - _encoder->process_end (); - throw; + _player->set_progress (_job); } - + if (_delay_line) { _delay_line->process_end (); } -- cgit v1.2.3 From 8218bf98ca1ec9399a968e57f416e110e14d5d9f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 12 Apr 2013 20:29:27 +0100 Subject: Catch exceptions when checking disk space. --- src/lib/job.cc | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/lib/job.cc b/src/lib/job.cc index ff0332d6d..f830975af 100644 --- a/src/lib/job.cc +++ b/src/lib/job.cc @@ -68,11 +68,15 @@ Job::run_wrapper () set_state (FINISHED_ERROR); string m = String::compose (_("An error occurred whilst handling the file %1."), boost::filesystem::path (e.filename()).leaf()); - - boost::filesystem::space_info const s = boost::filesystem::space (e.filename()); - if (s.available < pow (1024, 3)) { - m += N_("\n\n"); - m += _("The drive that the film is stored on is low in disc space. Free some more space and try again."); + + try { + boost::filesystem::space_info const s = boost::filesystem::space (e.filename()); + if (s.available < pow (1024, 3)) { + m += N_("\n\n"); + m += _("The drive that the film is stored on is low in disc space. Free some more space and try again."); + } + } catch (...) { + } set_error (e.what(), m); -- cgit v1.2.3 From 7ee21d16c01b90c22192cd10f118419881fe504e Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 13 Apr 2013 12:53:40 +0100 Subject: DVD-o-matic -> DCP-o-matic. --- Doxyfile | 2 +- README | 13 +- TODO | 137 ------ builds/control-12.04-32 | 8 +- builds/control-12.04-64 | 8 +- builds/control-12.10-32 | 8 +- builds/control-12.10-64 | 8 +- cscript | 14 +- cscript.py | 8 - debian/changelog | 136 +++--- debian/copyright | 4 +- debian/files | 2 +- debian/rules | 2 +- doc/mainpage.txt | 20 +- doc/manual/Makefile | 22 +- doc/manual/dvdomatic-html.xsl | 12 - doc/manual/dvdomatic-pdf.xsl | 17 - doc/manual/dvdomatic.css | 19 - doc/manual/dvdomatic.sty | 68 --- doc/manual/dvdomatic.xml | 932 ------------------------------------- dvdomatic.desktop.in | 10 - hacks/python-playback/config.py | 2 - hacks/python-playback/dvdomatic | 209 --------- hacks/python-playback/film.py | 188 -------- hacks/python-playback/film_view.py | 212 --------- hacks/python-playback/player.py | 112 ----- hacks/python-playback/ratio.py | 56 --- hacks/python-playback/screens | 62 --- hacks/python-playback/screens.py | 85 ---- hacks/python-playback/thumbs.py | 76 --- hacks/python-playback/util.py | 7 - hacks/python-playback/xrandr-notes | 17 - icons/128x128/dvdomatic.png | Bin 18365 -> 0 bytes icons/16x16/dvdomatic.png | Bin 211 -> 0 bytes icons/22x22/dvdomatic.png | Bin 994 -> 0 bytes icons/32x32/dvdomatic.png | Bin 1747 -> 0 bytes icons/48x48/dvdomatic.png | Bin 3407 -> 0 bytes icons/64x64/dvdomatic.png | Bin 5421 -> 0 bytes run/dvdomatic | 15 - src/lib/audio_analysis.h | 4 +- src/lib/audio_content.h | 4 +- src/lib/audio_decoder.h | 4 +- src/lib/audio_mapping.h | 4 +- src/lib/audio_sink.h | 4 +- src/lib/audio_source.h | 4 +- src/lib/config.cc | 4 +- src/lib/config.h | 4 +- src/lib/content.h | 4 +- src/lib/cross.cc | 10 +- src/lib/cross.h | 4 +- src/lib/dci_metadata.h | 4 +- src/lib/dcp_content_type.h | 4 +- src/lib/dcp_video_frame.cc | 2 +- src/lib/decoder.h | 4 +- src/lib/encoder.cc | 2 +- src/lib/encoder.h | 4 +- src/lib/exceptions.h | 4 +- src/lib/ffmpeg_content.h | 4 +- src/lib/film.cc | 10 +- src/lib/film.h | 6 +- src/lib/filter.h | 4 +- src/lib/filter_graph.h | 4 +- src/lib/i18n.h | 2 +- src/lib/image.h | 4 +- src/lib/job.cc | 4 +- src/lib/job.h | 4 +- src/lib/job_manager.cc | 2 +- src/lib/log.h | 4 +- src/lib/player.h | 4 +- src/lib/po/es_ES.po | 6 +- src/lib/po/fr_FR.po | 8 +- src/lib/po/it_IT.po | 4 +- src/lib/po/sv_SE.po | 6 +- src/lib/processor.h | 4 +- src/lib/scaler.h | 4 +- src/lib/sound_processor.h | 4 +- src/lib/timer.h | 4 +- src/lib/types.h | 4 +- src/lib/ui_signaller.h | 4 +- src/lib/util.cc | 28 +- src/lib/util.h | 14 +- src/lib/version.h | 4 +- src/lib/video_content.h | 4 +- src/lib/video_decoder.h | 4 +- src/lib/video_sink.h | 4 +- src/lib/video_source.h | 4 +- src/lib/wscript | 10 +- src/tools/dvdomatic.cc | 578 ----------------------- src/tools/makedcp.cc | 12 +- src/tools/po/es_ES.po | 58 +-- src/tools/po/fr_FR.po | 58 +-- src/tools/po/it_IT.po | 56 +-- src/tools/po/sv_SE.po | 58 +-- src/tools/servomatic_cli.cc | 4 +- src/tools/servomatic_gui.cc | 6 +- src/tools/servomatictest.cc | 2 +- src/tools/wscript | 14 +- src/wx/audio_dialog.cc | 2 +- src/wx/config_dialog.cc | 6 +- src/wx/config_dialog.h | 4 +- src/wx/po/es_ES.po | 16 +- src/wx/po/fr_FR.po | 16 +- src/wx/po/it_IT.po | 16 +- src/wx/po/sv_SE.po | 18 +- src/wx/wscript | 12 +- src/wx/wx_util.cc | 2 +- test/test.cc | 14 +- test/wscript | 2 +- windows/dvdomatic.bmp | Bin 343254 -> 0 bytes windows/dvdomatic.ico | Bin 9662 -> 0 bytes windows/dvdomatic.rc | 3 - windows/dvdomatic_taskbar.ico | Bin 1150 -> 0 bytes windows/installer.nsi.32.in | 70 +-- windows/installer.nsi.64.in | 72 +-- wscript | 24 +- 115 files changed, 515 insertions(+), 3345 deletions(-) delete mode 100644 TODO delete mode 100644 cscript.py delete mode 100644 doc/manual/dvdomatic-html.xsl delete mode 100644 doc/manual/dvdomatic-pdf.xsl delete mode 100644 doc/manual/dvdomatic.css delete mode 100644 doc/manual/dvdomatic.sty delete mode 100644 doc/manual/dvdomatic.xml delete mode 100644 dvdomatic.desktop.in delete mode 100644 hacks/python-playback/config.py delete mode 100755 hacks/python-playback/dvdomatic delete mode 100644 hacks/python-playback/film.py delete mode 100644 hacks/python-playback/film_view.py delete mode 100644 hacks/python-playback/player.py delete mode 100644 hacks/python-playback/ratio.py delete mode 100644 hacks/python-playback/screens delete mode 100644 hacks/python-playback/screens.py delete mode 100644 hacks/python-playback/thumbs.py delete mode 100644 hacks/python-playback/util.py delete mode 100644 hacks/python-playback/xrandr-notes delete mode 100644 icons/128x128/dvdomatic.png delete mode 100644 icons/16x16/dvdomatic.png delete mode 100644 icons/22x22/dvdomatic.png delete mode 100644 icons/32x32/dvdomatic.png delete mode 100644 icons/48x48/dvdomatic.png delete mode 100644 icons/64x64/dvdomatic.png delete mode 100755 run/dvdomatic delete mode 100644 src/tools/dvdomatic.cc delete mode 100644 windows/dvdomatic.bmp delete mode 100644 windows/dvdomatic.ico delete mode 100644 windows/dvdomatic.rc delete mode 100644 windows/dvdomatic_taskbar.ico (limited to 'src') diff --git a/Doxyfile b/Doxyfile index 56f7e1d3c..4ed65e4f1 100644 --- a/Doxyfile +++ b/Doxyfile @@ -26,7 +26,7 @@ DOXYFILE_ENCODING = UTF-8 # identify the project. Note that if you do not use Doxywizard you need # to put quotes around the project name if it contains spaces. -PROJECT_NAME = DVD-o-matic +PROJECT_NAME = DCP-o-matic # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or diff --git a/README b/README index fd3983c29..c218ed1a5 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -dvd-o-matic +DCP-o-matic ----------- Hello! @@ -33,27 +33,22 @@ You will need these libraries: libsndfile libssh -and also the command line tool: - - vobcopy (if you want to rip DVDs straight into DVD-o-matic) - Documentation ------------- -There is a manual available at http://carlh.net/software/dvdomatic +There is a manual available at http://carlh.net/software/dcpomatic The DocBook source for this is in doc/manual. In a nutshell ------------- -The `dvdomatic' program is a GTK front-end which is probably easiest +The `dcpomatic' program is a GTK front-end which is probably easiest to use. It will create a directory for a particular project, and write its data to that directory. The basic approach is: "File->New"; specify a directory. -Choose "Jobs->Copy from DVD" to read a DVD from your drive, if you have one. Fill in the fields in the window (most importantly the `content' field: specify your video, and the `Name' field: give your project [and hence DCP] a name.) @@ -76,7 +71,7 @@ Server/client ------------- Running the `servomatic' program on a remote machine will make it -listen on port 6192 (by default) and process requests from a dvdomatic +listen on port 6192 (by default) and process requests from a dcpomatic instance. This has been written with no thought to security, so don't do it over the public internet! The connection will probably need to be 1 Gb/s to make it worthwhile. diff --git a/TODO b/TODO deleted file mode 100644 index 17f02e429..000000000 --- a/TODO +++ /dev/null @@ -1,137 +0,0 @@ -Make a DCP with subs using subtitle edit. - -Look at http://liblqr.wikidot.com/en:manual - -EC2 - -Small instance $0.085 ph -Sintel Trailer 1080p @ 200000 Mbps -1247 frames @ 24fps ie 51.96s -Took 1h20 to encode - -High-CPU medium $0.186 ph -Sintel Trailer 1080p @ 200000 Mbps -1247 frames @ 24fps ie 51.96s -Took 23m to encode - -High-CPU extra-large $0.744 ph -Sintel Trailer 1080p @ 200000 Mbps -1247 frames @ 24fps ie 51.96s - - -Transfer in free -Transfer out $0.120 per GB - - -Port DVD rip - -Write still j2ks straight to a MXF. -md5_data to use openssl -Write all j2ks straight to a MXF? Possible? - -Standardise j2c/j2k -Format name in ~/.dvdomatic screws up with spaces; use ID or something -Thumbnails are poorly named -x-thread signaller -Restartable jobs somehow -More logging -Nice error when trying to thumbnail with no content. -Destroy _buffer_src_context / _buffer_sink_context -Don't start later jobs when one breaks. -Compute time remaining based on more recent information. -Use lexical_cast more -Do deps better - -options summary - -1: L -2: R -3: C -4: Lfe -5: Ls -6: Rs - -City Screen - -Screen 1: "1.37" masking preset, projector only has DCI 133 preset. - -With 1480x1080 alignment in DCI 133: bottom you see purple, yellow; top purple; left and right no lines -With 1480x1080 alignment in DCI Flat: outside masks, but you see bottom purple, yellow; left/right all; top purple - - -Screen 2: no real masking preset, projector has DCI 133 and DCI 137 - -1480x1080, DCI 133 -L yellow purple -R none -B purple -T none -1480x1080, DCI 137 -L all -R all but blue -T purple -B purple - - -Screen 3: projector has DCI 1.38 - -1480x1080 -L, R, T none -B purple + yellow - - -films-0.6: Dolby Countdown looks as though it's 3D. THX Terminator 2 fucked -(these on default settings) -fq/gradfun --- no obvious effect -hqdn3d --- pretty good denoising -ow --- no obvious effect -tn --- interesting; much noise reduction, bad artefacts on movement, colour tint even in black -unsharp --- worse - -Benchmark SWS options: lanczos ? -hqdn3d=0:0:6 ? (turn off chroma/luma blurring) - -Lanczos; no visible effect on Ghostbusters. - - -THX_Monster with master Intel Core 2 Duo E4600 (2.4GHz), slave Intel Core i3 M350 (2.27GHz) -1920 x 1080 original -> DCI Flat -240 frames - -[Gbit: gigabit ethernet rather than 100Mbit] -[im-mod: after modification to memcpy RGB data then to RGB -> XYZ in the encode thread -[hack1]: after modification to pass YUV and to swscale in the encode thread (includes im-mod) -[hack2]: modified hack1 - Time Seconds FPS Speedup relative to 1 local -1 local: 20m57 1257 0.19 x 1 -2 local: 11m24 684 0.35 x 1.84 -2 local [im-mod]: 13m13 -2 local + 1 slave: 6m34 394 0.61 x 3.19 -2 local + 2 slave: 5m13 313 0.77 x 4.02 -2 local + 4 slave: 5m05 303 0.79 x 4.15 -2 local + 4 slave [Gbit]: 2m50 170 1.41 x 7.39 -2 local + 4 slave [Gbit,im-mod]:2m33 -2 local + 4 slave [Gbit,hack1]: 3m20 -2 local + 4 slave [Gbit,hack2]: 2m22 -1 local + 8 slave [Gbit]: 2m28 148 1.62 x 8.49 -2 local + 8 slave [Gbit]: 2m41 161 1.49 x 7.81 -2 local + 8 slave [Gbit,im-mod]:2m35 - - - -Just encode 52s -Encode + Image create 1m27 -Encode + Image create (memcpy, not convert) 53s. - -THX_Monster with master Intel Core i3 M350 (2.27GHz), slave Intel Core 2 Duo E4600 (2.4GHz) -1920 x 1080 original -> DCI Flat -240 frames - - -4 local: 2m45 -4 local [im-mod]: 2m53 -4 local + 2 slave [Gbit]: 2m22 -4 local + 4 slave [Gbit]: 2m21 -4 local + 4 slave [Gbit,in-mod]:2m21 - - diff --git a/builds/control-12.04-32 b/builds/control-12.04-32 index 8cb5aceb3..d31a5e384 100644 --- a/builds/control-12.04-32 +++ b/builds/control-12.04-32 @@ -1,15 +1,15 @@ -Source: dvdomatic +Source: dcpomatic Section: video Priority: extra Maintainer: Carl Hetherington Build-Depends: debhelper (>= 8.0.0), python (>= 2.7.3), g++ (>= 4:4.6.3), pkg-config (>= 0.26), libwxgtk2.8-dev (>= 2.8.12.1), libssh-dev (>= 0.5.2), libboost-filesystem-dev (>= 1.46.0), libboost-thread-dev (>= 1.46.0), libsndfile1-dev (>= 1.0.25), libmagick++-dev (>= 8:6.6.9.7) Standards-Version: 3.9.3 -Homepage: http://carlh.net/software/dvdomatic +Homepage: http://carlh.net/software/dcpomatic -Package: dvdomatic +Package: dcpomatic Architecture: i386 Depends: libc6 (>= 2.15), libwxgtk2.8-0 (>= 2.8.12.1), libssh-4 (>= 0.5.2), libboost-filesystem1.46.1 (>= 1.46.1), libboost-thread1.46.1 (>= 1.46.1), libsndfile1 (>= 1.0.25), libmagick++4 (>= 8:6.6.9.7), libxml++2.6-2 (>= 2.34.1) Description: Generator of Digital Cinema Packages (DCPs) - DVD-o-matic generates Digital Cinema Packages (DCPs) from video and audio + DCP-o-matic generates Digital Cinema Packages (DCPs) from video and audio files (such as those from DVDs or Blu-Rays) for presentation on DCI-compliant digital projectors. diff --git a/builds/control-12.04-64 b/builds/control-12.04-64 index cdb15a87b..5d41558b6 100644 --- a/builds/control-12.04-64 +++ b/builds/control-12.04-64 @@ -1,15 +1,15 @@ -Source: dvdomatic +Source: dcpomatic Section: video Priority: extra Maintainer: Carl Hetherington Build-Depends: debhelper (>= 8.0.0), python (>= 2.7.3), g++ (>= 4:4.6.3), pkg-config (>= 0.26), libwxgtk2.8-dev (>= 2.8.12.1), libssh-dev (>= 0.5.2), libboost-filesystem-dev (>= 1.46.0), libboost-thread-dev (>= 1.46.0), libsndfile1-dev (>= 1.0.25), libmagick++-dev (>= 8:6.6.9.7) Standards-Version: 3.9.3 -Homepage: http://carlh.net/software/dvdomatic +Homepage: http://carlh.net/software/dcpomatic -Package: dvdomatic +Package: dcpomatic Architecture: amd64 Depends: libc6 (>= 2.15), libwxgtk2.8-0 (>= 2.8.12.1), libssh-4 (>= 0.5.2), libboost-filesystem1.46.1 (>= 1.46.1), libboost-thread1.46.1 (>= 1.46.1), libsndfile1 (>= 1.0.25), libmagick++4 (>= 8:6.6.9.7), libxml++2.6-2 (>= 2.34.1) Description: Generator of Digital Cinema Packages (DCPs) - DVD-o-matic generates Digital Cinema Packages (DCPs) from video and audio + DCP-o-matic generates Digital Cinema Packages (DCPs) from video and audio files (such as those from DVDs or Blu-Rays) for presentation on DCI-compliant digital projectors. diff --git a/builds/control-12.10-32 b/builds/control-12.10-32 index 1dc91b701..67933f2ed 100644 --- a/builds/control-12.10-32 +++ b/builds/control-12.10-32 @@ -1,15 +1,15 @@ -Source: dvdomatic +Source: dcpomatic Section: video Priority: extra Maintainer: Carl Hetherington Build-Depends: debhelper (>= 8.0.0), python (>= 2.7.3), g++ (>= 4:4.6.3), pkg-config (>= 0.26), libwxgtk2.8-dev (>= 2.8.12.1), libssh-dev (>= 0.5.2), libboost-filesystem-dev (>= 1.46.0), libboost-thread-dev (>= 1.46.0), libsndfile1-dev (>= 1.0.25), libmagick++-dev (>= 8:6.6.9.7) Standards-Version: 3.9.3 -Homepage: http://carlh.net/software/dvdomatic +Homepage: http://carlh.net/software/dcpomatic -Package: dvdomatic +Package: dcpomatic Architecture: i386 Depends: libc6 (>= 2.15), libwxgtk2.8-0 (>= 2.8.12.1), libssh-4 (>= 0.5.2), libboost-filesystem1.49.0 (>= 1.49.0), libboost-thread1.49.0 (>= 1.49.0), libsndfile1 (>= 1.0.25), libmagick++5 (>= 8:6.7.7.10), libxml++2.6-2 (>= 2.34.2) Description: Generator of Digital Cinema Packages (DCPs) - DVD-o-matic generates Digital Cinema Packages (DCPs) from video and audio + DCP-o-matic generates Digital Cinema Packages (DCPs) from video and audio files (such as those from DVDs or Blu-Rays) for presentation on DCI-compliant digital projectors. diff --git a/builds/control-12.10-64 b/builds/control-12.10-64 index ed0b36b2e..cddf80007 100644 --- a/builds/control-12.10-64 +++ b/builds/control-12.10-64 @@ -1,15 +1,15 @@ -Source: dvdomatic +Source: dcpomatic Section: video Priority: extra Maintainer: Carl Hetherington Build-Depends: debhelper (>= 8.0.0), python (>= 2.7.3), g++ (>= 4:4.6.3), pkg-config (>= 0.26), libwxgtk2.8-dev (>= 2.8.12.1), libssh-dev (>= 0.5.2), libboost-filesystem-dev (>= 1.46.0), libboost-thread-dev (>= 1.46.0), libsndfile1-dev (>= 1.0.25), libmagick++-dev (>= 8:6.6.9.7) Standards-Version: 3.9.3 -Homepage: http://carlh.net/software/dvdomatic +Homepage: http://carlh.net/software/dcpomatic -Package: dvdomatic +Package: dcpomatic Architecture: amd64 Depends: libc6 (>= 2.15), libwxgtk2.8-0 (>= 2.8.12.1), libssh-4 (>= 0.5.2), libboost-filesystem1.49.0 (>= 1.49.0), libboost-thread1.49.0 (>= 1.49.0), libsndfile1 (>= 1.0.25), libmagick++5 (>= 8:6.7.7.10), libxml++2.6-2 (>= 2.34.2) Description: Generator of Digital Cinema Packages (DCPs) - DVD-o-matic generates Digital Cinema Packages (DCPs) from video and audio + DCP-o-matic generates Digital Cinema Packages (DCPs) from video and audio files (such as those from DVDs or Blu-Rays) for presentation on DCI-compliant digital projectors. diff --git a/cscript b/cscript index 4873df654..07840c109 100644 --- a/cscript +++ b/cscript @@ -25,13 +25,13 @@ def build(environment, variant, version): shutil.copyfile(os.path.join('builds', 'control-%s' % variant), os.path.join('debian', 'control')) command('./waf dist') f = open(os.path.join('debian', 'files'), 'w') - print >>f,'dvdomatic_%s-1_%s.deb video extra' % (version, cpu) + print >>f,'dcpomatic_%s-1_%s.deb video extra' % (version, cpu) shutil.rmtree('build/deb', ignore_errors=True) os.makedirs('build/deb') os.chdir('build/deb') - shutil.move('../../dvdomatic-%s.tar.bz2' % version, 'dvdomatic_%s.orig.tar.bz2' % version) - command('tar xjf dvdomatic_%s.orig.tar.bz2' % version) - os.chdir('dvdomatic-%s' % version) + shutil.move('../../dcpomatic-%s.tar.bz2' % version, 'dcpomatic_%s.orig.tar.bz2' % version) + command('tar xjf dcpomatic_%s.orig.tar.bz2' % version) + os.chdir('dcpomatic-%s' % version) command('dch -b -v %s-1 "New upstream release."' % version) command('dpkg-source -b .') command('dpkg-buildpackage') @@ -39,9 +39,9 @@ def build(environment, variant, version): def make_pot(): command('./waf pot') - return [os.path.abspath('build/src/lib/libdvdomatic.pot'), - os.path.abspath('build/src/wx/libdvdomatic-wx.pot'), - os.path.abspath('build/src/tools/dvdomatic.pot')] + return [os.path.abspath('build/src/lib/libdcpomatic.pot'), + os.path.abspath('build/src/wx/libdcpomatic-wx.pot'), + os.path.abspath('build/src/tools/dcpomatic.pot')] def make_manual(): os.chdir('doc/manual') diff --git a/cscript.py b/cscript.py deleted file mode 100644 index 9b8fa46c0..000000000 --- a/cscript.py +++ /dev/null @@ -1,8 +0,0 @@ -import cdist - -def builds(): - return ['source'] - -def build_source(): - cdist.build_source_waf() - diff --git a/debian/changelog b/debian/changelog index d1cea437d..0a53eff15 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,298 +1,298 @@ -dvdomatic (0.83-1) UNRELEASED; urgency=low +dcpomatic (0.83-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Wed, 10 Apr 2013 12:48:25 +0100 -dvdomatic (0.82-1) UNRELEASED; urgency=low +dcpomatic (0.82-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Tue, 09 Apr 2013 23:43:35 +0100 -dvdomatic (0.82beta1-1) UNRELEASED; urgency=low +dcpomatic (0.82beta1-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Tue, 09 Apr 2013 21:48:56 +0100 -dvdomatic (0.81-1) UNRELEASED; urgency=low +dcpomatic (0.81-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Tue, 09 Apr 2013 19:48:04 +0100 -dvdomatic (0.81beta1-1) UNRELEASED; urgency=low +dcpomatic (0.81beta1-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Tue, 09 Apr 2013 15:37:32 +0100 -dvdomatic (0.80-1) UNRELEASED; urgency=low +dcpomatic (0.80-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Sun, 07 Apr 2013 23:48:12 +0100 -dvdomatic (0.80beta4-1) UNRELEASED; urgency=low +dcpomatic (0.80beta4-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Sun, 07 Apr 2013 23:08:49 +0100 -dvdomatic (0.80beta3-1) UNRELEASED; urgency=low +dcpomatic (0.80beta3-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Sun, 07 Apr 2013 22:44:29 +0100 -dvdomatic (0.80beta2-1) UNRELEASED; urgency=low +dcpomatic (0.80beta2-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Sun, 07 Apr 2013 22:19:34 +0100 -dvdomatic (0.80beta1-1) UNRELEASED; urgency=low +dcpomatic (0.80beta1-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Sun, 07 Apr 2013 18:21:33 +0100 -dvdomatic (0.79-1) UNRELEASED; urgency=low +dcpomatic (0.79-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Mon, 01 Apr 2013 22:37:03 +0100 -dvdomatic (0.78-1) UNRELEASED; urgency=low +dcpomatic (0.78-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Sun, 31 Mar 2013 02:43:03 +0100 -dvdomatic (0.78beta16-1) UNRELEASED; urgency=low +dcpomatic (0.78beta16-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Thu, 28 Mar 2013 16:28:05 +0000 -dvdomatic (0.78beta15-1) UNRELEASED; urgency=low +dcpomatic (0.78beta15-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Thu, 28 Mar 2013 14:25:56 +0000 -dvdomatic (0.78beta14-1) UNRELEASED; urgency=low +dcpomatic (0.78beta14-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Thu, 28 Mar 2013 10:38:07 +0000 -dvdomatic (0.78beta13-1) UNRELEASED; urgency=low +dcpomatic (0.78beta13-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Wed, 27 Mar 2013 12:26:55 +0000 -dvdomatic (0.78beta12-1) UNRELEASED; urgency=low +dcpomatic (0.78beta12-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Tue, 26 Mar 2013 21:13:54 +0000 -dvdomatic (0.78beta11-1) UNRELEASED; urgency=low +dcpomatic (0.78beta11-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Tue, 26 Mar 2013 17:34:49 +0000 -dvdomatic (0.78beta10-1) UNRELEASED; urgency=low +dcpomatic (0.78beta10-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Tue, 26 Mar 2013 11:35:15 +0000 -dvdomatic (0.78beta9-1) UNRELEASED; urgency=low +dcpomatic (0.78beta9-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Tue, 26 Mar 2013 10:36:05 +0000 -dvdomatic (0.78beta8-1) UNRELEASED; urgency=low +dcpomatic (0.78beta8-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Tue, 26 Mar 2013 00:59:36 +0000 -dvdomatic (0.78beta7-1) UNRELEASED; urgency=low +dcpomatic (0.78beta7-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Tue, 26 Mar 2013 00:19:21 +0000 -dvdomatic (0.78beta6-1) UNRELEASED; urgency=low +dcpomatic (0.78beta6-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Mon, 25 Mar 2013 00:08:10 +0000 -dvdomatic (0.78beta5-1) UNRELEASED; urgency=low +dcpomatic (0.78beta5-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Thu, 21 Mar 2013 16:32:21 +0000 -dvdomatic (0.78beta4-1) UNRELEASED; urgency=low +dcpomatic (0.78beta4-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Wed, 20 Mar 2013 15:01:10 +0000 -dvdomatic (0.78beta3-1) UNRELEASED; urgency=low +dcpomatic (0.78beta3-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Wed, 20 Mar 2013 10:49:17 +0000 -dvdomatic (0.78beta2-1) UNRELEASED; urgency=low +dcpomatic (0.78beta2-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Tue, 19 Mar 2013 21:35:50 +0000 -dvdomatic (0.78beta1-1) UNRELEASED; urgency=low +dcpomatic (0.78beta1-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Tue, 19 Mar 2013 20:50:54 +0000 -dvdomatic (0.77-1) UNRELEASED; urgency=low +dcpomatic (0.77-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Thu, 14 Mar 2013 17:12:03 +0000 -dvdomatic (0.77beta2-1) UNRELEASED; urgency=low +dcpomatic (0.77beta2-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Thu, 14 Mar 2013 15:50:43 +0000 -dvdomatic (0.77beta1-1) UNRELEASED; urgency=low +dcpomatic (0.77beta1-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Thu, 14 Mar 2013 15:14:01 +0000 -dvdomatic (0.76-1) UNRELEASED; urgency=low +dcpomatic (0.76-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Tue, 05 Mar 2013 13:30:28 +0000 -dvdomatic (0.76beta3-1) UNRELEASED; urgency=low +dcpomatic (0.76beta3-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Tue, 05 Mar 2013 12:47:20 +0000 -dvdomatic (0.76beta2-1) UNRELEASED; urgency=low +dcpomatic (0.76beta2-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Fri, 01 Mar 2013 18:32:16 +0000 -dvdomatic (0.76beta1-1) UNRELEASED; urgency=low +dcpomatic (0.76beta1-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Fri, 01 Mar 2013 17:36:55 +0000 -dvdomatic (0.75-1) UNRELEASED; urgency=low +dcpomatic (0.75-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Wed, 27 Feb 2013 11:03:07 +0000 -dvdomatic (0.75beta1-1) UNRELEASED; urgency=low +dcpomatic (0.75beta1-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Wed, 27 Feb 2013 08:20:42 +0000 -dvdomatic (0.74-1) UNRELEASED; urgency=low +dcpomatic (0.74-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Sat, 23 Feb 2013 22:57:20 +0000 -dvdomatic (0.74beta1-1) UNRELEASED; urgency=low +dcpomatic (0.74beta1-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Sat, 23 Feb 2013 21:44:22 +0000 -dvdomatic (0.73-1) UNRELEASED; urgency=low +dcpomatic (0.73-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Thu, 21 Feb 2013 00:43:40 +0000 -dvdomatic (0.73beta9-1) UNRELEASED; urgency=low +dcpomatic (0.73beta9-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Wed, 20 Feb 2013 23:40:24 +0000 -dvdomatic (0.73beta8-1) UNRELEASED; urgency=low +dcpomatic (0.73beta8-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Mon, 18 Feb 2013 22:35:51 +0000 -dvdomatic (0.73beta7-1) UNRELEASED; urgency=low +dcpomatic (0.73beta7-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Mon, 18 Feb 2013 20:38:51 +0000 -dvdomatic (0.73beta6-1) UNRELEASED; urgency=low +dcpomatic (0.73beta6-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Sun, 17 Feb 2013 23:05:56 +0000 -dvdomatic (0.73beta3-1) UNRELEASED; urgency=low +dcpomatic (0.73beta3-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Sun, 17 Feb 2013 23:05:05 +0000 -dvdomatic (0.73beta2-1) UNRELEASED; urgency=low +dcpomatic (0.73beta2-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Sat, 16 Feb 2013 22:42:32 +0000 -dvdomatic (0.73beta1-1) UNRELEASED; urgency=low +dcpomatic (0.73beta1-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Sat, 16 Feb 2013 21:19:24 +0000 -dvdomatic (0.72-1) UNRELEASED; urgency=low +dcpomatic (0.72-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Thu, 24 Jan 2013 15:31:57 +0000 -dvdomatic (0.71-1) UNRELEASED; urgency=low +dcpomatic (0.71-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Thu, 24 Jan 2013 11:36:04 +0000 -dvdomatic (0.70-1) UNRELEASED; urgency=low +dcpomatic (0.70-1) UNRELEASED; urgency=low * New upstream release. * New upstream release. @@ -300,7 +300,7 @@ dvdomatic (0.70-1) UNRELEASED; urgency=low -- Carl Hetherington Sat, 12 Jan 2013 23:07:15 +0000 -dvdomatic (0.70beta3-1) UNRELEASED; urgency=low +dcpomatic (0.70beta3-1) UNRELEASED; urgency=low * New upstream release. * New upstream release. @@ -309,13 +309,13 @@ dvdomatic (0.70beta3-1) UNRELEASED; urgency=low -- Carl Hetherington Sun, 06 Jan 2013 23:44:24 +0000 -dvdomatic (0.68-1) UNRELEASED; urgency=low +dcpomatic (0.68-1) UNRELEASED; urgency=low * New upstream release. -- Carl Hetherington Sun, 23 Dec 2012 01:43:44 +0000 -dvdomatic (0.68beta10-1) UNRELEASED; urgency=low +dcpomatic (0.68beta10-1) UNRELEASED; urgency=low * New upstream release. * New upstream release. @@ -325,91 +325,91 @@ dvdomatic (0.68beta10-1) UNRELEASED; urgency=low -- Carl Hetherington Sat, 22 Dec 2012 13:27:27 +0000 -dvdomatic (0.68beta5-1) unstable; urgency=low +dcpomatic (0.68beta5-1) unstable; urgency=low * New upstream release. -- Carl Hetherington Thu, 20 Dec 2012 07:53:46 +0000 -dvdomatic (0.68beta4-1) unstable; urgency=low +dcpomatic (0.68beta4-1) unstable; urgency=low * New upstream release. -- Carl Hetherington Thu, 20 Dec 2012 07:48:45 +0000 -dvdomatic (0.68beta3-1) unstable; urgency=low +dcpomatic (0.68beta3-1) unstable; urgency=low * New upstream release. -- Carl Hetherington Thu, 20 Dec 2012 00:35:45 +0000 -dvdomatic (0.68beta2-1) unstable; urgency=low +dcpomatic (0.68beta2-1) unstable; urgency=low * New upstream release. -- Carl Hetherington Wed, 19 Dec 2012 11:22:58 +0000 -dvdomatic (0.68beta1-1) unstable; urgency=low +dcpomatic (0.68beta1-1) unstable; urgency=low * New upstream release. -- Carl Hetherington Wed, 19 Dec 2012 10:11:13 +0000 -dvdomatic (0.67-1) unstable; urgency=low +dcpomatic (0.67-1) unstable; urgency=low * New upstream release. -- Carl Hetherington Tue, 18 Dec 2012 23:49:27 +0000 -dvdomatic (0.66-1) unstable; urgency=low +dcpomatic (0.66-1) unstable; urgency=low * New upstream release. -- Carl Hetherington Tue, 18 Dec 2012 11:29:04 +0000 -dvdomatic (0.65-1) unstable; urgency=low +dcpomatic (0.65-1) unstable; urgency=low * New upstream release. -- Carl Hetherington Tue, 18 Dec 2012 09:24:56 +0000 -dvdomatic (0.64-1) unstable; urgency=low +dcpomatic (0.64-1) unstable; urgency=low * New upstream release. -- Carl Hetherington Thu, 13 Dec 2012 21:52:09 +0000 -dvdomatic (0.63pre-1) unstable; urgency=low +dcpomatic (0.63pre-1) unstable; urgency=low * New upstream release. -- Carl Hetherington Tue, 11 Dec 2012 23:15:52 +0000 -dvdomatic (0.60-1) unstable; urgency=low +dcpomatic (0.60-1) unstable; urgency=low * New upstream release. -- Carl Hetherington Tue, 11 Dec 2012 22:46:04 +0000 -dvdomatic (0.59-1) unstable; urgency=low +dcpomatic (0.59-1) unstable; urgency=low * New upstream release. -- Carl Hetherington Mon, 10 Dec 2012 20:58:19 +0000 -dvdomatic (0.59beta5-1) unstable; urgency=low +dcpomatic (0.59beta5-1) unstable; urgency=low * New upstream release. -- Carl Hetherington Sun, 09 Dec 2012 23:51:55 +0000 -dvdomatic (0.59beta4-1) unstable; urgency=low +dcpomatic (0.59beta4-1) unstable; urgency=low * New upstream release. -- Carl Hetherington Sun, 09 Dec 2012 21:38:00 +0000 -dvdomatic (0.59beta1-1) unstable; urgency=low +dcpomatic (0.59beta1-1) unstable; urgency=low * Initial release. diff --git a/debian/copyright b/debian/copyright index 2579947e4..0cf23aacd 100644 --- a/debian/copyright +++ b/debian/copyright @@ -1,6 +1,6 @@ Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: dvdomatic -Source: +Upstream-Name: dcpomatic +Source: Files: * Copyright: 2012 Carl Hetherington diff --git a/debian/files b/debian/files index 7639f05ac..ca46cf438 100644 --- a/debian/files +++ b/debian/files @@ -1 +1 @@ -dvdomatic_0.59beta1-1_i386.deb video extra +dcpomatic_0.59beta1-1_i386.deb video extra diff --git a/debian/rules b/debian/rules index 3320087a5..ba42e5291 100755 --- a/debian/rules +++ b/debian/rules @@ -19,5 +19,5 @@ override_dh_auto_build: ./waf --nocache build override_dh_auto_install: - ./waf --nocache install --destdir=debian/dvdomatic + ./waf --nocache install --destdir=debian/dcpomatic diff --git a/doc/mainpage.txt b/doc/mainpage.txt index 59c578899..649c9c609 100644 --- a/doc/mainpage.txt +++ b/doc/mainpage.txt @@ -1,37 +1,37 @@ -/** @mainpage DVD-o-matic +/** @mainpage DCP-o-matic * - * DVD-o-matic is a tool to create digital cinema packages (DCPs) from + * DCP-o-matic is a tool to create digital cinema packages (DCPs) from * video files, or from sets of TIFF image files. It is written in C++ * and distributed under the GPL. * * Video files are decoded using FFmpeg (http://ffmpeg.org), so any video - * supported by FFmpeg should be usable with DVD-o-matic. DVD-o-matic's output has been + * supported by FFmpeg should be usable with DCP-o-matic. DCP-o-matic's output has been * tested on numerous digital projectors. * - * DVD-o-matic allows you to crop black borders from movies, scale them to the correct + * DCP-o-matic allows you to crop black borders from movies, scale them to the correct * aspect ratio and apply FFmpeg filters. The time-consuming encoding of JPEG2000 files * can be parallelised amongst any number of processors on the local host and any number * of servers over a network. * - * DVD-o-matic can also make DCPs from still images, for advertisements and such-like. + * DCP-o-matic can also make DCPs from still images, for advertisements and such-like. * - * Parts of DVD-o-matic are based on OpenDCP (http://code.google.com/p/opendcp), + * Parts of DCP-o-matic are based on OpenDCP (http://code.google.com/p/opendcp), * written by Terrence Meiczinger. * - * DVD-o-matic uses libopenjpeg (http://code.google.com/p/openjpeg/) for JPEG2000 encoding + * DCP-o-matic uses libopenjpeg (http://code.google.com/p/openjpeg/) for JPEG2000 encoding * and libsndfile (http://www.mega-nerd.com/libsndfile/) for WAV file manipulation. It * also makes heavy use of the boost libraries (http://www.boost.org/). ImageMagick * (http://www.imagemagick.org/) is used for still-image encoding and decoding, and the GUI is * built using wxWidgets (http://wxwidgets.org/). It also uses libmhash (http://mhash.sourceforge.net/) * for debugging purposes. * - * Thanks are due to the authors and communities of all DVD-o-matic's dependencies. + * Thanks are due to the authors and communities of all DCP-o-matic's dependencies. * - * DVD-o-matic is distributed in the hope that there are still cinemas with projectionists + * DCP-o-matic is distributed in the hope that there are still cinemas with projectionists * who might want to use it. As Mark Kermode says, "if it doesn't have a projectionist * it's not a cinema - it's a sweetshop with a video-screen." * * Email correspondance is welcome to cth@carlh.net * - * More details can be found at http://carlh.net/software/dvdomatic + * More details can be found at http://carlh.net/software/dcpomatic */ diff --git a/doc/manual/Makefile b/doc/manual/Makefile index 94abc8516..115d7c3c8 100644 --- a/doc/manual/Makefile +++ b/doc/manual/Makefile @@ -1,4 +1,4 @@ -# DVD-o-matic manual makefile +# DCP-o-matic manual makefile all: html pdf @@ -8,7 +8,7 @@ SCREENSHOTS := file-new.png video-new-film.png still-new-film.png click-content- still-select-content-file.png examine-thumbs.png \ calculate-audio-gain.png prefs.png making-dcp.png filters.png film-tab.png video-tab.png audio-tab.png subtitles-tab.png -XML := dvdomatic.xml +XML := dcpomatic.xml GRAPHICS := @@ -70,7 +70,7 @@ diagrams/%.pdf: diagrams/%.svg # HTML # -html: $(XML) dvdomatic-html.xsl extensions-html.ent dvdomatic.css \ +html: $(XML) dcpomatic-html.xsl extensions-html.ent dcpomatic.css \ $(addprefix html/screenshots/,$(SCREENSHOTS)) \ $(subst .svg,.png,$(addprefix diagrams/,$(DIAGRAMS))) \ $(subst .svg,.png,$(addprefix graphics/,$(GRAPHICS))) \ @@ -80,19 +80,19 @@ html: $(XML) dvdomatic-html.xsl extensions-html.ent dvdomatic.css \ cp extensions-html.ent extensions.ent # DocBoox -> html - xmlto html -m dvdomatic-html.xsl dvdomatic.xml --skip-validation -o html + xmlto html -m dcpomatic-html.xsl dcpomatic.xml --skip-validation -o html # Copy graphics and CSS in # mkdir -p html/diagrams html/graphics # cp diagrams/*.png html/diagrams # cp graphics/*.png html/graphics - cp dvdomatic.css html + cp dcpomatic.css html # # PDF # -pdf: $(XML) dvdomatic-pdf.xsl extensions-pdf.ent screenshots/*.png $(subst .svg,.pdf,$(addprefix diagrams/,$(DIAGRAMS))) +pdf: $(XML) dcpomatic-pdf.xsl extensions-pdf.ent screenshots/*.png $(subst .svg,.pdf,$(addprefix diagrams/,$(DIAGRAMS))) # The DocBook needs to know what file extensions to look for # for screenshots and diagrams; use the correct file to tell it. @@ -100,14 +100,14 @@ pdf: $(XML) dvdomatic-pdf.xsl extensions-pdf.ent screenshots/*.png $(subst .svg, mkdir -p pdf - dblatex -p dvdomatic-pdf.xsl -s dvdomatic.sty -r pptex.py -T native dvdomatic.xml -t pdf -o pdf/dvdomatic.pdf + dblatex -p dcpomatic-pdf.xsl -s dcpomatic.sty -r pptex.py -T native dcpomatic.xml -t pdf -o pdf/dcpomatic.pdf # # LaTeX (handy for debugging) # -tex: $(XML) dvdomatic-pdf.xsl extensions-pdf.ent +tex: $(XML) dcpomatic-pdf.xsl extensions-pdf.ent # The DocBook needs to know what file extensions to look for # for screenshots and diagrams; use the correct file to tell it. @@ -116,8 +116,8 @@ tex: $(XML) dvdomatic-pdf.xsl extensions-pdf.ent mkdir -p tex # -P removes the revhistory table - dblatex -P doc.collab.show=0 -P latex.output.revhistory=0 -p dvdomatic-pdf.xsl -s dvdomatic.sty -r pptex.py -T native dvdomatic.xml -t tex -o tex/dvdomatic.tex + dblatex -P doc.collab.show=0 -P latex.output.revhistory=0 -p dcpomatic-pdf.xsl -s dcpomatic.sty -r pptex.py -T native dcpomatic.xml -t tex -o tex/dcpomatic.tex -clean:; rm -rf html pdf diagrams/*.pdf diagrams/*.png graphics/*.png *.aux dvdomatic.cb dvdomatic.cb2 dvdomatic.glo dvdomatic.idx dvdomatic.ilg - rm -rf dvdomatic.ind dvdomatic.lof dvdomatic.log dvdomatic.tex dvdomatic.toc extensions.ent dvdomatic.out +clean:; rm -rf html pdf diagrams/*.pdf diagrams/*.png graphics/*.png *.aux dcpomatic.cb dcpomatic.cb2 dcpomatic.glo dcpomatic.idx dcpomatic.ilg + rm -rf dcpomatic.ind dcpomatic.lof dcpomatic.log dcpomatic.tex dcpomatic.toc extensions.ent dcpomatic.out diff --git a/doc/manual/dvdomatic-html.xsl b/doc/manual/dvdomatic-html.xsl deleted file mode 100644 index 059d7ead7..000000000 --- a/doc/manual/dvdomatic-html.xsl +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - diff --git a/doc/manual/dvdomatic-pdf.xsl b/doc/manual/dvdomatic-pdf.xsl deleted file mode 100644 index 414fb64b8..000000000 --- a/doc/manual/dvdomatic-pdf.xsl +++ /dev/null @@ -1,17 +0,0 @@ - - - - -colorlinks,linkcolor=black,urlcolor=black - - -0 -0 - - -scale=0.6 - - -3 - - diff --git a/doc/manual/dvdomatic.css b/doc/manual/dvdomatic.css deleted file mode 100644 index 0e4982f20..000000000 --- a/doc/manual/dvdomatic.css +++ /dev/null @@ -1,19 +0,0 @@ -body { - font-family: luxi sans, sans-serif; - margin-left: 4em; - margin-right: 4em; - margin-top: 1em; - margin-bottom: 1em; - background-color: #E2E8EE; -} - -div.sidebar { - margin-left: 1em; - margin-right: 1em; - padding-left: 1em; - padding-right: 1em; - border-color: #000000; - border-width: 2px; - border-style: solid; - background-color: #E2E8EE; -} diff --git a/doc/manual/dvdomatic.sty b/doc/manual/dvdomatic.sty deleted file mode 100644 index 834e581fc..000000000 --- a/doc/manual/dvdomatic.sty +++ /dev/null @@ -1,68 +0,0 @@ -%% -%% This style is derivated from the docbook one -%% -\NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{ardour}[2007/04/04 My DocBook Style] - -%% Just use the original package and pass the options -\RequirePackageWithOptions{docbook} - -% Use a nice font -\usepackage{lmodern} - -% Define \dbend as the dangerous bend sign -\font\manual=manfnt -\def\dbend{{\manual\char127}} - -% Redefine sidebar environment to use the dangerous bend style -% Danger, Will Robinson! -\def\sidebar{\begin{trivlist}\item[]\noindent% -\begingroup\hangindent=2pc\hangafter=-2%\clubpenalty=10000% -\def\par{\endgraf\endgroup}% -\hbox to0pt{\hskip-\hangindent\dbend\hfill}\ignorespaces} -\def\endsidebar{\par\end{trivlist}} - - -% Futz with the title page; basically a copy of -% /usr/share/texmf/tex/latex/dblatex/style/dbk_title.sty -% with authors added. - -\def\DBKcover{ -\ifthenelse{\equal{\DBKedition}{}}{\def\edhead{}}{\def\edhead{Ed. \DBKedition}} - -\pagestyle{empty} - -% interligne double -\setlength{\oldbaselineskip}{\baselineskip} -\setlength{\baselineskip}{2\oldbaselineskip} -\textsf{ -\vfill -\vspace{2.5cm} -\begin{center} - \huge{\textbf{\DBKtitle}}\\ % - \ \\ % - \ \\ % - \Large{\DBKauthor}\\ % - \ifx\DBKsubtitle\relax\else% - \underline{\ \ \ \ \ \ \ \ \ \ \ }\\ % - \ \\ % - \huge{\textbf{\DBKsubtitle}}\\ % - \fi -\end{center} -\vfill -\setlength{\baselineskip}{\oldbaselineskip} -\hspace{1cm} -\vspace{1cm} -\begin{center} -\begin{tabular}{p{7cm} p{7cm}} -\Large{\DBKreference{} \edhead} & \\ -\end{tabular} -\end{center} -} - -% Format for the other pages -\newpage -\setlength{\baselineskip}{\oldbaselineskip} -%\chead[]{\DBKcheadfront} -\lfoot[]{} -} diff --git a/doc/manual/dvdomatic.xml b/doc/manual/dvdomatic.xml deleted file mode 100644 index 58315eca6..000000000 --- a/doc/manual/dvdomatic.xml +++ /dev/null @@ -1,932 +0,0 @@ - - - - -%dbcent; - -%extensions; -]> - - - -DVD-o-matic -CarlHetherington - - - -Introduction - - -Hello, and welcome to DVD-o-matic! - - -
-What is DVD-o-matic? - - -DVD-o-matic is a program to generate Digital -Cinema Packages (DCPs) from DVDs, Blu-Rays, video files such as MP4 -and AVI, or still images. The resulting DCPs will play on modern digital -cinema projectors. - - - -You might find it useful to make DVDs easier to present, to encode -independently-shot feature films, or to generate local advertising for -your cinema. - - -
- -
-Licence - - -DVD-o-matic is licensed under the GNU GPL. - - -
- -
- - -Installation - -
-Windows - - -To install DVD-o-matic on Windows, simply download the installer from -http://carlh.net -and double-click it. Click through the installer wizard, and -DVD-o-matic will be installed onto your machine. - - - -If you are using a 32-bit version of Windows, you will need the 32-bit -installer. For 64-bit Windows, either installer will work, but I -suggest you used the 64-bit version as it will allow DVD-o-matic to -use more memory. You may find that DVD-o-matic crashes if you run -many parallel encoding threads (more than 4) on the 32-bit -version. - - -
- -
-Ubuntu Linux - - -You can install DVD-o-matic on Ubuntu 12.04 (‘Precise -Pangolin’) or 12.10 (‘Quantal Quetzal’) using -.deb packages: download the appropriate package from -http://carlh.net and -double-click it. Ubuntu will install the necessary bits and pieces -and set DVD-o-matic up for you. - - -
- -
-Other Linux distributions - - -Installation on non-Ubuntu Linux is currently a little involved, as -there are no packages available (yet); you will have to compile it -from source. If you are using a non-Ubuntu distribution, do let me -know via the mailing -list and I will see about building some packages. - - - -The following dependencies are required: - -FFmpeg -libsndfile -OpenSSL -libopenjpeg -ImageMagick -Boost -libssh -GTK -wxWidgets -libdcp - - - - -Once you have installed the development packages for the dependencies, -download the source code from http://carlh.net, -unpack it and run the following commands from inside the source -directory: - - - -./waf configure -./waf build -sudo ./waf install - - - -With any luck, this will build and install DVD-o-matic on your system. To run it, enter: - - - -dvdomatic - - - -in a shell. - - -
-
- - -Creating a video DCP - - -In this chapter we will see how to create a video DCP using -DVD-o-matic. We will gloss over some of the finer details, which are -explained in later chapters. - - -
-Creating a new film - - -Let's make a very simple DCP to see how DVD-o-matic works. First, we -need some content. Download the low-resolution trailer for the open -movie Sintel from their -website. Generally, of course, one would want to use the -highest-resolution material available, but for this test we will use -the low-resolution version to save everyone's bandwidth bills. - - - -Now, start DVD-o-matic and its window will open. First, we will -create a new ‘film’. A ‘film’ is how DVD-o-matic refers to -a piece of content, along with some settings, which we will make into -a DCP. DVD-o-matic stores its data in a folder on your disk while it -creates the DCP. You can create a new film by selecting -New from the File menu, as -shown in . - - -
- Creating a new film - - - - - -
- - -This will open a dialogue box for the new film, as shown in . - - -
- Dialogue box for creating a new film - - - - - -
- - -In this dialogue box you can choose a name for the film. This will be -used to name the folder to store its data in, and also as the initial -name for the DCP itself. You can also choose whereabouts you want to create -the film. In the example from the figure, DVD-o-matic will create a -folder called ‘DCP Test’ inside my home folder (carl) into which it -will write its working files. - - - -If you always create your DCPs in a particular folder, you can use -DVD-o-matic's Preferences to make life a little -easier by setting the default folder that DVD-o-matic will offer in this dialogue. -See . - - -
- -
-Selecting content - - -The next step is to set the content that you want to use. Click the -content selector, as shown in , and a file chooser will -open for you to select the content file to use, as shown in . - - -
- Opening the content selector - - - - - -
- -
- Selecting a video content file - - - - - -
- - -Select your content file and click Open. In this -case we are using the Sintel trailer that we downloaded earlier. - - - -When you do this, DVD-o-matic will take a look at your file. After a -short while (when the progress bar at the bottom right of the window -has finished), you can look through your content using the slider to -the right of the window, as shown in . - - -
- Examining the content - - - - - -
- - -Dragging the slider will move through your video. You can also click -the Play button to play the content back. Note -that there will be no sound, and playback might not be entirely -accurate (it may be slightly slower or faster than it should be, for -example). This player is really only intended for brief inspection of -content; if you need to check it more thoroughly, use another player -such as Totem, mplayer or VLC. - - -
- -
-Setting up - - -Now there are a few things to set up to describe how the DCP should be -created. The settings are divided into four tabs: film, video, audio and subtitles. - - -
-Film tab - - -The ‘film’ tab contains settings that pertain to the whole film, as shown in . - - -
- Film settings tab - - - - - -
- - -The first thing here is the name. This is generally set to the title -of the film that is being encoded. If Use DCI -name is not ticked, the name that you specify will be used -as-is for the name of the DCP. If Use DCI name -is ticked, the name that you enter will be used as part of a -DCI-compliant name. - - - -Underneath the name field is a preview of the name that the DCP will -get. To use a DCI-compliant name, tick the Use DCI -name checkbox. The DCI name will be composed using details -of your content's soundtrack, the current date and other things that -can be specified in the DCI name details dialogue box, which you can -open by clicking on the Details button. - - - -If the DCP name is long, it may not all be visible. You can see the -full name by hovering the mouse pointer over the partial name. - - - -The Trust content's header button starts off -checked, and this means that DVD-o-matic will use the content's header -information to determine its length. If, for some reason, this header -length is wrong, uncheck the Trust content's -header button and DVD-o-matic will run through the content -to find its exact length. This may take a while for large pieces of content. - - - -Next up is the content type. This can be -‘feature’, ‘trailer’ or whatever; select the -required type from the drop-down list. - - - -The trim frames settings allow you to trim frames -from the beginning and end of the content; any trimmed frames will not -be included in the DCP. - - -
- -
-Video tab - - -This tab contains settings related to the picture in your DCP, as shown in . - - -
- Video settings tab - - - - - -
- - -The first option on this tab is the format. This will govern the -shape that DVD-o-matic will make your image into. Select the aspect -ratio that your content should be presented in. The ‘4:3 within -Flat’ and ‘16:9 within Flat’ settings will put the -image at the specified ratio within a Flat (1.85:1) frame, so that you -can project the DCP using your projector's Flat preset. - - - -The remaining options can often be left alone, but may sometimes be -useful. The ‘crop’ settings can be used to crop your -content, which can be used to remove black borders from round the -edges of DVD images, for example. The specified number of pixels will -be trimmed from each edge, and the content image in the right of the -window will be updated to show the effect of the crop. - - - -The ‘filters’ settings allow you to apply various video -filters to the image. These may be useful to try to improve -poor-quality sources like DVDs. We will discuss filtering later in the manual. - - - - -The ‘scaler’ is the method that will be used to scale up -your content to the required size for the DCP, if required. We will -discuss the options in more detail later; Bicubic is a fine choice in -most situations. - - - - -The ‘colour look-up table’ specifies the colour space that -your input content will be expected to be in. If in doubt, leave it -set to ‘sRGB’. - - - -Finally, the ‘JPEG2000 bandwidth’ setting changes how big the final -image files used within the DCP will be. Larger numbers will give -better quality, but correspondingly larger DCPs. The bandwidth can be -between 50 and 250 megabits per second (MBps). - - -
- -
-Audio tab - - -This tab contains settings related to the sound in your DCP, as shown in . - - -
- Audio settings tab - - - - - -
- - - -‘Audio Gain’ is used to alter the volume of the -soundtrack. The specified gain (in dB) will be applied to each sound -channel before it is written to the DCP. - - - -If you use a sound processor that DVD-o-matic knows about, it can help -you calculate changes in gain that you should apply. Say, for -example, that you make a test DCP and find that you have to run it at -volume 5 instead of volume 7 to get a good sound level in the screen. -If this is the case, click the Calculate... -button next to the audio gain entry, and the dialogue box in will open. - - -
- Calculating audio gain - - - - - -
- - -For our example, put 5 in the first box and 7 in the second and click -OK. DVD-o-matic will calculate the audio gain -that it should apply to make this happen. Then you can re-make the -DCP (this will be reasonably fast, as the video data will already have -been done) and it should play back at the correct volume with 7 on -your sound-rack fader. - - - -Current versions of DVD-o-matic only know about the Dolby CP750. If -you use a different sound processor, and know the gain curve of its -volume control, get in -touch. - - - -‘Audio Delay’ is used to adjust the synchronisation -between audio and video. A positive delay will move the audio later -with respect to the video, and a negative delay will move it earlier. - - - -By default the Use content‘s audio button -will be selected. This means that the DCP will use one of the -soundtracks from your content file; you can select the soundtrack that -you wish to use from the drop-down box. - - - -Note that if your content's audio is mono, DVD-o-matic will place it -in the centre channel in the DCP. - - - -Alternatively, you can supply different sound files by clicking the -Use external audio button and choosing a WAV file -for any channels that you want to appear in the DCP. These files can -be any bit depth and sampling rate, and will be re-sampled and -bit-depth converted if required. - - -
-
-Subtitles tab - - -This tab contains settings related to subtitles in your DCP, as shown in . - - -
- Subtitle settings tab - - - - - -
- - -DVD-o-matic will extract subtitles from the content, if present, and -they can be ‘burnt into’ the DCP (that is, they are -included in the image and not overlaid by the projector). Note that -DVD and Blu-Ray subtitles are stored as bitmaps, so it is not possible -(automatically) to use non-burnt-in subtitles with these sources. -Select the With Subtitles checkbox to enable -subtitles. The offset control moves the -subtitles up and down the image, and the scale -control changes their size. - - - -Future versions of DVD-o-matic will hopefully include the option to -use text subtitles (as is the norm with most professionally-mastered -DCPs). - - -
-
- -
-Making the DCP - - -Now that we have set everything up, choose Make -DCP from the Jobs menu. DVD-o-matic -will encode your DCP. This may take some time (many hours in some -cases). While the job is in progress, DVD-o-matic will update you on -how it is getting on with the progress bar in the bottom of its window, as shown in . - - -
- Making the DCP - - - - - -
- - -When it has finished, the DCP will end up on your disk inside the -film's directory. You can then copy this to a projector via a USB -stick, hard-drive or network connection. - - - -Alternatively, if you have a projector or TMS that is accessible via -SCP across your network, you can upload the content directly from -DVD-o-matic. See . - - -
-
- - - -Creating a still-image DCP - - -DVD-o-matic can also be used to create DCPs of a still image, perhaps -for an advertisement or an on-screen announcement. This chapter shows you -how to do it. - - - -As with video DCPs, the first step is to create a new -‘Film’; select New from the -File menu and the new film dialogue will open as -shown in . - - -
- Dialogue box for creating a new film - - - - - -
- - -Enter a name and click OK. Then we set up the -content; click the content selector as before, and this time we will -choose an image file, as shown in . - - -
- Selecting a still content file - - - - - -
- - -Setting up for a still image DCP is somewhat simpler than for a video; -the tabs are all the same, but many options are removed and a few are added. - - - -As with video, you can select a content type and the format (ratio) -that your image should be presented in. It will be scaled and padded -to fit the selected ratio, but in such a way that the pixel aspect -ratio is preserved. In other words, the image will not be stretched, -merely scaled; if you want to stretch your image, you will need to do -so in a separate program before importing it into DVD-o-matic. You -can also crop your image, if you so choose, and then set a duration -(in seconds) that the image should appear on screen. - - - -Still-image DCPs can include sound; this can be added from the -Audio tab. If your specified duration is shorter -than the audio, the audio will be cut off at the duration; if it is -longer, silence will be added after your audio. - - - -Finally, as with video, you can choose Make DCP -from the Jobs menu to create your DCP. This will -be much quicker than creating a video DCP, as DVD-o-matic only needs -to encode a single frame which it can then repeat. - - -
- - - -Preferences - - -DVD-o-matic provides a few preferences which can be used to modify its -behaviour. This chapter explains those options. - - -
-The preferences dialogue - - -The preferences dialogue is opened by choosing -Preferences... from the Edit -menu. The dialogue is shown in . - - -
- Preferences - - - - - -
- -
-TMS setup - - -The first part of the dialogue gives some options for specifying -details about your TMS. If you do this, and your TMS accepts SSH -connections, you can upload DCPs directly from DVD-o-matic to the TMS. -This is discussed in . - - - -TMS IP address should be set to the IP address of -your TMS, TMS target path to the place that DCPs -should be uploaded to (which will be relative to the home directory of -the SSH user). Finally, the user name and password are the -credentials required to log into the TMS via SSH. - -
- -
-Threads - - -When DVD-o-matic is encoding DCPs it can use multiple parallel threads -to speed things up. Set this value to the number of threads -DVD-o-matic should use. This would typically be set to the number of -processors (or processor cores) in your machine. - - -
- -
-Default directory for new films - - -This is the directory which DVD-o-matic will suggest initially as a place to put new films. - - -
- -
-A/B options - - -These options are for DVD-o-matic's special mode of making A/B -comparison DCPs for checking the performance of video filters. Their -use is described in . - - -
- -
-Encoding servers - - -If you have spare machines sitting around on your network not doing -much, they can be pressed into service to speed up DCP encodes. This -is done by running a small server program on the machine, which will -encode video sent to it by the ‘master’ DVD-o-matic. This -option is described in more detail in . -Use these preferences to specify the encoding servers that should be -used. - - -
- -
-
- - -Advanced topics - -This chapter describes some parts of DVD-o-matic that are -probably not essential, but which you might find useful in some -circumstances. - - -
-Filtering - - -DVD-o-matic offers a variety of filters that can be applied to your -video content. You can set up the filters by clicking the -Edit button next to the filters entry in the -setup area of the DVD-o-matic window; this opens the filters selector -as shown in . - - -
- Filters selector - - - - - -
- - -After changing the filters setup, you will need to regenerate the DCP -to see the effect on the cinema screen. The preview in DVD-o-matic -will update itself whenever filters are changed, though of course this -image is much smaller and of lower resolution than a projected image! - - -
- -
-Scaling - - -If your source material is not of the DCI-specified size, or if it -uses non-square pixels, DVD-o-matic will need to scale it. The -algorithm used to scale is set up by the Scaler -entry in the film setup area. We think ‘Bicubic’ is the -best all-round option, but tests are ongoing. - - -
- -
-TMS upload - - -If you have configured details of a TMS in the preferences dialogue -() you can upload a completed DCP -straight to your TMS buy choosing Send DCP to TMS -from the Jobs menu. - - -
- - -
-A/B comparison - - -When evaluating the effects of different filters or scalers on the -image quality, A/B mode might be useful. In this mode, DVD-o-matic -will generate a DCP where the left half of the image uses some -‘reference’ filtering and scaling, and the right half of -the image uses a different set of filters and a different scaler. -This DCP can then be played back on a projector and the image quality -evaluated. - - - -To enable A/B mode, click the A/B checkbox in the setup area of the -DVD-o-matic window. When you generate your DCP, the left half of the -screen will use the filters and scaler specified in the preferences dialogue, and the right -half will use the filters and scaler specified in the film setup. - - -
- -
-Encoding servers - - -One way to increase the speed of DCP encoding is to use more -than one machine at the same time. An instance of DVD-o-matic can -offload some of the time-consuming JPEG2000 encoding to any number of -other machines on a network. To do this, one ‘master’ -machine runs DVD-o-matic, and the ‘server’ machines run -a small program called ‘servomatic’. - - -
-Running the servers - - -There are two options for the encoding server; -servomatic_cli, which runs on the command line, and -servomatic_gui, which has a simple GUI. The command line -version is well-suited to headless servers, especially on Linux, and -the GUI version works best on Windows where it will put an icon in the -system tray. - - - -To run the command line version, simply enter: - - - -servomatic_cli - - - -at a command prompt. If you are running the program on a machine with -a multi-core processor, you can run multiple parallel encoding threads -by doing something like: - - - -servomatic_cli -t 4 - - - -to run 4 threads in parallel. - - - -To run the GUI version on windows, run the ‘DVD-o-matic encode -server’ from the start menu. An icon will appear in the system -tray; right-click it to open a menu from whence you can quit the -server or open a window to show its status. - - -
-
-Setting up DVD-o-matic - - -Once your servers are running, you need to tell your master -DVD-o-matic instance about them. Start DVD-o-matic and open the -Preferences dialog from the -Edit menu. At the bottom of this dialog is a -section where you can add, edit and remove encoding servers. For each -encoding server you need only specify its IP address and the number of -threads that it is running, so that DVD-o-matic knows how many -parallel encode jobs to send to the server. - - - -Once this is done, any encodes that you start will split the workload -up between the master machine and the servers. - - -
-
-Some notes about encode servers - - -DVD-o-matic does not mind if servers come and go; if a server -disappears, DVD-o-matic will stop sending work to it, and will check -it every minute or so in case it has come back online. - - - -You will probably find that using a 1Gb/s or faster network will -provide a significant speed-up compared to a 100Mb/s network. - - - -Making changes to the server configuration in the master DVD-o-matic -will have no effect while an encode is running; the changes will only -be noticed when a new encode is started. - - -
-
- -
- - -
diff --git a/dvdomatic.desktop.in b/dvdomatic.desktop.in deleted file mode 100644 index 65067eb3b..000000000 --- a/dvdomatic.desktop.in +++ /dev/null @@ -1,10 +0,0 @@ -[Desktop Entry] -Encoding=UTF-8 -Version=1.0 -Type=Application -Terminal=false -Exec=@PREFIX@/bin/dvdomatic -Name=DVD-o-matic -Icon=dvdomatic -Comment=DCP generator -Categories=AudioVideo;Video diff --git a/hacks/python-playback/config.py b/hacks/python-playback/config.py deleted file mode 100644 index fecf261f5..000000000 --- a/hacks/python-playback/config.py +++ /dev/null @@ -1,2 +0,0 @@ - -LEFT_SCREEN_WIDTH = 1366 diff --git a/hacks/python-playback/dvdomatic b/hacks/python-playback/dvdomatic deleted file mode 100755 index ce405f37e..000000000 --- a/hacks/python-playback/dvdomatic +++ /dev/null @@ -1,209 +0,0 @@ -#!/usr/bin/python - -import os -import operator -import traceback -import pygtk -pygtk.require('2.0') -import gtk -import glib -import gobject -import film -import film_view -import player -import screens -import thumbs -import ratio -import util - -FILM_DIRECTORY = '/home/carl/DVD' - -current_player = None -films = [] -inhibit_selection_update = False - -def find_films(): - global films - films = [] - for root, dirs, files in os.walk(FILM_DIRECTORY): - for name in files: - if os.path.basename(name) == 'info': - films.append(film.Film(os.path.join(root, os.path.dirname(name)))) - - films.sort(key = operator.attrgetter('name')) - -def update_film_store(): - global film_store - global films - global inhibit_selection_update - inhibit_selection_update = True - film_store.clear() - for f in films: - film_store.append([f.name]) - inhibit_selection_update = False - -def update_screen_store(screen_store, screens): - screen_store.clear() - for s in screens.screens: - screen_store.append([s.name]) - -def create_film_tree_view(film_store): - view = gtk.TreeView(film_store) - column = gtk.TreeViewColumn() - view.append_column(column) - cell = gtk.CellRendererText() - column.pack_start(cell) - column.add_attribute(cell, 'text', 0) - view.get_selection().set_mode(gtk.SELECTION_SINGLE) - return view - -def create_screen_view(screen_store): - view = gtk.TreeView(screen_store) - column = gtk.TreeViewColumn() - view.append_column(column) - cell = gtk.CellRendererText() - column.pack_start(cell) - column.add_attribute(cell, 'text', 0) - view.get_selection().set_mode(gtk.SELECTION_SINGLE) - return view - -def get_selected_film(): - (model, iter) = film_tree_view.get_selection().get_selected() - - for f in films: - if f.name == model.get(iter, 0)[0]: - return f - - return None - -# @return Selected screen name -def get_selected_screen(): - (model, iter) = screen_view.get_selection().get_selected() - return model.get(iter, 0)[0] - -def film_selected(selection): - if inhibit_selection_update: - return - - film_view.set(get_selected_film()) - check_for_playability() - -def screen_selected(selection): - check_for_playability() - -def check_for_playability(): - f = get_selected_film() - if screens.get_format(get_selected_screen(), f.ratio) is not None: - play_button.set_label("Play") - play_button.set_sensitive(True) - else: - play_button.set_label("Cannot play: no setting for %s on screen %s" % (ratio.find(f.ratio).name(), get_selected_screen())) - play_button.set_sensitive(False) - -def update_status(s): - global current_player - if current_player is None: - s.set_text("Not playing") - return True - - position = current_player.time_pos - if position is None: - return True - position_hms = util.s_to_hms(position) - - length = current_player.length - if length is None: - return True - - remaining = length - position - remaining_hms = util.s_to_hms(remaining) - s.set_text("Playing: %d:%02d:%02d, %d:%02d:%02d remaining" % (position_hms[0], position_hms[1], position_hms[2], remaining_hms[0], remaining_hms[1], remaining_hms[2])) - return True - -def play_clicked(b): - global current_player - f = get_selected_film() - current_player = player.get_player(f, screens.get_format(get_selected_screen(), f.ratio)) - print current_player.args - -def stop_clicked(b): - global current_player - if current_player is not None: - current_player.stop() - current_player = None - -def add_film_clicked(b): - global films - c = gtk.FileChooserDialog("New Film", main_window, gtk.FILE_CHOOSER_ACTION_CREATE_FOLDER, (("Add", gtk.RESPONSE_OK))) - c.set_current_folder(FILM_DIRECTORY) - if c.run() == gtk.RESPONSE_OK: - f = film.Film() - f.data = c.get_filename() - f.name = os.path.basename(c.get_filename()) - f.write() - find_films() - update_film_store() - c.hide() - - for i in range(0, len(films)): - if films[i].name == f.name: - film_tree_view.get_selection().select_path((i, )) - -main_window = gtk.Window(gtk.WINDOW_TOPLEVEL) -main_window.set_title("DVD-o-matic") -main_window.maximize() - -main_hbox = gtk.HBox() -main_hbox.set_spacing(12) -main_hbox.set_border_width(12) -main_window.add(main_hbox) - -find_films() -film_view = film_view.FilmView(main_window) -screens = screens.Screens("screens") - -left_vbox = gtk.VBox() -left_vbox.set_spacing(12) -main_hbox.pack_start(left_vbox, False, False) -right_vbox = gtk.VBox() -right_vbox.set_spacing(12) -main_hbox.pack_start(right_vbox) - -film_store = gtk.ListStore(gobject.TYPE_STRING) -update_film_store() - -film_tree_view = create_film_tree_view(film_store) -left_vbox.pack_start(film_tree_view, True, True) -film_tree_view.get_selection().select_path((0, )) -film_tree_view.get_selection().connect("changed", film_selected) - -add_film_button = gtk.Button(stock = gtk.STOCK_ADD) -left_vbox.pack_start(add_film_button, False, False) -add_film_button.connect("clicked", add_film_clicked) - -screen_store = gtk.ListStore(gobject.TYPE_STRING) -update_screen_store(screen_store, screens) - -screen_view = create_screen_view(screen_store) -left_vbox.pack_start(screen_view, False, False) -screen_view.get_selection().select_path((0, )) -screen_view.get_selection().connect("changed", screen_selected) - -right_vbox.pack_start(film_view, False, False) -film_view.set(films[0]) - -play_button = gtk.Button("Play") -right_vbox.pack_start(play_button) -play_button.connect("clicked", play_clicked) - -stop_button = gtk.Button("Stop") -right_vbox.pack_start(stop_button) -stop_button.connect("clicked", stop_clicked) - -status = gtk.Label() -right_vbox.pack_start(status, False, False) -glib.timeout_add_seconds(1, update_status, status) - -check_for_playability() -main_window.show_all() -gtk.main() diff --git a/hacks/python-playback/film.py b/hacks/python-playback/film.py deleted file mode 100644 index 3ad128027..000000000 --- a/hacks/python-playback/film.py +++ /dev/null @@ -1,188 +0,0 @@ -import os -import subprocess -import shlex -import shutil -import player - -class Film: - def __init__(self, data = None): - # File or directory containing content - self.content = None - # True if content is in DVD format - self.dvd = False - # DVD title number - self.dvd_title = 1 - # Directory containing metadata - self.data = None - # Film name - self.name = None - # Number of pixels by which to crop the content from each edge - self.left_crop = 0 - self.top_crop = 0 - self.right_crop = 0 - self.bottom_crop = 0 - # Use deinterlacing filter - self.deinterlace = False - # Target ratio - self.ratio = 1.85 - # Audio stream ID to play - self.aid = None - - self.width = None - self.height = None - self.fps = None - self.length = None - - if data is not None: - self.data = data - f = open(os.path.join(self.data, 'info'), 'r') - while 1: - l = f.readline() - if l == '': - break - - d = l.strip() - - s = d.find(' ') - if s != -1: - key = d[:s] - value = d[s+1:] - - if key == 'name': - self.name = value - elif key == 'content': - self.content = value - elif key == 'dvd': - self.dvd = int(value) == 1 - elif key == 'dvd_title': - self.dvd_title = int(value) - elif key == 'left_crop': - self.left_crop = int(value) - elif key == 'top_crop': - self.top_crop = int(value) - elif key == 'right_crop': - self.right_crop = int(value) - elif key == 'bottom_crop': - self.bottom_crop = int(value) - elif key == 'deinterlace': - self.deinterlace = int(value) == 1 - elif key == 'ratio': - self.ratio = float(value) - elif key == 'aid': - self.aid = int(value) - elif key == 'width': - self.width = int(value) - elif key == 'height': - self.height = int(value) - elif key == 'fps': - self.fps = float(value) - elif key == 'length': - self.length = float(value) - - if self.width is None or self.height is None or self.fps is None or self.length is None: - self.update_content_metadata() - - def write(self): - try: - os.mkdir(self.data) - except OSError: - pass - - f = open(os.path.join(self.data, 'info'), 'w') - self.write_datum(f, 'name', self.name) - self.write_datum(f, 'content', self.content) - self.write_datum(f, 'dvd', int(self.dvd)) - self.write_datum(f, 'dvd_title', self.dvd_title) - self.write_datum(f, 'left_crop', self.left_crop) - self.write_datum(f, 'top_crop', self.top_crop) - self.write_datum(f, 'right_crop', self.right_crop) - self.write_datum(f, 'bottom_crop', self.bottom_crop) - self.write_datum(f, 'deinterlace', int(self.deinterlace)) - self.write_datum(f, 'ratio', self.ratio) - self.write_datum(f, 'aid', self.aid) - self.write_datum(f, 'width', self.width) - self.write_datum(f, 'height', self.height) - self.write_datum(f, 'fps', self.fps) - self.write_datum(f, 'length', self.length) - - def write_datum(self, f, key, value): - if value is not None: - print >>f,'%s %s' % (key, str(value)) - - def thumbs_dir(self): - t = os.path.join(self.data, 'thumbs') - - try: - os.mkdir(t) - except OSError: - pass - - return t - - def thumb(self, n): - return os.path.join(self.thumbs_dir(), str('%08d.png' % (n + 1))) - - def thumbs(self): - return len(os.listdir(self.thumbs_dir())) - - def remove_thumbs(self): - shutil.rmtree(self.thumbs_dir()) - - def make_thumbs(self): - num_thumbs = 128 - cl = self.player_command_line() - if self.length is not None: - sstep = self.length / num_thumbs - else: - sstep = 100 - cl.extra = '-vo png -frames %d -sstep %d -nosound' % (num_thumbs, sstep) - os.chdir(self.thumbs_dir()) - os.system(cl.get(True)) - - def set_dvd(self, d): - self.dvd = d - self.remove_thumbs() - - def set_dvd_title(self, t): - self.dvd_title = t - self.remove_thumbs() - - def set_content(self, c): - if c == self.content: - return - - self.content = c - self.update_content_metadata() - - def player_command_line(self): - cl = player.CommandLine() - cl.dvd = self.dvd - cl.dvd_title = self.dvd_title - cl.content = self.content - return cl - - def update_content_metadata(self): - if self.content is None: - return - - self.width = None - self.height = None - self.fps = None - self.length = None - - cl = self.player_command_line() - cl.extra = '-identify -vo null -ao null -frames 0' - text = subprocess.check_output(shlex.split(cl.get(True))).decode('utf-8') - lines = text.split('\n') - for l in lines: - s = l.strip() - b = s.split('=') - if len(b) == 2: - if b[0] == 'ID_VIDEO_WIDTH': - self.width = int(b[1]) - elif b[0] == 'ID_VIDEO_HEIGHT': - self.height = int(b[1]) - elif b[0] == 'ID_VIDEO_FPS': - self.fps = float(b[1]) - elif b[0] == 'ID_LENGTH': - self.length = float(b[1]) diff --git a/hacks/python-playback/film_view.py b/hacks/python-playback/film_view.py deleted file mode 100644 index c11b2e657..000000000 --- a/hacks/python-playback/film_view.py +++ /dev/null @@ -1,212 +0,0 @@ -import os -import pygtk -pygtk.require('2.0') -import gtk -import ratio -import util -import thumbs - -class FilmView(gtk.HBox): - def __init__(self, parent): - gtk.HBox.__init__(self) - - self.parent_window = parent - - self.inhibit_save = True - - self.table = gtk.Table() - self.pack_start(self.table, True, True) - - self.table.set_row_spacings(4) - self.table.set_col_spacings(12) - self.film_name = gtk.Entry() - self.ratio = gtk.combo_box_new_text() - for r in ratio.ratios: - self.ratio.append_text(r.name()) - self.content_file_radio = gtk.RadioButton() - self.content_file_radio.set_label("File") - self.content_file_chooser = gtk.FileChooserDialog("Content", self.parent_window, gtk.FILE_CHOOSER_ACTION_OPEN, (("Select", gtk.RESPONSE_OK))) - self.content_file_button = gtk.FileChooserButton(self.content_file_chooser) - self.content_folder_radio = gtk.RadioButton() - self.content_folder_radio.set_label("Folder") - self.content_folder_radio.set_group(self.content_file_radio) - self.content_folder_chooser = gtk.FileChooserDialog("Content", self.parent_window, gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, (("Select", gtk.RESPONSE_OK))) - self.content_folder_button = gtk.FileChooserButton(self.content_folder_chooser) - self.dvd = gtk.CheckButton("DVD") - self.dvd_title = gtk.SpinButton() - self.dvd_title.set_range(0, 32) - self.dvd_title.set_increments(1, 4) - self.deinterlace = gtk.CheckButton("Deinterlace") - self.left_crop = self.crop_spinbutton() - self.right_crop = self.crop_spinbutton() - self.top_crop = self.crop_spinbutton() - self.bottom_crop = self.crop_spinbutton() - - # Information about the content (immutable) - self.source_size = self.label() - self.fps = self.label() - self.length = self.label() - - # Buttons - self.thumbs_button = gtk.Button("Show Thumbnails") - - self.film_name.connect("changed", self.changed, self) - self.ratio.connect("changed", self.changed, self) - self.deinterlace.connect("toggled", self.changed, self) - self.thumbs_button.connect("clicked", self.thumbs_clicked, self) - self.content_file_radio.connect("toggled", self.content_radio_toggled, self) - self.content_folder_radio.connect("toggled", self.content_radio_toggled, self) - self.content_file_button.connect("file-set", self.content_file_chooser_file_set, self) - self.content_folder_button.connect("file-set", self.content_folder_chooser_file_set, self) - self.dvd.connect("toggled", self.changed, self) - self.dvd_title.connect("value-changed", self.changed, self) - - n = 0 - self.table.attach(self.label("Film"), 0, 1, n, n + 1) - self.table.attach(self.film_name, 1, 2, n, n + 1) - n += 1 - self.table.attach(self.label("Ratio"), 0, 1, n, n + 1) - self.table.attach(self.ratio, 1, 2, n, n + 1) - n += 1 - self.table.attach(self.label("Content"), 0, 1, n, n + 1) - b = gtk.HBox() - b.set_spacing(4) - b.pack_start(self.content_file_radio, False, False) - b.pack_start(self.content_file_button, True, True) - b.pack_start(self.content_folder_radio, False, False) - b.pack_start(self.content_folder_button, True, True) - self.table.attach(b, 1, 2, n, n + 1) - n += 1 - self.table.attach(self.dvd, 0, 2, n, n + 1) - n += 1 - self.table.attach(self.label("DVD title"), 0, 1, n, n + 1) - self.table.attach(self.dvd_title, 1, 2, n, n + 1) - n += 1 - self.table.attach(self.deinterlace, 0, 2, n, n + 1) - n += 1 - self.table.attach(self.label("Left Crop"), 0, 1, n, n + 1) - self.table.attach(self.left_crop, 1, 2, n, n + 1) - n += 1 - self.table.attach(self.label("Right Crop"), 0, 1, n, n + 1) - self.table.attach(self.right_crop, 1, 2, n, n + 1) - n += 1 - self.table.attach(self.label("Top Crop"), 0, 1, n, n + 1) - self.table.attach(self.top_crop, 1, 2, n, n + 1) - n += 1 - self.table.attach(self.label("Bottom Crop"), 0, 1, n, n + 1) - self.table.attach(self.bottom_crop, 1, 2, n, n + 1) - n += 1 - self.table.attach(self.label("Source size"), 0, 1, n, n + 1) - self.table.attach(self.source_size, 1, 2, n, n + 1) - n += 1 - self.table.attach(self.label("Frames per second"), 0, 1, n, n + 1) - self.table.attach(self.fps, 1, 2, n, n + 1) - n += 1 - self.table.attach(self.label("Length"), 0, 1, n, n + 1) - self.table.attach(self.length, 1, 2, n, n + 1) - - self.right_vbox = gtk.VBox() - self.pack_start(self.right_vbox, False, False) - - self.right_vbox.pack_start(self.thumbs_button, False, False) - - self.inhibit_save = False - - def set(self, film): - self.inhibit_save = True - - self.film = film - self.film_name.set_text(film.name) - self.ratio.set_active(ratio.ratio_to_index(film.ratio)) - if film.content is not None: - if os.path.isfile(film.content): - self.set_content_is_file(True) - self.content_file_button.set_filename(film.content) - else: - self.set_content_is_file(False) - self.content_folder_button.set_filename(film.content) - self.dvd.set_active(film.dvd) - self.dvd_title.set_value(film.dvd_title) - self.dvd_title.set_sensitive(film.dvd) - self.deinterlace.set_active(film.deinterlace) - self.left_crop.set_value(film.left_crop) - self.right_crop.set_value(film.right_crop) - self.top_crop.set_value(film.top_crop) - self.bottom_crop.set_value(film.bottom_crop) - - # Content information - if film.width is not None and film.height is not None: - self.source_size.set_text("%dx%d" % (film.width, film.height)) - else: - self.source_size.set_text("Unknown") - if film.fps is not None: - self.fps.set_text(str(film.fps)) - if film.length is not None: - self.length.set_text("%d:%02d:%02d" % util.s_to_hms(film.length)) - - self.inhibit_save = False - - def set_content_is_file(self, f): - self.content_file_button.set_sensitive(f) - self.content_folder_button.set_sensitive(not f) - self.content_file_radio.set_active(f) - self.content_folder_radio.set_active(not f) - - def label(self, text = ""): - l = gtk.Label(text) - l.set_alignment(0, 0.5) - return l - - def changed(self, a, b): - self.dvd_title.set_sensitive(self.dvd.get_active()) - self.save_film() - - def crop_spinbutton(self): - s = gtk.SpinButton() - s.set_range(0, 1024) - s.set_increments(1, 16) - s.connect("value-changed", self.changed, self) - return s - - def save_film(self): - if self.inhibit_save: - return - - self.film.name = self.film_name.get_text() - self.film.ratio = ratio.index_to_ratio(self.ratio.get_active()).ratio - - if self.content_file_radio.get_active(): - self.film.set_content(self.content_file_button.get_filename()) - else: - self.film.set_content(self.content_folder_button.get_filename()) - self.film.set_dvd(self.dvd.get_active()) - self.film.set_dvd_title(self.dvd_title.get_value_as_int()) - self.film.deinterlace = self.deinterlace.get_active() - self.film.left_crop = self.left_crop.get_value_as_int() - self.film.right_crop = self.right_crop.get_value_as_int() - self.film.top_crop = self.top_crop.get_value_as_int() - self.film.bottom_crop = self.bottom_crop.get_value_as_int() - self.film.write() - - def thumbs_clicked(self, a, b): - if self.film.thumbs() == 0: - self.film.make_thumbs() - - t = thumbs.Thumbs(self.film) - t.run() - t.hide() - self.left_crop.set_value(t.left_crop()) - self.right_crop.set_value(t.right_crop()) - self.top_crop.set_value(t.top_crop()) - self.bottom_crop.set_value(t.bottom_crop()) - - def content_file_chooser_file_set(self, a, b): - self.changed(a, b) - - def content_folder_chooser_file_set(self, a, b): - self.changed(a, b) - - def content_radio_toggled(self, a, b): - self.set_content_is_file(self.content_file_radio.get_active()) - self.changed(a, b) - diff --git a/hacks/python-playback/player.py b/hacks/python-playback/player.py deleted file mode 100644 index 5cc8da711..000000000 --- a/hacks/python-playback/player.py +++ /dev/null @@ -1,112 +0,0 @@ -import os -import threading -import subprocess -import shlex -import select -import film -import config -import mplayer - -class CommandLine: - def __init__(self): - self.position_x = 0 - self.position_y = 0 - self.output_width = None - self.output_height = None - self.mov = False - self.delay = None - self.dvd = False - self.dvd_title = 1 - self.content = None - self.extra = '' - self.crop_x = None - self.crop_y = None - self.crop_w = None - self.crop_h = None - self.deinterlace = False - self.aid = None - - def get(self, with_binary): - # hqdn3d? - # nr, unsharp? - # -vo x11 appears to be necessary to prevent unwanted hardware scaling - # -noaspect stops mplayer rescaling to the movie's specified aspect ratio - args = '-vo x11 -noaspect -ao pulse -noborder -noautosub -nosub -sws 10 ' - args += '-geometry %d:%d ' % (self.position_x, self.position_y) - - # Video filters (passed to -vf) - - filters = [] - - if self.crop_x is not None or self.crop_y is not None or self.crop_w is not None or self.crop_h is not None: - crop = 'crop=' - if self.crop_w is not None and self.crop_h is not None: - crop += '%d:%d' % (self.crop_w, self.crop_h) - if self.crop_x is not None and self.crop_x is not None: - crop += ':%d:%d' % (self.crop_x, self.crop_y) - filters.append(crop) - - if self.output_width is not None or self.output_height is not None: - filters.append('scale=%d:%d' % (self.output_width, self.output_height)) - - # Post processing - pp = [] - if self.deinterlace: - pp.append('lb') - - # Deringing filter - pp.append('dr') - - if len(pp) > 0: - pp_string = 'pp=' - for i in range(0, len(pp)): - pp_string += pp[i] - if i < len(pp) - 1: - pp += ',' - - filters.append(pp_string) - - if len(filters) > 0: - args += '-vf ' - for i in range(0, len(filters)): - args += filters[i] - if i < len(filters) - 1: - args += ',' - args += ' ' - - if self.mov: - args += '-demuxer mov ' - if self.delay is not None: - args += '-delay %f ' % float(args.delay) - if self.aid is not None: - args += '-aid %s ' % self.aid - - args += self.extra - - if self.dvd: - data_specifier = 'dvd://%d -dvd-device \"%s\"' % (self.dvd_title, self.content) - else: - data_specifier = '\"%s\"' % self.content - - if with_binary: - return 'mplayer %s %s' % (args, data_specifier) - - return '%s %s' % (args, data_specifier) - -def get_player(film, format): - cl = CommandLine() - cl.dvd = film.dvd - cl.dvd_title = film.dvd_title - cl.content = film.content - cl.crop_w = film.width - film.left_crop - film.right_crop - cl.crop_h = film.height - film.top_crop - film.bottom_crop - cl.position_x = format.x - if format.external: - cl.position_x = format.x + config.LEFT_SCREEN_WIDTH - cl.position_y = format.y - cl.output_width = format.width - cl.output_height = format.height - cl.deinterlace = film.deinterlace - cl.aid = film.aid - return mplayer.Player(cl.get(False)) - diff --git a/hacks/python-playback/ratio.py b/hacks/python-playback/ratio.py deleted file mode 100644 index 62320dc8a..000000000 --- a/hacks/python-playback/ratio.py +++ /dev/null @@ -1,56 +0,0 @@ -# Class to describe a Ratio, and a collection of common -# (and not-so-common) film ratios collected from Wikipedia. - -class Ratio: - def __init__(self, ratio, nickname = None): - self.nickname = nickname - self.ratio = ratio - - # @return presentation name of this ratio - def name(self): - if self.nickname is not None: - return "%.2f (%s)" % (self.ratio, self.nickname) - - return "%.2f" % self.ratio - -ratios = [] -ratios.append(Ratio(1.33, '4:3')) -ratios.append(Ratio(1.37, 'Academy')) -ratios.append(Ratio(1.78, '16:9')) -ratios.append(Ratio(1.85, 'Flat / widescreen')) -ratios.append(Ratio(2.39, 'CinemaScope / Panavision')) -ratios.append(Ratio(1.15, 'Movietone')) -ratios.append(Ratio(1.43, 'IMAX')) -ratios.append(Ratio(1.5)) -ratios.append(Ratio(1.56, '14:9')) -ratios.append(Ratio(1.6, '16:10')) -ratios.append(Ratio(1.67)) -ratios.append(Ratio(2, 'SuperScope')) -ratios.append(Ratio(2.2, 'Todd-AO')) -ratios.append(Ratio(2.35, 'Early CinemaScope / Panavision')) -ratios.append(Ratio(2.37, '21:9')) -ratios.append(Ratio(2.55, 'CinemaScope 55')) -ratios.append(Ratio(2.59, 'Cinerama')) -ratios.append(Ratio(2.76, 'Ultra Panavision')) -ratios.append(Ratio(2.93, 'MGM Camera 65')) -ratios.append(Ratio(4, 'Polyvision')) - -# Find a Ratio object from a fractional ratio -def find(ratio): - for r in ratios: - if r.ratio == ratio: - return r - - return None - -# @return the ith ratio -def index_to_ratio(i): - return ratios[i] - -# @return the index within the ratios list of a given fractional ratio -def ratio_to_index(r): - for i in range(0, len(ratios)): - if ratios[i].ratio == r: - return i - - return None diff --git a/hacks/python-playback/screens b/hacks/python-playback/screens deleted file mode 100644 index f389cb1c4..000000000 --- a/hacks/python-playback/screens +++ /dev/null @@ -1,62 +0,0 @@ -# Screen 1 (untested) -screen 1 -ratio 1.85 -x 175 -y 100 -width 1550 -height 950 -external 1 -ratio 2.39 -x 0 -y 200 -width 2000 -height 860 -external 1 - -# Screen 2 -screen 2 -ratio 1.85 -x 175 -y 100 -width 1550 -height 950 -external 1 -ratio 2.39 -x 0 -y 200 -width 2000 -height 860 -external 1 - -# Screen 3 (untested) -screen 3 -ratio 1.85 -x 175 -y 100 -width 1550 -height 950 -external 1 -ratio 2.39 -x 0 -y 200 -width 2000 -height 860 -external 1 - -# Carl's Laptop -screen laptop -ratio 1.85 -x 0 -y 0 -width 1366 -height 738 -ratio 2.39 -x 0 -y 0 -width 1366 -height 572 -ratio 1.78 -x 0 -y 0 -width 1366 -height 767 diff --git a/hacks/python-playback/screens.py b/hacks/python-playback/screens.py deleted file mode 100644 index 4230a4cf8..000000000 --- a/hacks/python-playback/screens.py +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/python - -class Screen: - def __init__(self): - self.name = None - self.formats = [] - -class Format: - def __init__(self): - self.ratio = None - self.x = None - self.y = None - self.width = None - self.height = None - self.external = False - -class Screens: - def __init__(self, file): - - self.screens = [] - - f = open(file, 'r') - current_screen = None - current_format = None - while 1: - l = f.readline() - if l == '': - break - if len(l) > 0 and l[0] == '#': - continue - - s = l.strip() - - if len(s) == 0: - continue - - b = s.split() - - if len(b) != 2: - print "WARNING: ignored line `%s' in screens file" % (s) - continue - - if b[0] == 'screen': - if current_format is not None: - current_screen.formats.append(current_format) - current_format = None - - if current_screen is not None: - self.screens.append(current_screen) - current_screen = None - - current_screen = Screen() - current_screen.name = b[1] - elif b[0] == 'ratio': - if current_format is not None: - current_screen.formats.append(current_format) - current_format = None - - current_format = Format() - current_format.ratio = float(b[1]) - elif b[0] == 'x': - current_format.x = int(b[1]) - elif b[0] == 'y': - current_format.y = int(b[1]) - elif b[0] == 'width': - current_format.width = int(b[1]) - elif b[0] == 'height': - current_format.height = int(b[1]) - elif b[0] == 'external': - current_format.external = int(b[1]) == 1 - - if current_format is not None: - current_screen.formats.append(current_format) - - if current_screen is not None: - self.screens.append(current_screen) - - def get_format(self, screen, ratio): - for s in self.screens: - if s.name == screen: - for f in s.formats: - if f.ratio == ratio: - return f - - return None diff --git a/hacks/python-playback/thumbs.py b/hacks/python-playback/thumbs.py deleted file mode 100644 index 921f82f5d..000000000 --- a/hacks/python-playback/thumbs.py +++ /dev/null @@ -1,76 +0,0 @@ -# GUI to display thumbnails and allow cropping -# to be set up - -import os -import sys -import pygtk -pygtk.require('2.0') -import gtk -import film -import player - -class Thumbs(gtk.Dialog): - def __init__(self, film): - gtk.Dialog.__init__(self) - self.film = film - self.controls = gtk.Table() - self.controls.set_col_spacings(4) - self.thumb_adj = gtk.Adjustment(0, 0, self.film.thumbs() - 1, 1, 10) - self.add_control("Thumbnail", self.thumb_adj, 0) - self.left_crop_adj = gtk.Adjustment(self.film.left_crop, 0, 1024, 1, 128) - self.add_control("Left crop", self.left_crop_adj, 1) - self.right_crop_adj = gtk.Adjustment(self.film.right_crop, 0, 1024, 1, 128) - self.add_control("Right crop", self.right_crop_adj, 2) - self.top_crop_adj = gtk.Adjustment(self.film.top_crop, 0, 1024, 1, 128) - self.add_control("Top crop", self.top_crop_adj, 3) - self.bottom_crop_adj = gtk.Adjustment(self.film.bottom_crop, 0, 1024, 1, 128) - self.add_control("Bottom crop", self.bottom_crop_adj, 4) - self.display_image = gtk.Image() - self.update_display() - window_box = gtk.HBox() - window_box.set_spacing(12) - - controls_vbox = gtk.VBox() - controls_vbox.set_spacing(4) - controls_vbox.pack_start(self.controls, False, False) - - window_box.pack_start(controls_vbox, True, True) - window_box.pack_start(self.display_image) - - self.set_title("%s Thumbnails" % film.name) - self.get_content_area().add(window_box) - self.add_button("Close", gtk.RESPONSE_ACCEPT) - self.show_all() - - for a in [self.thumb_adj, self.left_crop_adj, self.right_crop_adj, self.top_crop_adj, self.bottom_crop_adj]: - a.connect('value-changed', self.update_display, self) - - def add_control(self, name, adj, n): - l = gtk.Label(name) - l.set_alignment(1, 0.5) - self.controls.attach(l, 0, 1, n, n + 1) - s = gtk.SpinButton(adj) - self.controls.attach(s, 1, 2, n, n + 1) - - def update_display(self, a = None, b = None): - thumb_pixbuf = gtk.gdk.pixbuf_new_from_file(self.film.thumb(self.thumb_adj.get_value())) - self.width = thumb_pixbuf.get_width() - self.height = thumb_pixbuf.get_height() - left = self.left_crop() - right = self.right_crop() - top = self.top_crop() - bottom = self.bottom_crop() - pixbuf = thumb_pixbuf.subpixbuf(left, top, self.width - left - right, self.height - top - bottom) - self.display_image.set_from_pixbuf(pixbuf) - - def top_crop(self): - return int(self.top_crop_adj.get_value()) - - def bottom_crop(self): - return int(self.bottom_crop_adj.get_value()) - - def left_crop(self): - return int(self.left_crop_adj.get_value()) - - def right_crop(self): - return int(self.right_crop_adj.get_value()) diff --git a/hacks/python-playback/util.py b/hacks/python-playback/util.py deleted file mode 100644 index d78abdd00..000000000 --- a/hacks/python-playback/util.py +++ /dev/null @@ -1,7 +0,0 @@ - -def s_to_hms(s): - m = int(s / 60) - s -= (m * 60) - h = int(m / 60) - m -= (h * 60) - return (h, m, s) diff --git a/hacks/python-playback/xrandr-notes b/hacks/python-playback/xrandr-notes deleted file mode 100644 index eeabf1423..000000000 --- a/hacks/python-playback/xrandr-notes +++ /dev/null @@ -1,17 +0,0 @@ -Recommended 1680 x 1050, 60 fps -xrandr --output HDMI1 --mode 0xbc - -List modes -xrandr --verbose -q - -2048 x 1024, 24 fps -xrandr --output HDMI1 --mode 0xd1 - -cvt -to give modeline, then -xrandr --newmode modeline -then add -xrandr --verbose --addmode HDMI1 modename -then activate -xrandr --output HDMI1 --mode foo - diff --git a/icons/128x128/dvdomatic.png b/icons/128x128/dvdomatic.png deleted file mode 100644 index 9936b39af..000000000 Binary files a/icons/128x128/dvdomatic.png and /dev/null differ diff --git a/icons/16x16/dvdomatic.png b/icons/16x16/dvdomatic.png deleted file mode 100644 index 3c5a10f2d..000000000 Binary files a/icons/16x16/dvdomatic.png and /dev/null differ diff --git a/icons/22x22/dvdomatic.png b/icons/22x22/dvdomatic.png deleted file mode 100644 index dddb86298..000000000 Binary files a/icons/22x22/dvdomatic.png and /dev/null differ diff --git a/icons/32x32/dvdomatic.png b/icons/32x32/dvdomatic.png deleted file mode 100644 index 8cecf08f8..000000000 Binary files a/icons/32x32/dvdomatic.png and /dev/null differ diff --git a/icons/48x48/dvdomatic.png b/icons/48x48/dvdomatic.png deleted file mode 100644 index 07bf2d10b..000000000 Binary files a/icons/48x48/dvdomatic.png and /dev/null differ diff --git a/icons/64x64/dvdomatic.png b/icons/64x64/dvdomatic.png deleted file mode 100644 index 35564a8a2..000000000 Binary files a/icons/64x64/dvdomatic.png and /dev/null differ diff --git a/run/dvdomatic b/run/dvdomatic deleted file mode 100755 index dbc63d44a..000000000 --- a/run/dvdomatic +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -export LD_LIBRARY_PATH=build/src/lib:build/src/wx:build/src/asdcplib/src:$LD_LIBRARY_PATH -if [ "$1" == "--debug" ]; then - shift - gdb --args build/src/tools/dvdomatic $* -elif [ "$1" == "--valgrind" ]; then - shift - valgrind --tool="memcheck" build/src/tools/dvdomatic $* -elif [ "$1" == "--i18n" ]; then - shift - LANGUAGE=fr_FR.UTF8 LANG=fr_FR.UTF8 build/src/tools/dvdomatic "$*" -else - build/src/tools/dvdomatic $* -fi diff --git a/src/lib/audio_analysis.h b/src/lib/audio_analysis.h index 6e0e2b78a..ec6905105 100644 --- a/src/lib/audio_analysis.h +++ b/src/lib/audio_analysis.h @@ -17,8 +17,8 @@ */ -#ifndef DVDOMATIC_AUDIO_ANALYSIS_H -#define DVDOMATIC_AUDIO_ANALYSIS_H +#ifndef DCPOMATIC_AUDIO_ANALYSIS_H +#define DCPOMATIC_AUDIO_ANALYSIS_H #include #include diff --git a/src/lib/audio_content.h b/src/lib/audio_content.h index dbd55943d..2362786d9 100644 --- a/src/lib/audio_content.h +++ b/src/lib/audio_content.h @@ -17,8 +17,8 @@ */ -#ifndef DVDOMATIC_AUDIO_CONTENT_H -#define DVDOMATIC_AUDIO_CONTENT_H +#ifndef DCPOMATIC_AUDIO_CONTENT_H +#define DCPOMATIC_AUDIO_CONTENT_H #include "content.h" #include "util.h" diff --git a/src/lib/audio_decoder.h b/src/lib/audio_decoder.h index 24e2796ae..418fc6da2 100644 --- a/src/lib/audio_decoder.h +++ b/src/lib/audio_decoder.h @@ -21,8 +21,8 @@ * @brief Parent class for audio decoders. */ -#ifndef DVDOMATIC_AUDIO_DECODER_H -#define DVDOMATIC_AUDIO_DECODER_H +#ifndef DCPOMATIC_AUDIO_DECODER_H +#define DCPOMATIC_AUDIO_DECODER_H #include "audio_source.h" #include "decoder.h" diff --git a/src/lib/audio_mapping.h b/src/lib/audio_mapping.h index 4f2cdb7f8..248d2570e 100644 --- a/src/lib/audio_mapping.h +++ b/src/lib/audio_mapping.h @@ -17,8 +17,8 @@ */ -#ifndef DVDOMATIC_AUDIO_MAPPING_H -#define DVDOMATIC_AUDIO_MAPPING_H +#ifndef DCPOMATIC_AUDIO_MAPPING_H +#define DCPOMATIC_AUDIO_MAPPING_H #include #include diff --git a/src/lib/audio_sink.h b/src/lib/audio_sink.h index 11d578a60..085491657 100644 --- a/src/lib/audio_sink.h +++ b/src/lib/audio_sink.h @@ -17,8 +17,8 @@ */ -#ifndef DVDOMATIC_AUDIO_SINK_H -#define DVDOMATIC_AUDIO_SINK_H +#ifndef DCPOMATIC_AUDIO_SINK_H +#define DCPOMATIC_AUDIO_SINK_H class AudioSink { diff --git a/src/lib/audio_source.h b/src/lib/audio_source.h index 5a1510d3c..ee5c606dc 100644 --- a/src/lib/audio_source.h +++ b/src/lib/audio_source.h @@ -21,8 +21,8 @@ * @brief Parent class for classes which emit audio data. */ -#ifndef DVDOMATIC_AUDIO_SOURCE_H -#define DVDOMATIC_AUDIO_SOURCE_H +#ifndef DCPOMATIC_AUDIO_SOURCE_H +#define DCPOMATIC_AUDIO_SOURCE_H #include diff --git a/src/lib/config.cc b/src/lib/config.cc index 2defa0539..354940b1c 100644 --- a/src/lib/config.cc +++ b/src/lib/config.cc @@ -155,9 +155,9 @@ Config::file (bool old) const boost::filesystem::path p; p /= g_get_user_config_dir (); if (old) { - p /= ".dvdomatic"; + p /= ".dcpomatic"; } else { - p /= ".dvdomatic.xml"; + p /= ".dcpomatic.xml"; } return p.string (); } diff --git a/src/lib/config.h b/src/lib/config.h index 13d36d236..57f4fb8a9 100644 --- a/src/lib/config.h +++ b/src/lib/config.h @@ -21,8 +21,8 @@ * @brief Class holding configuration. */ -#ifndef DVDOMATIC_CONFIG_H -#define DVDOMATIC_CONFIG_H +#ifndef DCPOMATIC_CONFIG_H +#define DCPOMATIC_CONFIG_H #include #include diff --git a/src/lib/content.h b/src/lib/content.h index c8aa6b0e0..d39fc9e1a 100644 --- a/src/lib/content.h +++ b/src/lib/content.h @@ -17,8 +17,8 @@ */ -#ifndef DVDOMATIC_CONTENT_H -#define DVDOMATIC_CONTENT_H +#ifndef DCPOMATIC_CONTENT_H +#define DCPOMATIC_CONTENT_H #include #include diff --git a/src/lib/cross.cc b/src/lib/cross.cc index 2c66ab53a..f232f1779 100644 --- a/src/lib/cross.cc +++ b/src/lib/cross.cc @@ -18,20 +18,20 @@ */ #include "cross.h" -#ifdef DVDOMATIC_POSIX +#ifdef DCPOMATIC_POSIX #include #endif -#ifdef DVDOMATIC_WINDOWS +#ifdef DCPOMATIC_WINDOWS #include "windows.h" #endif void -dvdomatic_sleep (int s) +dcpomatic_sleep (int s) { -#ifdef DVDOMATIC_POSIX +#ifdef DCPOMATIC_POSIX sleep (s); #endif -#ifdef DVDOMATIC_WINDOWS +#ifdef DCPOMATIC_WINDOWS Sleep (s * 1000); #endif } diff --git a/src/lib/cross.h b/src/lib/cross.h index 110660b16..00457c968 100644 --- a/src/lib/cross.h +++ b/src/lib/cross.h @@ -17,8 +17,8 @@ */ -#ifdef DVDOMATIC_WINDOWS +#ifdef DCPOMATIC_WINDOWS #define WEXITSTATUS(w) (w) #endif -void dvdomatic_sleep (int); +void dcpomatic_sleep (int); diff --git a/src/lib/dci_metadata.h b/src/lib/dci_metadata.h index f61dae5a8..b87609ed0 100644 --- a/src/lib/dci_metadata.h +++ b/src/lib/dci_metadata.h @@ -17,8 +17,8 @@ */ -#ifndef DVDOMATIC_DCI_METADATA_H -#define DVDOMATIC_DCI_METADATA_H +#ifndef DCPOMATIC_DCI_METADATA_H +#define DCPOMATIC_DCI_METADATA_H #include #include diff --git a/src/lib/dcp_content_type.h b/src/lib/dcp_content_type.h index 960bb0129..14204bd72 100644 --- a/src/lib/dcp_content_type.h +++ b/src/lib/dcp_content_type.h @@ -17,8 +17,8 @@ */ -#ifndef DVDOMATIC_DCP_CONTENT_TYPE_H -#define DVDOMATIC_DCP_CONTENT_TYPE_H +#ifndef DCPOMATIC_DCP_CONTENT_TYPE_H +#define DCPOMATIC_DCP_CONTENT_TYPE_H /** @file src/content_type.h * @brief A description of the type of content for a DCP (e.g. feature, trailer etc.) diff --git a/src/lib/dcp_video_frame.cc b/src/lib/dcp_video_frame.cc index e9499871a..da51665d1 100644 --- a/src/lib/dcp_video_frame.cc +++ b/src/lib/dcp_video_frame.cc @@ -266,7 +266,7 @@ DCPVideoFrame::encode_locally () _parameters->tcp_numlayers++; _parameters->cp_disto_alloc = 1; _parameters->cp_rsiz = CINEMA2K; - _parameters->cp_comment = strdup (N_("DVD-o-matic")); + _parameters->cp_comment = strdup (N_("DCP-o-matic")); _parameters->cp_cinema = CINEMA2K_24; /* 3 components, so use MCT */ diff --git a/src/lib/decoder.h b/src/lib/decoder.h index 0fffef257..72b866ffe 100644 --- a/src/lib/decoder.h +++ b/src/lib/decoder.h @@ -21,8 +21,8 @@ * @brief Parent class for decoders of content. */ -#ifndef DVDOMATIC_DECODER_H -#define DVDOMATIC_DECODER_H +#ifndef DCPOMATIC_DECODER_H +#define DCPOMATIC_DECODER_H #include #include diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index b897c8a31..a8e3547a1 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -423,7 +423,7 @@ Encoder::encoder_thread (ServerDescription* server) } if (remote_backoff > 0) { - dvdomatic_sleep (remote_backoff); + dcpomatic_sleep (remote_backoff); } lock.lock (); diff --git a/src/lib/encoder.h b/src/lib/encoder.h index 70e6eea9a..56007fd48 100644 --- a/src/lib/encoder.h +++ b/src/lib/encoder.h @@ -17,8 +17,8 @@ */ -#ifndef DVDOMATIC_ENCODER_H -#define DVDOMATIC_ENCODER_H +#ifndef DCPOMATIC_ENCODER_H +#define DCPOMATIC_ENCODER_H /** @file src/encoder.h * @brief Encoder to J2K and WAV for DCP. diff --git a/src/lib/exceptions.h b/src/lib/exceptions.h index 6920556e5..6bad7c924 100644 --- a/src/lib/exceptions.h +++ b/src/lib/exceptions.h @@ -17,8 +17,8 @@ */ -#ifndef DVDOMATIC_EXCEPTIONS_H -#define DVDOMATIC_EXCEPTIONS_H +#ifndef DCPOMATIC_EXCEPTIONS_H +#define DCPOMATIC_EXCEPTIONS_H /** @file src/exceptions.h * @brief Our exceptions. diff --git a/src/lib/ffmpeg_content.h b/src/lib/ffmpeg_content.h index b49e5790e..8bf4d42a5 100644 --- a/src/lib/ffmpeg_content.h +++ b/src/lib/ffmpeg_content.h @@ -17,8 +17,8 @@ */ -#ifndef DVDOMATIC_FFMPEG_CONTENT_H -#define DVDOMATIC_FFMPEG_CONTENT_H +#ifndef DCPOMATIC_FFMPEG_CONTENT_H +#define DCPOMATIC_FFMPEG_CONTENT_H #include #include "video_content.h" diff --git a/src/lib/film.cc b/src/lib/film.cc index 6ab6551da..67605ffca 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -254,7 +254,7 @@ Film::make_dcp () throw BadSettingError (_("name"), _("cannot contain slashes")); } - log()->log (String::compose ("DVD-o-matic %1 git %2 using %3", dvdomatic_version, dvdomatic_git_commit, dependency_version_summary())); + log()->log (String::compose ("DCP-o-matic %1 git %2 using %3", dcpomatic_version, dcpomatic_git_commit, dependency_version_summary())); { char buffer[128]; @@ -270,10 +270,10 @@ Film::make_dcp () // log()->log (String::compose ("Content at %1 fps, DCP at %2 fps", source_frame_rate(), dcp_frame_rate())); log()->log (String::compose ("%1 threads", Config::instance()->num_local_encoding_threads())); log()->log (String::compose ("J2K bandwidth %1", j2k_bandwidth())); -#ifdef DVDOMATIC_DEBUG - log()->log ("DVD-o-matic built in debug mode."); +#ifdef DCPOMATIC_DEBUG + log()->log ("DCP-o-matic built in debug mode."); #else - log()->log ("DVD-o-matic built in optimised mode."); + log()->log ("DCP-o-matic built in optimised mode."); #endif #ifdef LIBDCP_DEBUG log()->log ("libdcp built in debug mode."); @@ -432,7 +432,7 @@ Film::read_metadata () boost::mutex::scoped_lock lm (_state_mutex); if (boost::filesystem::exists (file ("metadata")) && !boost::filesystem::exists (file ("metadata.xml"))) { - throw StringError (_("This film was created with an older version of DVD-o-matic, and unfortunately it cannot be loaded into this version. You will need to create a new Film, re-add your content and set it up again. Sorry!")); + throw StringError (_("This film was created with an older version of DCP-o-matic, and unfortunately it cannot be loaded into this version. You will need to create a new Film, re-add your content and set it up again. Sorry!")); } cxml::File f (file ("metadata.xml"), "Metadata"); diff --git a/src/lib/film.h b/src/lib/film.h index 4d994996e..ffa5d0690 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -22,8 +22,8 @@ * how they should be presented in a DCP. */ -#ifndef DVDOMATIC_FILM_H -#define DVDOMATIC_FILM_H +#ifndef DCPOMATIC_FILM_H +#define DCPOMATIC_FILM_H #include #include @@ -336,7 +336,7 @@ private: /** Mutex for _directory */ mutable boost::mutex _directory_mutex; - /** Name for DVD-o-matic */ + /** Name for DCP-o-matic */ std::string _name; /** True if a auto-generated DCI-compliant name should be used for our DCP */ bool _use_dci_name; diff --git a/src/lib/filter.h b/src/lib/filter.h index 205d92482..7587312c2 100644 --- a/src/lib/filter.h +++ b/src/lib/filter.h @@ -21,8 +21,8 @@ * @brief A class to describe one of FFmpeg's video or post-processing filters. */ -#ifndef DVDOMATIC_FILTER_H -#define DVDOMATIC_FILTER_H +#ifndef DCPOMATIC_FILTER_H +#define DCPOMATIC_FILTER_H #include #include diff --git a/src/lib/filter_graph.h b/src/lib/filter_graph.h index db86a677d..1ff5527ab 100644 --- a/src/lib/filter_graph.h +++ b/src/lib/filter_graph.h @@ -21,8 +21,8 @@ * @brief A graph of FFmpeg filters. */ -#ifndef DVDOMATIC_FILTER_GRAPH_H -#define DVDOMATIC_FILTER_GRAPH_H +#ifndef DCPOMATIC_FILTER_GRAPH_H +#define DCPOMATIC_FILTER_GRAPH_H #include "util.h" #include "ffmpeg_compatibility.h" diff --git a/src/lib/i18n.h b/src/lib/i18n.h index 46bb1d565..890313bc6 100644 --- a/src/lib/i18n.h +++ b/src/lib/i18n.h @@ -19,5 +19,5 @@ #include -#define _(x) dgettext ("libdvdomatic", x) +#define _(x) dgettext ("libdcpomatic", x) #define N_(x) x diff --git a/src/lib/image.h b/src/lib/image.h index 6b9ade99e..1d7d75dfc 100644 --- a/src/lib/image.h +++ b/src/lib/image.h @@ -21,8 +21,8 @@ * @brief A set of classes to describe video images. */ -#ifndef DVDOMATIC_IMAGE_H -#define DVDOMATIC_IMAGE_H +#ifndef DCPOMATIC_IMAGE_H +#define DCPOMATIC_IMAGE_H #include #include diff --git a/src/lib/job.cc b/src/lib/job.cc index ff0332d6d..2a4986f0d 100644 --- a/src/lib/job.cc +++ b/src/lib/job.cc @@ -87,7 +87,7 @@ Job::run_wrapper () set_state (FINISHED_ERROR); set_error ( e.what (), - _("It is not known what caused this error. The best idea is to report the problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)") + _("It is not known what caused this error. The best idea is to report the problem to the DCP-o-matic mailing list (dcpomatic@carlh.net)") ); } catch (...) { @@ -96,7 +96,7 @@ Job::run_wrapper () set_state (FINISHED_ERROR); set_error ( _("Unknown error"), - _("It is not known what caused this error. The best idea is to report the problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)") + _("It is not known what caused this error. The best idea is to report the problem to the DCP-o-matic mailing list (dcpomatic@carlh.net)") ); } diff --git a/src/lib/job.h b/src/lib/job.h index f5175c525..2119db2f3 100644 --- a/src/lib/job.h +++ b/src/lib/job.h @@ -21,8 +21,8 @@ * @brief A parent class to represent long-running tasks which are run in their own thread. */ -#ifndef DVDOMATIC_JOB_H -#define DVDOMATIC_JOB_H +#ifndef DCPOMATIC_JOB_H +#define DCPOMATIC_JOB_H #include #include diff --git a/src/lib/job_manager.cc b/src/lib/job_manager.cc index 910597628..f96275467 100644 --- a/src/lib/job_manager.cc +++ b/src/lib/job_manager.cc @@ -126,7 +126,7 @@ JobManager::scheduler () } } - dvdomatic_sleep (1); + dcpomatic_sleep (1); } } diff --git a/src/lib/log.h b/src/lib/log.h index 3a2cfcbfd..3ad6516c1 100644 --- a/src/lib/log.h +++ b/src/lib/log.h @@ -17,8 +17,8 @@ */ -#ifndef DVDOMATIC_LOG_H -#define DVDOMATIC_LOG_H +#ifndef DCPOMATIC_LOG_H +#define DCPOMATIC_LOG_H /** @file src/log.h * @brief A very simple logging class. diff --git a/src/lib/player.h b/src/lib/player.h index 8a82ab298..dbfde09a6 100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@ -17,8 +17,8 @@ */ -#ifndef DVDOMATIC_PLAYER_H -#define DVDOMATIC_PLAYER_H +#ifndef DCPOMATIC_PLAYER_H +#define DCPOMATIC_PLAYER_H #include #include diff --git a/src/lib/po/es_ES.po b/src/lib/po/es_ES.po index 17051bd98..5c8d642e3 100644 --- a/src/lib/po/es_ES.po +++ b/src/lib/po/es_ES.po @@ -5,7 +5,7 @@ # msgid "" msgstr "" -"Project-Id-Version: LIBDVDOMATIC\n" +"Project-Id-Version: LIBDCPOMATIC\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-04-09 11:14+0100\n" "PO-Revision-Date: 2013-04-02 19:10-0500\n" @@ -250,10 +250,10 @@ msgstr "Horizontal deblocking filter A" #: src/lib/job.cc:92 src/lib/job.cc:101 msgid "" "It is not known what caused this error. The best idea is to report the " -"problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" +"problem to the DCP-o-matic mailing list (dcpomatic@carlh.net)" msgstr "" "Error desconocido. La mejor idea es informar del problema a la lista de " -"correo de DVD-O-matic (dvdomatic@carlh.net)" +"correo de DCP-o-matic (dcpomatic@carlh.net)" #: src/lib/filter.cc:82 msgid "Kernel deinterlacer" diff --git a/src/lib/po/fr_FR.po b/src/lib/po/fr_FR.po index d9d945b52..af6890d97 100644 --- a/src/lib/po/fr_FR.po +++ b/src/lib/po/fr_FR.po @@ -5,7 +5,7 @@ # msgid "" msgstr "" -"Project-Id-Version: DVD-o-matic FRENCH\n" +"Project-Id-Version: DCP-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-04-09 11:14+0100\n" "PO-Revision-Date: 2013-03-20 00:39+0100\n" @@ -248,10 +248,10 @@ msgstr "Filtre dé-bloc horizontal" #: src/lib/job.cc:92 src/lib/job.cc:101 msgid "" "It is not known what caused this error. The best idea is to report the " -"problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" +"problem to the DCP-o-matic mailing list (dcpomatic@carlh.net)" msgstr "" -"Erreur indéterminée. Merci de rapporter le problème à la liste DVD-o-matic " -"(dvdomatic@carlh.net)" +"Erreur indéterminée. Merci de rapporter le problème à la liste DCP-o-matic " +"(dcpomatic@carlh.net)" #: src/lib/filter.cc:82 msgid "Kernel deinterlacer" diff --git a/src/lib/po/it_IT.po b/src/lib/po/it_IT.po index 992eda107..c1ca26ea3 100644 --- a/src/lib/po/it_IT.po +++ b/src/lib/po/it_IT.po @@ -248,10 +248,10 @@ msgstr "Filtro A sblocco orizzontale" #: src/lib/job.cc:92 src/lib/job.cc:101 msgid "" "It is not known what caused this error. The best idea is to report the " -"problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" +"problem to the DCP-o-matic mailing list (dcpomatic@carlh.net)" msgstr "" "Non sappiamo cosa ha causato questo errore. La cosa migliore è inviare un " -"report del problema alla mailing list di DVD-o-matic (dvdomatic@carlh.net)" +"report del problema alla mailing list di DCP-o-matic (dcpomatic@carlh.net)" #: src/lib/filter.cc:82 msgid "Kernel deinterlacer" diff --git a/src/lib/po/sv_SE.po b/src/lib/po/sv_SE.po index d574261c8..c8695ce4d 100644 --- a/src/lib/po/sv_SE.po +++ b/src/lib/po/sv_SE.po @@ -5,7 +5,7 @@ # msgid "" msgstr "" -"Project-Id-Version: DVD-o-matic\n" +"Project-Id-Version: DCP-o-matic\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-04-09 11:14+0100\n" "PO-Revision-Date: 2013-04-09 10:13+0100\n" @@ -249,10 +249,10 @@ msgstr "Filter för horisontal kantighetsutjämning A" #: src/lib/job.cc:92 src/lib/job.cc:101 msgid "" "It is not known what caused this error. The best idea is to report the " -"problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" +"problem to the DCP-o-matic mailing list (dcpomatic@carlh.net)" msgstr "" "Det är inte känt vad som orsakade detta fel. Bästa sättet att rapportera " -"problemet är till DVD-o-matics mejl-lista (dvdomatic@carlh.net)" +"problemet är till DCP-o-matics mejl-lista (dcpomatic@carlh.net)" #: src/lib/filter.cc:82 msgid "Kernel deinterlacer" diff --git a/src/lib/processor.h b/src/lib/processor.h index 1ba396f2f..5dbafab7f 100644 --- a/src/lib/processor.h +++ b/src/lib/processor.h @@ -21,8 +21,8 @@ * @brief Parent class for classes which accept and then emit video or audio data. */ -#ifndef DVDOMATIC_PROCESSOR_H -#define DVDOMATIC_PROCESSOR_H +#ifndef DCPOMATIC_PROCESSOR_H +#define DCPOMATIC_PROCESSOR_H #include "video_source.h" #include "video_sink.h" diff --git a/src/lib/scaler.h b/src/lib/scaler.h index c80f4b7db..a736e92de 100644 --- a/src/lib/scaler.h +++ b/src/lib/scaler.h @@ -21,8 +21,8 @@ * @brief A class to describe one of FFmpeg's software scalers. */ -#ifndef DVDOMATIC_SCALER_H -#define DVDOMATIC_SCALER_H +#ifndef DCPOMATIC_SCALER_H +#define DCPOMATIC_SCALER_H #include #include diff --git a/src/lib/sound_processor.h b/src/lib/sound_processor.h index 2edf38840..bdbe72ba2 100644 --- a/src/lib/sound_processor.h +++ b/src/lib/sound_processor.h @@ -21,8 +21,8 @@ * @brief A class to describe a sound processor. */ -#ifndef DVDOMATIC_SOUND_PROCESSOR_H -#define DVDOMATIC_SOUND_PROCESSOR_H +#ifndef DCPOMATIC_SOUND_PROCESSOR_H +#define DCPOMATIC_SOUND_PROCESSOR_H #include #include diff --git a/src/lib/timer.h b/src/lib/timer.h index f509a7492..173d0d961 100644 --- a/src/lib/timer.h +++ b/src/lib/timer.h @@ -22,8 +22,8 @@ * @brief Some timing classes for debugging and profiling. */ -#ifndef DVDOMATIC_TIMER_H -#define DVDOMATIC_TIMER_H +#ifndef DCPOMATIC_TIMER_H +#define DCPOMATIC_TIMER_H #include #include diff --git a/src/lib/types.h b/src/lib/types.h index f821a74ac..c2bb9d853 100644 --- a/src/lib/types.h +++ b/src/lib/types.h @@ -17,8 +17,8 @@ */ -#ifndef DVDOMATIC_TYPES_H -#define DVDOMATIC_TYPES_H +#ifndef DCPOMATIC_TYPES_H +#define DCPOMATIC_TYPES_H #include #include diff --git a/src/lib/ui_signaller.h b/src/lib/ui_signaller.h index 221bcbe95..428ab698f 100644 --- a/src/lib/ui_signaller.h +++ b/src/lib/ui_signaller.h @@ -17,8 +17,8 @@ */ -#ifndef DVDOMATIC_UI_SIGNALLER_H -#define DVDOMATIC_UI_SIGNALLER_H +#ifndef DCPOMATIC_UI_SIGNALLER_H +#define DCPOMATIC_UI_SIGNALLER_H #include #include diff --git a/src/lib/util.cc b/src/lib/util.cc index 06da94294..ad08c6ab4 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -27,7 +27,7 @@ #include #include #include -#ifdef DVDOMATIC_POSIX +#ifdef DCPOMATIC_POSIX #include #include #endif @@ -148,7 +148,7 @@ seconds_to_approximate_hms (int s) return ap.str (); } -#ifdef DVDOMATIC_POSIX +#ifdef DCPOMATIC_POSIX /** @param l Mangled C++ identifier. * @return Demangled version. */ @@ -247,11 +247,11 @@ seconds (struct timeval t) return t.tv_sec + (double (t.tv_usec) / 1e6); } -/** Call the required functions to set up DVD-o-matic's static arrays, etc. +/** Call the required functions to set up DCP-o-matic's static arrays, etc. * Must be called from the UI thread, if there is one. */ void -dvdomatic_setup () +dcpomatic_setup () { avfilter_register_all (); @@ -264,7 +264,7 @@ dvdomatic_setup () ui_thread = boost::this_thread::get_id (); } -#ifdef DVDOMATIC_WINDOWS +#ifdef DCPOMATIC_WINDOWS boost::filesystem::path mo_path () { @@ -279,9 +279,9 @@ mo_path () #endif void -dvdomatic_setup_i18n (string lang) +dcpomatic_setup_i18n (string lang) { -#ifdef DVDOMATIC_POSIX +#ifdef DCPOMATIC_POSIX lang += ".UTF8"; #endif @@ -297,15 +297,15 @@ dvdomatic_setup_i18n (string lang) } setlocale (LC_ALL, ""); - textdomain ("libdvdomatic"); + textdomain ("libdcpomatic"); -#ifdef DVDOMATIC_WINDOWS - bindtextdomain ("libdvdomatic", mo_path().string().c_str()); - bind_textdomain_codeset ("libdvdomatic", "UTF8"); +#ifdef DCPOMATIC_WINDOWS + bindtextdomain ("libdcpomatic", mo_path().string().c_str()); + bind_textdomain_codeset ("libdcpomatic", "UTF8"); #endif -#ifdef DVDOMATIC_POSIX - bindtextdomain ("libdvdomatic", POSIX_LOCALE_PREFIX); +#ifdef DCPOMATIC_POSIX + bindtextdomain ("libdcpomatic", POSIX_LOCALE_PREFIX); #endif } @@ -909,7 +909,7 @@ cpu_info () pair info; info.second = 0; -#ifdef DVDOMATIC_POSIX +#ifdef DCPOMATIC_POSIX ifstream f (N_("/proc/cpuinfo")); while (f.good ()) { string l; diff --git a/src/lib/util.h b/src/lib/util.h index f4af7c22b..065801a88 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -22,8 +22,8 @@ * @brief Some utility functions and classes. */ -#ifndef DVDOMATIC_UTIL_H -#define DVDOMATIC_UTIL_H +#ifndef DCPOMATIC_UTIL_H +#define DCPOMATIC_UTIL_H #include #include @@ -39,7 +39,7 @@ extern "C" { #include "compose.hpp" #include "types.h" -#ifdef DVDOMATIC_DEBUG +#ifdef DCPOMATIC_DEBUG #define TIMING(...) _film->log()->microsecond_log (String::compose (__VA_ARGS__), Log::TIMING); #else #define TIMING(...) @@ -55,14 +55,14 @@ extern std::string seconds_to_approximate_hms (int); extern void stacktrace (std::ostream &, int); extern std::string dependency_version_summary (); extern double seconds (struct timeval); -extern void dvdomatic_setup (); -extern void dvdomatic_setup_i18n (std::string); +extern void dcpomatic_setup (); +extern void dcpomatic_setup_i18n (std::string); extern std::vector split_at_spaces_considering_quotes (std::string); extern std::string md5_digest (boost::filesystem::path); extern std::string md5_digest (void const *, int); extern void ensure_ui_thread (); extern std::string audio_channel_name (int); -#ifdef DVDOMATIC_WINDOWS +#ifdef DCPOMATIC_WINDOWS extern boost::filesystem::path mo_path (); #endif @@ -117,7 +117,7 @@ extern std::string get_optional_string (std::multimap /** @class Socket * @brief A class to wrap a boost::asio::ip::tcp::socket with some things - * that are useful for DVD-o-matic. + * that are useful for DCP-o-matic. * * This class wraps some things that I could not work out how to do with boost; * most notably, sync read/write calls with timeouts. diff --git a/src/lib/version.h b/src/lib/version.h index 71639e3bc..518862fc4 100644 --- a/src/lib/version.h +++ b/src/lib/version.h @@ -1,3 +1,3 @@ -extern char const * dvdomatic_version; -extern char const * dvdomatic_git_commit; +extern char const * dcpomatic_version; +extern char const * dcpomatic_git_commit; diff --git a/src/lib/video_content.h b/src/lib/video_content.h index 3d2c4cab2..75e507d4d 100644 --- a/src/lib/video_content.h +++ b/src/lib/video_content.h @@ -17,8 +17,8 @@ */ -#ifndef DVDOMATIC_VIDEO_CONTENT_H -#define DVDOMATIC_VIDEO_CONTENT_H +#ifndef DCPOMATIC_VIDEO_CONTENT_H +#define DCPOMATIC_VIDEO_CONTENT_H #include "content.h" #include "util.h" diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h index 05cf99a96..23817c055 100644 --- a/src/lib/video_decoder.h +++ b/src/lib/video_decoder.h @@ -17,8 +17,8 @@ */ -#ifndef DVDOMATIC_VIDEO_DECODER_H -#define DVDOMATIC_VIDEO_DECODER_H +#ifndef DCPOMATIC_VIDEO_DECODER_H +#define DCPOMATIC_VIDEO_DECODER_H #include "video_source.h" #include "decoder.h" diff --git a/src/lib/video_sink.h b/src/lib/video_sink.h index 7c128cf73..c68651005 100644 --- a/src/lib/video_sink.h +++ b/src/lib/video_sink.h @@ -17,8 +17,8 @@ */ -#ifndef DVDOMATIC_VIDEO_SINK_H -#define DVDOMATIC_VIDEO_SINK_H +#ifndef DCPOMATIC_VIDEO_SINK_H +#define DCPOMATIC_VIDEO_SINK_H #include #include "util.h" diff --git a/src/lib/video_source.h b/src/lib/video_source.h index e60e7dfd0..e7c9805ef 100644 --- a/src/lib/video_source.h +++ b/src/lib/video_source.h @@ -21,8 +21,8 @@ * @brief Parent class for classes which emit video data. */ -#ifndef DVDOMATIC_VIDEO_SOURCE_H -#define DVDOMATIC_VIDEO_SOURCE_H +#ifndef DCPOMATIC_VIDEO_SOURCE_H +#define DCPOMATIC_VIDEO_SOURCE_H #include #include diff --git a/src/lib/wscript b/src/lib/wscript index 2a26c2bfe..fddebe8e6 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -66,7 +66,7 @@ def build(bld): else: obj = bld(features = 'cxx cxxshlib') - obj.name = 'libdvdomatic' + obj.name = 'libdcpomatic' obj.export_includes = ['.'] obj.uselib = """ AVCODEC AVUTIL AVFORMAT AVFILTER SWSCALE SWRESAMPLE @@ -78,12 +78,12 @@ def build(bld): if bld.env.STATIC: obj.uselib += ' XML++' obj.source = sources + " version.cc" - obj.target = 'dvdomatic' + obj.target = 'dcpomatic' - i18n.po_to_mo(os.path.join('src', 'lib'), 'libdvdomatic', bld) + i18n.po_to_mo(os.path.join('src', 'lib'), 'libdcpomatic', bld) def pot(bld): - i18n.pot(os.path.join('src', 'lib'), sources, 'libdvdomatic') + i18n.pot(os.path.join('src', 'lib'), sources, 'libdcpomatic') def pot_merge(bld): - i18n.pot_merge(os.path.join('src', 'lib'), 'libdvdomatic') + i18n.pot_merge(os.path.join('src', 'lib'), 'libdcpomatic') diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc deleted file mode 100644 index 768819abc..000000000 --- a/src/tools/dvdomatic.cc +++ /dev/null @@ -1,578 +0,0 @@ -/* - Copyright (C) 2012 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include -#include -#ifdef __WXMSW__ -#include -#endif -#include -#include -#include -#include "wx/film_viewer.h" -#include "wx/film_editor.h" -#include "wx/job_manager_view.h" -#include "wx/config_dialog.h" -#include "wx/job_wrapper.h" -#include "wx/wx_util.h" -#include "wx/new_film_dialog.h" -#include "wx/properties_dialog.h" -#include "wx/wx_ui_signaller.h" -#include "lib/film.h" -#include "lib/format.h" -#include "lib/config.h" -#include "lib/filter.h" -#include "lib/util.h" -#include "lib/scaler.h" -#include "lib/exceptions.h" -#include "lib/version.h" -#include "lib/ui_signaller.h" -#include "lib/log.h" - -using std::cout; -using std::string; -using std::wstring; -using std::stringstream; -using std::map; -using std::make_pair; -using std::exception; -using boost::shared_ptr; - -static FilmEditor* film_editor = 0; -static FilmViewer* film_viewer = 0; -static shared_ptr film; -static std::string log_level; -static std::string film_to_load; -static std::string film_to_create; -static wxMenu* jobs_menu = 0; -static wxLocale* locale = 0; - -static void set_menu_sensitivity (); - -class FilmChangedDialog -{ -public: - FilmChangedDialog () - { - _dialog = new wxMessageDialog ( - 0, - wxString::Format (_("Save changes to film \"%s\" before closing?"), std_to_wx (film->name ()).data()), - _("Film changed"), - wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION - ); - } - - ~FilmChangedDialog () - { - _dialog->Destroy (); - } - - int run () - { - return _dialog->ShowModal (); - } - -private: - wxMessageDialog* _dialog; -}; - - -void -maybe_save_then_delete_film () -{ - if (!film) { - return; - } - - if (film->dirty ()) { - FilmChangedDialog d; - switch (d.run ()) { - case wxID_NO: - break; - case wxID_YES: - film->write_metadata (); - break; - } - } - - film.reset (); -} - -enum Sensitivity { - ALWAYS, - NEEDS_FILM -}; - -map menu_items; - -void -add_item (wxMenu* menu, wxString text, int id, Sensitivity sens) -{ - wxMenuItem* item = menu->Append (id, text); - menu_items.insert (make_pair (item, sens)); -} - -void -set_menu_sensitivity () -{ - for (map::iterator i = menu_items.begin(); i != menu_items.end(); ++i) { - if (i->second == NEEDS_FILM) { - i->first->Enable (film != 0); - } else { - i->first->Enable (true); - } - } -} - -enum { - ID_file_new = 1, - ID_file_open, - ID_file_save, - ID_file_properties, - ID_file_quit, - ID_edit_preferences, - ID_jobs_make_dcp, - ID_jobs_send_dcp_to_tms, - ID_jobs_show_dcp, - ID_jobs_analyse_audio, - ID_help_about -}; - -void -setup_menu (wxMenuBar* m) -{ - wxMenu* file = new wxMenu; - add_item (file, _("New..."), ID_file_new, ALWAYS); - add_item (file, _("&Open..."), ID_file_open, ALWAYS); - file->AppendSeparator (); - add_item (file, _("&Save"), ID_file_save, NEEDS_FILM); - file->AppendSeparator (); - add_item (file, _("&Properties..."), ID_file_properties, NEEDS_FILM); - file->AppendSeparator (); - add_item (file, _("&Quit"), ID_file_quit, ALWAYS); - - wxMenu* edit = new wxMenu; - add_item (edit, _("&Preferences..."), ID_edit_preferences, ALWAYS); - - jobs_menu = new wxMenu; - add_item (jobs_menu, _("&Make DCP"), ID_jobs_make_dcp, NEEDS_FILM); - add_item (jobs_menu, _("&Send DCP to TMS"), ID_jobs_send_dcp_to_tms, NEEDS_FILM); - add_item (jobs_menu, _("S&how DCP"), ID_jobs_show_dcp, NEEDS_FILM); - jobs_menu->AppendSeparator (); - add_item (jobs_menu, _("&Analyse audio"), ID_jobs_analyse_audio, NEEDS_FILM); - - wxMenu* help = new wxMenu; - add_item (help, _("About"), ID_help_about, ALWAYS); - - m->Append (file, _("&File")); - m->Append (edit, _("&Edit")); - m->Append (jobs_menu, _("&Jobs")); - m->Append (help, _("&Help")); -} - -bool -window_closed (wxCommandEvent &) -{ - maybe_save_then_delete_film (); - return false; -} - -class Frame : public wxFrame -{ -public: - Frame (wxString const & title) - : wxFrame (NULL, -1, title) - { - wxMenuBar* bar = new wxMenuBar; - setup_menu (bar); - SetMenuBar (bar); - - Connect (ID_file_new, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::file_new)); - Connect (ID_file_open, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::file_open)); - Connect (ID_file_save, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::file_save)); - Connect (ID_file_properties, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::file_properties)); - Connect (ID_file_quit, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::file_quit)); - Connect (ID_edit_preferences, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::edit_preferences)); - Connect (ID_jobs_make_dcp, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::jobs_make_dcp)); - Connect (ID_jobs_send_dcp_to_tms, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::jobs_send_dcp_to_tms)); - Connect (ID_jobs_show_dcp, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::jobs_show_dcp)); - Connect (ID_jobs_analyse_audio, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::jobs_analyse_audio)); - Connect (ID_help_about, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::help_about)); - - Connect (wxID_ANY, wxEVT_MENU_OPEN, wxMenuEventHandler (Frame::menu_opened)); - - wxPanel* panel = new wxPanel (this); - wxSizer* s = new wxBoxSizer (wxHORIZONTAL); - s->Add (panel, 1, wxEXPAND); - SetSizer (s); - - film_editor = new FilmEditor (film, panel); - film_viewer = new FilmViewer (film, panel); - JobManagerView* job_manager_view = new JobManagerView (panel); - - _top_sizer = new wxBoxSizer (wxHORIZONTAL); - _top_sizer->Add (film_editor, 0, wxALL, 6); - _top_sizer->Add (film_viewer, 1, wxEXPAND | wxALL, 6); - - wxBoxSizer* main_sizer = new wxBoxSizer (wxVERTICAL); - main_sizer->Add (_top_sizer, 2, wxEXPAND | wxALL, 6); - main_sizer->Add (job_manager_view, 1, wxEXPAND | wxALL, 6); - panel->SetSizer (main_sizer); - - set_menu_sensitivity (); - - film_editor->FileChanged.connect (bind (&Frame::file_changed, this, _1)); - if (film) { - file_changed (film->directory ()); - } else { - file_changed (""); - } - - set_film (); - - film_editor->Connect (wxID_ANY, wxEVT_SIZE, wxSizeEventHandler (Frame::film_editor_sized), 0, this); - } - -private: - - void film_editor_sized (wxSizeEvent &) - { - static bool in_layout = false; - if (!in_layout) { - in_layout = true; - _top_sizer->Layout (); - in_layout = false; - } - } - - void menu_opened (wxMenuEvent& ev) - { - if (ev.GetMenu() != jobs_menu) { - return; - } - - bool const have_dcp = film && film->have_dcp(); - jobs_menu->Enable (ID_jobs_send_dcp_to_tms, have_dcp); - jobs_menu->Enable (ID_jobs_show_dcp, have_dcp); - } - - void set_film () - { - film_viewer->set_film (film); - film_editor->set_film (film); - set_menu_sensitivity (); - } - - void file_changed (string f) - { - stringstream s; - s << wx_to_std (_("DVD-o-matic")); - if (!f.empty ()) { - s << " - " << f; - } - - SetTitle (std_to_wx (s.str())); - } - - void file_new (wxCommandEvent &) - { - NewFilmDialog* d = new NewFilmDialog (this); - int const r = d->ShowModal (); - - if (r == wxID_OK) { - - if (boost::filesystem::exists (d->get_path())) { - error_dialog (this, std_to_wx (String::compose (wx_to_std (_("The directory %1 already exists.")), d->get_path().c_str()))); - return; - } - - maybe_save_then_delete_film (); - film.reset (new Film (d->get_path (), false)); - film->log()->set_level (log_level); - film->set_name (boost::filesystem::path (d->get_path()).filename().generic_string()); - set_film (); - } - - d->Destroy (); - } - - void file_open (wxCommandEvent &) - { - wxDirDialog* c = new wxDirDialog (this, _("Select film to open"), wxStandardPaths::Get().GetDocumentsDir(), wxDEFAULT_DIALOG_STYLE | wxDD_DIR_MUST_EXIST); - int r; - while (1) { - r = c->ShowModal (); - if (r == wxID_OK && c->GetPath() == wxStandardPaths::Get().GetDocumentsDir()) { - error_dialog (this, _("You did not select a folder. Make sure that you select a folder before clicking Open.")); - } else { - break; - } - } - - if (r == wxID_OK) { - maybe_save_then_delete_film (); - try { - film.reset (new Film (wx_to_std (c->GetPath ()))); - film->log()->set_level (log_level); - set_film (); - } catch (std::exception& e) { - wxString p = c->GetPath (); - wxCharBuffer b = p.ToUTF8 (); - error_dialog (this, wxString::Format (_("Could not open film at %s (%s)"), p.data(), std_to_wx (e.what()).data())); - } - } - - c->Destroy (); - } - - void file_save (wxCommandEvent &) - { - film->write_metadata (); - } - - void file_properties (wxCommandEvent &) - { - PropertiesDialog* d = new PropertiesDialog (this, film); - d->ShowModal (); - d->Destroy (); - } - - void file_quit (wxCommandEvent &) - { - maybe_save_then_delete_film (); - Close (true); - } - - void edit_preferences (wxCommandEvent &) - { - ConfigDialog* d = new ConfigDialog (this); - d->ShowModal (); - d->Destroy (); - Config::instance()->write (); - } - - void jobs_make_dcp (wxCommandEvent &) - { - JobWrapper::make_dcp (this, film); - } - - void jobs_send_dcp_to_tms (wxCommandEvent &) - { - film->send_dcp_to_tms (); - } - - void jobs_show_dcp (wxCommandEvent &) - { -#ifdef __WXMSW__ - string d = film->directory(); - wstring w; - w.assign (d.begin(), d.end()); - ShellExecute (0, L"open", w.c_str(), 0, 0, SW_SHOWDEFAULT); -#else - int r = system ("which nautilus"); - if (WEXITSTATUS (r) == 0) { - system (string ("nautilus " + film->directory()).c_str ()); - } else { - int r = system ("which konqueror"); - if (WEXITSTATUS (r) == 0) { - system (string ("konqueror " + film->directory()).c_str ()); - } - } -#endif - } - - void jobs_analyse_audio (wxCommandEvent &) - { - film->analyse_audio (); - } - - void help_about (wxCommandEvent &) - { - wxAboutDialogInfo info; - info.SetName (_("DVD-o-matic")); - if (strcmp (dvdomatic_git_commit, "release") == 0) { - info.SetVersion (std_to_wx (String::compose ("version %1", dvdomatic_version))); - } else { - info.SetVersion (std_to_wx (String::compose ("version %1 git %2", dvdomatic_version, dvdomatic_git_commit))); - } - info.SetDescription (_("Free, open-source DCP generation from almost anything.")); - info.SetCopyright (_("(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen")); - - wxArrayString authors; - authors.Add (wxT ("Carl Hetherington")); - authors.Add (wxT ("Terrence Meiczinger")); - authors.Add (wxT ("Paul Davis")); - authors.Add (wxT ("Ole Laursen")); - info.SetDevelopers (authors); - - wxArrayString translators; - translators.Add (wxT ("Olivier Perriere")); - translators.Add (wxT ("Lilian Lefranc")); - translators.Add (wxT ("Thierry Journet")); - translators.Add (wxT ("Massimiliano Broggi")); - translators.Add (wxT ("Manuel AC")); - translators.Add (wxT ("Adam Klotblixt")); - info.SetTranslators (translators); - - info.SetWebSite (wxT ("http://carlh.net/software/dvdomatic")); - wxAboutBox (info); - } - - wxSizer* _top_sizer; -}; - -#if wxMINOR_VERSION == 9 -static const wxCmdLineEntryDesc command_line_description[] = { - { wxCMD_LINE_OPTION, "l", "log", "set log level (silent, verbose or timing)", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL }, - { wxCMD_LINE_SWITCH, "n", "new", "create new film", wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL }, - { wxCMD_LINE_PARAM, 0, 0, "film to load or create", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE | wxCMD_LINE_PARAM_OPTIONAL }, - { wxCMD_LINE_NONE, "", "", "", wxCmdLineParamType (0), 0 } -}; -#else -static const wxCmdLineEntryDesc command_line_description[] = { - { wxCMD_LINE_OPTION, wxT("l"), wxT("log"), wxT("set log level (silent, verbose or timing)"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL }, - { wxCMD_LINE_SWITCH, wxT("n"), wxT("new"), wxT("create new film"), wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL }, - { wxCMD_LINE_PARAM, 0, 0, wxT("film to load or create"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE | wxCMD_LINE_PARAM_OPTIONAL }, - { wxCMD_LINE_NONE, wxT(""), wxT(""), wxT(""), wxCmdLineParamType (0), 0 } -}; -#endif - -void -setup_i18n () -{ - int language = wxLANGUAGE_DEFAULT; - - if (Config::instance()->language()) { - wxLanguageInfo const * li = wxLocale::FindLanguageInfo (std_to_wx (Config::instance()->language().get())); - if (li) { - language = li->Language; - } - } - - if (wxLocale::IsAvailable (language)) { - locale = new wxLocale (language, wxLOCALE_LOAD_DEFAULT); - -#ifdef DVDOMATIC_WINDOWS - locale->AddCatalogLookupPathPrefix (std_to_wx (mo_path().string())); -#endif - - locale->AddCatalog (wxT ("libdvdomatic-wx")); - locale->AddCatalog (wxT ("dvdomatic")); - - if (!locale->IsOk()) { - delete locale; - locale = new wxLocale (wxLANGUAGE_ENGLISH); - language = wxLANGUAGE_ENGLISH; - } - } - - if (locale) { - dvdomatic_setup_i18n (wx_to_std (locale->GetCanonicalName ())); - } -} - -class App : public wxApp -{ - bool OnInit () - { - if (!wxApp::OnInit()) { - return false; - } - -#ifdef DVDOMATIC_POSIX - unsetenv ("UBUNTU_MENUPROXY"); -#endif - - wxInitAllImageHandlers (); - - /* Enable i18n; this will create a Config object - to look for a force-configured language. This Config - object will be wrong, however, because dvdomatic_setup - hasn't yet been called and there aren't any scalers, filters etc. - set up yet. - */ - setup_i18n (); - - /* Set things up, including scalers / filters etc. - which will now be internationalised correctly. - */ - dvdomatic_setup (); - - /* Force the configuration to be re-loaded correctly next - time it is needed. - */ - Config::drop (); - - if (!film_to_load.empty() && boost::filesystem::is_directory (film_to_load)) { - try { - film.reset (new Film (film_to_load)); - film->log()->set_level (log_level); - } catch (exception& e) { - error_dialog (0, std_to_wx (String::compose (wx_to_std (_("Could not load film %1 (%2)")), film_to_load, e.what()))); - } - } - - if (!film_to_create.empty ()) { - film.reset (new Film (film_to_create, false)); - film->log()->set_level (log_level); - film->set_name (boost::filesystem::path (film_to_create).filename().generic_string ()); - } - - Frame* f = new Frame (_("DVD-o-matic")); - SetTopWindow (f); - f->Maximize (); - f->Show (); - - ui_signaller = new wxUISignaller (this); - this->Connect (-1, wxEVT_IDLE, wxIdleEventHandler (App::idle)); - - return true; - } - - void OnInitCmdLine (wxCmdLineParser& parser) - { - parser.SetDesc (command_line_description); - parser.SetSwitchChars (wxT ("-")); - } - - bool OnCmdLineParsed (wxCmdLineParser& parser) - { - if (parser.GetParamCount() > 0) { - if (parser.Found (wxT ("new"))) { - film_to_create = wx_to_std (parser.GetParam (0)); - } else { - film_to_load = wx_to_std (parser.GetParam(0)); - } - } - - wxString log; - if (parser.Found (wxT ("log"), &log)) { - log_level = wx_to_std (log); - } - - return true; - } - - void idle (wxIdleEvent &) - { - ui_signaller->ui_idle (); - } -}; - -IMPLEMENT_APP (App) diff --git a/src/tools/makedcp.cc b/src/tools/makedcp.cc index 85134b3c5..e2e1874c4 100644 --- a/src/tools/makedcp.cc +++ b/src/tools/makedcp.cc @@ -47,9 +47,9 @@ static void help (string n) { cerr << "Syntax: " << n << " [OPTION] \n" - << " -v, --version show DVD-o-matic version\n" + << " -v, --version show DCP-o-matic version\n" << " -h, --help show this help\n" - << " -d, --deps list DVD-o-matic dependency details and quit\n" + << " -d, --deps list DCP-o-matic dependency details and quit\n" << " -t, --test run in test mode (repeatable UUID generation, timestamps etc.)\n" << " -n, --no-progress do not print progress to stdout\n" << " -r, --no-remote do not use any remote servers\n" @@ -87,7 +87,7 @@ main (int argc, char* argv[]) switch (c) { case 'v': - cout << "dvdomatic version " << dvdomatic_version << " " << dvdomatic_git_commit << "\n"; + cout << "dcpomatic version " << dcpomatic_version << " " << dcpomatic_git_commit << "\n"; exit (EXIT_SUCCESS); case 'h': help (argv[0]); @@ -117,13 +117,13 @@ main (int argc, char* argv[]) film_dir = argv[optind]; - dvdomatic_setup (); + dcpomatic_setup (); if (no_remote) { Config::instance()->set_servers (vector ()); } - cout << "DVD-o-matic " << dvdomatic_version << " git " << dvdomatic_git_commit; + cout << "DCP-o-matic " << dcpomatic_version << " git " << dcpomatic_git_commit; char buf[256]; if (gethostname (buf, 256) == 0) { cout << " on " << buf; @@ -162,7 +162,7 @@ main (int argc, char* argv[]) bool error = false; while (!should_stop) { - dvdomatic_sleep (5); + dcpomatic_sleep (5); list > jobs = JobManager::instance()->get (); diff --git a/src/tools/po/es_ES.po b/src/tools/po/es_ES.po index abfbfef6d..d35f104c6 100644 --- a/src/tools/po/es_ES.po +++ b/src/tools/po/es_ES.po @@ -5,7 +5,7 @@ # msgid "" msgstr "" -"Project-Id-Version: DVDOMATIC\n" +"Project-Id-Version: DCPOMATIC\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-04-09 11:14+0100\n" "PO-Revision-Date: 2013-03-23 21:08-0500\n" @@ -17,111 +17,111 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" -#: src/tools/dvdomatic.cc:177 +#: src/tools/dcpomatic.cc:177 msgid "&Analyse audio" msgstr "&Analizar audio" -#: src/tools/dvdomatic.cc:183 +#: src/tools/dcpomatic.cc:183 msgid "&Edit" msgstr "&Editar" -#: src/tools/dvdomatic.cc:182 +#: src/tools/dcpomatic.cc:182 msgid "&File" msgstr "&Archivo" -#: src/tools/dvdomatic.cc:185 +#: src/tools/dcpomatic.cc:185 msgid "&Help" msgstr "&Ayuda" -#: src/tools/dvdomatic.cc:184 +#: src/tools/dcpomatic.cc:184 msgid "&Jobs" msgstr "&Tareas" -#: src/tools/dvdomatic.cc:173 +#: src/tools/dcpomatic.cc:173 msgid "&Make DCP" msgstr "&Crear DCP" -#: src/tools/dvdomatic.cc:161 +#: src/tools/dcpomatic.cc:161 msgid "&Open..." msgstr "&Abrir..." -#: src/tools/dvdomatic.cc:170 +#: src/tools/dcpomatic.cc:170 msgid "&Preferences..." msgstr "&Preferencias..." -#: src/tools/dvdomatic.cc:165 +#: src/tools/dcpomatic.cc:165 msgid "&Properties..." msgstr "&Propiedades..." -#: src/tools/dvdomatic.cc:167 +#: src/tools/dcpomatic.cc:167 msgid "&Quit" msgstr "&Salir" -#: src/tools/dvdomatic.cc:163 +#: src/tools/dcpomatic.cc:163 msgid "&Save" msgstr "&Guardar" -#: src/tools/dvdomatic.cc:174 +#: src/tools/dcpomatic.cc:174 msgid "&Send DCP to TMS" msgstr "&Enviar DCP al TMS" -#: src/tools/dvdomatic.cc:417 +#: src/tools/dcpomatic.cc:417 msgid "" "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" msgstr "" "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" -#: src/tools/dvdomatic.cc:180 +#: src/tools/dcpomatic.cc:180 msgid "About" msgstr "Acerca de" -#: src/tools/dvdomatic.cc:527 +#: src/tools/dcpomatic.cc:527 #, fuzzy msgid "Could not load film %1 (%2)" msgstr "No se pudo cargar la película %s (%s)" -#: src/tools/dvdomatic.cc:339 +#: src/tools/dcpomatic.cc:339 #, c-format msgid "Could not open film at %s (%s)" msgstr "No se pudo cargar la película en %s (%s)" -#: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:410 -#: src/tools/dvdomatic.cc:531 -msgid "DVD-o-matic" -msgstr "DVD-o-matic" +#: src/tools/dcpomatic.cc:287 src/tools/dcpomatic.cc:410 +#: src/tools/dcpomatic.cc:531 +msgid "DCP-o-matic" +msgstr "DCP-o-matic" -#: src/tools/dvdomatic.cc:75 +#: src/tools/dcpomatic.cc:75 msgid "Film changed" msgstr "Película cambiada" -#: src/tools/dvdomatic.cc:416 +#: src/tools/dcpomatic.cc:416 msgid "Free, open-source DCP generation from almost anything." msgstr "" "Generación de DCP a partir de casi cualquier fuente, libre y de código " "abierto." -#: src/tools/dvdomatic.cc:160 +#: src/tools/dcpomatic.cc:160 msgid "New..." msgstr "Nuevo..." -#: src/tools/dvdomatic.cc:175 +#: src/tools/dcpomatic.cc:175 msgid "S&how DCP" msgstr "&Mostrar DCP" -#: src/tools/dvdomatic.cc:74 +#: src/tools/dcpomatic.cc:74 msgid "Save changes to film \"%s\" before closing?" msgstr "" -#: src/tools/dvdomatic.cc:319 +#: src/tools/dcpomatic.cc:319 msgid "Select film to open" msgstr "Selecciona la película a abrir" -#: src/tools/dvdomatic.cc:303 +#: src/tools/dcpomatic.cc:303 #, fuzzy msgid "The directory %1 already exists." msgstr "La carpeta %s ya existe." -#: src/tools/dvdomatic.cc:324 +#: src/tools/dcpomatic.cc:324 msgid "" "You did not select a folder. Make sure that you select a folder before " "clicking Open." diff --git a/src/tools/po/fr_FR.po b/src/tools/po/fr_FR.po index b40c86877..ef2246992 100644 --- a/src/tools/po/fr_FR.po +++ b/src/tools/po/fr_FR.po @@ -5,7 +5,7 @@ # msgid "" msgstr "" -"Project-Id-Version: DVD-o-matic FRENCH\n" +"Project-Id-Version: DCP-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-04-09 11:14+0100\n" "PO-Revision-Date: 2013-03-13 22:33+0100\n" @@ -16,109 +16,109 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: src/tools/dvdomatic.cc:177 +#: src/tools/dcpomatic.cc:177 msgid "&Analyse audio" msgstr "&Analyser le son" -#: src/tools/dvdomatic.cc:183 +#: src/tools/dcpomatic.cc:183 msgid "&Edit" msgstr "&Edition" -#: src/tools/dvdomatic.cc:182 +#: src/tools/dcpomatic.cc:182 msgid "&File" msgstr "&Fichier" -#: src/tools/dvdomatic.cc:185 +#: src/tools/dcpomatic.cc:185 msgid "&Help" msgstr "&Aide" -#: src/tools/dvdomatic.cc:184 +#: src/tools/dcpomatic.cc:184 msgid "&Jobs" msgstr "&Travaux" -#: src/tools/dvdomatic.cc:173 +#: src/tools/dcpomatic.cc:173 msgid "&Make DCP" msgstr "&Créer le DCP" -#: src/tools/dvdomatic.cc:161 +#: src/tools/dcpomatic.cc:161 msgid "&Open..." msgstr "&Ouvrir..." -#: src/tools/dvdomatic.cc:170 +#: src/tools/dcpomatic.cc:170 msgid "&Preferences..." msgstr "&Préférences..." -#: src/tools/dvdomatic.cc:165 +#: src/tools/dcpomatic.cc:165 msgid "&Properties..." msgstr "&Propriétés..." -#: src/tools/dvdomatic.cc:167 +#: src/tools/dcpomatic.cc:167 msgid "&Quit" msgstr "&Quitter" -#: src/tools/dvdomatic.cc:163 +#: src/tools/dcpomatic.cc:163 msgid "&Save" msgstr "&Enregistrer" -#: src/tools/dvdomatic.cc:174 +#: src/tools/dcpomatic.cc:174 msgid "&Send DCP to TMS" msgstr "&Envoyer le DCP dans le TMS" -#: src/tools/dvdomatic.cc:417 +#: src/tools/dcpomatic.cc:417 msgid "" "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" msgstr "" "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" -#: src/tools/dvdomatic.cc:180 +#: src/tools/dcpomatic.cc:180 msgid "About" msgstr "A Propos" -#: src/tools/dvdomatic.cc:527 +#: src/tools/dcpomatic.cc:527 #, fuzzy msgid "Could not load film %1 (%2)" msgstr "Impossible de charger le film %s (%s)" -#: src/tools/dvdomatic.cc:339 +#: src/tools/dcpomatic.cc:339 #, c-format msgid "Could not open film at %s (%s)" msgstr "Impossible d'ouvrir le film à %s (%s)" -#: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:410 -#: src/tools/dvdomatic.cc:531 -msgid "DVD-o-matic" -msgstr "DVD-o-matic" +#: src/tools/dcpomatic.cc:287 src/tools/dcpomatic.cc:410 +#: src/tools/dcpomatic.cc:531 +msgid "DCP-o-matic" +msgstr "DCP-o-matic" -#: src/tools/dvdomatic.cc:75 +#: src/tools/dcpomatic.cc:75 msgid "Film changed" msgstr "Film changé" -#: src/tools/dvdomatic.cc:416 +#: src/tools/dcpomatic.cc:416 msgid "Free, open-source DCP generation from almost anything." msgstr "Création de DCP libre et open-source à partir de presque tout." -#: src/tools/dvdomatic.cc:160 +#: src/tools/dcpomatic.cc:160 msgid "New..." msgstr "Nouveau..." -#: src/tools/dvdomatic.cc:175 +#: src/tools/dcpomatic.cc:175 msgid "S&how DCP" msgstr "Voir le DCP" -#: src/tools/dvdomatic.cc:74 +#: src/tools/dcpomatic.cc:74 msgid "Save changes to film \"%s\" before closing?" msgstr "" -#: src/tools/dvdomatic.cc:319 +#: src/tools/dcpomatic.cc:319 msgid "Select film to open" msgstr "Sélectionner le film à ouvrir" -#: src/tools/dvdomatic.cc:303 +#: src/tools/dcpomatic.cc:303 #, fuzzy msgid "The directory %1 already exists." msgstr "Le dossier %s existe déjà." -#: src/tools/dvdomatic.cc:324 +#: src/tools/dcpomatic.cc:324 msgid "" "You did not select a folder. Make sure that you select a folder before " "clicking Open." diff --git a/src/tools/po/it_IT.po b/src/tools/po/it_IT.po index 38cbec157..998f70059 100644 --- a/src/tools/po/it_IT.po +++ b/src/tools/po/it_IT.po @@ -17,107 +17,107 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" -#: src/tools/dvdomatic.cc:177 +#: src/tools/dcpomatic.cc:177 msgid "&Analyse audio" msgstr "&Analizza audio" -#: src/tools/dvdomatic.cc:183 +#: src/tools/dcpomatic.cc:183 msgid "&Edit" msgstr "&Modifica" -#: src/tools/dvdomatic.cc:182 +#: src/tools/dcpomatic.cc:182 msgid "&File" msgstr "&File" -#: src/tools/dvdomatic.cc:185 +#: src/tools/dcpomatic.cc:185 msgid "&Help" msgstr "&Aiuto" -#: src/tools/dvdomatic.cc:184 +#: src/tools/dcpomatic.cc:184 msgid "&Jobs" msgstr "&Lavori" -#: src/tools/dvdomatic.cc:173 +#: src/tools/dcpomatic.cc:173 msgid "&Make DCP" msgstr "&Crea DCP" -#: src/tools/dvdomatic.cc:161 +#: src/tools/dcpomatic.cc:161 msgid "&Open..." msgstr "&Apri..." -#: src/tools/dvdomatic.cc:170 +#: src/tools/dcpomatic.cc:170 msgid "&Preferences..." msgstr "&Preferenze..." -#: src/tools/dvdomatic.cc:165 +#: src/tools/dcpomatic.cc:165 msgid "&Properties..." msgstr "&Proprieta'..." -#: src/tools/dvdomatic.cc:167 +#: src/tools/dcpomatic.cc:167 msgid "&Quit" msgstr "&Esci" -#: src/tools/dvdomatic.cc:163 +#: src/tools/dcpomatic.cc:163 msgid "&Save" msgstr "&Salva" -#: src/tools/dvdomatic.cc:174 +#: src/tools/dcpomatic.cc:174 msgid "&Send DCP to TMS" msgstr "&Invia DCP a TMS" -#: src/tools/dvdomatic.cc:417 +#: src/tools/dcpomatic.cc:417 msgid "" "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" msgstr "" "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" -#: src/tools/dvdomatic.cc:180 +#: src/tools/dcpomatic.cc:180 msgid "About" msgstr "Informazioni" -#: src/tools/dvdomatic.cc:527 +#: src/tools/dcpomatic.cc:527 msgid "Could not load film %1 (%2)" msgstr "Non posso caricare il film %s (%s)" -#: src/tools/dvdomatic.cc:339 +#: src/tools/dcpomatic.cc:339 #, c-format msgid "Could not open film at %s (%s)" msgstr "Non posso aprire il film in %s (%s)" -#: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:410 -#: src/tools/dvdomatic.cc:531 -msgid "DVD-o-matic" -msgstr "DVD-o-matic" +#: src/tools/dcpomatic.cc:287 src/tools/dcpomatic.cc:410 +#: src/tools/dcpomatic.cc:531 +msgid "DCP-o-matic" +msgstr "DCP-o-matic" -#: src/tools/dvdomatic.cc:75 +#: src/tools/dcpomatic.cc:75 msgid "Film changed" msgstr "Film modificato" -#: src/tools/dvdomatic.cc:416 +#: src/tools/dcpomatic.cc:416 msgid "Free, open-source DCP generation from almost anything." msgstr "Genera DCP da quasi tutto, free e open-source." -#: src/tools/dvdomatic.cc:160 +#: src/tools/dcpomatic.cc:160 msgid "New..." msgstr "Nuovo" -#: src/tools/dvdomatic.cc:175 +#: src/tools/dcpomatic.cc:175 msgid "S&how DCP" msgstr "&Mostra DCP" -#: src/tools/dvdomatic.cc:74 +#: src/tools/dcpomatic.cc:74 msgid "Save changes to film \"%s\" before closing?" msgstr "Salvare i cambiamenti del film \"%s\" prima di chiudere?" -#: src/tools/dvdomatic.cc:319 +#: src/tools/dcpomatic.cc:319 msgid "Select film to open" msgstr "Seleziona il film da aprire" -#: src/tools/dvdomatic.cc:303 +#: src/tools/dcpomatic.cc:303 msgid "The directory %1 already exists." msgstr "La directory %s esiste gia'." -#: src/tools/dvdomatic.cc:324 +#: src/tools/dcpomatic.cc:324 msgid "" "You did not select a folder. Make sure that you select a folder before " "clicking Open." diff --git a/src/tools/po/sv_SE.po b/src/tools/po/sv_SE.po index 57254770c..4765c2d98 100644 --- a/src/tools/po/sv_SE.po +++ b/src/tools/po/sv_SE.po @@ -5,7 +5,7 @@ # msgid "" msgstr "" -"Project-Id-Version: DVD-o-matic\n" +"Project-Id-Version: DCP-o-matic\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-04-09 11:14+0100\n" "PO-Revision-Date: 2013-04-09 10:12+0100\n" @@ -17,108 +17,108 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" -#: src/tools/dvdomatic.cc:177 +#: src/tools/dcpomatic.cc:177 msgid "&Analyse audio" msgstr "&Analysera audio" -#: src/tools/dvdomatic.cc:183 +#: src/tools/dcpomatic.cc:183 msgid "&Edit" msgstr "&Redigera" -#: src/tools/dvdomatic.cc:182 +#: src/tools/dcpomatic.cc:182 msgid "&File" msgstr "&Fil" -#: src/tools/dvdomatic.cc:185 +#: src/tools/dcpomatic.cc:185 msgid "&Help" msgstr "&Hjälp" -#: src/tools/dvdomatic.cc:184 +#: src/tools/dcpomatic.cc:184 msgid "&Jobs" msgstr "&Jobb" -#: src/tools/dvdomatic.cc:173 +#: src/tools/dcpomatic.cc:173 msgid "&Make DCP" msgstr "&Skapa DCP" -#: src/tools/dvdomatic.cc:161 +#: src/tools/dcpomatic.cc:161 msgid "&Open..." msgstr "&Öppna" -#: src/tools/dvdomatic.cc:170 +#: src/tools/dcpomatic.cc:170 msgid "&Preferences..." msgstr "&Inställningar" -#: src/tools/dvdomatic.cc:165 +#: src/tools/dcpomatic.cc:165 msgid "&Properties..." msgstr "&Egenskaper" -#: src/tools/dvdomatic.cc:167 +#: src/tools/dcpomatic.cc:167 msgid "&Quit" msgstr "&Avsluta" -#: src/tools/dvdomatic.cc:163 +#: src/tools/dcpomatic.cc:163 msgid "&Save" msgstr "&Spara" -#: src/tools/dvdomatic.cc:174 +#: src/tools/dcpomatic.cc:174 msgid "&Send DCP to TMS" msgstr "&Skicka DCP till TMS" -#: src/tools/dvdomatic.cc:417 +#: src/tools/dcpomatic.cc:417 msgid "" "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" msgstr "" "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" -#: src/tools/dvdomatic.cc:180 +#: src/tools/dcpomatic.cc:180 msgid "About" msgstr "Om" -#: src/tools/dvdomatic.cc:527 +#: src/tools/dcpomatic.cc:527 msgid "Could not load film %1 (%2)" msgstr "Kunde inte öppna filmen %1 (%2)" -#: src/tools/dvdomatic.cc:339 +#: src/tools/dcpomatic.cc:339 #, c-format msgid "Could not open film at %s (%s)" msgstr "Kunde inte öppna filmen vid %s (%s)" -#: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:410 -#: src/tools/dvdomatic.cc:531 -msgid "DVD-o-matic" -msgstr "DVD-o-matic" +#: src/tools/dcpomatic.cc:287 src/tools/dcpomatic.cc:410 +#: src/tools/dcpomatic.cc:531 +msgid "DCP-o-matic" +msgstr "DCP-o-matic" -#: src/tools/dvdomatic.cc:75 +#: src/tools/dcpomatic.cc:75 msgid "Film changed" msgstr "Film ändrad" -#: src/tools/dvdomatic.cc:416 +#: src/tools/dcpomatic.cc:416 msgid "Free, open-source DCP generation from almost anything." msgstr "" "Fri, öppen-källkodsprogramvara för DCP-generering från nästan vad som helst." -#: src/tools/dvdomatic.cc:160 +#: src/tools/dcpomatic.cc:160 msgid "New..." msgstr "Ny..." -#: src/tools/dvdomatic.cc:175 +#: src/tools/dcpomatic.cc:175 msgid "S&how DCP" msgstr "&Visa DCP" -#: src/tools/dvdomatic.cc:74 +#: src/tools/dcpomatic.cc:74 msgid "Save changes to film \"%s\" before closing?" msgstr "Spara ändringarna till filmen \"%s\" före avslut?" -#: src/tools/dvdomatic.cc:319 +#: src/tools/dcpomatic.cc:319 msgid "Select film to open" msgstr "Välj film att öppna" -#: src/tools/dvdomatic.cc:303 +#: src/tools/dcpomatic.cc:303 msgid "The directory %1 already exists." msgstr "Katalogen %1 finns redan." -#: src/tools/dvdomatic.cc:324 +#: src/tools/dcpomatic.cc:324 msgid "" "You did not select a folder. Make sure that you select a folder before " "clicking Open." diff --git a/src/tools/servomatic_cli.cc b/src/tools/servomatic_cli.cc index 6626d45b9..76d085034 100644 --- a/src/tools/servomatic_cli.cc +++ b/src/tools/servomatic_cli.cc @@ -51,7 +51,7 @@ static void help (string n) { cerr << "Syntax: " << n << " [OPTION]\n" - << " -v, --version show DVD-o-matic version\n" + << " -v, --version show DCP-o-matic version\n" << " -h, --help show this help\n" << " -t, --threads number of parallel encoding threads to use\n"; } @@ -78,7 +78,7 @@ main (int argc, char* argv[]) switch (c) { case 'v': - cout << "dvdomatic version " << dvdomatic_version << " " << dvdomatic_git_commit << "\n"; + cout << "dcpomatic version " << dcpomatic_version << " " << dcpomatic_git_commit << "\n"; exit (EXIT_SUCCESS); case 'h': help (argv[0]); diff --git a/src/tools/servomatic_gui.cc b/src/tools/servomatic_gui.cc index 5e36660eb..152e063c1 100644 --- a/src/tools/servomatic_gui.cc +++ b/src/tools/servomatic_gui.cc @@ -61,7 +61,7 @@ class StatusDialog : public wxDialog { public: StatusDialog () - : wxDialog (0, wxID_ANY, _("DVD-o-matic encode server"), wxDefaultPosition, wxSize (600, 80), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) + : wxDialog (0, wxID_ANY, _("DCP-o-matic encode server"), wxDefaultPosition, wxSize (600, 80), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) , _timer (this, ID_timer) { _sizer = new wxFlexGridSizer (1, 6, 6); @@ -103,7 +103,7 @@ public: wxIcon icon; icon.CopyFromBitmap (bitmap); #endif - SetIcon (icon, std_to_wx ("DVD-o-matic encode server")); + SetIcon (icon, std_to_wx ("DCP-o-matic encode server")); Connect (ID_status, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (TaskBarIcon::status)); Connect (ID_quit, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (TaskBarIcon::quit)); @@ -147,7 +147,7 @@ private: return false; } - dvdomatic_setup (); + dcpomatic_setup (); _icon = new TaskBarIcon; _thread = new thread (bind (&App::main_thread, this)); diff --git a/src/tools/servomatictest.cc b/src/tools/servomatictest.cc index d3222faa3..42cc76871 100644 --- a/src/tools/servomatictest.cc +++ b/src/tools/servomatictest.cc @@ -145,7 +145,7 @@ main (int argc, char* argv[]) exit (EXIT_FAILURE); } - dvdomatic_setup (); + dcpomatic_setup (); server = new ServerDescription (server_host, 1); shared_ptr film (new Film (film_dir, true)); diff --git a/src/tools/wscript b/src/tools/wscript index 9cc7e9d1b..f0ffb8e89 100644 --- a/src/tools/wscript +++ b/src/tools/wscript @@ -8,25 +8,25 @@ def build(bld): obj = bld(features = 'cxx cxxprogram') obj.uselib = 'BOOST_THREAD OPENJPEG DCP CXML AVFORMAT AVFILTER AVCODEC AVUTIL SWSCALE POSTPROC' obj.includes = ['..'] - obj.use = ['libdvdomatic'] + obj.use = ['libdcpomatic'] obj.source = '%s.cc' % t obj.target = t if not bld.env.DISABLE_GUI: - for t in ['dvdomatic', 'servomatic_gui']: + for t in ['dcpomatic', 'servomatic_gui']: obj = bld(features = 'cxx cxxprogram') obj.uselib = 'DCP CXML OPENJPEG AVFORMAT AVFILTER AVCODEC AVUTIL SWSCALE POSTPROC' obj.includes = ['..'] - obj.use = ['libdvdomatic', 'libdvdomatic-wx'] + obj.use = ['libdcpomatic', 'libdcpomatic-wx'] obj.source = '%s.cc' % t if bld.env.TARGET_WINDOWS: - obj.source += ' ../../windows/dvdomatic.rc' + obj.source += ' ../../windows/dcpomatic.rc' obj.target = t - i18n.po_to_mo(os.path.join('src', 'tools'), 'dvdomatic', bld) + i18n.po_to_mo(os.path.join('src', 'tools'), 'dcpomatic', bld) def pot(bld): - i18n.pot(os.path.join('src', 'tools'), 'dvdomatic.cc', 'dvdomatic') + i18n.pot(os.path.join('src', 'tools'), 'dcpomatic.cc', 'dcpomatic') def pot_merge(bld): - i18n.pot_merge(os.path.join('src', 'tools'), 'dvdomatic') + i18n.pot_merge(os.path.join('src', 'tools'), 'dcpomatic') diff --git a/src/wx/audio_dialog.cc b/src/wx/audio_dialog.cc index bed7aac6d..15d746839 100644 --- a/src/wx/audio_dialog.cc +++ b/src/wx/audio_dialog.cc @@ -100,7 +100,7 @@ AudioDialog::set_film (shared_ptr f) _film_changed_connection = _film->Changed.connect (bind (&AudioDialog::film_changed, this, _1)); _film_audio_analysis_succeeded_connection = _film->AudioAnalysisSucceeded.connect (bind (&AudioDialog::try_to_load_analysis, this)); - SetTitle (wxString::Format (_("DVD-o-matic audio - %s"), std_to_wx(_film->name()).data())); + SetTitle (wxString::Format (_("DCP-o-matic audio - %s"), std_to_wx(_film->name()).data())); } diff --git a/src/wx/config_dialog.cc b/src/wx/config_dialog.cc index 1d025f3fa..4ae8f1eb4 100644 --- a/src/wx/config_dialog.cc +++ b/src/wx/config_dialog.cc @@ -18,7 +18,7 @@ */ /** @file src/config_dialog.cc - * @brief A dialogue to edit DVD-o-matic configuration. + * @brief A dialogue to edit DCP-o-matic configuration. */ #include @@ -41,7 +41,7 @@ using namespace std; using boost::bind; ConfigDialog::ConfigDialog (wxWindow* parent) - : wxDialog (parent, wxID_ANY, _("DVD-o-matic Preferences"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) + : wxDialog (parent, wxID_ANY, _("DCP-o-matic Preferences"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) { wxFlexGridSizer* table = new wxFlexGridSizer (3, 6, 6); table->AddGrowableCol (1, 1); @@ -58,7 +58,7 @@ ConfigDialog::ConfigDialog (wxWindow* parent) table->AddSpacer (0); table->AddSpacer (0); - wxStaticText* restart = add_label_to_sizer (table, this, _("(restart DVD-o-matic to see language changes)")); + wxStaticText* restart = add_label_to_sizer (table, this, _("(restart DCP-o-matic to see language changes)")); wxFont font = restart->GetFont(); font.SetStyle (wxFONTSTYLE_ITALIC); font.SetPointSize (font.GetPointSize() - 1); diff --git a/src/wx/config_dialog.h b/src/wx/config_dialog.h index f6f3b3707..a2fc1f4b1 100644 --- a/src/wx/config_dialog.h +++ b/src/wx/config_dialog.h @@ -18,7 +18,7 @@ */ /** @file src/config_dialog.h - * @brief A dialogue to edit DVD-o-matic configuration. + * @brief A dialogue to edit DCP-o-matic configuration. */ #include @@ -31,7 +31,7 @@ class DirPickerCtrl; class ServerDescription; /** @class ConfigDialog - * @brief A dialogue to edit DVD-o-matic configuration. + * @brief A dialogue to edit DCP-o-matic configuration. */ class ConfigDialog : public wxDialog { diff --git a/src/wx/po/es_ES.po b/src/wx/po/es_ES.po index 207708589..abb6b780f 100644 --- a/src/wx/po/es_ES.po +++ b/src/wx/po/es_ES.po @@ -5,7 +5,7 @@ # msgid "" msgstr "" -"Project-Id-Version: libdvdomatic-wx\n" +"Project-Id-Version: libdcpomatic-wx\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-04-09 11:14+0100\n" "PO-Revision-Date: 2013-04-02 19:08-0500\n" @@ -22,7 +22,7 @@ msgid "%" msgstr "%" #: src/wx/config_dialog.cc:61 -msgid "(restart DVD-o-matic to see language changes)" +msgid "(restart DCP-o-matic to see language changes)" msgstr "" #: src/wx/film_editor.cc:1269 @@ -141,17 +141,17 @@ msgid "DCP Name" msgstr "Nombre DCP" #: src/wx/wx_util.cc:61 -msgid "DVD-o-matic" -msgstr "DVD-o-matic" +msgid "DCP-o-matic" +msgstr "DCP-o-matic" #: src/wx/config_dialog.cc:44 -msgid "DVD-o-matic Preferences" -msgstr "Preferencias DVD-o-matic" +msgid "DCP-o-matic Preferences" +msgstr "Preferencias DCP-o-matic" #: src/wx/audio_dialog.cc:101 #, fuzzy, c-format -msgid "DVD-o-matic audio - %s" -msgstr "Audio DVD-o-matic - %1" +msgid "DCP-o-matic audio - %s" +msgstr "Audio DCP-o-matic - %1" #: src/wx/config_dialog.cc:102 msgid "Default DCI name details" diff --git a/src/wx/po/fr_FR.po b/src/wx/po/fr_FR.po index 80ee5dbfd..2aac7114c 100644 --- a/src/wx/po/fr_FR.po +++ b/src/wx/po/fr_FR.po @@ -5,7 +5,7 @@ # msgid "" msgstr "" -"Project-Id-Version: DVD-o-matic FRENCH\n" +"Project-Id-Version: DCP-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-04-09 11:14+0100\n" "PO-Revision-Date: 2013-03-20 00:34+0100\n" @@ -21,7 +21,7 @@ msgid "%" msgstr "%" #: src/wx/config_dialog.cc:61 -msgid "(restart DVD-o-matic to see language changes)" +msgid "(restart DCP-o-matic to see language changes)" msgstr "" #: src/wx/film_editor.cc:1269 @@ -140,17 +140,17 @@ msgid "DCP Name" msgstr "Nom du DCP" #: src/wx/wx_util.cc:61 -msgid "DVD-o-matic" -msgstr "DVD-o-matic" +msgid "DCP-o-matic" +msgstr "DCP-o-matic" #: src/wx/config_dialog.cc:44 -msgid "DVD-o-matic Preferences" -msgstr "Préférences DVD-o-matic" +msgid "DCP-o-matic Preferences" +msgstr "Préférences DCP-o-matic" #: src/wx/audio_dialog.cc:101 #, c-format -msgid "DVD-o-matic audio - %s" -msgstr "Son DVD-o-matic - %s" +msgid "DCP-o-matic audio - %s" +msgstr "Son DCP-o-matic - %s" #: src/wx/config_dialog.cc:102 msgid "Default DCI name details" diff --git a/src/wx/po/it_IT.po b/src/wx/po/it_IT.po index 78fd0dee9..7b06495e8 100644 --- a/src/wx/po/it_IT.po +++ b/src/wx/po/it_IT.po @@ -22,8 +22,8 @@ msgid "%" msgstr "%" #: src/wx/config_dialog.cc:61 -msgid "(restart DVD-o-matic to see language changes)" -msgstr "(riavviare DVD-o-matic per vedere i cambiamenti di lingua)" +msgid "(restart DCP-o-matic to see language changes)" +msgstr "(riavviare DCP-o-matic per vedere i cambiamenti di lingua)" #: src/wx/film_editor.cc:1269 msgid "1 channel" @@ -141,17 +141,17 @@ msgid "DCP Name" msgstr "Nome del DCP" #: src/wx/wx_util.cc:61 -msgid "DVD-o-matic" -msgstr "DVD-o-matic" +msgid "DCP-o-matic" +msgstr "DCP-o-matic" #: src/wx/config_dialog.cc:44 -msgid "DVD-o-matic Preferences" -msgstr "Preferenze DVD-o-matic" +msgid "DCP-o-matic Preferences" +msgstr "Preferenze DCP-o-matic" #: src/wx/audio_dialog.cc:101 #, c-format -msgid "DVD-o-matic audio - %s" -msgstr "Audio DVD-o-matic - %s" +msgid "DCP-o-matic audio - %s" +msgstr "Audio DCP-o-matic - %s" #: src/wx/config_dialog.cc:102 msgid "Default DCI name details" diff --git a/src/wx/po/sv_SE.po b/src/wx/po/sv_SE.po index e52589ff0..96fafadeb 100644 --- a/src/wx/po/sv_SE.po +++ b/src/wx/po/sv_SE.po @@ -5,7 +5,7 @@ # msgid "" msgstr "" -"Project-Id-Version: DVD-o-matic\n" +"Project-Id-Version: DCP-o-matic\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-04-09 11:14+0100\n" "PO-Revision-Date: 2013-04-09 10:13+0100\n" @@ -22,8 +22,8 @@ msgid "%" msgstr "%" #: src/wx/config_dialog.cc:61 -msgid "(restart DVD-o-matic to see language changes)" -msgstr "(starta om DVD-o-matic för att se språkändringar)" +msgid "(restart DCP-o-matic to see language changes)" +msgstr "(starta om DCP-o-matic för att se språkändringar)" #: src/wx/film_editor.cc:1269 msgid "1 channel" @@ -141,17 +141,17 @@ msgid "DCP Name" msgstr "DCP Namn" #: src/wx/wx_util.cc:61 -msgid "DVD-o-matic" -msgstr "DVD-o-matic" +msgid "DCP-o-matic" +msgstr "DCP-o-matic" #: src/wx/config_dialog.cc:44 -msgid "DVD-o-matic Preferences" -msgstr "DVD-o-matic Inställningar" +msgid "DCP-o-matic Preferences" +msgstr "DCP-o-matic Inställningar" #: src/wx/audio_dialog.cc:101 #, c-format -msgid "DVD-o-matic audio - %s" -msgstr "DVD-o-matic audio - %s" +msgid "DCP-o-matic audio - %s" +msgstr "DCP-o-matic audio - %s" #: src/wx/config_dialog.cc:102 msgid "Default DCI name details" diff --git a/src/wx/wscript b/src/wx/wscript index 7f9cde9ac..09bf40393 100644 --- a/src/wx/wscript +++ b/src/wx/wscript @@ -34,18 +34,18 @@ def build(bld): else: obj = bld(features = 'cxx cxxshlib') - obj.name = 'libdvdomatic-wx' + obj.name = 'libdcpomatic-wx' obj.includes = [ '..' ] obj.export_includes = ['.'] obj.uselib = 'WXWIDGETS' - obj.use = 'libdvdomatic' + obj.use = 'libdcpomatic' obj.source = sources - obj.target = 'dvdomatic-wx' + obj.target = 'dcpomatic-wx' - i18n.po_to_mo(os.path.join('src', 'wx'), 'libdvdomatic-wx', bld) + i18n.po_to_mo(os.path.join('src', 'wx'), 'libdcpomatic-wx', bld) def pot(bld): - i18n.pot(os.path.join('src', 'wx'), sources, 'libdvdomatic-wx') + i18n.pot(os.path.join('src', 'wx'), sources, 'libdcpomatic-wx') def pot_merge(bld): - i18n.pot_merge(os.path.join('src', 'wx'), 'libdvdomatic-wx') + i18n.pot_merge(os.path.join('src', 'wx'), 'libdcpomatic-wx') diff --git a/src/wx/wx_util.cc b/src/wx/wx_util.cc index 720a058cb..3dad6e7fd 100644 --- a/src/wx/wx_util.cc +++ b/src/wx/wx_util.cc @@ -58,7 +58,7 @@ add_label_to_grid_bag_sizer (wxGridBagSizer* s, wxWindow* p, wxString t, wxGBPos void error_dialog (wxWindow* parent, wxString m) { - wxMessageDialog* d = new wxMessageDialog (parent, m, _("DVD-o-matic"), wxOK); + wxMessageDialog* d = new wxMessageDialog (parent, m, _("DCP-o-matic"), wxOK); d->ShowModal (); d->Destroy (); } diff --git a/test/test.cc b/test/test.cc index 592bad836..39a921d36 100644 --- a/test/test.cc +++ b/test/test.cc @@ -42,7 +42,7 @@ #include "sndfile_decoder.h" #include "dcp_content_type.h" #define BOOST_TEST_DYN_LINK -#define BOOST_TEST_MODULE dvdomatic_test +#define BOOST_TEST_MODULE dcpomatic_test #include using std::string; @@ -90,7 +90,7 @@ new_test_film (string name) BOOST_AUTO_TEST_CASE (make_black_test) { /* This needs to happen in the first test */ - dvdomatic_setup (); + dcpomatic_setup (); libdcp::Size in_size (512, 512); libdcp::Size out_size (1024, 1024); @@ -392,7 +392,7 @@ BOOST_AUTO_TEST_CASE (client_server_test) new thread (boost::bind (&Server::run, server, 2)); /* Let the server get itself ready */ - dvdomatic_sleep (1); + dcpomatic_sleep (1); ServerDescription description ("localhost", 2); @@ -421,7 +421,7 @@ BOOST_AUTO_TEST_CASE (make_dcp_test) film->write_metadata (); while (JobManager::instance()->work_to_do ()) { - dvdomatic_sleep (1); + dcpomatic_sleep (1); } BOOST_CHECK_EQUAL (JobManager::instance()->errors(), false); @@ -452,7 +452,7 @@ BOOST_AUTO_TEST_CASE (make_dcp_with_range_test) film->make_dcp (); while (JobManager::instance()->work_to_do() && !JobManager::instance()->errors()) { - dvdomatic_sleep (1); + dcpomatic_sleep (1); } BOOST_CHECK_EQUAL (JobManager::instance()->errors(), false); @@ -689,10 +689,10 @@ BOOST_AUTO_TEST_CASE (job_manager_test) shared_ptr a (new TestJob (f)); JobManager::instance()->add (a); - dvdomatic_sleep (1); + dcpomatic_sleep (1); BOOST_CHECK_EQUAL (a->running (), true); a->set_finished_ok (); - dvdomatic_sleep (2); + dcpomatic_sleep (2); BOOST_CHECK_EQUAL (a->finished_ok(), true); } diff --git a/test/wscript b/test/wscript index 493270903..61c391663 100644 --- a/test/wscript +++ b/test/wscript @@ -9,7 +9,7 @@ def build(bld): obj = bld(features = 'cxx cxxprogram') obj.name = 'unit-tests' obj.uselib = 'BOOST_TEST CXML DCP OPENJPEG AVFORMAT AVFILTER AVCODEC AVUTIL SWSCALE POSTPROC' - obj.use = 'libdvdomatic' + obj.use = 'libdcpomatic' obj.source = 'test.cc' obj.target = 'unit-tests' obj.install_path = '' diff --git a/windows/dvdomatic.bmp b/windows/dvdomatic.bmp deleted file mode 100644 index 0a196f7a0..000000000 Binary files a/windows/dvdomatic.bmp and /dev/null differ diff --git a/windows/dvdomatic.ico b/windows/dvdomatic.ico deleted file mode 100644 index 225008cfe..000000000 Binary files a/windows/dvdomatic.ico and /dev/null differ diff --git a/windows/dvdomatic.rc b/windows/dvdomatic.rc deleted file mode 100644 index 17790cf0d..000000000 --- a/windows/dvdomatic.rc +++ /dev/null @@ -1,3 +0,0 @@ -id ICON "dvdomatic.ico" -taskbar_icon ICON "dvdomatic_taskbar.ico" -#include "wx-2.9/wx/msw/wx.rc" diff --git a/windows/dvdomatic_taskbar.ico b/windows/dvdomatic_taskbar.ico deleted file mode 100644 index f4489fa14..000000000 Binary files a/windows/dvdomatic_taskbar.ico and /dev/null differ diff --git a/windows/installer.nsi.32.in b/windows/installer.nsi.32.in index 553a94d2b..15a0a1886 100644 --- a/windows/installer.nsi.32.in +++ b/windows/installer.nsi.32.in @@ -1,14 +1,14 @@ !include "MUI2.nsh" -Name "DVD-o-matic" +Name "DCP-o-matic" RequestExecutionLevel admin -outFile "DVD-o-matic @version@ 32-bit Installer.exe" -!define MUI_ICON "%resources%/dvdomatic.ico" -!define MUI_UNICON "%resources%/dvdomatic.ico" -!define MUI_SPECIALBITMAP "%resources%/dvdomatic.bmp" +outFile "DCP-o-matic @version@ 32-bit Installer.exe" +!define MUI_ICON "%resources%/dcpomatic.ico" +!define MUI_UNICON "%resources%/dcpomatic.ico" +!define MUI_SPECIALBITMAP "%resources%/dcpomatic.bmp" -InstallDir "$PROGRAMFILES\DVD-o-matic" +InstallDir "$PROGRAMFILES\DCP-o-matic" !insertmacro MUI_PAGE_WELCOME !insertmacro MUI_PAGE_LICENSE "../../COPYING" @@ -81,9 +81,9 @@ File "%deps%/bin/libexpat-1.dll" File "%deps%/bin/libbz2.dll" File "%deps%/bin/cxml.dll" -File "%binaries%/src/wx/dvdomatic-wx.dll" -File "%binaries%/src/lib/dvdomatic.dll" -File "%binaries%/src/tools/dvdomatic.exe" +File "%binaries%/src/wx/dcpomatic-wx.dll" +File "%binaries%/src/lib/dcpomatic.dll" +File "%binaries%/src/tools/dcpomatic.exe" File "%binaries%/src/tools/servomatic_cli.exe" File "%binaries%/src/tools/servomatic_gui.exe" @@ -95,32 +95,32 @@ SetOutPath "$PROFILE\.magick" File "%deps%/etc/ImageMagick/delegates.xml" SetOutPath "$INSTDIR\locale\fr\LC_MESSAGES" -File "%binaries%/src/lib/mo/fr_FR/libdvdomatic.mo" -File "%binaries%/src/wx/mo/fr_FR/libdvdomatic-wx.mo" -File "%binaries%/src/tools/mo/fr_FR/dvdomatic.mo" +File "%binaries%/src/lib/mo/fr_FR/libdcpomatic.mo" +File "%binaries%/src/wx/mo/fr_FR/libdcpomatic-wx.mo" +File "%binaries%/src/tools/mo/fr_FR/dcpomatic.mo" SetOutPath "$INSTDIR\locale\it\LC_MESSAGES" -File "%binaries%/src/lib/mo/it_IT/libdvdomatic.mo" -File "%binaries%/src/wx/mo/it_IT/libdvdomatic-wx.mo" -File "%binaries%/src/tools/mo/it_IT/dvdomatic.mo" +File "%binaries%/src/lib/mo/it_IT/libdcpomatic.mo" +File "%binaries%/src/wx/mo/it_IT/libdcpomatic-wx.mo" +File "%binaries%/src/tools/mo/it_IT/dcpomatic.mo" SetOutPath "$INSTDIR\locale\es\LC_MESSAGES" -File "%binaries%/src/lib/mo/es_ES/libdvdomatic.mo" -File "%binaries%/src/wx/mo/es_ES/libdvdomatic-wx.mo" -File "%binaries%/src/tools/mo/es_ES/dvdomatic.mo" +File "%binaries%/src/lib/mo/es_ES/libdcpomatic.mo" +File "%binaries%/src/wx/mo/es_ES/libdcpomatic-wx.mo" +File "%binaries%/src/tools/mo/es_ES/dcpomatic.mo" SetOutPath "$INSTDIR\locale\sv\LC_MESSAGES" -File "%binaries%/src/lib/mo/sv_SE/libdvdomatic.mo" -File "%binaries%/src/wx/mo/sv_SE/libdvdomatic-wx.mo" -File "%binaries%/src/tools/mo/sv_SE/dvdomatic.mo" +File "%binaries%/src/lib/mo/sv_SE/libdcpomatic.mo" +File "%binaries%/src/wx/mo/sv_SE/libdcpomatic-wx.mo" +File "%binaries%/src/tools/mo/sv_SE/dcpomatic.mo" -CreateShortCut "$DESKTOP\DVD-o-matic.lnk" "$INSTDIR\bin\dvdomatic.exe" "" -CreateShortCut "$DESKTOP\DVD-o-matic encode server.lnk" "$INSTDIR\bin\servomatic_gui.exe" "" +CreateShortCut "$DESKTOP\DCP-o-matic.lnk" "$INSTDIR\bin\dcpomatic.exe" "" +CreateShortCut "$DESKTOP\DCP-o-matic encode server.lnk" "$INSTDIR\bin\servomatic_gui.exe" "" -CreateDirectory "$SMPROGRAMS\DVD-o-matic" -CreateShortCut "$SMPROGRAMS\DVD-o-matic\Uninstall DVD-o-matic.lnk" "$INSTDIR\Uninstall.exe" "" "$INSTDIR\Uninstall.exe" 0 -CreateShortCut "$SMPROGRAMS\DVD-o-matic\DVD-o-matic.lnk" "$INSTDIR\bin\dvdomatic.exe" "" "$INSTDIR\bin\dvdomatic.exe" 0 -CreateShortCut "$SMPROGRAMS\DVD-o-matic\DVD-o-matic encode server.lnk" "$INSTDIR\bin\servomatic_gui.exe" "" "$INSTDIR\bin\servomatic_gui.exe" 0 +CreateDirectory "$SMPROGRAMS\DCP-o-matic" +CreateShortCut "$SMPROGRAMS\DCP-o-matic\Uninstall DCP-o-matic.lnk" "$INSTDIR\Uninstall.exe" "" "$INSTDIR\Uninstall.exe" 0 +CreateShortCut "$SMPROGRAMS\DCP-o-matic\DCP-o-matic.lnk" "$INSTDIR\bin\dcpomatic.exe" "" "$INSTDIR\bin\dcpomatic.exe" 0 +CreateShortCut "$SMPROGRAMS\DCP-o-matic\DCP-o-matic encode server.lnk" "$INSTDIR\bin\servomatic_gui.exe" "" "$INSTDIR\bin\servomatic_gui.exe" 0 -WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\DVD-o-matic" "DisplayName" "DVD-o-matic (remove only)" -WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\DVD-o-matic" "UninstallString" "$INSTDIR\Uninstall.exe" +WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\DCP-o-matic" "DisplayName" "DCP-o-matic (remove only)" +WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\DCP-o-matic" "UninstallString" "$INSTDIR\Uninstall.exe" WriteUninstaller "$INSTDIR\Uninstall.exe" @@ -131,11 +131,11 @@ Section "Uninstall" RMDir /r "$INSTDIR\*.*" RMDir "$INSTDIR" -Delete "$DESKTOP\DVD-o-matic.lnk" -Delete "$DESKTOP\DVD-o-matic encode server.lnk" -Delete "$SMPROGRAMS\DVD-o-matic\*.*" -RmDir "$SMPROGRAMS\DVD-o-matic" -DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\DVD-o-matic" -DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\DVD-o-matic" +Delete "$DESKTOP\DCP-o-matic.lnk" +Delete "$DESKTOP\DCP-o-matic encode server.lnk" +Delete "$SMPROGRAMS\DCP-o-matic\*.*" +RmDir "$SMPROGRAMS\DCP-o-matic" +DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\DCP-o-matic" +DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\DCP-o-matic" SectionEnd diff --git a/windows/installer.nsi.64.in b/windows/installer.nsi.64.in index bb5456936..566907e39 100644 --- a/windows/installer.nsi.64.in +++ b/windows/installer.nsi.64.in @@ -1,16 +1,16 @@ !include "MUI2.nsh" !include "x64.nsh" -Name "DVD-o-matic" +Name "DCP-o-matic" RequestExecutionLevel admin -outFile "DVD-o-matic @version@ 64-bit Installer.exe" -!define MUI_ICON "%resources%/dvdomatic.ico" -!define MUI_UNICON "%resources%/dvdomatic.ico" -!define MUI_SPECIALBITMAP "%resources%/dvdomatic.bmp" +outFile "DCP-o-matic @version@ 64-bit Installer.exe" +!define MUI_ICON "%resources%/dcpomatic.ico" +!define MUI_UNICON "%resources%/dcpomatic.ico" +!define MUI_SPECIALBITMAP "%resources%/dcpomatic.bmp" -InstallDir "$PROGRAMFILES\DVD-o-matic" +InstallDir "$PROGRAMFILES\DCP-o-matic" !insertmacro MUI_PAGE_WELCOME !insertmacro MUI_PAGE_LICENSE "../../COPYING" @@ -32,7 +32,7 @@ ${If} ${RunningX64} ; disable registry redirection (enable access to 64-bit portion of registry) SetRegView 64 ; change install dir - StrCpy $INSTDIR "$PROGRAMFILES64\DVD-o-matic" + StrCpy $INSTDIR "$PROGRAMFILES64\DCP-o-matic" ${EndIf} SetOutPath "$INSTDIR\bin" @@ -91,9 +91,9 @@ File "%deps%/bin/libexpat-1.dll" File "%deps%/bin/libbz2.dll" File "%deps%/bin/cxml.dll" -File "%binaries%/src/wx/dvdomatic-wx.dll" -File "%binaries%/src/lib/dvdomatic.dll" -File "%binaries%/src/tools/dvdomatic.exe" +File "%binaries%/src/wx/dcpomatic-wx.dll" +File "%binaries%/src/lib/dcpomatic.dll" +File "%binaries%/src/tools/dcpomatic.exe" File "%binaries%/src/tools/servomatic_cli.exe" File "%binaries%/src/tools/servomatic_gui.exe" @@ -105,32 +105,32 @@ SetOutPath "$PROFILE\.magick" File "%deps%/etc/ImageMagick/delegates.xml" SetOutPath "$INSTDIR\locale\fr\LC_MESSAGES" -File "%binaries%/src/lib/mo/fr_FR/libdvdomatic.mo" -File "%binaries%/src/wx/mo/fr_FR/libdvdomatic-wx.mo" -File "%binaries%/src/tools/mo/fr_FR/dvdomatic.mo" +File "%binaries%/src/lib/mo/fr_FR/libdcpomatic.mo" +File "%binaries%/src/wx/mo/fr_FR/libdcpomatic-wx.mo" +File "%binaries%/src/tools/mo/fr_FR/dcpomatic.mo" SetOutPath "$INSTDIR\locale\it\LC_MESSAGES" -File "%binaries%/src/lib/mo/it_IT/libdvdomatic.mo" -File "%binaries%/src/wx/mo/it_IT/libdvdomatic-wx.mo" -File "%binaries%/src/tools/mo/it_IT/dvdomatic.mo" +File "%binaries%/src/lib/mo/it_IT/libdcpomatic.mo" +File "%binaries%/src/wx/mo/it_IT/libdcpomatic-wx.mo" +File "%binaries%/src/tools/mo/it_IT/dcpomatic.mo" SetOutPath "$INSTDIR\locale\es\LC_MESSAGES" -File "%binaries%/src/lib/mo/es_ES/libdvdomatic.mo" -File "%binaries%/src/wx/mo/es_ES/libdvdomatic-wx.mo" -File "%binaries%/src/tools/mo/es_ES/dvdomatic.mo" +File "%binaries%/src/lib/mo/es_ES/libdcpomatic.mo" +File "%binaries%/src/wx/mo/es_ES/libdcpomatic-wx.mo" +File "%binaries%/src/tools/mo/es_ES/dcpomatic.mo" SetOutPath "$INSTDIR\locale\sv\LC_MESSAGES" -File "%binaries%/src/lib/mo/sv_SE/libdvdomatic.mo" -File "%binaries%/src/wx/mo/sv_SE/libdvdomatic-wx.mo" -File "%binaries%/src/tools/mo/sv_SE/dvdomatic.mo" +File "%binaries%/src/lib/mo/sv_SE/libdcpomatic.mo" +File "%binaries%/src/wx/mo/sv_SE/libdcpomatic-wx.mo" +File "%binaries%/src/tools/mo/sv_SE/dcpomatic.mo" -CreateShortCut "$DESKTOP\DVD-o-matic.lnk" "$INSTDIR\bin\dvdomatic.exe" "" -CreateShortCut "$DESKTOP\DVD-o-matic encode server.lnk" "$INSTDIR\bin\servomatic_gui.exe" "" +CreateShortCut "$DESKTOP\DCP-o-matic.lnk" "$INSTDIR\bin\dcpomatic.exe" "" +CreateShortCut "$DESKTOP\DCP-o-matic encode server.lnk" "$INSTDIR\bin\servomatic_gui.exe" "" -CreateDirectory "$SMPROGRAMS\DVD-o-matic" -CreateShortCut "$SMPROGRAMS\DVD-o-matic\Uninstall DVD-o-matic.lnk" "$INSTDIR\Uninstall.exe" "" "$INSTDIR\Uninstall.exe" 0 -CreateShortCut "$SMPROGRAMS\DVD-o-matic\DVD-o-matic.lnk" "$INSTDIR\bin\dvdomatic.exe" "" "$INSTDIR\bin\dvdomatic.exe" 0 -CreateShortCut "$SMPROGRAMS\DVD-o-matic\DVD-o-matic encode server.lnk" "$INSTDIR\bin\servomatic_gui.exe" "" "$INSTDIR\bin\servomatic_gui.exe" 0 +CreateDirectory "$SMPROGRAMS\DCP-o-matic" +CreateShortCut "$SMPROGRAMS\DCP-o-matic\Uninstall DCP-o-matic.lnk" "$INSTDIR\Uninstall.exe" "" "$INSTDIR\Uninstall.exe" 0 +CreateShortCut "$SMPROGRAMS\DCP-o-matic\DCP-o-matic.lnk" "$INSTDIR\bin\dcpomatic.exe" "" "$INSTDIR\bin\dcpomatic.exe" 0 +CreateShortCut "$SMPROGRAMS\DCP-o-matic\DCP-o-matic encode server.lnk" "$INSTDIR\bin\servomatic_gui.exe" "" "$INSTDIR\bin\servomatic_gui.exe" 0 -WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\DVD-o-matic" "DisplayName" "DVD-o-matic (remove only)" -WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\DVD-o-matic" "UninstallString" "$INSTDIR\Uninstall.exe" +WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\DCP-o-matic" "DisplayName" "DCP-o-matic (remove only)" +WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\DCP-o-matic" "UninstallString" "$INSTDIR\Uninstall.exe" WriteUninstaller "$INSTDIR\Uninstall.exe" @@ -141,11 +141,11 @@ Section "Uninstall" RMDir /r "$INSTDIR\*.*" RMDir "$INSTDIR" -Delete "$DESKTOP\DVD-o-matic.lnk" -Delete "$DESKTOP\DVD-o-matic encode server.lnk" -Delete "$SMPROGRAMS\DVD-o-matic\*.*" -RmDir "$SMPROGRAMS\DVD-o-matic" -DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\DVD-o-matic" -DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\DVD-o-matic" +Delete "$DESKTOP\DCP-o-matic.lnk" +Delete "$DESKTOP\DCP-o-matic encode server.lnk" +Delete "$SMPROGRAMS\DCP-o-matic\*.*" +RmDir "$SMPROGRAMS\DCP-o-matic" +DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\DCP-o-matic" +DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\DCP-o-matic" SectionEnd diff --git a/wscript b/wscript index 502f27fd1..f784d760d 100644 --- a/wscript +++ b/wscript @@ -2,7 +2,7 @@ import subprocess import os import sys -APPNAME = 'dvdomatic' +APPNAME = 'dcpomatic' VERSION = '0.84pre' def options(opt): @@ -25,7 +25,7 @@ def configure(conf): '-Wall', '-Wno-attributes', '-Wextra']) if conf.options.target_windows: - conf.env.append_value('CXXFLAGS', ['-DDVDOMATIC_WINDOWS', '-DWIN32_LEAN_AND_MEAN', '-DBOOST_USE_WINDOWS_H', '-DUNICODE']) + conf.env.append_value('CXXFLAGS', ['-DDCPOMATIC_WINDOWS', '-DWIN32_LEAN_AND_MEAN', '-DBOOST_USE_WINDOWS_H', '-DUNICODE']) wxrc = os.popen('wx-config --rescomp').read().split()[1:] conf.env.append_value('WINRCFLAGS', wxrc) if conf.options.enable_debug: @@ -35,9 +35,9 @@ def configure(conf): boost_lib_suffix = '-mt' boost_thread = 'boost_thread_win32-mt' else: - conf.env.append_value('CXXFLAGS', '-DDVDOMATIC_POSIX') + conf.env.append_value('CXXFLAGS', '-DDCPOMATIC_POSIX') conf.env.append_value('CXXFLAGS', '-DPOSIX_LOCALE_PREFIX="%s/share/locale"' % conf.env['PREFIX']) - conf.env.append_value('CXXFLAGS', '-DPOSIX_ICON_PREFIX="%s/share/dvdomatic"' % conf.env['PREFIX']) + conf.env.append_value('CXXFLAGS', '-DPOSIX_ICON_PREFIX="%s/share/dcpomatic"' % conf.env['PREFIX']) boost_lib_suffix = '' boost_thread = 'boost_thread' conf.env.append_value('LINKFLAGS', '-pthread') @@ -50,7 +50,7 @@ def configure(conf): conf.env.VERSION = VERSION if conf.options.enable_debug: - conf.env.append_value('CXXFLAGS', ['-g', '-DDVDOMATIC_DEBUG']) + conf.env.append_value('CXXFLAGS', ['-g', '-DDCPOMATIC_DEBUG']) else: conf.env.append_value('CXXFLAGS', '-O2') @@ -228,16 +228,16 @@ def build(bld): d = { 'PREFIX' : '${PREFIX' } obj = bld(features = 'subst') - obj.source = 'dvdomatic.desktop.in' - obj.target = 'dvdomatic.desktop' + obj.source = 'dcpomatic.desktop.in' + obj.target = 'dcpomatic.desktop' obj.dict = d - bld.install_files('${PREFIX}/share/applications', 'dvdomatic.desktop') + bld.install_files('${PREFIX}/share/applications', 'dcpomatic.desktop') for r in ['22x22', '32x32', '48x48', '64x64', '128x128']: - bld.install_files('${PREFIX}/share/icons/hicolor/%s/apps' % r, 'icons/%s/dvdomatic.png' % r) + bld.install_files('${PREFIX}/share/icons/hicolor/%s/apps' % r, 'icons/%s/dcpomatic.png' % r) if not bld.env.TARGET_WINDOWS: - bld.install_files('${PREFIX}/share/dvdomatic', 'icons/taskbar_icon.png') + bld.install_files('${PREFIX}/share/dcpomatic', 'icons/taskbar_icon.png') bld.add_post_fun(post) @@ -259,8 +259,8 @@ def create_version_cc(version): try: text = '#include "version.h"\n' - text += 'char const * dvdomatic_git_commit = \"%s\";\n' % commit - text += 'char const * dvdomatic_version = \"%s\";\n' % version + text += 'char const * dcpomatic_git_commit = \"%s\";\n' % commit + text += 'char const * dcpomatic_version = \"%s\";\n' % version print('Writing version information to src/lib/version.cc') o = open('src/lib/version.cc', 'w') o.write(text) -- cgit v1.2.3 From 8e61be024ddc5a7a6bf03b0c1c71e2add97db965 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 13 Apr 2013 21:00:22 +0100 Subject: Some logging. --- src/tools/dvdomatic.cc | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src') diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 212d4848e..b09f4e554 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -458,14 +458,21 @@ setup_i18n () { int language = wxLANGUAGE_DEFAULT; + ofstream f ("c:/users/carl/foo", ios::app); + f << "Hello.\n"; + if (Config::instance()->language()) { + f << "Configured language " << Config::instance()->language().get() << "\n"; wxLanguageInfo const * li = wxLocale::FindLanguageInfo (std_to_wx (Config::instance()->language().get())); + f << "LanguageInfo " << li << "\n"; if (li) { language = li->Language; + f << "language=" << language << " cf " << wxLANGUAGE_DEFAULT << " " << wxLANGUAGE_ENGLISH << "\n"; } } if (wxLocale::IsAvailable (language)) { + f << "Language is available.\n"; locale = new wxLocale (language, wxLOCALE_LOAD_DEFAULT); #ifdef DVDOMATIC_WINDOWS @@ -476,6 +483,7 @@ setup_i18n () locale->AddCatalog (wxT ("dvdomatic")); if (!locale->IsOk()) { + f << "Locale is not ok.\n"; delete locale; locale = new wxLocale (wxLANGUAGE_ENGLISH); language = wxLANGUAGE_ENGLISH; -- cgit v1.2.3 From 784c560e3437136d6006f8df2fb35f41585b6a8d Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 13 Apr 2013 21:24:18 +0100 Subject: Use film-name-derived names for MXFs in DCPs. --- src/lib/film.cc | 32 ++++++++++++++++++++++++++++++-- src/lib/film.h | 8 ++++++-- src/lib/writer.cc | 18 +++++++++--------- test/test.cc | 2 +- 4 files changed, 46 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/lib/film.cc b/src/lib/film.cc index bd11c1eb5..077c9e17f 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -232,18 +232,46 @@ Film::info_dir () const } string -Film::video_mxf_dir () const +Film::internal_video_mxf_dir () const { boost::filesystem::path p; return dir ("video"); } string -Film::video_mxf_filename () const +Film::internal_video_mxf_filename () const { return video_state_identifier() + ".mxf"; } +string +Film::dcp_video_mxf_filename () const +{ + return filename_safe_name() + "_video.mxf"; +} + +string +Film::dcp_audio_mxf_filename () const +{ + return filename_safe_name() + "_audio.mxf"; +} + +string +Film::filename_safe_name () const +{ + string const n = name (); + string o; + for (size_t i = 0; i < n.length(); ++i) { + if (isalnum (n[i])) { + o += n[i]; + } else { + o += "_"; + } + } + + return o; +} + string Film::audio_analysis_path () const { diff --git a/src/lib/film.h b/src/lib/film.h index adc4b0eec..a5a8ac5fa 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -64,10 +64,13 @@ public: std::string info_dir () const; std::string j2c_path (int f, bool t) const; std::string info_path (int f) const; - std::string video_mxf_dir () const; - std::string video_mxf_filename () const; + std::string internal_video_mxf_dir () const; + std::string internal_video_mxf_filename () const; std::string audio_analysis_path () const; + std::string dcp_video_mxf_filename () const; + std::string dcp_audio_mxf_filename () const; + void examine_content (); void analyse_audio (); void send_dcp_to_tms (); @@ -387,6 +390,7 @@ private: void examine_content_finished (); void analyse_audio_finished (); std::string video_state_identifier () const; + std::string filename_safe_name () const; /** Complete path to directory containing the film metadata; * must not be relative. diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 2d7ee9ba3..c6ce4711d 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -65,8 +65,8 @@ Writer::Writer (shared_ptr f) _picture_asset.reset ( new libdcp::MonoPictureAsset ( - _film->video_mxf_dir (), - _film->video_mxf_filename (), + _film->internal_video_mxf_dir (), + _film->internal_video_mxf_filename (), _film->dcp_frame_rate (), _film->format()->dcp_size () ) @@ -80,7 +80,7 @@ Writer::Writer (shared_ptr f) _sound_asset.reset ( new libdcp::SoundAsset ( _film->dir (_film->dcp_name()), - N_("audio.mxf"), + _film->dcp_audio_mxf_filename (), _film->dcp_frame_rate (), m.dcp_channels (), dcp_audio_sample_rate (_film->audio_stream()->sample_rate()) @@ -267,12 +267,12 @@ Writer::finish () /* Hard-link the video MXF into the DCP */ boost::filesystem::path from; - from /= _film->video_mxf_dir(); - from /= _film->video_mxf_filename(); + from /= _film->internal_video_mxf_dir(); + from /= _film->internal_video_mxf_filename(); boost::filesystem::path to; to /= _film->dir (_film->dcp_name()); - to /= N_("video.mxf"); + to /= _film->dcp_video_mxf_filename (); boost::system::error_code ec; boost::filesystem::create_hard_link (from, to, ec); @@ -285,7 +285,7 @@ Writer::finish () /* And update the asset */ _picture_asset->set_directory (_film->dir (_film->dcp_name ())); - _picture_asset->set_file_name (N_("video.mxf")); + _picture_asset->set_file_name (_film->dcp_video_mxf_filename ()); if (_sound_asset) { _sound_asset->set_entry_point (_film->trim_start ()); @@ -339,8 +339,8 @@ Writer::check_existing_picture_mxf () { /* Try to open the existing MXF */ boost::filesystem::path p; - p /= _film->video_mxf_dir (); - p /= _film->video_mxf_filename (); + p /= _film->internal_video_mxf_dir (); + p /= _film->internal_video_mxf_filename (); FILE* mxf = fopen (p.string().c_str(), N_("rb")); if (!mxf) { return; diff --git a/test/test.cc b/test/test.cc index d1bb400f9..6fad0986b 100644 --- a/test/test.cc +++ b/test/test.cc @@ -504,7 +504,7 @@ BOOST_AUTO_TEST_CASE (have_dcp_test) BOOST_CHECK (f.have_dcp()); p /= f.dcp_name(); - p /= "video.mxf"; + p /= f.dcp_video_mxf_filename(); boost::filesystem::remove (p); BOOST_CHECK (!f.have_dcp ()); } -- cgit v1.2.3 From b8d4a4326e8dae1bd1b850e6798cda9c6c319c91 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 13 Apr 2013 21:27:00 +0100 Subject: Missing using. --- src/tools/dvdomatic.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index b09f4e554..70a96866c 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -52,6 +52,7 @@ using std::stringstream; using std::map; using std::make_pair; using std::exception; +using std::ofstream; using boost::shared_ptr; static FilmEditor* film_editor = 0; -- cgit v1.2.3 From 7fb622a18582f18fcc6cfe140a262fd6cc8cad88 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 14 Apr 2013 00:48:27 +0100 Subject: Fix mapping of audio in DCP. --- src/lib/audio_mapping.cc | 2 +- src/lib/encoder.cc | 6 +++--- src/lib/player.cc | 31 ++++++++++++++++--------------- src/lib/player.h | 2 +- 4 files changed, 21 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/lib/audio_mapping.cc b/src/lib/audio_mapping.cc index b85ea7314..2e8077565 100644 --- a/src/lib/audio_mapping.cc +++ b/src/lib/audio_mapping.cc @@ -41,7 +41,7 @@ int AudioMapping::dcp_channels () const { for (list >::const_iterator i = _content_to_dcp.begin(); i != _content_to_dcp.end(); ++i) { - if (((int) i->second) > 2) { + if (((int) i->second) >= 2) { return 6; } } diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index b897c8a31..d6a57ae6b 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -135,9 +135,9 @@ void Encoder::process_end () { #if HAVE_SWRESAMPLE - if (_film->has_audio() && _film->audio_channels() && _swr_context) { + if (_film->has_audio() && _swr_context) { - shared_ptr out (new AudioBuffers (_film->audio_channels(), 256)); + shared_ptr out (new AudioBuffers (_film->audio_mapping().dcp_channels(), 256)); while (1) { int const frames = swr_convert (_swr_context, (uint8_t **) out->data(), 256, 0, 0); @@ -312,7 +312,7 @@ Encoder::process_audio (shared_ptr data) /* Compute the resampled frames count and add 32 for luck */ int const max_resampled_frames = ceil ((int64_t) data->frames() * _film->target_audio_sample_rate() / _film->audio_frame_rate()) + 32; - shared_ptr resampled (new AudioBuffers (_film->audio_channels(), max_resampled_frames)); + shared_ptr resampled (new AudioBuffers (_film->audio_mapping().dcp_channels(), max_resampled_frames)); /* Resample audio */ int const resampled_frames = swr_convert ( diff --git a/src/lib/player.cc b/src/lib/player.cc index 92c2929ac..c77059b0a 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -92,8 +92,8 @@ Player::pass () } } - Audio (_sndfile_buffers); - _sndfile_buffers.reset (); + Audio (_audio_buffers); + _audio_buffers.reset (); } return done; @@ -126,22 +126,23 @@ Player::process_video (shared_ptr i, bool same, shared_ptr s) void Player::process_audio (weak_ptr c, shared_ptr b) { - if (_playlist->audio_from() == Playlist::AUDIO_SNDFILE) { - AudioMapping mapping = _film->audio_mapping (); - if (!_sndfile_buffers) { - _sndfile_buffers.reset (new AudioBuffers (mapping.dcp_channels(), b->frames ())); - _sndfile_buffers->make_silent (); - } + AudioMapping mapping = _film->audio_mapping (); + if (!_audio_buffers) { + _audio_buffers.reset (new AudioBuffers (mapping.dcp_channels(), b->frames ())); + _audio_buffers->make_silent (); + } - for (int i = 0; i < b->channels(); ++i) { - list dcp = mapping.content_to_dcp (AudioMapping::Channel (c, i)); - for (list::iterator j = dcp.begin(); j != dcp.end(); ++j) { - _sndfile_buffers->accumulate (b, i, static_cast (*j)); - } + for (int i = 0; i < b->channels(); ++i) { + list dcp = mapping.content_to_dcp (AudioMapping::Channel (c, i)); + for (list::iterator j = dcp.begin(); j != dcp.end(); ++j) { + _audio_buffers->accumulate (b, i, static_cast (*j)); } + } - } else { - Audio (b); + if (_playlist->audio_from() == Playlist::AUDIO_FFMPEG) { + /* We can just emit this audio now as it will all be here */ + Audio (_audio_buffers); + _audio_buffers.reset (); } } diff --git a/src/lib/player.h b/src/lib/player.h index 8a82ab298..7a99d6561 100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@ -70,7 +70,7 @@ private: std::list >::iterator _video_decoder; std::list > _sndfile_decoders; - boost::shared_ptr _sndfile_buffers; + boost::shared_ptr _audio_buffers; bool _video_sync; }; -- cgit v1.2.3 From ea7b50b1b1f42e3a722f2efdca6fa2c3184d2105 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 14 Apr 2013 01:17:14 +0100 Subject: UI and basic back-end state for trim type. --- src/lib/film.cc | 26 ++++++++++++++ src/lib/film.h | 13 +++++++ src/wx/film_editor.cc | 93 ++++++++++++++++++++++++++++----------------------- src/wx/film_editor.h | 4 +-- 4 files changed, 92 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/lib/film.cc b/src/lib/film.cc index 077c9e17f..a42b874e8 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -93,6 +93,7 @@ Film::Film (string d, bool must_exist) , _scaler (Scaler::from_id ("bicubic")) , _trim_start (0) , _trim_end (0) + , _trim_type (CPL) , _dcp_ab (false) , _use_content_audio (true) , _audio_gain (0) @@ -163,6 +164,7 @@ Film::Film (Film const & o) , _scaler (o._scaler) , _trim_start (o._trim_start) , _trim_end (o._trim_end) + , _trim_type (o._trim_type) , _dcp_ab (o._dcp_ab) , _content_audio_stream (o._content_audio_stream) , _external_audio (o._external_audio) @@ -456,6 +458,14 @@ Film::write_metadata () const f << "scaler " << _scaler->id () << endl; f << "trim_start " << _trim_start << endl; f << "trim_end " << _trim_end << endl; + switch (_trim_type) { + case CPL: + f << "trim_type cpl\n"; + break; + case ENCODE: + f << "trim_type encode\n"; + break; + } f << "dcp_ab " << (_dcp_ab ? "1" : "0") << endl; if (_content_audio_stream) { f << "selected_content_audio_stream " << _content_audio_stream->to_string() << endl; @@ -569,6 +579,12 @@ Film::read_metadata () _trim_start = atoi (v.c_str ()); } else if ( ((!version || version < 2) && k == "dcp_trim_end") || k == "trim_end") { _trim_end = atoi (v.c_str ()); + } else if (k == "trim_type") { + if (v == "cpl") { + _trim_type = CPL; + } else if (v == "encode") { + _trim_type = ENCODE; + } } else if (k == "dcp_ab") { _dcp_ab = (v == "1"); } else if (k == "selected_content_audio_stream" || (!version && k == "selected_audio_stream")) { @@ -1124,6 +1140,16 @@ Film::set_trim_end (int t) signal_changed (TRIM_END); } +void +Film::set_trim_type (TrimType t) +{ + { + boost::mutex::scoped_lock lm (_state_mutex); + _trim_type = t; + } + signal_changed (TRIM_TYPE); +} + void Film::set_dcp_ab (bool a) { diff --git a/src/lib/film.h b/src/lib/film.h index a5a8ac5fa..dd0a83d94 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -112,6 +112,11 @@ public: bool have_dcp () const; + enum TrimType { + CPL, + ENCODE + }; + /** Identifiers for the parts of our state; used for signalling changes. */ @@ -128,6 +133,7 @@ public: SCALER, TRIM_START, TRIM_END, + TRIM_TYPE, DCP_AB, CONTENT_AUDIO_STREAM, EXTERNAL_AUDIO, @@ -213,6 +219,11 @@ public: return _trim_end; } + TrimType trim_type () const { + boost::mutex::scoped_lock lm (_state_mutex); + return _trim_type; + } + bool dcp_ab () const { boost::mutex::scoped_lock lm (_state_mutex); return _dcp_ab; @@ -345,6 +356,7 @@ public: void set_scaler (Scaler const *); void set_trim_start (int); void set_trim_end (int); + void set_trim_type (TrimType); void set_dcp_ab (bool); void set_content_audio_stream (boost::shared_ptr); void set_external_audio (std::vector); @@ -426,6 +438,7 @@ private: int _trim_start; /** Frames to trim off the end of the DCP */ int _trim_end; + TrimType _trim_type; /** true to create an A/B comparison DCP, where the left half of the image is the video without any filters or post-processing, and the right half has the specified filters and post-processing. diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 62eecb70c..a21782a6f 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -156,11 +156,6 @@ FilmEditor::make_film_panel () _frame_rate_description->SetFont(font); ++r; - video_control (add_label_to_grid_bag_sizer (grid, _film_panel, _("Original Size"), wxGBPosition (r, 0))); - _original_size = new wxStaticText (_film_panel, wxID_ANY, wxT ("")); - grid->Add (video_control (_original_size), wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); - ++r; - video_control (add_label_to_grid_bag_sizer (grid, _film_panel, _("Length"), wxGBPosition (r, 0))); _length = new wxStaticText (_film_panel, wxID_ANY, wxT ("")); grid->Add (video_control (_length), wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); @@ -181,6 +176,11 @@ FilmEditor::make_film_panel () } ++r; + video_control (add_label_to_grid_bag_sizer (grid, _film_panel, _("Trim method"), wxGBPosition (r, 0))); + _trim_type = new wxChoice (_film_panel, wxID_ANY); + grid->Add (video_control (_trim_type), wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); + ++r; + _dcp_ab = new wxCheckBox (_film_panel, wxID_ANY, _("A/B")); video_control (_dcp_ab); grid->Add (_dcp_ab, wxGBPosition (r, 0)); @@ -208,45 +208,49 @@ FilmEditor::make_film_panel () for (list::const_iterator i = dfr.begin(); i != dfr.end(); ++i) { _dcp_frame_rate->Append (std_to_wx (boost::lexical_cast (*i))); } + + _trim_type->Append (_("encode all frames and play the subset")); + _trim_type->Append (_("encode only the subset")); } void FilmEditor::connect_to_widgets () { - _name->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (FilmEditor::name_changed), 0, this); - _use_dci_name->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::use_dci_name_toggled), 0, this); - _edit_dci_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::edit_dci_button_clicked), 0, this); - _format->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::format_changed), 0, this); - _content->Connect (wxID_ANY, wxEVT_COMMAND_FILEPICKER_CHANGED, wxCommandEventHandler (FilmEditor::content_changed), 0, this); - _trust_content_header->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::trust_content_header_changed), 0, this); - _left_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::left_crop_changed), 0, this); - _right_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::right_crop_changed), 0, this); - _top_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::top_crop_changed), 0, this); - _bottom_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::bottom_crop_changed), 0, this); - _filters_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::edit_filters_clicked), 0, this); - _scaler->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::scaler_changed), 0, this); - _dcp_content_type->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::dcp_content_type_changed), 0, this); - _dcp_frame_rate->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::dcp_frame_rate_changed), 0, this); - _best_dcp_frame_rate->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::best_dcp_frame_rate_clicked), 0, this); - _dcp_ab->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::dcp_ab_toggled), 0, this); - _still_duration->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::still_duration_changed), 0, this); - _trim_start->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::trim_start_changed), 0, this); - _trim_end->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::trim_end_changed), 0, this); - _with_subtitles->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::with_subtitles_toggled), 0, this); - _subtitle_offset->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::subtitle_offset_changed), 0, this); - _subtitle_scale->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::subtitle_scale_changed), 0, this); - _colour_lut->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::colour_lut_changed), 0, this); - _j2k_bandwidth->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::j2k_bandwidth_changed), 0, this); - _subtitle_stream->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::subtitle_stream_changed), 0, this); - _audio_stream->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::audio_stream_changed), 0, this); - _audio_gain->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::audio_gain_changed), 0, this); + _name->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (FilmEditor::name_changed), 0, this); + _use_dci_name->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::use_dci_name_toggled), 0, this); + _edit_dci_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::edit_dci_button_clicked), 0, this); + _format->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::format_changed), 0, this); + _content->Connect (wxID_ANY, wxEVT_COMMAND_FILEPICKER_CHANGED, wxCommandEventHandler (FilmEditor::content_changed), 0, this); + _trust_content_header->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::trust_content_header_changed), 0, this); + _left_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::left_crop_changed), 0, this); + _right_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::right_crop_changed), 0, this); + _top_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::top_crop_changed), 0, this); + _bottom_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::bottom_crop_changed), 0, this); + _filters_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::edit_filters_clicked), 0, this); + _scaler->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::scaler_changed), 0, this); + _dcp_content_type->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::dcp_content_type_changed), 0, this); + _dcp_frame_rate->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::dcp_frame_rate_changed), 0, this); + _best_dcp_frame_rate->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::best_dcp_frame_rate_clicked), 0, this); + _dcp_ab->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::dcp_ab_toggled), 0, this); + _still_duration->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::still_duration_changed), 0, this); + _trim_start->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::trim_start_changed), 0, this); + _trim_end->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::trim_end_changed), 0, this); + _trim_type->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::trim_type_changed), 0, this); + _with_subtitles->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::with_subtitles_toggled), 0, this); + _subtitle_offset->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::subtitle_offset_changed), 0, this); + _subtitle_scale->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::subtitle_scale_changed), 0, this); + _colour_lut->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::colour_lut_changed), 0, this); + _j2k_bandwidth->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::j2k_bandwidth_changed), 0, this); + _subtitle_stream->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::subtitle_stream_changed), 0, this); + _audio_stream->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::audio_stream_changed), 0, this); + _audio_gain->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::audio_gain_changed), 0, this); _audio_gain_calculate_button->Connect ( wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::audio_gain_calculate_button_clicked), 0, this ); - _show_audio->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::show_audio_clicked), 0, this); - _audio_delay->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::audio_delay_changed), 0, this); - _use_content_audio->Connect (wxID_ANY, wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler (FilmEditor::use_audio_changed), 0, this); - _use_external_audio->Connect (wxID_ANY, wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler (FilmEditor::use_audio_changed), 0, this); + _show_audio->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::show_audio_clicked), 0, this); + _audio_delay->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::audio_delay_changed), 0, this); + _use_content_audio->Connect (wxID_ANY, wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler (FilmEditor::use_audio_changed), 0, this); + _use_external_audio->Connect (wxID_ANY, wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler (FilmEditor::use_audio_changed), 0, this); for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) { _external_audio[i]->Connect ( wxID_ANY, wxEVT_COMMAND_FILEPICKER_CHANGED, wxCommandEventHandler (FilmEditor::external_audio_changed), 0, this @@ -682,12 +686,6 @@ FilmEditor::film_changed (Film::Property p) setup_frame_rate_description (); break; case Film::SIZE: - if (_film->size().width == 0 && _film->size().height == 0) { - _original_size->SetLabel (wxT ("")); - } else { - s << _film->size().width << " x " << _film->size().height; - _original_size->SetLabel (std_to_wx (s.str ())); - } setup_scaling_description (); break; case Film::LENGTH: @@ -720,6 +718,9 @@ FilmEditor::film_changed (Film::Property p) case Film::TRIM_END: checked_set (_trim_end, _film->trim_end()); break; + case Film::TRIM_TYPE: + checked_set (_trim_type, _film->trim_type() == Film::CPL ? 0 : 1); + break; case Film::AUDIO_GAIN: checked_set (_audio_gain, _film->audio_gain ()); break; @@ -898,6 +899,7 @@ FilmEditor::set_film (shared_ptr f) film_changed (Film::SCALER); film_changed (Film::TRIM_START); film_changed (Film::TRIM_END); + film_changed (Film::TRIM_TYPE); film_changed (Film::DCP_AB); film_changed (Film::CONTENT_AUDIO_STREAM); film_changed (Film::EXTERNAL_AUDIO); @@ -944,6 +946,7 @@ FilmEditor::set_things_sensitive (bool s) _dcp_frame_rate->Enable (s); _trim_start->Enable (s); _trim_end->Enable (s); + _trim_type->Enable (s); _dcp_ab->Enable (s); _colour_lut->Enable (s); _j2k_bandwidth->Enable (s); @@ -1400,3 +1403,9 @@ FilmEditor::setup_scaling_description () _scaling_description->SetLabel (d); } + +void +FilmEditor::trim_type_changed (wxCommandEvent &) +{ + _film->set_trim_type (_trim_type->GetSelection () == 0 ? Film::CPL : Film::ENCODE); +} diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index 7123620d3..e2a4d5836 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -65,6 +65,7 @@ private: void format_changed (wxCommandEvent &); void trim_start_changed (wxCommandEvent &); void trim_end_changed (wxCommandEvent &); + void trim_type_changed (wxCommandEvent &); void dcp_content_type_changed (wxCommandEvent &); void dcp_ab_toggled (wxCommandEvent &); void scaler_changed (wxCommandEvent &); @@ -169,8 +170,6 @@ private: wxChoice* _dcp_frame_rate; wxButton* _best_dcp_frame_rate; wxStaticText* _frame_rate_description; - /** The Film's original size */ - wxStaticText* _original_size; /** The Film's length */ wxStaticText* _length; /** The Film's audio details */ @@ -180,6 +179,7 @@ private: wxSpinCtrl* _trim_start; wxSpinCtrl* _trim_end; + wxChoice* _trim_type; /** Selector to generate an A/B comparison DCP */ wxCheckBox* _dcp_ab; -- cgit v1.2.3 From aa3c4f99bc31ed85262031bc347a75361f93eb09 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 14 Apr 2013 01:36:51 +0100 Subject: NS fix. --- src/tools/dvdomatic.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 70a96866c..3628fd450 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -18,6 +18,7 @@ */ #include +#include #include #ifdef __WXMSW__ #include @@ -459,7 +460,7 @@ setup_i18n () { int language = wxLANGUAGE_DEFAULT; - ofstream f ("c:/users/carl/foo", ios::app); + ofstream f ("c:/users/carl/foo", std::ios::app); f << "Hello.\n"; if (Config::instance()->language()) { -- cgit v1.2.3 From 133afe16d6149effe39a061311d2832c30a77222 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 14 Apr 2013 14:08:57 +0100 Subject: Re-add some missing files. --- dcpomatic.desktop.in | 10 + doc/manual/dcpomatic-html.xsl | 12 + doc/manual/dcpomatic-pdf.xml | 17 + doc/manual/dcpomatic.css | 19 + doc/manual/dcpomatic.sty | 68 +++ doc/manual/dcpomatic.xml | 932 ++++++++++++++++++++++++++++++++++++++++++ icons/128x128/dcpomatic.png | Bin 0 -> 18365 bytes icons/16x16/dcpomatic.png | Bin 0 -> 211 bytes icons/22x22/dcpomatic.png | Bin 0 -> 994 bytes icons/32x32/dcpomatic.png | Bin 0 -> 1747 bytes icons/48x48/dcpomatic.png | Bin 0 -> 3407 bytes icons/64x64/dcpomatic.png | Bin 0 -> 5421 bytes run/dcpomatic | 15 + src/tools/dcpomatic.cc | 578 ++++++++++++++++++++++++++ windows/dcpomatic.bmp | Bin 0 -> 343254 bytes windows/dcpomatic.ico | Bin 0 -> 9662 bytes windows/dcpomatic.rc | 3 + windows/dcpomatic_taskbar.ico | Bin 0 -> 1150 bytes 18 files changed, 1654 insertions(+) create mode 100644 dcpomatic.desktop.in create mode 100644 doc/manual/dcpomatic-html.xsl create mode 100644 doc/manual/dcpomatic-pdf.xml create mode 100644 doc/manual/dcpomatic.css create mode 100644 doc/manual/dcpomatic.sty create mode 100644 doc/manual/dcpomatic.xml create mode 100644 icons/128x128/dcpomatic.png create mode 100644 icons/16x16/dcpomatic.png create mode 100644 icons/22x22/dcpomatic.png create mode 100644 icons/32x32/dcpomatic.png create mode 100644 icons/48x48/dcpomatic.png create mode 100644 icons/64x64/dcpomatic.png create mode 100755 run/dcpomatic create mode 100644 src/tools/dcpomatic.cc create mode 100644 windows/dcpomatic.bmp create mode 100644 windows/dcpomatic.ico create mode 100644 windows/dcpomatic.rc create mode 100644 windows/dcpomatic_taskbar.ico (limited to 'src') diff --git a/dcpomatic.desktop.in b/dcpomatic.desktop.in new file mode 100644 index 000000000..aabd992f5 --- /dev/null +++ b/dcpomatic.desktop.in @@ -0,0 +1,10 @@ +[Desktop Entry] +Encoding=UTF-8 +Version=1.0 +Type=Application +Terminal=false +Exec=@PREFIX@/bin/dcpomatic +Name=DCP-o-matic +Icon=dcpomatic +Comment=DCP generator +Categories=AudioVideo;Video diff --git a/doc/manual/dcpomatic-html.xsl b/doc/manual/dcpomatic-html.xsl new file mode 100644 index 000000000..144675d47 --- /dev/null +++ b/doc/manual/dcpomatic-html.xsl @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/doc/manual/dcpomatic-pdf.xml b/doc/manual/dcpomatic-pdf.xml new file mode 100644 index 000000000..414fb64b8 --- /dev/null +++ b/doc/manual/dcpomatic-pdf.xml @@ -0,0 +1,17 @@ + + + + +colorlinks,linkcolor=black,urlcolor=black + + +0 +0 + + +scale=0.6 + + +3 + + diff --git a/doc/manual/dcpomatic.css b/doc/manual/dcpomatic.css new file mode 100644 index 000000000..0e4982f20 --- /dev/null +++ b/doc/manual/dcpomatic.css @@ -0,0 +1,19 @@ +body { + font-family: luxi sans, sans-serif; + margin-left: 4em; + margin-right: 4em; + margin-top: 1em; + margin-bottom: 1em; + background-color: #E2E8EE; +} + +div.sidebar { + margin-left: 1em; + margin-right: 1em; + padding-left: 1em; + padding-right: 1em; + border-color: #000000; + border-width: 2px; + border-style: solid; + background-color: #E2E8EE; +} diff --git a/doc/manual/dcpomatic.sty b/doc/manual/dcpomatic.sty new file mode 100644 index 000000000..834e581fc --- /dev/null +++ b/doc/manual/dcpomatic.sty @@ -0,0 +1,68 @@ +%% +%% This style is derivated from the docbook one +%% +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{ardour}[2007/04/04 My DocBook Style] + +%% Just use the original package and pass the options +\RequirePackageWithOptions{docbook} + +% Use a nice font +\usepackage{lmodern} + +% Define \dbend as the dangerous bend sign +\font\manual=manfnt +\def\dbend{{\manual\char127}} + +% Redefine sidebar environment to use the dangerous bend style +% Danger, Will Robinson! +\def\sidebar{\begin{trivlist}\item[]\noindent% +\begingroup\hangindent=2pc\hangafter=-2%\clubpenalty=10000% +\def\par{\endgraf\endgroup}% +\hbox to0pt{\hskip-\hangindent\dbend\hfill}\ignorespaces} +\def\endsidebar{\par\end{trivlist}} + + +% Futz with the title page; basically a copy of +% /usr/share/texmf/tex/latex/dblatex/style/dbk_title.sty +% with authors added. + +\def\DBKcover{ +\ifthenelse{\equal{\DBKedition}{}}{\def\edhead{}}{\def\edhead{Ed. \DBKedition}} + +\pagestyle{empty} + +% interligne double +\setlength{\oldbaselineskip}{\baselineskip} +\setlength{\baselineskip}{2\oldbaselineskip} +\textsf{ +\vfill +\vspace{2.5cm} +\begin{center} + \huge{\textbf{\DBKtitle}}\\ % + \ \\ % + \ \\ % + \Large{\DBKauthor}\\ % + \ifx\DBKsubtitle\relax\else% + \underline{\ \ \ \ \ \ \ \ \ \ \ }\\ % + \ \\ % + \huge{\textbf{\DBKsubtitle}}\\ % + \fi +\end{center} +\vfill +\setlength{\baselineskip}{\oldbaselineskip} +\hspace{1cm} +\vspace{1cm} +\begin{center} +\begin{tabular}{p{7cm} p{7cm}} +\Large{\DBKreference{} \edhead} & \\ +\end{tabular} +\end{center} +} + +% Format for the other pages +\newpage +\setlength{\baselineskip}{\oldbaselineskip} +%\chead[]{\DBKcheadfront} +\lfoot[]{} +} diff --git a/doc/manual/dcpomatic.xml b/doc/manual/dcpomatic.xml new file mode 100644 index 000000000..ee7b96083 --- /dev/null +++ b/doc/manual/dcpomatic.xml @@ -0,0 +1,932 @@ + + + + +%dbcent; + +%extensions; +]> + + + +DCP-o-matic +CarlHetherington + + + +Introduction + + +Hello, and welcome to DCP-o-matic! + + +
+What is DCP-o-matic? + + +DCP-o-matic is a program to generate Digital +Cinema Packages (DCPs) from DVDs, Blu-Rays, video files such as MP4 +and AVI, or still images. The resulting DCPs will play on modern digital +cinema projectors. + + + +You might find it useful to make DVDs easier to present, to encode +independently-shot feature films, or to generate local advertising for +your cinema. + + +
+ +
+Licence + + +DCP-o-matic is licensed under the GNU GPL. + + +
+ +
+ + +Installation + +
+Windows + + +To install DCP-o-matic on Windows, simply download the installer from +http://carlh.net +and double-click it. Click through the installer wizard, and +DCP-o-matic will be installed onto your machine. + + + +If you are using a 32-bit version of Windows, you will need the 32-bit +installer. For 64-bit Windows, either installer will work, but I +suggest you used the 64-bit version as it will allow DCP-o-matic to +use more memory. You may find that DCP-o-matic crashes if you run +many parallel encoding threads (more than 4) on the 32-bit +version. + + +
+ +
+Ubuntu Linux + + +You can install DCP-o-matic on Ubuntu 12.04 (‘Precise +Pangolin’) or 12.10 (‘Quantal Quetzal’) using +.deb packages: download the appropriate package from +http://carlh.net and +double-click it. Ubuntu will install the necessary bits and pieces +and set DCP-o-matic up for you. + + +
+ +
+Other Linux distributions + + +Installation on non-Ubuntu Linux is currently a little involved, as +there are no packages available (yet); you will have to compile it +from source. If you are using a non-Ubuntu distribution, do let me +know via the mailing +list and I will see about building some packages. + + + +The following dependencies are required: + +FFmpeg +libsndfile +OpenSSL +libopenjpeg +ImageMagick +Boost +libssh +GTK +wxWidgets +libdcp + + + + +Once you have installed the development packages for the dependencies, +download the source code from http://carlh.net, +unpack it and run the following commands from inside the source +directory: + + + +./waf configure +./waf build +sudo ./waf install + + + +With any luck, this will build and install DCP-o-matic on your system. To run it, enter: + + + +dcpomatic + + + +in a shell. + + +
+
+ + +Creating a video DCP + + +In this chapter we will see how to create a video DCP using +DCP-o-matic. We will gloss over some of the finer details, which are +explained in later chapters. + + +
+Creating a new film + + +Let's make a very simple DCP to see how DCP-o-matic works. First, we +need some content. Download the low-resolution trailer for the open +movie Sintel from their +website. Generally, of course, one would want to use the +highest-resolution material available, but for this test we will use +the low-resolution version to save everyone's bandwidth bills. + + + +Now, start DCP-o-matic and its window will open. First, we will +create a new ‘film’. A ‘film’ is how DCP-o-matic refers to +a piece of content, along with some settings, which we will make into +a DCP. DCP-o-matic stores its data in a folder on your disk while it +creates the DCP. You can create a new film by selecting +New from the File menu, as +shown in . + + +
+ Creating a new film + + + + + +
+ + +This will open a dialogue box for the new film, as shown in . + + +
+ Dialogue box for creating a new film + + + + + +
+ + +In this dialogue box you can choose a name for the film. This will be +used to name the folder to store its data in, and also as the initial +name for the DCP itself. You can also choose whereabouts you want to create +the film. In the example from the figure, DCP-o-matic will create a +folder called ‘DCP Test’ inside my home folder (carl) into which it +will write its working files. + + + +If you always create your DCPs in a particular folder, you can use +DCP-o-matic's Preferences to make life a little +easier by setting the default folder that DCP-o-matic will offer in this dialogue. +See . + + +
+ +
+Selecting content + + +The next step is to set the content that you want to use. Click the +content selector, as shown in , and a file chooser will +open for you to select the content file to use, as shown in . + + +
+ Opening the content selector + + + + + +
+ +
+ Selecting a video content file + + + + + +
+ + +Select your content file and click Open. In this +case we are using the Sintel trailer that we downloaded earlier. + + + +When you do this, DCP-o-matic will take a look at your file. After a +short while (when the progress bar at the bottom right of the window +has finished), you can look through your content using the slider to +the right of the window, as shown in . + + +
+ Examining the content + + + + + +
+ + +Dragging the slider will move through your video. You can also click +the Play button to play the content back. Note +that there will be no sound, and playback might not be entirely +accurate (it may be slightly slower or faster than it should be, for +example). This player is really only intended for brief inspection of +content; if you need to check it more thoroughly, use another player +such as Totem, mplayer or VLC. + + +
+ +
+Setting up + + +Now there are a few things to set up to describe how the DCP should be +created. The settings are divided into four tabs: film, video, audio and subtitles. + + +
+Film tab + + +The ‘film’ tab contains settings that pertain to the whole film, as shown in . + + +
+ Film settings tab + + + + + +
+ + +The first thing here is the name. This is generally set to the title +of the film that is being encoded. If Use DCI +name is not ticked, the name that you specify will be used +as-is for the name of the DCP. If Use DCI name +is ticked, the name that you enter will be used as part of a +DCI-compliant name. + + + +Underneath the name field is a preview of the name that the DCP will +get. To use a DCI-compliant name, tick the Use DCI +name checkbox. The DCI name will be composed using details +of your content's soundtrack, the current date and other things that +can be specified in the DCI name details dialogue box, which you can +open by clicking on the Details button. + + + +If the DCP name is long, it may not all be visible. You can see the +full name by hovering the mouse pointer over the partial name. + + + +The Trust content's header button starts off +checked, and this means that DCP-o-matic will use the content's header +information to determine its length. If, for some reason, this header +length is wrong, uncheck the Trust content's +header button and DCP-o-matic will run through the content +to find its exact length. This may take a while for large pieces of content. + + + +Next up is the content type. This can be +‘feature’, ‘trailer’ or whatever; select the +required type from the drop-down list. + + + +The trim frames settings allow you to trim frames +from the beginning and end of the content; any trimmed frames will not +be included in the DCP. + + +
+ +
+Video tab + + +This tab contains settings related to the picture in your DCP, as shown in . + + +
+ Video settings tab + + + + + +
+ + +The first option on this tab is the format. This will govern the +shape that DCP-o-matic will make your image into. Select the aspect +ratio that your content should be presented in. The ‘4:3 within +Flat’ and ‘16:9 within Flat’ settings will put the +image at the specified ratio within a Flat (1.85:1) frame, so that you +can project the DCP using your projector's Flat preset. + + + +The remaining options can often be left alone, but may sometimes be +useful. The ‘crop’ settings can be used to crop your +content, which can be used to remove black borders from round the +edges of DVD images, for example. The specified number of pixels will +be trimmed from each edge, and the content image in the right of the +window will be updated to show the effect of the crop. + + + +The ‘filters’ settings allow you to apply various video +filters to the image. These may be useful to try to improve +poor-quality sources like DVDs. We will discuss filtering later in the manual. + + + + +The ‘scaler’ is the method that will be used to scale up +your content to the required size for the DCP, if required. We will +discuss the options in more detail later; Bicubic is a fine choice in +most situations. + + + + +The ‘colour look-up table’ specifies the colour space that +your input content will be expected to be in. If in doubt, leave it +set to ‘sRGB’. + + + +Finally, the ‘JPEG2000 bandwidth’ setting changes how big the final +image files used within the DCP will be. Larger numbers will give +better quality, but correspondingly larger DCPs. The bandwidth can be +between 50 and 250 megabits per second (MBps). + + +
+ +
+Audio tab + + +This tab contains settings related to the sound in your DCP, as shown in . + + +
+ Audio settings tab + + + + + +
+ + + +‘Audio Gain’ is used to alter the volume of the +soundtrack. The specified gain (in dB) will be applied to each sound +channel before it is written to the DCP. + + + +If you use a sound processor that DCP-o-matic knows about, it can help +you calculate changes in gain that you should apply. Say, for +example, that you make a test DCP and find that you have to run it at +volume 5 instead of volume 7 to get a good sound level in the screen. +If this is the case, click the Calculate... +button next to the audio gain entry, and the dialogue box in will open. + + +
+ Calculating audio gain + + + + + +
+ + +For our example, put 5 in the first box and 7 in the second and click +OK. DCP-o-matic will calculate the audio gain +that it should apply to make this happen. Then you can re-make the +DCP (this will be reasonably fast, as the video data will already have +been done) and it should play back at the correct volume with 7 on +your sound-rack fader. + + + +Current versions of DCP-o-matic only know about the Dolby CP750. If +you use a different sound processor, and know the gain curve of its +volume control, get in +touch. + + + +‘Audio Delay’ is used to adjust the synchronisation +between audio and video. A positive delay will move the audio later +with respect to the video, and a negative delay will move it earlier. + + + +By default the Use content‘s audio button +will be selected. This means that the DCP will use one of the +soundtracks from your content file; you can select the soundtrack that +you wish to use from the drop-down box. + + + +Note that if your content's audio is mono, DCP-o-matic will place it +in the centre channel in the DCP. + + + +Alternatively, you can supply different sound files by clicking the +Use external audio button and choosing a WAV file +for any channels that you want to appear in the DCP. These files can +be any bit depth and sampling rate, and will be re-sampled and +bit-depth converted if required. + + +
+
+Subtitles tab + + +This tab contains settings related to subtitles in your DCP, as shown in . + + +
+ Subtitle settings tab + + + + + +
+ + +DCP-o-matic will extract subtitles from the content, if present, and +they can be ‘burnt into’ the DCP (that is, they are +included in the image and not overlaid by the projector). Note that +DVD and Blu-Ray subtitles are stored as bitmaps, so it is not possible +(automatically) to use non-burnt-in subtitles with these sources. +Select the With Subtitles checkbox to enable +subtitles. The offset control moves the +subtitles up and down the image, and the scale +control changes their size. + + + +Future versions of DCP-o-matic will hopefully include the option to +use text subtitles (as is the norm with most professionally-mastered +DCPs). + + +
+
+ +
+Making the DCP + + +Now that we have set everything up, choose Make +DCP from the Jobs menu. DCP-o-matic +will encode your DCP. This may take some time (many hours in some +cases). While the job is in progress, DCP-o-matic will update you on +how it is getting on with the progress bar in the bottom of its window, as shown in . + + +
+ Making the DCP + + + + + +
+ + +When it has finished, the DCP will end up on your disk inside the +film's directory. You can then copy this to a projector via a USB +stick, hard-drive or network connection. + + + +Alternatively, if you have a projector or TMS that is accessible via +SCP across your network, you can upload the content directly from +DCP-o-matic. See . + + +
+
+ + + +Creating a still-image DCP + + +DCP-o-matic can also be used to create DCPs of a still image, perhaps +for an advertisement or an on-screen announcement. This chapter shows you +how to do it. + + + +As with video DCPs, the first step is to create a new +‘Film’; select New from the +File menu and the new film dialogue will open as +shown in . + + +
+ Dialogue box for creating a new film + + + + + +
+ + +Enter a name and click OK. Then we set up the +content; click the content selector as before, and this time we will +choose an image file, as shown in . + + +
+ Selecting a still content file + + + + + +
+ + +Setting up for a still image DCP is somewhat simpler than for a video; +the tabs are all the same, but many options are removed and a few are added. + + + +As with video, you can select a content type and the format (ratio) +that your image should be presented in. It will be scaled and padded +to fit the selected ratio, but in such a way that the pixel aspect +ratio is preserved. In other words, the image will not be stretched, +merely scaled; if you want to stretch your image, you will need to do +so in a separate program before importing it into DCP-o-matic. You +can also crop your image, if you so choose, and then set a duration +(in seconds) that the image should appear on screen. + + + +Still-image DCPs can include sound; this can be added from the +Audio tab. If your specified duration is shorter +than the audio, the audio will be cut off at the duration; if it is +longer, silence will be added after your audio. + + + +Finally, as with video, you can choose Make DCP +from the Jobs menu to create your DCP. This will +be much quicker than creating a video DCP, as DCP-o-matic only needs +to encode a single frame which it can then repeat. + + +
+ + + +Preferences + + +DCP-o-matic provides a few preferences which can be used to modify its +behaviour. This chapter explains those options. + + +
+The preferences dialogue + + +The preferences dialogue is opened by choosing +Preferences... from the Edit +menu. The dialogue is shown in . + + +
+ Preferences + + + + + +
+ +
+TMS setup + + +The first part of the dialogue gives some options for specifying +details about your TMS. If you do this, and your TMS accepts SSH +connections, you can upload DCPs directly from DCP-o-matic to the TMS. +This is discussed in . + + + +TMS IP address should be set to the IP address of +your TMS, TMS target path to the place that DCPs +should be uploaded to (which will be relative to the home directory of +the SSH user). Finally, the user name and password are the +credentials required to log into the TMS via SSH. + +
+ +
+Threads + + +When DCP-o-matic is encoding DCPs it can use multiple parallel threads +to speed things up. Set this value to the number of threads +DCP-o-matic should use. This would typically be set to the number of +processors (or processor cores) in your machine. + + +
+ +
+Default directory for new films + + +This is the directory which DCP-o-matic will suggest initially as a place to put new films. + + +
+ +
+A/B options + + +These options are for DCP-o-matic's special mode of making A/B +comparison DCPs for checking the performance of video filters. Their +use is described in . + + +
+ +
+Encoding servers + + +If you have spare machines sitting around on your network not doing +much, they can be pressed into service to speed up DCP encodes. This +is done by running a small server program on the machine, which will +encode video sent to it by the ‘master’ DCP-o-matic. This +option is described in more detail in . +Use these preferences to specify the encoding servers that should be +used. + + +
+ +
+
+ + +Advanced topics + +This chapter describes some parts of DCP-o-matic that are +probably not essential, but which you might find useful in some +circumstances. + + +
+Filtering + + +DCP-o-matic offers a variety of filters that can be applied to your +video content. You can set up the filters by clicking the +Edit button next to the filters entry in the +setup area of the DCP-o-matic window; this opens the filters selector +as shown in . + + +
+ Filters selector + + + + + +
+ + +After changing the filters setup, you will need to regenerate the DCP +to see the effect on the cinema screen. The preview in DCP-o-matic +will update itself whenever filters are changed, though of course this +image is much smaller and of lower resolution than a projected image! + + +
+ +
+Scaling + + +If your source material is not of the DCI-specified size, or if it +uses non-square pixels, DCP-o-matic will need to scale it. The +algorithm used to scale is set up by the Scaler +entry in the film setup area. We think ‘Bicubic’ is the +best all-round option, but tests are ongoing. + + +
+ +
+TMS upload + + +If you have configured details of a TMS in the preferences dialogue +() you can upload a completed DCP +straight to your TMS buy choosing Send DCP to TMS +from the Jobs menu. + + +
+ + +
+A/B comparison + + +When evaluating the effects of different filters or scalers on the +image quality, A/B mode might be useful. In this mode, DCP-o-matic +will generate a DCP where the left half of the image uses some +‘reference’ filtering and scaling, and the right half of +the image uses a different set of filters and a different scaler. +This DCP can then be played back on a projector and the image quality +evaluated. + + + +To enable A/B mode, click the A/B checkbox in the setup area of the +DCP-o-matic window. When you generate your DCP, the left half of the +screen will use the filters and scaler specified in the preferences dialogue, and the right +half will use the filters and scaler specified in the film setup. + + +
+ +
+Encoding servers + + +One way to increase the speed of DCP encoding is to use more +than one machine at the same time. An instance of DCP-o-matic can +offload some of the time-consuming JPEG2000 encoding to any number of +other machines on a network. To do this, one ‘master’ +machine runs DCP-o-matic, and the ‘server’ machines run +a small program called ‘servomatic’. + + +
+Running the servers + + +There are two options for the encoding server; +servomatic_cli, which runs on the command line, and +servomatic_gui, which has a simple GUI. The command line +version is well-suited to headless servers, especially on Linux, and +the GUI version works best on Windows where it will put an icon in the +system tray. + + + +To run the command line version, simply enter: + + + +servomatic_cli + + + +at a command prompt. If you are running the program on a machine with +a multi-core processor, you can run multiple parallel encoding threads +by doing something like: + + + +servomatic_cli -t 4 + + + +to run 4 threads in parallel. + + + +To run the GUI version on windows, run the ‘DCP-o-matic encode +server’ from the start menu. An icon will appear in the system +tray; right-click it to open a menu from whence you can quit the +server or open a window to show its status. + + +
+
+Setting up DCP-o-matic + + +Once your servers are running, you need to tell your master +DCP-o-matic instance about them. Start DCP-o-matic and open the +Preferences dialog from the +Edit menu. At the bottom of this dialog is a +section where you can add, edit and remove encoding servers. For each +encoding server you need only specify its IP address and the number of +threads that it is running, so that DCP-o-matic knows how many +parallel encode jobs to send to the server. + + + +Once this is done, any encodes that you start will split the workload +up between the master machine and the servers. + + +
+
+Some notes about encode servers + + +DCP-o-matic does not mind if servers come and go; if a server +disappears, DCP-o-matic will stop sending work to it, and will check +it every minute or so in case it has come back online. + + + +You will probably find that using a 1Gb/s or faster network will +provide a significant speed-up compared to a 100Mb/s network. + + + +Making changes to the server configuration in the master DCP-o-matic +will have no effect while an encode is running; the changes will only +be noticed when a new encode is started. + + +
+
+ +
+ + +
diff --git a/icons/128x128/dcpomatic.png b/icons/128x128/dcpomatic.png new file mode 100644 index 000000000..9936b39af Binary files /dev/null and b/icons/128x128/dcpomatic.png differ diff --git a/icons/16x16/dcpomatic.png b/icons/16x16/dcpomatic.png new file mode 100644 index 000000000..3c5a10f2d Binary files /dev/null and b/icons/16x16/dcpomatic.png differ diff --git a/icons/22x22/dcpomatic.png b/icons/22x22/dcpomatic.png new file mode 100644 index 000000000..dddb86298 Binary files /dev/null and b/icons/22x22/dcpomatic.png differ diff --git a/icons/32x32/dcpomatic.png b/icons/32x32/dcpomatic.png new file mode 100644 index 000000000..8cecf08f8 Binary files /dev/null and b/icons/32x32/dcpomatic.png differ diff --git a/icons/48x48/dcpomatic.png b/icons/48x48/dcpomatic.png new file mode 100644 index 000000000..07bf2d10b Binary files /dev/null and b/icons/48x48/dcpomatic.png differ diff --git a/icons/64x64/dcpomatic.png b/icons/64x64/dcpomatic.png new file mode 100644 index 000000000..35564a8a2 Binary files /dev/null and b/icons/64x64/dcpomatic.png differ diff --git a/run/dcpomatic b/run/dcpomatic new file mode 100755 index 000000000..7ea08778c --- /dev/null +++ b/run/dcpomatic @@ -0,0 +1,15 @@ +#!/bin/bash + +export LD_LIBRARY_PATH=build/src/lib:build/src/wx:build/src/asdcplib/src:$LD_LIBRARY_PATH +if [ "$1" == "--debug" ]; then + shift + gdb --args build/src/tools/dcpomatic $* +elif [ "$1" == "--valgrind" ]; then + shift + valgrind --tool="memcheck" build/src/tools/dcpomatic $* +elif [ "$1" == "--i18n" ]; then + shift + LANGUAGE=fr_FR.UTF8 LANG=fr_FR.UTF8 build/src/tools/dcpomatic "$*" +else + build/src/tools/dcpomatic $* +fi diff --git a/src/tools/dcpomatic.cc b/src/tools/dcpomatic.cc new file mode 100644 index 000000000..ee9f9977c --- /dev/null +++ b/src/tools/dcpomatic.cc @@ -0,0 +1,578 @@ +/* + Copyright (C) 2012 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include +#ifdef __WXMSW__ +#include +#endif +#include +#include +#include +#include "wx/film_viewer.h" +#include "wx/film_editor.h" +#include "wx/job_manager_view.h" +#include "wx/config_dialog.h" +#include "wx/job_wrapper.h" +#include "wx/wx_util.h" +#include "wx/new_film_dialog.h" +#include "wx/properties_dialog.h" +#include "wx/wx_ui_signaller.h" +#include "lib/film.h" +#include "lib/format.h" +#include "lib/config.h" +#include "lib/filter.h" +#include "lib/util.h" +#include "lib/scaler.h" +#include "lib/exceptions.h" +#include "lib/version.h" +#include "lib/ui_signaller.h" +#include "lib/log.h" + +using std::cout; +using std::string; +using std::wstring; +using std::stringstream; +using std::map; +using std::make_pair; +using std::exception; +using boost::shared_ptr; + +static FilmEditor* film_editor = 0; +static FilmViewer* film_viewer = 0; +static shared_ptr film; +static std::string log_level; +static std::string film_to_load; +static std::string film_to_create; +static wxMenu* jobs_menu = 0; +static wxLocale* locale = 0; + +static void set_menu_sensitivity (); + +class FilmChangedDialog +{ +public: + FilmChangedDialog () + { + _dialog = new wxMessageDialog ( + 0, + wxString::Format (_("Save changes to film \"%s\" before closing?"), std_to_wx (film->name ()).data()), + _("Film changed"), + wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION + ); + } + + ~FilmChangedDialog () + { + _dialog->Destroy (); + } + + int run () + { + return _dialog->ShowModal (); + } + +private: + wxMessageDialog* _dialog; +}; + + +void +maybe_save_then_delete_film () +{ + if (!film) { + return; + } + + if (film->dirty ()) { + FilmChangedDialog d; + switch (d.run ()) { + case wxID_NO: + break; + case wxID_YES: + film->write_metadata (); + break; + } + } + + film.reset (); +} + +enum Sensitivity { + ALWAYS, + NEEDS_FILM +}; + +map menu_items; + +void +add_item (wxMenu* menu, wxString text, int id, Sensitivity sens) +{ + wxMenuItem* item = menu->Append (id, text); + menu_items.insert (make_pair (item, sens)); +} + +void +set_menu_sensitivity () +{ + for (map::iterator i = menu_items.begin(); i != menu_items.end(); ++i) { + if (i->second == NEEDS_FILM) { + i->first->Enable (film != 0); + } else { + i->first->Enable (true); + } + } +} + +enum { + ID_file_new = 1, + ID_file_open, + ID_file_save, + ID_file_properties, + ID_file_quit, + ID_edit_preferences, + ID_jobs_make_dcp, + ID_jobs_send_dcp_to_tms, + ID_jobs_show_dcp, + ID_jobs_analyse_audio, + ID_help_about +}; + +void +setup_menu (wxMenuBar* m) +{ + wxMenu* file = new wxMenu; + add_item (file, _("New..."), ID_file_new, ALWAYS); + add_item (file, _("&Open..."), ID_file_open, ALWAYS); + file->AppendSeparator (); + add_item (file, _("&Save"), ID_file_save, NEEDS_FILM); + file->AppendSeparator (); + add_item (file, _("&Properties..."), ID_file_properties, NEEDS_FILM); + file->AppendSeparator (); + add_item (file, _("&Quit"), ID_file_quit, ALWAYS); + + wxMenu* edit = new wxMenu; + add_item (edit, _("&Preferences..."), ID_edit_preferences, ALWAYS); + + jobs_menu = new wxMenu; + add_item (jobs_menu, _("&Make DCP"), ID_jobs_make_dcp, NEEDS_FILM); + add_item (jobs_menu, _("&Send DCP to TMS"), ID_jobs_send_dcp_to_tms, NEEDS_FILM); + add_item (jobs_menu, _("S&how DCP"), ID_jobs_show_dcp, NEEDS_FILM); + jobs_menu->AppendSeparator (); + add_item (jobs_menu, _("&Analyse audio"), ID_jobs_analyse_audio, NEEDS_FILM); + + wxMenu* help = new wxMenu; + add_item (help, _("About"), ID_help_about, ALWAYS); + + m->Append (file, _("&File")); + m->Append (edit, _("&Edit")); + m->Append (jobs_menu, _("&Jobs")); + m->Append (help, _("&Help")); +} + +bool +window_closed (wxCommandEvent &) +{ + maybe_save_then_delete_film (); + return false; +} + +class Frame : public wxFrame +{ +public: + Frame (wxString const & title) + : wxFrame (NULL, -1, title) + { + wxMenuBar* bar = new wxMenuBar; + setup_menu (bar); + SetMenuBar (bar); + + Connect (ID_file_new, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::file_new)); + Connect (ID_file_open, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::file_open)); + Connect (ID_file_save, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::file_save)); + Connect (ID_file_properties, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::file_properties)); + Connect (ID_file_quit, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::file_quit)); + Connect (ID_edit_preferences, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::edit_preferences)); + Connect (ID_jobs_make_dcp, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::jobs_make_dcp)); + Connect (ID_jobs_send_dcp_to_tms, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::jobs_send_dcp_to_tms)); + Connect (ID_jobs_show_dcp, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::jobs_show_dcp)); + Connect (ID_jobs_analyse_audio, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::jobs_analyse_audio)); + Connect (ID_help_about, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::help_about)); + + Connect (wxID_ANY, wxEVT_MENU_OPEN, wxMenuEventHandler (Frame::menu_opened)); + + wxPanel* panel = new wxPanel (this); + wxSizer* s = new wxBoxSizer (wxHORIZONTAL); + s->Add (panel, 1, wxEXPAND); + SetSizer (s); + + film_editor = new FilmEditor (film, panel); + film_viewer = new FilmViewer (film, panel); + JobManagerView* job_manager_view = new JobManagerView (panel); + + _top_sizer = new wxBoxSizer (wxHORIZONTAL); + _top_sizer->Add (film_editor, 0, wxALL, 6); + _top_sizer->Add (film_viewer, 1, wxEXPAND | wxALL, 6); + + wxBoxSizer* main_sizer = new wxBoxSizer (wxVERTICAL); + main_sizer->Add (_top_sizer, 2, wxEXPAND | wxALL, 6); + main_sizer->Add (job_manager_view, 1, wxEXPAND | wxALL, 6); + panel->SetSizer (main_sizer); + + set_menu_sensitivity (); + + film_editor->FileChanged.connect (bind (&Frame::file_changed, this, _1)); + if (film) { + file_changed (film->directory ()); + } else { + file_changed (""); + } + + set_film (); + + film_editor->Connect (wxID_ANY, wxEVT_SIZE, wxSizeEventHandler (Frame::film_editor_sized), 0, this); + } + +private: + + void film_editor_sized (wxSizeEvent &) + { + static bool in_layout = false; + if (!in_layout) { + in_layout = true; + _top_sizer->Layout (); + in_layout = false; + } + } + + void menu_opened (wxMenuEvent& ev) + { + if (ev.GetMenu() != jobs_menu) { + return; + } + + bool const have_dcp = film && film->have_dcp(); + jobs_menu->Enable (ID_jobs_send_dcp_to_tms, have_dcp); + jobs_menu->Enable (ID_jobs_show_dcp, have_dcp); + } + + void set_film () + { + film_viewer->set_film (film); + film_editor->set_film (film); + set_menu_sensitivity (); + } + + void file_changed (string f) + { + stringstream s; + s << wx_to_std (_("DCP-o-matic")); + if (!f.empty ()) { + s << " - " << f; + } + + SetTitle (std_to_wx (s.str())); + } + + void file_new (wxCommandEvent &) + { + NewFilmDialog* d = new NewFilmDialog (this); + int const r = d->ShowModal (); + + if (r == wxID_OK) { + + if (boost::filesystem::exists (d->get_path())) { + error_dialog (this, std_to_wx (String::compose (wx_to_std (_("The directory %1 already exists.")), d->get_path().c_str()))); + return; + } + + maybe_save_then_delete_film (); + film.reset (new Film (d->get_path (), false)); + film->log()->set_level (log_level); + film->set_name (boost::filesystem::path (d->get_path()).filename().generic_string()); + set_film (); + } + + d->Destroy (); + } + + void file_open (wxCommandEvent &) + { + wxDirDialog* c = new wxDirDialog (this, _("Select film to open"), wxStandardPaths::Get().GetDocumentsDir(), wxDEFAULT_DIALOG_STYLE | wxDD_DIR_MUST_EXIST); + int r; + while (1) { + r = c->ShowModal (); + if (r == wxID_OK && c->GetPath() == wxStandardPaths::Get().GetDocumentsDir()) { + error_dialog (this, _("You did not select a folder. Make sure that you select a folder before clicking Open.")); + } else { + break; + } + } + + if (r == wxID_OK) { + maybe_save_then_delete_film (); + try { + film.reset (new Film (wx_to_std (c->GetPath ()))); + film->log()->set_level (log_level); + set_film (); + } catch (std::exception& e) { + wxString p = c->GetPath (); + wxCharBuffer b = p.ToUTF8 (); + error_dialog (this, wxString::Format (_("Could not open film at %s (%s)"), p.data(), std_to_wx (e.what()).data())); + } + } + + c->Destroy (); + } + + void file_save (wxCommandEvent &) + { + film->write_metadata (); + } + + void file_properties (wxCommandEvent &) + { + PropertiesDialog* d = new PropertiesDialog (this, film); + d->ShowModal (); + d->Destroy (); + } + + void file_quit (wxCommandEvent &) + { + maybe_save_then_delete_film (); + Close (true); + } + + void edit_preferences (wxCommandEvent &) + { + ConfigDialog* d = new ConfigDialog (this); + d->ShowModal (); + d->Destroy (); + Config::instance()->write (); + } + + void jobs_make_dcp (wxCommandEvent &) + { + JobWrapper::make_dcp (this, film); + } + + void jobs_send_dcp_to_tms (wxCommandEvent &) + { + film->send_dcp_to_tms (); + } + + void jobs_show_dcp (wxCommandEvent &) + { +#ifdef __WXMSW__ + string d = film->directory(); + wstring w; + w.assign (d.begin(), d.end()); + ShellExecute (0, L"open", w.c_str(), 0, 0, SW_SHOWDEFAULT); +#else + int r = system ("which nautilus"); + if (WEXITSTATUS (r) == 0) { + system (string ("nautilus " + film->directory()).c_str ()); + } else { + int r = system ("which konqueror"); + if (WEXITSTATUS (r) == 0) { + system (string ("konqueror " + film->directory()).c_str ()); + } + } +#endif + } + + void jobs_analyse_audio (wxCommandEvent &) + { + film->analyse_audio (); + } + + void help_about (wxCommandEvent &) + { + wxAboutDialogInfo info; + info.SetName (_("DCP-o-matic")); + if (strcmp (dcpomatic_git_commit, "release") == 0) { + info.SetVersion (std_to_wx (String::compose ("version %1", dcpomatic_version))); + } else { + info.SetVersion (std_to_wx (String::compose ("version %1 git %2", dcpomatic_version, dcpomatic_git_commit))); + } + info.SetDescription (_("Free, open-source DCP generation from almost anything.")); + info.SetCopyright (_("(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen")); + + wxArrayString authors; + authors.Add (wxT ("Carl Hetherington")); + authors.Add (wxT ("Terrence Meiczinger")); + authors.Add (wxT ("Paul Davis")); + authors.Add (wxT ("Ole Laursen")); + info.SetDevelopers (authors); + + wxArrayString translators; + translators.Add (wxT ("Olivier Perriere")); + translators.Add (wxT ("Lilian Lefranc")); + translators.Add (wxT ("Thierry Journet")); + translators.Add (wxT ("Massimiliano Broggi")); + translators.Add (wxT ("Manuel AC")); + translators.Add (wxT ("Adam Klotblixt")); + info.SetTranslators (translators); + + info.SetWebSite (wxT ("http://carlh.net/software/dcpomatic")); + wxAboutBox (info); + } + + wxSizer* _top_sizer; +}; + +#if wxMINOR_VERSION == 9 +static const wxCmdLineEntryDesc command_line_description[] = { + { wxCMD_LINE_OPTION, "l", "log", "set log level (silent, verbose or timing)", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL }, + { wxCMD_LINE_SWITCH, "n", "new", "create new film", wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL }, + { wxCMD_LINE_PARAM, 0, 0, "film to load or create", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE | wxCMD_LINE_PARAM_OPTIONAL }, + { wxCMD_LINE_NONE, "", "", "", wxCmdLineParamType (0), 0 } +}; +#else +static const wxCmdLineEntryDesc command_line_description[] = { + { wxCMD_LINE_OPTION, wxT("l"), wxT("log"), wxT("set log level (silent, verbose or timing)"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL }, + { wxCMD_LINE_SWITCH, wxT("n"), wxT("new"), wxT("create new film"), wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL }, + { wxCMD_LINE_PARAM, 0, 0, wxT("film to load or create"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE | wxCMD_LINE_PARAM_OPTIONAL }, + { wxCMD_LINE_NONE, wxT(""), wxT(""), wxT(""), wxCmdLineParamType (0), 0 } +}; +#endif + +void +setup_i18n () +{ + int language = wxLANGUAGE_DEFAULT; + + if (Config::instance()->language()) { + wxLanguageInfo const * li = wxLocale::FindLanguageInfo (std_to_wx (Config::instance()->language().get())); + if (li) { + language = li->Language; + } + } + + if (wxLocale::IsAvailable (language)) { + locale = new wxLocale (language, wxLOCALE_LOAD_DEFAULT); + +#ifdef DCPOMATIC_WINDOWS + locale->AddCatalogLookupPathPrefix (std_to_wx (mo_path().string())); +#endif + + locale->AddCatalog (wxT ("libdcpomatic-wx")); + locale->AddCatalog (wxT ("dcpomatic")); + + if (!locale->IsOk()) { + delete locale; + locale = new wxLocale (wxLANGUAGE_ENGLISH); + language = wxLANGUAGE_ENGLISH; + } + } + + if (locale) { + dcpomatic_setup_i18n (wx_to_std (locale->GetCanonicalName ())); + } +} + +class App : public wxApp +{ + bool OnInit () + { + if (!wxApp::OnInit()) { + return false; + } + +#ifdef DCPOMATIC_POSIX + unsetenv ("UBUNTU_MENUPROXY"); +#endif + + wxInitAllImageHandlers (); + + /* Enable i18n; this will create a Config object + to look for a force-configured language. This Config + object will be wrong, however, because dcpomatic_setup + hasn't yet been called and there aren't any scalers, filters etc. + set up yet. + */ + setup_i18n (); + + /* Set things up, including scalers / filters etc. + which will now be internationalised correctly. + */ + dcpomatic_setup (); + + /* Force the configuration to be re-loaded correctly next + time it is needed. + */ + Config::drop (); + + if (!film_to_load.empty() && boost::filesystem::is_directory (film_to_load)) { + try { + film.reset (new Film (film_to_load)); + film->log()->set_level (log_level); + } catch (exception& e) { + error_dialog (0, std_to_wx (String::compose (wx_to_std (_("Could not load film %1 (%2)")), film_to_load, e.what()))); + } + } + + if (!film_to_create.empty ()) { + film.reset (new Film (film_to_create, false)); + film->log()->set_level (log_level); + film->set_name (boost::filesystem::path (film_to_create).filename().generic_string ()); + } + + Frame* f = new Frame (_("DCP-o-matic")); + SetTopWindow (f); + f->Maximize (); + f->Show (); + + ui_signaller = new wxUISignaller (this); + this->Connect (-1, wxEVT_IDLE, wxIdleEventHandler (App::idle)); + + return true; + } + + void OnInitCmdLine (wxCmdLineParser& parser) + { + parser.SetDesc (command_line_description); + parser.SetSwitchChars (wxT ("-")); + } + + bool OnCmdLineParsed (wxCmdLineParser& parser) + { + if (parser.GetParamCount() > 0) { + if (parser.Found (wxT ("new"))) { + film_to_create = wx_to_std (parser.GetParam (0)); + } else { + film_to_load = wx_to_std (parser.GetParam(0)); + } + } + + wxString log; + if (parser.Found (wxT ("log"), &log)) { + log_level = wx_to_std (log); + } + + return true; + } + + void idle (wxIdleEvent &) + { + ui_signaller->ui_idle (); + } +}; + +IMPLEMENT_APP (App) diff --git a/windows/dcpomatic.bmp b/windows/dcpomatic.bmp new file mode 100644 index 000000000..0a196f7a0 Binary files /dev/null and b/windows/dcpomatic.bmp differ diff --git a/windows/dcpomatic.ico b/windows/dcpomatic.ico new file mode 100644 index 000000000..225008cfe Binary files /dev/null and b/windows/dcpomatic.ico differ diff --git a/windows/dcpomatic.rc b/windows/dcpomatic.rc new file mode 100644 index 000000000..3963873bc --- /dev/null +++ b/windows/dcpomatic.rc @@ -0,0 +1,3 @@ +id ICON "dcpomatic.ico" +taskbar_icon ICON "dcpomatic_taskbar.ico" +#include "wx-2.9/wx/msw/wx.rc" diff --git a/windows/dcpomatic_taskbar.ico b/windows/dcpomatic_taskbar.ico new file mode 100644 index 000000000..f4489fa14 Binary files /dev/null and b/windows/dcpomatic_taskbar.ico differ -- cgit v1.2.3 From 50dd871c5a924660499b3fd599f1c68af5e3dbc1 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 14 Apr 2013 14:24:07 +0100 Subject: Fix Playlist::has_audio(). --- src/lib/playlist.cc | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index 7fe4fb2a5..f04bbe0cb 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -182,8 +182,18 @@ Playlist::video_length () const bool Playlist::has_audio () const { - /* XXX */ - return true; + if (!_sndfile.empty ()) { + return true; + } + + for (list >::const_iterator i = _video.begin(); i != _video.end(); ++i) { + shared_ptr fc = dynamic_pointer_cast (*i); + if (fc && fc->audio_stream ()) { + return true; + } + } + + return false; } void -- cgit v1.2.3 From 3b85509d3bda75c2402327fbbe55ad008c57df71 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 14 Apr 2013 23:40:15 +0100 Subject: Try to fix path. --- src/tools/dvdomatic.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 3628fd450..6c7da4610 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -460,7 +460,7 @@ setup_i18n () { int language = wxLANGUAGE_DEFAULT; - ofstream f ("c:/users/carl/foo", std::ios::app); + ofstream f ("c:/users/carl hetherington/foo", std::ios::app); f << "Hello.\n"; if (Config::instance()->language()) { -- cgit v1.2.3 From 9fcaaf1cc7582598b06f5a43878cbd9aa2b4ff17 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 14 Apr 2013 23:41:57 +0100 Subject: Add Trimmer class; not linked in. --- src/lib/trimmer.cc | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/trimmer.h | 39 +++++++++++++++++++++ src/lib/writer.cc | 13 +++++-- src/lib/wscript | 1 + test/metadata.ref | 1 + test/test.cc | 51 +++++++++++++++++++++++++++ 6 files changed, 202 insertions(+), 3 deletions(-) create mode 100644 src/lib/trimmer.cc create mode 100644 src/lib/trimmer.h (limited to 'src') diff --git a/src/lib/trimmer.cc b/src/lib/trimmer.cc new file mode 100644 index 000000000..68364e50a --- /dev/null +++ b/src/lib/trimmer.cc @@ -0,0 +1,100 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include "trimmer.h" + +using std::cout; +using std::max; +using boost::shared_ptr; + +/** @param audio_sample_rate Audio sampling rate, or 0 if there is no audio */ +Trimmer::Trimmer ( + shared_ptr log, + int video_trim_start, + int video_trim_end, int video_length, + int audio_sample_rate, + float frames_per_second, + int dcp_frames_per_second + ) + : AudioVideoProcessor (log) + , _video_start (video_trim_start) + , _video_end (video_length - video_trim_end) + , _video_in (0) + , _audio_in (0) +{ + FrameRateConversion frc (frames_per_second, dcp_frames_per_second); + + if (frc.skip) { + _video_start /= 2; + _video_end /= 2; + } else if (frc.repeat) { + _video_start *= 2; + _video_end *= 2; + } + + if (audio_sample_rate) { + _audio_start = video_frames_to_audio_frames (_video_start, audio_sample_rate, frames_per_second); + _audio_end = video_frames_to_audio_frames (_video_end, audio_sample_rate, frames_per_second); + } +} + +void +Trimmer::process_video (shared_ptr image, bool same, shared_ptr sub) +{ + if (_video_in >= _video_start && _video_in <= _video_end) { + Video (image, same, sub); + } + + ++_video_in; +} + +void +Trimmer::process_audio (shared_ptr audio) +{ + int64_t offset = _audio_start - _audio_in; + if (offset > audio->frames()) { + _audio_in += audio->frames (); + return; + } + + if (offset < 0) { + offset = 0; + } + + int64_t length = _audio_end - max (_audio_in, _audio_start); + if (length < 0) { + _audio_in += audio->frames (); + return; + } + + if (length > (audio->frames() - offset)) { + length = audio->frames () - offset; + } + + _audio_in += audio->frames (); + + if (offset != 0 || length != audio->frames ()) { + audio->move (offset, 0, length); + audio->set_frames (length); + } + + Audio (audio); +} + diff --git a/src/lib/trimmer.h b/src/lib/trimmer.h new file mode 100644 index 000000000..ff7e9514d --- /dev/null +++ b/src/lib/trimmer.h @@ -0,0 +1,39 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "processor.h" + +class Trimmer : public AudioVideoProcessor +{ +public: + Trimmer (boost::shared_ptr, int, int, int, int, float, int); + + void process_video (boost::shared_ptr i, bool, boost::shared_ptr s); + void process_audio (boost::shared_ptr); + +private: + friend class trimmer_test; + + int _video_start; + int _video_end; + int _video_in; + int64_t _audio_start; + int64_t _audio_end; + int64_t _audio_in; +}; diff --git a/src/lib/writer.cc b/src/lib/writer.cc index c6ce4711d..ad81686d1 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -259,9 +259,14 @@ Writer::finish () } int const frames = _last_written_frame + 1; - int const duration = frames - _film->trim_start() - _film->trim_end(); + int duration = 0; + if (_film->trim_type() == Film::CPL) { + duration = frames - _film->trim_start() - _film->trim_end(); + _picture_asset->set_entry_point (_film->trim_start ()); + } else { + duration = frames; + } - _picture_asset->set_entry_point (_film->trim_start ()); _picture_asset->set_duration (duration); /* Hard-link the video MXF into the DCP */ @@ -288,7 +293,9 @@ Writer::finish () _picture_asset->set_file_name (_film->dcp_video_mxf_filename ()); if (_sound_asset) { - _sound_asset->set_entry_point (_film->trim_start ()); + if (_film->trim_type() == Film::CPL) { + _sound_asset->set_entry_point (_film->trim_start ()); + } _sound_asset->set_duration (duration); } diff --git a/src/lib/wscript b/src/lib/wscript index 8e9d34706..51b103afd 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -45,6 +45,7 @@ sources = """ timer.cc transcode_job.cc transcoder.cc + trimmer.cc ui_signaller.cc util.cc video_decoder.cc diff --git a/test/metadata.ref b/test/metadata.ref index 16e3837c8..b7a031883 100644 --- a/test/metadata.ref +++ b/test/metadata.ref @@ -14,6 +14,7 @@ filter unsharp scaler bicubic trim_start 42 trim_end 99 +trim_type cpl dcp_ab 1 use_content_audio 1 audio_gain 0 diff --git a/test/test.cc b/test/test.cc index 6fad0986b..ac7ab85fe 100644 --- a/test/test.cc +++ b/test/test.cc @@ -40,6 +40,7 @@ #include "scaler.h" #include "ffmpeg_decoder.h" #include "sndfile_decoder.h" +#include "trimmer.h" #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MODULE dvdomatic_test #include @@ -123,6 +124,55 @@ BOOST_AUTO_TEST_CASE (make_black_test) } } +shared_ptr trimmer_test_last; + +void +trimmer_test_helper (shared_ptr audio) +{ + trimmer_test_last = audio; +} + +/** Test the audio handling of the Trimmer */ +BOOST_AUTO_TEST_CASE (trimmer_test) +{ + Trimmer trimmer (shared_ptr (), 25, 75, 200, 48000, 25, 25); + + trimmer.Audio.connect (bind (&trimmer_test_helper, _1)); + + /* 21 video frames-worth of audio frames; should be completely stripped */ + trimmer_test_last.reset (); + shared_ptr audio (new AudioBuffers (6, 21 * 1920)); + trimmer.process_audio (audio); + BOOST_CHECK (trimmer_test_last == 0); + + /* 42 more video frames-worth, 4 should be stripped from the start */ + audio.reset (new AudioBuffers (6, 42 * 1920)); + trimmer.process_audio (audio); + BOOST_CHECK (trimmer_test_last); + BOOST_CHECK_EQUAL (trimmer_test_last->frames(), 38 * 1920); + + /* 42 more video frames-worth, should be kept as-is */ + trimmer_test_last.reset (); + audio.reset (new AudioBuffers (6, 42 * 1920)); + trimmer.process_audio (audio); + BOOST_CHECK (trimmer_test_last); + BOOST_CHECK_EQUAL (trimmer_test_last->frames(), 42 * 1920); + + /* 25 more video frames-worth, 5 should be trimmed from the end */ + trimmer_test_last.reset (); + audio.reset (new AudioBuffers (6, 25 * 1920)); + trimmer.process_audio (audio); + BOOST_CHECK (trimmer_test_last); + BOOST_CHECK_EQUAL (trimmer_test_last->frames(), 20 * 1920); + + /* Now some more; all should be trimmed */ + trimmer_test_last.reset (); + audio.reset (new AudioBuffers (6, 100 * 1920)); + trimmer.process_audio (audio); + BOOST_CHECK (trimmer_test_last == 0); +} + + BOOST_AUTO_TEST_CASE (film_metadata_test) { setup_test_config (); @@ -863,3 +913,4 @@ BOOST_AUTO_TEST_CASE (aligned_image_test) delete t; delete u; } + -- cgit v1.2.3 From 2cc70328d69fab3b08b368e3a2a93ab73c9fba16 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 15 Apr 2013 00:20:56 +0100 Subject: Try to fix problems with empty configured language. --- src/tools/dvdomatic.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 6c7da4610..2dc4c4de1 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -463,9 +463,10 @@ setup_i18n () ofstream f ("c:/users/carl hetherington/foo", std::ios::app); f << "Hello.\n"; - if (Config::instance()->language()) { - f << "Configured language " << Config::instance()->language().get() << "\n"; - wxLanguageInfo const * li = wxLocale::FindLanguageInfo (std_to_wx (Config::instance()->language().get())); + boost::optional config_lang = Config::instance()->language (); + if (config_lang && !config_lang.empty ()) { + f << "Configured language " << config_lang.get() << "\n"; + wxLanguageInfo const * li = wxLocale::FindLanguageInfo (std_to_wx (config_lang.get ())); f << "LanguageInfo " << li << "\n"; if (li) { language = li->Language; -- cgit v1.2.3 From 09a0fa8b6b9af3a333ee1918ee711ccc0f75c781 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 15 Apr 2013 08:25:59 +0100 Subject: Fix typo. --- src/tools/dvdomatic.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 2dc4c4de1..2a995bee8 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -464,7 +464,7 @@ setup_i18n () f << "Hello.\n"; boost::optional config_lang = Config::instance()->language (); - if (config_lang && !config_lang.empty ()) { + if (config_lang && !config_lang->empty ()) { f << "Configured language " << config_lang.get() << "\n"; wxLanguageInfo const * li = wxLocale::FindLanguageInfo (std_to_wx (config_lang.get ())); f << "LanguageInfo " << li << "\n"; -- cgit v1.2.3 From 3f2365fcf3a1ffc50901eb2e4af246aa4c83e272 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 15 Apr 2013 16:24:03 +0100 Subject: Repair very bad merge. Mysterious. --- src/lib/ab_transcoder.cc | 4 ++-- src/lib/audio_decoder.h | 2 +- src/lib/audio_sink.h | 7 +++++++ src/lib/audio_source.cc | 6 ++++++ src/lib/audio_source.h | 12 ++++++++++++ src/lib/combiner.cc | 8 ++++---- src/lib/combiner.h | 6 +++--- src/lib/delay_line.cc | 4 ++-- src/lib/delay_line.h | 4 ++-- src/lib/matcher.cc | 2 +- src/lib/matcher.h | 6 +++--- src/lib/processor.h | 17 +++++++++++++++++ src/lib/sndfile_decoder.cc | 5 +++-- src/lib/transcoder.cc | 9 --------- src/lib/video_decoder.h | 2 +- src/lib/video_sink.h | 12 ++++++++++++ src/lib/video_source.cc | 6 ++++++ src/lib/video_source.h | 23 +++++++++++++++++++++-- 18 files changed, 103 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/lib/ab_transcoder.cc b/src/lib/ab_transcoder.cc index 7db13afcc..6eef397c2 100644 --- a/src/lib/ab_transcoder.cc +++ b/src/lib/ab_transcoder.cc @@ -70,8 +70,8 @@ ABTranscoder::ABTranscoder ( _db.video->set_subtitle_stream (_film_a->subtitle_stream ()); _da.audio->set_audio_stream (_film_a->audio_stream ()); - _da.video->Video.connect (bind (&Combiner::process_video, _combiner, _1, _2, _3)); - _db.video->Video.connect (bind (&Combiner::process_video_b, _combiner, _1, _2, _3)); + _da.video->Video.connect (bind (&Combiner::process_video, _combiner, _1, _2, _3, _4)); + _db.video->Video.connect (bind (&Combiner::process_video_b, _combiner, _1, _2, _3, _4)); _combiner->connect_video (_delay_line); _delay_line->connect_video (_matcher); diff --git a/src/lib/audio_decoder.h b/src/lib/audio_decoder.h index 9bef8e0e7..cfe94b528 100644 --- a/src/lib/audio_decoder.h +++ b/src/lib/audio_decoder.h @@ -31,7 +31,7 @@ /** @class AudioDecoder. * @brief Parent class for audio decoders. */ -class AudioDecoder : public AudioSource, public virtual Decoder +class AudioDecoder : public TimedAudioSource, public virtual Decoder { public: AudioDecoder (boost::shared_ptr, DecodeOptions); diff --git a/src/lib/audio_sink.h b/src/lib/audio_sink.h index 11d578a60..f34b24f88 100644 --- a/src/lib/audio_sink.h +++ b/src/lib/audio_sink.h @@ -27,4 +27,11 @@ public: virtual void process_audio (boost::shared_ptr) = 0; }; +class TimedAudioSink +{ +public: + /** Call with some audio data */ + virtual void process_audio (boost::shared_ptr, double t) = 0; +}; + #endif diff --git a/src/lib/audio_source.cc b/src/lib/audio_source.cc index 53b0dda15..bca3562cf 100644 --- a/src/lib/audio_source.cc +++ b/src/lib/audio_source.cc @@ -28,3 +28,9 @@ AudioSource::connect_audio (shared_ptr s) { Audio.connect (bind (&AudioSink::process_audio, s, _1)); } + +void +TimedAudioSource::connect_audio (shared_ptr s) +{ + Audio.connect (bind (&TimedAudioSink::process_audio, s, _1, _2)); +} diff --git a/src/lib/audio_source.h b/src/lib/audio_source.h index 5a1510d3c..3dc998cca 100644 --- a/src/lib/audio_source.h +++ b/src/lib/audio_source.h @@ -28,6 +28,7 @@ class AudioBuffers; class AudioSink; +class TimedAudioSink; /** A class that emits audio data */ class AudioSource @@ -39,4 +40,15 @@ public: void connect_audio (boost::shared_ptr); }; + +/** A class that emits audio data with timestamps */ +class TimedAudioSource +{ +public: + /** Emitted when some audio data is ready */ + boost::signals2::signal, double)> Audio; + + void connect_audio (boost::shared_ptr); +}; + #endif diff --git a/src/lib/combiner.cc b/src/lib/combiner.cc index 12ce4a96e..006dd2697 100644 --- a/src/lib/combiner.cc +++ b/src/lib/combiner.cc @@ -23,7 +23,7 @@ using boost::shared_ptr; Combiner::Combiner (shared_ptr log) - : VideoProcessor (log) + : TimedVideoProcessor (log) { } @@ -33,7 +33,7 @@ Combiner::Combiner (shared_ptr log) * @param image Frame image. */ void -Combiner::process_video (shared_ptr image, bool, shared_ptr) +Combiner::process_video (shared_ptr image, bool, shared_ptr, double t) { _image = image; } @@ -43,7 +43,7 @@ Combiner::process_video (shared_ptr image, bool, shared_ptr) * @param sub Subtitle (which will be put onto the whole frame) */ void -Combiner::process_video_b (shared_ptr image, bool, shared_ptr sub) +Combiner::process_video_b (shared_ptr image, bool, shared_ptr sub, double t) { /* Copy the right half of this image into our _image */ /* XXX: this should probably be in the Image class */ @@ -62,6 +62,6 @@ Combiner::process_video_b (shared_ptr image, bool, shared_ptr s } } - Video (_image, false, sub); + Video (_image, false, sub, t); _image.reset (); } diff --git a/src/lib/combiner.h b/src/lib/combiner.h index 68026eaff..a8f1fa804 100644 --- a/src/lib/combiner.h +++ b/src/lib/combiner.h @@ -28,13 +28,13 @@ * one image used for the left half of the screen and the other for * the right. */ -class Combiner : public VideoProcessor +class Combiner : public TimedVideoProcessor { public: Combiner (boost::shared_ptr log); - void process_video (boost::shared_ptr i, bool, boost::shared_ptr s); - void process_video_b (boost::shared_ptr i, bool, boost::shared_ptr s); + void process_video (boost::shared_ptr i, bool, boost::shared_ptr s, double); + void process_video_b (boost::shared_ptr i, bool, boost::shared_ptr s, double); private: /** The image that we are currently working on */ diff --git a/src/lib/delay_line.cc b/src/lib/delay_line.cc index c8e593a18..9e6baeba8 100644 --- a/src/lib/delay_line.cc +++ b/src/lib/delay_line.cc @@ -30,14 +30,14 @@ using boost::shared_ptr; /* @param seconds Delay in seconds, +ve to move audio later. */ DelayLine::DelayLine (shared_ptr log, double seconds) - : Processor (log) + : TimedAudioVideoProcessor (log) , _seconds (seconds) { } void -DelayLine::process_audio (shared_ptr data) +DelayLine::process_audio (shared_ptr data, double t) { if (_seconds > 0) { t += _seconds; diff --git a/src/lib/delay_line.h b/src/lib/delay_line.h index 7a8b11c69..90f1dcfa7 100644 --- a/src/lib/delay_line.h +++ b/src/lib/delay_line.h @@ -20,8 +20,8 @@ #include #include "processor.h" -/** A delay line for audio */ -class DelayLine : public Processor, public TimedAudioSink, public TimedAudioSource, public TimedVideoSink, public TimedVideoSource +/** A delay line */ +class DelayLine : public TimedAudioVideoProcessor { public: DelayLine (boost::shared_ptr log, double); diff --git a/src/lib/matcher.cc b/src/lib/matcher.cc index 69d12e2c4..34ddc86d6 100644 --- a/src/lib/matcher.cc +++ b/src/lib/matcher.cc @@ -29,7 +29,7 @@ using std::list; using boost::shared_ptr; Matcher::Matcher (shared_ptr log, int sample_rate, float frames_per_second) - : AudioVideoProcessor (log) + : Processor (log) , _sample_rate (sample_rate) , _frames_per_second (frames_per_second) , _video_frames (0) diff --git a/src/lib/matcher.h b/src/lib/matcher.h index 4ec0a3e96..f54aa4b6a 100644 --- a/src/lib/matcher.h +++ b/src/lib/matcher.h @@ -21,12 +21,12 @@ #include "processor.h" #include "ffmpeg_compatibility.h" -class Matcher : public AudioVideoProcessor +class Matcher : public Processor, public TimedAudioSink, public TimedVideoSink, public AudioSource, public VideoSource { public: Matcher (boost::shared_ptr log, int sample_rate, float frames_per_second); - void process_video (boost::shared_ptr i, bool, boost::shared_ptr s); - void process_audio (boost::shared_ptr); + void process_video (boost::shared_ptr i, bool, boost::shared_ptr s, double); + void process_audio (boost::shared_ptr, double); void process_end (); private: diff --git a/src/lib/processor.h b/src/lib/processor.h index 1ba396f2f..603239f8f 100644 --- a/src/lib/processor.h +++ b/src/lib/processor.h @@ -67,6 +67,15 @@ public: {} }; +class TimedAudioVideoProcessor : public Processor, public TimedVideoSource, public TimedVideoSink, public TimedAudioSource, public TimedAudioSink +{ +public: + TimedAudioVideoProcessor (boost::shared_ptr log) + : Processor (log) + {} +}; + + /** @class AudioProcessor * @brief A processor which handles just audio data. */ @@ -95,4 +104,12 @@ public: {} }; +class TimedVideoProcessor : public Processor, public TimedVideoSource, public TimedVideoSink +{ +public: + TimedVideoProcessor (boost::shared_ptr log) + : Processor (log) + {} +}; + #endif diff --git a/src/lib/sndfile_decoder.cc b/src/lib/sndfile_decoder.cc index 0e3e5e234..af59c049c 100644 --- a/src/lib/sndfile_decoder.cc +++ b/src/lib/sndfile_decoder.cc @@ -113,8 +113,8 @@ SndfileDecoder::pass () to what FFmpeg (and in particular the resampler) can cope with. */ sf_count_t const block = _audio_stream->sample_rate() / 2; - shared_ptr audio (new AudioBuffers (_audio_stream->channels(), block)); + sf_count_t done = 0; while (frames > 0) { sf_count_t const this_time = min (block, frames); for (size_t i = 0; i < sndfiles.size(); ++i) { @@ -126,7 +126,8 @@ SndfileDecoder::pass () } audio->set_frames (this_time); - Audio (audio); + Audio (audio, double(done) / _audio_stream->sample_rate()); + done += this_time; frames -= this_time; } diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc index 8046080de..23fb5b788 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -63,18 +63,9 @@ Transcoder::Transcoder (shared_ptr f, DecodeOptions o, Job* j, shared_ptr< _decoders.video->set_subtitle_stream (f->subtitle_stream ()); _decoders.audio->set_audio_stream (f->audio_stream ()); -<<<<<<< HEAD _decoders.video->connect_video (_delay_line); _delay_line->connect_video (_matcher); _matcher->connect_video (_encoder); -======= - if (_matcher) { - _decoders.video->connect_video (_matcher); - _matcher->connect_video (_encoder); - } else { - _decoders.video->connect_video (_encoder); - } ->>>>>>> master _decoders.audio->connect_audio (_delay_line); _delay_line->connect_audio (_matcher); diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h index f8612dff2..6e4fd48c0 100644 --- a/src/lib/video_decoder.h +++ b/src/lib/video_decoder.h @@ -24,7 +24,7 @@ #include "stream.h" #include "decoder.h" -class VideoDecoder : public VideoSource, public virtual Decoder +class VideoDecoder : public TimedVideoSource, public virtual Decoder { public: VideoDecoder (boost::shared_ptr, DecodeOptions); diff --git a/src/lib/video_sink.h b/src/lib/video_sink.h index 7c128cf73..32c7f3b38 100644 --- a/src/lib/video_sink.h +++ b/src/lib/video_sink.h @@ -37,4 +37,16 @@ public: virtual void process_video (boost::shared_ptr i, bool same, boost::shared_ptr s) = 0; }; +class TimedVideoSink +{ +public: + /** Call with a frame of video. + * @param i Video frame image. + * @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. + * @param t Source timestamp. + */ + virtual void process_video (boost::shared_ptr i, bool same, boost::shared_ptr s, double t) = 0; +}; + #endif diff --git a/src/lib/video_source.cc b/src/lib/video_source.cc index 56742e2b4..af6f941fd 100644 --- a/src/lib/video_source.cc +++ b/src/lib/video_source.cc @@ -28,3 +28,9 @@ VideoSource::connect_video (shared_ptr s) { Video.connect (bind (&VideoSink::process_video, s, _1, _2, _3)); } + +void +TimedVideoSource::connect_video (shared_ptr s) +{ + Video.connect (bind (&TimedVideoSink::process_video, s, _1, _2, _3, _4)); +} diff --git a/src/lib/video_source.h b/src/lib/video_source.h index 893629160..705b0023a 100644 --- a/src/lib/video_source.h +++ b/src/lib/video_source.h @@ -29,11 +29,12 @@ #include "util.h" class VideoSink; +class TimedVideoSink; class Subtitle; class Image; -/** @class VideoSink - * @param A class that emits video data. +/** @class VideoSource + * @param A class that emits video data without timestamps. */ class VideoSource { @@ -49,4 +50,22 @@ public: void connect_video (boost::shared_ptr); }; +/** @class TimedVideoSource + * @param A class that emits video data with timestamps. + */ +class TimedVideoSource +{ +public: + + /** Emitted when a video frame is ready. + * First parameter is the video image. + * 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. + * Fourth parameter is the source timestamp of this frame. + */ + boost::signals2::signal, bool, boost::shared_ptr, double)> Video; + + void connect_video (boost::shared_ptr); +}; + #endif -- cgit v1.2.3 From 8ef3014198e46957d0a79d4e006e5f82a345bfa7 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 15 Apr 2013 21:36:23 +0100 Subject: Set language for English rather than just using blank string. --- src/wx/config_dialog.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/wx/config_dialog.cc b/src/wx/config_dialog.cc index 1d025f3fa..c32b03ec0 100644 --- a/src/wx/config_dialog.cc +++ b/src/wx/config_dialog.cc @@ -226,7 +226,7 @@ ConfigDialog::language_changed (wxCommandEvent &) { switch (_language->GetSelection ()) { case 0: - Config::instance()->set_language (""); + Config::instance()->set_language ("en"); break; case 1: Config::instance()->set_language ("fr"); -- cgit v1.2.3 From a4a30d3a84998801fd6132da2d9ce789351c5a8e Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 16 Apr 2013 12:28:15 +0100 Subject: Fix setup of resampler channel counts. --- src/lib/encoder.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 3201e6ecb..f56440dd7 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -93,13 +93,13 @@ Encoder::process_begin () decide if rematrixing is needed. It won't be, since input and output layouts are the same. */ - + _swr_context = swr_alloc_set_opts ( 0, - av_get_default_channel_layout (_film->audio_channels ()), + av_get_default_channel_layout (_film->audio_mapping().dcp_channels ()), AV_SAMPLE_FMT_FLTP, _film->target_audio_sample_rate(), - av_get_default_channel_layout (_film->audio_channels ()), + av_get_default_channel_layout (_film->audio_mapping().dcp_channels ()), AV_SAMPLE_FMT_FLTP, _film->audio_frame_rate(), 0, 0 -- cgit v1.2.3 From 4a3d017ef63c1442e00954c0c222b66ab51a4ee9 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 19 Apr 2013 00:28:10 +0100 Subject: Fix warning. --- src/lib/combiner.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/combiner.cc b/src/lib/combiner.cc index 006dd2697..0a9eaf6b6 100644 --- a/src/lib/combiner.cc +++ b/src/lib/combiner.cc @@ -33,7 +33,7 @@ Combiner::Combiner (shared_ptr log) * @param image Frame image. */ void -Combiner::process_video (shared_ptr image, bool, shared_ptr, double t) +Combiner::process_video (shared_ptr image, bool, shared_ptr, double) { _image = image; } -- cgit v1.2.3 From c9375d572f6e508f4d6a3c039d3827ef44407c1a Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 19 Apr 2013 21:20:00 +0100 Subject: Write metadata on new film to go with the directory that is created. --- src/lib/film.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/lib/film.cc b/src/lib/film.cc index a42b874e8..227f8557b 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -143,6 +143,8 @@ Film::Film (string d, bool must_exist) if (must_exist) { read_metadata (); + } else { + write_metadata (); } _log.reset (new FileLog (file ("log"))); -- cgit v1.2.3 From f2989966b2871ac5fc5f78c2a3ce7867f344b7cd Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 19 Apr 2013 22:10:10 +0100 Subject: Basic frame index and timecode (part of #68). --- ChangeLog | 2 ++ src/wx/film_viewer.cc | 24 ++++++++++++++++++++++++ src/wx/film_viewer.h | 2 ++ 3 files changed, 28 insertions(+) (limited to 'src') diff --git a/ChangeLog b/ChangeLog index fb526efd1..12890135c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2013-04-19 Carl Hetherington + * Add basic frame index and timecode to viewer (part of #68). + * Version 0.84beta4 released. 2013-04-19 Carl Hetherington diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 40b74ac39..00f895285 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -51,6 +51,8 @@ FilmViewer::FilmViewer (shared_ptr f, wxWindow* p) : wxPanel (p) , _panel (new wxPanel (this)) , _slider (new wxSlider (this, wxID_ANY, 0, 0, 4096)) + , _frame (new wxStaticText (this, wxID_ANY, wxT(""))) + , _timecode (new wxStaticText (this, wxID_ANY, wxT(""))) , _play_button (new wxToggleButton (this, wxID_ANY, _("Play"))) , _display_frame_x (0) , _got_frame (false) @@ -66,11 +68,19 @@ FilmViewer::FilmViewer (shared_ptr f, wxWindow* p) _v_sizer->Add (_panel, 1, wxEXPAND); wxBoxSizer* h_sizer = new wxBoxSizer (wxHORIZONTAL); + + wxBoxSizer* time_sizer = new wxBoxSizer (wxVERTICAL); + time_sizer->Add (_frame, 0, wxEXPAND); + time_sizer->Add (_timecode, 0, wxEXPAND); + + h_sizer->Add (time_sizer, 0, wxEXPAND); h_sizer->Add (_play_button, 0, wxEXPAND); h_sizer->Add (_slider, 1, wxEXPAND); _v_sizer->Add (h_sizer, 0, wxEXPAND | wxALL, 6); + _frame->SetMinSize (wxSize (84, -1)); + _panel->Connect (wxID_ANY, wxEVT_PAINT, wxPaintEventHandler (FilmViewer::paint_panel), 0, this); _panel->Connect (wxID_ANY, wxEVT_SIZE, wxSizeEventHandler (FilmViewer::panel_sized), 0, this); _slider->Connect (wxID_ANY, wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler (FilmViewer::slider_moved), 0, this); @@ -390,6 +400,20 @@ FilmViewer::process_video (shared_ptr image, bool, shared_ptr s raw_to_display (); _got_frame = true; + + double const t = _decoders.video->last_source_time (); + double const fps = _decoders.video->frames_per_second (); + _frame->SetLabel (wxString::Format ("%d", int (rint (t * fps)))); + + double w = t; + int const h = (w / 3600); + w -= h * 3600; + int const m = (w / 60); + w -= m * 60; + int const s = floor (w); + w -= s; + int const f = rint (w * fps); + _timecode->SetLabel (wxString::Format ("%02d:%02d:%02d:%02d", h, m, s, f)); } void diff --git a/src/wx/film_viewer.h b/src/wx/film_viewer.h index 784434f6b..859bf7ede 100644 --- a/src/wx/film_viewer.h +++ b/src/wx/film_viewer.h @@ -62,6 +62,8 @@ private: wxSizer* _v_sizer; wxPanel* _panel; wxSlider* _slider; + wxStaticText* _frame; + wxStaticText* _timecode; wxToggleButton* _play_button; wxTimer _timer; -- cgit v1.2.3 From 45747c8dce6448cc6b6c797ae04f3e5fc3b741e8 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 20 Apr 2013 02:18:23 +0100 Subject: Fix for 2.8. --- src/wx/film_viewer.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 00f895285..fe2025b78 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -403,7 +403,7 @@ FilmViewer::process_video (shared_ptr image, bool, shared_ptr s double const t = _decoders.video->last_source_time (); double const fps = _decoders.video->frames_per_second (); - _frame->SetLabel (wxString::Format ("%d", int (rint (t * fps)))); + _frame->SetLabel (wxString::Format (wxT("%d"), int (rint (t * fps)))); double w = t; int const h = (w / 3600); @@ -413,7 +413,7 @@ FilmViewer::process_video (shared_ptr image, bool, shared_ptr s int const s = floor (w); w -= s; int const f = rint (w * fps); - _timecode->SetLabel (wxString::Format ("%02d:%02d:%02d:%02d", h, m, s, f)); + _timecode->SetLabel (wxString::Format (wxT("%02d:%02d:%02d:%02d"), h, m, s, f)); } void -- cgit v1.2.3 From 98499a61e17e68c438e56fd8854081a4c98b15ad Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 20 Apr 2013 02:26:23 +0100 Subject: Somewhat hacky but seemingly functional frame back/forward (rest of #68). --- src/lib/decoder.h | 2 ++ src/lib/ffmpeg_decoder.cc | 46 +++++++++++++++++++++++++++++++++++++++++----- src/lib/ffmpeg_decoder.h | 4 +++- src/lib/format.cc | 2 +- src/wx/film_viewer.cc | 40 ++++++++++++++++++++++++++++++++++++---- src/wx/film_viewer.h | 6 +++++- 6 files changed, 88 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/lib/decoder.h b/src/lib/decoder.h index f2f523516..2bc462c33 100644 --- a/src/lib/decoder.h +++ b/src/lib/decoder.h @@ -59,6 +59,8 @@ public: virtual bool pass () = 0; virtual bool seek (double); virtual bool seek_to_last (); + virtual void seek_back () {} + virtual void seek_forward () {} boost::signals2::signal OutputChanged; diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 2d7092789..7c88c3c35 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -530,7 +530,7 @@ FFmpegDecoder::filter_and_emit_video () bool FFmpegDecoder::seek (double p) { - return do_seek (p, false); + return do_seek (p, false, false); } bool @@ -540,21 +540,57 @@ FFmpegDecoder::seek_to_last () (used when we change decoder parameters and want to re-fetch the frame) we end up going forwards rather than staying in the same place. */ - return do_seek (last_source_time(), true); + return do_seek (last_source_time(), true, false); +} + +void +FFmpegDecoder::seek_back () +{ + do_seek (last_source_time() - 2.5 / frames_per_second (), true, true); +} + +void +FFmpegDecoder::seek_forward () +{ + do_seek (last_source_time() - 0.5 / frames_per_second(), true, true); } bool -FFmpegDecoder::do_seek (double p, bool backwards) +FFmpegDecoder::do_seek (double p, bool backwards, bool accurate) { int64_t const vt = p / av_q2d (_format_context->streams[_video_stream]->time_base); int const r = av_seek_frame (_format_context, _video_stream, vt, backwards ? AVSEEK_FLAG_BACKWARD : 0); - + avcodec_flush_buffers (_video_codec_context); if (_subtitle_codec_context) { avcodec_flush_buffers (_subtitle_codec_context); } - + + if (accurate) { + while (1) { + int r = av_read_frame (_format_context, &_packet); + if (r < 0) { + return true; + } + + avcodec_get_frame_defaults (_frame); + + if (_packet.stream_index == _video_stream) { + int finished = 0; + int const r = avcodec_decode_video2 (_video_codec_context, _frame, &finished, &_packet); + if (r >= 0 && finished) { + int64_t const bet = av_frame_get_best_effort_timestamp (_frame); + if (bet > vt) { + break; + } + } + } + + av_free_packet (&_packet); + } + } + return r < 0; } diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h index 2a4d40b1d..0c89b973d 100644 --- a/src/lib/ffmpeg_decoder.h +++ b/src/lib/ffmpeg_decoder.h @@ -102,11 +102,13 @@ public: bool seek (double); bool seek_to_last (); + void seek_forward (); + void seek_back (); private: bool pass (); - bool do_seek (double p, bool); + bool do_seek (double p, bool, bool); PixelFormat pixel_format () const; AVSampleFormat audio_sample_format () const; int bytes_per_audio_sample () const; diff --git a/src/lib/format.cc b/src/lib/format.cc index 640eee167..8c3d0d8ad 100644 --- a/src/lib/format.cc +++ b/src/lib/format.cc @@ -50,7 +50,7 @@ FixedFormat::name () const s << _nickname << N_(" ("); } - s << setprecision(3) << (_ratio / 100.0) << N_(":1"); + s << setprecision(3) << _ratio << N_(":1"); if (!_nickname.empty ()) { s << N_(")"); diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 00f895285..5770c5b70 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -51,6 +51,8 @@ FilmViewer::FilmViewer (shared_ptr f, wxWindow* p) : wxPanel (p) , _panel (new wxPanel (this)) , _slider (new wxSlider (this, wxID_ANY, 0, 0, 4096)) + , _back_button (new wxButton (this, wxID_ANY, wxT("<"))) + , _forward_button (new wxButton (this, wxID_ANY, wxT(">"))) , _frame (new wxStaticText (this, wxID_ANY, wxT(""))) , _timecode (new wxStaticText (this, wxID_ANY, wxT(""))) , _play_button (new wxToggleButton (this, wxID_ANY, _("Play"))) @@ -72,14 +74,18 @@ FilmViewer::FilmViewer (shared_ptr f, wxWindow* p) wxBoxSizer* time_sizer = new wxBoxSizer (wxVERTICAL); time_sizer->Add (_frame, 0, wxEXPAND); time_sizer->Add (_timecode, 0, wxEXPAND); - + + h_sizer->Add (_back_button, 0, wxALL, 2); h_sizer->Add (time_sizer, 0, wxEXPAND); + h_sizer->Add (_forward_button, 0, wxALL, 2); h_sizer->Add (_play_button, 0, wxEXPAND); h_sizer->Add (_slider, 1, wxEXPAND); _v_sizer->Add (h_sizer, 0, wxEXPAND | wxALL, 6); _frame->SetMinSize (wxSize (84, -1)); + _back_button->SetMinSize (wxSize (32, -1)); + _forward_button->SetMinSize (wxSize (32, -1)); _panel->Connect (wxID_ANY, wxEVT_PAINT, wxPaintEventHandler (FilmViewer::paint_panel), 0, this); _panel->Connect (wxID_ANY, wxEVT_SIZE, wxSizeEventHandler (FilmViewer::panel_sized), 0, this); @@ -88,6 +94,8 @@ FilmViewer::FilmViewer (shared_ptr f, wxWindow* p) _slider->Connect (wxID_ANY, wxEVT_SCROLL_PAGEDOWN, wxScrollEventHandler (FilmViewer::slider_moved), 0, this); _play_button->Connect (wxID_ANY, wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler (FilmViewer::play_clicked), 0, this); _timer.Connect (wxID_ANY, wxEVT_TIMER, wxTimerEventHandler (FilmViewer::timer), 0, this); + _back_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmViewer::back_clicked), 0, this); + _forward_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmViewer::forward_clicked), 0, this); set_film (f); @@ -121,7 +129,7 @@ FilmViewer::film_changed (Film::Property p) if (_decoders.video == 0) { break; } - _decoders.video->Video.connect (bind (&FilmViewer::process_video, this, _1, _2, _3)); + _decoders.video->Video.connect (bind (&FilmViewer::process_video, this, _1, _2, _3, _4)); _decoders.video->OutputChanged.connect (boost::bind (&FilmViewer::decoder_changed, this)); _decoders.video->set_subtitle_stream (_film->subtitle_stream()); calculate_sizes (); @@ -392,7 +400,7 @@ FilmViewer::check_play_state () } void -FilmViewer::process_video (shared_ptr image, bool, shared_ptr sub) +FilmViewer::process_video (shared_ptr image, bool, shared_ptr sub, double t) { _raw_frame = image; _raw_sub = sub; @@ -401,7 +409,6 @@ FilmViewer::process_video (shared_ptr image, bool, shared_ptr s _got_frame = true; - double const t = _decoders.video->last_source_time (); double const fps = _decoders.video->frames_per_second (); _frame->SetLabel (wxString::Format ("%d", int (rint (t * fps)))); @@ -465,3 +472,28 @@ FilmViewer::active_jobs_changed (bool a) _play_button->Enable (!a); } +void +FilmViewer::back_clicked (wxCommandEvent &) +{ + if (!_decoders.video) { + return; + } + + _decoders.video->seek_back (); + get_frame (); + _panel->Refresh (); + _panel->Update (); +} + +void +FilmViewer::forward_clicked (wxCommandEvent &) +{ + if (!_decoders.video) { + return; + } + + _decoders.video->seek_forward (); + get_frame (); + _panel->Refresh (); + _panel->Update (); +} diff --git a/src/wx/film_viewer.h b/src/wx/film_viewer.h index 859bf7ede..a78c772a4 100644 --- a/src/wx/film_viewer.h +++ b/src/wx/film_viewer.h @@ -48,7 +48,7 @@ private: void slider_moved (wxScrollEvent &); void play_clicked (wxCommandEvent &); void timer (wxTimerEvent &); - void process_video (boost::shared_ptr, bool, boost::shared_ptr); + void process_video (boost::shared_ptr, bool, boost::shared_ptr, double); void calculate_sizes (); void check_play_state (); void update_from_raw (); @@ -56,12 +56,16 @@ private: void raw_to_display (); void get_frame (); void active_jobs_changed (bool); + void back_clicked (wxCommandEvent &); + void forward_clicked (wxCommandEvent &); boost::shared_ptr _film; wxSizer* _v_sizer; wxPanel* _panel; wxSlider* _slider; + wxButton* _back_button; + wxButton* _forward_button; wxStaticText* _frame; wxStaticText* _timecode; wxToggleButton* _play_button; -- cgit v1.2.3 From 2c1533e4e5568a8bb4f538cfb845d07b0637380c Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 20 Apr 2013 02:50:09 +0100 Subject: Be more careful about the validity of s->metadata. --- src/lib/ffmpeg_decoder.cc | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 7c88c3c35..8e09810cb 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -453,18 +453,20 @@ string FFmpegDecoder::stream_name (AVStream* s) const { stringstream n; - - AVDictionaryEntry const * lang = av_dict_get (s->metadata, N_("language"), 0, 0); - if (lang) { - n << lang->value; - } - - AVDictionaryEntry const * title = av_dict_get (s->metadata, N_("title"), 0, 0); - if (title) { - if (!n.str().empty()) { - n << N_(" "); + + if (s->metadata) { + AVDictionaryEntry const * lang = av_dict_get (s->metadata, N_("language"), 0, 0); + if (lang) { + n << lang->value; + } + + AVDictionaryEntry const * title = av_dict_get (s->metadata, N_("title"), 0, 0); + if (title) { + if (!n.str().empty()) { + n << N_(" "); + } + n << title->value; } - n << title->value; } if (n.str().empty()) { -- cgit v1.2.3 From f20cd70a9afc28f785ef4a50c875ccf6c3729462 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 20 Apr 2013 20:45:32 +0100 Subject: Import Ardour's LocaleGuard to fix problems with saving decimals to metadata (#119). --- ChangeLog | 5 +++++ src/lib/film.cc | 3 +++ src/lib/util.cc | 19 +++++++++++++++++++ src/lib/util.h | 11 +++++++++++ 4 files changed, 38 insertions(+) (limited to 'src') diff --git a/ChangeLog b/ChangeLog index 85cdb48a6..0fbb73773 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-04-20 Carl Hetherington + + * Fix bad saving of metadata in locales which use + commas to separate decimals (#119). + 2013-04-19 Carl Hetherington * Add basic frame index and timecode to viewer, and previous/next diff --git a/src/lib/film.cc b/src/lib/film.cc index 227f8557b..b0785df34 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -204,6 +204,7 @@ string Film::video_state_identifier () const { assert (format ()); + LocaleGuard lg; pair f = Filter::ffmpeg_strings (filters()); @@ -428,6 +429,7 @@ void Film::write_metadata () const { boost::mutex::scoped_lock lm (_state_mutex); + LocaleGuard lg; boost::filesystem::create_directories (directory()); @@ -515,6 +517,7 @@ void Film::read_metadata () { boost::mutex::scoped_lock lm (_state_mutex); + LocaleGuard lg; _external_audio.clear (); _content_audio_streams.clear (); diff --git a/src/lib/util.cc b/src/lib/util.cc index 557e9a34b..e43b598ab 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -1018,3 +1018,22 @@ FrameRateConversion::FrameRateConversion (float source, int dcp) } } } + +LocaleGuard::LocaleGuard () + : _old (0) +{ + char const * old = setlocale (LC_NUMERIC, 0); + + if (old) { + _old = strdup (old); + if (strcmp (_old, "POSIX")) { + setlocale (LC_NUMERIC, "POSIX"); + } + } +} + +LocaleGuard::~LocaleGuard () +{ + setlocale (LC_NUMERIC, _old); + free (_old); +} diff --git a/src/lib/util.h b/src/lib/util.h index 3d251cf06..31d0fc967 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -293,5 +293,16 @@ extern int64_t video_frames_to_audio_frames (SourceFrame v, float audio_sample_r extern bool still_image_file (std::string); extern std::pair cpu_info (); +class LocaleGuard +{ +public: + LocaleGuard (); + ~LocaleGuard (); + +private: + char* _old; +}; + + #endif -- cgit v1.2.3 From 074e70083a115eaac2b593b1c42962ff7e0c3951 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 22 Apr 2013 13:33:20 +0100 Subject: Try to fix it. --- src/lib/transcoder.cc | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc index 23fb5b788..e00b2f1e0 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -55,21 +55,33 @@ Transcoder::Transcoder (shared_ptr f, DecodeOptions o, Job* j, shared_ptr< assert (_encoder); shared_ptr st = f->audio_stream(); - _matcher.reset (new Matcher (f->log(), st->sample_rate(), f->source_frame_rate())); + if (st) { + _matcher.reset (new Matcher (f->log(), st->sample_rate(), f->source_frame_rate())); + } _delay_line.reset (new DelayLine (f->log(), f->audio_delay() / 1000.0f)); _gain.reset (new Gain (f->log(), f->audio_gain())); /* Set up the decoder to use the film's set streams */ _decoders.video->set_subtitle_stream (f->subtitle_stream ()); - _decoders.audio->set_audio_stream (f->audio_stream ()); + if (f->audio_stream ()) { + _decoders.audio->set_audio_stream (f->audio_stream ()); + } _decoders.video->connect_video (_delay_line); - _delay_line->connect_video (_matcher); - _matcher->connect_video (_encoder); + if (_matcher) { + _delay_line->connect_video (_matcher); + _matcher->connect_video (_encoder); + } else { + _delay_line->Video.connect (bind (&Encoder::process_video, _encoder, _1, _2, _3)); + } _decoders.audio->connect_audio (_delay_line); - _delay_line->connect_audio (_matcher); - _matcher->connect_audio (_gain); + if (_matcher) { + _delay_line->connect_audio (_matcher); + _matcher->connect_audio (_gain); + } else { + _delay_line->Audio.connect (bind (&Encoder::process_audio, _encoder, _1)); + } _gain->connect_audio (_encoder); } @@ -108,7 +120,9 @@ Transcoder::go () } _delay_line->process_end (); - _matcher->process_end (); + if (_matcher) { + _matcher->process_end (); + } _gain->process_end (); _encoder->process_end (); } -- cgit v1.2.3 From 8eabffda9a95de36df560c1b6eadd1a7baa852c7 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 22 Apr 2013 15:06:11 +0100 Subject: Fix french message (#125). --- src/lib/po/fr_FR.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/po/fr_FR.po b/src/lib/po/fr_FR.po index d9d945b52..cce92822e 100644 --- a/src/lib/po/fr_FR.po +++ b/src/lib/po/fr_FR.po @@ -51,7 +51,7 @@ msgstr "16:9 dans Flat" #: src/lib/format.cc:115 #, fuzzy msgid "16:9 within Scope" -msgstr "16:9 dans Flat" +msgstr "16:9 dans Scope" #: src/lib/filter.cc:88 msgid "3D denoiser" -- cgit v1.2.3 From 6d278a2db4625cc3b8b7c8d4623e7672aa4c360b Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 22 Apr 2013 15:06:37 +0100 Subject: Merge new pot files. --- src/lib/po/es_ES.po | 51 +++++++++++++----------- src/lib/po/fr_FR.po | 51 +++++++++++++----------- src/lib/po/it_IT.po | 51 +++++++++++++----------- src/lib/po/sv_SE.po | 52 +++++++++++++----------- src/tools/po/es_ES.po | 55 ++++++++++++------------- src/tools/po/fr_FR.po | 55 ++++++++++++------------- src/tools/po/it_IT.po | 55 ++++++++++++------------- src/tools/po/sv_SE.po | 57 +++++++++++++------------- src/wx/po/es_ES.po | 108 ++++++++++++++++++++++++++++---------------------- src/wx/po/fr_FR.po | 108 ++++++++++++++++++++++++++++---------------------- src/wx/po/it_IT.po | 108 ++++++++++++++++++++++++++++---------------------- src/wx/po/sv_SE.po | 108 ++++++++++++++++++++++++++++---------------------- 12 files changed, 462 insertions(+), 397 deletions(-) (limited to 'src') diff --git a/src/lib/po/es_ES.po b/src/lib/po/es_ES.po index 17051bd98..1608f3b0c 100644 --- a/src/lib/po/es_ES.po +++ b/src/lib/po/es_ES.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: LIBDVDOMATIC\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-09 11:14+0100\n" +"POT-Creation-Date: 2013-04-22 15:06+0100\n" "PO-Revision-Date: 2013-04-02 19:10-0500\n" "Last-Translator: Manuel AC \n" "Language-Team: Manuel AC \n" @@ -25,10 +25,6 @@ msgstr "0%" msgid "1.19" msgstr "1.19" -#: src/lib/format.cc:79 -msgid "1.33" -msgstr "1.33" - #: src/lib/format.cc:83 msgid "1.375" msgstr "1.375" @@ -58,6 +54,10 @@ msgstr "16:9 en Flat" msgid "3D denoiser" msgstr "reducción de ruido 3D" +#: src/lib/format.cc:79 +msgid "4:3" +msgstr "" + #: src/lib/format.cc:87 msgid "4:3 within Flat" msgstr "4:3 en Flat" @@ -94,7 +94,7 @@ msgstr "Bicúbico" msgid "Bilinear" msgstr "Bilineal" -#: src/lib/job.cc:302 +#: src/lib/job.cc:306 msgid "Cancelled" msgstr "" @@ -175,7 +175,7 @@ msgstr "Dolby CP750" msgid "Each source frame will be doubled in the DCP.\n" msgstr "Se doblará cada fotograma de la fuente en el DCP.\n" -#: src/lib/job.cc:300 +#: src/lib/job.cc:304 msgid "Error (%1)" msgstr "Error (%1)" @@ -247,7 +247,7 @@ msgstr "Horizontal deblocking filter" msgid "Horizontal deblocking filter A" msgstr "Horizontal deblocking filter A" -#: src/lib/job.cc:92 src/lib/job.cc:101 +#: src/lib/job.cc:96 src/lib/job.cc:105 msgid "" "It is not known what caused this error. The best idea is to report the " "problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" @@ -301,7 +301,7 @@ msgstr "Motion compensating deinterlacer" msgid "Noise reduction" msgstr "Reducción de ruido" -#: src/lib/job.cc:298 +#: src/lib/job.cc:302 msgid "OK (ran for %1)" msgstr "OK (ejecución %1)" @@ -373,7 +373,7 @@ msgstr "Temporal noise reducer" msgid "Test" msgstr "Test" -#: src/lib/job.cc:77 +#: src/lib/job.cc:78 msgid "" "The drive that the film is stored on is low in disc space. Free some more " "space and try again." @@ -393,11 +393,11 @@ msgstr "Codificar %1" msgid "Transitional" msgstr "Transitional" -#: src/lib/job.cc:100 +#: src/lib/job.cc:104 msgid "Unknown error" msgstr "Error desconocido" -#: src/lib/ffmpeg_decoder.cc:396 +#: src/lib/ffmpeg_decoder.cc:388 msgid "Unrecognised audio sample format (%1)" msgstr "Formato de audio desconocido (%1)" @@ -425,7 +425,7 @@ msgstr "X" msgid "Yet Another Deinterlacing Filter" msgstr "Yet Another Deinterlacing Filter" -#: src/lib/film.cc:263 +#: src/lib/film.cc:296 msgid "cannot contain slashes" msgstr "no puede contener barras" @@ -437,11 +437,11 @@ msgstr "tiempo de conexión agotado" msgid "connecting" msgstr "conectando" -#: src/lib/film.cc:300 +#: src/lib/film.cc:333 msgid "content" msgstr "contenido" -#: src/lib/film.cc:304 +#: src/lib/film.cc:337 msgid "content type" msgstr "tipo de contenido" @@ -454,19 +454,19 @@ msgstr "copiando %1" msgid "could not create file %1" msgstr "No se pudo escribir el fichero remoto (%1)" -#: src/lib/ffmpeg_decoder.cc:191 +#: src/lib/ffmpeg_decoder.cc:187 msgid "could not find audio decoder" msgstr "no se encontró el decodificador de audio" -#: src/lib/ffmpeg_decoder.cc:118 +#: src/lib/ffmpeg_decoder.cc:114 msgid "could not find stream information" msgstr "no se pudo encontrar información del flujo" -#: src/lib/ffmpeg_decoder.cc:210 +#: src/lib/ffmpeg_decoder.cc:206 msgid "could not find subtitle decoder" msgstr "no se pudo encontrar decodificador de subtítutlos" -#: src/lib/ffmpeg_decoder.cc:169 +#: src/lib/ffmpeg_decoder.cc:165 msgid "could not find video decoder" msgstr "no se pudo encontrar decodificador de vídeo" @@ -513,7 +513,7 @@ msgstr "los ficheros externos de sonido tienen duraciones diferentes" msgid "external audio files must be mono" msgstr "los ficheros externos de sonido deben ser mono" -#: src/lib/film.cc:296 +#: src/lib/film.cc:329 msgid "format" msgstr "formato" @@ -549,7 +549,7 @@ msgstr "" msgid "multi-part subtitles not yet supported" msgstr "todavía no se soportan subtítulos en múltiples partes" -#: src/lib/film.cc:263 src/lib/film.cc:308 +#: src/lib/film.cc:296 src/lib/film.cc:341 msgid "name" msgstr "nombre" @@ -563,7 +563,7 @@ msgstr "todavía no se soportan subtítulos que no son en mapas de bits" #. / TRANSLATORS: remaining here follows an amount of time that is remaining #. / on an operation. -#: src/lib/job.cc:295 +#: src/lib/job.cc:299 msgid "remaining" msgstr "pendiente" @@ -575,14 +575,17 @@ msgstr "sRGB" msgid "seconds" msgstr "segundos" -#: src/lib/film.cc:274 +#: src/lib/film.cc:307 msgid "still" msgstr "imagen fija" -#: src/lib/film.cc:274 +#: src/lib/film.cc:307 msgid "video" msgstr "vídeo" +#~ msgid "1.33" +#~ msgstr "1.33" + #~ msgid "Source scaled to 1.19:1" #~ msgstr "Fuente escalada a 1.19:1" diff --git a/src/lib/po/fr_FR.po b/src/lib/po/fr_FR.po index cce92822e..d1123d84b 100644 --- a/src/lib/po/fr_FR.po +++ b/src/lib/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-09 11:14+0100\n" +"POT-Creation-Date: 2013-04-22 15:06+0100\n" "PO-Revision-Date: 2013-03-20 00:39+0100\n" "Last-Translator: FreeDCP.net \n" "Language-Team: \n" @@ -24,10 +24,6 @@ msgstr "0%" msgid "1.19" msgstr "1.19" -#: src/lib/format.cc:79 -msgid "1.33" -msgstr "1.33" - #: src/lib/format.cc:83 msgid "1.375" msgstr "1.375" @@ -57,6 +53,10 @@ msgstr "16:9 dans Scope" msgid "3D denoiser" msgstr "Débruitage 3D" +#: src/lib/format.cc:79 +msgid "4:3" +msgstr "" + #: src/lib/format.cc:87 msgid "4:3 within Flat" msgstr "4:3 dans Flat" @@ -93,7 +93,7 @@ msgstr "Bicubique" msgid "Bilinear" msgstr "Bilinéaire" -#: src/lib/job.cc:302 +#: src/lib/job.cc:306 msgid "Cancelled" msgstr "" @@ -173,7 +173,7 @@ msgstr "Dolby CP750" msgid "Each source frame will be doubled in the DCP.\n" msgstr "Chaque image source sera dupliquée dans le DCP.\n" -#: src/lib/job.cc:300 +#: src/lib/job.cc:304 msgid "Error (%1)" msgstr "Erreur (%1)" @@ -245,7 +245,7 @@ msgstr "Filtre dé-bloc horizontal" msgid "Horizontal deblocking filter A" msgstr "Filtre dé-bloc horizontal" -#: src/lib/job.cc:92 src/lib/job.cc:101 +#: src/lib/job.cc:96 src/lib/job.cc:105 msgid "" "It is not known what caused this error. The best idea is to report the " "problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" @@ -299,7 +299,7 @@ msgstr "Désentrelaceur par compensation de mouvement" msgid "Noise reduction" msgstr "Réduction de bruit" -#: src/lib/job.cc:298 +#: src/lib/job.cc:302 msgid "OK (ran for %1)" msgstr "OK (processus %1)" @@ -371,7 +371,7 @@ msgstr "Réduction de bruit temporel" msgid "Test" msgstr "Test" -#: src/lib/job.cc:77 +#: src/lib/job.cc:78 msgid "" "The drive that the film is stored on is low in disc space. Free some more " "space and try again." @@ -391,11 +391,11 @@ msgstr "Transcodage %1" msgid "Transitional" msgstr "Transitional" -#: src/lib/job.cc:100 +#: src/lib/job.cc:104 msgid "Unknown error" msgstr "Erreur inconnue" -#: src/lib/ffmpeg_decoder.cc:396 +#: src/lib/ffmpeg_decoder.cc:388 msgid "Unrecognised audio sample format (%1)" msgstr "Échantillonnage audio (%1) inconnu" @@ -423,7 +423,7 @@ msgstr "X" msgid "Yet Another Deinterlacing Filter" msgstr "Un autre filtre de désentrelacement" -#: src/lib/film.cc:263 +#: src/lib/film.cc:296 msgid "cannot contain slashes" msgstr "slash interdit" @@ -435,11 +435,11 @@ msgstr "temps de connexion expiré" msgid "connecting" msgstr "connexion" -#: src/lib/film.cc:300 +#: src/lib/film.cc:333 msgid "content" msgstr "contenu" -#: src/lib/film.cc:304 +#: src/lib/film.cc:337 msgid "content type" msgstr "type de contenu" @@ -451,19 +451,19 @@ msgstr "copie de %1" msgid "could not create file %1" msgstr "Écriture vers fichier distant (%1) impossible" -#: src/lib/ffmpeg_decoder.cc:191 +#: src/lib/ffmpeg_decoder.cc:187 msgid "could not find audio decoder" msgstr "décodeur audio introuvable" -#: src/lib/ffmpeg_decoder.cc:118 +#: src/lib/ffmpeg_decoder.cc:114 msgid "could not find stream information" msgstr "information du flux introuvable" -#: src/lib/ffmpeg_decoder.cc:210 +#: src/lib/ffmpeg_decoder.cc:206 msgid "could not find subtitle decoder" msgstr "décodeur de sous-titre introuvable" -#: src/lib/ffmpeg_decoder.cc:169 +#: src/lib/ffmpeg_decoder.cc:165 msgid "could not find video decoder" msgstr "décodeur vidéo introuvable" @@ -507,7 +507,7 @@ msgstr "Les fichiers audio externes ont des durées différentes" msgid "external audio files must be mono" msgstr "les fichiers audio externes doivent être en mono" -#: src/lib/film.cc:296 +#: src/lib/film.cc:329 msgid "format" msgstr "format" @@ -543,7 +543,7 @@ msgstr "" msgid "multi-part subtitles not yet supported" msgstr "sous-titres en plusieurs parties non supportés" -#: src/lib/film.cc:263 src/lib/film.cc:308 +#: src/lib/film.cc:296 src/lib/film.cc:341 msgid "name" msgstr "nom" @@ -557,7 +557,7 @@ msgstr "sous-titres non-bitmap non supportés actuellement" #. / TRANSLATORS: remaining here follows an amount of time that is remaining #. / on an operation. -#: src/lib/job.cc:295 +#: src/lib/job.cc:299 msgid "remaining" msgstr "restant" @@ -569,14 +569,17 @@ msgstr "sRGB" msgid "seconds" msgstr "secondes" -#: src/lib/film.cc:274 +#: src/lib/film.cc:307 msgid "still" msgstr "fixe" -#: src/lib/film.cc:274 +#: src/lib/film.cc:307 msgid "video" msgstr "vidéo" +#~ msgid "1.33" +#~ msgstr "1.33" + #~ msgid "Source scaled to 1.19:1" #~ msgstr "Source mise à l'échelle en 1.19:1" diff --git a/src/lib/po/it_IT.po b/src/lib/po/it_IT.po index 992eda107..5f9e9e862 100644 --- a/src/lib/po/it_IT.po +++ b/src/lib/po/it_IT.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-09 11:14+0100\n" +"POT-Creation-Date: 2013-04-22 15:06+0100\n" "PO-Revision-Date: 2013-04-03 15:04+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" @@ -25,10 +25,6 @@ msgstr "0%" msgid "1.19" msgstr "1.19" -#: src/lib/format.cc:79 -msgid "1.33" -msgstr "1.33" - #: src/lib/format.cc:83 msgid "1.375" msgstr "1.375" @@ -58,6 +54,10 @@ msgstr "16:9 all'interno di Flat" msgid "3D denoiser" msgstr "Riduttore di rumore 3D" +#: src/lib/format.cc:79 +msgid "4:3" +msgstr "" + #: src/lib/format.cc:87 msgid "4:3 within Flat" msgstr "4:3 all'interno di Flat" @@ -94,7 +94,7 @@ msgstr "Bicubica" msgid "Bilinear" msgstr "Bilineare" -#: src/lib/job.cc:302 +#: src/lib/job.cc:306 msgid "Cancelled" msgstr "Cancellato" @@ -173,7 +173,7 @@ msgstr "Dolby CP750" msgid "Each source frame will be doubled in the DCP.\n" msgstr "Ogni fotogramma del sorgente sarà raddoppiato nel DCP.\n" -#: src/lib/job.cc:300 +#: src/lib/job.cc:304 msgid "Error (%1)" msgstr "Errore (%1)" @@ -245,7 +245,7 @@ msgstr "Filtro sblocco orizzontale" msgid "Horizontal deblocking filter A" msgstr "Filtro A sblocco orizzontale" -#: src/lib/job.cc:92 src/lib/job.cc:101 +#: src/lib/job.cc:96 src/lib/job.cc:105 msgid "" "It is not known what caused this error. The best idea is to report the " "problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" @@ -299,7 +299,7 @@ msgstr "Dinterlacciatore compensativo di movimento" msgid "Noise reduction" msgstr "Riduzione del rumore" -#: src/lib/job.cc:298 +#: src/lib/job.cc:302 msgid "OK (ran for %1)" msgstr "OK (procede al %1)" @@ -371,7 +371,7 @@ msgstr "Riduttore temporale di rumore" msgid "Test" msgstr "Prova" -#: src/lib/job.cc:77 +#: src/lib/job.cc:78 msgid "" "The drive that the film is stored on is low in disc space. Free some more " "space and try again." @@ -391,11 +391,11 @@ msgstr "Transcodifica %1" msgid "Transitional" msgstr "Di transizione" -#: src/lib/job.cc:100 +#: src/lib/job.cc:104 msgid "Unknown error" msgstr "Errore sconosciuto" -#: src/lib/ffmpeg_decoder.cc:396 +#: src/lib/ffmpeg_decoder.cc:388 msgid "Unrecognised audio sample format (%1)" msgstr "Formato di campionamento audio non riconosciuto (%1)" @@ -423,7 +423,7 @@ msgstr "X" msgid "Yet Another Deinterlacing Filter" msgstr "Altro filtro di deinterlacciamento" -#: src/lib/film.cc:263 +#: src/lib/film.cc:296 msgid "cannot contain slashes" msgstr "non può contenere barre" @@ -435,11 +435,11 @@ msgstr "connessione scaduta" msgid "connecting" msgstr "mi sto connettendo" -#: src/lib/film.cc:300 +#: src/lib/film.cc:333 msgid "content" msgstr "contenuto" -#: src/lib/film.cc:304 +#: src/lib/film.cc:337 msgid "content type" msgstr "tipo di contenuto" @@ -451,19 +451,19 @@ msgstr "copia %1" msgid "could not create file %1" msgstr "Non posso scrivere il file remoto (%1)" -#: src/lib/ffmpeg_decoder.cc:191 +#: src/lib/ffmpeg_decoder.cc:187 msgid "could not find audio decoder" msgstr "non riesco a trovare il decoder audio" -#: src/lib/ffmpeg_decoder.cc:118 +#: src/lib/ffmpeg_decoder.cc:114 msgid "could not find stream information" msgstr "non riesco a trovare informazioni sullo streaming" -#: src/lib/ffmpeg_decoder.cc:210 +#: src/lib/ffmpeg_decoder.cc:206 msgid "could not find subtitle decoder" msgstr "non riesco a trovare il decoder dei sottotitoli" -#: src/lib/ffmpeg_decoder.cc:169 +#: src/lib/ffmpeg_decoder.cc:165 msgid "could not find video decoder" msgstr "non riesco a trovare il decoder video" @@ -507,7 +507,7 @@ msgstr "i files dell'audio esterno hanno durata diversa" msgid "external audio files must be mono" msgstr "i files dell'audio esterno devono essere mono" -#: src/lib/film.cc:296 +#: src/lib/film.cc:329 msgid "format" msgstr "formato" @@ -543,7 +543,7 @@ msgstr "persa la regolazione richiesta %1" msgid "multi-part subtitles not yet supported" msgstr "sottotitoli multi-part non ancora supportati" -#: src/lib/film.cc:263 src/lib/film.cc:308 +#: src/lib/film.cc:296 src/lib/film.cc:341 msgid "name" msgstr "nome" @@ -557,7 +557,7 @@ msgstr "sottotitoli non-bitmap non ancora supportati" #. / TRANSLATORS: remaining here follows an amount of time that is remaining #. / on an operation. -#: src/lib/job.cc:295 +#: src/lib/job.cc:299 msgid "remaining" msgstr "restano" @@ -569,14 +569,17 @@ msgstr "sRGB" msgid "seconds" msgstr "secondi" -#: src/lib/film.cc:274 +#: src/lib/film.cc:307 msgid "still" msgstr "ancora" -#: src/lib/film.cc:274 +#: src/lib/film.cc:307 msgid "video" msgstr "video" +#~ msgid "1.33" +#~ msgstr "1.33" + #~ msgid "Source scaled to 1.19:1" #~ msgstr "Sorgente scalato a 1.19:1" diff --git a/src/lib/po/sv_SE.po b/src/lib/po/sv_SE.po index ef8109dfa..11aeff987 100644 --- a/src/lib/po/sv_SE.po +++ b/src/lib/po/sv_SE.po @@ -7,10 +7,11 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-09 11:14+0100\n" +"POT-Creation-Date: 2013-04-22 15:06+0100\n" "PO-Revision-Date: 2013-04-10 15:35+0100\n" "Last-Translator: Adam Klotblixt \n" "Language-Team: \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -24,10 +25,6 @@ msgstr "0%" msgid "1.19" msgstr "1,19" -#: src/lib/format.cc:79 -msgid "1.33" -msgstr "1,33" - #: src/lib/format.cc:83 msgid "1.375" msgstr "1,375" @@ -56,6 +53,10 @@ msgstr "16:9 innanför Scope" msgid "3D denoiser" msgstr "3D brusreducering" +#: src/lib/format.cc:79 +msgid "4:3" +msgstr "" + #: src/lib/format.cc:87 msgid "4:3 within Flat" msgstr "4:3 innanför Flat" @@ -92,7 +93,7 @@ msgstr "Bikubisk" msgid "Bilinear" msgstr "Bilinjär" -#: src/lib/job.cc:302 +#: src/lib/job.cc:306 msgid "Cancelled" msgstr "Avbruten" @@ -172,7 +173,7 @@ msgstr "Dolby CP750" msgid "Each source frame will be doubled in the DCP.\n" msgstr "Varje bild från källan kommer att användas två gånger i DCPn.\n" -#: src/lib/job.cc:300 +#: src/lib/job.cc:304 msgid "Error (%1)" msgstr "Fel (%1)" @@ -244,7 +245,7 @@ msgstr "Filter för horisontal kantighetsutjämning" msgid "Horizontal deblocking filter A" msgstr "Filter för horisontal kantighetsutjämning A" -#: src/lib/job.cc:92 src/lib/job.cc:101 +#: src/lib/job.cc:96 src/lib/job.cc:105 msgid "" "It is not known what caused this error. The best idea is to report the " "problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" @@ -298,7 +299,7 @@ msgstr "Rörelsekompenserande avflätare" msgid "Noise reduction" msgstr "Brusreducering" -#: src/lib/job.cc:298 +#: src/lib/job.cc:302 msgid "OK (ran for %1)" msgstr "OK (kördes %1)" @@ -370,7 +371,7 @@ msgstr "Temporal brusreducering" msgid "Test" msgstr "Test" -#: src/lib/job.cc:77 +#: src/lib/job.cc:78 msgid "" "The drive that the film is stored on is low in disc space. Free some more " "space and try again." @@ -390,12 +391,12 @@ msgstr "Konvertera %1" msgid "Transitional" msgstr "Övergångsklipp" -#: src/lib/job.cc:100 +#: src/lib/job.cc:104 msgid "Unknown error" msgstr "Okänt fel" # Svengelska -#: src/lib/ffmpeg_decoder.cc:396 +#: src/lib/ffmpeg_decoder.cc:388 #, fuzzy msgid "Unrecognised audio sample format (%1)" msgstr "Okänt audio-sampelformat (%1)" @@ -425,7 +426,7 @@ msgstr "X" msgid "Yet Another Deinterlacing Filter" msgstr "Yet Another Deinterlacing Filter" -#: src/lib/film.cc:263 +#: src/lib/film.cc:296 msgid "cannot contain slashes" msgstr "får inte innehålla snedstreck" @@ -439,11 +440,11 @@ msgstr "uppkopplingen tajmade ur" msgid "connecting" msgstr "kopplar upp" -#: src/lib/film.cc:300 +#: src/lib/film.cc:333 msgid "content" msgstr "innehåll" -#: src/lib/film.cc:304 +#: src/lib/film.cc:337 msgid "content type" msgstr "innehållstyp" @@ -455,19 +456,19 @@ msgstr "kopierar %1" msgid "could not create file %1" msgstr "kunde inte skapa fil %1" -#: src/lib/ffmpeg_decoder.cc:191 +#: src/lib/ffmpeg_decoder.cc:187 msgid "could not find audio decoder" msgstr "kunde inte hitta audio-avkodare" -#: src/lib/ffmpeg_decoder.cc:118 +#: src/lib/ffmpeg_decoder.cc:114 msgid "could not find stream information" msgstr "kunde inte hitta information om strömmen" -#: src/lib/ffmpeg_decoder.cc:210 +#: src/lib/ffmpeg_decoder.cc:206 msgid "could not find subtitle decoder" msgstr "kunde inte hitta undertext-avkodare" -#: src/lib/ffmpeg_decoder.cc:169 +#: src/lib/ffmpeg_decoder.cc:165 msgid "could not find video decoder" msgstr "kunde inte hitta video-avkodare" @@ -511,7 +512,7 @@ msgstr "externa audio-filer har olika längder" msgid "external audio files must be mono" msgstr "externa audio-filer måste vara mono" -#: src/lib/film.cc:296 +#: src/lib/film.cc:329 msgid "format" msgstr "format" @@ -547,7 +548,7 @@ msgstr "saknad nödvändig inställning %1" msgid "multi-part subtitles not yet supported" msgstr "undertexter i flera delar stöds inte ännu" -#: src/lib/film.cc:263 src/lib/film.cc:308 +#: src/lib/film.cc:296 src/lib/film.cc:341 msgid "name" msgstr "namn" @@ -561,7 +562,7 @@ msgstr "icke-rastergrafiska undertexter stöds inte ännu" #. / TRANSLATORS: remaining here follows an amount of time that is remaining #. / on an operation. -#: src/lib/job.cc:295 +#: src/lib/job.cc:299 msgid "remaining" msgstr "återstående tid" @@ -573,14 +574,17 @@ msgstr "sRGB" msgid "seconds" msgstr "sekunder" -#: src/lib/film.cc:274 +#: src/lib/film.cc:307 msgid "still" msgstr "stillbild" -#: src/lib/film.cc:274 +#: src/lib/film.cc:307 msgid "video" msgstr "video" +#~ msgid "1.33" +#~ msgstr "1,33" + #~ msgid "Source scaled to 1.19:1" #~ msgstr "Källan skalad till 1,19:1" diff --git a/src/tools/po/es_ES.po b/src/tools/po/es_ES.po index abfbfef6d..1739f97cd 100644 --- a/src/tools/po/es_ES.po +++ b/src/tools/po/es_ES.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVDOMATIC\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-09 11:14+0100\n" +"POT-Creation-Date: 2013-04-22 15:06+0100\n" "PO-Revision-Date: 2013-03-23 21:08-0500\n" "Last-Translator: Manuel AC \n" "Language-Team: Manuel AC \n" @@ -17,111 +17,112 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" -#: src/tools/dvdomatic.cc:177 +#: src/tools/dvdomatic.cc:179 msgid "&Analyse audio" msgstr "&Analizar audio" -#: src/tools/dvdomatic.cc:183 +#: src/tools/dvdomatic.cc:185 msgid "&Edit" msgstr "&Editar" -#: src/tools/dvdomatic.cc:182 +#: src/tools/dvdomatic.cc:184 msgid "&File" msgstr "&Archivo" -#: src/tools/dvdomatic.cc:185 +#: src/tools/dvdomatic.cc:187 msgid "&Help" msgstr "&Ayuda" -#: src/tools/dvdomatic.cc:184 +#: src/tools/dvdomatic.cc:186 msgid "&Jobs" msgstr "&Tareas" -#: src/tools/dvdomatic.cc:173 +#: src/tools/dvdomatic.cc:175 msgid "&Make DCP" msgstr "&Crear DCP" -#: src/tools/dvdomatic.cc:161 +#: src/tools/dvdomatic.cc:163 msgid "&Open..." msgstr "&Abrir..." -#: src/tools/dvdomatic.cc:170 +#: src/tools/dvdomatic.cc:172 msgid "&Preferences..." msgstr "&Preferencias..." -#: src/tools/dvdomatic.cc:165 +#: src/tools/dvdomatic.cc:167 msgid "&Properties..." msgstr "&Propiedades..." -#: src/tools/dvdomatic.cc:167 +#: src/tools/dvdomatic.cc:169 msgid "&Quit" msgstr "&Salir" -#: src/tools/dvdomatic.cc:163 +#: src/tools/dvdomatic.cc:165 msgid "&Save" msgstr "&Guardar" -#: src/tools/dvdomatic.cc:174 +#: src/tools/dvdomatic.cc:176 msgid "&Send DCP to TMS" msgstr "&Enviar DCP al TMS" -#: src/tools/dvdomatic.cc:417 +#: src/tools/dvdomatic.cc:419 msgid "" "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" msgstr "" "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" -#: src/tools/dvdomatic.cc:180 +#: src/tools/dvdomatic.cc:182 msgid "About" msgstr "Acerca de" -#: src/tools/dvdomatic.cc:527 +#: src/tools/dvdomatic.cc:538 #, fuzzy msgid "Could not load film %1 (%2)" msgstr "No se pudo cargar la película %s (%s)" -#: src/tools/dvdomatic.cc:339 +#: src/tools/dvdomatic.cc:341 #, c-format msgid "Could not open film at %s (%s)" msgstr "No se pudo cargar la película en %s (%s)" -#: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:410 -#: src/tools/dvdomatic.cc:531 +#: src/tools/dvdomatic.cc:289 src/tools/dvdomatic.cc:412 +#: src/tools/dvdomatic.cc:542 msgid "DVD-o-matic" msgstr "DVD-o-matic" -#: src/tools/dvdomatic.cc:75 +#: src/tools/dvdomatic.cc:77 msgid "Film changed" msgstr "Película cambiada" -#: src/tools/dvdomatic.cc:416 +#: src/tools/dvdomatic.cc:418 msgid "Free, open-source DCP generation from almost anything." msgstr "" "Generación de DCP a partir de casi cualquier fuente, libre y de código " "abierto." -#: src/tools/dvdomatic.cc:160 +#: src/tools/dvdomatic.cc:162 msgid "New..." msgstr "Nuevo..." -#: src/tools/dvdomatic.cc:175 +#: src/tools/dvdomatic.cc:177 msgid "S&how DCP" msgstr "&Mostrar DCP" -#: src/tools/dvdomatic.cc:74 +#: src/tools/dvdomatic.cc:76 +#, c-format msgid "Save changes to film \"%s\" before closing?" msgstr "" -#: src/tools/dvdomatic.cc:319 +#: src/tools/dvdomatic.cc:321 msgid "Select film to open" msgstr "Selecciona la película a abrir" -#: src/tools/dvdomatic.cc:303 +#: src/tools/dvdomatic.cc:305 #, fuzzy msgid "The directory %1 already exists." msgstr "La carpeta %s ya existe." -#: src/tools/dvdomatic.cc:324 +#: src/tools/dvdomatic.cc:326 msgid "" "You did not select a folder. Make sure that you select a folder before " "clicking Open." diff --git a/src/tools/po/fr_FR.po b/src/tools/po/fr_FR.po index b40c86877..c1447f7e6 100644 --- a/src/tools/po/fr_FR.po +++ b/src/tools/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-09 11:14+0100\n" +"POT-Creation-Date: 2013-04-22 15:06+0100\n" "PO-Revision-Date: 2013-03-13 22:33+0100\n" "Last-Translator: \n" "Language-Team: \n" @@ -16,109 +16,110 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: src/tools/dvdomatic.cc:177 +#: src/tools/dvdomatic.cc:179 msgid "&Analyse audio" msgstr "&Analyser le son" -#: src/tools/dvdomatic.cc:183 +#: src/tools/dvdomatic.cc:185 msgid "&Edit" msgstr "&Edition" -#: src/tools/dvdomatic.cc:182 +#: src/tools/dvdomatic.cc:184 msgid "&File" msgstr "&Fichier" -#: src/tools/dvdomatic.cc:185 +#: src/tools/dvdomatic.cc:187 msgid "&Help" msgstr "&Aide" -#: src/tools/dvdomatic.cc:184 +#: src/tools/dvdomatic.cc:186 msgid "&Jobs" msgstr "&Travaux" -#: src/tools/dvdomatic.cc:173 +#: src/tools/dvdomatic.cc:175 msgid "&Make DCP" msgstr "&Créer le DCP" -#: src/tools/dvdomatic.cc:161 +#: src/tools/dvdomatic.cc:163 msgid "&Open..." msgstr "&Ouvrir..." -#: src/tools/dvdomatic.cc:170 +#: src/tools/dvdomatic.cc:172 msgid "&Preferences..." msgstr "&Préférences..." -#: src/tools/dvdomatic.cc:165 +#: src/tools/dvdomatic.cc:167 msgid "&Properties..." msgstr "&Propriétés..." -#: src/tools/dvdomatic.cc:167 +#: src/tools/dvdomatic.cc:169 msgid "&Quit" msgstr "&Quitter" -#: src/tools/dvdomatic.cc:163 +#: src/tools/dvdomatic.cc:165 msgid "&Save" msgstr "&Enregistrer" -#: src/tools/dvdomatic.cc:174 +#: src/tools/dvdomatic.cc:176 msgid "&Send DCP to TMS" msgstr "&Envoyer le DCP dans le TMS" -#: src/tools/dvdomatic.cc:417 +#: src/tools/dvdomatic.cc:419 msgid "" "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" msgstr "" "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" -#: src/tools/dvdomatic.cc:180 +#: src/tools/dvdomatic.cc:182 msgid "About" msgstr "A Propos" -#: src/tools/dvdomatic.cc:527 +#: src/tools/dvdomatic.cc:538 #, fuzzy msgid "Could not load film %1 (%2)" msgstr "Impossible de charger le film %s (%s)" -#: src/tools/dvdomatic.cc:339 +#: src/tools/dvdomatic.cc:341 #, c-format msgid "Could not open film at %s (%s)" msgstr "Impossible d'ouvrir le film à %s (%s)" -#: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:410 -#: src/tools/dvdomatic.cc:531 +#: src/tools/dvdomatic.cc:289 src/tools/dvdomatic.cc:412 +#: src/tools/dvdomatic.cc:542 msgid "DVD-o-matic" msgstr "DVD-o-matic" -#: src/tools/dvdomatic.cc:75 +#: src/tools/dvdomatic.cc:77 msgid "Film changed" msgstr "Film changé" -#: src/tools/dvdomatic.cc:416 +#: src/tools/dvdomatic.cc:418 msgid "Free, open-source DCP generation from almost anything." msgstr "Création de DCP libre et open-source à partir de presque tout." -#: src/tools/dvdomatic.cc:160 +#: src/tools/dvdomatic.cc:162 msgid "New..." msgstr "Nouveau..." -#: src/tools/dvdomatic.cc:175 +#: src/tools/dvdomatic.cc:177 msgid "S&how DCP" msgstr "Voir le DCP" -#: src/tools/dvdomatic.cc:74 +#: src/tools/dvdomatic.cc:76 +#, c-format msgid "Save changes to film \"%s\" before closing?" msgstr "" -#: src/tools/dvdomatic.cc:319 +#: src/tools/dvdomatic.cc:321 msgid "Select film to open" msgstr "Sélectionner le film à ouvrir" -#: src/tools/dvdomatic.cc:303 +#: src/tools/dvdomatic.cc:305 #, fuzzy msgid "The directory %1 already exists." msgstr "Le dossier %s existe déjà." -#: src/tools/dvdomatic.cc:324 +#: src/tools/dvdomatic.cc:326 msgid "" "You did not select a folder. Make sure that you select a folder before " "clicking Open." diff --git a/src/tools/po/it_IT.po b/src/tools/po/it_IT.po index 38cbec157..1e0d8446a 100644 --- a/src/tools/po/it_IT.po +++ b/src/tools/po/it_IT.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-09 11:14+0100\n" +"POT-Creation-Date: 2013-04-22 15:06+0100\n" "PO-Revision-Date: 2013-04-03 13:00+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" @@ -17,107 +17,108 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" -#: src/tools/dvdomatic.cc:177 +#: src/tools/dvdomatic.cc:179 msgid "&Analyse audio" msgstr "&Analizza audio" -#: src/tools/dvdomatic.cc:183 +#: src/tools/dvdomatic.cc:185 msgid "&Edit" msgstr "&Modifica" -#: src/tools/dvdomatic.cc:182 +#: src/tools/dvdomatic.cc:184 msgid "&File" msgstr "&File" -#: src/tools/dvdomatic.cc:185 +#: src/tools/dvdomatic.cc:187 msgid "&Help" msgstr "&Aiuto" -#: src/tools/dvdomatic.cc:184 +#: src/tools/dvdomatic.cc:186 msgid "&Jobs" msgstr "&Lavori" -#: src/tools/dvdomatic.cc:173 +#: src/tools/dvdomatic.cc:175 msgid "&Make DCP" msgstr "&Crea DCP" -#: src/tools/dvdomatic.cc:161 +#: src/tools/dvdomatic.cc:163 msgid "&Open..." msgstr "&Apri..." -#: src/tools/dvdomatic.cc:170 +#: src/tools/dvdomatic.cc:172 msgid "&Preferences..." msgstr "&Preferenze..." -#: src/tools/dvdomatic.cc:165 +#: src/tools/dvdomatic.cc:167 msgid "&Properties..." msgstr "&Proprieta'..." -#: src/tools/dvdomatic.cc:167 +#: src/tools/dvdomatic.cc:169 msgid "&Quit" msgstr "&Esci" -#: src/tools/dvdomatic.cc:163 +#: src/tools/dvdomatic.cc:165 msgid "&Save" msgstr "&Salva" -#: src/tools/dvdomatic.cc:174 +#: src/tools/dvdomatic.cc:176 msgid "&Send DCP to TMS" msgstr "&Invia DCP a TMS" -#: src/tools/dvdomatic.cc:417 +#: src/tools/dvdomatic.cc:419 msgid "" "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" msgstr "" "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" -#: src/tools/dvdomatic.cc:180 +#: src/tools/dvdomatic.cc:182 msgid "About" msgstr "Informazioni" -#: src/tools/dvdomatic.cc:527 +#: src/tools/dvdomatic.cc:538 msgid "Could not load film %1 (%2)" msgstr "Non posso caricare il film %s (%s)" -#: src/tools/dvdomatic.cc:339 +#: src/tools/dvdomatic.cc:341 #, c-format msgid "Could not open film at %s (%s)" msgstr "Non posso aprire il film in %s (%s)" -#: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:410 -#: src/tools/dvdomatic.cc:531 +#: src/tools/dvdomatic.cc:289 src/tools/dvdomatic.cc:412 +#: src/tools/dvdomatic.cc:542 msgid "DVD-o-matic" msgstr "DVD-o-matic" -#: src/tools/dvdomatic.cc:75 +#: src/tools/dvdomatic.cc:77 msgid "Film changed" msgstr "Film modificato" -#: src/tools/dvdomatic.cc:416 +#: src/tools/dvdomatic.cc:418 msgid "Free, open-source DCP generation from almost anything." msgstr "Genera DCP da quasi tutto, free e open-source." -#: src/tools/dvdomatic.cc:160 +#: src/tools/dvdomatic.cc:162 msgid "New..." msgstr "Nuovo" -#: src/tools/dvdomatic.cc:175 +#: src/tools/dvdomatic.cc:177 msgid "S&how DCP" msgstr "&Mostra DCP" -#: src/tools/dvdomatic.cc:74 +#: src/tools/dvdomatic.cc:76 +#, c-format msgid "Save changes to film \"%s\" before closing?" msgstr "Salvare i cambiamenti del film \"%s\" prima di chiudere?" -#: src/tools/dvdomatic.cc:319 +#: src/tools/dvdomatic.cc:321 msgid "Select film to open" msgstr "Seleziona il film da aprire" -#: src/tools/dvdomatic.cc:303 +#: src/tools/dvdomatic.cc:305 msgid "The directory %1 already exists." msgstr "La directory %s esiste gia'." -#: src/tools/dvdomatic.cc:324 +#: src/tools/dvdomatic.cc:326 msgid "" "You did not select a folder. Make sure that you select a folder before " "clicking Open." diff --git a/src/tools/po/sv_SE.po b/src/tools/po/sv_SE.po index 28566d876..8ae68853f 100644 --- a/src/tools/po/sv_SE.po +++ b/src/tools/po/sv_SE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-09 11:14+0100\n" +"POT-Creation-Date: 2013-04-22 15:06+0100\n" "PO-Revision-Date: 2013-04-09 10:12+0100\n" "Last-Translator: Adam Klotblixt \n" "Language-Team: \n" @@ -17,108 +17,109 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" -#: src/tools/dvdomatic.cc:177 +#: src/tools/dvdomatic.cc:179 msgid "&Analyse audio" msgstr "&Analysera audio" -#: src/tools/dvdomatic.cc:183 +#: src/tools/dvdomatic.cc:185 msgid "&Edit" msgstr "&Redigera" -#: src/tools/dvdomatic.cc:182 +#: src/tools/dvdomatic.cc:184 msgid "&File" msgstr "&Fil" -#: src/tools/dvdomatic.cc:185 +#: src/tools/dvdomatic.cc:187 msgid "&Help" msgstr "&Hjälp" -#: src/tools/dvdomatic.cc:184 +#: src/tools/dvdomatic.cc:186 msgid "&Jobs" msgstr "&Jobb" -#: src/tools/dvdomatic.cc:173 +#: src/tools/dvdomatic.cc:175 msgid "&Make DCP" msgstr "&Skapa DCP" -#: src/tools/dvdomatic.cc:161 +#: src/tools/dvdomatic.cc:163 msgid "&Open..." msgstr "&Öppna" -#: src/tools/dvdomatic.cc:170 +#: src/tools/dvdomatic.cc:172 msgid "&Preferences..." msgstr "&Inställningar" -#: src/tools/dvdomatic.cc:165 +#: src/tools/dvdomatic.cc:167 msgid "&Properties..." msgstr "&Egenskaper" -#: src/tools/dvdomatic.cc:167 +#: src/tools/dvdomatic.cc:169 msgid "&Quit" msgstr "&Avsluta" -#: src/tools/dvdomatic.cc:163 +#: src/tools/dvdomatic.cc:165 msgid "&Save" msgstr "&Spara" -#: src/tools/dvdomatic.cc:174 +#: src/tools/dvdomatic.cc:176 msgid "&Send DCP to TMS" msgstr "&Skicka DCP till TMS" -#: src/tools/dvdomatic.cc:417 +#: src/tools/dvdomatic.cc:419 msgid "" "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" msgstr "" "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" -#: src/tools/dvdomatic.cc:180 +#: src/tools/dvdomatic.cc:182 msgid "About" msgstr "Om" -#: src/tools/dvdomatic.cc:527 +#: src/tools/dvdomatic.cc:538 msgid "Could not load film %1 (%2)" msgstr "Kunde inte öppna filmen %1 (%2)" -#: src/tools/dvdomatic.cc:339 +#: src/tools/dvdomatic.cc:341 #, c-format msgid "Could not open film at %s (%s)" msgstr "Kunde inte öppna filmen vid %s (%s)" -#: src/tools/dvdomatic.cc:287 src/tools/dvdomatic.cc:410 -#: src/tools/dvdomatic.cc:531 +#: src/tools/dvdomatic.cc:289 src/tools/dvdomatic.cc:412 +#: src/tools/dvdomatic.cc:542 msgid "DVD-o-matic" msgstr "DVD-o-matic" -#: src/tools/dvdomatic.cc:75 +#: src/tools/dvdomatic.cc:77 msgid "Film changed" msgstr "Film ändrad" -#: src/tools/dvdomatic.cc:416 +#: src/tools/dvdomatic.cc:418 msgid "Free, open-source DCP generation from almost anything." msgstr "" "Fri, öppen-källkodsprogramvara för DCP-generering från nästan vad som helst." -#: src/tools/dvdomatic.cc:160 +#: src/tools/dvdomatic.cc:162 msgid "New..." msgstr "Ny..." -#: src/tools/dvdomatic.cc:175 +#: src/tools/dvdomatic.cc:177 msgid "S&how DCP" msgstr "&Visa DCP" -#: src/tools/dvdomatic.cc:74 -msgid "Save changes to film \"%1\" before closing?" +#: src/tools/dvdomatic.cc:76 +#, fuzzy, c-format +msgid "Save changes to film \"%s\" before closing?" msgstr "Spara ändringarna till filmen \"%1\" före avslut?" -#: src/tools/dvdomatic.cc:319 +#: src/tools/dvdomatic.cc:321 msgid "Select film to open" msgstr "Välj film att öppna" -#: src/tools/dvdomatic.cc:303 +#: src/tools/dvdomatic.cc:305 msgid "The directory %1 already exists." msgstr "Katalogen %1 finns redan." -#: src/tools/dvdomatic.cc:324 +#: src/tools/dvdomatic.cc:326 msgid "" "You did not select a folder. Make sure that you select a folder before " "clicking Open." diff --git a/src/wx/po/es_ES.po b/src/wx/po/es_ES.po index 207708589..56c0856bd 100644 --- a/src/wx/po/es_ES.po +++ b/src/wx/po/es_ES.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: libdvdomatic-wx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-09 11:14+0100\n" +"POT-Creation-Date: 2013-04-22 15:06+0100\n" "PO-Revision-Date: 2013-04-02 19:08-0500\n" "Last-Translator: Manuel AC \n" "Language-Team: Manuel AC \n" @@ -17,7 +17,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" -#: src/wx/film_editor.cc:445 +#: src/wx/film_editor.cc:449 msgid "%" msgstr "%" @@ -25,7 +25,7 @@ msgstr "%" msgid "(restart DVD-o-matic to see language changes)" msgstr "" -#: src/wx/film_editor.cc:1269 +#: src/wx/film_editor.cc:1276 msgid "1 channel" msgstr "1 canal" @@ -41,11 +41,11 @@ msgstr "Añadir" msgid "Audio" msgstr "Audio" -#: src/wx/film_editor.cc:381 +#: src/wx/film_editor.cc:385 msgid "Audio Delay" msgstr "Retardo del audio" -#: src/wx/film_editor.cc:369 +#: src/wx/film_editor.cc:373 msgid "Audio Gain" msgstr "Ganancia del audio" @@ -53,7 +53,7 @@ msgstr "Ganancia del audio" msgid "Audio Language (e.g. EN)" msgstr "Idioma del audio (ej. ES)" -#: src/wx/film_editor.cc:820 +#: src/wx/film_editor.cc:824 #, c-format msgid "Audio will be resampled from %dHz to %dHz\n" msgstr "" @@ -63,7 +63,7 @@ msgstr "" msgid "Bad setting for %s (%s)" msgstr "Configuración erronea para %s (%s)" -#: src/wx/film_editor.cc:288 +#: src/wx/film_editor.cc:292 msgid "Bottom crop" msgstr "Recortar abajo" @@ -75,7 +75,7 @@ msgstr "Explorar..." msgid "But I have to use fader" msgstr "pero tengo que usar el fader a" -#: src/wx/film_editor.cc:374 +#: src/wx/film_editor.cc:378 msgid "Calculate..." msgstr "Calcular..." @@ -87,7 +87,7 @@ msgstr "" msgid "Channels" msgstr "Canales" -#: src/wx/film_editor.cc:325 +#: src/wx/film_editor.cc:329 msgid "Colour look-up table" msgstr "Tabla de referencia de colores" @@ -99,7 +99,7 @@ msgstr "Contenido" msgid "Content Type" msgstr "Tipo de contenido" -#: src/wx/film_viewer.cc:415 +#: src/wx/film_viewer.cc:451 #, c-format msgid "Could not decode video for view (%s)" msgstr "No se pudo decodificar el vídeo para mostrarlo (%s)" @@ -109,12 +109,12 @@ msgstr "No se pudo decodificar el vídeo para mostrarlo (%s)" msgid "Could not make DCP: %s" msgstr "No se pudo crear el DCP: %s" -#: src/wx/film_viewer.cc:107 +#: src/wx/film_viewer.cc:125 #, c-format msgid "Could not open content file (%s)" msgstr "No se pudo abrir el fichero (%s)" -#: src/wx/film_editor.cc:509 +#: src/wx/film_editor.cc:513 #, c-format msgid "Could not set content: %s" msgstr "No se pudo establecer el contenido: %s" @@ -123,7 +123,7 @@ msgstr "No se pudo establecer el contenido: %s" msgid "Create in folder" msgstr "Crear en carpeta" -#: src/wx/film_editor.cc:1363 +#: src/wx/film_editor.cc:1371 #, c-format msgid "Cropped to %dx%d (%.2f:1)\n" msgstr "" @@ -178,7 +178,7 @@ msgid "Edit" msgstr "Editar" #: src/wx/config_dialog.cc:103 src/wx/config_dialog.cc:122 -#: src/wx/film_editor.cc:308 +#: src/wx/film_editor.cc:312 msgid "Edit..." msgstr "Editar..." @@ -186,7 +186,7 @@ msgstr "Editar..." msgid "Encoding Servers" msgstr "Servidores de codificación" -#: src/wx/film_editor.cc:176 +#: src/wx/film_editor.cc:171 msgid "End" msgstr "Fin" @@ -206,11 +206,11 @@ msgstr "Propiedades de la película" msgid "Film name" msgstr "Nombre de la película" -#: src/wx/film_editor.cc:303 src/wx/filter_dialog.cc:32 +#: src/wx/film_editor.cc:307 src/wx/filter_dialog.cc:32 msgid "Filters" msgstr "Filtros" -#: src/wx/film_editor.cc:268 +#: src/wx/film_editor.cc:272 msgid "Format" msgstr "Formato" @@ -234,7 +234,7 @@ msgstr "Gb" msgid "Host name or IP address" msgstr "Nombre o dirección IP" -#: src/wx/film_editor.cc:1273 +#: src/wx/film_editor.cc:1280 msgid "Hz" msgstr "Hz" @@ -246,19 +246,19 @@ msgstr "Quiero reproducir con el fader a" msgid "IP address" msgstr "Dirección IP" -#: src/wx/film_editor.cc:335 +#: src/wx/film_editor.cc:339 msgid "JPEG2000 bandwidth" msgstr "Ancho de banda JPEG2000" -#: src/wx/film_editor.cc:273 +#: src/wx/film_editor.cc:277 msgid "Left crop" msgstr "Recorte izquierda" -#: src/wx/film_editor.cc:164 +#: src/wx/film_editor.cc:159 msgid "Length" msgstr "Longitud" -#: src/wx/film_editor.cc:339 +#: src/wx/film_editor.cc:343 msgid "MBps" msgstr "MBps" @@ -274,7 +274,7 @@ msgstr "Nombre" msgid "New Film" msgstr "Nueva película" -#: src/wx/film_editor.cc:305 src/wx/film_editor.cc:667 +#: src/wx/film_editor.cc:309 src/wx/film_editor.cc:671 msgid "None" msgstr "Ninguno" @@ -282,11 +282,7 @@ msgstr "Ninguno" msgid "Original Frame Rate" msgstr "Velocidad original" -#: src/wx/film_editor.cc:159 -msgid "Original Size" -msgstr "Tamaño original" - -#: src/wx/film_editor.cc:1352 +#: src/wx/film_editor.cc:1360 #, c-format msgid "Original video is %dx%d (%.2f:1)\n" msgstr "" @@ -295,7 +291,7 @@ msgstr "" msgid "Package Type (e.g. OV)" msgstr "Tipo de paquete (ej. OV)" -#: src/wx/film_editor.cc:1384 +#: src/wx/film_editor.cc:1392 #, c-format msgid "Padded with black to %dx%d (%.2f:1)\n" msgstr "" @@ -304,7 +300,7 @@ msgstr "" msgid "Peak" msgstr "Pico" -#: src/wx/film_viewer.cc:54 +#: src/wx/film_viewer.cc:58 msgid "Play" msgstr "Reproducir" @@ -332,7 +328,7 @@ msgstr "Escalador de referencia para A/B" msgid "Remove" msgstr "Quitar" -#: src/wx/film_editor.cc:278 +#: src/wx/film_editor.cc:282 msgid "Right crop" msgstr "Recorte derecha" @@ -340,16 +336,16 @@ msgstr "Recorte derecha" msgid "Running" msgstr "Ejecutando" -#: src/wx/film_editor.cc:1376 +#: src/wx/film_editor.cc:1384 #, c-format msgid "Scaled to %dx%d (%.2f:1)\n" msgstr "" -#: src/wx/film_editor.cc:315 +#: src/wx/film_editor.cc:319 msgid "Scaler" msgstr "Escalador" -#: src/wx/film_editor.cc:407 +#: src/wx/film_editor.cc:411 msgid "Select Audio File" msgstr "Seleccionar fichero de audio" @@ -365,7 +361,7 @@ msgstr "Servidor" msgid "Set language" msgstr "" -#: src/wx/film_editor.cc:364 +#: src/wx/film_editor.cc:368 msgid "Show Audio..." msgstr "Mostrar audio..." @@ -373,7 +369,7 @@ msgstr "Mostrar audio..." msgid "Smoothing" msgstr "Suavizado" -#: src/wx/film_editor.cc:173 +#: src/wx/film_editor.cc:168 msgid "Start" msgstr "Inicio" @@ -385,11 +381,11 @@ msgstr "Estudio (ej. TCF)" msgid "Subtitle Language (e.g. FR)" msgstr "Idioma del subtítulo (ej. EN)" -#: src/wx/film_editor.cc:432 +#: src/wx/film_editor.cc:436 msgid "Subtitle Offset" msgstr "Desplazamiento del subtítulo" -#: src/wx/film_editor.cc:441 +#: src/wx/film_editor.cc:445 msgid "Subtitle Scale" msgstr "Escala del subtítulo" @@ -433,14 +429,19 @@ msgstr "Hilos a utilizar para la codificación en esta máquina" msgid "Time" msgstr "Tiempo" -#: src/wx/film_editor.cc:283 +#: src/wx/film_editor.cc:287 msgid "Top crop" msgstr "Recortar arriba" -#: src/wx/film_editor.cc:171 +#: src/wx/film_editor.cc:166 msgid "Trim frames" msgstr "Recortar fotogramas" +#: src/wx/film_editor.cc:179 +#, fuzzy +msgid "Trim method" +msgstr "Recortar fotogramas" + #: src/wx/film_editor.cc:125 msgid "Trust content's header" msgstr "Confiar en la cabecera del contenido" @@ -457,11 +458,11 @@ msgstr "Usar el nombre DCI" msgid "Use best" msgstr "Usar la mejor" -#: src/wx/film_editor.cc:391 +#: src/wx/film_editor.cc:395 msgid "Use content's audio" msgstr "Usar el audio del contenido" -#: src/wx/film_editor.cc:401 +#: src/wx/film_editor.cc:405 msgid "Use external audio" msgstr "Usar audio externo" @@ -469,11 +470,11 @@ msgstr "Usar audio externo" msgid "Video" msgstr "Vídeo" -#: src/wx/film_editor.cc:424 +#: src/wx/film_editor.cc:428 msgid "With Subtitles" msgstr "Con subtítulos" -#: src/wx/film_editor.cc:1271 +#: src/wx/film_editor.cc:1278 msgid "channels" msgstr "canales" @@ -481,20 +482,28 @@ msgstr "canales" msgid "counting..." msgstr "contando..." -#: src/wx/film_editor.cc:373 +#: src/wx/film_editor.cc:377 msgid "dB" msgstr "dB" -#: src/wx/film_editor.cc:696 src/wx/film_editor.cc:699 +#: src/wx/film_editor.cc:212 +msgid "encode all frames and play the subset" +msgstr "" + +#: src/wx/film_editor.cc:213 +msgid "encode only the subset" +msgstr "" + +#: src/wx/film_editor.cc:694 src/wx/film_editor.cc:697 msgid "frames" msgstr "fotogramas" #. / TRANSLATORS: this is an abbreviation for milliseconds, the unit of time -#: src/wx/film_editor.cc:386 +#: src/wx/film_editor.cc:390 msgid "ms" msgstr "ms" -#: src/wx/film_editor.cc:436 +#: src/wx/film_editor.cc:440 msgid "pixels" msgstr "" @@ -506,3 +515,6 @@ msgstr "s" #: src/wx/properties_dialog.cc:62 src/wx/properties_dialog.cc:63 msgid "unknown" msgstr "desconocido" + +#~ msgid "Original Size" +#~ msgstr "Tamaño original" diff --git a/src/wx/po/fr_FR.po b/src/wx/po/fr_FR.po index 80ee5dbfd..f06be6031 100644 --- a/src/wx/po/fr_FR.po +++ b/src/wx/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-09 11:14+0100\n" +"POT-Creation-Date: 2013-04-22 15:06+0100\n" "PO-Revision-Date: 2013-03-20 00:34+0100\n" "Last-Translator: FreeDCP.net \n" "Language-Team: \n" @@ -16,7 +16,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: src/wx/film_editor.cc:445 +#: src/wx/film_editor.cc:449 msgid "%" msgstr "%" @@ -24,7 +24,7 @@ msgstr "%" msgid "(restart DVD-o-matic to see language changes)" msgstr "" -#: src/wx/film_editor.cc:1269 +#: src/wx/film_editor.cc:1276 msgid "1 channel" msgstr "1 canal" @@ -40,11 +40,11 @@ msgstr "Ajouter" msgid "Audio" msgstr "Audio" -#: src/wx/film_editor.cc:381 +#: src/wx/film_editor.cc:385 msgid "Audio Delay" msgstr "Délai audio" -#: src/wx/film_editor.cc:369 +#: src/wx/film_editor.cc:373 msgid "Audio Gain" msgstr "Gain audio" @@ -52,7 +52,7 @@ msgstr "Gain audio" msgid "Audio Language (e.g. EN)" msgstr "Langue audio (ex. FR)" -#: src/wx/film_editor.cc:820 +#: src/wx/film_editor.cc:824 #, c-format msgid "Audio will be resampled from %dHz to %dHz\n" msgstr "" @@ -62,7 +62,7 @@ msgstr "" msgid "Bad setting for %s (%s)" msgstr "Mauvais paramètre pour %s (%s)" -#: src/wx/film_editor.cc:288 +#: src/wx/film_editor.cc:292 msgid "Bottom crop" msgstr "Découpe bas" @@ -74,7 +74,7 @@ msgstr "Parcourir..." msgid "But I have to use fader" msgstr "Je souhaite utiliser ce volume" -#: src/wx/film_editor.cc:374 +#: src/wx/film_editor.cc:378 msgid "Calculate..." msgstr "Calcul..." @@ -86,7 +86,7 @@ msgstr "Annuler" msgid "Channels" msgstr "Canaux" -#: src/wx/film_editor.cc:325 +#: src/wx/film_editor.cc:329 msgid "Colour look-up table" msgstr "Espace colorimétrique" @@ -98,7 +98,7 @@ msgstr "Contenu" msgid "Content Type" msgstr "Type de Contenu" -#: src/wx/film_viewer.cc:415 +#: src/wx/film_viewer.cc:451 #, c-format msgid "Could not decode video for view (%s)" msgstr "Décodage de la vidéo pour visualisation impossible (%s)" @@ -108,12 +108,12 @@ msgstr "Décodage de la vidéo pour visualisation impossible (%s)" msgid "Could not make DCP: %s" msgstr "Impossible de créer le DCP : %s" -#: src/wx/film_viewer.cc:107 +#: src/wx/film_viewer.cc:125 #, c-format msgid "Could not open content file (%s)" msgstr "Ouverture du contenu impossible (%s)" -#: src/wx/film_editor.cc:509 +#: src/wx/film_editor.cc:513 #, c-format msgid "Could not set content: %s" msgstr "Sélectionner du contenu impossible : %s" @@ -122,7 +122,7 @@ msgstr "Sélectionner du contenu impossible : %s" msgid "Create in folder" msgstr "Créer dans le dossier" -#: src/wx/film_editor.cc:1363 +#: src/wx/film_editor.cc:1371 #, c-format msgid "Cropped to %dx%d (%.2f:1)\n" msgstr "" @@ -177,7 +177,7 @@ msgid "Edit" msgstr "Édition" #: src/wx/config_dialog.cc:103 src/wx/config_dialog.cc:122 -#: src/wx/film_editor.cc:308 +#: src/wx/film_editor.cc:312 msgid "Edit..." msgstr "Éditer..." @@ -185,7 +185,7 @@ msgstr "Éditer..." msgid "Encoding Servers" msgstr "Serveurs d'encodage" -#: src/wx/film_editor.cc:176 +#: src/wx/film_editor.cc:171 msgid "End" msgstr "Fin" @@ -205,11 +205,11 @@ msgstr "Propriétés du film" msgid "Film name" msgstr "Nom du Film" -#: src/wx/film_editor.cc:303 src/wx/filter_dialog.cc:32 +#: src/wx/film_editor.cc:307 src/wx/filter_dialog.cc:32 msgid "Filters" msgstr "Filtres" -#: src/wx/film_editor.cc:268 +#: src/wx/film_editor.cc:272 msgid "Format" msgstr "Format" @@ -233,7 +233,7 @@ msgstr "Gb" msgid "Host name or IP address" msgstr "Nom de l'hôte ou adresse IP" -#: src/wx/film_editor.cc:1273 +#: src/wx/film_editor.cc:1280 msgid "Hz" msgstr "Hz" @@ -245,19 +245,19 @@ msgstr "Je veux le jouer à ce volume" msgid "IP address" msgstr "Adresse IP" -#: src/wx/film_editor.cc:335 +#: src/wx/film_editor.cc:339 msgid "JPEG2000 bandwidth" msgstr "Qualité JPEG2000" -#: src/wx/film_editor.cc:273 +#: src/wx/film_editor.cc:277 msgid "Left crop" msgstr "Découpe gauche" -#: src/wx/film_editor.cc:164 +#: src/wx/film_editor.cc:159 msgid "Length" msgstr "Longueur / durée" -#: src/wx/film_editor.cc:339 +#: src/wx/film_editor.cc:343 msgid "MBps" msgstr "MBps" @@ -273,7 +273,7 @@ msgstr "Nom" msgid "New Film" msgstr "Nouveau Film" -#: src/wx/film_editor.cc:305 src/wx/film_editor.cc:667 +#: src/wx/film_editor.cc:309 src/wx/film_editor.cc:671 msgid "None" msgstr "Aucun" @@ -281,11 +281,7 @@ msgstr "Aucun" msgid "Original Frame Rate" msgstr "Cadence d'images originale" -#: src/wx/film_editor.cc:159 -msgid "Original Size" -msgstr "Taille Originale" - -#: src/wx/film_editor.cc:1352 +#: src/wx/film_editor.cc:1360 #, c-format msgid "Original video is %dx%d (%.2f:1)\n" msgstr "" @@ -294,7 +290,7 @@ msgstr "" msgid "Package Type (e.g. OV)" msgstr "Type de paquet (ex. OV)" -#: src/wx/film_editor.cc:1384 +#: src/wx/film_editor.cc:1392 #, c-format msgid "Padded with black to %dx%d (%.2f:1)\n" msgstr "" @@ -303,7 +299,7 @@ msgstr "" msgid "Peak" msgstr "Crête" -#: src/wx/film_viewer.cc:54 +#: src/wx/film_viewer.cc:58 msgid "Play" msgstr "Lecture" @@ -331,7 +327,7 @@ msgstr "Échelle de référence pour A/B" msgid "Remove" msgstr "Supprimer" -#: src/wx/film_editor.cc:278 +#: src/wx/film_editor.cc:282 msgid "Right crop" msgstr "Découpe droite" @@ -339,16 +335,16 @@ msgstr "Découpe droite" msgid "Running" msgstr "Progression" -#: src/wx/film_editor.cc:1376 +#: src/wx/film_editor.cc:1384 #, c-format msgid "Scaled to %dx%d (%.2f:1)\n" msgstr "" -#: src/wx/film_editor.cc:315 +#: src/wx/film_editor.cc:319 msgid "Scaler" msgstr "Mise à l'échelle" -#: src/wx/film_editor.cc:407 +#: src/wx/film_editor.cc:411 msgid "Select Audio File" msgstr "Sélectionner le fichier son" @@ -364,7 +360,7 @@ msgstr "Serveur" msgid "Set language" msgstr "" -#: src/wx/film_editor.cc:364 +#: src/wx/film_editor.cc:368 msgid "Show Audio..." msgstr "Analyser le son..." @@ -372,7 +368,7 @@ msgstr "Analyser le son..." msgid "Smoothing" msgstr "Lissage" -#: src/wx/film_editor.cc:173 +#: src/wx/film_editor.cc:168 msgid "Start" msgstr "Début" @@ -384,11 +380,11 @@ msgstr "Studio (ex. TCF)" msgid "Subtitle Language (e.g. FR)" msgstr "Langue de sous-titres (ex. FR)" -#: src/wx/film_editor.cc:432 +#: src/wx/film_editor.cc:436 msgid "Subtitle Offset" msgstr "Décalage du sous-titre" -#: src/wx/film_editor.cc:441 +#: src/wx/film_editor.cc:445 msgid "Subtitle Scale" msgstr "Taille du sous-titre" @@ -432,14 +428,19 @@ msgstr "Nombre de processus à utiliser sur cet hôte" msgid "Time" msgstr "Durée" -#: src/wx/film_editor.cc:283 +#: src/wx/film_editor.cc:287 msgid "Top crop" msgstr "Découpe haut" -#: src/wx/film_editor.cc:171 +#: src/wx/film_editor.cc:166 msgid "Trim frames" msgstr "Images coupées" +#: src/wx/film_editor.cc:179 +#, fuzzy +msgid "Trim method" +msgstr "Images coupées" + #: src/wx/film_editor.cc:125 msgid "Trust content's header" msgstr "Faire confiance à l'en-tête" @@ -456,11 +457,11 @@ msgstr "Utiliser le nom DCI" msgid "Use best" msgstr "Automatique" -#: src/wx/film_editor.cc:391 +#: src/wx/film_editor.cc:395 msgid "Use content's audio" msgstr "Utiliser le son intégré" -#: src/wx/film_editor.cc:401 +#: src/wx/film_editor.cc:405 msgid "Use external audio" msgstr "Utiliser une source audio externe" @@ -468,11 +469,11 @@ msgstr "Utiliser une source audio externe" msgid "Video" msgstr "Vidéo" -#: src/wx/film_editor.cc:424 +#: src/wx/film_editor.cc:428 msgid "With Subtitles" msgstr "Avec sous-titres" -#: src/wx/film_editor.cc:1271 +#: src/wx/film_editor.cc:1278 msgid "channels" msgstr "canaux" @@ -480,20 +481,28 @@ msgstr "canaux" msgid "counting..." msgstr "calcul..." -#: src/wx/film_editor.cc:373 +#: src/wx/film_editor.cc:377 msgid "dB" msgstr "dB" -#: src/wx/film_editor.cc:696 src/wx/film_editor.cc:699 +#: src/wx/film_editor.cc:212 +msgid "encode all frames and play the subset" +msgstr "" + +#: src/wx/film_editor.cc:213 +msgid "encode only the subset" +msgstr "" + +#: src/wx/film_editor.cc:694 src/wx/film_editor.cc:697 msgid "frames" msgstr "images" #. / TRANSLATORS: this is an abbreviation for milliseconds, the unit of time -#: src/wx/film_editor.cc:386 +#: src/wx/film_editor.cc:390 msgid "ms" msgstr "ms" -#: src/wx/film_editor.cc:436 +#: src/wx/film_editor.cc:440 msgid "pixels" msgstr "" @@ -505,3 +514,6 @@ msgstr "s" #: src/wx/properties_dialog.cc:62 src/wx/properties_dialog.cc:63 msgid "unknown" msgstr "inconnu" + +#~ msgid "Original Size" +#~ msgstr "Taille Originale" diff --git a/src/wx/po/it_IT.po b/src/wx/po/it_IT.po index 78fd0dee9..c730a7ff7 100644 --- a/src/wx/po/it_IT.po +++ b/src/wx/po/it_IT.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-09 11:14+0100\n" +"POT-Creation-Date: 2013-04-22 15:06+0100\n" "PO-Revision-Date: 2013-04-03 12:37+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" @@ -17,7 +17,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" -#: src/wx/film_editor.cc:445 +#: src/wx/film_editor.cc:449 msgid "%" msgstr "%" @@ -25,7 +25,7 @@ msgstr "%" msgid "(restart DVD-o-matic to see language changes)" msgstr "(riavviare DVD-o-matic per vedere i cambiamenti di lingua)" -#: src/wx/film_editor.cc:1269 +#: src/wx/film_editor.cc:1276 msgid "1 channel" msgstr "Canale 1" @@ -41,11 +41,11 @@ msgstr "Aggiungi" msgid "Audio" msgstr "Audio" -#: src/wx/film_editor.cc:381 +#: src/wx/film_editor.cc:385 msgid "Audio Delay" msgstr "Ritardo dell'audio" -#: src/wx/film_editor.cc:369 +#: src/wx/film_editor.cc:373 msgid "Audio Gain" msgstr "Guadagno dell'audio" @@ -53,7 +53,7 @@ msgstr "Guadagno dell'audio" msgid "Audio Language (e.g. EN)" msgstr "Lingua dell'audio (es. EN)" -#: src/wx/film_editor.cc:820 +#: src/wx/film_editor.cc:824 #, c-format msgid "Audio will be resampled from %dHz to %dHz\n" msgstr "" @@ -63,7 +63,7 @@ msgstr "" msgid "Bad setting for %s (%s)" msgstr "Valore sbagliato per %s (%s)" -#: src/wx/film_editor.cc:288 +#: src/wx/film_editor.cc:292 msgid "Bottom crop" msgstr "Taglio in basso" @@ -75,7 +75,7 @@ msgstr "Sfoglia..." msgid "But I have to use fader" msgstr "Ma dovrò riprodurre con il fader a" -#: src/wx/film_editor.cc:374 +#: src/wx/film_editor.cc:378 msgid "Calculate..." msgstr "Calcola..." @@ -87,7 +87,7 @@ msgstr "Annulla" msgid "Channels" msgstr "Canali" -#: src/wx/film_editor.cc:325 +#: src/wx/film_editor.cc:329 msgid "Colour look-up table" msgstr "Tabella per ricerca del colore" @@ -99,7 +99,7 @@ msgstr "Contenuto" msgid "Content Type" msgstr "Tipo di contenuto" -#: src/wx/film_viewer.cc:415 +#: src/wx/film_viewer.cc:451 #, c-format msgid "Could not decode video for view (%s)" msgstr "Non posso decodificare il video per guardarlo (%s)" @@ -109,12 +109,12 @@ msgstr "Non posso decodificare il video per guardarlo (%s)" msgid "Could not make DCP: %s" msgstr "Non posso creare il DCP: %s" -#: src/wx/film_viewer.cc:107 +#: src/wx/film_viewer.cc:125 #, c-format msgid "Could not open content file (%s)" msgstr "Non posso aprire il file del contenuto (%s)" -#: src/wx/film_editor.cc:509 +#: src/wx/film_editor.cc:513 #, c-format msgid "Could not set content: %s" msgstr "Non posso regolare il contenuto: %s" @@ -123,7 +123,7 @@ msgstr "Non posso regolare il contenuto: %s" msgid "Create in folder" msgstr "Crea nella cartella" -#: src/wx/film_editor.cc:1363 +#: src/wx/film_editor.cc:1371 #, c-format msgid "Cropped to %dx%d (%.2f:1)\n" msgstr "" @@ -178,7 +178,7 @@ msgid "Edit" msgstr "Modifica" #: src/wx/config_dialog.cc:103 src/wx/config_dialog.cc:122 -#: src/wx/film_editor.cc:308 +#: src/wx/film_editor.cc:312 msgid "Edit..." msgstr "Modifica..." @@ -186,7 +186,7 @@ msgstr "Modifica..." msgid "Encoding Servers" msgstr "Servers di codifica" -#: src/wx/film_editor.cc:176 +#: src/wx/film_editor.cc:171 msgid "End" msgstr "Fine" @@ -206,11 +206,11 @@ msgstr "Proprietà del film" msgid "Film name" msgstr "Nome del film" -#: src/wx/film_editor.cc:303 src/wx/filter_dialog.cc:32 +#: src/wx/film_editor.cc:307 src/wx/filter_dialog.cc:32 msgid "Filters" msgstr "Filtri" -#: src/wx/film_editor.cc:268 +#: src/wx/film_editor.cc:272 msgid "Format" msgstr "Formato" @@ -234,7 +234,7 @@ msgstr "Gb" msgid "Host name or IP address" msgstr "Nome dell'Host o indirizzo IP" -#: src/wx/film_editor.cc:1273 +#: src/wx/film_editor.cc:1280 msgid "Hz" msgstr "Hz" @@ -246,19 +246,19 @@ msgstr "Sto usando il fader a" msgid "IP address" msgstr "Indirizzo IP" -#: src/wx/film_editor.cc:335 +#: src/wx/film_editor.cc:339 msgid "JPEG2000 bandwidth" msgstr "Banda passante JPEG2000" -#: src/wx/film_editor.cc:273 +#: src/wx/film_editor.cc:277 msgid "Left crop" msgstr "Taglio a sinistra" -#: src/wx/film_editor.cc:164 +#: src/wx/film_editor.cc:159 msgid "Length" msgstr "Lunghezza" -#: src/wx/film_editor.cc:339 +#: src/wx/film_editor.cc:343 msgid "MBps" msgstr "MBps" @@ -274,7 +274,7 @@ msgstr "Nome" msgid "New Film" msgstr "Nuovo Film" -#: src/wx/film_editor.cc:305 src/wx/film_editor.cc:667 +#: src/wx/film_editor.cc:309 src/wx/film_editor.cc:671 msgid "None" msgstr "Nessuno" @@ -282,11 +282,7 @@ msgstr "Nessuno" msgid "Original Frame Rate" msgstr "Frequenza fotogrammi originale" -#: src/wx/film_editor.cc:159 -msgid "Original Size" -msgstr "Dimensione Originale" - -#: src/wx/film_editor.cc:1352 +#: src/wx/film_editor.cc:1360 #, c-format msgid "Original video is %dx%d (%.2f:1)\n" msgstr "" @@ -295,7 +291,7 @@ msgstr "" msgid "Package Type (e.g. OV)" msgstr "Tipo di Package (es. OV)" -#: src/wx/film_editor.cc:1384 +#: src/wx/film_editor.cc:1392 #, c-format msgid "Padded with black to %dx%d (%.2f:1)\n" msgstr "" @@ -304,7 +300,7 @@ msgstr "" msgid "Peak" msgstr "Picco" -#: src/wx/film_viewer.cc:54 +#: src/wx/film_viewer.cc:58 msgid "Play" msgstr "Riproduci" @@ -332,7 +328,7 @@ msgstr "Scalatura di riferimento A/B" msgid "Remove" msgstr "Rimuovi" -#: src/wx/film_editor.cc:278 +#: src/wx/film_editor.cc:282 msgid "Right crop" msgstr "Taglio a destra" @@ -340,16 +336,16 @@ msgstr "Taglio a destra" msgid "Running" msgstr "In corso" -#: src/wx/film_editor.cc:1376 +#: src/wx/film_editor.cc:1384 #, c-format msgid "Scaled to %dx%d (%.2f:1)\n" msgstr "" -#: src/wx/film_editor.cc:315 +#: src/wx/film_editor.cc:319 msgid "Scaler" msgstr "Scaler" -#: src/wx/film_editor.cc:407 +#: src/wx/film_editor.cc:411 msgid "Select Audio File" msgstr "Seleziona file audio" @@ -365,7 +361,7 @@ msgstr "Server" msgid "Set language" msgstr "Seleziona la lingua" -#: src/wx/film_editor.cc:364 +#: src/wx/film_editor.cc:368 msgid "Show Audio..." msgstr "Mostra Audio..." @@ -373,7 +369,7 @@ msgstr "Mostra Audio..." msgid "Smoothing" msgstr "Levigatura" -#: src/wx/film_editor.cc:173 +#: src/wx/film_editor.cc:168 msgid "Start" msgstr "Inizio" @@ -385,11 +381,11 @@ msgstr "Studio (es. TCF)" msgid "Subtitle Language (e.g. FR)" msgstr "Lingua dei Sottotitoli (es. FR)" -#: src/wx/film_editor.cc:432 +#: src/wx/film_editor.cc:436 msgid "Subtitle Offset" msgstr "Sfalsamento dei Sottotitoli" -#: src/wx/film_editor.cc:441 +#: src/wx/film_editor.cc:445 msgid "Subtitle Scale" msgstr "Scala dei Sottotitoli" @@ -433,14 +429,19 @@ msgstr "Threads da usare per codificare su questo host" msgid "Time" msgstr "Tempo" -#: src/wx/film_editor.cc:283 +#: src/wx/film_editor.cc:287 msgid "Top crop" msgstr "Taglio in alto" -#: src/wx/film_editor.cc:171 +#: src/wx/film_editor.cc:166 msgid "Trim frames" msgstr "Taglia fotogrammi" +#: src/wx/film_editor.cc:179 +#, fuzzy +msgid "Trim method" +msgstr "Taglia fotogrammi" + #: src/wx/film_editor.cc:125 msgid "Trust content's header" msgstr "Conferma l'intestazione del contenuto" @@ -457,11 +458,11 @@ msgstr "Usa nome DCI" msgid "Use best" msgstr "Usa la migliore" -#: src/wx/film_editor.cc:391 +#: src/wx/film_editor.cc:395 msgid "Use content's audio" msgstr "Usa l'audio del contenuto" -#: src/wx/film_editor.cc:401 +#: src/wx/film_editor.cc:405 msgid "Use external audio" msgstr "Usa l'audio esterno" @@ -469,11 +470,11 @@ msgstr "Usa l'audio esterno" msgid "Video" msgstr "Video" -#: src/wx/film_editor.cc:424 +#: src/wx/film_editor.cc:428 msgid "With Subtitles" msgstr "Con Sottotitoli" -#: src/wx/film_editor.cc:1271 +#: src/wx/film_editor.cc:1278 msgid "channels" msgstr "canali" @@ -481,20 +482,28 @@ msgstr "canali" msgid "counting..." msgstr "conteggio..." -#: src/wx/film_editor.cc:373 +#: src/wx/film_editor.cc:377 msgid "dB" msgstr "dB" -#: src/wx/film_editor.cc:696 src/wx/film_editor.cc:699 +#: src/wx/film_editor.cc:212 +msgid "encode all frames and play the subset" +msgstr "" + +#: src/wx/film_editor.cc:213 +msgid "encode only the subset" +msgstr "" + +#: src/wx/film_editor.cc:694 src/wx/film_editor.cc:697 msgid "frames" msgstr "fotogrammi" #. / TRANSLATORS: this is an abbreviation for milliseconds, the unit of time -#: src/wx/film_editor.cc:386 +#: src/wx/film_editor.cc:390 msgid "ms" msgstr "ms" -#: src/wx/film_editor.cc:436 +#: src/wx/film_editor.cc:440 msgid "pixels" msgstr "" @@ -506,3 +515,6 @@ msgstr "s" #: src/wx/properties_dialog.cc:62 src/wx/properties_dialog.cc:63 msgid "unknown" msgstr "sconosciuto" + +#~ msgid "Original Size" +#~ msgstr "Dimensione Originale" diff --git a/src/wx/po/sv_SE.po b/src/wx/po/sv_SE.po index e52589ff0..4127d77f8 100644 --- a/src/wx/po/sv_SE.po +++ b/src/wx/po/sv_SE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-09 11:14+0100\n" +"POT-Creation-Date: 2013-04-22 15:06+0100\n" "PO-Revision-Date: 2013-04-09 10:13+0100\n" "Last-Translator: Adam Klotblixt \n" "Language-Team: \n" @@ -17,7 +17,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" -#: src/wx/film_editor.cc:445 +#: src/wx/film_editor.cc:449 msgid "%" msgstr "%" @@ -25,7 +25,7 @@ msgstr "%" msgid "(restart DVD-o-matic to see language changes)" msgstr "(starta om DVD-o-matic för att se språkändringar)" -#: src/wx/film_editor.cc:1269 +#: src/wx/film_editor.cc:1276 msgid "1 channel" msgstr "1 kanal" @@ -41,11 +41,11 @@ msgstr "Lägg till" msgid "Audio" msgstr "Audio" -#: src/wx/film_editor.cc:381 +#: src/wx/film_editor.cc:385 msgid "Audio Delay" msgstr "Audio Fördröjning" -#: src/wx/film_editor.cc:369 +#: src/wx/film_editor.cc:373 msgid "Audio Gain" msgstr "Audio Förstärkning" @@ -53,7 +53,7 @@ msgstr "Audio Förstärkning" msgid "Audio Language (e.g. EN)" msgstr "Audio Språk (ex. SV)" -#: src/wx/film_editor.cc:820 +#: src/wx/film_editor.cc:824 #, c-format msgid "Audio will be resampled from %dHz to %dHz\n" msgstr "Audio kommer att samplas om från %dHz till %dHz\n" @@ -63,7 +63,7 @@ msgstr "Audio kommer att samplas om från %dHz till %dHz\n" msgid "Bad setting for %s (%s)" msgstr "Felaktig inställning för %s (%s)" -#: src/wx/film_editor.cc:288 +#: src/wx/film_editor.cc:292 msgid "Bottom crop" msgstr "Nedre beskärning" @@ -75,7 +75,7 @@ msgstr "Bläddra..." msgid "But I have to use fader" msgstr "Men jag måste använda mixervolym" -#: src/wx/film_editor.cc:374 +#: src/wx/film_editor.cc:378 msgid "Calculate..." msgstr "Beräkna..." @@ -87,7 +87,7 @@ msgstr "Avbryt" msgid "Channels" msgstr "Kanaler" -#: src/wx/film_editor.cc:325 +#: src/wx/film_editor.cc:329 msgid "Colour look-up table" msgstr "Färguppslagningstabell" @@ -99,7 +99,7 @@ msgstr "Innehåll" msgid "Content Type" msgstr "Innehållstyp" -#: src/wx/film_viewer.cc:415 +#: src/wx/film_viewer.cc:451 #, c-format msgid "Could not decode video for view (%s)" msgstr "Kunde inte avkoda video för visning (%s)" @@ -109,12 +109,12 @@ msgstr "Kunde inte avkoda video för visning (%s)" msgid "Could not make DCP: %s" msgstr "Kunde inte skapa DCP: %s" -#: src/wx/film_viewer.cc:107 +#: src/wx/film_viewer.cc:125 #, c-format msgid "Could not open content file (%s)" msgstr "Kunde inte öppna innehållsfilen (%s)" -#: src/wx/film_editor.cc:509 +#: src/wx/film_editor.cc:513 #, c-format msgid "Could not set content: %s" msgstr "Kunde inte fastställa innehåll: %s" @@ -123,7 +123,7 @@ msgstr "Kunde inte fastställa innehåll: %s" msgid "Create in folder" msgstr "Skapa i katalog" -#: src/wx/film_editor.cc:1363 +#: src/wx/film_editor.cc:1371 #, c-format msgid "Cropped to %dx%d (%.2f:1)\n" msgstr "Beskuren till %dx%d (%.2f:1)\n" @@ -178,7 +178,7 @@ msgid "Edit" msgstr "Redigera" #: src/wx/config_dialog.cc:103 src/wx/config_dialog.cc:122 -#: src/wx/film_editor.cc:308 +#: src/wx/film_editor.cc:312 msgid "Edit..." msgstr "Redigera..." @@ -186,7 +186,7 @@ msgstr "Redigera..." msgid "Encoding Servers" msgstr "Kodningsservrar" -#: src/wx/film_editor.cc:176 +#: src/wx/film_editor.cc:171 msgid "End" msgstr "Slut" @@ -206,11 +206,11 @@ msgstr "Film Egenskaper" msgid "Film name" msgstr "film namn" -#: src/wx/film_editor.cc:303 src/wx/filter_dialog.cc:32 +#: src/wx/film_editor.cc:307 src/wx/filter_dialog.cc:32 msgid "Filters" msgstr "Filter" -#: src/wx/film_editor.cc:268 +#: src/wx/film_editor.cc:272 msgid "Format" msgstr "Format" @@ -234,7 +234,7 @@ msgstr "Gb" msgid "Host name or IP address" msgstr "Värd-namn eller IP-adress" -#: src/wx/film_editor.cc:1273 +#: src/wx/film_editor.cc:1280 msgid "Hz" msgstr "Hz" @@ -246,19 +246,19 @@ msgstr "Jag vill spela upp detta med mixervolym" msgid "IP address" msgstr "IP-adress" -#: src/wx/film_editor.cc:335 +#: src/wx/film_editor.cc:339 msgid "JPEG2000 bandwidth" msgstr "JPEG2000 bandbredd" -#: src/wx/film_editor.cc:273 +#: src/wx/film_editor.cc:277 msgid "Left crop" msgstr "Vänster beskärning" -#: src/wx/film_editor.cc:164 +#: src/wx/film_editor.cc:159 msgid "Length" msgstr "Längd" -#: src/wx/film_editor.cc:339 +#: src/wx/film_editor.cc:343 msgid "MBps" msgstr "MBps" @@ -274,7 +274,7 @@ msgstr "Namn" msgid "New Film" msgstr "Ny Film" -#: src/wx/film_editor.cc:305 src/wx/film_editor.cc:667 +#: src/wx/film_editor.cc:309 src/wx/film_editor.cc:671 msgid "None" msgstr "Inget" @@ -282,11 +282,7 @@ msgstr "Inget" msgid "Original Frame Rate" msgstr "Ursprunglig bildhastighet" -#: src/wx/film_editor.cc:159 -msgid "Original Size" -msgstr "Ursprunglig Storlek" - -#: src/wx/film_editor.cc:1352 +#: src/wx/film_editor.cc:1360 #, c-format msgid "Original video is %dx%d (%.2f:1)\n" msgstr "Original-videon är %dx%d (%.2f:1)\n" @@ -295,7 +291,7 @@ msgstr "Original-videon är %dx%d (%.2f:1)\n" msgid "Package Type (e.g. OV)" msgstr "Förpackningstyp (ex. OV)" -#: src/wx/film_editor.cc:1384 +#: src/wx/film_editor.cc:1392 #, c-format msgid "Padded with black to %dx%d (%.2f:1)\n" msgstr "Svarta kanter tillagda för %dx%d (%.2f:1)\n" @@ -304,7 +300,7 @@ msgstr "Svarta kanter tillagda för %dx%d (%.2f:1)\n" msgid "Peak" msgstr "Topp" -#: src/wx/film_viewer.cc:54 +#: src/wx/film_viewer.cc:58 msgid "Play" msgstr "Spela" @@ -332,7 +328,7 @@ msgstr "Referensomskalare för A/B" msgid "Remove" msgstr "Ta bort" -#: src/wx/film_editor.cc:278 +#: src/wx/film_editor.cc:282 msgid "Right crop" msgstr "Höger beskärning" @@ -340,16 +336,16 @@ msgstr "Höger beskärning" msgid "Running" msgstr "Körs" -#: src/wx/film_editor.cc:1376 +#: src/wx/film_editor.cc:1384 #, c-format msgid "Scaled to %dx%d (%.2f:1)\n" msgstr "Skalad till %dx%d (%.2f:1)\n" -#: src/wx/film_editor.cc:315 +#: src/wx/film_editor.cc:319 msgid "Scaler" msgstr "Omskalare" -#: src/wx/film_editor.cc:407 +#: src/wx/film_editor.cc:411 msgid "Select Audio File" msgstr "Välj audiofil" @@ -365,7 +361,7 @@ msgstr "Server" msgid "Set language" msgstr "Välj språk" -#: src/wx/film_editor.cc:364 +#: src/wx/film_editor.cc:368 msgid "Show Audio..." msgstr "Visa Audio..." @@ -373,7 +369,7 @@ msgstr "Visa Audio..." msgid "Smoothing" msgstr "Utjämning" -#: src/wx/film_editor.cc:173 +#: src/wx/film_editor.cc:168 msgid "Start" msgstr "Start" @@ -385,11 +381,11 @@ msgstr "Studio (ex. TCF)" msgid "Subtitle Language (e.g. FR)" msgstr "Undertextspråk (ex. SV)" -#: src/wx/film_editor.cc:432 +#: src/wx/film_editor.cc:436 msgid "Subtitle Offset" msgstr "Undertext Förskjutning" -#: src/wx/film_editor.cc:441 +#: src/wx/film_editor.cc:445 msgid "Subtitle Scale" msgstr "Undertext Skalning" @@ -433,14 +429,19 @@ msgstr "Antal trådar att använda vid kodning på denna maskin" msgid "Time" msgstr "Tid" -#: src/wx/film_editor.cc:283 +#: src/wx/film_editor.cc:287 msgid "Top crop" msgstr "Övre beskärning" -#: src/wx/film_editor.cc:171 +#: src/wx/film_editor.cc:166 msgid "Trim frames" msgstr "Skippa bilder" +#: src/wx/film_editor.cc:179 +#, fuzzy +msgid "Trim method" +msgstr "Skippa bilder" + #: src/wx/film_editor.cc:125 msgid "Trust content's header" msgstr "Lita på källans information" @@ -457,11 +458,11 @@ msgstr "Använd DCI-namnet" msgid "Use best" msgstr "Använd bästa" -#: src/wx/film_editor.cc:391 +#: src/wx/film_editor.cc:395 msgid "Use content's audio" msgstr "Använd innehållets audio" -#: src/wx/film_editor.cc:401 +#: src/wx/film_editor.cc:405 msgid "Use external audio" msgstr "Använd extern audio" @@ -469,11 +470,11 @@ msgstr "Använd extern audio" msgid "Video" msgstr "Video" -#: src/wx/film_editor.cc:424 +#: src/wx/film_editor.cc:428 msgid "With Subtitles" msgstr "Med Undertexter" -#: src/wx/film_editor.cc:1271 +#: src/wx/film_editor.cc:1278 msgid "channels" msgstr "kanaler" @@ -481,20 +482,28 @@ msgstr "kanaler" msgid "counting..." msgstr "räknar..." -#: src/wx/film_editor.cc:373 +#: src/wx/film_editor.cc:377 msgid "dB" msgstr "dB" -#: src/wx/film_editor.cc:696 src/wx/film_editor.cc:699 +#: src/wx/film_editor.cc:212 +msgid "encode all frames and play the subset" +msgstr "" + +#: src/wx/film_editor.cc:213 +msgid "encode only the subset" +msgstr "" + +#: src/wx/film_editor.cc:694 src/wx/film_editor.cc:697 msgid "frames" msgstr "bilder" #. / TRANSLATORS: this is an abbreviation for milliseconds, the unit of time -#: src/wx/film_editor.cc:386 +#: src/wx/film_editor.cc:390 msgid "ms" msgstr "ms" -#: src/wx/film_editor.cc:436 +#: src/wx/film_editor.cc:440 msgid "pixels" msgstr "pixlar" @@ -506,3 +515,6 @@ msgstr "s" #: src/wx/properties_dialog.cc:62 src/wx/properties_dialog.cc:63 msgid "unknown" msgstr "okänt" + +#~ msgid "Original Size" +#~ msgstr "Ursprunglig Storlek" -- cgit v1.2.3 From 979f68288ffe879a46a51a0f45175c7feb624a62 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 22 Apr 2013 15:08:32 +0100 Subject: fr_FR translation for a couple of new strings from Thierry (#125). --- src/wx/po/fr_FR.po | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/wx/po/fr_FR.po b/src/wx/po/fr_FR.po index f06be6031..c7ef31f5a 100644 --- a/src/wx/po/fr_FR.po +++ b/src/wx/po/fr_FR.po @@ -437,9 +437,8 @@ msgid "Trim frames" msgstr "Images coupées" #: src/wx/film_editor.cc:179 -#, fuzzy msgid "Trim method" -msgstr "Images coupées" +msgstr "Méthod de découpage" #: src/wx/film_editor.cc:125 msgid "Trust content's header" @@ -487,11 +486,11 @@ msgstr "dB" #: src/wx/film_editor.cc:212 msgid "encode all frames and play the subset" -msgstr "" +msgstr "encoder toutes les images mais lire seulement la sélection" #: src/wx/film_editor.cc:213 msgid "encode only the subset" -msgstr "" +msgstr "encoder seulement la sélection" #: src/wx/film_editor.cc:694 src/wx/film_editor.cc:697 msgid "frames" -- cgit v1.2.3 From 425ef773dbf91d2fecd8e2fbdc20becbfbda46f8 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 23 Apr 2013 16:17:20 +0100 Subject: Connect Trimmer clsas. --- src/lib/ab_transcoder.cc | 37 ++++++++++++++++++++++++++++++------- src/lib/ab_transcoder.h | 2 ++ src/lib/audio_source.cc | 6 ++++++ src/lib/audio_source.h | 1 + src/lib/transcoder.cc | 19 +++++++++++++++---- src/lib/transcoder.h | 2 ++ src/lib/video_source.cc | 8 ++++++++ src/lib/video_source.h | 1 + 8 files changed, 65 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/lib/ab_transcoder.cc b/src/lib/ab_transcoder.cc index 6eef397c2..26643b50e 100644 --- a/src/lib/ab_transcoder.cc +++ b/src/lib/ab_transcoder.cc @@ -32,6 +32,7 @@ #include "delay_line.h" #include "gain.h" #include "combiner.h" +#include "trimmer.h" /** @file src/ab_transcoder.cc * @brief A transcoder which uses one Film for the left half of the screen, and a different one @@ -61,26 +62,48 @@ ABTranscoder::ABTranscoder ( _db = decoder_factory (_film_b, o); shared_ptr st = _film_a->audio_stream(); - _matcher.reset (new Matcher (_film_a->log(), st->sample_rate(), _film_a->source_frame_rate())); + if (st) { + _matcher.reset (new Matcher (_film_a->log(), st->sample_rate(), _film_a->source_frame_rate())); + } _delay_line.reset (new DelayLine (_film_a->log(), _film_a->audio_delay() / 1000.0f)); _gain.reset (new Gain (_film_a->log(), _film_a->audio_gain())); + int const sr = st ? st->sample_rate() : 0; + int const trim_start = _film_a->trim_type() == Film::ENCODE ? _film_a->trim_start() : 0; + int const trim_end = _film_a->trim_type() == Film::ENCODE ? _film_a->trim_end() : 0; + _trimmer.reset (new Trimmer ( + _film_a->log(), trim_start, trim_end, _film_a->length().get(), + sr, _film_a->source_frame_rate(), _film_a->dcp_frame_rate() + )); + /* Set up the decoder to use the film's set streams */ _da.video->set_subtitle_stream (_film_a->subtitle_stream ()); _db.video->set_subtitle_stream (_film_a->subtitle_stream ()); - _da.audio->set_audio_stream (_film_a->audio_stream ()); + if (_film_a->audio_stream ()) { + _da.audio->set_audio_stream (_film_a->audio_stream ()); + } _da.video->Video.connect (bind (&Combiner::process_video, _combiner, _1, _2, _3, _4)); _db.video->Video.connect (bind (&Combiner::process_video_b, _combiner, _1, _2, _3, _4)); _combiner->connect_video (_delay_line); - _delay_line->connect_video (_matcher); - _matcher->connect_video (_encoder); + if (_matcher) { + _delay_line->connect_video (_matcher); + _matcher->connect_video (_trimmer); + } else { + _delay_line->connect_video (_trimmer); + } + _trimmer->connect_video (_encoder); _da.audio->connect_audio (_delay_line); - _delay_line->connect_audio (_matcher); - _matcher->connect_audio (_gain); - _gain->connect_audio (_encoder); + if (_matcher) { + _delay_line->connect_audio (_matcher); + _matcher->connect_audio (_gain); + } else { + _delay_line->connect_audio (_gain); + } + _gain->connect_audio (_trimmer); + _trimmer->connect_audio (_encoder); } void diff --git a/src/lib/ab_transcoder.h b/src/lib/ab_transcoder.h index 58a08af04..4f1b14e48 100644 --- a/src/lib/ab_transcoder.h +++ b/src/lib/ab_transcoder.h @@ -39,6 +39,7 @@ class Matcher; class DelayLine; class Gain; class Combiner; +class Trimmer; /** @class ABTranscoder * @brief A transcoder which uses one Film for the left half of the screen, and a different one @@ -68,5 +69,6 @@ private: boost::shared_ptr _matcher; boost::shared_ptr _delay_line; boost::shared_ptr _gain; + boost::shared_ptr _trimmer; boost::shared_ptr _image; }; diff --git a/src/lib/audio_source.cc b/src/lib/audio_source.cc index bca3562cf..d77e89367 100644 --- a/src/lib/audio_source.cc +++ b/src/lib/audio_source.cc @@ -34,3 +34,9 @@ TimedAudioSource::connect_audio (shared_ptr s) { Audio.connect (bind (&TimedAudioSink::process_audio, s, _1, _2)); } + +void +TimedAudioSource::connect_audio (shared_ptr s) +{ + Audio.connect (bind (&AudioSink::process_audio, s, _1)); +} diff --git a/src/lib/audio_source.h b/src/lib/audio_source.h index 3dc998cca..e255d566d 100644 --- a/src/lib/audio_source.h +++ b/src/lib/audio_source.h @@ -48,6 +48,7 @@ public: /** Emitted when some audio data is ready */ boost::signals2::signal, double)> Audio; + void connect_audio (boost::shared_ptr); void connect_audio (boost::shared_ptr); }; diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc index e00b2f1e0..a10789e11 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -36,6 +36,7 @@ #include "gain.h" #include "video_decoder.h" #include "audio_decoder.h" +#include "trimmer.h" using std::string; using boost::shared_ptr; @@ -61,6 +62,14 @@ Transcoder::Transcoder (shared_ptr f, DecodeOptions o, Job* j, shared_ptr< _delay_line.reset (new DelayLine (f->log(), f->audio_delay() / 1000.0f)); _gain.reset (new Gain (f->log(), f->audio_gain())); + int const sr = st ? st->sample_rate() : 0; + int const trim_start = f->trim_type() == Film::ENCODE ? f->trim_start() : 0; + int const trim_end = f->trim_type() == Film::ENCODE ? f->trim_end() : 0; + _trimmer.reset (new Trimmer ( + f->log(), trim_start, trim_end, f->length().get(), + sr, f->source_frame_rate(), f->dcp_frame_rate() + )); + /* Set up the decoder to use the film's set streams */ _decoders.video->set_subtitle_stream (f->subtitle_stream ()); if (f->audio_stream ()) { @@ -70,19 +79,21 @@ Transcoder::Transcoder (shared_ptr f, DecodeOptions o, Job* j, shared_ptr< _decoders.video->connect_video (_delay_line); if (_matcher) { _delay_line->connect_video (_matcher); - _matcher->connect_video (_encoder); + _matcher->connect_video (_trimmer); } else { - _delay_line->Video.connect (bind (&Encoder::process_video, _encoder, _1, _2, _3)); + _delay_line->connect_video (_trimmer); } + _trimmer->connect_video (_encoder); _decoders.audio->connect_audio (_delay_line); if (_matcher) { _delay_line->connect_audio (_matcher); _matcher->connect_audio (_gain); } else { - _delay_line->Audio.connect (bind (&Encoder::process_audio, _encoder, _1)); + _delay_line->connect_audio (_gain); } - _gain->connect_audio (_encoder); + _gain->connect_audio (_trimmer); + _trimmer->connect_audio (_encoder); } /** Run the decoder, passing its output to the encoder, until the decoder diff --git a/src/lib/transcoder.h b/src/lib/transcoder.h index b0c263d07..f5b8ae6e3 100644 --- a/src/lib/transcoder.h +++ b/src/lib/transcoder.h @@ -35,6 +35,7 @@ class Gain; class VideoDecoder; class AudioDecoder; class DelayLine; +class Trimmer; /** @class Transcoder * @brief A class which takes a Film and some Options, then uses those to transcode the film. @@ -68,4 +69,5 @@ protected: boost::shared_ptr _matcher; boost::shared_ptr _delay_line; boost::shared_ptr _gain; + boost::shared_ptr _trimmer; }; diff --git a/src/lib/video_source.cc b/src/lib/video_source.cc index af6f941fd..539243402 100644 --- a/src/lib/video_source.cc +++ b/src/lib/video_source.cc @@ -34,3 +34,11 @@ TimedVideoSource::connect_video (shared_ptr s) { Video.connect (bind (&TimedVideoSink::process_video, s, _1, _2, _3, _4)); } + +void +TimedVideoSource::connect_video (shared_ptr s) +{ + Video.connect (bind (&VideoSink::process_video, s, _1, _2, _3)); +} + + diff --git a/src/lib/video_source.h b/src/lib/video_source.h index 705b0023a..e4a8ab058 100644 --- a/src/lib/video_source.h +++ b/src/lib/video_source.h @@ -65,6 +65,7 @@ public: */ boost::signals2::signal, bool, boost::shared_ptr, double)> Video; + void connect_video (boost::shared_ptr); void connect_video (boost::shared_ptr); }; -- cgit v1.2.3 From be1862fefb1378c78bcc4bd6334694797755ea47 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 23 Apr 2013 20:46:45 +0100 Subject: Add a test; turn off verbose logging by default in makedcp; improve log message. --- src/lib/matcher.cc | 6 +++++- src/tools/makedcp.cc | 2 +- test/test.cc | 59 +++++++++++++++++++++++++++++++++++++--------------- 3 files changed, 48 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/lib/matcher.cc b/src/lib/matcher.cc index 34ddc86d6..dd0312f67 100644 --- a/src/lib/matcher.cc +++ b/src/lib/matcher.cc @@ -94,7 +94,11 @@ Matcher::process_audio (boost::shared_ptr b, double t) { _channels = b->channels (); - _log->log (String::compose ("Matcher audio @ %1 [video=%2, audio=%3, pending_audio=%4]", t, _video_frames, _audio_frames, _pending_audio.size())); + _log->log (String::compose ( + "Matcher audio (%1 frames) @ %2 [video=%3, audio=%4, pending_audio=%5]", + b->frames(), t, _video_frames, _audio_frames, _pending_audio.size() + ) + ); if (!_first_input) { _first_input = t; diff --git a/src/tools/makedcp.cc b/src/tools/makedcp.cc index 0c6390771..c594991a6 100644 --- a/src/tools/makedcp.cc +++ b/src/tools/makedcp.cc @@ -64,7 +64,7 @@ main (int argc, char* argv[]) bool test_mode = false; bool progress = true; bool no_remote = false; - int log_level = 1; + int log_level = 0; int option_index = 0; while (1) { diff --git a/test/test.cc b/test/test.cc index b0b2cef7d..595d8fc93 100644 --- a/test/test.cc +++ b/test/test.cc @@ -123,52 +123,77 @@ BOOST_AUTO_TEST_CASE (make_black_test) } } -shared_ptr trimmer_test_last; +shared_ptr trimmer_test_last_video; +shared_ptr trimmer_test_last_audio; void -trimmer_test_helper (shared_ptr audio) +trimmer_test_video_helper (shared_ptr image, bool, shared_ptr) { - trimmer_test_last = audio; + trimmer_test_last_video = image; } +void +trimmer_test_audio_helper (shared_ptr audio) +{ + trimmer_test_last_audio = audio; +} + +BOOST_AUTO_TEST_CASE (trimmer_passthrough_test) +{ + Trimmer trimmer (shared_ptr (), 0, 0, 200, 48000, 25, 25); + trimmer.Video.connect (bind (&trimmer_test_video_helper, _1, _2, _3)); + trimmer.Audio.connect (bind (&trimmer_test_audio_helper, _1)); + + shared_ptr video (new SimpleImage (PIX_FMT_RGB24, libdcp::Size (1998, 1080), true)); + shared_ptr audio (new AudioBuffers (6, 42 * 1920)); + + trimmer.process_video (video, false, shared_ptr ()); + trimmer.process_audio (audio); + + BOOST_CHECK_EQUAL (video.get(), trimmer_test_last_video.get()); + BOOST_CHECK_EQUAL (audio.get(), trimmer_test_last_audio.get()); + BOOST_CHECK_EQUAL (audio->frames(), trimmer_test_last_audio->frames()); +} + + /** Test the audio handling of the Trimmer */ -BOOST_AUTO_TEST_CASE (trimmer_test) +BOOST_AUTO_TEST_CASE (trimmer_audio_test) { Trimmer trimmer (shared_ptr (), 25, 75, 200, 48000, 25, 25); - trimmer.Audio.connect (bind (&trimmer_test_helper, _1)); + trimmer.Audio.connect (bind (&trimmer_test_audio_helper, _1)); /* 21 video frames-worth of audio frames; should be completely stripped */ - trimmer_test_last.reset (); + trimmer_test_last_audio.reset (); shared_ptr audio (new AudioBuffers (6, 21 * 1920)); trimmer.process_audio (audio); - BOOST_CHECK (trimmer_test_last == 0); + BOOST_CHECK (trimmer_test_last_audio == 0); /* 42 more video frames-worth, 4 should be stripped from the start */ audio.reset (new AudioBuffers (6, 42 * 1920)); trimmer.process_audio (audio); - BOOST_CHECK (trimmer_test_last); - BOOST_CHECK_EQUAL (trimmer_test_last->frames(), 38 * 1920); + BOOST_CHECK (trimmer_test_last_audio); + BOOST_CHECK_EQUAL (trimmer_test_last_audio->frames(), 38 * 1920); /* 42 more video frames-worth, should be kept as-is */ - trimmer_test_last.reset (); + trimmer_test_last_audio.reset (); audio.reset (new AudioBuffers (6, 42 * 1920)); trimmer.process_audio (audio); - BOOST_CHECK (trimmer_test_last); - BOOST_CHECK_EQUAL (trimmer_test_last->frames(), 42 * 1920); + BOOST_CHECK (trimmer_test_last_audio); + BOOST_CHECK_EQUAL (trimmer_test_last_audio->frames(), 42 * 1920); /* 25 more video frames-worth, 5 should be trimmed from the end */ - trimmer_test_last.reset (); + trimmer_test_last_audio.reset (); audio.reset (new AudioBuffers (6, 25 * 1920)); trimmer.process_audio (audio); - BOOST_CHECK (trimmer_test_last); - BOOST_CHECK_EQUAL (trimmer_test_last->frames(), 20 * 1920); + BOOST_CHECK (trimmer_test_last_audio); + BOOST_CHECK_EQUAL (trimmer_test_last_audio->frames(), 20 * 1920); /* Now some more; all should be trimmed */ - trimmer_test_last.reset (); + trimmer_test_last_audio.reset (); audio.reset (new AudioBuffers (6, 100 * 1920)); trimmer.process_audio (audio); - BOOST_CHECK (trimmer_test_last == 0); + BOOST_CHECK (trimmer_test_last_audio == 0); } -- cgit v1.2.3 From 8dd9ea3086b4934f2719648ffa6333c0d106ff36 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 24 Apr 2013 01:02:25 +0100 Subject: Some const correctness. --- src/lib/analyse_audio_job.cc | 2 +- src/lib/analyse_audio_job.h | 2 +- src/lib/audio_sink.h | 4 +- src/lib/audio_source.h | 4 +- src/lib/combiner.cc | 6 +-- src/lib/combiner.h | 4 +- src/lib/delay_line.cc | 4 +- src/lib/delay_line.h | 4 +- src/lib/encoder.cc | 4 +- src/lib/encoder.h | 4 +- src/lib/gain.cc | 2 +- src/lib/gain.h | 2 +- src/lib/image.cc | 6 +++ src/lib/image.h | 6 +++ src/lib/matcher.cc | 9 +++-- src/lib/matcher.h | 10 ++--- src/lib/trimmer.cc | 10 +++-- src/lib/trimmer.h | 4 +- src/lib/util.cc | 90 +++++++++++++++++++++++++++++--------------- src/lib/util.h | 1 + src/lib/video_sink.h | 4 +- src/lib/video_source.h | 4 +- src/tools/servomatictest.cc | 2 +- src/wx/film_viewer.cc | 4 +- src/wx/film_viewer.h | 6 +-- test/test.cc | 8 ++-- 26 files changed, 125 insertions(+), 81 deletions(-) (limited to 'src') diff --git a/src/lib/analyse_audio_job.cc b/src/lib/analyse_audio_job.cc index 43eecbcbd..88cd65fee 100644 --- a/src/lib/analyse_audio_job.cc +++ b/src/lib/analyse_audio_job.cc @@ -84,7 +84,7 @@ AnalyseAudioJob::run () } void -AnalyseAudioJob::audio (shared_ptr b) +AnalyseAudioJob::audio (shared_ptr b) { for (int i = 0; i < b->frames(); ++i) { for (int j = 0; j < b->channels(); ++j) { diff --git a/src/lib/analyse_audio_job.h b/src/lib/analyse_audio_job.h index dc1e073ee..5435e0a7c 100644 --- a/src/lib/analyse_audio_job.h +++ b/src/lib/analyse_audio_job.h @@ -31,7 +31,7 @@ public: void run (); private: - void audio (boost::shared_ptr); + void audio (boost::shared_ptr); int64_t _done; int64_t _samples_per_point; diff --git a/src/lib/audio_sink.h b/src/lib/audio_sink.h index f34b24f88..69b3a4b75 100644 --- a/src/lib/audio_sink.h +++ b/src/lib/audio_sink.h @@ -24,14 +24,14 @@ class AudioSink { public: /** Call with some audio data */ - virtual void process_audio (boost::shared_ptr) = 0; + virtual void process_audio (boost::shared_ptr) = 0; }; class TimedAudioSink { public: /** Call with some audio data */ - virtual void process_audio (boost::shared_ptr, double t) = 0; + virtual void process_audio (boost::shared_ptr, double t) = 0; }; #endif diff --git a/src/lib/audio_source.h b/src/lib/audio_source.h index e255d566d..c13f1636b 100644 --- a/src/lib/audio_source.h +++ b/src/lib/audio_source.h @@ -35,7 +35,7 @@ class AudioSource { public: /** Emitted when some audio data is ready */ - boost::signals2::signal)> Audio; + boost::signals2::signal)> Audio; void connect_audio (boost::shared_ptr); }; @@ -46,7 +46,7 @@ class TimedAudioSource { public: /** Emitted when some audio data is ready */ - boost::signals2::signal, double)> Audio; + boost::signals2::signal, double)> Audio; void connect_audio (boost::shared_ptr); void connect_audio (boost::shared_ptr); diff --git a/src/lib/combiner.cc b/src/lib/combiner.cc index 0a9eaf6b6..250528aeb 100644 --- a/src/lib/combiner.cc +++ b/src/lib/combiner.cc @@ -33,9 +33,9 @@ Combiner::Combiner (shared_ptr log) * @param image Frame image. */ void -Combiner::process_video (shared_ptr image, bool, shared_ptr, double) +Combiner::process_video (shared_ptr image, bool, shared_ptr, double) { - _image = image; + _image = image->clone (); } /** Process video for the right half of the frame. @@ -43,7 +43,7 @@ Combiner::process_video (shared_ptr image, bool, shared_ptr, do * @param sub Subtitle (which will be put onto the whole frame) */ void -Combiner::process_video_b (shared_ptr image, bool, shared_ptr sub, double t) +Combiner::process_video_b (shared_ptr image, bool, shared_ptr sub, double t) { /* Copy the right half of this image into our _image */ /* XXX: this should probably be in the Image class */ diff --git a/src/lib/combiner.h b/src/lib/combiner.h index a8f1fa804..7ed316e26 100644 --- a/src/lib/combiner.h +++ b/src/lib/combiner.h @@ -33,8 +33,8 @@ class Combiner : public TimedVideoProcessor public: Combiner (boost::shared_ptr log); - void process_video (boost::shared_ptr i, bool, boost::shared_ptr s, double); - void process_video_b (boost::shared_ptr i, bool, boost::shared_ptr s, double); + void process_video (boost::shared_ptr i, bool, boost::shared_ptr s, double); + void process_video_b (boost::shared_ptr i, bool, boost::shared_ptr s, double); private: /** The image that we are currently working on */ diff --git a/src/lib/delay_line.cc b/src/lib/delay_line.cc index 9e6baeba8..b0180800a 100644 --- a/src/lib/delay_line.cc +++ b/src/lib/delay_line.cc @@ -37,7 +37,7 @@ DelayLine::DelayLine (shared_ptr log, double seconds) } void -DelayLine::process_audio (shared_ptr data, double t) +DelayLine::process_audio (shared_ptr data, double t) { if (_seconds > 0) { t += _seconds; @@ -47,7 +47,7 @@ DelayLine::process_audio (shared_ptr data, double t) } void -DelayLine::process_video (boost::shared_ptr image, bool same, boost::shared_ptr sub, double t) +DelayLine::process_video (shared_ptr image, bool same, boost::shared_ptr sub, double t) { if (_seconds < 0) { t += _seconds; diff --git a/src/lib/delay_line.h b/src/lib/delay_line.h index 90f1dcfa7..781dce88a 100644 --- a/src/lib/delay_line.h +++ b/src/lib/delay_line.h @@ -26,8 +26,8 @@ class DelayLine : public TimedAudioVideoProcessor public: DelayLine (boost::shared_ptr log, double); - void process_video (boost::shared_ptr, bool, boost::shared_ptr, double); - void process_audio (boost::shared_ptr, double); + void process_video (boost::shared_ptr, bool, boost::shared_ptr, double); + void process_audio (boost::shared_ptr, double); private: double _seconds; diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 7b338407e..7a1eea069 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -231,7 +231,7 @@ Encoder::frame_done () } void -Encoder::process_video (shared_ptr image, bool same, boost::shared_ptr sub) +Encoder::process_video (shared_ptr image, bool same, boost::shared_ptr sub) { FrameRateConversion frc (_film->source_frame_rate(), _film->dcp_frame_rate()); @@ -294,7 +294,7 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ptr data) +Encoder::process_audio (shared_ptr data) { #if HAVE_SWRESAMPLE /* Maybe sample-rate convert */ diff --git a/src/lib/encoder.h b/src/lib/encoder.h index 86880bc34..70e81a7e0 100644 --- a/src/lib/encoder.h +++ b/src/lib/encoder.h @@ -73,10 +73,10 @@ public: * @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 i, bool same, boost::shared_ptr s); + void process_video (boost::shared_ptr i, bool same, boost::shared_ptr s); /** Call with some audio data */ - void process_audio (boost::shared_ptr); + void process_audio (boost::shared_ptr); /** Called when a processing run has finished */ virtual void process_end (); diff --git a/src/lib/gain.cc b/src/lib/gain.cc index df7011d2e..ccd779d71 100644 --- a/src/lib/gain.cc +++ b/src/lib/gain.cc @@ -30,7 +30,7 @@ Gain::Gain (shared_ptr log, float gain) } void -Gain::process_audio (shared_ptr b) +Gain::process_audio (shared_ptr b) { if (_gain != 0) { float const linear_gain = pow (10, _gain / 20); diff --git a/src/lib/gain.h b/src/lib/gain.h index d462e5aee..61fef5e85 100644 --- a/src/lib/gain.h +++ b/src/lib/gain.h @@ -24,7 +24,7 @@ class Gain : public AudioProcessor public: Gain (boost::shared_ptr log, float gain); - void process_audio (boost::shared_ptr); + void process_audio (boost::shared_ptr); private: float _gain; diff --git a/src/lib/image.cc b/src/lib/image.cc index 2355d22e5..9bcbb87ab 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -583,6 +583,12 @@ SimpleImage::aligned () const return _aligned; } +shared_ptr +SimpleImage::clone () const +{ + return shared_ptr (new SimpleImage (*this)); +} + FilterBufferImage::FilterBufferImage (AVPixelFormat p, AVFilterBufferRef* b) : Image (p) , _buffer (b) diff --git a/src/lib/image.h b/src/lib/image.h index 6b9ade99e..31035d272 100644 --- a/src/lib/image.h +++ b/src/lib/image.h @@ -70,6 +70,8 @@ public: virtual bool aligned () const = 0; + virtual boost::shared_ptr clone () const = 0; + int components () const; int lines (int) const; @@ -118,6 +120,9 @@ private: /* Not allowed */ FilterBufferImage (FilterBufferImage const &); FilterBufferImage& operator= (FilterBufferImage const &); + boost::shared_ptr clone () const { + assert (false); + } AVFilterBufferRef* _buffer; int* _line_size; @@ -139,6 +144,7 @@ public: int * stride () const; libdcp::Size size () const; bool aligned () const; + boost::shared_ptr clone () const; protected: void allocate (); diff --git a/src/lib/matcher.cc b/src/lib/matcher.cc index dd0312f67..9924c003a 100644 --- a/src/lib/matcher.cc +++ b/src/lib/matcher.cc @@ -41,7 +41,7 @@ Matcher::Matcher (shared_ptr log, int sample_rate, float frames_per_second) } void -Matcher::process_video (boost::shared_ptr image, bool same, boost::shared_ptr sub, double t) +Matcher::process_video (boost::shared_ptr image, bool same, boost::shared_ptr sub, double t) { _pixel_format = image->pixel_format (); _size = image->size (); @@ -90,7 +90,7 @@ Matcher::process_video (boost::shared_ptr image, bool same, boost::shared } void -Matcher::process_audio (boost::shared_ptr b, double t) +Matcher::process_audio (boost::shared_ptr b, double t) { _channels = b->channels (); @@ -202,8 +202,9 @@ void Matcher::repeat_last_video () { if (!_last_image) { - _last_image.reset (new SimpleImage (_pixel_format.get(), _size.get(), true)); - _last_image->make_black (); + shared_ptr im (new SimpleImage (_pixel_format.get(), _size.get(), true)); + im->make_black (); + _last_image = im; } Video (_last_image, true, _last_subtitle); diff --git a/src/lib/matcher.h b/src/lib/matcher.h index f54aa4b6a..41aa373a4 100644 --- a/src/lib/matcher.h +++ b/src/lib/matcher.h @@ -25,8 +25,8 @@ class Matcher : public Processor, public TimedAudioSink, public TimedVideoSink, { public: Matcher (boost::shared_ptr log, int sample_rate, float frames_per_second); - void process_video (boost::shared_ptr i, bool, boost::shared_ptr s, double); - void process_audio (boost::shared_ptr, double); + void process_video (boost::shared_ptr i, bool, boost::shared_ptr s, double); + void process_audio (boost::shared_ptr, double); void process_end (); private: @@ -43,19 +43,19 @@ private: boost::optional _channels; struct AudioRecord { - AudioRecord (boost::shared_ptr a, double t) + AudioRecord (boost::shared_ptr a, double t) : audio (a) , time (t) {} - boost::shared_ptr audio; + boost::shared_ptr audio; double time; }; std::list _pending_audio; boost::optional _first_input; - boost::shared_ptr _last_image; + boost::shared_ptr _last_image; boost::shared_ptr _last_subtitle; bool _had_first_video; diff --git a/src/lib/trimmer.cc b/src/lib/trimmer.cc index 68364e50a..39ec44fcb 100644 --- a/src/lib/trimmer.cc +++ b/src/lib/trimmer.cc @@ -56,7 +56,7 @@ Trimmer::Trimmer ( } void -Trimmer::process_video (shared_ptr image, bool same, shared_ptr sub) +Trimmer::process_video (shared_ptr image, bool same, shared_ptr sub) { if (_video_in >= _video_start && _video_in <= _video_end) { Video (image, same, sub); @@ -66,7 +66,7 @@ Trimmer::process_video (shared_ptr image, bool same, shared_ptr } void -Trimmer::process_audio (shared_ptr audio) +Trimmer::process_audio (shared_ptr audio) { int64_t offset = _audio_start - _audio_in; if (offset > audio->frames()) { @@ -91,8 +91,10 @@ Trimmer::process_audio (shared_ptr audio) _audio_in += audio->frames (); if (offset != 0 || length != audio->frames ()) { - audio->move (offset, 0, length); - audio->set_frames (length); + shared_ptr copy (new AudioBuffers (audio)); + copy->move (offset, 0, length); + copy->set_frames (length); + audio = copy; } Audio (audio); diff --git a/src/lib/trimmer.h b/src/lib/trimmer.h index ff7e9514d..45b3f149a 100644 --- a/src/lib/trimmer.h +++ b/src/lib/trimmer.h @@ -24,8 +24,8 @@ class Trimmer : public AudioVideoProcessor public: Trimmer (boost::shared_ptr, int, int, int, int, float, int); - void process_video (boost::shared_ptr i, bool, boost::shared_ptr s); - void process_audio (boost::shared_ptr); + void process_video (boost::shared_ptr i, bool, boost::shared_ptr s); + void process_audio (boost::shared_ptr); private: friend class trimmer_test; diff --git a/src/lib/util.cc b/src/lib/util.cc index e43b598ab..859aa6de7 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -63,11 +63,24 @@ extern "C" { #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. @@ -87,9 +100,9 @@ seconds_to_hms (int s) 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 (); } @@ -185,7 +198,7 @@ stacktrace (ostream& out, int levels) 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); @@ -243,7 +256,7 @@ dvdomatic_setup () Filter::setup_filters (); SoundProcessor::setup_sound_processors (); - ui_thread = this_thread::get_id (); + ui_thread = boost::this_thread::get_id (); } #ifdef DVDOMATIC_WINDOWS @@ -338,7 +351,7 @@ md5_digest (void const * data, int 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 (); @@ -350,14 +363,14 @@ md5_digest (void const * data, int size) 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]; @@ -376,7 +389,7 @@ md5_digest (string file) 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 (); @@ -441,8 +454,8 @@ best_dcp_frame_rate (float source_fps) } /* Pick the best one, bailing early if we hit an exact match */ - float error = numeric_limits::max (); - boost::optional best; + float error = std::numeric_limits::max (); + optional best; list::iterator i = candidates.begin(); while (i != candidates.end()) { @@ -509,16 +522,16 @@ Socket::Socket (int timeout) , _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)); @@ -528,14 +541,14 @@ Socket::check () * @param endpoint End-point to connect to. */ void -Socket::connect (asio::ip::basic_resolver_entry const & endpoint) +Socket::connect (boost::asio::ip::basic_resolver_entry 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")); @@ -549,14 +562,14 @@ Socket::connect (asio::ip::basic_resolver_entry const & endpoint) 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 ()); @@ -577,14 +590,14 @@ Socket::write (uint32_t v) 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 ()); @@ -761,6 +774,21 @@ AudioBuffers::AudioBuffers (AudioBuffers const & other) } } +/* 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 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 () { @@ -865,7 +893,7 @@ AudioBuffers::move (int from, int to, int frames) void ensure_ui_thread () { - assert (this_thread::get_id() == ui_thread); + assert (boost::this_thread::get_id() == ui_thread); } /** @param v Source video frame. diff --git a/src/lib/util.h b/src/lib/util.h index 31d0fc967..99670110e 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -241,6 +241,7 @@ class AudioBuffers public: AudioBuffers (int channels, int frames); AudioBuffers (AudioBuffers const &); + AudioBuffers (boost::shared_ptr); ~AudioBuffers (); float** data () const { diff --git a/src/lib/video_sink.h b/src/lib/video_sink.h index 32c7f3b38..0170c7350 100644 --- a/src/lib/video_sink.h +++ b/src/lib/video_sink.h @@ -34,7 +34,7 @@ public: * @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 i, bool same, boost::shared_ptr s) = 0; + virtual void process_video (boost::shared_ptr i, bool same, boost::shared_ptr s) = 0; }; class TimedVideoSink @@ -46,7 +46,7 @@ public: * @param s A subtitle that should be on this frame, or 0. * @param t Source timestamp. */ - virtual void process_video (boost::shared_ptr i, bool same, boost::shared_ptr s, double t) = 0; + virtual void process_video (boost::shared_ptr i, bool same, boost::shared_ptr s, double t) = 0; }; #endif diff --git a/src/lib/video_source.h b/src/lib/video_source.h index e4a8ab058..748cb6fe9 100644 --- a/src/lib/video_source.h +++ b/src/lib/video_source.h @@ -45,7 +45,7 @@ public: * 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, bool, boost::shared_ptr)> Video; + boost::signals2::signal, bool, boost::shared_ptr)> Video; void connect_video (boost::shared_ptr); }; @@ -63,7 +63,7 @@ public: * 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, bool, boost::shared_ptr, double)> Video; + boost::signals2::signal, bool, boost::shared_ptr, double)> Video; void connect_video (boost::shared_ptr); void connect_video (boost::shared_ptr); diff --git a/src/tools/servomatictest.cc b/src/tools/servomatictest.cc index f5756c693..5e1cf49b4 100644 --- a/src/tools/servomatictest.cc +++ b/src/tools/servomatictest.cc @@ -47,7 +47,7 @@ static shared_ptr log_ (new FileLog ("servomatictest.log")); static int frame = 0; void -process_video (shared_ptr image, bool, shared_ptr sub) +process_video (shared_ptr image, bool, shared_ptr sub) { shared_ptr local ( new DCPVideoFrame ( diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 8508ec2a2..4f2985a06 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -308,7 +308,7 @@ FilmViewer::raw_to_display () return; } - boost::shared_ptr input = _raw_frame; + boost::shared_ptr input = _raw_frame; pair const s = Filter::ffmpeg_strings (_film->filters()); if (!s.second.empty ()) { @@ -400,7 +400,7 @@ FilmViewer::check_play_state () } void -FilmViewer::process_video (shared_ptr image, bool, shared_ptr sub, double t) +FilmViewer::process_video (shared_ptr image, bool, shared_ptr sub, double t) { _raw_frame = image; _raw_sub = sub; diff --git a/src/wx/film_viewer.h b/src/wx/film_viewer.h index a78c772a4..ed5874fbc 100644 --- a/src/wx/film_viewer.h +++ b/src/wx/film_viewer.h @@ -48,7 +48,7 @@ private: void slider_moved (wxScrollEvent &); void play_clicked (wxCommandEvent &); void timer (wxTimerEvent &); - void process_video (boost::shared_ptr, bool, boost::shared_ptr, double); + void process_video (boost::shared_ptr, bool, boost::shared_ptr, double); void calculate_sizes (); void check_play_state (); void update_from_raw (); @@ -72,9 +72,9 @@ private: wxTimer _timer; Decoders _decoders; - boost::shared_ptr _raw_frame; + boost::shared_ptr _raw_frame; boost::shared_ptr _raw_sub; - boost::shared_ptr _display_frame; + boost::shared_ptr _display_frame; /* The x offset at which we display the actual film content; this corresponds to the film's padding converted to our coordinates. */ diff --git a/test/test.cc b/test/test.cc index 595d8fc93..496c91519 100644 --- a/test/test.cc +++ b/test/test.cc @@ -123,17 +123,17 @@ BOOST_AUTO_TEST_CASE (make_black_test) } } -shared_ptr trimmer_test_last_video; -shared_ptr trimmer_test_last_audio; +shared_ptr trimmer_test_last_video; +shared_ptr trimmer_test_last_audio; void -trimmer_test_video_helper (shared_ptr image, bool, shared_ptr) +trimmer_test_video_helper (shared_ptr image, bool, shared_ptr) { trimmer_test_last_video = image; } void -trimmer_test_audio_helper (shared_ptr audio) +trimmer_test_audio_helper (shared_ptr audio) { trimmer_test_last_audio = audio; } -- cgit v1.2.3 From 9c591cc25317fa7f8eac7bd7ca36a741a519e5d0 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 24 Apr 2013 01:18:49 +0100 Subject: Hack around no-trim altering the ends of encodes. --- src/lib/trimmer.cc | 14 +++++++++++++- src/lib/trimmer.h | 1 + 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/trimmer.cc b/src/lib/trimmer.cc index 39ec44fcb..0746b7410 100644 --- a/src/lib/trimmer.cc +++ b/src/lib/trimmer.cc @@ -53,12 +53,19 @@ Trimmer::Trimmer ( _audio_start = video_frames_to_audio_frames (_video_start, audio_sample_rate, frames_per_second); _audio_end = video_frames_to_audio_frames (_video_end, audio_sample_rate, frames_per_second); } + + /* XXX: this is a hack; this flag means that no trim is happening at the end of the film, and I'm + using that to prevent audio trim being rounded to video trim, which breaks the current set + of regression tests. This could be removed if a) the regression tests are regenerated and b) + I can work out what DCP length should be. + */ + _no_trim = (_video_start == 0) && (_video_end == (video_length - video_trim_end)); } void Trimmer::process_video (shared_ptr image, bool same, shared_ptr sub) { - if (_video_in >= _video_start && _video_in <= _video_end) { + if (_no_trim || (_video_in >= _video_start && _video_in <= _video_end)) { Video (image, same, sub); } @@ -68,6 +75,11 @@ Trimmer::process_video (shared_ptr image, bool same, shared_ptr audio) { + if (_no_trim) { + Audio (audio); + return; + } + int64_t offset = _audio_start - _audio_in; if (offset > audio->frames()) { _audio_in += audio->frames (); diff --git a/src/lib/trimmer.h b/src/lib/trimmer.h index 45b3f149a..98a118fb2 100644 --- a/src/lib/trimmer.h +++ b/src/lib/trimmer.h @@ -36,4 +36,5 @@ private: int64_t _audio_start; int64_t _audio_end; int64_t _audio_in; + bool _no_trim; }; -- cgit v1.2.3 From 6aa1a3e3808319d26659d3008a83f79f695fb6b2 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 24 Apr 2013 16:28:16 +0100 Subject: Try to fix crash with still-image DCPs. --- src/lib/transcoder.cc | 2 +- src/lib/trimmer.cc | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc index a10789e11..4d3f29e83 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -66,7 +66,7 @@ Transcoder::Transcoder (shared_ptr f, DecodeOptions o, Job* j, shared_ptr< int const trim_start = f->trim_type() == Film::ENCODE ? f->trim_start() : 0; int const trim_end = f->trim_type() == Film::ENCODE ? f->trim_end() : 0; _trimmer.reset (new Trimmer ( - f->log(), trim_start, trim_end, f->length().get(), + f->log(), trim_start, trim_end, f->length().get_value_or(0), sr, f->source_frame_rate(), f->dcp_frame_rate() )); diff --git a/src/lib/trimmer.cc b/src/lib/trimmer.cc index 0746b7410..b7afc9299 100644 --- a/src/lib/trimmer.cc +++ b/src/lib/trimmer.cc @@ -28,7 +28,8 @@ using boost::shared_ptr; Trimmer::Trimmer ( shared_ptr log, int video_trim_start, - int video_trim_end, int video_length, + int video_trim_end, + int video_length, int audio_sample_rate, float frames_per_second, int dcp_frames_per_second -- cgit v1.2.3 From fbbbda8082f17cb0946c4a489ba9330301069575 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 24 Apr 2013 21:58:31 +0100 Subject: Fix sensitivity of best DCP frame rate. --- src/wx/film_editor.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index ad028c930..7e3750911 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -930,6 +930,7 @@ FilmEditor::set_things_sensitive (bool s) _scaler->Enable (s); _ffmpeg_audio_stream->Enable (s); _dcp_content_type->Enable (s); + _best_dcp_frame_rate->Enable (s); _dcp_frame_rate->Enable (s); _trim_start->Enable (s); _trim_end->Enable (s); -- cgit v1.2.3 From ccc07eebc492d74c351c235584fd708c46b5b656 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 24 Apr 2013 22:30:05 +0100 Subject: Fix #124 (allow use of existing directories for new films). --- ChangeLog | 6 ++++++ src/tools/dvdomatic.cc | 14 +++++++++++--- src/wx/wx_util.cc | 10 ++++++++++ src/wx/wx_util.h | 1 + 4 files changed, 28 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/ChangeLog b/ChangeLog index ef8fd96c1..8cabafd0b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2013-04-24 Carl Hetherington + + * Allow use of existing empty directories for new films (without + confirmation) and existing non-empty directories (with confirmation) + (#124). + 2013-04-23 Carl Hetherington * Version 0.86 released. diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 2a995bee8..b161ac7e3 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -301,9 +301,17 @@ private: if (r == wxID_OK) { - if (boost::filesystem::exists (d->get_path())) { - error_dialog (this, std_to_wx (String::compose (wx_to_std (_("The directory %1 already exists.")), d->get_path().c_str()))); - return; + if (boost::filesystem::exists (d->get_path()) && !boost::filesystem::is_empty(d->get_path())) { + if (!confirm_dialog ( + this, + std_to_wx ( + String::compose (wx_to_std (_("The directory %1 already exists and is not empty. " + "Are you sure you want to use it?")), + d->get_path().c_str()) + ) + )) { + return; + } } maybe_save_then_delete_film (); diff --git a/src/wx/wx_util.cc b/src/wx/wx_util.cc index 720a058cb..77f5da293 100644 --- a/src/wx/wx_util.cc +++ b/src/wx/wx_util.cc @@ -63,6 +63,16 @@ error_dialog (wxWindow* parent, wxString m) d->Destroy (); } +bool +confirm_dialog (wxWindow* parent, wxString m) +{ + wxMessageDialog* d = new wxMessageDialog (parent, m, _("DVD-o-matic"), wxYES_NO | wxICON_QUESTION); + int const r = d->ShowModal (); + d->Destroy (); + return r == wxID_YES; +} + + /** @param s wxWidgets string. * @return Corresponding STL string. */ diff --git a/src/wx/wx_util.h b/src/wx/wx_util.h index bff3d7982..b3ab706df 100644 --- a/src/wx/wx_util.h +++ b/src/wx/wx_util.h @@ -31,6 +31,7 @@ class wxGridBagSizer; */ extern void error_dialog (wxWindow *, wxString); +extern bool confirm_dialog (wxWindow *, wxString); extern wxStaticText* add_label_to_sizer (wxSizer *, wxWindow *, wxString, int prop = 0); extern wxStaticText* add_label_to_grid_bag_sizer (wxGridBagSizer *, wxWindow *, wxString, wxGBPosition, wxGBSpan span = wxDefaultSpan); extern std::string wx_to_std (wxString); -- cgit v1.2.3 From 7b2ec1dd69951649f2c912fcf90b22913b1f6c3a Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 25 Apr 2013 13:44:02 +0100 Subject: Remove Image::clone in favour of a copy constructor for SimpleImage; clean up A/B transcoder slightly; fix combiner if image strides differ; try to fix problems when destroying Encoders; fix SimpleImage copy constructor to cope with aligned images; don't call encoder::process_end if the encode throws an exception. --- src/lib/ab_transcoder.cc | 14 +++++--------- src/lib/combiner.cc | 7 +++---- src/lib/encoder.cc | 4 +++- src/lib/image.cc | 34 +++++++++++++++++++++++++++------- src/lib/image.h | 7 +------ src/lib/transcoder.cc | 37 ++++++++++++++++--------------------- 6 files changed, 55 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/lib/ab_transcoder.cc b/src/lib/ab_transcoder.cc index 26643b50e..d8f13dae4 100644 --- a/src/lib/ab_transcoder.cc +++ b/src/lib/ab_transcoder.cc @@ -122,25 +122,21 @@ ABTranscoder::go () } else { done[2] = true; } - + if (_job) { _da.video->set_progress (_job); } - + if (done[0] && done[1] && done[2]) { break; } } - - if (_delay_line) { - _delay_line->process_end (); - } + + _delay_line->process_end (); if (_matcher) { _matcher->process_end (); } - if (_gain) { - _gain->process_end (); - } + _gain->process_end (); _encoder->process_end (); } diff --git a/src/lib/combiner.cc b/src/lib/combiner.cc index 250528aeb..367cefa7f 100644 --- a/src/lib/combiner.cc +++ b/src/lib/combiner.cc @@ -35,7 +35,7 @@ Combiner::Combiner (shared_ptr log) void Combiner::process_video (shared_ptr image, bool, shared_ptr, double) { - _image = image->clone (); + _image.reset (new SimpleImage (image)); } /** Process video for the right half of the frame. @@ -50,15 +50,14 @@ Combiner::process_video_b (shared_ptr image, bool, shared_ptrcomponents(); ++i) { int const line_size = image->line_size()[i]; int const half_line_size = line_size / 2; - int const stride = image->stride()[i]; uint8_t* p = _image->data()[i]; uint8_t* q = image->data()[i]; for (int j = 0; j < image->lines (i); ++j) { memcpy (p + half_line_size, q + half_line_size, half_line_size); - p += stride; - q += stride; + p += _image->stride()[i]; + q += image->stride()[i]; } } diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 7a1eea069..cff9899ac 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -333,7 +333,9 @@ Encoder::terminate_threads () lock.unlock (); for (list::iterator i = _threads.begin(); i != _threads.end(); ++i) { - (*i)->join (); + if ((*i)->joinable ()) { + (*i)->join (); + } delete *i; } } diff --git a/src/lib/image.cc b/src/lib/image.cc index 9bcbb87ab..1be41fecf 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -509,7 +509,33 @@ SimpleImage::SimpleImage (SimpleImage const & other) allocate (); for (int i = 0; i < components(); ++i) { - memcpy (_data[i], other._data[i], _line_size[i] * lines(i)); + uint8_t* p = _data[i]; + uint8_t* q = other._data[i]; + for (int j = 0; j < lines(i); ++j) { + memcpy (p, q, _line_size[i]); + p += stride()[i]; + q += other.stride()[i]; + } + } +} + +SimpleImage::SimpleImage (shared_ptr other) + : Image (*other.get()) +{ + _size = other->size (); + _aligned = true; + + allocate (); + + for (int i = 0; i < components(); ++i) { + assert(line_size()[i] == other->line_size()[i]); + uint8_t* p = _data[i]; + uint8_t* q = other->data()[i]; + for (int j = 0; j < lines(i); ++j) { + memcpy (p, q, line_size()[i]); + p += stride()[i]; + q += other->stride()[i]; + } } } @@ -583,12 +609,6 @@ SimpleImage::aligned () const return _aligned; } -shared_ptr -SimpleImage::clone () const -{ - return shared_ptr (new SimpleImage (*this)); -} - FilterBufferImage::FilterBufferImage (AVPixelFormat p, AVFilterBufferRef* b) : Image (p) , _buffer (b) diff --git a/src/lib/image.h b/src/lib/image.h index 31035d272..62961a92e 100644 --- a/src/lib/image.h +++ b/src/lib/image.h @@ -70,8 +70,6 @@ public: virtual bool aligned () const = 0; - virtual boost::shared_ptr clone () const = 0; - int components () const; int lines (int) const; @@ -120,9 +118,6 @@ private: /* Not allowed */ FilterBufferImage (FilterBufferImage const &); FilterBufferImage& operator= (FilterBufferImage const &); - boost::shared_ptr clone () const { - assert (false); - } AVFilterBufferRef* _buffer; int* _line_size; @@ -136,6 +131,7 @@ class SimpleImage : public Image public: SimpleImage (AVPixelFormat, libdcp::Size, bool); SimpleImage (SimpleImage const &); + SimpleImage (boost::shared_ptr); SimpleImage& operator= (SimpleImage const &); ~SimpleImage (); @@ -144,7 +140,6 @@ public: int * stride () const; libdcp::Size size () const; bool aligned () const; - boost::shared_ptr clone () const; protected: void allocate (); diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc index 4d3f29e83..faafcaf8b 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -103,31 +103,26 @@ void Transcoder::go () { _encoder->process_begin (); - try { - bool done[2] = { false, false }; - - while (1) { - if (!done[0]) { - done[0] = _decoders.video->pass (); - if (_job) { - _decoders.video->set_progress (_job); - } - } - - if (!done[1] && _decoders.audio && dynamic_pointer_cast (_decoders.audio) != dynamic_pointer_cast (_decoders.video)) { - done[1] = _decoders.audio->pass (); - } else { - done[1] = true; - } - if (done[0] && done[1]) { - break; + bool done[2] = { false, false }; + + while (1) { + if (!done[0]) { + done[0] = _decoders.video->pass (); + if (_job) { + _decoders.video->set_progress (_job); } } - } catch (...) { - _encoder->process_end (); - throw; + if (!done[1] && _decoders.audio && dynamic_pointer_cast (_decoders.audio) != dynamic_pointer_cast (_decoders.video)) { + done[1] = _decoders.audio->pass (); + } else { + done[1] = true; + } + + if (done[0] && done[1]) { + break; + } } _delay_line->process_end (); -- cgit v1.2.3 From 51fcb7e0f42b385f569f10f93c29f5a1f2802d82 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 25 Apr 2013 20:52:47 +0100 Subject: Use content digest for audio maps, not file name. --- src/lib/audio_mapping.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/lib/audio_mapping.cc b/src/lib/audio_mapping.cc index 2e8077565..83c748f1a 100644 --- a/src/lib/audio_mapping.cc +++ b/src/lib/audio_mapping.cc @@ -94,7 +94,7 @@ AudioMapping::as_xml (xmlpp::Node* node) const for (list >::const_iterator i = _content_to_dcp.begin(); i != _content_to_dcp.end(); ++i) { xmlpp::Node* t = node->add_child ("Map"); shared_ptr c = i->first.content.lock (); - t->add_child ("Content")->add_child_text (c->file().string ()); + t->add_child ("Content")->add_child_text (c->digest ()); t->add_child ("ContentIndex")->add_child_text (lexical_cast (i->first.index)); t->add_child ("DCP")->add_child_text (lexical_cast (i->second)); } @@ -107,7 +107,7 @@ AudioMapping::set_from_xml (ContentList const & content, shared_ptr >::const_iterator i = c.begin(); i != c.end(); ++i) { string const c = (*i)->string_child ("Content"); ContentList::const_iterator j = content.begin (); - while (j != content.end() && (*j)->file().string() != c) { + while (j != content.end() && (*j)->digest() != c) { ++j; } -- cgit v1.2.3 From b6580da280e138743c2a90cfb37ec4f415daa6cb Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 25 Apr 2013 21:25:25 +0100 Subject: Fix some leftovers on creating a new film. --- branch-notes | 5 ----- src/wx/film_editor.cc | 17 +++++++++++++---- 2 files changed, 13 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/branch-notes b/branch-notes index 7298973ae..99338e8bf 100644 --- a/branch-notes +++ b/branch-notes @@ -1,8 +1,3 @@ -doesn't reset content details, length, dcp frame rate on new film. - -no subs in viewer on e.g. creating new arrietty_EN-EN; player does not enable them in its decoder unless -the film has them turned on. - audio map view is screwed up on windows, apparently not extended to full height crash on analyse audio diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 7e3750911..f9ca8609b 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -617,6 +617,7 @@ FilmEditor::film_changed (Film::Property p) setup_subtitle_control_sensitivity (); setup_streams (); setup_show_audio_sensitivity (); + setup_length (); break; case Film::TRUST_CONTENT_HEADERS: checked_set (_trust_content_headers, _film->trust_content_headers ()); @@ -697,15 +698,20 @@ FilmEditor::film_changed (Film::Property p) setup_dcp_name (); break; case Film::DCP_FRAME_RATE: + { + bool done = false; for (unsigned int i = 0; i < _dcp_frame_rate->GetCount(); ++i) { if (wx_to_std (_dcp_frame_rate->GetString(i)) == boost::lexical_cast (_film->dcp_frame_rate())) { - if (_dcp_frame_rate->GetSelection() != int(i)) { - _dcp_frame_rate->SetSelection (i); - break; - } + checked_set (_dcp_frame_rate, i); + done = true; + break; } } + if (!done) { + checked_set (_dcp_frame_rate, -1); + } + if (_film->video_frame_rate()) { _best_dcp_frame_rate->Enable (best_dcp_frame_rate (_film->video_frame_rate ()) != _film->dcp_frame_rate ()); } else { @@ -713,6 +719,7 @@ FilmEditor::film_changed (Film::Property p) } setup_frame_rate_description (); break; + } case Film::AUDIO_MAPPING: _audio_mapping->set_mapping (_film->audio_mapping ()); break; @@ -905,6 +912,8 @@ FilmEditor::set_film (shared_ptr f) film_content_changed (boost::shared_ptr (), FFmpegContentProperty::SUBTITLE_STREAM); film_content_changed (boost::shared_ptr (), FFmpegContentProperty::AUDIO_STREAMS); film_content_changed (boost::shared_ptr (), FFmpegContentProperty::AUDIO_STREAM); + + setup_content_information (); } /** Updates the sensitivity of lots of widgets to a given value. -- cgit v1.2.3 From 384e364f02b9a598044aff6073ea0f61c87c62b0 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 26 Apr 2013 00:21:52 +0100 Subject: Try to clean up some aspects of video/audio/video-audio content; fixes crash with audio analysis due to no audio being analysed for FFmpeg-only content. --- src/lib/player.cc | 69 +++++++++++++++++++++++---- src/lib/player.h | 14 ++++-- src/lib/playlist.cc | 135 +++++++++++++++++++++------------------------------- src/lib/playlist.h | 24 ++++++++-- 4 files changed, 142 insertions(+), 100 deletions(-) (limited to 'src') diff --git a/src/lib/player.cc b/src/lib/player.cc index 635b67cad..7a149d734 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -75,6 +75,9 @@ Player::pass () bool done = true; if (_video_decoder != _video_decoders.end ()) { + + /* Run video decoder; this may also produce audio */ + if ((*_video_decoder)->pass ()) { _video_decoder++; } @@ -82,10 +85,24 @@ Player::pass () if (_video_decoder != _video_decoders.end ()) { done = false; } - } + + } else if (!_video && _playlist->audio_from() == Playlist::AUDIO_FFMPEG && _sequential_audio_decoder != _audio_decoders.end ()) { - if (_playlist->audio_from() == Playlist::AUDIO_SNDFILE) { - for (list >::iterator i = _sndfile_decoders.begin(); i != _sndfile_decoders.end(); ++i) { + /* We're not producing video, so we may need to run FFmpeg content to get the audio */ + + if ((*_sequential_audio_decoder)->pass ()) { + _sequential_audio_decoder++; + } + + if (_sequential_audio_decoder != _audio_decoders.end ()) { + done = false; + } + + } else if (_playlist->audio_from() == Playlist::AUDIO_SNDFILE) { + + /* We're getting audio from SndfileContent */ + + for (list >::iterator i = _audio_decoders.begin(); i != _audio_decoders.end(); ++i) { if (!(*i)->pass ()) { done = false; } @@ -200,7 +217,7 @@ Player::setup_decoders () { _video_decoders.clear (); _video_decoder = _video_decoders.end (); - _sndfile_decoders.clear (); + _audio_decoders.clear (); if (_video) { list > vc = _playlist->video (); @@ -239,12 +256,44 @@ Player::setup_decoders () _video_decoder = _video_decoders.begin (); } - if (_audio && _playlist->audio_from() == Playlist::AUDIO_SNDFILE) { - list > sc = _playlist->sndfile (); - for (list >::iterator i = sc.begin(); i != sc.end(); ++i) { - shared_ptr d (new SndfileDecoder (_film, *i)); - _sndfile_decoders.push_back (d); - d->Audio.connect (bind (&Player::process_audio, this, *i, _1, _2)); + if (_playlist->audio_from() == Playlist::AUDIO_FFMPEG && !_video) { + + /* If we're getting audio from FFmpegContent but not the video, we need a set + of decoders for the audio. + */ + + list > ac = _playlist->audio (); + for (list >::iterator i = ac.begin(); i != ac.end(); ++i) { + + shared_ptr fc = dynamic_pointer_cast (*i); + assert (fc); + + shared_ptr d ( + new FFmpegDecoder ( + _film, fc, _video, + _audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG, + _subtitles + ) + ); + + d->Audio.connect (bind (&Player::process_audio, this, fc, _1, _2)); + _audio_decoders.push_back (d); + } + + _sequential_audio_decoder = _audio_decoders.begin (); + } + + if (_playlist->audio_from() == Playlist::AUDIO_SNDFILE) { + + list > ac = _playlist->audio (); + for (list >::iterator i = ac.begin(); i != ac.end(); ++i) { + + shared_ptr sc = dynamic_pointer_cast (*i); + assert (sc); + + shared_ptr d (new SndfileDecoder (_film, sc)); + d->Audio.connect (bind (&Player::process_audio, this, sc, _1, _2)); + _audio_decoders.push_back (d); } } } diff --git a/src/lib/player.h b/src/lib/player.h index 539fae67a..44b7c126d 100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@ -29,12 +29,16 @@ #include "audio_sink.h" class VideoDecoder; -class SndfileDecoder; +class AudioDecoder; class Job; class Film; class Playlist; class AudioContent; +/** @class Player + * @brief A class which can `play' a Playlist; emitting its audio and video. + */ + class Player : public TimedVideoSource, public TimedAudioSource, public TimedVideoSink, public boost::enable_shared_from_this { public: @@ -65,11 +69,15 @@ private: bool _video; bool _audio; bool _subtitles; - + + /** Our decoders are ready to go; if this is false the decoders must be (re-)created before they are used */ bool _have_valid_decoders; std::list > _video_decoders; std::list >::iterator _video_decoder; - std::list > _sndfile_decoders; + std::list > _audio_decoders; + + /** Current audio decoder if we are running them sequentially; otherwise undefined */ + std::list >::iterator _sequential_audio_decoder; boost::shared_ptr _audio_buffers; boost::optional _audio_time; diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index f04bbe0cb..e32788951 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -51,7 +51,7 @@ Playlist::setup (ContentList content) _audio_from = AUDIO_FFMPEG; _video.clear (); - _sndfile.clear (); + _audio.clear (); for (list::iterator i = _content_connections.begin(); i != _content_connections.end(); ++i) { i->disconnect (); @@ -60,15 +60,31 @@ Playlist::setup (ContentList content) _content_connections.clear (); for (ContentList::const_iterator i = content.begin(); i != content.end(); ++i) { + + /* Video is video */ shared_ptr vc = dynamic_pointer_cast (*i); if (vc) { _video.push_back (vc); } - + + /* FFmpegContent is audio if we are doing AUDIO_FFMPEG */ + shared_ptr fc = dynamic_pointer_cast (*i); + if (fc && _audio_from == AUDIO_FFMPEG) { + _audio.push_back (fc); + } + + /* SndfileContent trumps FFmpegContent for audio */ shared_ptr sc = dynamic_pointer_cast (*i); if (sc) { - _sndfile.push_back (sc); - _audio_from = AUDIO_SNDFILE; + if (_audio_from == AUDIO_FFMPEG) { + /* This is our fist SndfileContent; clear any FFmpegContent and + say that we are using Sndfile. + */ + _audio.clear (); + _audio_from = AUDIO_SNDFILE; + } + + _audio.push_back (sc); } _content_connections.push_back ((*i)->Changed.connect (bind (&Playlist::content_changed, this, _1, _2))); @@ -77,23 +93,23 @@ Playlist::setup (ContentList content) Changed (); } +/** @return Length of our audio */ ContentAudioFrame Playlist::audio_length () const { ContentAudioFrame len = 0; - + switch (_audio_from) { case AUDIO_FFMPEG: - for (list >::const_iterator i = _video.begin(); i != _video.end(); ++i) { - shared_ptr fc = dynamic_pointer_cast (*i); - if (fc) { - len += fc->audio_length (); - } + /* FFmpeg content is sequential */ + for (list >::const_iterator i = _audio.begin(); i != _audio.end(); ++i) { + len += (*i)->audio_length (); } break; case AUDIO_SNDFILE: - for (list >::const_iterator i = _sndfile.begin(); i != _sndfile.end(); ++i) { - len += (*i)->audio_length (); + /* Sndfile content is simultaneous */ + for (list >::const_iterator i = _audio.begin(); i != _audio.end(); ++i) { + len = max (len, (*i)->audio_length ()); } break; } @@ -101,6 +117,7 @@ Playlist::audio_length () const return len; } +/** @return number of audio channels */ int Playlist::audio_channels () const { @@ -108,15 +125,14 @@ Playlist::audio_channels () const switch (_audio_from) { case AUDIO_FFMPEG: - for (list >::const_iterator i = _video.begin(); i != _video.end(); ++i) { - shared_ptr fc = dynamic_pointer_cast (*i); - if (fc) { - channels = max (channels, fc->audio_channels ()); - } + /* FFmpeg audio is sequential, so use the maximum channel count */ + for (list >::const_iterator i = _audio.begin(); i != _audio.end(); ++i) { + channels = max (channels, (*i)->audio_channels ()); } break; case AUDIO_SNDFILE: - for (list >::const_iterator i = _sndfile.begin(); i != _sndfile.end(); ++i) { + /* Sndfile audio is simultaneous, so it's the sum of the channel counts */ + for (list >::const_iterator i = _audio.begin(); i != _audio.end(); ++i) { channels += (*i)->audio_channels (); } break; @@ -128,22 +144,12 @@ Playlist::audio_channels () const int Playlist::audio_frame_rate () const { - /* XXX: assuming that all content has the same rate */ - - switch (_audio_from) { - case AUDIO_FFMPEG: - { - shared_ptr fc = first_ffmpeg (); - if (fc) { - return fc->audio_frame_rate (); - } - break; - } - case AUDIO_SNDFILE: - return _sndfile.front()->audio_frame_rate (); + if (_audio.empty ()) { + return 0; } - return 0; + /* XXX: assuming that all content has the same rate */ + return _audio.front()->audio_frame_rate (); } float @@ -182,18 +188,7 @@ Playlist::video_length () const bool Playlist::has_audio () const { - if (!_sndfile.empty ()) { - return true; - } - - for (list >::const_iterator i = _video.begin(); i != _video.end(); ++i) { - shared_ptr fc = dynamic_pointer_cast (*i); - if (fc && fc->audio_stream ()) { - return true; - } - } - - return false; + return !_audio.empty (); } void @@ -202,42 +197,26 @@ Playlist::content_changed (weak_ptr c, int p) ContentChanged (c, p); } -shared_ptr -Playlist::first_ffmpeg () const -{ - for (list >::const_iterator i = _video.begin(); i != _video.end(); ++i) { - shared_ptr fc = dynamic_pointer_cast (*i); - if (fc) { - return fc; - } - } - - return shared_ptr (); -} - - AudioMapping Playlist::default_audio_mapping () const { AudioMapping m; + if (_audio.empty ()) { + return m; + } switch (_audio_from) { case AUDIO_FFMPEG: { - shared_ptr fc = first_ffmpeg (); - if (!fc) { - break; - } - /* XXX: assumes all the same */ - if (fc->audio_channels() == 1) { + if (_audio.front()->audio_channels() == 1) { /* Map mono sources to centre */ - m.add (AudioMapping::Channel (fc, 0), libdcp::CENTRE); + m.add (AudioMapping::Channel (_audio.front(), 0), libdcp::CENTRE); } else { - int const N = min (fc->audio_channels (), MAX_AUDIO_CHANNELS); + int const N = min (_audio.front()->audio_channels (), MAX_AUDIO_CHANNELS); /* Otherwise just start with a 1:1 mapping */ for (int i = 0; i < N; ++i) { - m.add (AudioMapping::Channel (fc, i), (libdcp::Channel) i); + m.add (AudioMapping::Channel (_audio.front(), i), (libdcp::Channel) i); } } break; @@ -246,7 +225,7 @@ Playlist::default_audio_mapping () const case AUDIO_SNDFILE: { int n = 0; - for (list >::const_iterator i = _sndfile.begin(); i != _sndfile.end(); ++i) { + for (list >::const_iterator i = _audio.begin(); i != _audio.end(); ++i) { for (int j = 0; j < (*i)->audio_channels(); ++j) { m.add (AudioMapping::Channel (*i, j), (libdcp::Channel) n); ++n; @@ -270,21 +249,13 @@ Playlist::audio_digest () const { string t; - switch (_audio_from) { - case AUDIO_FFMPEG: - for (list >::const_iterator i = _video.begin(); i != _video.end(); ++i) { - shared_ptr fc = dynamic_pointer_cast (*i); - if (fc) { - t += (*i)->digest (); - t += lexical_cast (fc->audio_stream()->id); - } - } - break; - case AUDIO_SNDFILE: - for (list >::const_iterator i = _sndfile.begin(); i != _sndfile.end(); ++i) { - t += (*i)->digest (); + for (list >::const_iterator i = _audio.begin(); i != _audio.end(); ++i) { + t += (*i)->digest (); + + shared_ptr fc = dynamic_pointer_cast (*i); + if (fc) { + t += lexical_cast (fc->audio_stream()->id); } - break; } return md5_digest (t.c_str(), t.length()); diff --git a/src/lib/playlist.h b/src/lib/playlist.h index d1f766d55..9a2627b1d 100644 --- a/src/lib/playlist.h +++ b/src/lib/playlist.h @@ -37,6 +37,16 @@ class SndfileDecoder; class Job; class Film; +/** @class Playlist + * @brief A set of content files (video and audio), with knowledge of how they should be arranged into + * a DCP. + * + * This class holds Content objects, and it knows how they should be arranged. At the moment + * the ordering is implicit; video content is placed sequentially, and audio content is taken + * from the video unless any sound-only files are present. If sound-only files exist, they + * are played simultaneously (i.e. they can be split up into multiple files for different channels) + */ + class Playlist { public: @@ -68,8 +78,8 @@ public: return _video; } - std::list > sndfile () const { - return _sndfile; + std::list > audio () const { + return _audio; } std::string audio_digest () const; @@ -80,12 +90,16 @@ public: private: void content_changed (boost::weak_ptr, int); - boost::shared_ptr first_ffmpeg () const; - + + /** where we should get our audio from */ AudioFrom _audio_from; + /** all our content which contains video */ std::list > _video; - std::list > _sndfile; + /** all our content which contains audio. This may contain the same objects + * as _video for FFmpegContent. + */ + std::list > _audio; std::list _content_connections; }; -- cgit v1.2.3 From 23050047454f1c1f7aadad41bf7b05d00d8ffe7f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 26 Apr 2013 15:24:57 +0100 Subject: Attempted fixes for some unimplemented timing bits. --- src/lib/decoder.h | 8 +++-- src/lib/ffmpeg_decoder.cc | 16 +++++++--- src/lib/ffmpeg_decoder.h | 4 +-- src/lib/player.cc | 77 ++++++++++++++++++++++++++--------------------- src/lib/player.h | 18 +++++++---- 5 files changed, 75 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/lib/decoder.h b/src/lib/decoder.h index 20e32bfbf..02ccaa42b 100644 --- a/src/lib/decoder.h +++ b/src/lib/decoder.h @@ -56,8 +56,12 @@ public: virtual bool pass () = 0; virtual bool seek (double); - virtual void seek_back () {} - virtual void seek_forward () {} + virtual bool seek_back () { + return true; + } + virtual bool seek_forward () { + return true; + } boost::signals2::signal OutputChanged; diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 82c7cafd1..d5285b73a 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -519,16 +519,24 @@ FFmpegDecoder::seek (double p) return do_seek (p, false, false); } -void +bool FFmpegDecoder::seek_back () { - do_seek (last_content_time() - 2.5 / video_frame_rate(), true, true); + if (last_content_time() < 2.5) { + return true; + } + + return do_seek (last_content_time() - 2.5 / video_frame_rate(), true, true); } -void +bool FFmpegDecoder::seek_forward () { - do_seek (last_content_time() - 0.5 / video_frame_rate(), true, true); + if (last_content_time() >= (video_length() - video_frame_rate())) { + return true; + } + + return do_seek (last_content_time() - 0.5 / video_frame_rate(), true, true); } bool diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h index 174cc3995..1e273752a 100644 --- a/src/lib/ffmpeg_decoder.h +++ b/src/lib/ffmpeg_decoder.h @@ -77,8 +77,8 @@ public: } bool seek (double); - void seek_forward (); - void seek_back (); + bool seek_forward (); + bool seek_back (); bool pass (); private: diff --git a/src/lib/player.cc b/src/lib/player.cc index 7a149d734..01bdc5ee0 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -30,6 +30,7 @@ using std::list; using std::cout; +using std::vector; using boost::shared_ptr; using boost::weak_ptr; using boost::dynamic_pointer_cast; @@ -74,27 +75,27 @@ Player::pass () bool done = true; - if (_video_decoder != _video_decoders.end ()) { + if (_video_decoder < _video_decoders.size ()) { /* Run video decoder; this may also produce audio */ - if ((*_video_decoder)->pass ()) { + if (_video_decoders[_video_decoder]->pass ()) { _video_decoder++; } - if (_video_decoder != _video_decoders.end ()) { + if (_video_decoder < _video_decoders.size ()) { done = false; } - } else if (!_video && _playlist->audio_from() == Playlist::AUDIO_FFMPEG && _sequential_audio_decoder != _audio_decoders.end ()) { + } else if (!_video && _playlist->audio_from() == Playlist::AUDIO_FFMPEG && _sequential_audio_decoder < _audio_decoders.size ()) { /* We're not producing video, so we may need to run FFmpeg content to get the audio */ - if ((*_sequential_audio_decoder)->pass ()) { + if (_audio_decoders[_sequential_audio_decoder]->pass ()) { _sequential_audio_decoder++; } - if (_sequential_audio_decoder != _audio_decoders.end ()) { + if (_sequential_audio_decoder < _audio_decoders.size ()) { done = false; } @@ -102,7 +103,7 @@ Player::pass () /* We're getting audio from SndfileContent */ - for (list >::iterator i = _audio_decoders.begin(); i != _audio_decoders.end(); ++i) { + for (vector >::iterator i = _audio_decoders.begin(); i != _audio_decoders.end(); ++i) { if (!(*i)->pass ()) { done = false; } @@ -121,35 +122,30 @@ Player::set_progress (shared_ptr job) { /* Assume progress can be divined from how far through the video we are */ - if (_video_decoder == _video_decoders.end() || !_playlist->video_length()) { + if (_video_decoder >= _video_decoders.size() || !_playlist->video_length()) { return; } - - ContentVideoFrame p = 0; - list >::iterator i = _video_decoders.begin (); - while (i != _video_decoders.end() && i != _video_decoder) { - p += (*i)->video_length (); - } - job->set_progress (float ((*_video_decoder)->video_frame ()) / _playlist->video_length ()); + job->set_progress ((_video_start[_video_decoder] + _video_decoders[_video_decoder]->video_frame()) / _playlist->video_length ()); } void Player::process_video (shared_ptr i, bool same, shared_ptr s, double t) { - /* XXX: this time will need mangling to add on the offset of the start of the content */ - Video (i, same, s, t); + Video (i, same, s, _video_start[_video_decoder] + t); } void Player::process_audio (weak_ptr c, shared_ptr b, double t) { - /* XXX: this time will need mangling to add on the offset of the start of the content */ AudioMapping mapping = _film->audio_mapping (); if (!_audio_buffers) { _audio_buffers.reset (new AudioBuffers (mapping.dcp_channels(), b->frames ())); _audio_buffers->make_silent (); _audio_time = t; + if (_playlist->audio_from() == Playlist::AUDIO_FFMPEG) { + _audio_time = _audio_time.get() + _audio_start[_sequential_audio_decoder]; + } } for (int i = 0; i < b->channels(); ++i) { @@ -177,18 +173,20 @@ Player::seek (double t) } /* Find the decoder that contains this position */ - _video_decoder = _video_decoders.begin (); - while (_video_decoder != _video_decoders.end ()) { - double const this_length = double ((*_video_decoder)->video_length()) / _film->video_frame_rate (); - if (t < this_length) { + _video_decoder = 0; + while (_video_decoder < _video_decoders.size ()) { + if (t < _video_start[_video_decoder]) { + assert (_video_decoder); + --_video_decoder; break; } - t -= this_length; + + t -= _video_start[_video_decoder]; ++_video_decoder; } - if (_video_decoder != _video_decoders.end()) { - (*_video_decoder)->seek (t); + if (_video_decoder < _video_decoders.size()) { + _video_decoders[_video_decoder]->seek (t); } else { return true; } @@ -216,13 +214,21 @@ void Player::setup_decoders () { _video_decoders.clear (); - _video_decoder = _video_decoders.end (); + _video_decoder = 0; _audio_decoders.clear (); + _sequential_audio_decoder = 0; + + _video_start.clear(); + _audio_start.clear(); + + double video_so_far = 0; + double audio_so_far = 0; if (_video) { list > vc = _playlist->video (); for (list >::iterator i = vc.begin(); i != vc.end(); ++i) { + shared_ptr c; shared_ptr d; /* XXX: into content? */ @@ -241,19 +247,23 @@ Player::setup_decoders () fd->Audio.connect (bind (&Player::process_audio, this, fc, _1, _2)); } + c = fc; d = fd; } shared_ptr ic = dynamic_pointer_cast (*i); if (ic) { + c = ic; d.reset (new ImageMagickDecoder (_film, ic)); } d->connect_video (shared_from_this ()); _video_decoders.push_back (d); + _video_start.push_back (video_so_far); + video_so_far += c->video_length() / c->video_frame_rate(); } - _video_decoder = _video_decoders.begin (); + _video_decoder = 0; } if (_playlist->audio_from() == Playlist::AUDIO_FFMPEG && !_video) { @@ -278,9 +288,11 @@ Player::setup_decoders () d->Audio.connect (bind (&Player::process_audio, this, fc, _1, _2)); _audio_decoders.push_back (d); + _audio_start.push_back (audio_so_far); + audio_so_far += fc->audio_length() / fc->audio_frame_rate(); } - _sequential_audio_decoder = _audio_decoders.begin (); + _sequential_audio_decoder = 0; } if (_playlist->audio_from() == Playlist::AUDIO_SNDFILE) { @@ -294,6 +306,8 @@ Player::setup_decoders () shared_ptr d (new SndfileDecoder (_film, sc)); d->Audio.connect (bind (&Player::process_audio, this, sc, _1, _2)); _audio_decoders.push_back (d); + _audio_start.push_back (audio_so_far); + audio_so_far += sc->audio_length () / sc->audio_frame_rate(); } } } @@ -301,12 +315,7 @@ Player::setup_decoders () double Player::last_video_time () const { - double t = 0; - for (list >::const_iterator i = _video_decoders.begin(); i != _video_decoder; ++i) { - t += (*i)->video_length() / (*i)->video_frame_rate (); - } - - return t + (*_video_decoder)->last_content_time (); + return _video_start[_video_decoder] + _video_decoders[_video_decoder]->last_content_time (); } void diff --git a/src/lib/player.h b/src/lib/player.h index 44b7c126d..2069064d7 100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@ -72,12 +72,18 @@ private: /** Our decoders are ready to go; if this is false the decoders must be (re-)created before they are used */ bool _have_valid_decoders; - std::list > _video_decoders; - std::list >::iterator _video_decoder; - std::list > _audio_decoders; - - /** Current audio decoder if we are running them sequentially; otherwise undefined */ - std::list >::iterator _sequential_audio_decoder; + /** Video decoders in order of presentation */ + std::vector > _video_decoders; + /** Start positions of each video decoder in seconds*/ + std::vector _video_start; + /** Index of current video decoder */ + size_t _video_decoder; + /** Audio decoders in order of presentation (if they are from FFmpeg) */ + std::vector > _audio_decoders; + /** Start positions of each audio decoder (if they are from FFmpeg) in seconds */ + std::vector _audio_start; + /** Current audio decoder index if we are running them sequentially; otherwise undefined */ + size_t _sequential_audio_decoder; boost::shared_ptr _audio_buffers; boost::optional _audio_time; -- cgit v1.2.3 From 9a600583510db7925767edb7fc3b742449ce3486 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 26 Apr 2013 17:32:42 +0100 Subject: Fix up handling of FFmpeg audio a bit. --- src/lib/player.cc | 98 +++++++++++++++++++++---------------------------------- 1 file changed, 37 insertions(+), 61 deletions(-) (limited to 'src') diff --git a/src/lib/player.cc b/src/lib/player.cc index 01bdc5ee0..a84117a4e 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -224,76 +224,53 @@ Player::setup_decoders () double video_so_far = 0; double audio_so_far = 0; - if (_video) { - list > vc = _playlist->video (); - for (list >::iterator i = vc.begin(); i != vc.end(); ++i) { - - shared_ptr c; - shared_ptr d; - - /* XXX: into content? */ - - shared_ptr fc = dynamic_pointer_cast (*i); - if (fc) { - shared_ptr fd ( - new FFmpegDecoder ( - _film, fc, _video, - _audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG, - _subtitles - ) - ); - - if (_playlist->audio_from() == Playlist::AUDIO_FFMPEG) { - fd->Audio.connect (bind (&Player::process_audio, this, fc, _1, _2)); - } - - c = fc; - d = fd; - } - - shared_ptr ic = dynamic_pointer_cast (*i); - if (ic) { - c = ic; - d.reset (new ImageMagickDecoder (_film, ic)); - } - - d->connect_video (shared_from_this ()); - _video_decoders.push_back (d); - _video_start.push_back (video_so_far); - video_so_far += c->video_length() / c->video_frame_rate(); - } - - _video_decoder = 0; - } - - if (_playlist->audio_from() == Playlist::AUDIO_FFMPEG && !_video) { - - /* If we're getting audio from FFmpegContent but not the video, we need a set - of decoders for the audio. - */ + list > vc = _playlist->video (); + for (list >::iterator i = vc.begin(); i != vc.end(); ++i) { - list > ac = _playlist->audio (); - for (list >::iterator i = ac.begin(); i != ac.end(); ++i) { - - shared_ptr fc = dynamic_pointer_cast (*i); - assert (fc); - - shared_ptr d ( + shared_ptr video_content; + shared_ptr audio_content; + shared_ptr video_decoder; + shared_ptr audio_decoder; + + /* XXX: into content? */ + + shared_ptr fc = dynamic_pointer_cast (*i); + if (fc) { + shared_ptr fd ( new FFmpegDecoder ( _film, fc, _video, _audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG, _subtitles ) ); - - d->Audio.connect (bind (&Player::process_audio, this, fc, _1, _2)); - _audio_decoders.push_back (d); + + video_content = fc; + audio_content = fc; + video_decoder = fd; + audio_decoder = fd; + } + + shared_ptr ic = dynamic_pointer_cast (*i); + if (ic) { + video_content = ic; + video_decoder.reset (new ImageMagickDecoder (_film, ic)); + } + + video_decoder->connect_video (shared_from_this ()); + _video_decoders.push_back (video_decoder); + _video_start.push_back (video_so_far); + video_so_far += video_content->video_length() / video_content->video_frame_rate(); + + if (audio_decoder && _playlist->audio_from() == Playlist::AUDIO_FFMPEG) { + audio_decoder->Audio.connect (bind (&Player::process_audio, this, audio_content, _1, _2)); + _audio_decoders.push_back (audio_decoder); _audio_start.push_back (audio_so_far); - audio_so_far += fc->audio_length() / fc->audio_frame_rate(); + audio_so_far += double(audio_content->audio_length()) / audio_content->audio_frame_rate(); } - - _sequential_audio_decoder = 0; } + + _video_decoder = 0; + _sequential_audio_decoder = 0; if (_playlist->audio_from() == Playlist::AUDIO_SNDFILE) { @@ -307,7 +284,6 @@ Player::setup_decoders () d->Audio.connect (bind (&Player::process_audio, this, sc, _1, _2)); _audio_decoders.push_back (d); _audio_start.push_back (audio_so_far); - audio_so_far += sc->audio_length () / sc->audio_frame_rate(); } } } -- cgit v1.2.3 From 3e1ae9934f3b908943c90db523ae2332022b5f1d Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 26 Apr 2013 19:13:50 +0100 Subject: Fix seek. --- src/lib/player.cc | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/lib/player.cc b/src/lib/player.cc index a84117a4e..357c69e82 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -174,17 +174,15 @@ Player::seek (double t) /* Find the decoder that contains this position */ _video_decoder = 0; - while (_video_decoder < _video_decoders.size ()) { - if (t < _video_start[_video_decoder]) { - assert (_video_decoder); + while (1) { + ++_video_decoder; + if (_video_decoder >= _video_decoders.size () || t < _video_start[_video_decoder]) { --_video_decoder; + t -= _video_start[_video_decoder]; break; } - - t -= _video_start[_video_decoder]; - ++_video_decoder; } - + if (_video_decoder < _video_decoders.size()) { _video_decoders[_video_decoder]->seek (t); } else { -- cgit v1.2.3 From 18593159bef6174dc65520df1c4b871e13baf1f7 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 26 Apr 2013 19:29:53 +0100 Subject: Fix player logic. --- src/lib/player.cc | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/lib/player.cc b/src/lib/player.cc index 357c69e82..4caddb7e6 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -75,7 +75,7 @@ Player::pass () bool done = true; - if (_video_decoder < _video_decoders.size ()) { + if (_video && _video_decoder < _video_decoders.size ()) { /* Run video decoder; this may also produce audio */ @@ -87,7 +87,9 @@ Player::pass () done = false; } - } else if (!_video && _playlist->audio_from() == Playlist::AUDIO_FFMPEG && _sequential_audio_decoder < _audio_decoders.size ()) { + } + + if (!_video && _playlist->audio_from() == Playlist::AUDIO_FFMPEG && _sequential_audio_decoder < _audio_decoders.size ()) { /* We're not producing video, so we may need to run FFmpeg content to get the audio */ @@ -99,8 +101,10 @@ Player::pass () done = false; } - } else if (_playlist->audio_from() == Playlist::AUDIO_SNDFILE) { + } + if (_playlist->audio_from() == Playlist::AUDIO_SNDFILE) { + /* We're getting audio from SndfileContent */ for (vector >::iterator i = _audio_decoders.begin(); i != _audio_decoders.end(); ++i) { -- cgit v1.2.3 From 976263adce6580a0bf73dd1f287848c0cbcd96c2 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 26 Apr 2013 19:53:10 +0100 Subject: Fix update of display on re-order of still content. --- src/wx/film_viewer.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 688be3bd0..e742a3e41 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -118,11 +118,12 @@ FilmViewer::film_changed (Film::Property p) update_from_raw (); break; case Film::CONTENT: + { calculate_sizes (); - get_frame (); - _panel->Refresh (); - _v_sizer->Layout (); + wxScrollEvent ev; + slider_moved (ev); break; + } case Film::WITH_SUBTITLES: case Film::SUBTITLE_OFFSET: case Film::SUBTITLE_SCALE: -- cgit v1.2.3 From 9883b9c5a5c29c3308aa816b322e552ff188c213 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 26 Apr 2013 20:27:19 +0100 Subject: Pick up old config file. --- src/lib/config.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/config.cc b/src/lib/config.cc index 354940b1c..e6f657a39 100644 --- a/src/lib/config.cc +++ b/src/lib/config.cc @@ -155,7 +155,7 @@ Config::file (bool old) const boost::filesystem::path p; p /= g_get_user_config_dir (); if (old) { - p /= ".dcpomatic"; + p /= ".dvdomatic"; } else { p /= ".dcpomatic.xml"; } -- cgit v1.2.3 From d851e5d3fd3e5af48c7e464a305c9d0001999700 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 26 Apr 2013 21:35:02 +0100 Subject: Fix content length reporting; fix crash when player has audio disabled. --- branch-notes | 1 - src/lib/film.cc | 8 +++++++- src/lib/film.h | 4 +++- src/lib/player.cc | 4 ++-- src/lib/playlist.cc | 12 ++++++++++++ src/lib/playlist.h | 1 + src/wx/film_editor.cc | 25 ++++++++++++++----------- 7 files changed, 39 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/branch-notes b/branch-notes index e9c85d565..dd90ed91f 100644 --- a/branch-notes +++ b/branch-notes @@ -1,4 +1,3 @@ audio map view is screwed up on windows, apparently not extended to full height -length of film not reported right when sound is longer than video still image stuff pretty slow diff --git a/src/lib/film.cc b/src/lib/film.cc index 361031fc8..98c6c0610 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -1215,6 +1215,12 @@ Film::video_length () const return _playlist->video_length (); } +ContentVideoFrame +Film::content_length () const +{ + return _playlist->content_length (); +} + /** Unfortunately this is needed as the GUI has FFmpeg-specific controls */ shared_ptr Film::ffmpeg () const @@ -1311,7 +1317,7 @@ Film::content_changed (boost::weak_ptr c, int p) set_dcp_frame_rate (best_dcp_frame_rate (video_frame_rate ())); } else if (p == AudioContentProperty::AUDIO_CHANNELS) { set_audio_mapping (_playlist->default_audio_mapping ()); - } + } if (ui_signaller) { ui_signaller->emit (boost::bind (boost::ref (ContentChanged), c, p)); diff --git a/src/lib/film.h b/src/lib/film.h index 071f474ac..43b5d1a17 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -113,7 +113,9 @@ public: float video_frame_rate () const; libdcp::Size video_size () const; - ContentVideoFrame video_length () const; + ContentVideoFrame video_length () const; + + ContentVideoFrame content_length () const; std::vector ffmpeg_subtitle_streams () const; boost::optional ffmpeg_subtitle_stream () const; diff --git a/src/lib/player.cc b/src/lib/player.cc index 4caddb7e6..7c75597ea 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -89,7 +89,7 @@ Player::pass () } - if (!_video && _playlist->audio_from() == Playlist::AUDIO_FFMPEG && _sequential_audio_decoder < _audio_decoders.size ()) { + if (!_video && _audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG && _sequential_audio_decoder < _audio_decoders.size ()) { /* We're not producing video, so we may need to run FFmpeg content to get the audio */ @@ -103,7 +103,7 @@ Player::pass () } - if (_playlist->audio_from() == Playlist::AUDIO_SNDFILE) { + if (_audio && _playlist->audio_from() == Playlist::AUDIO_SNDFILE) { /* We're getting audio from SndfileContent */ diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index e32788951..3c69ae15f 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -276,3 +276,15 @@ Playlist::video_digest () const return md5_digest (t.c_str(), t.length()); } + +ContentVideoFrame +Playlist::content_length () const +{ + float const vfr = video_frame_rate() > 0 ? video_frame_rate() : 24; + int const afr = audio_frame_rate() > 0 ? audio_frame_rate() : 48000; + + return max ( + video_length(), + ContentVideoFrame (audio_length() * vfr / afr) + ); +} diff --git a/src/lib/playlist.h b/src/lib/playlist.h index 9a2627b1d..85bde64ff 100644 --- a/src/lib/playlist.h +++ b/src/lib/playlist.h @@ -64,6 +64,7 @@ public: ContentVideoFrame video_length () const; AudioMapping default_audio_mapping () const; + ContentVideoFrame content_length () const; enum AudioFrom { AUDIO_FFMPEG, diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index f9ca8609b..f909a8e2e 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -60,6 +60,7 @@ using std::fixed; using std::setprecision; using std::list; using std::vector; +using std::max; using boost::shared_ptr; using boost::weak_ptr; using boost::dynamic_pointer_cast; @@ -742,7 +743,7 @@ FilmEditor::film_content_changed (weak_ptr content, int property) } else if (property == FFmpegContentProperty::AUDIO_STREAMS) { setup_streams (); setup_show_audio_sensitivity (); - } else if (property == VideoContentProperty::VIDEO_LENGTH) { + } else if (property == VideoContentProperty::VIDEO_LENGTH || property == AudioContentProperty::AUDIO_LENGTH) { setup_length (); boost::shared_ptr c = content.lock (); if (c && c == selected_content()) { @@ -786,17 +787,19 @@ void FilmEditor::setup_length () { stringstream s; - if (_film->video_frame_rate() > 0 && _film->video_length()) { - s << _film->video_length() << " " - << wx_to_std (_("frames")) << "; " << seconds_to_hms (_film->video_length() / _film->video_frame_rate()); - } else if (_film->video_length()) { - s << _film->video_length() << " " - << wx_to_std (_("frames")); - } + ContentVideoFrame const frames = _film->content_length (); + + if (frames && _film->video_frame_rate()) { + s << frames << " " << wx_to_std (_("frames")) << "; " << seconds_to_hms (frames / _film->video_frame_rate()); + } else if (frames) { + s << frames << " " << wx_to_std (_("frames")); + } + _length->SetLabel (std_to_wx (s.str ())); - if (_film->video_length()) { - _trim_start->SetRange (0, _film->video_length()); - _trim_end->SetRange (0, _film->video_length()); + + if (frames) { + _trim_start->SetRange (0, frames); + _trim_end->SetRange (0, frames); } } -- cgit v1.2.3 From 0194092f7f2b4a6ceb3e69c470fae8c92bdca077 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 26 Apr 2013 22:25:09 +0100 Subject: Rename server and makedcp (temporarily?) so that it is parallel installable with dvd-o-matic. --- src/tools/makedcp.cc | 217 -------------------------------------------- src/tools/servomatic_cli.cc | 97 -------------------- src/tools/servomatic_gui.cc | 174 ----------------------------------- src/tools/wscript | 4 +- 4 files changed, 2 insertions(+), 490 deletions(-) delete mode 100644 src/tools/makedcp.cc delete mode 100644 src/tools/servomatic_cli.cc delete mode 100644 src/tools/servomatic_gui.cc (limited to 'src') diff --git a/src/tools/makedcp.cc b/src/tools/makedcp.cc deleted file mode 100644 index e2e1874c4..000000000 --- a/src/tools/makedcp.cc +++ /dev/null @@ -1,217 +0,0 @@ -/* - Copyright (C) 2012 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include -#include -#include -#include -#include -#include "format.h" -#include "film.h" -#include "filter.h" -#include "transcode_job.h" -#include "job_manager.h" -#include "ab_transcode_job.h" -#include "util.h" -#include "scaler.h" -#include "version.h" -#include "cross.h" -#include "config.h" -#include "log.h" - -using std::string; -using std::cerr; -using std::cout; -using std::vector; -using std::pair; -using std::list; -using boost::shared_ptr; - -static void -help (string n) -{ - cerr << "Syntax: " << n << " [OPTION] \n" - << " -v, --version show DCP-o-matic version\n" - << " -h, --help show this help\n" - << " -d, --deps list DCP-o-matic dependency details and quit\n" - << " -t, --test run in test mode (repeatable UUID generation, timestamps etc.)\n" - << " -n, --no-progress do not print progress to stdout\n" - << " -r, --no-remote do not use any remote servers\n" - << "\n" - << " is the film directory.\n"; -} - -int -main (int argc, char* argv[]) -{ - string film_dir; - bool test_mode = false; - bool progress = true; - bool no_remote = false; - int log_level = 1; - - int option_index = 0; - while (1) { - static struct option long_options[] = { - { "version", no_argument, 0, 'v'}, - { "help", no_argument, 0, 'h'}, - { "deps", no_argument, 0, 'd'}, - { "test", no_argument, 0, 't'}, - { "no-progress", no_argument, 0, 'n'}, - { "no-remote", no_argument, 0, 'r'}, - { "log-level", required_argument, 0, 'l' }, - { 0, 0, 0, 0 } - }; - - int c = getopt_long (argc, argv, "vhdtnrl:", long_options, &option_index); - - if (c == -1) { - break; - } - - switch (c) { - case 'v': - cout << "dcpomatic version " << dcpomatic_version << " " << dcpomatic_git_commit << "\n"; - exit (EXIT_SUCCESS); - case 'h': - help (argv[0]); - exit (EXIT_SUCCESS); - case 'd': - cout << dependency_version_summary () << "\n"; - exit (EXIT_SUCCESS); - case 't': - test_mode = true; - break; - case 'n': - progress = false; - break; - case 'r': - no_remote = true; - break; - case 'l': - log_level = atoi (optarg); - break; - } - } - - if (optind >= argc) { - help (argv[0]); - exit (EXIT_FAILURE); - } - - film_dir = argv[optind]; - - dcpomatic_setup (); - - if (no_remote) { - Config::instance()->set_servers (vector ()); - } - - cout << "DCP-o-matic " << dcpomatic_version << " git " << dcpomatic_git_commit; - char buf[256]; - if (gethostname (buf, 256) == 0) { - cout << " on " << buf; - } - cout << "\n"; - - if (test_mode) { - libdcp::enable_test_mode (); - cout << dependency_version_summary() << "\n"; - } - - shared_ptr film; - try { - film.reset (new Film (film_dir, true)); - } catch (std::exception& e) { - cerr << argv[0] << ": error reading film `" << film_dir << "' (" << e.what() << ")\n"; - exit (EXIT_FAILURE); - } - - film->log()->set_level ((Log::Level) log_level); - - cout << "\nMaking "; - if (film->ab()) { - cout << "A/B "; - } - cout << "DCP for " << film->name() << "\n"; - cout << "Test mode: " << (test_mode ? "yes" : "no") << "\n"; -// cout << "Content: " << film->content() << "\n"; - pair const f = Filter::ffmpeg_strings (film->filters ()); - cout << "Filters: " << f.first << " " << f.second << "\n"; - - film->make_dcp (); - - bool should_stop = false; - bool first = true; - bool error = false; - while (!should_stop) { - - dcpomatic_sleep (5); - - list > jobs = JobManager::instance()->get (); - - if (!first && progress) { - cout << "\033[" << jobs.size() << "A"; - cout.flush (); - } - - first = false; - - int unfinished = 0; - int finished_in_error = 0; - - for (list >::iterator i = jobs.begin(); i != jobs.end(); ++i) { - if (progress) { - cout << (*i)->name() << ": "; - - float const p = (*i)->overall_progress (); - - if (p >= 0) { - cout << (*i)->status() << " \n"; - } else { - cout << ": Running \n"; - } - } - - if (!(*i)->finished ()) { - ++unfinished; - } - - if ((*i)->finished_in_error ()) { - ++finished_in_error; - error = true; - } - - if (!progress && (*i)->finished_in_error ()) { - /* We won't see this error if we haven't been showing progress, - so show it now. - */ - cout << (*i)->status() << "\n"; - } - } - - if (unfinished == 0 || finished_in_error != 0) { - should_stop = true; - } - } - - return error ? EXIT_FAILURE : EXIT_SUCCESS; -} - - diff --git a/src/tools/servomatic_cli.cc b/src/tools/servomatic_cli.cc deleted file mode 100644 index 76d085034..000000000 --- a/src/tools/servomatic_cli.cc +++ /dev/null @@ -1,97 +0,0 @@ -/* - Copyright (C) 2012 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include "lib/server.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "config.h" -#include "dcp_video_frame.h" -#include "exceptions.h" -#include "util.h" -#include "config.h" -#include "scaler.h" -#include "image.h" -#include "log.h" -#include "version.h" - -using std::cerr; -using std::string; -using std::cout; -using boost::shared_ptr; - -static void -help (string n) -{ - cerr << "Syntax: " << n << " [OPTION]\n" - << " -v, --version show DCP-o-matic version\n" - << " -h, --help show this help\n" - << " -t, --threads number of parallel encoding threads to use\n"; -} - -int -main (int argc, char* argv[]) -{ - int num_threads = Config::instance()->num_local_encoding_threads (); - - int option_index = 0; - while (1) { - static struct option long_options[] = { - { "version", no_argument, 0, 'v'}, - { "help", no_argument, 0, 'h'}, - { "threads", required_argument, 0, 't'}, - { 0, 0, 0, 0 } - }; - - int c = getopt_long (argc, argv, "vht:", long_options, &option_index); - - if (c == -1) { - break; - } - - switch (c) { - case 'v': - cout << "dcpomatic version " << dcpomatic_version << " " << dcpomatic_git_commit << "\n"; - exit (EXIT_SUCCESS); - case 'h': - help (argv[0]); - exit (EXIT_SUCCESS); - case 't': - num_threads = atoi (optarg); - break; - } - } - - Scaler::setup_scalers (); - shared_ptr log (new FileLog ("servomatic.log")); - Server server (log); - server.run (num_threads); - return 0; -} diff --git a/src/tools/servomatic_gui.cc b/src/tools/servomatic_gui.cc deleted file mode 100644 index 152e063c1..000000000 --- a/src/tools/servomatic_gui.cc +++ /dev/null @@ -1,174 +0,0 @@ -/* - Copyright (C) 2012 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include -#include -#include -#include "wx_util.h" -#include "lib/util.h" -#include "lib/server.h" -#include "lib/config.h" - -using std::cout; -using std::string; -using boost::shared_ptr; -using boost::thread; -using boost::bind; - -enum { - ID_status = 1, - ID_quit, - ID_timer -}; - -class MemoryLog : public Log -{ -public: - - string get () const { - boost::mutex::scoped_lock (_mutex); - return _log; - } - -private: - void do_log (string m) - { - _log = m; - } - - string _log; -}; - -static shared_ptr memory_log (new MemoryLog); - -class StatusDialog : public wxDialog -{ -public: - StatusDialog () - : wxDialog (0, wxID_ANY, _("DCP-o-matic encode server"), wxDefaultPosition, wxSize (600, 80), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) - , _timer (this, ID_timer) - { - _sizer = new wxFlexGridSizer (1, 6, 6); - _sizer->AddGrowableCol (0, 1); - - _text = new wxTextCtrl (this, wxID_ANY, _(""), wxDefaultPosition, wxDefaultSize, wxTE_READONLY); - _sizer->Add (_text, 1, wxEXPAND); - - SetSizer (_sizer); - _sizer->Layout (); - - Connect (ID_timer, wxEVT_TIMER, wxTimerEventHandler (StatusDialog::update)); - _timer.Start (1000); - } - -private: - void update (wxTimerEvent &) - { - _text->ChangeValue (std_to_wx (memory_log->get ())); - _sizer->Layout (); - } - - wxFlexGridSizer* _sizer; - wxTextCtrl* _text; - wxTimer _timer; -}; - -class TaskBarIcon : public wxTaskBarIcon -{ -public: - TaskBarIcon () - { -#ifdef __WXMSW__ - wxIcon icon (std_to_wx ("taskbar_icon")); -#endif -#ifdef __WXGTK__ - wxInitAllImageHandlers(); - wxBitmap bitmap (wxString::Format (wxT ("%s/taskbar_icon.png"), POSIX_ICON_PREFIX), wxBITMAP_TYPE_PNG); - wxIcon icon; - icon.CopyFromBitmap (bitmap); -#endif - SetIcon (icon, std_to_wx ("DCP-o-matic encode server")); - - Connect (ID_status, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (TaskBarIcon::status)); - Connect (ID_quit, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (TaskBarIcon::quit)); - } - - wxMenu* CreatePopupMenu () - { - wxMenu* menu = new wxMenu; - menu->Append (ID_status, std_to_wx ("Status...")); - menu->Append (ID_quit, std_to_wx ("Quit")); - return menu; - } - -private: - void status (wxCommandEvent &) - { - StatusDialog* d = new StatusDialog; - d->Show (); - } - - void quit (wxCommandEvent &) - { - wxTheApp->ExitMainLoop (); - } -}; - -class App : public wxApp -{ -public: - App () - : wxApp () - , _thread (0) - , _icon (0) - {} - -private: - - bool OnInit () - { - if (!wxApp::OnInit ()) { - return false; - } - - dcpomatic_setup (); - - _icon = new TaskBarIcon; - _thread = new thread (bind (&App::main_thread, this)); - - return true; - } - - int OnExit () - { - delete _icon; - return wxApp::OnExit (); - } - - void main_thread () - { - Server server (memory_log); - server.run (Config::instance()->num_local_encoding_threads ()); - } - - boost::thread* _thread; - TaskBarIcon* _icon; -}; - -IMPLEMENT_APP (App) diff --git a/src/tools/wscript b/src/tools/wscript index f0ffb8e89..466f29031 100644 --- a/src/tools/wscript +++ b/src/tools/wscript @@ -4,7 +4,7 @@ from waflib import Logs import i18n def build(bld): - for t in ['makedcp', 'servomatic_cli', 'servomatictest']: + for t in ['dcpomatic_cli', 'dcpomatic_server_cli']: obj = bld(features = 'cxx cxxprogram') obj.uselib = 'BOOST_THREAD OPENJPEG DCP CXML AVFORMAT AVFILTER AVCODEC AVUTIL SWSCALE POSTPROC' obj.includes = ['..'] @@ -13,7 +13,7 @@ def build(bld): obj.target = t if not bld.env.DISABLE_GUI: - for t in ['dcpomatic', 'servomatic_gui']: + for t in ['dcpomatic', 'dcpomatic_server']: obj = bld(features = 'cxx cxxprogram') obj.uselib = 'DCP CXML OPENJPEG AVFORMAT AVFILTER AVCODEC AVUTIL SWSCALE POSTPROC' obj.includes = ['..'] -- cgit v1.2.3 From f09c6b53f155de601900afa90045059b20310c0d Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 26 Apr 2013 22:36:10 +0100 Subject: Add missing files. --- src/tools/dcpomatic_cli.cc | 217 ++++++++++++++++++++++++++++++++++++++ src/tools/dcpomatic_server.cc | 174 ++++++++++++++++++++++++++++++ src/tools/dcpomatic_server_cli.cc | 97 +++++++++++++++++ 3 files changed, 488 insertions(+) create mode 100644 src/tools/dcpomatic_cli.cc create mode 100644 src/tools/dcpomatic_server.cc create mode 100644 src/tools/dcpomatic_server_cli.cc (limited to 'src') diff --git a/src/tools/dcpomatic_cli.cc b/src/tools/dcpomatic_cli.cc new file mode 100644 index 000000000..e2e1874c4 --- /dev/null +++ b/src/tools/dcpomatic_cli.cc @@ -0,0 +1,217 @@ +/* + Copyright (C) 2012 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include +#include +#include +#include +#include "format.h" +#include "film.h" +#include "filter.h" +#include "transcode_job.h" +#include "job_manager.h" +#include "ab_transcode_job.h" +#include "util.h" +#include "scaler.h" +#include "version.h" +#include "cross.h" +#include "config.h" +#include "log.h" + +using std::string; +using std::cerr; +using std::cout; +using std::vector; +using std::pair; +using std::list; +using boost::shared_ptr; + +static void +help (string n) +{ + cerr << "Syntax: " << n << " [OPTION] \n" + << " -v, --version show DCP-o-matic version\n" + << " -h, --help show this help\n" + << " -d, --deps list DCP-o-matic dependency details and quit\n" + << " -t, --test run in test mode (repeatable UUID generation, timestamps etc.)\n" + << " -n, --no-progress do not print progress to stdout\n" + << " -r, --no-remote do not use any remote servers\n" + << "\n" + << " is the film directory.\n"; +} + +int +main (int argc, char* argv[]) +{ + string film_dir; + bool test_mode = false; + bool progress = true; + bool no_remote = false; + int log_level = 1; + + int option_index = 0; + while (1) { + static struct option long_options[] = { + { "version", no_argument, 0, 'v'}, + { "help", no_argument, 0, 'h'}, + { "deps", no_argument, 0, 'd'}, + { "test", no_argument, 0, 't'}, + { "no-progress", no_argument, 0, 'n'}, + { "no-remote", no_argument, 0, 'r'}, + { "log-level", required_argument, 0, 'l' }, + { 0, 0, 0, 0 } + }; + + int c = getopt_long (argc, argv, "vhdtnrl:", long_options, &option_index); + + if (c == -1) { + break; + } + + switch (c) { + case 'v': + cout << "dcpomatic version " << dcpomatic_version << " " << dcpomatic_git_commit << "\n"; + exit (EXIT_SUCCESS); + case 'h': + help (argv[0]); + exit (EXIT_SUCCESS); + case 'd': + cout << dependency_version_summary () << "\n"; + exit (EXIT_SUCCESS); + case 't': + test_mode = true; + break; + case 'n': + progress = false; + break; + case 'r': + no_remote = true; + break; + case 'l': + log_level = atoi (optarg); + break; + } + } + + if (optind >= argc) { + help (argv[0]); + exit (EXIT_FAILURE); + } + + film_dir = argv[optind]; + + dcpomatic_setup (); + + if (no_remote) { + Config::instance()->set_servers (vector ()); + } + + cout << "DCP-o-matic " << dcpomatic_version << " git " << dcpomatic_git_commit; + char buf[256]; + if (gethostname (buf, 256) == 0) { + cout << " on " << buf; + } + cout << "\n"; + + if (test_mode) { + libdcp::enable_test_mode (); + cout << dependency_version_summary() << "\n"; + } + + shared_ptr film; + try { + film.reset (new Film (film_dir, true)); + } catch (std::exception& e) { + cerr << argv[0] << ": error reading film `" << film_dir << "' (" << e.what() << ")\n"; + exit (EXIT_FAILURE); + } + + film->log()->set_level ((Log::Level) log_level); + + cout << "\nMaking "; + if (film->ab()) { + cout << "A/B "; + } + cout << "DCP for " << film->name() << "\n"; + cout << "Test mode: " << (test_mode ? "yes" : "no") << "\n"; +// cout << "Content: " << film->content() << "\n"; + pair const f = Filter::ffmpeg_strings (film->filters ()); + cout << "Filters: " << f.first << " " << f.second << "\n"; + + film->make_dcp (); + + bool should_stop = false; + bool first = true; + bool error = false; + while (!should_stop) { + + dcpomatic_sleep (5); + + list > jobs = JobManager::instance()->get (); + + if (!first && progress) { + cout << "\033[" << jobs.size() << "A"; + cout.flush (); + } + + first = false; + + int unfinished = 0; + int finished_in_error = 0; + + for (list >::iterator i = jobs.begin(); i != jobs.end(); ++i) { + if (progress) { + cout << (*i)->name() << ": "; + + float const p = (*i)->overall_progress (); + + if (p >= 0) { + cout << (*i)->status() << " \n"; + } else { + cout << ": Running \n"; + } + } + + if (!(*i)->finished ()) { + ++unfinished; + } + + if ((*i)->finished_in_error ()) { + ++finished_in_error; + error = true; + } + + if (!progress && (*i)->finished_in_error ()) { + /* We won't see this error if we haven't been showing progress, + so show it now. + */ + cout << (*i)->status() << "\n"; + } + } + + if (unfinished == 0 || finished_in_error != 0) { + should_stop = true; + } + } + + return error ? EXIT_FAILURE : EXIT_SUCCESS; +} + + diff --git a/src/tools/dcpomatic_server.cc b/src/tools/dcpomatic_server.cc new file mode 100644 index 000000000..152e063c1 --- /dev/null +++ b/src/tools/dcpomatic_server.cc @@ -0,0 +1,174 @@ +/* + Copyright (C) 2012 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include +#include +#include "wx_util.h" +#include "lib/util.h" +#include "lib/server.h" +#include "lib/config.h" + +using std::cout; +using std::string; +using boost::shared_ptr; +using boost::thread; +using boost::bind; + +enum { + ID_status = 1, + ID_quit, + ID_timer +}; + +class MemoryLog : public Log +{ +public: + + string get () const { + boost::mutex::scoped_lock (_mutex); + return _log; + } + +private: + void do_log (string m) + { + _log = m; + } + + string _log; +}; + +static shared_ptr memory_log (new MemoryLog); + +class StatusDialog : public wxDialog +{ +public: + StatusDialog () + : wxDialog (0, wxID_ANY, _("DCP-o-matic encode server"), wxDefaultPosition, wxSize (600, 80), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) + , _timer (this, ID_timer) + { + _sizer = new wxFlexGridSizer (1, 6, 6); + _sizer->AddGrowableCol (0, 1); + + _text = new wxTextCtrl (this, wxID_ANY, _(""), wxDefaultPosition, wxDefaultSize, wxTE_READONLY); + _sizer->Add (_text, 1, wxEXPAND); + + SetSizer (_sizer); + _sizer->Layout (); + + Connect (ID_timer, wxEVT_TIMER, wxTimerEventHandler (StatusDialog::update)); + _timer.Start (1000); + } + +private: + void update (wxTimerEvent &) + { + _text->ChangeValue (std_to_wx (memory_log->get ())); + _sizer->Layout (); + } + + wxFlexGridSizer* _sizer; + wxTextCtrl* _text; + wxTimer _timer; +}; + +class TaskBarIcon : public wxTaskBarIcon +{ +public: + TaskBarIcon () + { +#ifdef __WXMSW__ + wxIcon icon (std_to_wx ("taskbar_icon")); +#endif +#ifdef __WXGTK__ + wxInitAllImageHandlers(); + wxBitmap bitmap (wxString::Format (wxT ("%s/taskbar_icon.png"), POSIX_ICON_PREFIX), wxBITMAP_TYPE_PNG); + wxIcon icon; + icon.CopyFromBitmap (bitmap); +#endif + SetIcon (icon, std_to_wx ("DCP-o-matic encode server")); + + Connect (ID_status, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (TaskBarIcon::status)); + Connect (ID_quit, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (TaskBarIcon::quit)); + } + + wxMenu* CreatePopupMenu () + { + wxMenu* menu = new wxMenu; + menu->Append (ID_status, std_to_wx ("Status...")); + menu->Append (ID_quit, std_to_wx ("Quit")); + return menu; + } + +private: + void status (wxCommandEvent &) + { + StatusDialog* d = new StatusDialog; + d->Show (); + } + + void quit (wxCommandEvent &) + { + wxTheApp->ExitMainLoop (); + } +}; + +class App : public wxApp +{ +public: + App () + : wxApp () + , _thread (0) + , _icon (0) + {} + +private: + + bool OnInit () + { + if (!wxApp::OnInit ()) { + return false; + } + + dcpomatic_setup (); + + _icon = new TaskBarIcon; + _thread = new thread (bind (&App::main_thread, this)); + + return true; + } + + int OnExit () + { + delete _icon; + return wxApp::OnExit (); + } + + void main_thread () + { + Server server (memory_log); + server.run (Config::instance()->num_local_encoding_threads ()); + } + + boost::thread* _thread; + TaskBarIcon* _icon; +}; + +IMPLEMENT_APP (App) diff --git a/src/tools/dcpomatic_server_cli.cc b/src/tools/dcpomatic_server_cli.cc new file mode 100644 index 000000000..76d085034 --- /dev/null +++ b/src/tools/dcpomatic_server_cli.cc @@ -0,0 +1,97 @@ +/* + Copyright (C) 2012 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "lib/server.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "config.h" +#include "dcp_video_frame.h" +#include "exceptions.h" +#include "util.h" +#include "config.h" +#include "scaler.h" +#include "image.h" +#include "log.h" +#include "version.h" + +using std::cerr; +using std::string; +using std::cout; +using boost::shared_ptr; + +static void +help (string n) +{ + cerr << "Syntax: " << n << " [OPTION]\n" + << " -v, --version show DCP-o-matic version\n" + << " -h, --help show this help\n" + << " -t, --threads number of parallel encoding threads to use\n"; +} + +int +main (int argc, char* argv[]) +{ + int num_threads = Config::instance()->num_local_encoding_threads (); + + int option_index = 0; + while (1) { + static struct option long_options[] = { + { "version", no_argument, 0, 'v'}, + { "help", no_argument, 0, 'h'}, + { "threads", required_argument, 0, 't'}, + { 0, 0, 0, 0 } + }; + + int c = getopt_long (argc, argv, "vht:", long_options, &option_index); + + if (c == -1) { + break; + } + + switch (c) { + case 'v': + cout << "dcpomatic version " << dcpomatic_version << " " << dcpomatic_git_commit << "\n"; + exit (EXIT_SUCCESS); + case 'h': + help (argv[0]); + exit (EXIT_SUCCESS); + case 't': + num_threads = atoi (optarg); + break; + } + } + + Scaler::setup_scalers (); + shared_ptr log (new FileLog ("servomatic.log")); + Server server (log); + server.run (num_threads); + return 0; +} -- cgit v1.2.3 From e72546dc3846c9516563d972091c9cf31affd5f5 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 27 Apr 2013 19:05:06 +0100 Subject: Allow multiple selection of content files, and improve behaviour on examining still-image content. --- src/lib/player.cc | 5 +---- src/wx/film_editor.cc | 22 +++++++++++++--------- 2 files changed, 14 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/lib/player.cc b/src/lib/player.cc index 09f1f55a3..b21224587 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -309,10 +309,7 @@ Player::content_changed (weak_ptr w, int p) } if (p == VideoContentProperty::VIDEO_LENGTH) { - if (dynamic_pointer_cast (c)) { - /* FFmpeg content length changes are serious; we need new decoders */ - _have_valid_decoders = false; - } + _have_valid_decoders = false; } } diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index f909a8e2e..b6be39e9b 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -1298,7 +1298,7 @@ FilmEditor::setup_content () void FilmEditor::content_add_clicked (wxCommandEvent &) { - wxFileDialog* d = new wxFileDialog (this); + wxFileDialog* d = new wxFileDialog (this, _("Choose a file or files"), wxT (""), wxT (""), wxT ("*.*"), wxFD_MULTIPLE); int const r = d->ShowModal (); d->Destroy (); @@ -1306,16 +1306,20 @@ FilmEditor::content_add_clicked (wxCommandEvent &) return; } - boost::filesystem::path p (wx_to_std (d->GetPath())); + wxArrayString paths; + d->GetPaths (paths); - if (ImageMagickContent::valid_file (p)) { - _film->add_content (shared_ptr (new ImageMagickContent (p))); - } else if (SndfileContent::valid_file (p)) { - _film->add_content (shared_ptr (new SndfileContent (p))); - } else { - _film->add_content (shared_ptr (new FFmpegContent (p))); + for (unsigned int i = 0; i < paths.GetCount(); ++i) { + boost::filesystem::path p (wx_to_std (paths[i])); + + if (ImageMagickContent::valid_file (p)) { + _film->add_content (shared_ptr (new ImageMagickContent (p))); + } else if (SndfileContent::valid_file (p)) { + _film->add_content (shared_ptr (new SndfileContent (p))); + } else { + _film->add_content (shared_ptr (new FFmpegContent (p))); + } } - } void -- cgit v1.2.3 From f85101ff72bf93ab3546ea0c4ec8e3f1242f256f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 27 Apr 2013 19:51:08 +0100 Subject: Add default still length option. Split config dialog into tabs. --- src/lib/config.cc | 9 +- src/lib/config.h | 11 +- src/lib/imagemagick_content.cc | 3 +- src/wx/config_dialog.cc | 263 ++++++++++++++++++++++++++--------------- src/wx/config_dialog.h | 13 ++ 5 files changed, 202 insertions(+), 97 deletions(-) (limited to 'src') diff --git a/src/lib/config.cc b/src/lib/config.cc index e6f657a39..4f90581f6 100644 --- a/src/lib/config.cc +++ b/src/lib/config.cc @@ -37,6 +37,7 @@ using std::string; using std::ofstream; using std::list; using boost::shared_ptr; +using boost::lexical_cast; using boost::optional; Config* Config::_instance = 0; @@ -48,6 +49,7 @@ Config::Config () , _reference_scaler (Scaler::from_id (N_("bicubic"))) , _tms_path (N_(".")) , _sound_processor (SoundProcessor::from_id (N_("dolby_cp750"))) + , _default_still_length (10) { _allowed_dcp_frame_rates.push_back (24); _allowed_dcp_frame_rates.push_back (25); @@ -94,6 +96,7 @@ Config::Config () _language = f.optional_string_child ("Language"); _default_dci_metadata = DCIMetadata (f.node_child ("DCIMetadata")); + _default_still_length = f.optional_number_child("DefaultStillLength").get_value_or (10); } void @@ -180,9 +183,9 @@ Config::write () const xmlpp::Document doc; xmlpp::Element* root = doc.create_root_node ("Config"); - root->add_child("NumLocalEncodingThreads")->add_child_text (boost::lexical_cast (_num_local_encoding_threads)); + root->add_child("NumLocalEncodingThreads")->add_child_text (lexical_cast (_num_local_encoding_threads)); root->add_child("DefaultDirectory")->add_child_text (_default_directory); - root->add_child("ServerPort")->add_child_text (boost::lexical_cast (_server_port)); + root->add_child("ServerPort")->add_child_text (lexical_cast (_server_port)); if (_reference_scaler) { root->add_child("ReferenceScaler")->add_child_text (_reference_scaler->id ()); } @@ -208,6 +211,8 @@ Config::write () const _default_dci_metadata.as_xml (root->add_child ("DCIMetadata")); + root->add_child("DefaultStillLength")->add_child_text (lexical_cast (_default_still_length)); + doc.write_to_file_formatted (file (false)); } diff --git a/src/lib/config.h b/src/lib/config.h index 57f4fb8a9..91926750b 100644 --- a/src/lib/config.h +++ b/src/lib/config.h @@ -107,6 +107,10 @@ public: return _language; } + int default_still_length () const { + return _default_still_length; + } + /** @param n New number of local encoding threads */ void set_num_local_encoding_threads (int n) { _num_local_encoding_threads = n; @@ -169,7 +173,11 @@ public: void unset_language () { _language = boost::none; } - + + void set_default_still_length (int s) { + _default_still_length = s; + } + void write () const; static Config* instance (); @@ -207,6 +215,7 @@ private: /** Default DCI metadata for newly-created Films */ DCIMetadata _default_dci_metadata; boost::optional _language; + int _default_still_length; /** Singleton instance, or 0 */ static Config* _instance; diff --git a/src/lib/imagemagick_content.cc b/src/lib/imagemagick_content.cc index 24f6d338d..9e5f00ba0 100644 --- a/src/lib/imagemagick_content.cc +++ b/src/lib/imagemagick_content.cc @@ -20,6 +20,7 @@ #include #include "imagemagick_content.h" #include "imagemagick_decoder.h" +#include "config.h" #include "compose.hpp" #include "i18n.h" @@ -73,7 +74,7 @@ ImageMagickContent::examine (shared_ptr film, shared_ptr job, bool qu { boost::mutex::scoped_lock lm (_mutex); /* Initial length */ - _video_length = 10 * 24; + _video_length = Config::instance()->default_still_length() * 24; } take_from_video_decoder (decoder); diff --git a/src/wx/config_dialog.cc b/src/wx/config_dialog.cc index c3eebc015..e1fc7a20f 100644 --- a/src/wx/config_dialog.cc +++ b/src/wx/config_dialog.cc @@ -25,6 +25,7 @@ #include #include #include +#include #include "lib/config.h" #include "lib/server.h" #include "lib/format.h" @@ -43,12 +44,46 @@ using boost::bind; ConfigDialog::ConfigDialog (wxWindow* parent) : wxDialog (parent, wxID_ANY, _("DCP-o-matic Preferences"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) { + wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); + _notebook = new wxNotebook (this, wxID_ANY); + s->Add (_notebook, 1); + + make_misc_panel (); + _notebook->AddPage (_misc_panel, _("Miscellaneous"), true); + make_servers_panel (); + _notebook->AddPage (_servers_panel, _("Encoding servers"), false); + make_tms_panel (); + _notebook->AddPage (_tms_panel, _("TMS"), false); + make_ab_panel (); + _notebook->AddPage (_ab_panel, _("A/B mode"), false); + + wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL); + overall_sizer->Add (s, 1, wxEXPAND | wxALL, 6); + + wxSizer* buttons = CreateSeparatedButtonSizer (wxOK); + if (buttons) { + overall_sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder()); + } + + SetSizer (overall_sizer); + overall_sizer->Layout (); + overall_sizer->SetSizeHints (this); +} + +void +ConfigDialog::make_misc_panel () +{ + _misc_panel = new wxPanel (_notebook); + wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); + _misc_panel->SetSizer (s); + wxFlexGridSizer* table = new wxFlexGridSizer (3, 6, 6); table->AddGrowableCol (1, 1); + s->Add (table, 1, wxALL | wxEXPAND, 8); - _set_language = new wxCheckBox (this, wxID_ANY, _("Set language")); + _set_language = new wxCheckBox (_misc_panel, wxID_ANY, _("Set language")); table->Add (_set_language, 1, wxEXPAND); - _language = new wxChoice (this, wxID_ANY); + _language = new wxChoice (_misc_panel, wxID_ANY); _language->Append (wxT ("English")); _language->Append (wxT ("Français")); _language->Append (wxT ("Italiano")); @@ -57,98 +92,38 @@ ConfigDialog::ConfigDialog (wxWindow* parent) table->Add (_language, 1, wxEXPAND); table->AddSpacer (0); - table->AddSpacer (0); - wxStaticText* restart = add_label_to_sizer (table, this, _("(restart DCP-o-matic to see language changes)")); + wxStaticText* restart = add_label_to_sizer (table, _misc_panel, _("(restart DCP-o-matic to see language changes)")); wxFont font = restart->GetFont(); font.SetStyle (wxFONTSTYLE_ITALIC); font.SetPointSize (font.GetPointSize() - 1); restart->SetFont (font); table->AddSpacer (0); - - add_label_to_sizer (table, this, _("TMS IP address")); - _tms_ip = new wxTextCtrl (this, wxID_ANY); - table->Add (_tms_ip, 1, wxEXPAND); - table->AddSpacer (0); - - add_label_to_sizer (table, this, _("TMS target path")); - _tms_path = new wxTextCtrl (this, wxID_ANY); - table->Add (_tms_path, 1, wxEXPAND); - table->AddSpacer (0); - - add_label_to_sizer (table, this, _("TMS user name")); - _tms_user = new wxTextCtrl (this, wxID_ANY); - table->Add (_tms_user, 1, wxEXPAND); table->AddSpacer (0); - add_label_to_sizer (table, this, _("TMS password")); - _tms_password = new wxTextCtrl (this, wxID_ANY); - table->Add (_tms_password, 1, wxEXPAND); - table->AddSpacer (0); - - add_label_to_sizer (table, this, _("Threads to use for encoding on this host")); - _num_local_encoding_threads = new wxSpinCtrl (this); + add_label_to_sizer (table, _misc_panel, _("Threads to use for encoding on this host")); + _num_local_encoding_threads = new wxSpinCtrl (_misc_panel); table->Add (_num_local_encoding_threads, 1, wxEXPAND); table->AddSpacer (0); - add_label_to_sizer (table, this, _("Default directory for new films")); + add_label_to_sizer (table, _misc_panel, _("Default duration of still images")); + _default_still_length = new wxSpinCtrl (_misc_panel); + table->Add (_default_still_length, 1, wxEXPAND); + add_label_to_sizer (table, _misc_panel, _("s")); + + add_label_to_sizer (table, _misc_panel, _("Default directory for new films")); #ifdef __WXMSW__ - _default_directory = new DirPickerCtrl (this); + _default_directory = new DirPickerCtrl (_misc_panel); #else - _default_directory = new wxDirPickerCtrl (this, wxDD_DIR_MUST_EXIST); + _default_directory = new wxDirPickerCtrl (_misc_panel, wxDD_DIR_MUST_EXIST); #endif table->Add (_default_directory, 1, wxEXPAND); table->AddSpacer (0); - add_label_to_sizer (table, this, _("Default DCI name details")); - _default_dci_metadata_button = new wxButton (this, wxID_ANY, _("Edit...")); + add_label_to_sizer (table, _misc_panel, _("Default DCI name details")); + _default_dci_metadata_button = new wxButton (_misc_panel, wxID_ANY, _("Edit...")); table->Add (_default_dci_metadata_button); table->AddSpacer (1); - add_label_to_sizer (table, this, _("Reference scaler for A/B")); - _reference_scaler = new wxChoice (this, wxID_ANY); - vector const sc = Scaler::all (); - for (vector::const_iterator i = sc.begin(); i != sc.end(); ++i) { - _reference_scaler->Append (std_to_wx ((*i)->name ())); - } - - table->Add (_reference_scaler, 1, wxEXPAND); - table->AddSpacer (0); - - { - add_label_to_sizer (table, this, _("Reference filters for A/B")); - wxSizer* s = new wxBoxSizer (wxHORIZONTAL); - _reference_filters = new wxStaticText (this, wxID_ANY, wxT ("")); - s->Add (_reference_filters, 1, wxEXPAND); - _reference_filters_button = new wxButton (this, wxID_ANY, _("Edit...")); - s->Add (_reference_filters_button, 0); - table->Add (s, 1, wxEXPAND); - table->AddSpacer (0); - } - - add_label_to_sizer (table, this, _("Encoding Servers")); - _servers = new wxListCtrl (this, wxID_ANY, wxDefaultPosition, wxSize (220, 100), wxLC_REPORT | wxLC_SINGLE_SEL); - wxListItem ip; - ip.SetId (0); - ip.SetText (_("IP address")); - ip.SetWidth (120); - _servers->InsertColumn (0, ip); - ip.SetId (1); - ip.SetText (_("Threads")); - ip.SetWidth (80); - _servers->InsertColumn (1, ip); - table->Add (_servers, 1, wxEXPAND | wxALL); - - { - wxSizer* s = new wxBoxSizer (wxVERTICAL); - _add_server = new wxButton (this, wxID_ANY, _("Add")); - s->Add (_add_server); - _edit_server = new wxButton (this, wxID_ANY, _("Edit")); - s->Add (_edit_server); - _remove_server = new wxButton (this, wxID_ANY, _("Remove")); - s->Add (_remove_server); - table->Add (s, 0); - } - Config* config = Config::instance (); _set_language->SetValue (config->language ()); @@ -169,6 +144,51 @@ ConfigDialog::ConfigDialog (wxWindow* parent) _set_language->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (ConfigDialog::set_language_changed), 0, this); _language->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (ConfigDialog::language_changed), 0, this); + + _num_local_encoding_threads->SetRange (1, 128); + _num_local_encoding_threads->SetValue (config->num_local_encoding_threads ()); + _num_local_encoding_threads->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (ConfigDialog::num_local_encoding_threads_changed), 0, this); + + _default_still_length->SetRange (1, 3600); + _default_still_length->SetValue (config->default_still_length ()); + _default_still_length->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (ConfigDialog::default_still_length_changed), 0, this); + + _default_directory->SetPath (std_to_wx (config->default_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())))); + _default_directory->Connect (wxID_ANY, wxEVT_COMMAND_DIRPICKER_CHANGED, wxCommandEventHandler (ConfigDialog::default_directory_changed), 0, this); + + _default_dci_metadata_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (ConfigDialog::edit_default_dci_metadata_clicked), 0, this); + +} + +void +ConfigDialog::make_tms_panel () +{ + _tms_panel = new wxPanel (_notebook); + wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); + _tms_panel->SetSizer (s); + + wxFlexGridSizer* table = new wxFlexGridSizer (2, 6, 6); + table->AddGrowableCol (1, 1); + s->Add (table, 1, wxALL | wxEXPAND, 8); + + add_label_to_sizer (table, _tms_panel, _("IP address")); + _tms_ip = new wxTextCtrl (_tms_panel, wxID_ANY); + table->Add (_tms_ip, 1, wxEXPAND); + + add_label_to_sizer (table, _tms_panel, _("Target path")); + _tms_path = new wxTextCtrl (_tms_panel, wxID_ANY); + table->Add (_tms_path, 1, wxEXPAND); + + add_label_to_sizer (table, _tms_panel, _("User name")); + _tms_user = new wxTextCtrl (_tms_panel, wxID_ANY); + table->Add (_tms_user, 1, wxEXPAND); + + add_label_to_sizer (table, _tms_panel, _("Password")); + _tms_password = new wxTextCtrl (_tms_panel, wxID_ANY); + table->Add (_tms_password, 1, wxEXPAND); + + Config* config = Config::instance (); + _tms_ip->SetValue (std_to_wx (config->tms_ip ())); _tms_ip->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (ConfigDialog::tms_ip_changed), 0, this); _tms_path->SetValue (std_to_wx (config->tms_path ())); @@ -177,22 +197,85 @@ ConfigDialog::ConfigDialog (wxWindow* parent) _tms_user->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (ConfigDialog::tms_user_changed), 0, this); _tms_password->SetValue (std_to_wx (config->tms_password ())); _tms_password->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (ConfigDialog::tms_password_changed), 0, this); +} - _num_local_encoding_threads->SetRange (1, 128); - _num_local_encoding_threads->SetValue (config->num_local_encoding_threads ()); - _num_local_encoding_threads->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (ConfigDialog::num_local_encoding_threads_changed), 0, this); +void +ConfigDialog::make_ab_panel () +{ + _ab_panel = new wxPanel (_notebook); + wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); + _ab_panel->SetSizer (s); - _default_directory->SetPath (std_to_wx (config->default_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())))); - _default_directory->Connect (wxID_ANY, wxEVT_COMMAND_DIRPICKER_CHANGED, wxCommandEventHandler (ConfigDialog::default_directory_changed), 0, this); + wxFlexGridSizer* table = new wxFlexGridSizer (3, 6, 6); + table->AddGrowableCol (1, 1); + s->Add (table, 1, wxALL, 8); + + add_label_to_sizer (table, _ab_panel, _("Reference scaler")); + _reference_scaler = new wxChoice (_ab_panel, wxID_ANY); + vector const sc = Scaler::all (); + for (vector::const_iterator i = sc.begin(); i != sc.end(); ++i) { + _reference_scaler->Append (std_to_wx ((*i)->name ())); + } - _default_dci_metadata_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (ConfigDialog::edit_default_dci_metadata_clicked), 0, this); + table->Add (_reference_scaler, 1, wxEXPAND); + table->AddSpacer (0); + + { + add_label_to_sizer (table, _ab_panel, _("Reference filters")); + wxSizer* s = new wxBoxSizer (wxHORIZONTAL); + _reference_filters = new wxStaticText (_ab_panel, wxID_ANY, wxT ("")); + s->Add (_reference_filters, 1, wxEXPAND); + _reference_filters_button = new wxButton (_ab_panel, wxID_ANY, _("Edit...")); + s->Add (_reference_filters_button, 0); + table->Add (s, 1, wxEXPAND); + table->AddSpacer (0); + } + Config* config = Config::instance (); + _reference_scaler->SetSelection (Scaler::as_index (config->reference_scaler ())); _reference_scaler->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (ConfigDialog::reference_scaler_changed), 0, this); pair p = Filter::ffmpeg_strings (config->reference_filters ()); _reference_filters->SetLabel (std_to_wx (p.first) + N_(" ") + std_to_wx (p.second)); _reference_filters_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (ConfigDialog::edit_reference_filters_clicked), 0, this); +} + +void +ConfigDialog::make_servers_panel () +{ + _servers_panel = new wxPanel (_notebook); + wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); + _servers_panel->SetSizer (s); + + wxFlexGridSizer* table = new wxFlexGridSizer (2, 6, 6); + table->AddGrowableCol (0, 1); + s->Add (table, 1, wxALL | wxEXPAND, 8); + + Config* config = Config::instance (); + + _servers = new wxListCtrl (_servers_panel, wxID_ANY, wxDefaultPosition, wxSize (220, 100), wxLC_REPORT | wxLC_SINGLE_SEL); + wxListItem ip; + ip.SetId (0); + ip.SetText (_("IP address")); + ip.SetWidth (120); + _servers->InsertColumn (0, ip); + ip.SetId (1); + ip.SetText (_("Threads")); + ip.SetWidth (80); + _servers->InsertColumn (1, ip); + table->Add (_servers, 1, wxEXPAND | wxALL); + + { + wxSizer* s = new wxBoxSizer (wxVERTICAL); + _add_server = new wxButton (_servers_panel, wxID_ANY, _("Add")); + s->Add (_add_server); + _edit_server = new wxButton (_servers_panel, wxID_ANY, _("Edit")); + s->Add (_edit_server); + _remove_server = new wxButton (_servers_panel, wxID_ANY, _("Remove")); + s->Add (_remove_server); + table->Add (s, 0); + } vector servers = config->servers (); for (vector::iterator i = servers.begin(); i != servers.end(); ++i) { @@ -207,18 +290,6 @@ ConfigDialog::ConfigDialog (wxWindow* parent) _servers->Connect (wxID_ANY, wxEVT_COMMAND_LIST_ITEM_DESELECTED, wxListEventHandler (ConfigDialog::server_selection_changed), 0, this); wxListEvent ev; server_selection_changed (ev); - - wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL); - overall_sizer->Add (table, 1, wxEXPAND | wxALL, 6); - - wxSizer* buttons = CreateSeparatedButtonSizer (wxOK); - if (buttons) { - overall_sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder()); - } - - SetSizer (overall_sizer); - overall_sizer->Layout (); - overall_sizer->SetSizeHints (this); } void @@ -400,3 +471,9 @@ ConfigDialog::setup_language_sensitivity () { _language->Enable (_set_language->GetValue ()); } + +void +ConfigDialog::default_still_length_changed (wxCommandEvent &) +{ + Config::instance()->set_default_still_length (_default_still_length->GetValue ()); +} diff --git a/src/wx/config_dialog.h b/src/wx/config_dialog.h index a2fc1f4b1..852925e1d 100644 --- a/src/wx/config_dialog.h +++ b/src/wx/config_dialog.h @@ -27,6 +27,7 @@ #include class DirPickerCtrl; +class wxNotebook; class ServerDescription; @@ -46,6 +47,7 @@ private: void tms_user_changed (wxCommandEvent &); void tms_password_changed (wxCommandEvent &); void num_local_encoding_threads_changed (wxCommandEvent &); + void default_still_length_changed (wxCommandEvent &); void default_directory_changed (wxCommandEvent &); void edit_default_dci_metadata_clicked (wxCommandEvent &); void reference_scaler_changed (wxCommandEvent &); @@ -59,6 +61,16 @@ private: void add_server_to_control (ServerDescription *); void setup_language_sensitivity (); + void make_misc_panel (); + void make_tms_panel (); + void make_ab_panel (); + void make_servers_panel (); + + wxNotebook* _notebook; + wxPanel* _misc_panel; + wxPanel* _tms_panel; + wxPanel* _ab_panel; + wxPanel* _servers_panel; wxCheckBox* _set_language; wxChoice* _language; wxTextCtrl* _tms_ip; @@ -66,6 +78,7 @@ private: wxTextCtrl* _tms_user; wxTextCtrl* _tms_password; wxSpinCtrl* _num_local_encoding_threads; + wxSpinCtrl* _default_still_length; #ifdef __WXMSW__ DirPickerCtrl* _default_directory; #else -- cgit v1.2.3 From d487ee606113a2b4bbab1810758e9777792f1cac Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 28 Apr 2013 01:20:55 +0100 Subject: Add total-playlist loop option; move state of content list into the Playlist. --- src/lib/audio_mapping.cc | 2 +- src/lib/film.cc | 159 ++++++++++++++--------------------------------- src/lib/film.h | 18 +++--- src/lib/player.cc | 114 ++++++++++++++++----------------- src/lib/playlist.cc | 132 +++++++++++++++++++++++++++++++++++++-- src/lib/playlist.h | 26 +++++++- src/wx/film_editor.cc | 42 +++++++++++++ src/wx/film_editor.h | 5 ++ 8 files changed, 315 insertions(+), 183 deletions(-) (limited to 'src') diff --git a/src/lib/audio_mapping.cc b/src/lib/audio_mapping.cc index 83c748f1a..7e28aa5c4 100644 --- a/src/lib/audio_mapping.cc +++ b/src/lib/audio_mapping.cc @@ -115,7 +115,7 @@ AudioMapping::set_from_xml (ContentList const & content, shared_ptr ac = dynamic_pointer_cast (*j); + shared_ptr ac = dynamic_pointer_cast (*j); assert (ac); add (AudioMapping::Channel (ac, (*i)->number_child ("ContentIndex")), static_cast ((*i)->number_child ("DCP"))); diff --git a/src/lib/film.cc b/src/lib/film.cc index 98c6c0610..5481bd012 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -113,7 +113,8 @@ Film::Film (string d, bool must_exist) { set_dci_date_today (); - _playlist->ContentChanged.connect (bind (&Film::content_changed, this, _1, _2)); + _playlist->Changed.connect (bind (&Film::playlist_changed, this)); + _playlist->ContentChanged.connect (bind (&Film::playlist_content_changed, this, _1, _2)); /* Make state.directory a complete path without ..s (where possible) (Code swiped from Adam Bowen on stackoverflow) @@ -156,7 +157,7 @@ Film::Film (Film const & o) : boost::enable_shared_from_this (o) /* note: the copied film shares the original's log */ , _log (o._log) - , _playlist (new Playlist) + , _playlist (new Playlist (o._playlist)) , _directory (o._directory) , _name (o._name) , _use_dci_name (o._use_dci_name) @@ -182,13 +183,7 @@ Film::Film (Film const & o) , _dci_date (o._dci_date) , _dirty (o._dirty) { - for (ContentList::const_iterator i = o._content.begin(); i != o._content.end(); ++i) { - _content.push_back ((*i)->clone ()); - } - - _playlist->ContentChanged.connect (bind (&Film::content_changed, this, _1, _2)); - - _playlist->setup (_content); + _playlist->ContentChanged.connect (bind (&Film::playlist_content_changed, this, _1, _2)); } string @@ -320,7 +315,7 @@ Film::make_dcp () throw MissingSettingError (_("format")); } - if (content().empty ()) { + if (_playlist->content().empty ()) { throw MissingSettingError (_("content")); } @@ -405,8 +400,6 @@ Film::encoded_frames () const void Film::write_metadata () const { - ContentList the_content = content (); - boost::mutex::scoped_lock lm (_state_mutex); LocaleGuard lg; @@ -460,10 +453,7 @@ Film::write_metadata () const root->add_child("DCPFrameRate")->add_child_text (boost::lexical_cast (_dcp_frame_rate)); root->add_child("DCIDate")->add_child_text (boost::gregorian::to_iso_string (_dci_date)); _audio_mapping.as_xml (root->add_child("AudioMapping")); - - for (ContentList::iterator i = the_content.begin(); i != the_content.end(); ++i) { - (*i)->as_xml (root->add_child ("Content")); - } + _playlist->as_xml (root->add_child ("Playlist")); doc.write_to_file_formatted (file ("metadata.xml")); @@ -537,29 +527,10 @@ Film::read_metadata () _dcp_frame_rate = f.number_child ("DCPFrameRate"); _dci_date = boost::gregorian::from_undelimited_string (f.string_child ("DCIDate")); - list > c = f.node_children ("Content"); - for (list >::iterator i = c.begin(); i != c.end(); ++i) { - - string const type = (*i)->string_child ("Type"); - boost::shared_ptr c; - - if (type == "FFmpeg") { - c.reset (new FFmpegContent (*i)); - } else if (type == "ImageMagick") { - c.reset (new ImageMagickContent (*i)); - } else if (type == "Sndfile") { - c.reset (new SndfileContent (*i)); - } - - _content.push_back (c); - } - - /* This must come after we've loaded the content, as we're looking things up in _content */ - _audio_mapping.set_from_xml (_content, f.node_child ("AudioMapping")); + _playlist->set_from_xml (f.node_child ("Playlist")); + _audio_mapping.set_from_xml (_playlist->content(), f.node_child ("AudioMapping")); _dirty = false; - - _playlist->setup (_content); } libdcp::Size @@ -766,10 +737,11 @@ Film::set_trust_content_headers (bool t) signal_changed (TRUST_CONTENT_HEADERS); - if (!_trust_content_headers && !content().empty()) { + + ContentList content = _playlist->content (); + if (!_trust_content_headers && !content.empty()) { /* We just said that we don't trust the content's header */ - ContentList c = content (); - for (ContentList::iterator i = c.begin(); i != c.end(); ++i) { + for (ContentList::iterator i = content.begin(); i != content.end(); ++i) { examine_content (*i); } } @@ -1023,7 +995,6 @@ Film::signal_changed (Property p) switch (p) { case Film::CONTENT: - _playlist->setup (content ()); set_dcp_frame_rate (best_dcp_frame_rate (video_frame_rate ())); set_audio_mapping (_playlist->default_audio_mapping ()); break; @@ -1104,73 +1075,35 @@ Film::player () const return shared_ptr (new Player (shared_from_this (), _playlist)); } +ContentList +Film::content () const +{ + return _playlist->content (); +} + void Film::add_content (shared_ptr c) { - { - boost::mutex::scoped_lock lm (_state_mutex); - _content.push_back (c); - } - - signal_changed (CONTENT); - + _playlist->add (c); examine_content (c); } void Film::remove_content (shared_ptr c) { - { - boost::mutex::scoped_lock lm (_state_mutex); - ContentList::iterator i = find (_content.begin(), _content.end(), c); - if (i != _content.end ()) { - _content.erase (i); - } - } - - signal_changed (CONTENT); + _playlist->remove (c); } void Film::move_content_earlier (shared_ptr c) { - { - boost::mutex::scoped_lock lm (_state_mutex); - ContentList::iterator i = find (_content.begin(), _content.end(), c); - if (i == _content.begin () || i == _content.end()) { - return; - } - - ContentList::iterator j = i; - --j; - - swap (*i, *j); - } - - signal_changed (CONTENT); + _playlist->move_earlier (c); } void Film::move_content_later (shared_ptr c) { - { - boost::mutex::scoped_lock lm (_state_mutex); - ContentList::iterator i = find (_content.begin(), _content.end(), c); - if (i == _content.end()) { - return; - } - - ContentList::iterator j = i; - ++j; - if (j == _content.end ()) { - return; - } - - swap (*i, *j); - } - - signal_changed (CONTENT); - + _playlist->move_later (c); } ContentAudioFrame @@ -1221,26 +1154,10 @@ Film::content_length () const return _playlist->content_length (); } -/** Unfortunately this is needed as the GUI has FFmpeg-specific controls */ -shared_ptr -Film::ffmpeg () const -{ - boost::mutex::scoped_lock lm (_state_mutex); - - for (ContentList::const_iterator i = _content.begin (); i != _content.end(); ++i) { - shared_ptr f = boost::dynamic_pointer_cast (*i); - if (f) { - return f; - } - } - - return shared_ptr (); -} - vector Film::ffmpeg_subtitle_streams () const { - shared_ptr f = ffmpeg (); + shared_ptr f = _playlist->ffmpeg (); if (f) { return f->subtitle_streams (); } @@ -1251,7 +1168,7 @@ Film::ffmpeg_subtitle_streams () const boost::optional Film::ffmpeg_subtitle_stream () const { - shared_ptr f = ffmpeg (); + shared_ptr f = _playlist->ffmpeg (); if (f) { return f->subtitle_stream (); } @@ -1262,7 +1179,7 @@ Film::ffmpeg_subtitle_stream () const vector Film::ffmpeg_audio_streams () const { - shared_ptr f = ffmpeg (); + shared_ptr f = _playlist->ffmpeg (); if (f) { return f->audio_streams (); } @@ -1273,7 +1190,7 @@ Film::ffmpeg_audio_streams () const boost::optional Film::ffmpeg_audio_stream () const { - shared_ptr f = ffmpeg (); + shared_ptr f = _playlist->ffmpeg (); if (f) { return f->audio_stream (); } @@ -1284,7 +1201,7 @@ Film::ffmpeg_audio_stream () const void Film::set_ffmpeg_subtitle_stream (FFmpegSubtitleStream s) { - shared_ptr f = ffmpeg (); + shared_ptr f = _playlist->ffmpeg (); if (f) { f->set_subtitle_stream (s); } @@ -1293,7 +1210,7 @@ Film::set_ffmpeg_subtitle_stream (FFmpegSubtitleStream s) void Film::set_ffmpeg_audio_stream (FFmpegAudioStream s) { - shared_ptr f = ffmpeg (); + shared_ptr f = _playlist->ffmpeg (); if (f) { f->set_audio_stream (s); } @@ -1311,7 +1228,7 @@ Film::set_audio_mapping (AudioMapping m) } void -Film::content_changed (boost::weak_ptr c, int p) +Film::playlist_content_changed (boost::weak_ptr c, int p) { if (p == VideoContentProperty::VIDEO_FRAME_RATE) { set_dcp_frame_rate (best_dcp_frame_rate (video_frame_rate ())); @@ -1323,3 +1240,21 @@ Film::content_changed (boost::weak_ptr c, int p) ui_signaller->emit (boost::bind (boost::ref (ContentChanged), c, p)); } } + +void +Film::playlist_changed () +{ + signal_changed (CONTENT); +} + +int +Film::loop () const +{ + return _playlist->loop (); +} + +void +Film::set_loop (int c) +{ + _playlist->set_loop (c); +} diff --git a/src/lib/film.h b/src/lib/film.h index 43b5d1a17..f4d7cde67 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -106,6 +106,8 @@ public: /* Proxies for some Playlist methods */ + ContentList content () const; + ContentAudioFrame audio_length () const; int audio_channels () const; int audio_frame_rate () const; @@ -125,6 +127,9 @@ public: void set_ffmpeg_subtitle_stream (FFmpegSubtitleStream); void set_ffmpeg_audio_stream (FFmpegAudioStream); + void set_loop (int); + int loop () const; + enum TrimType { CPL, ENCODE @@ -138,8 +143,9 @@ public: NAME, USE_DCI_NAME, TRUST_CONTENT_HEADERS, - /** The content list has changed (i.e. content has been added, moved around or removed) */ + /** The playlist's content list has changed (i.e. content has been added, moved around or removed) */ CONTENT, + LOOP, DCP_CONTENT_TYPE, FORMAT, CROP, @@ -184,11 +190,6 @@ public: return _trust_content_headers; } - ContentList content () const { - boost::mutex::scoped_lock lm (_state_mutex); - return _content; - } - DCPContentType const * dcp_content_type () const { boost::mutex::scoped_lock lm (_state_mutex); return _dcp_content_type; @@ -336,8 +337,8 @@ private: void analyse_audio_finished (); std::string video_state_identifier () const; void read_metadata (); - void content_changed (boost::weak_ptr, int); - boost::shared_ptr ffmpeg () const; + void playlist_changed (); + void playlist_content_changed (boost::weak_ptr, int); void setup_default_audio_mapping (); std::string filename_safe_name () const; @@ -359,7 +360,6 @@ private: /** True if a auto-generated DCI-compliant name should be used for our DCP */ bool _use_dci_name; bool _trust_content_headers; - ContentList _content; /** The type of content that this Film represents (feature, trailer etc.) */ DCPContentType const * _dcp_content_type; /** The format to present this Film in (flat, scope, etc.) */ diff --git a/src/lib/player.cc b/src/lib/player.cc index b21224587..d62d8f8b6 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -229,67 +229,69 @@ Player::setup_decoders () double video_so_far = 0; double audio_so_far = 0; - - list > vc = _playlist->video (); - for (list >::iterator i = vc.begin(); i != vc.end(); ++i) { - - shared_ptr video_content; - shared_ptr audio_content; - shared_ptr video_decoder; - shared_ptr audio_decoder; - - /* XXX: into content? */ - - shared_ptr fc = dynamic_pointer_cast (*i); - if (fc) { - shared_ptr fd ( - new FFmpegDecoder ( - _film, fc, _video, - _audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG, - _subtitles - ) - ); + + for (int l = 0; l < _playlist->loop(); ++l) { + list > vc = _playlist->video (); + for (list >::iterator i = vc.begin(); i != vc.end(); ++i) { - video_content = fc; - audio_content = fc; - video_decoder = fd; - audio_decoder = fd; - } - - shared_ptr ic = dynamic_pointer_cast (*i); - if (ic) { - video_content = ic; - video_decoder.reset (new ImageMagickDecoder (_film, ic)); + shared_ptr video_content; + shared_ptr audio_content; + shared_ptr video_decoder; + shared_ptr audio_decoder; + + /* XXX: into content? */ + + shared_ptr fc = dynamic_pointer_cast (*i); + if (fc) { + shared_ptr fd ( + new FFmpegDecoder ( + _film, fc, _video, + _audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG, + _subtitles + ) + ); + + video_content = fc; + audio_content = fc; + video_decoder = fd; + audio_decoder = fd; + } + + shared_ptr ic = dynamic_pointer_cast (*i); + if (ic) { + video_content = ic; + video_decoder.reset (new ImageMagickDecoder (_film, ic)); + } + + video_decoder->connect_video (shared_from_this ()); + _video_decoders.push_back (video_decoder); + _video_start.push_back (video_so_far); + video_so_far += video_content->video_length() / video_content->video_frame_rate(); + + if (audio_decoder && _playlist->audio_from() == Playlist::AUDIO_FFMPEG) { + audio_decoder->Audio.connect (bind (&Player::process_audio, this, audio_content, _1, _2)); + _audio_decoders.push_back (audio_decoder); + _audio_start.push_back (audio_so_far); + audio_so_far += double(audio_content->audio_length()) / audio_content->audio_frame_rate(); + } } - video_decoder->connect_video (shared_from_this ()); - _video_decoders.push_back (video_decoder); - _video_start.push_back (video_so_far); - video_so_far += video_content->video_length() / video_content->video_frame_rate(); - - if (audio_decoder && _playlist->audio_from() == Playlist::AUDIO_FFMPEG) { - audio_decoder->Audio.connect (bind (&Player::process_audio, this, audio_content, _1, _2)); - _audio_decoders.push_back (audio_decoder); - _audio_start.push_back (audio_so_far); - audio_so_far += double(audio_content->audio_length()) / audio_content->audio_frame_rate(); - } - } - - _video_decoder = 0; - _sequential_audio_decoder = 0; - - if (_playlist->audio_from() == Playlist::AUDIO_SNDFILE) { + _video_decoder = 0; + _sequential_audio_decoder = 0; - list > ac = _playlist->audio (); - for (list >::iterator i = ac.begin(); i != ac.end(); ++i) { + if (_playlist->audio_from() == Playlist::AUDIO_SNDFILE) { - shared_ptr sc = dynamic_pointer_cast (*i); - assert (sc); - - shared_ptr d (new SndfileDecoder (_film, sc)); - d->Audio.connect (bind (&Player::process_audio, this, sc, _1, _2)); - _audio_decoders.push_back (d); - _audio_start.push_back (audio_so_far); + list > ac = _playlist->audio (); + for (list >::iterator i = ac.begin(); i != ac.end(); ++i) { + + shared_ptr sc = dynamic_pointer_cast (*i); + assert (sc); + + shared_ptr d (new SndfileDecoder (_film, sc)); + d->Audio.connect (bind (&Player::process_audio, this, sc, _1, _2)); + _audio_decoders.push_back (d); + _audio_start.push_back (audio_so_far); + } } } } diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index 3c69ae15f..216244bd0 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -17,6 +17,7 @@ */ +#include #include #include #include "playlist.h" @@ -26,6 +27,7 @@ #include "ffmpeg_decoder.h" #include "ffmpeg_content.h" #include "imagemagick_decoder.h" +#include "imagemagick_content.h" #include "job.h" using std::list; @@ -41,12 +43,24 @@ using boost::lexical_cast; Playlist::Playlist () : _audio_from (AUDIO_FFMPEG) + , _loop (1) { } +Playlist::Playlist (shared_ptr other) + : _audio_from (other->_audio_from) + , _loop (other->_loop) +{ + for (ContentList::const_iterator i = other->_content.begin(); i != other->_content.end(); ++i) { + _content.push_back ((*i)->clone ()); + } + + setup (); +} + void -Playlist::setup (ContentList content) +Playlist::setup () { _audio_from = AUDIO_FFMPEG; @@ -59,7 +73,7 @@ Playlist::setup (ContentList content) _content_connections.clear (); - for (ContentList::const_iterator i = content.begin(); i != content.end(); ++i) { + for (ContentList::const_iterator i = _content.begin(); i != _content.end(); ++i) { /* Video is video */ shared_ptr vc = dynamic_pointer_cast (*i); @@ -114,7 +128,7 @@ Playlist::audio_length () const break; } - return len; + return len * _loop; } /** @return number of audio channels */ @@ -182,7 +196,7 @@ Playlist::video_length () const len += (*i)->video_length (); } - return len; + return len * _loop; } bool @@ -258,6 +272,8 @@ Playlist::audio_digest () const } } + t += lexical_cast (_loop); + return md5_digest (t.c_str(), t.length()); } @@ -274,6 +290,8 @@ Playlist::video_digest () const } } + t += lexical_cast (_loop); + return md5_digest (t.c_str(), t.length()); } @@ -288,3 +306,109 @@ Playlist::content_length () const ContentVideoFrame (audio_length() * vfr / afr) ); } + +void +Playlist::set_from_xml (shared_ptr node) +{ + list > c = node->node_children ("Content"); + for (list >::iterator i = c.begin(); i != c.end(); ++i) { + + string const type = (*i)->string_child ("Type"); + boost::shared_ptr c; + + if (type == "FFmpeg") { + c.reset (new FFmpegContent (*i)); + } else if (type == "ImageMagick") { + c.reset (new ImageMagickContent (*i)); + } else if (type == "Sndfile") { + c.reset (new SndfileContent (*i)); + } + + _content.push_back (c); + } + + _loop = node->number_child ("Loop"); +} + +void +Playlist::as_xml (xmlpp::Node* node) +{ + for (ContentList::iterator i = _content.begin(); i != _content.end(); ++i) { + (*i)->as_xml (node->add_child ("Content")); + } + + node->add_child("Loop")->add_child_text(lexical_cast (_loop)); +} + +void +Playlist::add (shared_ptr c) +{ + _content.push_back (c); + setup (); +} + +void +Playlist::remove (shared_ptr c) +{ + ContentList::iterator i = find (_content.begin(), _content.end(), c); + if (i != _content.end ()) { + _content.erase (i); + } + + setup (); +} + +void +Playlist::move_earlier (shared_ptr c) +{ + ContentList::iterator i = find (_content.begin(), _content.end(), c); + if (i == _content.begin () || i == _content.end()) { + return; + } + + ContentList::iterator j = i; + --j; + + swap (*i, *j); + + setup (); +} + +void +Playlist::move_later (shared_ptr c) +{ + ContentList::iterator i = find (_content.begin(), _content.end(), c); + if (i == _content.end()) { + return; + } + + ContentList::iterator j = i; + ++j; + if (j == _content.end ()) { + return; + } + + swap (*i, *j); + + setup (); +} + +void +Playlist::set_loop (int l) +{ + _loop = l; + Changed (); +} + +shared_ptr +Playlist::ffmpeg () const +{ + for (ContentList::const_iterator i = _content.begin(); i != _content.end(); ++i) { + shared_ptr fc = dynamic_pointer_cast (*i); + if (fc) { + return fc; + } + } + + return shared_ptr (); +} diff --git a/src/lib/playlist.h b/src/lib/playlist.h index 85bde64ff..935bbb2bd 100644 --- a/src/lib/playlist.h +++ b/src/lib/playlist.h @@ -51,8 +51,15 @@ class Playlist { public: Playlist (); + Playlist (boost::shared_ptr); - void setup (ContentList); + void as_xml (xmlpp::Node *); + void set_from_xml (boost::shared_ptr); + + void add (boost::shared_ptr); + void remove (boost::shared_ptr); + void move_earlier (boost::shared_ptr); + void move_later (boost::shared_ptr); ContentAudioFrame audio_length () const; int audio_channels () const; @@ -75,6 +82,12 @@ public: return _audio_from; } + ContentList content () const { + return _content; + } + + boost::shared_ptr ffmpeg () const; + std::list > video () const { return _video; } @@ -86,15 +99,24 @@ public: std::string audio_digest () const; std::string video_digest () const; + int loop () const { + return _loop; + } + + void set_loop (int l); + mutable boost::signals2::signal Changed; mutable boost::signals2::signal, int)> ContentChanged; private: + void setup (); void content_changed (boost::weak_ptr, int); /** where we should get our audio from */ AudioFrom _audio_from; + /** all our content */ + ContentList _content; /** all our content which contains video */ std::list > _video; /** all our content which contains audio. This may contain the same objects @@ -102,5 +124,7 @@ private: */ std::list > _audio; + int _loop; + std::list _content_connections; }; diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index b6be39e9b..4f08953b9 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -214,6 +214,8 @@ FilmEditor::connect_to_widgets () _content_edit->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_edit_clicked), 0, this); _content_earlier->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_earlier_clicked), 0, this); _content_later->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_later_clicked), 0, this); + _loop_content->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::loop_content_toggled), 0, this); + _loop_count->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::loop_count_changed), 0, this); _left_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::left_crop_changed), 0, this); _right_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::right_crop_changed), 0, this); _top_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::top_crop_changed), 0, this); @@ -369,8 +371,18 @@ FilmEditor::make_content_panel () _content_sizer->Add (s, 1, wxEXPAND | wxALL, 6); } + wxBoxSizer* h = new wxBoxSizer (wxHORIZONTAL); + _loop_content = new wxCheckBox (_content_panel, wxID_ANY, _("Loop everything")); + h->Add (_loop_content, 0, wxALL, 6); + _loop_count = new wxSpinCtrl (_content_panel, wxID_ANY); + h->Add (_loop_count, 0, wxALL, 6); + add_label_to_sizer (h, _content_panel, _("times")); + _content_sizer->Add (h, 0, wxALL, 6); + _content_information = new wxTextCtrl (_content_panel, wxID_ANY, wxT ("\n\n\n\n"), wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxTE_MULTILINE); _content_sizer->Add (_content_information, 1, wxEXPAND | wxALL, 6); + + _loop_count->SetRange (2, 1024); } void @@ -620,6 +632,11 @@ FilmEditor::film_changed (Film::Property p) setup_show_audio_sensitivity (); setup_length (); break; + case Film::LOOP: + checked_set (_loop_content, _film->loop() > 1); + checked_set (_loop_count, _film->loop()); + setup_loop_sensitivity (); + break; case Film::TRUST_CONTENT_HEADERS: checked_set (_trust_content_headers, _film->trust_content_headers ()); break; @@ -890,6 +907,7 @@ FilmEditor::set_film (shared_ptr f) film_changed (Film::NAME); film_changed (Film::USE_DCI_NAME); film_changed (Film::CONTENT); + film_changed (Film::LOOP); film_changed (Film::TRUST_CONTENT_HEADERS); film_changed (Film::DCP_CONTENT_TYPE); film_changed (Film::FORMAT); @@ -1491,3 +1509,27 @@ FilmEditor::trim_type_changed (wxCommandEvent &) { _film->set_trim_type (_trim_type->GetSelection () == 0 ? Film::CPL : Film::ENCODE); } + +void +FilmEditor::loop_content_toggled (wxCommandEvent &) +{ + if (_loop_content->GetValue ()) { + _film->set_loop (_loop_count->GetValue ()); + } else { + _film->set_loop (1); + } + + setup_loop_sensitivity (); +} + +void +FilmEditor::loop_count_changed (wxCommandEvent &) +{ + _film->set_loop (_loop_count->GetValue ()); +} + +void +FilmEditor::setup_loop_sensitivity () +{ + _loop_count->Enable (_loop_content->GetValue ()); +} diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index ffffc1e76..5944633a8 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -93,6 +93,8 @@ private: void dcp_frame_rate_changed (wxCommandEvent &); void best_dcp_frame_rate_clicked (wxCommandEvent &); void edit_filters_clicked (wxCommandEvent &); + void loop_content_toggled (wxCommandEvent &); + void loop_count_changed (wxCommandEvent &); /* Handle changes to the model */ void film_changed (Film::Property); @@ -113,6 +115,7 @@ private: void setup_length (); void setup_content_information (); void setup_content_button_sensitivity (); + void setup_loop_sensitivity (); void active_jobs_changed (bool); boost::shared_ptr selected_content (); @@ -143,6 +146,8 @@ private: wxButton* _content_earlier; wxButton* _content_later; wxTextCtrl* _content_information; + wxCheckBox* _loop_content; + wxSpinCtrl* _loop_count; wxButton* _edit_dci_button; wxChoice* _format; wxStaticText* _format_description; -- cgit v1.2.3 From a8d24d35dc999228f804ed425c0d9e90b9ddceaa Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 28 Apr 2013 16:23:35 +0100 Subject: Fix broken external audio support. --- ChangeLog | 4 +++ src/lib/sndfile_decoder.cc | 68 +++++++++++++++++----------------------------- src/lib/sndfile_decoder.h | 6 ++-- 3 files changed, 33 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/ChangeLog b/ChangeLog index 129d148e9..64db7a3ec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-04-28 Carl Hetherington + + * Fix broken external audio support. + 2013-04-24 Carl Hetherington * Allow use of existing empty directories for new films (without diff --git a/src/lib/sndfile_decoder.cc b/src/lib/sndfile_decoder.cc index af59c049c..fdaf2eeaa 100644 --- a/src/lib/sndfile_decoder.cc +++ b/src/lib/sndfile_decoder.cc @@ -36,15 +36,12 @@ using boost::optional; SndfileDecoder::SndfileDecoder (shared_ptr f, DecodeOptions o) : Decoder (f, o) , AudioDecoder (f, o) + , _done (0) + , _frames (0) { - sf_count_t frames; - vector sf = open_files (frames); - close_files (sf); -} - -vector -SndfileDecoder::open_files (sf_count_t & frames) -{ + _done = 0; + _frames = 0; + vector const files = _film->external_audio (); int N = 0; @@ -55,16 +52,14 @@ SndfileDecoder::open_files (sf_count_t & frames) } if (N == 0) { - return vector (); + return; } bool first = true; - frames = 0; - vector sndfiles; for (size_t i = 0; i < (size_t) N; ++i) { if (files[i].empty ()) { - sndfiles.push_back (0); + _sndfiles.push_back (0); } else { SF_INFO info; SNDFILE* s = sf_open (files[i].c_str(), SFM_READ, &info); @@ -76,7 +71,7 @@ SndfileDecoder::open_files (sf_count_t & frames) throw DecodeError (_("external audio files must be mono")); } - sndfiles.push_back (s); + _sndfiles.push_back (s); if (first) { shared_ptr st ( @@ -87,60 +82,47 @@ SndfileDecoder::open_files (sf_count_t & frames) _audio_streams.push_back (st); _audio_stream = st; - frames = info.frames; + _frames = info.frames; first = false; } else { - if (info.frames != frames) { + if (info.frames != _frames) { throw DecodeError (_("external audio files have differing lengths")); } } } } - - return sndfiles; } bool SndfileDecoder::pass () { - sf_count_t frames; - vector sndfiles = open_files (frames); - if (sndfiles.empty()) { - return true; - } - /* Do things in half second blocks as I think there may be limits to what FFmpeg (and in particular the resampler) can cope with. */ sf_count_t const block = _audio_stream->sample_rate() / 2; shared_ptr audio (new AudioBuffers (_audio_stream->channels(), block)); - sf_count_t done = 0; - while (frames > 0) { - sf_count_t const this_time = min (block, frames); - for (size_t i = 0; i < sndfiles.size(); ++i) { - if (!sndfiles[i]) { - audio->make_silent (i); - } else { - sf_read_float (sndfiles[i], audio->data(i), block); - } + sf_count_t const this_time = min (block, _frames - _done); + for (size_t i = 0; i < _sndfiles.size(); ++i) { + if (!_sndfiles[i]) { + audio->make_silent (i); + } else { + sf_read_float (_sndfiles[i], audio->data(i), this_time); } - - audio->set_frames (this_time); - Audio (audio, double(done) / _audio_stream->sample_rate()); - done += this_time; - frames -= this_time; } - close_files (sndfiles); + audio->set_frames (this_time); + Audio (audio, double(_done) / _audio_stream->sample_rate()); + _done += this_time; - return true; + return (_done == _frames); } -void -SndfileDecoder::close_files (vector const & sndfiles) +SndfileDecoder::~SndfileDecoder () { - for (size_t i = 0; i < sndfiles.size(); ++i) { - sf_close (sndfiles[i]); + for (size_t i = 0; i < _sndfiles.size(); ++i) { + if (_sndfiles[i]) { + sf_close (_sndfiles[i]); + } } } diff --git a/src/lib/sndfile_decoder.h b/src/lib/sndfile_decoder.h index e16eab673..9489cb5ec 100644 --- a/src/lib/sndfile_decoder.h +++ b/src/lib/sndfile_decoder.h @@ -45,10 +45,12 @@ class SndfileDecoder : public AudioDecoder { public: SndfileDecoder (boost::shared_ptr, DecodeOptions); + ~SndfileDecoder (); bool pass (); private: - std::vector open_files (sf_count_t &); - void close_files (std::vector const &); + std::vector _sndfiles; + sf_count_t _done; + sf_count_t _frames; }; -- cgit v1.2.3 From c75d5f1bbe03e83d3ab0ba4c76f8a6ce53eb197d Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 28 Apr 2013 16:27:32 +0100 Subject: Updated it_IT translation from Massimiliano --- src/lib/po/it_IT.po | 21 ++++++++++----------- src/tools/po/it_IT.po | 2 +- src/wx/po/it_IT.po | 27 +++++++++++++-------------- 3 files changed, 24 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/lib/po/it_IT.po b/src/lib/po/it_IT.po index 5f9e9e862..a3d35dec9 100644 --- a/src/lib/po/it_IT.po +++ b/src/lib/po/it_IT.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-04-22 15:06+0100\n" -"PO-Revision-Date: 2013-04-03 15:04+0100\n" +"PO-Revision-Date: 2013-04-28 10:26+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" "Language: Italiano\n" @@ -46,9 +46,8 @@ msgid "16:9 within Flat" msgstr "16:9 all'interno di Flat" #: src/lib/format.cc:115 -#, fuzzy msgid "16:9 within Scope" -msgstr "16:9 all'interno di Flat" +msgstr "16:9 all'interno di Scope" #: src/lib/filter.cc:88 msgid "3D denoiser" @@ -56,7 +55,7 @@ msgstr "Riduttore di rumore 3D" #: src/lib/format.cc:79 msgid "4:3" -msgstr "" +msgstr "4:3" #: src/lib/format.cc:87 msgid "4:3 within Flat" @@ -183,7 +182,7 @@ msgstr "Esamino il contenuto" #: src/lib/examine_content_job.cc:58 msgid "Examine content of %1" -msgstr "Esamo il contenuto di %1" +msgstr "Esamino il contenuto di %1" #: src/lib/filter.cc:72 msgid "Experimental horizontal deblocking filter 1" @@ -301,7 +300,7 @@ msgstr "Riduzione del rumore" #: src/lib/job.cc:302 msgid "OK (ran for %1)" -msgstr "OK (procede al %1)" +msgstr "OK (eseguito in %1)" #: src/lib/filter.cc:91 msgid "Overcomplete wavelet denoiser" @@ -473,7 +472,7 @@ msgstr "non riesco ad aprire il file dell'audio esterno per leggerlo" #: src/lib/exceptions.cc:29 msgid "could not open file %1" -msgstr "non riesco ad aprire il file per leggerlo" +msgstr "non riesco ad aprire %1" #: src/lib/dcp_video_frame.cc:388 msgid "could not open file for reading" @@ -481,11 +480,11 @@ msgstr "non riesco ad aprire il file per leggerlo" #: src/lib/exceptions.cc:44 msgid "could not read from file %1 (%2)" -msgstr "Non posso creare la directory remota %1 (%2)" +msgstr "non posso leggere dal file %1 (%2)" #: src/lib/encoder.cc:137 src/lib/encoder.cc:314 msgid "could not run sample-rate converter" -msgstr "non riesco a lanciare il convertitore della frequenza di campionamento" +msgstr "non riesco a eseguire il convertitore della frequenza di campionamento" #: src/lib/scp_dcp_job.cc:86 msgid "could not start SCP session (%1)" @@ -497,7 +496,7 @@ msgstr "non posso avviare la sessione SSH" #: src/lib/exceptions.cc:50 msgid "could not write to file %1 (%2)" -msgstr "Non posso scrivere il file remoto (%1)" +msgstr "non posso scrivere il file (%1)" #: src/lib/sndfile_decoder.cc:94 msgid "external audio files have differing lengths" @@ -549,7 +548,7 @@ msgstr "nome" #: src/lib/imagemagick_decoder.cc:60 msgid "no still image files found" -msgstr "file del fermo immagine non trovati" +msgstr "file immagini statiche non trovati" #: src/lib/subtitle.cc:58 msgid "non-bitmap subtitles not yet supported" diff --git a/src/tools/po/it_IT.po b/src/tools/po/it_IT.po index 1e0d8446a..f0984946d 100644 --- a/src/tools/po/it_IT.po +++ b/src/tools/po/it_IT.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-04-22 15:06+0100\n" -"PO-Revision-Date: 2013-04-03 13:00+0100\n" +"PO-Revision-Date: 2013-04-28 10:31+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" "Language: Italiano\n" diff --git a/src/wx/po/it_IT.po b/src/wx/po/it_IT.po index c730a7ff7..2d4ee7fd7 100644 --- a/src/wx/po/it_IT.po +++ b/src/wx/po/it_IT.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-04-22 15:06+0100\n" -"PO-Revision-Date: 2013-04-03 12:37+0100\n" +"PO-Revision-Date: 2013-04-28 10:27+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" "Language: Italiano\n" @@ -27,7 +27,7 @@ msgstr "(riavviare DVD-o-matic per vedere i cambiamenti di lingua)" #: src/wx/film_editor.cc:1276 msgid "1 channel" -msgstr "Canale 1" +msgstr "1 canale" #: src/wx/film_editor.cc:184 msgid "A/B" @@ -56,7 +56,7 @@ msgstr "Lingua dell'audio (es. EN)" #: src/wx/film_editor.cc:824 #, c-format msgid "Audio will be resampled from %dHz to %dHz\n" -msgstr "" +msgstr "L'Audio sarà ricampionato da %dHz a %dHz\n" #: src/wx/job_wrapper.cc:38 #, c-format @@ -126,7 +126,7 @@ msgstr "Crea nella cartella" #: src/wx/film_editor.cc:1371 #, c-format msgid "Cropped to %dx%d (%.2f:1)\n" -msgstr "" +msgstr "Tagliato da %dx%d (%.2f:1)\n" #: src/wx/dci_metadata_dialog.cc:28 msgid "DCI name" @@ -224,7 +224,7 @@ msgstr "Fotogrammi già codificati" #: src/wx/gain_calculator_dialog.cc:27 msgid "Gain Calculator" -msgstr "Calcola il guadagno audio" +msgstr "Calcolatore del guadagno audio" #: src/wx/properties_dialog.cc:59 msgid "Gb" @@ -285,7 +285,7 @@ msgstr "Frequenza fotogrammi originale" #: src/wx/film_editor.cc:1360 #, c-format msgid "Original video is %dx%d (%.2f:1)\n" -msgstr "" +msgstr "Il video originale è %dx%d (%.2f:1)\n" #: src/wx/dci_metadata_dialog.cc:57 msgid "Package Type (e.g. OV)" @@ -294,7 +294,7 @@ msgstr "Tipo di Package (es. OV)" #: src/wx/film_editor.cc:1392 #, c-format msgid "Padded with black to %dx%d (%.2f:1)\n" -msgstr "" +msgstr "Riempito con nero a %dx%d (%.2f:1)\n" #: src/wx/audio_dialog.cc:60 msgid "Peak" @@ -339,7 +339,7 @@ msgstr "In corso" #: src/wx/film_editor.cc:1384 #, c-format msgid "Scaled to %dx%d (%.2f:1)\n" -msgstr "" +msgstr "Scalato a %dx%d (%.2f:1)\n" #: src/wx/film_editor.cc:319 msgid "Scaler" @@ -438,9 +438,8 @@ msgid "Trim frames" msgstr "Taglia fotogrammi" #: src/wx/film_editor.cc:179 -#, fuzzy msgid "Trim method" -msgstr "Taglia fotogrammi" +msgstr "Metodo di taglio" #: src/wx/film_editor.cc:125 msgid "Trust content's header" @@ -472,7 +471,7 @@ msgstr "Video" #: src/wx/film_editor.cc:428 msgid "With Subtitles" -msgstr "Con Sottotitoli" +msgstr "Con sottotitoli" #: src/wx/film_editor.cc:1278 msgid "channels" @@ -488,11 +487,11 @@ msgstr "dB" #: src/wx/film_editor.cc:212 msgid "encode all frames and play the subset" -msgstr "" +msgstr "Codifica tutti i fotogrammi e riproduci la selezione" #: src/wx/film_editor.cc:213 msgid "encode only the subset" -msgstr "" +msgstr "codifica solo la selezione" #: src/wx/film_editor.cc:694 src/wx/film_editor.cc:697 msgid "frames" @@ -505,7 +504,7 @@ msgstr "ms" #: src/wx/film_editor.cc:440 msgid "pixels" -msgstr "" +msgstr "pizels" #. / TRANSLATORS: `s' here is an abbreviation for seconds, the unit of time #: src/wx/film_editor.cc:197 -- cgit v1.2.3 From 1432280f6c13d507690daf286e13cf850e612914 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 28 Apr 2013 22:50:00 +0100 Subject: Fix initial display of viewer image. --- src/lib/playlist.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index 216244bd0..72745f220 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -103,8 +103,6 @@ Playlist::setup () _content_connections.push_back ((*i)->Changed.connect (bind (&Playlist::content_changed, this, _1, _2))); } - - Changed (); } /** @return Length of our audio */ @@ -328,6 +326,8 @@ Playlist::set_from_xml (shared_ptr node) } _loop = node->number_child ("Loop"); + + setup (); } void @@ -345,6 +345,7 @@ Playlist::add (shared_ptr c) { _content.push_back (c); setup (); + Changed (); } void @@ -356,6 +357,7 @@ Playlist::remove (shared_ptr c) } setup (); + Changed (); } void @@ -372,6 +374,7 @@ Playlist::move_earlier (shared_ptr c) swap (*i, *j); setup (); + Changed (); } void @@ -391,6 +394,7 @@ Playlist::move_later (shared_ptr c) swap (*i, *j); setup (); + Changed (); } void -- cgit v1.2.3 From fca4842c205bc2fa74af94955100ca873bffc5d0 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 28 Apr 2013 22:59:41 +0100 Subject: Fix crash on preview playback reaching the end of the content (#131). --- src/lib/player.cc | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/lib/player.cc b/src/lib/player.cc index d62d8f8b6..a3d52f43e 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -299,6 +299,10 @@ Player::setup_decoders () double Player::last_video_time () const { + if (_video_decoder >= _video_decoders.size ()) { + return 0; + } + return _video_start[_video_decoder] + _video_decoders[_video_decoder]->last_content_time (); } -- cgit v1.2.3 From dbc43b6e3021e34875d7d5bba04abf7ad1fc8633 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 29 Apr 2013 14:46:20 +0100 Subject: More cycle-breaking of shared_ptr for decoder / player. --- src/lib/audio_source.cc | 18 ++++++++++++++---- src/lib/video_source.cc | 25 ++++++++++++++++--------- 2 files changed, 30 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/lib/audio_source.cc b/src/lib/audio_source.cc index 32b3deccf..2867bcc24 100644 --- a/src/lib/audio_source.cc +++ b/src/lib/audio_source.cc @@ -40,13 +40,23 @@ AudioSource::connect_audio (shared_ptr s) } void -TimedAudioSource::connect_audio (shared_ptr s) +TimedAudioSource::connect_audio (shared_ptr s) +{ + Audio.connect (bind (process_audio_proxy, weak_ptr (s), _1)); +} + +static void +timed_process_audio_proxy (weak_ptr sink, shared_ptr audio, double t) { - Audio.connect (bind (&TimedAudioSink::process_audio, s, _1, _2)); + shared_ptr p = sink.lock (); + if (p) { + p->process_audio (audio, t); + } } void -TimedAudioSource::connect_audio (shared_ptr s) +TimedAudioSource::connect_audio (shared_ptr s) { - Audio.connect (bind (&AudioSink::process_audio, s, _1)); + Audio.connect (bind (timed_process_audio_proxy, weak_ptr (s), _1, _2)); } + diff --git a/src/lib/video_source.cc b/src/lib/video_source.cc index 2de4db68d..4d505f9fe 100644 --- a/src/lib/video_source.cc +++ b/src/lib/video_source.cc @@ -36,22 +36,29 @@ process_video_proxy (weak_ptr sink, shared_ptr i, bool s void VideoSource::connect_video (shared_ptr s) { - /* If we bind, say, a Playlist (as the VideoSink) to a Decoder (which is owned - by the Playlist) we create a cycle. Use a weak_ptr to break it. + /* If we bind, say, a Player (as the VideoSink) to a Decoder (which is owned + by the Player) we create a cycle. Use a weak_ptr to break it. */ - Video.connect (bind (process_video_proxy, boost::weak_ptr (s), _1, _2, _3)); + Video.connect (bind (process_video_proxy, weak_ptr (s), _1, _2, _3)); } void -TimedVideoSource::connect_video (shared_ptr s) +TimedVideoSource::connect_video (shared_ptr s) { - Video.connect (bind (&TimedVideoSink::process_video, s, _1, _2, _3, _4)); + Video.connect (bind (process_video_proxy, weak_ptr (s), _1, _2, _3)); } -void -TimedVideoSource::connect_video (shared_ptr s) +static void +timed_process_video_proxy (weak_ptr sink, shared_ptr i, bool same, shared_ptr s, double t) { - Video.connect (bind (&VideoSink::process_video, s, _1, _2, _3)); + shared_ptr p = sink.lock (); + if (p) { + p->process_video (i, same, s, t); + } } - +void +TimedVideoSource::connect_video (shared_ptr s) +{ + Video.connect (bind (timed_process_video_proxy, weak_ptr (s), _1, _2, _3, _4)); +} -- cgit v1.2.3 From 326bf1a5409b2520464ff5df17051d4377955495 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 30 Apr 2013 15:47:41 +0100 Subject: Remove old ffmpeg compatibility stuff. --- src/lib/ffmpeg_compatibility.cc | 119 ---------------------------------------- src/lib/ffmpeg_compatibility.h | 31 ----------- src/lib/filter_graph.cc | 55 ++----------------- src/lib/filter_graph.h | 1 - src/lib/image.h | 1 - src/lib/matcher.h | 1 - src/lib/wscript | 1 - wscript | 30 ---------- 8 files changed, 4 insertions(+), 235 deletions(-) delete mode 100644 src/lib/ffmpeg_compatibility.cc delete mode 100644 src/lib/ffmpeg_compatibility.h (limited to 'src') diff --git a/src/lib/ffmpeg_compatibility.cc b/src/lib/ffmpeg_compatibility.cc deleted file mode 100644 index 361fa7423..000000000 --- a/src/lib/ffmpeg_compatibility.cc +++ /dev/null @@ -1,119 +0,0 @@ -/* - Copyright (C) 2012 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -extern "C" { -#include -} -#include "exceptions.h" - -#include "i18n.h" - -#if LIBAVFILTER_VERSION_MAJOR == 2 && LIBAVFILTER_VERSION_MINOR == 15 - -typedef struct { - enum PixelFormat pix_fmt; -} AVSinkContext; - -static int -avsink_init (AVFilterContext* ctx, const char* args, void* opaque) -{ - AVSinkContext* priv = (AVSinkContext *) ctx->priv; - if (!opaque) { - return AVERROR (EINVAL); - } - - *priv = *(AVSinkContext *) opaque; - return 0; -} - -static void -null_end_frame (AVFilterLink *) -{ - -} - -static int -avsink_query_formats (AVFilterContext* ctx) -{ - AVSinkContext* priv = (AVSinkContext *) ctx->priv; - enum PixelFormat pix_fmts[] = { - priv->pix_fmt, - PIX_FMT_NONE - }; - - avfilter_set_common_formats (ctx, avfilter_make_format_list ((int *) pix_fmts)); - return 0; -} - -#endif - -AVFilter* -get_sink () -{ -#if LIBAVFILTER_VERSION_MAJOR == 2 && LIBAVFILTER_VERSION_MINOR == 15 - /* XXX does this leak stuff? */ - AVFilter* buffer_sink = new AVFilter; - buffer_sink->name = av_strdup (N_("avsink")); - buffer_sink->priv_size = sizeof (AVSinkContext); - buffer_sink->init = avsink_init; - buffer_sink->query_formats = avsink_query_formats; - buffer_sink->inputs = new AVFilterPad[2]; - AVFilterPad* i0 = const_cast (&buffer_sink->inputs[0]); - i0->name = N_("default"); - i0->type = AVMEDIA_TYPE_VIDEO; - i0->min_perms = AV_PERM_READ; - i0->rej_perms = 0; - i0->start_frame = 0; - i0->get_video_buffer = 0; - i0->get_audio_buffer = 0; - i0->end_frame = null_end_frame; - i0->draw_slice = 0; - i0->filter_samples = 0; - i0->poll_frame = 0; - i0->request_frame = 0; - i0->config_props = 0; - const_cast (&buffer_sink->inputs[1])->name = 0; - buffer_sink->outputs = new AVFilterPad[1]; - const_cast (&buffer_sink->outputs[0])->name = 0; - return buffer_sink; -#else - AVFilter* buffer_sink = avfilter_get_by_name(N_("buffersink")); - if (buffer_sink == 0) { - throw DecodeError (N_("Could not create buffer sink filter")); - } - - return buffer_sink; -#endif -} - -#if LIBAVFILTER_VERSION_MAJOR == 2 && LIBAVFILTER_VERSION_MINOR == 15 -AVFilterInOut * -avfilter_inout_alloc () -{ - return (AVFilterInOut *) av_malloc (sizeof (AVFilterInOut)); -} -#endif - -#ifndef HAVE_AV_FRAME_GET_BEST_EFFORT_TIMESTAMP -int64_t av_frame_get_best_effort_timestamp (AVFrame const * f) -{ - return f->best_effort_timestamp; -} - -#endif diff --git a/src/lib/ffmpeg_compatibility.h b/src/lib/ffmpeg_compatibility.h deleted file mode 100644 index 772d22c33..000000000 --- a/src/lib/ffmpeg_compatibility.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright (C) 2012 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -struct AVFilterInOut; - -extern AVFilter* get_sink (); -extern AVFilterInOut* avfilter_inout_alloc (); - -#ifndef HAVE_AV_PIXEL_FORMAT -#define AVPixelFormat PixelFormat -#endif - -#ifndef HAVE_AV_FRAME_GET_BEST_EFFORT_TIMESTAMP -extern int64_t av_frame_get_best_effort_timestamp (AVFrame const *); -#endif diff --git a/src/lib/filter_graph.cc b/src/lib/filter_graph.cc index 045cbaa6a..c57d26e8d 100644 --- a/src/lib/filter_graph.cc +++ b/src/lib/filter_graph.cc @@ -23,20 +23,13 @@ extern "C" { #include -#ifdef HAVE_BUFFERSRC_H #include -#endif -#if (LIBAVFILTER_VERSION_MAJOR == 2 && LIBAVFILTER_VERSION_MINOR >= 53 && LIBAVFILTER_VERSION_MINOR <= 77) || LIBAVFILTER_VERSION_MAJOR == 3 #include #include -#elif LIBAVFILTER_VERSION_MAJOR == 2 && LIBAVFILTER_VERSION_MINOR == 15 -#include -#endif #include } #include "decoder.h" #include "filter_graph.h" -#include "ffmpeg_compatibility.h" #include "filter.h" #include "exceptions.h" #include "image.h" @@ -80,7 +73,10 @@ FilterGraph::FilterGraph (shared_ptr film, FFmpegDecoder* decoder, libdcp: throw DecodeError (N_("could not find buffer src filter")); } - AVFilter* buffer_sink = get_sink (); + AVFilter* buffer_sink = avfilter_get_by_name(N_("buffersink")); + if (buffer_sink == 0) { + throw DecodeError (N_("Could not create buffer sink filter")); + } stringstream a; a << _size.width << N_(":") @@ -119,15 +115,9 @@ FilterGraph::FilterGraph (shared_ptr film, FFmpegDecoder* decoder, libdcp: inputs->pad_idx = 0; inputs->next = 0; -#if LIBAVFILTER_VERSION_MAJOR == 2 && LIBAVFILTER_VERSION_MINOR == 15 - if (avfilter_graph_parse (graph, filters.c_str(), inputs, outputs, 0) < 0) { - throw DecodeError (N_("could not set up filter graph.")); - } -#else if (avfilter_graph_parse (graph, filters.c_str(), &inputs, &outputs, 0) < 0) { throw DecodeError (N_("could not set up filter graph.")); } -#endif if (avfilter_graph_config (graph, 0) < 0) { throw DecodeError (N_("could not configure filter graph.")); @@ -144,54 +134,17 @@ FilterGraph::process (AVFrame const * frame) { list > images; -#if LIBAVFILTER_VERSION_MAJOR == 2 && LIBAVFILTER_VERSION_MINOR >= 53 && LIBAVFILTER_VERSION_MINOR <= 61 - - if (av_vsrc_buffer_add_frame (_buffer_src_context, frame, 0) < 0) { - throw DecodeError (N_("could not push buffer into filter chain.")); - } - -#elif LIBAVFILTER_VERSION_MAJOR == 2 && LIBAVFILTER_VERSION_MINOR == 15 - - AVRational par; - par.num = sample_aspect_ratio_numerator (); - par.den = sample_aspect_ratio_denominator (); - - if (av_vsrc_buffer_add_frame (_buffer_src_context, frame, 0, par) < 0) { - throw DecodeError (N_("could not push buffer into filter chain.")); - } - -#else if (av_buffersrc_write_frame (_buffer_src_context, frame) < 0) { throw DecodeError (N_("could not push buffer into filter chain.")); } -#endif - -#if LIBAVFILTER_VERSION_MAJOR == 2 && LIBAVFILTER_VERSION_MINOR >= 15 && LIBAVFILTER_VERSION_MINOR <= 61 - while (avfilter_poll_frame (_buffer_sink_context->inputs[0])) { -#else while (av_buffersink_read (_buffer_sink_context, 0)) { -#endif - -#if LIBAVFILTER_VERSION_MAJOR == 2 && LIBAVFILTER_VERSION_MINOR >= 15 - - int r = avfilter_request_frame (_buffer_sink_context->inputs[0]); - if (r < 0) { - throw DecodeError (N_("could not request filtered frame")); - } - - AVFilterBufferRef* filter_buffer = _buffer_sink_context->inputs[0]->cur_buf; - -#else - AVFilterBufferRef* filter_buffer; if (av_buffersink_get_buffer_ref (_buffer_sink_context, &filter_buffer, 0) < 0) { filter_buffer = 0; } -#endif - if (filter_buffer) { /* This takes ownership of filter_buffer */ images.push_back (shared_ptr (new FilterBufferImage ((PixelFormat) frame->format, filter_buffer))); diff --git a/src/lib/filter_graph.h b/src/lib/filter_graph.h index 7e4e8422b..ffd6855de 100644 --- a/src/lib/filter_graph.h +++ b/src/lib/filter_graph.h @@ -25,7 +25,6 @@ #define DVDOMATIC_FILTER_GRAPH_H #include "util.h" -#include "ffmpeg_compatibility.h" class Image; class VideoFilter; diff --git a/src/lib/image.h b/src/lib/image.h index 62961a92e..ad2aa79bd 100644 --- a/src/lib/image.h +++ b/src/lib/image.h @@ -32,7 +32,6 @@ extern "C" { #include } #include "util.h" -#include "ffmpeg_compatibility.h" class Scaler; class RGBFrameImage; diff --git a/src/lib/matcher.h b/src/lib/matcher.h index 41aa373a4..21e42f53d 100644 --- a/src/lib/matcher.h +++ b/src/lib/matcher.h @@ -19,7 +19,6 @@ #include #include "processor.h" -#include "ffmpeg_compatibility.h" class Matcher : public Processor, public TimedAudioSink, public TimedVideoSink, public AudioSource, public VideoSource { diff --git a/src/lib/wscript b/src/lib/wscript index 51b103afd..a4b68801f 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -22,7 +22,6 @@ sources = """ examine_content_job.cc exceptions.cc filter_graph.cc - ffmpeg_compatibility.cc ffmpeg_decoder.cc film.cc filter.cc diff --git a/wscript b/wscript index 097474563..e10c68639 100644 --- a/wscript +++ b/wscript @@ -171,36 +171,6 @@ def configure(conf): define_name = 'HAVE_G_FORMAT_SIZE', mandatory = False) - conf.check_cc(fragment = """ - extern "C" { - #include - } - int main() { AVPixelFormat f; } - """, msg = 'Checking for AVPixelFormat', - uselib = 'AVUTIL', - define_name = 'HAVE_AV_PIXEL_FORMAT', - mandatory = False) - - conf.check_cc(fragment = """ - extern "C" { - #include - } - int main() { AVFrame* f; av_frame_get_best_effort_timestamp(f); } - """, msg = 'Checking for av_frame_get_best_effort_timestamp', - uselib = 'AVCODEC', - define_name = 'HAVE_AV_FRAME_GET_BEST_EFFORT_TIMESTAMP', - mandatory = False) - - conf.check_cc(fragment = """ - extern "C" { - #include - } - int main() { } - """, msg = 'Checking for buffersrc.h', - uselib = 'AVCODEC', - define_name = 'HAVE_BUFFERSRC_H', - mandatory = False) - conf.find_program('msgfmt', var='MSGFMT') datadir = conf.env.DATADIR -- cgit v1.2.3 From 8889cf7126810fb9b754643a45dcc94ad578125f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 30 Apr 2013 15:59:26 +0100 Subject: Update filter graph to new API. --- src/lib/filter_graph.cc | 20 +++++++++----------- src/lib/filter_graph.h | 2 +- src/lib/image.cc | 32 ++++++++++++++------------------ src/lib/image.h | 16 ++++++++-------- 4 files changed, 32 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/lib/filter_graph.cc b/src/lib/filter_graph.cc index c57d26e8d..2352b3e8a 100644 --- a/src/lib/filter_graph.cc +++ b/src/lib/filter_graph.cc @@ -130,25 +130,23 @@ FilterGraph::FilterGraph (shared_ptr film, FFmpegDecoder* decoder, libdcp: * set of Images. */ list > -FilterGraph::process (AVFrame const * frame) +FilterGraph::process (AVFrame* frame) { list > images; - - if (av_buffersrc_write_frame (_buffer_src_context, frame) < 0) { + if (av_buffersrc_add_frame (_buffer_src_context, frame) < 0) { throw DecodeError (N_("could not push buffer into filter chain.")); } - while (av_buffersink_read (_buffer_sink_context, 0)) { - AVFilterBufferRef* filter_buffer; - if (av_buffersink_get_buffer_ref (_buffer_sink_context, &filter_buffer, 0) < 0) { - filter_buffer = 0; + while (1) { + AVFrame* frame = av_frame_alloc (); + if (av_buffersink_get_frame (_buffer_sink_context, 0) < 0) { + av_frame_free (&frame); + break; } - if (filter_buffer) { - /* This takes ownership of filter_buffer */ - images.push_back (shared_ptr (new FilterBufferImage ((PixelFormat) frame->format, filter_buffer))); - } + /* This takes ownership of the AVFrame */ + images.push_back (shared_ptr (new FrameImage (frame))); } return images; diff --git a/src/lib/filter_graph.h b/src/lib/filter_graph.h index ffd6855de..249b89851 100644 --- a/src/lib/filter_graph.h +++ b/src/lib/filter_graph.h @@ -39,7 +39,7 @@ public: FilterGraph (boost::shared_ptr film, FFmpegDecoder* decoder, libdcp::Size s, AVPixelFormat p); bool can_process (libdcp::Size s, AVPixelFormat p) const; - std::list > process (AVFrame const * frame); + std::list > process (AVFrame * frame); private: AVFilterContext* _buffer_src_context; diff --git a/src/lib/image.cc b/src/lib/image.cc index 1be41fecf..2d4bc0af0 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -609,9 +609,9 @@ SimpleImage::aligned () const return _aligned; } -FilterBufferImage::FilterBufferImage (AVPixelFormat p, AVFilterBufferRef* b) - : Image (p) - , _buffer (b) +FrameImage::FrameImage (AVFrame* frame) + : Image (static_cast (frame->format)) + , _frame (frame) { _line_size = (int *) av_malloc (4 * sizeof (int)); _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0; @@ -621,44 +621,40 @@ FilterBufferImage::FilterBufferImage (AVPixelFormat p, AVFilterBufferRef* b) } } -FilterBufferImage::~FilterBufferImage () +FrameImage::~FrameImage () { - avfilter_unref_buffer (_buffer); + av_frame_free (&_frame); av_free (_line_size); } uint8_t ** -FilterBufferImage::data () const +FrameImage::data () const { - return _buffer->data; + return _frame->data; } int * -FilterBufferImage::line_size () const +FrameImage::line_size () const { return _line_size; } int * -FilterBufferImage::stride () const +FrameImage::stride () const { - /* I've seen images where the _buffer->linesize is larger than the width - (by a small amount), suggesting that _buffer->linesize is what we call - stride. But I'm not sure. - */ - return _buffer->linesize; + /* AVFrame's `linesize' is what we call `stride' */ + return _frame->linesize; } libdcp::Size -FilterBufferImage::size () const +FrameImage::size () const { - return libdcp::Size (_buffer->video->w, _buffer->video->h); + return libdcp::Size (_frame->width, _frame->height); } bool -FilterBufferImage::aligned () const +FrameImage::aligned () const { - /* XXX? */ return true; } diff --git a/src/lib/image.h b/src/lib/image.h index ad2aa79bd..00768ee02 100644 --- a/src/lib/image.h +++ b/src/lib/image.h @@ -98,14 +98,14 @@ private: AVPixelFormat _pixel_format; ///< FFmpeg's way of describing the pixel format of this Image }; -/** @class FilterBufferImage - * @brief An Image that is held in an AVFilterBufferRef. +/** @class FrameImage + * @brief An Image that is held in an AVFrame. */ -class FilterBufferImage : public Image +class FrameImage : public Image { public: - FilterBufferImage (AVPixelFormat, AVFilterBufferRef *); - ~FilterBufferImage (); + FrameImage (AVFrame *); + ~FrameImage (); uint8_t ** data () const; int * line_size () const; @@ -115,10 +115,10 @@ public: private: /* Not allowed */ - FilterBufferImage (FilterBufferImage const &); - FilterBufferImage& operator= (FilterBufferImage const &); + FrameImage (FrameImage const &); + FrameImage& operator= (FrameImage const &); - AVFilterBufferRef* _buffer; + AVFrame* _frame; int* _line_size; }; -- cgit v1.2.3 From 32b21d67ae5b87c5840dd0f642840aa2e245a6ed Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 30 Apr 2013 16:28:33 +0100 Subject: Typo. --- src/lib/filter_graph.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/filter_graph.cc b/src/lib/filter_graph.cc index 2352b3e8a..47f99da14 100644 --- a/src/lib/filter_graph.cc +++ b/src/lib/filter_graph.cc @@ -140,7 +140,7 @@ FilterGraph::process (AVFrame* frame) while (1) { AVFrame* frame = av_frame_alloc (); - if (av_buffersink_get_frame (_buffer_sink_context, 0) < 0) { + if (av_buffersink_get_frame (_buffer_sink_context, frame) < 0) { av_frame_free (&frame); break; } -- cgit v1.2.3 From 65cd9738e069023ae00d84b46d8eac74b016895c Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 30 Apr 2013 16:46:21 +0100 Subject: Fix reffing of the AVFrame output by the decoder. --- src/lib/filter_graph.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/filter_graph.cc b/src/lib/filter_graph.cc index 47f99da14..f0c49b37c 100644 --- a/src/lib/filter_graph.cc +++ b/src/lib/filter_graph.cc @@ -134,7 +134,7 @@ FilterGraph::process (AVFrame* frame) { list > images; - if (av_buffersrc_add_frame (_buffer_src_context, frame) < 0) { + if (av_buffersrc_write_frame (_buffer_src_context, frame) < 0) { throw DecodeError (N_("could not push buffer into filter chain.")); } -- cgit v1.2.3 From 254664b5a482cb3551d0a98ececfbdd8296e6c71 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 30 Apr 2013 19:13:09 +0100 Subject: Couple of missing formats from Image::components(). --- src/lib/image.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/lib/image.cc b/src/lib/image.cc index 2d4bc0af0..d2842e095 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -90,6 +90,9 @@ Image::components () const { switch (_pixel_format) { case PIX_FMT_YUV420P: + case PIX_FMT_YUV422P9BE + case PIX_FMT_YUV422P9LE: + case PIX_FMT_YUV422P10BE: case PIX_FMT_YUV422P10LE: case PIX_FMT_YUV422P: case PIX_FMT_YUV444P: -- cgit v1.2.3 From d6a5bde6923078f8914f263ee76c6122b588197d Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 1 May 2013 08:07:39 +0100 Subject: Typo. --- src/lib/image.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/image.cc b/src/lib/image.cc index d2842e095..5ae9ba1d3 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -90,7 +90,7 @@ Image::components () const { switch (_pixel_format) { case PIX_FMT_YUV420P: - case PIX_FMT_YUV422P9BE + case PIX_FMT_YUV422P9BE: case PIX_FMT_YUV422P9LE: case PIX_FMT_YUV422P10BE: case PIX_FMT_YUV422P10LE: -- cgit v1.2.3 From 502672fd38b12b41746949dd6d66cfe203b657df Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 1 May 2013 13:09:27 +0100 Subject: More pixel formats. --- src/lib/image.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/image.cc b/src/lib/image.cc index 5ae9ba1d3..6464d2368 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -68,8 +68,10 @@ Image::lines (int n) const break; case PIX_FMT_RGB24: case PIX_FMT_RGBA: - case PIX_FMT_YUV422P10LE: case PIX_FMT_YUV422P: + case PIX_FMT_YUV422P10LE: + case PIX_FMT_YUV422P16LE: + case PIX_FMT_YUV422P16BE: case PIX_FMT_YUV444P: case PIX_FMT_YUV444P9BE: case PIX_FMT_YUV444P9LE: @@ -94,12 +96,16 @@ Image::components () const case PIX_FMT_YUV422P9LE: case PIX_FMT_YUV422P10BE: case PIX_FMT_YUV422P10LE: + case PIX_FMT_YUV422P16LE: + case PIX_FMT_YUV422P16BE: case PIX_FMT_YUV422P: case PIX_FMT_YUV444P: case PIX_FMT_YUV444P9BE: case PIX_FMT_YUV444P9LE: case PIX_FMT_YUV444P10BE: case PIX_FMT_YUV444P10LE: + case PIX_FMT_YUV444P16LE: + case PIX_FMT_YUV444P16BE: return 3; case PIX_FMT_RGB24: case PIX_FMT_RGBA: @@ -448,6 +454,7 @@ Image::bytes_per_pixel (int c) const return 0.5; } case PIX_FMT_YUV422P10LE: + case PIX_FMT_YUV422P16LE: if (c == 0) { return 2; } else { -- cgit v1.2.3 From 85f70dbf690a9f77189067e655b02283f910a36f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 1 May 2013 14:16:38 +0100 Subject: Add pixel formats tests. --- src/lib/image.h | 2 ++ test/test.cc | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) (limited to 'src') diff --git a/src/lib/image.h b/src/lib/image.h index 00768ee02..39d84fcd4 100644 --- a/src/lib/image.h +++ b/src/lib/image.h @@ -91,6 +91,8 @@ protected: virtual void swap (Image &); float bytes_per_pixel (int) const; + friend class pixel_formats_test; + private: void yuv_16_black (uint16_t); static uint16_t swap_16 (uint16_t); diff --git a/test/test.cc b/test/test.cc index 496c91519..11ca56031 100644 --- a/test/test.cc +++ b/test/test.cc @@ -123,6 +123,59 @@ BOOST_AUTO_TEST_CASE (make_black_test) } } + +struct Case +{ + Case (AVPixelFormat f, int c, int l0, int l1, int l2, float b0, float b1, float b2) + : format(f) + , components(c) + { + lines[0] = l0; + lines[1] = l1; + lines[2] = l2; + bpp[0] = b0; + bpp[1] = b1; + bpp[2] = b2; + } + + AVPixelFormat format; + int components; + int lines[3]; + float bpp[3]; +}; + +BOOST_AUTO_TEST_CASE (pixel_formats_test) +{ + list cases; + cases.push_back(Case(AV_PIX_FMT_RGB24, 1, 480, 480, 480, 3, 0, 0 )); + cases.push_back(Case(AV_PIX_FMT_RGBA, 1, 480, 480, 480, 4, 0, 0 )); + cases.push_back(Case(AV_PIX_FMT_YUV420P, 3, 480, 240, 240, 1, 0.5, 0.5)); + cases.push_back(Case(AV_PIX_FMT_YUV422P, 3, 480, 480, 480, 1, 0.5, 0.5)); + cases.push_back(Case(AV_PIX_FMT_YUV422P10LE, 3, 480, 480, 480, 2, 1, 1 )); + cases.push_back(Case(AV_PIX_FMT_YUV422P16LE, 3, 480, 480, 480, 2, 1, 1 )); + cases.push_back(Case(AV_PIX_FMT_UYVY422, 1, 480, 480, 480, 2, 2, 2 )); + cases.push_back(Case(AV_PIX_FMT_YUV444P, 3, 480, 480, 480, 3, 3, 3 )); + cases.push_back(Case(AV_PIX_FMT_YUV444P9BE, 3, 480, 480, 480, 6, 6, 6 )); + cases.push_back(Case(AV_PIX_FMT_YUV444P9LE, 3, 480, 480, 480, 6, 6, 6 )); + cases.push_back(Case(AV_PIX_FMT_YUV444P10BE, 3, 480, 480, 480, 6, 6, 6 )); + cases.push_back(Case(AV_PIX_FMT_YUV444P10LE, 3, 480, 480, 480, 6, 6, 6 )); + + for (list::iterator i = cases.begin(); i != cases.end(); ++i) { + AVFrame* f = av_frame_alloc (); + f->width = 640; + f->height = 480; + f->format = static_cast (i->format); + FrameImage t (f); + BOOST_CHECK_EQUAL(t.components(), i->components); + BOOST_CHECK_EQUAL(t.lines(0), i->lines[0]); + BOOST_CHECK_EQUAL(t.lines(1), i->lines[1]); + BOOST_CHECK_EQUAL(t.lines(2), i->lines[2]); + BOOST_CHECK_EQUAL(t.bytes_per_pixel(0), i->bpp[0]); + BOOST_CHECK_EQUAL(t.bytes_per_pixel(1), i->bpp[1]); + BOOST_CHECK_EQUAL(t.bytes_per_pixel(2), i->bpp[2]); + } +} + shared_ptr trimmer_test_last_video; shared_ptr trimmer_test_last_audio; -- cgit v1.2.3 From c45fd99b0b4a193edcebccc927793d48431a5a13 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 1 May 2013 15:12:38 +0100 Subject: Use ffmpeg calls for pixel parameters; add (and alter, hmm) tests to suit. --- src/lib/image.cc | 125 ++----- test/client_server_test.cc | 106 ++++++ test/dcp_test.cc | 67 ++++ test/film_metadata_test.cc | 76 ++++ test/film_test.cc | 30 ++ test/format_test.cc | 61 ++++ test/frame_rate_test.cc | 211 +++++++++++ test/image_test.cc | 99 ++++++ test/job_test.cc | 64 ++++ test/make_black_test.cc | 55 +++ test/pixel_formats_test.cc | 77 ++++ test/stream_test.cc | 52 +++ test/test.cc | 849 ++------------------------------------------- test/trimmer_test.cc | 95 +++++ test/util_test.cc | 43 +++ 15 files changed, 1100 insertions(+), 910 deletions(-) create mode 100644 test/client_server_test.cc create mode 100644 test/dcp_test.cc create mode 100644 test/film_metadata_test.cc create mode 100644 test/film_test.cc create mode 100644 test/format_test.cc create mode 100644 test/frame_rate_test.cc create mode 100644 test/image_test.cc create mode 100644 test/job_test.cc create mode 100644 test/make_black_test.cc create mode 100644 test/pixel_formats_test.cc create mode 100644 test/stream_test.cc create mode 100644 test/trimmer_test.cc create mode 100644 test/util_test.cc (limited to 'src') diff --git a/src/lib/image.cc b/src/lib/image.cc index 6464d2368..0b887ea62 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -35,6 +35,7 @@ extern "C" { #include #include #include +#include } #include "image.h" #include "exceptions.h" @@ -58,64 +59,32 @@ Image::swap (Image& other) int Image::lines (int n) const { - switch (_pixel_format) { - case PIX_FMT_YUV420P: - if (n == 0) { - return size().height; - } else { - return size().height / 2; - } - break; - case PIX_FMT_RGB24: - case PIX_FMT_RGBA: - case PIX_FMT_YUV422P: - case PIX_FMT_YUV422P10LE: - case PIX_FMT_YUV422P16LE: - case PIX_FMT_YUV422P16BE: - case PIX_FMT_YUV444P: - case PIX_FMT_YUV444P9BE: - case PIX_FMT_YUV444P9LE: - case PIX_FMT_YUV444P10BE: - case PIX_FMT_YUV444P10LE: - case PIX_FMT_UYVY422: + if (n == 0) { return size().height; - default: + } + + AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format); + if (!d) { throw PixelFormatError (N_("lines()"), _pixel_format); } - - return 0; + + return size().height / pow(2, d->log2_chroma_h); } /** @return Number of components */ int Image::components () const { - switch (_pixel_format) { - case PIX_FMT_YUV420P: - case PIX_FMT_YUV422P9BE: - case PIX_FMT_YUV422P9LE: - case PIX_FMT_YUV422P10BE: - case PIX_FMT_YUV422P10LE: - case PIX_FMT_YUV422P16LE: - case PIX_FMT_YUV422P16BE: - case PIX_FMT_YUV422P: - case PIX_FMT_YUV444P: - case PIX_FMT_YUV444P9BE: - case PIX_FMT_YUV444P9LE: - case PIX_FMT_YUV444P10BE: - case PIX_FMT_YUV444P10LE: - case PIX_FMT_YUV444P16LE: - case PIX_FMT_YUV444P16BE: - return 3; - case PIX_FMT_RGB24: - case PIX_FMT_RGBA: - case PIX_FMT_UYVY422: - return 1; - default: + AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format); + if (!d) { throw PixelFormatError (N_("components()"), _pixel_format); } - return 0; + if ((d->flags & PIX_FMT_PLANAR) == 0) { + return 1; + } + + return d->nb_components; } shared_ptr @@ -429,54 +398,36 @@ Image::write_to_socket (shared_ptr socket) const float Image::bytes_per_pixel (int c) const { - if (c == 3) { + AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format); + if (!d) { + throw PixelFormatError (N_("lines()"), _pixel_format); + } + + if (c >= components()) { return 0; } + + float bpp[4] = { 0, 0, 0, 0 }; + + bpp[0] = floor ((d->comp[0].depth_minus1 + 1 + 7) / 8); + if (d->nb_components > 1) { + bpp[1] = floor ((d->comp[1].depth_minus1 + 1 + 7) / 8) / pow (2, d->log2_chroma_w); + } + if (d->nb_components > 2) { + bpp[2] = floor ((d->comp[2].depth_minus1 + 1 + 7) / 8) / pow (2, d->log2_chroma_w); + } + if (d->nb_components > 3) { + bpp[3] = floor ((d->comp[3].depth_minus1 + 1 + 7) / 8) / pow (2, d->log2_chroma_w); + } - switch (_pixel_format) { - case PIX_FMT_RGB24: - if (c == 0) { - return 3; - } else { - return 0; - } - case PIX_FMT_RGBA: - if (c == 0) { - return 4; - } else { - return 0; - } - case PIX_FMT_YUV420P: - case PIX_FMT_YUV422P: - if (c == 0) { - return 1; - } else { - return 0.5; - } - case PIX_FMT_YUV422P10LE: - case PIX_FMT_YUV422P16LE: - if (c == 0) { - return 2; - } else { - return 1; - } - case PIX_FMT_UYVY422: - return 2; - case PIX_FMT_YUV444P: - return 3; - case PIX_FMT_YUV444P9BE: - case PIX_FMT_YUV444P9LE: - case PIX_FMT_YUV444P10LE: - case PIX_FMT_YUV444P10BE: - return 6; - default: - throw PixelFormatError (N_("bytes_per_pixel()"), _pixel_format); + if ((d->flags & PIX_FMT_PLANAR) == 0) { + /* Not planar; sum them up */ + return bpp[0] + bpp[1] + bpp[2] + bpp[3]; } - return 0; + return bpp[c]; } - /** Construct a SimpleImage of a given size and format, allocating memory * as required. * diff --git a/test/client_server_test.cc b/test/client_server_test.cc new file mode 100644 index 000000000..e5229b5ff --- /dev/null +++ b/test/client_server_test.cc @@ -0,0 +1,106 @@ +/* + Copyright (C) 2012 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +void +do_remote_encode (shared_ptr frame, ServerDescription* description, shared_ptr locally_encoded) +{ + shared_ptr remotely_encoded; + BOOST_CHECK_NO_THROW (remotely_encoded = frame->encode_remotely (description)); + BOOST_CHECK (remotely_encoded); + + BOOST_CHECK_EQUAL (locally_encoded->size(), remotely_encoded->size()); + BOOST_CHECK (memcmp (locally_encoded->data(), remotely_encoded->data(), locally_encoded->size()) == 0); +} + +BOOST_AUTO_TEST_CASE (client_server_test) +{ + shared_ptr image (new SimpleImage (PIX_FMT_RGB24, libdcp::Size (1998, 1080), true)); + uint8_t* p = image->data()[0]; + + for (int y = 0; y < 1080; ++y) { + uint8_t* q = p; + for (int x = 0; x < 1998; ++x) { + *q++ = x % 256; + *q++ = y % 256; + *q++ = (x + y) % 256; + } + p += image->stride()[0]; + } + + shared_ptr sub_image (new SimpleImage (PIX_FMT_RGBA, libdcp::Size (100, 200), true)); + p = sub_image->data()[0]; + for (int y = 0; y < 200; ++y) { + uint8_t* q = p; + for (int x = 0; x < 100; ++x) { + *q++ = y % 256; + *q++ = x % 256; + *q++ = (x + y) % 256; + *q++ = 1; + } + p += sub_image->stride()[0]; + } + + shared_ptr subtitle (new Subtitle (Position (50, 60), sub_image)); + + shared_ptr log (new FileLog ("build/test/client_server_test.log")); + + shared_ptr frame ( + new DCPVideoFrame ( + image, + subtitle, + libdcp::Size (1998, 1080), + 0, + 0, + 1, + Scaler::from_id ("bicubic"), + 0, + 24, + "", + 0, + 200000000, + log + ) + ); + + shared_ptr locally_encoded = frame->encode_locally (); + BOOST_ASSERT (locally_encoded); + + Server* server = new Server (log); + + new thread (boost::bind (&Server::run, server, 2)); + + /* Let the server get itself ready */ + dvdomatic_sleep (1); + + ServerDescription description ("localhost", 2); + + list threads; + for (int i = 0; i < 8; ++i) { + threads.push_back (new thread (boost::bind (do_remote_encode, frame, &description, locally_encoded))); + } + + for (list::iterator i = threads.begin(); i != threads.end(); ++i) { + (*i)->join (); + } + + for (list::iterator i = threads.begin(); i != threads.end(); ++i) { + delete *i; + } +} + diff --git a/test/dcp_test.cc b/test/dcp_test.cc new file mode 100644 index 000000000..9312a2067 --- /dev/null +++ b/test/dcp_test.cc @@ -0,0 +1,67 @@ +/* + Copyright (C) 2012 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +BOOST_AUTO_TEST_CASE (make_dcp_test) +{ + shared_ptr film = new_test_film ("make_dcp_test"); + film->set_name ("test_film2"); + film->set_content ("../../../test/test.mp4"); + film->set_format (Format::from_nickname ("Flat")); + film->set_dcp_content_type (DCPContentType::from_pretty_name ("Test")); + film->make_dcp (); + film->write_metadata (); + + while (JobManager::instance()->work_to_do ()) { + dvdomatic_sleep (1); + } + + BOOST_CHECK_EQUAL (JobManager::instance()->errors(), false); +} + +/** Test Film::have_dcp(). Requires the output from make_dcp_test above */ +BOOST_AUTO_TEST_CASE (have_dcp_test) +{ + boost::filesystem::path p = test_film_dir ("make_dcp_test"); + Film f (p.string ()); + BOOST_CHECK (f.have_dcp()); + + p /= f.dcp_name(); + p /= f.dcp_video_mxf_filename(); + boost::filesystem::remove (p); + BOOST_CHECK (!f.have_dcp ()); +} + +BOOST_AUTO_TEST_CASE (make_dcp_with_range_test) +{ + shared_ptr film = new_test_film ("make_dcp_with_range_test"); + film->set_name ("test_film3"); + film->set_content ("../../../test/test.mp4"); + film->examine_content (); + film->set_format (Format::from_nickname ("Flat")); + film->set_dcp_content_type (DCPContentType::from_pretty_name ("Test")); + film->set_trim_end (42); + film->make_dcp (); + + while (JobManager::instance()->work_to_do() && !JobManager::instance()->errors()) { + dvdomatic_sleep (1); + } + + BOOST_CHECK_EQUAL (JobManager::instance()->errors(), false); +} + diff --git a/test/film_metadata_test.cc b/test/film_metadata_test.cc new file mode 100644 index 000000000..0b4495b48 --- /dev/null +++ b/test/film_metadata_test.cc @@ -0,0 +1,76 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +BOOST_AUTO_TEST_CASE (film_metadata_test) +{ + string const test_film = "build/test/film_metadata_test"; + + if (boost::filesystem::exists (test_film)) { + boost::filesystem::remove_all (test_film); + } + + BOOST_CHECK_THROW (new Film (test_film, true), OpenFileError); + + shared_ptr f (new Film (test_film, false)); + f->_dci_date = boost::gregorian::from_undelimited_string ("20130211"); + BOOST_CHECK (f->format() == 0); + BOOST_CHECK (f->dcp_content_type() == 0); + BOOST_CHECK (f->filters ().empty()); + + f->set_name ("fred"); + BOOST_CHECK_THROW (f->set_content ("jim"), OpenFileError); + f->set_dcp_content_type (DCPContentType::from_pretty_name ("Short")); + f->set_format (Format::from_nickname ("Flat")); + f->set_left_crop (1); + f->set_right_crop (2); + f->set_top_crop (3); + f->set_bottom_crop (4); + vector f_filters; + f_filters.push_back (Filter::from_id ("pphb")); + f_filters.push_back (Filter::from_id ("unsharp")); + f->set_filters (f_filters); + f->set_trim_start (42); + f->set_trim_end (99); + f->set_dcp_ab (true); + f->write_metadata (); + + stringstream s; + s << "diff -u test/metadata.ref " << test_film << "/metadata"; + BOOST_CHECK_EQUAL (::system (s.str().c_str ()), 0); + + shared_ptr g (new Film (test_film, true)); + + BOOST_CHECK_EQUAL (g->name(), "fred"); + BOOST_CHECK_EQUAL (g->dcp_content_type(), DCPContentType::from_pretty_name ("Short")); + BOOST_CHECK_EQUAL (g->format(), Format::from_nickname ("Flat")); + BOOST_CHECK_EQUAL (g->crop().left, 1); + BOOST_CHECK_EQUAL (g->crop().right, 2); + BOOST_CHECK_EQUAL (g->crop().top, 3); + BOOST_CHECK_EQUAL (g->crop().bottom, 4); + vector g_filters = g->filters (); + BOOST_CHECK_EQUAL (g_filters.size(), 2); + BOOST_CHECK_EQUAL (g_filters.front(), Filter::from_id ("pphb")); + BOOST_CHECK_EQUAL (g_filters.back(), Filter::from_id ("unsharp")); + BOOST_CHECK_EQUAL (g->trim_start(), 42); + BOOST_CHECK_EQUAL (g->trim_end(), 99); + BOOST_CHECK_EQUAL (g->dcp_ab(), true); + + g->write_metadata (); + BOOST_CHECK_EQUAL (::system (s.str().c_str ()), 0); +} diff --git a/test/film_test.cc b/test/film_test.cc new file mode 100644 index 000000000..02dfa0553 --- /dev/null +++ b/test/film_test.cc @@ -0,0 +1,30 @@ +/* + Copyright (C) 2012 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +BOOST_AUTO_TEST_CASE (paths_test) +{ + shared_ptr f = new_test_film ("paths_test"); + f->set_directory ("build/test/a/b/c/d/e"); + + f->_content = "/foo/bar/baz"; + BOOST_CHECK_EQUAL (f->content_path(), "/foo/bar/baz"); + f->_content = "foo/bar/baz"; + BOOST_CHECK_EQUAL (f->content_path(), "build/test/a/b/c/d/e/foo/bar/baz"); +} + diff --git a/test/format_test.cc b/test/format_test.cc new file mode 100644 index 000000000..b150738a4 --- /dev/null +++ b/test/format_test.cc @@ -0,0 +1,61 @@ +/* + Copyright (C) 2012 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +BOOST_AUTO_TEST_CASE (format_test) +{ + Format::setup_formats (); + + Format const * f = Format::from_nickname ("Flat"); + BOOST_CHECK (f); + BOOST_CHECK_EQUAL (f->dcp_size().width, 1998); + BOOST_CHECK_EQUAL (f->dcp_size().height, 1080); + + f = Format::from_nickname ("Scope"); + BOOST_CHECK (f); + BOOST_CHECK_EQUAL (f->dcp_size().width, 2048); + BOOST_CHECK_EQUAL (f->dcp_size().height, 858); +} + + +/* Test VariableFormat-based scaling of content */ +BOOST_AUTO_TEST_CASE (scaling_test) +{ + shared_ptr film (new Film (test_film_dir ("scaling_test").string(), false)); + + /* 4:3 ratio */ + film->set_size (libdcp::Size (320, 240)); + + /* This format should preserve aspect ratio of the source */ + Format const * format = Format::from_id ("var-185"); + + /* We should have enough padding that the result is 4:3, + which would be 1440 pixels. + */ + BOOST_CHECK_EQUAL (format->dcp_padding (film), (1998 - 1440) / 2); + + /* This crops it to 1.291666667 */ + film->set_left_crop (5); + film->set_right_crop (5); + + /* We should now have enough padding that the result is 1.29166667, + which would be 1395 pixels. + */ + BOOST_CHECK_EQUAL (format->dcp_padding (film), rint ((1998 - 1395) / 2.0)); +} + diff --git a/test/frame_rate_test.cc b/test/frame_rate_test.cc new file mode 100644 index 000000000..00700656e --- /dev/null +++ b/test/frame_rate_test.cc @@ -0,0 +1,211 @@ +/* + Copyright (C) 2012 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +/* Test best_dcp_frame_rate and FrameRateConversion */ +BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test) +{ + /* Run some tests with a limited range of allowed rates */ + + std::list afr; + afr.push_back (24); + afr.push_back (25); + afr.push_back (30); + Config::instance()->set_allowed_dcp_frame_rates (afr); + + int best = best_dcp_frame_rate (60); + FrameRateConversion frc = FrameRateConversion (60, best); + BOOST_CHECK_EQUAL (best, 30); + BOOST_CHECK_EQUAL (frc.skip, true); + BOOST_CHECK_EQUAL (frc.repeat, false); + BOOST_CHECK_EQUAL (frc.change_speed, false); + + best = best_dcp_frame_rate (50); + frc = FrameRateConversion (50, best); + BOOST_CHECK_EQUAL (best, 25); + BOOST_CHECK_EQUAL (frc.skip, true); + BOOST_CHECK_EQUAL (frc.repeat, false); + BOOST_CHECK_EQUAL (frc.change_speed, false); + + best = best_dcp_frame_rate (48); + frc = FrameRateConversion (48, best); + BOOST_CHECK_EQUAL (best, 24); + BOOST_CHECK_EQUAL (frc.skip, true); + BOOST_CHECK_EQUAL (frc.repeat, false); + BOOST_CHECK_EQUAL (frc.change_speed, false); + + best = best_dcp_frame_rate (30); + frc = FrameRateConversion (30, best); + BOOST_CHECK_EQUAL (best, 30); + BOOST_CHECK_EQUAL (frc.skip, false); + BOOST_CHECK_EQUAL (frc.repeat, false); + BOOST_CHECK_EQUAL (frc.change_speed, false); + + best = best_dcp_frame_rate (29.97); + frc = FrameRateConversion (29.97, best); + BOOST_CHECK_EQUAL (best, 30); + BOOST_CHECK_EQUAL (frc.skip, false); + BOOST_CHECK_EQUAL (frc.repeat, false); + BOOST_CHECK_EQUAL (frc.change_speed, true); + + best = best_dcp_frame_rate (25); + frc = FrameRateConversion (25, best); + BOOST_CHECK_EQUAL (best, 25); + BOOST_CHECK_EQUAL (frc.skip, false); + BOOST_CHECK_EQUAL (frc.repeat, false); + BOOST_CHECK_EQUAL (frc.change_speed, false); + + best = best_dcp_frame_rate (24); + frc = FrameRateConversion (24, best); + BOOST_CHECK_EQUAL (best, 24); + BOOST_CHECK_EQUAL (frc.skip, false); + BOOST_CHECK_EQUAL (frc.repeat, false); + BOOST_CHECK_EQUAL (frc.change_speed, false); + + best = best_dcp_frame_rate (14.5); + frc = FrameRateConversion (14.5, best); + BOOST_CHECK_EQUAL (best, 30); + BOOST_CHECK_EQUAL (frc.skip, false); + BOOST_CHECK_EQUAL (frc.repeat, true); + BOOST_CHECK_EQUAL (frc.change_speed, true); + + best = best_dcp_frame_rate (12.6); + frc = FrameRateConversion (12.6, best); + BOOST_CHECK_EQUAL (best, 25); + BOOST_CHECK_EQUAL (frc.skip, false); + BOOST_CHECK_EQUAL (frc.repeat, true); + BOOST_CHECK_EQUAL (frc.change_speed, true); + + best = best_dcp_frame_rate (12.4); + frc = FrameRateConversion (12.4, best); + BOOST_CHECK_EQUAL (best, 25); + BOOST_CHECK_EQUAL (frc.skip, false); + BOOST_CHECK_EQUAL (frc.repeat, true); + BOOST_CHECK_EQUAL (frc.change_speed, true); + + best = best_dcp_frame_rate (12); + frc = FrameRateConversion (12, best); + BOOST_CHECK_EQUAL (best, 24); + BOOST_CHECK_EQUAL (frc.skip, false); + BOOST_CHECK_EQUAL (frc.repeat, true); + BOOST_CHECK_EQUAL (frc.change_speed, false); + + /* Now add some more rates and see if it will use them + in preference to skip/repeat. + */ + + afr.push_back (48); + afr.push_back (50); + afr.push_back (60); + Config::instance()->set_allowed_dcp_frame_rates (afr); + + best = best_dcp_frame_rate (60); + frc = FrameRateConversion (60, best); + BOOST_CHECK_EQUAL (best, 60); + BOOST_CHECK_EQUAL (frc.skip, false); + BOOST_CHECK_EQUAL (frc.repeat, false); + BOOST_CHECK_EQUAL (frc.change_speed, false); + + best = best_dcp_frame_rate (50); + frc = FrameRateConversion (50, best); + BOOST_CHECK_EQUAL (best, 50); + BOOST_CHECK_EQUAL (frc.skip, false); + BOOST_CHECK_EQUAL (frc.repeat, false); + BOOST_CHECK_EQUAL (frc.change_speed, false); + + best = best_dcp_frame_rate (48); + frc = FrameRateConversion (48, best); + BOOST_CHECK_EQUAL (best, 48); + BOOST_CHECK_EQUAL (frc.skip, false); + BOOST_CHECK_EQUAL (frc.repeat, false); + BOOST_CHECK_EQUAL (frc.change_speed, false); + + /* Check some out-there conversions (not the best) */ + + frc = FrameRateConversion (14.99, 24); + BOOST_CHECK_EQUAL (frc.skip, false); + BOOST_CHECK_EQUAL (frc.repeat, true); + BOOST_CHECK_EQUAL (frc.change_speed, true); + + /* Check some conversions with limited DCP targets */ + + afr.clear (); + afr.push_back (24); + Config::instance()->set_allowed_dcp_frame_rates (afr); + + best = best_dcp_frame_rate (25); + frc = FrameRateConversion (25, best); + BOOST_CHECK_EQUAL (best, 24); + BOOST_CHECK_EQUAL (frc.skip, false); + BOOST_CHECK_EQUAL (frc.repeat, false); + BOOST_CHECK_EQUAL (frc.change_speed, true); +} + +BOOST_AUTO_TEST_CASE (audio_sampling_rate_test) +{ + std::list afr; + afr.push_back (24); + afr.push_back (25); + afr.push_back (30); + Config::instance()->set_allowed_dcp_frame_rates (afr); + + shared_ptr f = new_test_film ("audio_sampling_rate_test"); + f->set_source_frame_rate (24); + f->set_dcp_frame_rate (24); + + f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 48000, 0))); + BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 48000); + + f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 44100, 0))); + BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 48000); + + f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 80000, 0))); + BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 96000); + + f->set_source_frame_rate (23.976); + f->set_dcp_frame_rate (best_dcp_frame_rate (23.976)); + f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 48000, 0))); + BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 47952); + + f->set_source_frame_rate (29.97); + f->set_dcp_frame_rate (best_dcp_frame_rate (29.97)); + BOOST_CHECK_EQUAL (f->dcp_frame_rate (), 30); + f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 48000, 0))); + BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 47952); + + f->set_source_frame_rate (25); + f->set_dcp_frame_rate (24); + f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 48000, 0))); + BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 50000); + + f->set_source_frame_rate (25); + f->set_dcp_frame_rate (24); + f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 44100, 0))); + BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 50000); + + /* Check some out-there conversions (not the best) */ + + f->set_source_frame_rate (14.99); + f->set_dcp_frame_rate (25); + f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 16000, 0))); + /* The FrameRateConversion within target_audio_sample_rate should choose to double-up + the 14.99 fps video to 30 and then run it slow at 25. + */ + BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), rint (48000 * 2 * 14.99 / 25)); +} + diff --git a/test/image_test.cc b/test/image_test.cc new file mode 100644 index 000000000..a9ec3042a --- /dev/null +++ b/test/image_test.cc @@ -0,0 +1,99 @@ + +BOOST_AUTO_TEST_CASE (aligned_image_test) +{ + SimpleImage* s = new SimpleImage (PIX_FMT_RGB24, libdcp::Size (50, 50), true); + BOOST_CHECK_EQUAL (s->components(), 1); + /* 160 is 150 aligned to the nearest 32 bytes */ + BOOST_CHECK_EQUAL (s->stride()[0], 160); + BOOST_CHECK_EQUAL (s->line_size()[0], 150); + BOOST_CHECK (s->data()[0]); + BOOST_CHECK (!s->data()[1]); + BOOST_CHECK (!s->data()[2]); + BOOST_CHECK (!s->data()[3]); + + /* copy constructor */ + SimpleImage* t = new SimpleImage (*s); + BOOST_CHECK_EQUAL (t->components(), 1); + BOOST_CHECK_EQUAL (t->stride()[0], 160); + BOOST_CHECK_EQUAL (t->line_size()[0], 150); + BOOST_CHECK (t->data()[0]); + BOOST_CHECK (!t->data()[1]); + BOOST_CHECK (!t->data()[2]); + BOOST_CHECK (!t->data()[3]); + BOOST_CHECK (t->data() != s->data()); + BOOST_CHECK (t->data()[0] != s->data()[0]); + BOOST_CHECK (t->line_size() != s->line_size()); + BOOST_CHECK (t->line_size()[0] == s->line_size()[0]); + BOOST_CHECK (t->stride() != s->stride()); + BOOST_CHECK (t->stride()[0] == s->stride()[0]); + + /* assignment operator */ + SimpleImage* u = new SimpleImage (PIX_FMT_YUV422P, libdcp::Size (150, 150), false); + *u = *s; + BOOST_CHECK_EQUAL (u->components(), 1); + BOOST_CHECK_EQUAL (u->stride()[0], 160); + BOOST_CHECK_EQUAL (u->line_size()[0], 150); + BOOST_CHECK (u->data()[0]); + BOOST_CHECK (!u->data()[1]); + BOOST_CHECK (!u->data()[2]); + BOOST_CHECK (!u->data()[3]); + BOOST_CHECK (u->data() != s->data()); + BOOST_CHECK (u->data()[0] != s->data()[0]); + BOOST_CHECK (u->line_size() != s->line_size()); + BOOST_CHECK (u->line_size()[0] == s->line_size()[0]); + BOOST_CHECK (u->stride() != s->stride()); + BOOST_CHECK (u->stride()[0] == s->stride()[0]); + + delete s; + delete t; + delete u; +} + +BOOST_AUTO_TEST_CASE (compact_image_test) +{ + SimpleImage* s = new SimpleImage (PIX_FMT_RGB24, libdcp::Size (50, 50), false); + BOOST_CHECK_EQUAL (s->components(), 1); + BOOST_CHECK_EQUAL (s->stride()[0], 50 * 3); + BOOST_CHECK_EQUAL (s->line_size()[0], 50 * 3); + BOOST_CHECK (s->data()[0]); + BOOST_CHECK (!s->data()[1]); + BOOST_CHECK (!s->data()[2]); + BOOST_CHECK (!s->data()[3]); + + /* copy constructor */ + SimpleImage* t = new SimpleImage (*s); + BOOST_CHECK_EQUAL (t->components(), 1); + BOOST_CHECK_EQUAL (t->stride()[0], 50 * 3); + BOOST_CHECK_EQUAL (t->line_size()[0], 50 * 3); + BOOST_CHECK (t->data()[0]); + BOOST_CHECK (!t->data()[1]); + BOOST_CHECK (!t->data()[2]); + BOOST_CHECK (!t->data()[3]); + BOOST_CHECK (t->data() != s->data()); + BOOST_CHECK (t->data()[0] != s->data()[0]); + BOOST_CHECK (t->line_size() != s->line_size()); + BOOST_CHECK (t->line_size()[0] == s->line_size()[0]); + BOOST_CHECK (t->stride() != s->stride()); + BOOST_CHECK (t->stride()[0] == s->stride()[0]); + + /* assignment operator */ + SimpleImage* u = new SimpleImage (PIX_FMT_YUV422P, libdcp::Size (150, 150), true); + *u = *s; + BOOST_CHECK_EQUAL (u->components(), 1); + BOOST_CHECK_EQUAL (u->stride()[0], 50 * 3); + BOOST_CHECK_EQUAL (u->line_size()[0], 50 * 3); + BOOST_CHECK (u->data()[0]); + BOOST_CHECK (!u->data()[1]); + BOOST_CHECK (!u->data()[2]); + BOOST_CHECK (!u->data()[3]); + BOOST_CHECK (u->data() != s->data()); + BOOST_CHECK (u->data()[0] != s->data()[0]); + BOOST_CHECK (u->line_size() != s->line_size()); + BOOST_CHECK (u->line_size()[0] == s->line_size()[0]); + BOOST_CHECK (u->stride() != s->stride()); + BOOST_CHECK (u->stride()[0] == s->stride()[0]); + + delete s; + delete t; + delete u; +} diff --git a/test/job_test.cc b/test/job_test.cc new file mode 100644 index 000000000..247d4f756 --- /dev/null +++ b/test/job_test.cc @@ -0,0 +1,64 @@ +/* + Copyright (C) 2012 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +class TestJob : public Job +{ +public: + TestJob (shared_ptr f) + : Job (f) + { + + } + + void set_finished_ok () { + set_state (FINISHED_OK); + } + + void set_finished_error () { + set_state (FINISHED_ERROR); + } + + void run () + { + while (1) { + if (finished ()) { + return; + } + } + } + + string name () const { + return ""; + } +}; + +BOOST_AUTO_TEST_CASE (job_manager_test) +{ + shared_ptr f; + + /* Single job */ + shared_ptr a (new TestJob (f)); + + JobManager::instance()->add (a); + dvdomatic_sleep (1); + BOOST_CHECK_EQUAL (a->running (), true); + a->set_finished_ok (); + dvdomatic_sleep (2); + BOOST_CHECK_EQUAL (a->finished_ok(), true); +} diff --git a/test/make_black_test.cc b/test/make_black_test.cc new file mode 100644 index 000000000..76f38d676 --- /dev/null +++ b/test/make_black_test.cc @@ -0,0 +1,55 @@ +/* + Copyright (C) 2012 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +/* Check that Image::make_black works, and doesn't use values which crash + sws_scale(). +*/ +BOOST_AUTO_TEST_CASE (make_black_test) +{ + libdcp::Size in_size (512, 512); + libdcp::Size out_size (1024, 1024); + + list pix_fmts; + pix_fmts.push_back (AV_PIX_FMT_RGB24); + pix_fmts.push_back (AV_PIX_FMT_YUV420P); + pix_fmts.push_back (AV_PIX_FMT_YUV422P10LE); + pix_fmts.push_back (AV_PIX_FMT_YUV444P9LE); + pix_fmts.push_back (AV_PIX_FMT_YUV444P9BE); + pix_fmts.push_back (AV_PIX_FMT_YUV444P10LE); + pix_fmts.push_back (AV_PIX_FMT_YUV444P10BE); + pix_fmts.push_back (AV_PIX_FMT_UYVY422); + + int N = 0; + for (list::const_iterator i = pix_fmts.begin(); i != pix_fmts.end(); ++i) { + boost::shared_ptr foo (new SimpleImage (*i, in_size, true)); + foo->make_black (); + boost::shared_ptr bar = foo->scale_and_convert_to_rgb (out_size, 0, Scaler::from_id ("bicubic"), true); + + uint8_t* p = bar->data()[0]; + for (int y = 0; y < bar->size().height; ++y) { + uint8_t* q = p; + for (int x = 0; x < bar->line_size()[0]; ++x) { + BOOST_CHECK_EQUAL (*q++, 0); + } + p += bar->stride()[0]; + } + + ++N; + } +} diff --git a/test/pixel_formats_test.cc b/test/pixel_formats_test.cc new file mode 100644 index 000000000..e0f6c4373 --- /dev/null +++ b/test/pixel_formats_test.cc @@ -0,0 +1,77 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +using std::list; +using std::cout; + +struct Case +{ + Case (AVPixelFormat f, int c, int l0, int l1, int l2, float b0, float b1, float b2) + : format(f) + , components(c) + { + lines[0] = l0; + lines[1] = l1; + lines[2] = l2; + bpp[0] = b0; + bpp[1] = b1; + bpp[2] = b2; + } + + AVPixelFormat format; + int components; + int lines[3]; + float bpp[3]; +}; + + +BOOST_AUTO_TEST_CASE (pixel_formats_test) +{ + /* This needs to happen in the first test */ + dvdomatic_setup (); + + list cases; + cases.push_back(Case(AV_PIX_FMT_RGB24, 1, 480, 480, 480, 3, 0, 0 )); + cases.push_back(Case(AV_PIX_FMT_RGBA, 1, 480, 480, 480, 4, 0, 0 )); + cases.push_back(Case(AV_PIX_FMT_YUV420P, 3, 480, 240, 240, 1, 0.5, 0.5)); + cases.push_back(Case(AV_PIX_FMT_YUV422P, 3, 480, 480, 480, 1, 0.5, 0.5)); + cases.push_back(Case(AV_PIX_FMT_YUV422P10LE, 3, 480, 480, 480, 2, 1, 1 )); + cases.push_back(Case(AV_PIX_FMT_YUV422P16LE, 3, 480, 480, 480, 2, 1, 1 )); + cases.push_back(Case(AV_PIX_FMT_UYVY422, 1, 480, 480, 480, 2, 0, 0 )); + cases.push_back(Case(AV_PIX_FMT_YUV444P, 3, 480, 480, 480, 1, 1, 1 )); + cases.push_back(Case(AV_PIX_FMT_YUV444P9BE, 3, 480, 480, 480, 2, 2, 2 )); + cases.push_back(Case(AV_PIX_FMT_YUV444P9LE, 3, 480, 480, 480, 2, 2, 2 )); + cases.push_back(Case(AV_PIX_FMT_YUV444P10BE, 3, 480, 480, 480, 2, 2, 2 )); + cases.push_back(Case(AV_PIX_FMT_YUV444P10LE, 3, 480, 480, 480, 2, 2, 2 )); + + for (list::iterator i = cases.begin(); i != cases.end(); ++i) { + AVFrame* f = av_frame_alloc (); + f->width = 640; + f->height = 480; + f->format = static_cast (i->format); + FrameImage t (f); + BOOST_CHECK_EQUAL(t.components(), i->components); + BOOST_CHECK_EQUAL(t.lines(0), i->lines[0]); + BOOST_CHECK_EQUAL(t.lines(1), i->lines[1]); + BOOST_CHECK_EQUAL(t.lines(2), i->lines[2]); + BOOST_CHECK_EQUAL(t.bytes_per_pixel(0), i->bpp[0]); + BOOST_CHECK_EQUAL(t.bytes_per_pixel(1), i->bpp[1]); + BOOST_CHECK_EQUAL(t.bytes_per_pixel(2), i->bpp[2]); + } +} diff --git a/test/stream_test.cc b/test/stream_test.cc new file mode 100644 index 000000000..b467dc9a2 --- /dev/null +++ b/test/stream_test.cc @@ -0,0 +1,52 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +BOOST_AUTO_TEST_CASE (stream_test) +{ + FFmpegAudioStream a ("ffmpeg 4 44100 1 hello there world", boost::optional (1)); + BOOST_CHECK_EQUAL (a.id(), 4); + BOOST_CHECK_EQUAL (a.sample_rate(), 44100); + BOOST_CHECK_EQUAL (a.channel_layout(), 1); + BOOST_CHECK_EQUAL (a.name(), "hello there world"); + BOOST_CHECK_EQUAL (a.to_string(), "ffmpeg 4 44100 1 hello there world"); + + SndfileStream e ("external 44100 1", boost::optional (1)); + BOOST_CHECK_EQUAL (e.sample_rate(), 44100); + BOOST_CHECK_EQUAL (e.channel_layout(), 1); + BOOST_CHECK_EQUAL (e.to_string(), "external 44100 1"); + + SubtitleStream s ("5 a b c", boost::optional (1)); + BOOST_CHECK_EQUAL (s.id(), 5); + BOOST_CHECK_EQUAL (s.name(), "a b c"); + + shared_ptr ff = audio_stream_factory ("ffmpeg 4 44100 1 hello there world", boost::optional (1)); + shared_ptr cff = dynamic_pointer_cast (ff); + BOOST_CHECK (cff); + BOOST_CHECK_EQUAL (cff->id(), 4); + BOOST_CHECK_EQUAL (cff->sample_rate(), 44100); + BOOST_CHECK_EQUAL (cff->channel_layout(), 1); + BOOST_CHECK_EQUAL (cff->name(), "hello there world"); + BOOST_CHECK_EQUAL (cff->to_string(), "ffmpeg 4 44100 1 hello there world"); + + shared_ptr fe = audio_stream_factory ("external 44100 1", boost::optional (1)); + BOOST_CHECK_EQUAL (fe->sample_rate(), 44100); + BOOST_CHECK_EQUAL (fe->channel_layout(), 1); + BOOST_CHECK_EQUAL (fe->to_string(), "external 44100 1"); +} + diff --git a/test/test.cc b/test/test.cc index 11ca56031..91c876412 100644 --- a/test/test.cc +++ b/test/test.cc @@ -52,14 +52,20 @@ using boost::shared_ptr; using boost::thread; using boost::dynamic_pointer_cast; -void -setup_test_config () +struct TestConfig { - Config::instance()->set_num_local_encoding_threads (1); - Config::instance()->set_servers (vector ()); - Config::instance()->set_server_port (61920); - Config::instance()->set_default_dci_metadata (DCIMetadata ()); -} + TestConfig() + { + dvdomatic_setup(); + + Config::instance()->set_num_local_encoding_threads (1); + Config::instance()->set_servers (vector ()); + Config::instance()->set_server_port (61920); + Config::instance()->set_default_dci_metadata (DCIMetadata ()); + } +}; + +BOOST_GLOBAL_FIXTURE (TestConfig); boost::filesystem::path test_film_dir (string name) @@ -82,819 +88,16 @@ new_test_film (string name) return shared_ptr (new Film (p.string(), false)); } - -/* Check that Image::make_black works, and doesn't use values which crash - sws_scale(). -*/ -BOOST_AUTO_TEST_CASE (make_black_test) -{ - /* This needs to happen in the first test */ - dvdomatic_setup (); - - libdcp::Size in_size (512, 512); - libdcp::Size out_size (1024, 1024); - - list pix_fmts; - pix_fmts.push_back (AV_PIX_FMT_RGB24); - pix_fmts.push_back (AV_PIX_FMT_YUV420P); - pix_fmts.push_back (AV_PIX_FMT_YUV422P10LE); - pix_fmts.push_back (AV_PIX_FMT_YUV444P9LE); - pix_fmts.push_back (AV_PIX_FMT_YUV444P9BE); - pix_fmts.push_back (AV_PIX_FMT_YUV444P10LE); - pix_fmts.push_back (AV_PIX_FMT_YUV444P10BE); - pix_fmts.push_back (AV_PIX_FMT_UYVY422); - - int N = 0; - for (list::const_iterator i = pix_fmts.begin(); i != pix_fmts.end(); ++i) { - boost::shared_ptr foo (new SimpleImage (*i, in_size, true)); - foo->make_black (); - boost::shared_ptr bar = foo->scale_and_convert_to_rgb (out_size, 0, Scaler::from_id ("bicubic"), true); - - uint8_t* p = bar->data()[0]; - for (int y = 0; y < bar->size().height; ++y) { - uint8_t* q = p; - for (int x = 0; x < bar->line_size()[0]; ++x) { - BOOST_CHECK_EQUAL (*q++, 0); - } - p += bar->stride()[0]; - } - - ++N; - } -} - - -struct Case -{ - Case (AVPixelFormat f, int c, int l0, int l1, int l2, float b0, float b1, float b2) - : format(f) - , components(c) - { - lines[0] = l0; - lines[1] = l1; - lines[2] = l2; - bpp[0] = b0; - bpp[1] = b1; - bpp[2] = b2; - } - - AVPixelFormat format; - int components; - int lines[3]; - float bpp[3]; -}; - -BOOST_AUTO_TEST_CASE (pixel_formats_test) -{ - list cases; - cases.push_back(Case(AV_PIX_FMT_RGB24, 1, 480, 480, 480, 3, 0, 0 )); - cases.push_back(Case(AV_PIX_FMT_RGBA, 1, 480, 480, 480, 4, 0, 0 )); - cases.push_back(Case(AV_PIX_FMT_YUV420P, 3, 480, 240, 240, 1, 0.5, 0.5)); - cases.push_back(Case(AV_PIX_FMT_YUV422P, 3, 480, 480, 480, 1, 0.5, 0.5)); - cases.push_back(Case(AV_PIX_FMT_YUV422P10LE, 3, 480, 480, 480, 2, 1, 1 )); - cases.push_back(Case(AV_PIX_FMT_YUV422P16LE, 3, 480, 480, 480, 2, 1, 1 )); - cases.push_back(Case(AV_PIX_FMT_UYVY422, 1, 480, 480, 480, 2, 2, 2 )); - cases.push_back(Case(AV_PIX_FMT_YUV444P, 3, 480, 480, 480, 3, 3, 3 )); - cases.push_back(Case(AV_PIX_FMT_YUV444P9BE, 3, 480, 480, 480, 6, 6, 6 )); - cases.push_back(Case(AV_PIX_FMT_YUV444P9LE, 3, 480, 480, 480, 6, 6, 6 )); - cases.push_back(Case(AV_PIX_FMT_YUV444P10BE, 3, 480, 480, 480, 6, 6, 6 )); - cases.push_back(Case(AV_PIX_FMT_YUV444P10LE, 3, 480, 480, 480, 6, 6, 6 )); - - for (list::iterator i = cases.begin(); i != cases.end(); ++i) { - AVFrame* f = av_frame_alloc (); - f->width = 640; - f->height = 480; - f->format = static_cast (i->format); - FrameImage t (f); - BOOST_CHECK_EQUAL(t.components(), i->components); - BOOST_CHECK_EQUAL(t.lines(0), i->lines[0]); - BOOST_CHECK_EQUAL(t.lines(1), i->lines[1]); - BOOST_CHECK_EQUAL(t.lines(2), i->lines[2]); - BOOST_CHECK_EQUAL(t.bytes_per_pixel(0), i->bpp[0]); - BOOST_CHECK_EQUAL(t.bytes_per_pixel(1), i->bpp[1]); - BOOST_CHECK_EQUAL(t.bytes_per_pixel(2), i->bpp[2]); - } -} - -shared_ptr trimmer_test_last_video; -shared_ptr trimmer_test_last_audio; - -void -trimmer_test_video_helper (shared_ptr image, bool, shared_ptr) -{ - trimmer_test_last_video = image; -} - -void -trimmer_test_audio_helper (shared_ptr audio) -{ - trimmer_test_last_audio = audio; -} - -BOOST_AUTO_TEST_CASE (trimmer_passthrough_test) -{ - Trimmer trimmer (shared_ptr (), 0, 0, 200, 48000, 25, 25); - trimmer.Video.connect (bind (&trimmer_test_video_helper, _1, _2, _3)); - trimmer.Audio.connect (bind (&trimmer_test_audio_helper, _1)); - - shared_ptr video (new SimpleImage (PIX_FMT_RGB24, libdcp::Size (1998, 1080), true)); - shared_ptr audio (new AudioBuffers (6, 42 * 1920)); - - trimmer.process_video (video, false, shared_ptr ()); - trimmer.process_audio (audio); - - BOOST_CHECK_EQUAL (video.get(), trimmer_test_last_video.get()); - BOOST_CHECK_EQUAL (audio.get(), trimmer_test_last_audio.get()); - BOOST_CHECK_EQUAL (audio->frames(), trimmer_test_last_audio->frames()); -} - - -/** Test the audio handling of the Trimmer */ -BOOST_AUTO_TEST_CASE (trimmer_audio_test) -{ - Trimmer trimmer (shared_ptr (), 25, 75, 200, 48000, 25, 25); - - trimmer.Audio.connect (bind (&trimmer_test_audio_helper, _1)); - - /* 21 video frames-worth of audio frames; should be completely stripped */ - trimmer_test_last_audio.reset (); - shared_ptr audio (new AudioBuffers (6, 21 * 1920)); - trimmer.process_audio (audio); - BOOST_CHECK (trimmer_test_last_audio == 0); - - /* 42 more video frames-worth, 4 should be stripped from the start */ - audio.reset (new AudioBuffers (6, 42 * 1920)); - trimmer.process_audio (audio); - BOOST_CHECK (trimmer_test_last_audio); - BOOST_CHECK_EQUAL (trimmer_test_last_audio->frames(), 38 * 1920); - - /* 42 more video frames-worth, should be kept as-is */ - trimmer_test_last_audio.reset (); - audio.reset (new AudioBuffers (6, 42 * 1920)); - trimmer.process_audio (audio); - BOOST_CHECK (trimmer_test_last_audio); - BOOST_CHECK_EQUAL (trimmer_test_last_audio->frames(), 42 * 1920); - - /* 25 more video frames-worth, 5 should be trimmed from the end */ - trimmer_test_last_audio.reset (); - audio.reset (new AudioBuffers (6, 25 * 1920)); - trimmer.process_audio (audio); - BOOST_CHECK (trimmer_test_last_audio); - BOOST_CHECK_EQUAL (trimmer_test_last_audio->frames(), 20 * 1920); - - /* Now some more; all should be trimmed */ - trimmer_test_last_audio.reset (); - audio.reset (new AudioBuffers (6, 100 * 1920)); - trimmer.process_audio (audio); - BOOST_CHECK (trimmer_test_last_audio == 0); -} - - -BOOST_AUTO_TEST_CASE (film_metadata_test) -{ - setup_test_config (); - - string const test_film = "build/test/film_metadata_test"; - - if (boost::filesystem::exists (test_film)) { - boost::filesystem::remove_all (test_film); - } - - BOOST_CHECK_THROW (new Film (test_film, true), OpenFileError); - - shared_ptr f (new Film (test_film, false)); - f->_dci_date = boost::gregorian::from_undelimited_string ("20130211"); - BOOST_CHECK (f->format() == 0); - BOOST_CHECK (f->dcp_content_type() == 0); - BOOST_CHECK (f->filters ().empty()); - - f->set_name ("fred"); - BOOST_CHECK_THROW (f->set_content ("jim"), OpenFileError); - f->set_dcp_content_type (DCPContentType::from_pretty_name ("Short")); - f->set_format (Format::from_nickname ("Flat")); - f->set_left_crop (1); - f->set_right_crop (2); - f->set_top_crop (3); - f->set_bottom_crop (4); - vector f_filters; - f_filters.push_back (Filter::from_id ("pphb")); - f_filters.push_back (Filter::from_id ("unsharp")); - f->set_filters (f_filters); - f->set_trim_start (42); - f->set_trim_end (99); - f->set_dcp_ab (true); - f->write_metadata (); - - stringstream s; - s << "diff -u test/metadata.ref " << test_film << "/metadata"; - BOOST_CHECK_EQUAL (::system (s.str().c_str ()), 0); - - shared_ptr g (new Film (test_film, true)); - - BOOST_CHECK_EQUAL (g->name(), "fred"); - BOOST_CHECK_EQUAL (g->dcp_content_type(), DCPContentType::from_pretty_name ("Short")); - BOOST_CHECK_EQUAL (g->format(), Format::from_nickname ("Flat")); - BOOST_CHECK_EQUAL (g->crop().left, 1); - BOOST_CHECK_EQUAL (g->crop().right, 2); - BOOST_CHECK_EQUAL (g->crop().top, 3); - BOOST_CHECK_EQUAL (g->crop().bottom, 4); - vector g_filters = g->filters (); - BOOST_CHECK_EQUAL (g_filters.size(), 2); - BOOST_CHECK_EQUAL (g_filters.front(), Filter::from_id ("pphb")); - BOOST_CHECK_EQUAL (g_filters.back(), Filter::from_id ("unsharp")); - BOOST_CHECK_EQUAL (g->trim_start(), 42); - BOOST_CHECK_EQUAL (g->trim_end(), 99); - BOOST_CHECK_EQUAL (g->dcp_ab(), true); - - g->write_metadata (); - BOOST_CHECK_EQUAL (::system (s.str().c_str ()), 0); -} - -BOOST_AUTO_TEST_CASE (stream_test) -{ - FFmpegAudioStream a ("ffmpeg 4 44100 1 hello there world", boost::optional (1)); - BOOST_CHECK_EQUAL (a.id(), 4); - BOOST_CHECK_EQUAL (a.sample_rate(), 44100); - BOOST_CHECK_EQUAL (a.channel_layout(), 1); - BOOST_CHECK_EQUAL (a.name(), "hello there world"); - BOOST_CHECK_EQUAL (a.to_string(), "ffmpeg 4 44100 1 hello there world"); - - SndfileStream e ("external 44100 1", boost::optional (1)); - BOOST_CHECK_EQUAL (e.sample_rate(), 44100); - BOOST_CHECK_EQUAL (e.channel_layout(), 1); - BOOST_CHECK_EQUAL (e.to_string(), "external 44100 1"); - - SubtitleStream s ("5 a b c", boost::optional (1)); - BOOST_CHECK_EQUAL (s.id(), 5); - BOOST_CHECK_EQUAL (s.name(), "a b c"); - - shared_ptr ff = audio_stream_factory ("ffmpeg 4 44100 1 hello there world", boost::optional (1)); - shared_ptr cff = dynamic_pointer_cast (ff); - BOOST_CHECK (cff); - BOOST_CHECK_EQUAL (cff->id(), 4); - BOOST_CHECK_EQUAL (cff->sample_rate(), 44100); - BOOST_CHECK_EQUAL (cff->channel_layout(), 1); - BOOST_CHECK_EQUAL (cff->name(), "hello there world"); - BOOST_CHECK_EQUAL (cff->to_string(), "ffmpeg 4 44100 1 hello there world"); - - shared_ptr fe = audio_stream_factory ("external 44100 1", boost::optional (1)); - BOOST_CHECK_EQUAL (fe->sample_rate(), 44100); - BOOST_CHECK_EQUAL (fe->channel_layout(), 1); - BOOST_CHECK_EQUAL (fe->to_string(), "external 44100 1"); -} - -BOOST_AUTO_TEST_CASE (format_test) -{ - Format::setup_formats (); - - Format const * f = Format::from_nickname ("Flat"); - BOOST_CHECK (f); - BOOST_CHECK_EQUAL (f->dcp_size().width, 1998); - BOOST_CHECK_EQUAL (f->dcp_size().height, 1080); - - f = Format::from_nickname ("Scope"); - BOOST_CHECK (f); - BOOST_CHECK_EQUAL (f->dcp_size().width, 2048); - BOOST_CHECK_EQUAL (f->dcp_size().height, 858); -} - -/* Test VariableFormat-based scaling of content */ -BOOST_AUTO_TEST_CASE (scaling_test) -{ - shared_ptr film (new Film (test_film_dir ("scaling_test").string(), false)); - - /* 4:3 ratio */ - film->set_size (libdcp::Size (320, 240)); - - /* This format should preserve aspect ratio of the source */ - Format const * format = Format::from_id ("var-185"); - - /* We should have enough padding that the result is 4:3, - which would be 1440 pixels. - */ - BOOST_CHECK_EQUAL (format->dcp_padding (film), (1998 - 1440) / 2); - - /* This crops it to 1.291666667 */ - film->set_left_crop (5); - film->set_right_crop (5); - - /* We should now have enough padding that the result is 1.29166667, - which would be 1395 pixels. - */ - BOOST_CHECK_EQUAL (format->dcp_padding (film), rint ((1998 - 1395) / 2.0)); -} - -BOOST_AUTO_TEST_CASE (util_test) -{ - string t = "Hello this is a string \"with quotes\" and indeed without them"; - vector b = split_at_spaces_considering_quotes (t); - vector::iterator i = b.begin (); - BOOST_CHECK_EQUAL (*i++, "Hello"); - BOOST_CHECK_EQUAL (*i++, "this"); - BOOST_CHECK_EQUAL (*i++, "is"); - BOOST_CHECK_EQUAL (*i++, "a"); - BOOST_CHECK_EQUAL (*i++, "string"); - BOOST_CHECK_EQUAL (*i++, "with quotes"); - BOOST_CHECK_EQUAL (*i++, "and"); - BOOST_CHECK_EQUAL (*i++, "indeed"); - BOOST_CHECK_EQUAL (*i++, "without"); - BOOST_CHECK_EQUAL (*i++, "them"); -} - -class NullLog : public Log -{ -public: - void do_log (string) {} -}; - -BOOST_AUTO_TEST_CASE (md5_digest_test) -{ - string const t = md5_digest ("test/md5.test"); - BOOST_CHECK_EQUAL (t, "15058685ba99decdc4398c7634796eb0"); - - BOOST_CHECK_THROW (md5_digest ("foobar"), OpenFileError); -} - -BOOST_AUTO_TEST_CASE (paths_test) -{ - shared_ptr f = new_test_film ("paths_test"); - f->set_directory ("build/test/a/b/c/d/e"); - - f->_content = "/foo/bar/baz"; - BOOST_CHECK_EQUAL (f->content_path(), "/foo/bar/baz"); - f->_content = "foo/bar/baz"; - BOOST_CHECK_EQUAL (f->content_path(), "build/test/a/b/c/d/e/foo/bar/baz"); -} - -void -do_remote_encode (shared_ptr frame, ServerDescription* description, shared_ptr locally_encoded) -{ - shared_ptr remotely_encoded; - BOOST_CHECK_NO_THROW (remotely_encoded = frame->encode_remotely (description)); - BOOST_CHECK (remotely_encoded); - - BOOST_CHECK_EQUAL (locally_encoded->size(), remotely_encoded->size()); - BOOST_CHECK (memcmp (locally_encoded->data(), remotely_encoded->data(), locally_encoded->size()) == 0); -} - -BOOST_AUTO_TEST_CASE (client_server_test) -{ - shared_ptr image (new SimpleImage (PIX_FMT_RGB24, libdcp::Size (1998, 1080), true)); - uint8_t* p = image->data()[0]; - - for (int y = 0; y < 1080; ++y) { - uint8_t* q = p; - for (int x = 0; x < 1998; ++x) { - *q++ = x % 256; - *q++ = y % 256; - *q++ = (x + y) % 256; - } - p += image->stride()[0]; - } - - shared_ptr sub_image (new SimpleImage (PIX_FMT_RGBA, libdcp::Size (100, 200), true)); - p = sub_image->data()[0]; - for (int y = 0; y < 200; ++y) { - uint8_t* q = p; - for (int x = 0; x < 100; ++x) { - *q++ = y % 256; - *q++ = x % 256; - *q++ = (x + y) % 256; - *q++ = 1; - } - p += sub_image->stride()[0]; - } - - shared_ptr subtitle (new Subtitle (Position (50, 60), sub_image)); - - shared_ptr log (new FileLog ("build/test/client_server_test.log")); - - shared_ptr frame ( - new DCPVideoFrame ( - image, - subtitle, - libdcp::Size (1998, 1080), - 0, - 0, - 1, - Scaler::from_id ("bicubic"), - 0, - 24, - "", - 0, - 200000000, - log - ) - ); - - shared_ptr locally_encoded = frame->encode_locally (); - BOOST_ASSERT (locally_encoded); - - Server* server = new Server (log); - - new thread (boost::bind (&Server::run, server, 2)); - - /* Let the server get itself ready */ - dvdomatic_sleep (1); - - ServerDescription description ("localhost", 2); - - list threads; - for (int i = 0; i < 8; ++i) { - threads.push_back (new thread (boost::bind (do_remote_encode, frame, &description, locally_encoded))); - } - - for (list::iterator i = threads.begin(); i != threads.end(); ++i) { - (*i)->join (); - } - - for (list::iterator i = threads.begin(); i != threads.end(); ++i) { - delete *i; - } -} - -BOOST_AUTO_TEST_CASE (make_dcp_test) -{ - shared_ptr film = new_test_film ("make_dcp_test"); - film->set_name ("test_film2"); - film->set_content ("../../../test/test.mp4"); - film->set_format (Format::from_nickname ("Flat")); - film->set_dcp_content_type (DCPContentType::from_pretty_name ("Test")); - film->make_dcp (); - film->write_metadata (); - - while (JobManager::instance()->work_to_do ()) { - dvdomatic_sleep (1); - } - - BOOST_CHECK_EQUAL (JobManager::instance()->errors(), false); -} - -/** Test Film::have_dcp(). Requires the output from make_dcp_test above */ -BOOST_AUTO_TEST_CASE (have_dcp_test) -{ - boost::filesystem::path p = test_film_dir ("make_dcp_test"); - Film f (p.string ()); - BOOST_CHECK (f.have_dcp()); - - p /= f.dcp_name(); - p /= f.dcp_video_mxf_filename(); - boost::filesystem::remove (p); - BOOST_CHECK (!f.have_dcp ()); -} - -BOOST_AUTO_TEST_CASE (make_dcp_with_range_test) -{ - shared_ptr film = new_test_film ("make_dcp_with_range_test"); - film->set_name ("test_film3"); - film->set_content ("../../../test/test.mp4"); - film->examine_content (); - film->set_format (Format::from_nickname ("Flat")); - film->set_dcp_content_type (DCPContentType::from_pretty_name ("Test")); - film->set_trim_end (42); - film->make_dcp (); - - while (JobManager::instance()->work_to_do() && !JobManager::instance()->errors()) { - dvdomatic_sleep (1); - } - - BOOST_CHECK_EQUAL (JobManager::instance()->errors(), false); -} - -/* Test best_dcp_frame_rate and FrameRateConversion */ -BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test) -{ - /* Run some tests with a limited range of allowed rates */ - - std::list afr; - afr.push_back (24); - afr.push_back (25); - afr.push_back (30); - Config::instance()->set_allowed_dcp_frame_rates (afr); - - int best = best_dcp_frame_rate (60); - FrameRateConversion frc = FrameRateConversion (60, best); - BOOST_CHECK_EQUAL (best, 30); - BOOST_CHECK_EQUAL (frc.skip, true); - BOOST_CHECK_EQUAL (frc.repeat, false); - BOOST_CHECK_EQUAL (frc.change_speed, false); - - best = best_dcp_frame_rate (50); - frc = FrameRateConversion (50, best); - BOOST_CHECK_EQUAL (best, 25); - BOOST_CHECK_EQUAL (frc.skip, true); - BOOST_CHECK_EQUAL (frc.repeat, false); - BOOST_CHECK_EQUAL (frc.change_speed, false); - - best = best_dcp_frame_rate (48); - frc = FrameRateConversion (48, best); - BOOST_CHECK_EQUAL (best, 24); - BOOST_CHECK_EQUAL (frc.skip, true); - BOOST_CHECK_EQUAL (frc.repeat, false); - BOOST_CHECK_EQUAL (frc.change_speed, false); - - best = best_dcp_frame_rate (30); - frc = FrameRateConversion (30, best); - BOOST_CHECK_EQUAL (best, 30); - BOOST_CHECK_EQUAL (frc.skip, false); - BOOST_CHECK_EQUAL (frc.repeat, false); - BOOST_CHECK_EQUAL (frc.change_speed, false); - - best = best_dcp_frame_rate (29.97); - frc = FrameRateConversion (29.97, best); - BOOST_CHECK_EQUAL (best, 30); - BOOST_CHECK_EQUAL (frc.skip, false); - BOOST_CHECK_EQUAL (frc.repeat, false); - BOOST_CHECK_EQUAL (frc.change_speed, true); - - best = best_dcp_frame_rate (25); - frc = FrameRateConversion (25, best); - BOOST_CHECK_EQUAL (best, 25); - BOOST_CHECK_EQUAL (frc.skip, false); - BOOST_CHECK_EQUAL (frc.repeat, false); - BOOST_CHECK_EQUAL (frc.change_speed, false); - - best = best_dcp_frame_rate (24); - frc = FrameRateConversion (24, best); - BOOST_CHECK_EQUAL (best, 24); - BOOST_CHECK_EQUAL (frc.skip, false); - BOOST_CHECK_EQUAL (frc.repeat, false); - BOOST_CHECK_EQUAL (frc.change_speed, false); - - best = best_dcp_frame_rate (14.5); - frc = FrameRateConversion (14.5, best); - BOOST_CHECK_EQUAL (best, 30); - BOOST_CHECK_EQUAL (frc.skip, false); - BOOST_CHECK_EQUAL (frc.repeat, true); - BOOST_CHECK_EQUAL (frc.change_speed, true); - - best = best_dcp_frame_rate (12.6); - frc = FrameRateConversion (12.6, best); - BOOST_CHECK_EQUAL (best, 25); - BOOST_CHECK_EQUAL (frc.skip, false); - BOOST_CHECK_EQUAL (frc.repeat, true); - BOOST_CHECK_EQUAL (frc.change_speed, true); - - best = best_dcp_frame_rate (12.4); - frc = FrameRateConversion (12.4, best); - BOOST_CHECK_EQUAL (best, 25); - BOOST_CHECK_EQUAL (frc.skip, false); - BOOST_CHECK_EQUAL (frc.repeat, true); - BOOST_CHECK_EQUAL (frc.change_speed, true); - - best = best_dcp_frame_rate (12); - frc = FrameRateConversion (12, best); - BOOST_CHECK_EQUAL (best, 24); - BOOST_CHECK_EQUAL (frc.skip, false); - BOOST_CHECK_EQUAL (frc.repeat, true); - BOOST_CHECK_EQUAL (frc.change_speed, false); - - /* Now add some more rates and see if it will use them - in preference to skip/repeat. - */ - - afr.push_back (48); - afr.push_back (50); - afr.push_back (60); - Config::instance()->set_allowed_dcp_frame_rates (afr); - - best = best_dcp_frame_rate (60); - frc = FrameRateConversion (60, best); - BOOST_CHECK_EQUAL (best, 60); - BOOST_CHECK_EQUAL (frc.skip, false); - BOOST_CHECK_EQUAL (frc.repeat, false); - BOOST_CHECK_EQUAL (frc.change_speed, false); - - best = best_dcp_frame_rate (50); - frc = FrameRateConversion (50, best); - BOOST_CHECK_EQUAL (best, 50); - BOOST_CHECK_EQUAL (frc.skip, false); - BOOST_CHECK_EQUAL (frc.repeat, false); - BOOST_CHECK_EQUAL (frc.change_speed, false); - - best = best_dcp_frame_rate (48); - frc = FrameRateConversion (48, best); - BOOST_CHECK_EQUAL (best, 48); - BOOST_CHECK_EQUAL (frc.skip, false); - BOOST_CHECK_EQUAL (frc.repeat, false); - BOOST_CHECK_EQUAL (frc.change_speed, false); - - /* Check some out-there conversions (not the best) */ - - frc = FrameRateConversion (14.99, 24); - BOOST_CHECK_EQUAL (frc.skip, false); - BOOST_CHECK_EQUAL (frc.repeat, true); - BOOST_CHECK_EQUAL (frc.change_speed, true); - - /* Check some conversions with limited DCP targets */ - - afr.clear (); - afr.push_back (24); - Config::instance()->set_allowed_dcp_frame_rates (afr); - - best = best_dcp_frame_rate (25); - frc = FrameRateConversion (25, best); - BOOST_CHECK_EQUAL (best, 24); - BOOST_CHECK_EQUAL (frc.skip, false); - BOOST_CHECK_EQUAL (frc.repeat, false); - BOOST_CHECK_EQUAL (frc.change_speed, true); -} - -BOOST_AUTO_TEST_CASE (audio_sampling_rate_test) -{ - std::list afr; - afr.push_back (24); - afr.push_back (25); - afr.push_back (30); - Config::instance()->set_allowed_dcp_frame_rates (afr); - - shared_ptr f = new_test_film ("audio_sampling_rate_test"); - f->set_source_frame_rate (24); - f->set_dcp_frame_rate (24); - - f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 48000, 0))); - BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 48000); - - f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 44100, 0))); - BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 48000); - - f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 80000, 0))); - BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 96000); - - f->set_source_frame_rate (23.976); - f->set_dcp_frame_rate (best_dcp_frame_rate (23.976)); - f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 48000, 0))); - BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 47952); - - f->set_source_frame_rate (29.97); - f->set_dcp_frame_rate (best_dcp_frame_rate (29.97)); - BOOST_CHECK_EQUAL (f->dcp_frame_rate (), 30); - f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 48000, 0))); - BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 47952); - - f->set_source_frame_rate (25); - f->set_dcp_frame_rate (24); - f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 48000, 0))); - BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 50000); - - f->set_source_frame_rate (25); - f->set_dcp_frame_rate (24); - f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 44100, 0))); - BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 50000); - - /* Check some out-there conversions (not the best) */ - - f->set_source_frame_rate (14.99); - f->set_dcp_frame_rate (25); - f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 16000, 0))); - /* The FrameRateConversion within target_audio_sample_rate should choose to double-up - the 14.99 fps video to 30 and then run it slow at 25. - */ - BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), rint (48000 * 2 * 14.99 / 25)); -} - -class TestJob : public Job -{ -public: - TestJob (shared_ptr f) - : Job (f) - { - - } - - void set_finished_ok () { - set_state (FINISHED_OK); - } - - void set_finished_error () { - set_state (FINISHED_ERROR); - } - - void run () - { - while (1) { - if (finished ()) { - return; - } - } - } - - string name () const { - return ""; - } -}; - -BOOST_AUTO_TEST_CASE (job_manager_test) -{ - shared_ptr f; - - /* Single job */ - shared_ptr a (new TestJob (f)); - - JobManager::instance()->add (a); - dvdomatic_sleep (1); - BOOST_CHECK_EQUAL (a->running (), true); - a->set_finished_ok (); - dvdomatic_sleep (2); - BOOST_CHECK_EQUAL (a->finished_ok(), true); -} - -BOOST_AUTO_TEST_CASE (compact_image_test) -{ - SimpleImage* s = new SimpleImage (PIX_FMT_RGB24, libdcp::Size (50, 50), false); - BOOST_CHECK_EQUAL (s->components(), 1); - BOOST_CHECK_EQUAL (s->stride()[0], 50 * 3); - BOOST_CHECK_EQUAL (s->line_size()[0], 50 * 3); - BOOST_CHECK (s->data()[0]); - BOOST_CHECK (!s->data()[1]); - BOOST_CHECK (!s->data()[2]); - BOOST_CHECK (!s->data()[3]); - - /* copy constructor */ - SimpleImage* t = new SimpleImage (*s); - BOOST_CHECK_EQUAL (t->components(), 1); - BOOST_CHECK_EQUAL (t->stride()[0], 50 * 3); - BOOST_CHECK_EQUAL (t->line_size()[0], 50 * 3); - BOOST_CHECK (t->data()[0]); - BOOST_CHECK (!t->data()[1]); - BOOST_CHECK (!t->data()[2]); - BOOST_CHECK (!t->data()[3]); - BOOST_CHECK (t->data() != s->data()); - BOOST_CHECK (t->data()[0] != s->data()[0]); - BOOST_CHECK (t->line_size() != s->line_size()); - BOOST_CHECK (t->line_size()[0] == s->line_size()[0]); - BOOST_CHECK (t->stride() != s->stride()); - BOOST_CHECK (t->stride()[0] == s->stride()[0]); - - /* assignment operator */ - SimpleImage* u = new SimpleImage (PIX_FMT_YUV422P, libdcp::Size (150, 150), true); - *u = *s; - BOOST_CHECK_EQUAL (u->components(), 1); - BOOST_CHECK_EQUAL (u->stride()[0], 50 * 3); - BOOST_CHECK_EQUAL (u->line_size()[0], 50 * 3); - BOOST_CHECK (u->data()[0]); - BOOST_CHECK (!u->data()[1]); - BOOST_CHECK (!u->data()[2]); - BOOST_CHECK (!u->data()[3]); - BOOST_CHECK (u->data() != s->data()); - BOOST_CHECK (u->data()[0] != s->data()[0]); - BOOST_CHECK (u->line_size() != s->line_size()); - BOOST_CHECK (u->line_size()[0] == s->line_size()[0]); - BOOST_CHECK (u->stride() != s->stride()); - BOOST_CHECK (u->stride()[0] == s->stride()[0]); - - delete s; - delete t; - delete u; -} - -BOOST_AUTO_TEST_CASE (aligned_image_test) -{ - SimpleImage* s = new SimpleImage (PIX_FMT_RGB24, libdcp::Size (50, 50), true); - BOOST_CHECK_EQUAL (s->components(), 1); - /* 160 is 150 aligned to the nearest 32 bytes */ - BOOST_CHECK_EQUAL (s->stride()[0], 160); - BOOST_CHECK_EQUAL (s->line_size()[0], 150); - BOOST_CHECK (s->data()[0]); - BOOST_CHECK (!s->data()[1]); - BOOST_CHECK (!s->data()[2]); - BOOST_CHECK (!s->data()[3]); - - /* copy constructor */ - SimpleImage* t = new SimpleImage (*s); - BOOST_CHECK_EQUAL (t->components(), 1); - BOOST_CHECK_EQUAL (t->stride()[0], 160); - BOOST_CHECK_EQUAL (t->line_size()[0], 150); - BOOST_CHECK (t->data()[0]); - BOOST_CHECK (!t->data()[1]); - BOOST_CHECK (!t->data()[2]); - BOOST_CHECK (!t->data()[3]); - BOOST_CHECK (t->data() != s->data()); - BOOST_CHECK (t->data()[0] != s->data()[0]); - BOOST_CHECK (t->line_size() != s->line_size()); - BOOST_CHECK (t->line_size()[0] == s->line_size()[0]); - BOOST_CHECK (t->stride() != s->stride()); - BOOST_CHECK (t->stride()[0] == s->stride()[0]); - - /* assignment operator */ - SimpleImage* u = new SimpleImage (PIX_FMT_YUV422P, libdcp::Size (150, 150), false); - *u = *s; - BOOST_CHECK_EQUAL (u->components(), 1); - BOOST_CHECK_EQUAL (u->stride()[0], 160); - BOOST_CHECK_EQUAL (u->line_size()[0], 150); - BOOST_CHECK (u->data()[0]); - BOOST_CHECK (!u->data()[1]); - BOOST_CHECK (!u->data()[2]); - BOOST_CHECK (!u->data()[3]); - BOOST_CHECK (u->data() != s->data()); - BOOST_CHECK (u->data()[0] != s->data()[0]); - BOOST_CHECK (u->line_size() != s->line_size()); - BOOST_CHECK (u->line_size()[0] == s->line_size()[0]); - BOOST_CHECK (u->stride() != s->stride()); - BOOST_CHECK (u->stride()[0] == s->stride()[0]); - - delete s; - delete t; - delete u; -} - +#include "pixel_formats_test.cc" +#include "make_black_test.cc" +#include "trimmer_test.cc" +#include "film_metadata_test.cc" +#include "stream_test.cc" +#include "format_test.cc" +#include "util_test.cc" +#include "film_test.cc" +#include "dcp_test.cc" +#include "frame_rate_test.cc" +#include "job_test.cc" +#include "client_server_test.cc" +#include "image_test.cc" diff --git a/test/trimmer_test.cc b/test/trimmer_test.cc new file mode 100644 index 000000000..605f7d1b2 --- /dev/null +++ b/test/trimmer_test.cc @@ -0,0 +1,95 @@ +/* + Copyright (C) 2012 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +using boost::shared_ptr; + +shared_ptr trimmer_test_last_video; +shared_ptr trimmer_test_last_audio; + +void +trimmer_test_video_helper (shared_ptr image, bool, shared_ptr) +{ + trimmer_test_last_video = image; +} + +void +trimmer_test_audio_helper (shared_ptr audio) +{ + trimmer_test_last_audio = audio; +} + +BOOST_AUTO_TEST_CASE (trimmer_passthrough_test) +{ + Trimmer trimmer (shared_ptr (), 0, 0, 200, 48000, 25, 25); + trimmer.Video.connect (bind (&trimmer_test_video_helper, _1, _2, _3)); + trimmer.Audio.connect (bind (&trimmer_test_audio_helper, _1)); + + shared_ptr video (new SimpleImage (PIX_FMT_RGB24, libdcp::Size (1998, 1080), true)); + shared_ptr audio (new AudioBuffers (6, 42 * 1920)); + + trimmer.process_video (video, false, shared_ptr ()); + trimmer.process_audio (audio); + + BOOST_CHECK_EQUAL (video.get(), trimmer_test_last_video.get()); + BOOST_CHECK_EQUAL (audio.get(), trimmer_test_last_audio.get()); + BOOST_CHECK_EQUAL (audio->frames(), trimmer_test_last_audio->frames()); +} + + +/** Test the audio handling of the Trimmer */ +BOOST_AUTO_TEST_CASE (trimmer_audio_test) +{ + Trimmer trimmer (shared_ptr (), 25, 75, 200, 48000, 25, 25); + + trimmer.Audio.connect (bind (&trimmer_test_audio_helper, _1)); + + /* 21 video frames-worth of audio frames; should be completely stripped */ + trimmer_test_last_audio.reset (); + shared_ptr audio (new AudioBuffers (6, 21 * 1920)); + trimmer.process_audio (audio); + BOOST_CHECK (trimmer_test_last_audio == 0); + + /* 42 more video frames-worth, 4 should be stripped from the start */ + audio.reset (new AudioBuffers (6, 42 * 1920)); + trimmer.process_audio (audio); + BOOST_CHECK (trimmer_test_last_audio); + BOOST_CHECK_EQUAL (trimmer_test_last_audio->frames(), 38 * 1920); + + /* 42 more video frames-worth, should be kept as-is */ + trimmer_test_last_audio.reset (); + audio.reset (new AudioBuffers (6, 42 * 1920)); + trimmer.process_audio (audio); + BOOST_CHECK (trimmer_test_last_audio); + BOOST_CHECK_EQUAL (trimmer_test_last_audio->frames(), 42 * 1920); + + /* 25 more video frames-worth, 5 should be trimmed from the end */ + trimmer_test_last_audio.reset (); + audio.reset (new AudioBuffers (6, 25 * 1920)); + trimmer.process_audio (audio); + BOOST_CHECK (trimmer_test_last_audio); + BOOST_CHECK_EQUAL (trimmer_test_last_audio->frames(), 20 * 1920); + + /* Now some more; all should be trimmed */ + trimmer_test_last_audio.reset (); + audio.reset (new AudioBuffers (6, 100 * 1920)); + trimmer.process_audio (audio); + BOOST_CHECK (trimmer_test_last_audio == 0); +} + + diff --git a/test/util_test.cc b/test/util_test.cc new file mode 100644 index 000000000..18c24ac3a --- /dev/null +++ b/test/util_test.cc @@ -0,0 +1,43 @@ +/* + Copyright (C) 2012 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +BOOST_AUTO_TEST_CASE (util_test) +{ + string t = "Hello this is a string \"with quotes\" and indeed without them"; + vector b = split_at_spaces_considering_quotes (t); + vector::iterator i = b.begin (); + BOOST_CHECK_EQUAL (*i++, "Hello"); + BOOST_CHECK_EQUAL (*i++, "this"); + BOOST_CHECK_EQUAL (*i++, "is"); + BOOST_CHECK_EQUAL (*i++, "a"); + BOOST_CHECK_EQUAL (*i++, "string"); + BOOST_CHECK_EQUAL (*i++, "with quotes"); + BOOST_CHECK_EQUAL (*i++, "and"); + BOOST_CHECK_EQUAL (*i++, "indeed"); + BOOST_CHECK_EQUAL (*i++, "without"); + BOOST_CHECK_EQUAL (*i++, "them"); +} + +BOOST_AUTO_TEST_CASE (md5_digest_test) +{ + string const t = md5_digest ("test/md5.test"); + BOOST_CHECK_EQUAL (t, "15058685ba99decdc4398c7634796eb0"); + + BOOST_CHECK_THROW (md5_digest ("foobar"), OpenFileError); +} -- cgit v1.2.3 From 36fec15b78e6d5017c9f631bd2e828aa9ca91aa1 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 1 May 2013 22:24:08 +0100 Subject: Missing format for make_black. --- src/lib/image.cc | 12 +++++++++--- test/make_black_test.cc | 1 + 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/lib/image.cc b/src/lib/image.cc index 0b887ea62..b97291585 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -274,12 +274,12 @@ Image::make_black () { /* U/V black value for 8-bit colour */ static uint8_t const eight_bit_uv = (1 << 7) - 1; - /* U/V black value for 9-bit colour */ static uint16_t const nine_bit_uv = (1 << 8) - 1; - /* U/V black value for 10-bit colour */ static uint16_t const ten_bit_uv = (1 << 9) - 1; + /* U/V black value for 16-bit colour */ + static uint16_t const sixteen_bit_uv = (1 << 15) - 1; switch (_pixel_format) { case PIX_FMT_YUV420P: @@ -304,11 +304,17 @@ Image::make_black () case PIX_FMT_YUV444P10LE: yuv_16_black (ten_bit_uv); break; + + case PIX_FMT_YUV422P16LE: + case PIX_FMT_YUV444P16LE: + yuv_16_black (sixteen_bit_uv); + break; case PIX_FMT_YUV444P10BE: case PIX_FMT_YUV422P10BE: yuv_16_black (swap_16 (ten_bit_uv)); - + break; + case PIX_FMT_RGB24: memset (data()[0], 0, lines(0) * stride()[0]); break; diff --git a/test/make_black_test.cc b/test/make_black_test.cc index 76f38d676..3c0b979ff 100644 --- a/test/make_black_test.cc +++ b/test/make_black_test.cc @@ -29,6 +29,7 @@ BOOST_AUTO_TEST_CASE (make_black_test) pix_fmts.push_back (AV_PIX_FMT_RGB24); pix_fmts.push_back (AV_PIX_FMT_YUV420P); pix_fmts.push_back (AV_PIX_FMT_YUV422P10LE); + pix_fmts.push_back (AV_PIX_FMT_YUV422P16LE); pix_fmts.push_back (AV_PIX_FMT_YUV444P9LE); pix_fmts.push_back (AV_PIX_FMT_YUV444P9BE); pix_fmts.push_back (AV_PIX_FMT_YUV444P10LE); -- cgit v1.2.3 From fdd63a4c9925f0339089dce3a52f0d6ed0d97880 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 2 May 2013 22:15:32 +0100 Subject: Use newer format to specify filter graphs; don't filter unless necessary; fix tiny memory leak. --- src/lib/ffmpeg_decoder.cc | 45 +++++++++++++++++++++++++++------------------ src/lib/filter_graph.cc | 19 +++++++++---------- src/lib/image.cc | 8 ++++++-- src/lib/image.h | 3 ++- test/pixel_formats_test.cc | 2 +- 5 files changed, 45 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 8e09810cb..cd68e5294 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -500,32 +500,41 @@ FFmpegDecoder::set_subtitle_stream (shared_ptr s) void FFmpegDecoder::filter_and_emit_video () { - boost::mutex::scoped_lock lm (_filter_graphs_mutex); + int64_t const bet = av_frame_get_best_effort_timestamp (_frame); + if (bet == AV_NOPTS_VALUE) { + _film->log()->log ("Dropping frame without PTS"); + return; + } - shared_ptr graph; - - list >::iterator i = _filter_graphs.begin(); - while (i != _filter_graphs.end() && !(*i)->can_process (libdcp::Size (_frame->width, _frame->height), (AVPixelFormat) _frame->format)) { - ++i; + if (_film->crop() == Crop() && _film->filters().empty()) { + /* No filter graph needed; just emit */ + emit_video (shared_ptr (new FrameImage (_frame, false)), false, bet * av_q2d (_format_context->streams[_video_stream]->time_base)); + return; } + + shared_ptr graph; - if (i == _filter_graphs.end ()) { - graph.reset (new FilterGraph (_film, this, libdcp::Size (_frame->width, _frame->height), (AVPixelFormat) _frame->format)); - _filter_graphs.push_back (graph); - _film->log()->log (String::compose (N_("New graph for %1x%2, pixel format %3"), _frame->width, _frame->height, _frame->format)); - } else { - graph = *i; + { + boost::mutex::scoped_lock lm (_filter_graphs_mutex); + + list >::iterator i = _filter_graphs.begin(); + while (i != _filter_graphs.end() && !(*i)->can_process (libdcp::Size (_frame->width, _frame->height), (AVPixelFormat) _frame->format)) { + ++i; + } + + if (i == _filter_graphs.end ()) { + graph.reset (new FilterGraph (_film, this, libdcp::Size (_frame->width, _frame->height), (AVPixelFormat) _frame->format)); + _filter_graphs.push_back (graph); + _film->log()->log (String::compose (N_("New graph for %1x%2, pixel format %3"), _frame->width, _frame->height, _frame->format)); + } else { + graph = *i; + } } list > images = graph->process (_frame); for (list >::iterator i = images.begin(); i != images.end(); ++i) { - int64_t const bet = av_frame_get_best_effort_timestamp (_frame); - if (bet != AV_NOPTS_VALUE) { - emit_video (*i, false, bet * av_q2d (_format_context->streams[_video_stream]->time_base)); - } else { - _film->log()->log ("Dropping frame without PTS"); - } + emit_video (*i, false, bet * av_q2d (_format_context->streams[_video_stream]->time_base)); } } diff --git a/src/lib/filter_graph.cc b/src/lib/filter_graph.cc index f0c49b37c..2624bc4d7 100644 --- a/src/lib/filter_graph.cc +++ b/src/lib/filter_graph.cc @@ -79,17 +79,14 @@ FilterGraph::FilterGraph (shared_ptr film, FFmpegDecoder* decoder, libdcp: } stringstream a; - a << _size.width << N_(":") - << _size.height << N_(":") - << _pixel_format << N_(":") - << decoder->time_base_numerator() << N_(":") - << decoder->time_base_denominator() << N_(":") - << decoder->sample_aspect_ratio_numerator() << N_(":") - << decoder->sample_aspect_ratio_denominator(); + a << "video_size=" << _size.width << "x" << _size.height << ":" + << "pix_fmt=" << _pixel_format << ":" + << "time_base=" << decoder->time_base_numerator() << "/" << decoder->time_base_denominator() << ":" + << "pixel_aspect=" << decoder->sample_aspect_ratio_numerator() << "/" << decoder->sample_aspect_ratio_denominator(); int r; - if ((r = avfilter_graph_create_filter (&_buffer_src_context, buffer_src, N_("in"), a.str().c_str(), 0, graph)) < 0) { + if ((r = avfilter_graph_create_filter (&_buffer_src_context, buffer_src, "in", a.str().c_str(), 0, graph)) < 0) { throw DecodeError (N_("could not create buffer source")); } @@ -103,6 +100,8 @@ FilterGraph::FilterGraph (shared_ptr film, FFmpegDecoder* decoder, libdcp: throw DecodeError (N_("could not create buffer sink.")); } + av_free (sink_params); + AVFilterInOut* outputs = avfilter_inout_alloc (); outputs->name = av_strdup(N_("in")); outputs->filter_ctx = _buffer_src_context; @@ -133,7 +132,7 @@ list > FilterGraph::process (AVFrame* frame) { list > images; - + if (av_buffersrc_write_frame (_buffer_src_context, frame) < 0) { throw DecodeError (N_("could not push buffer into filter chain.")); } @@ -146,7 +145,7 @@ FilterGraph::process (AVFrame* frame) } /* This takes ownership of the AVFrame */ - images.push_back (shared_ptr (new FrameImage (frame))); + images.push_back (shared_ptr (new FrameImage (frame, true))); } return images; diff --git a/src/lib/image.cc b/src/lib/image.cc index b97291585..1768be924 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -576,9 +576,10 @@ SimpleImage::aligned () const return _aligned; } -FrameImage::FrameImage (AVFrame* frame) +FrameImage::FrameImage (AVFrame* frame, bool own) : Image (static_cast (frame->format)) , _frame (frame) + , _own (own) { _line_size = (int *) av_malloc (4 * sizeof (int)); _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0; @@ -590,7 +591,10 @@ FrameImage::FrameImage (AVFrame* frame) FrameImage::~FrameImage () { - av_frame_free (&_frame); + if (_own) { + av_frame_free (&_frame); + } + av_free (_line_size); } diff --git a/src/lib/image.h b/src/lib/image.h index 39d84fcd4..16fbd28c2 100644 --- a/src/lib/image.h +++ b/src/lib/image.h @@ -106,7 +106,7 @@ private: class FrameImage : public Image { public: - FrameImage (AVFrame *); + FrameImage (AVFrame *, bool); ~FrameImage (); uint8_t ** data () const; @@ -121,6 +121,7 @@ private: FrameImage& operator= (FrameImage const &); AVFrame* _frame; + bool _own; int* _line_size; }; diff --git a/test/pixel_formats_test.cc b/test/pixel_formats_test.cc index e0f6c4373..e8ad725ff 100644 --- a/test/pixel_formats_test.cc +++ b/test/pixel_formats_test.cc @@ -65,7 +65,7 @@ BOOST_AUTO_TEST_CASE (pixel_formats_test) f->width = 640; f->height = 480; f->format = static_cast (i->format); - FrameImage t (f); + FrameImage t (f, true); BOOST_CHECK_EQUAL(t.components(), i->components); BOOST_CHECK_EQUAL(t.lines(0), i->lines[0]); BOOST_CHECK_EQUAL(t.lines(1), i->lines[1]); -- cgit v1.2.3 From ccf029f29d128a6cc92a8d77b1e0d0e483fd1beb Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 2 May 2013 22:36:41 +0100 Subject: Back-port tabbed config dialog from 1.0 --- src/wx/config_dialog.cc | 252 ++++++++++++++++++++++++++++++------------------ src/wx/config_dialog.h | 15 ++- 2 files changed, 170 insertions(+), 97 deletions(-) (limited to 'src') diff --git a/src/wx/config_dialog.cc b/src/wx/config_dialog.cc index c32b03ec0..07866f6f4 100644 --- a/src/wx/config_dialog.cc +++ b/src/wx/config_dialog.cc @@ -18,13 +18,14 @@ */ /** @file src/config_dialog.cc - * @brief A dialogue to edit DVD-o-matic configuration. + * @brief A dialogue to edit DCP-o-matic configuration. */ #include #include #include #include +#include #include "lib/config.h" #include "lib/server.h" #include "lib/format.h" @@ -41,14 +42,48 @@ using namespace std; using boost::bind; ConfigDialog::ConfigDialog (wxWindow* parent) - : wxDialog (parent, wxID_ANY, _("DVD-o-matic Preferences"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) + : wxDialog (parent, wxID_ANY, _("DCP-o-matic Preferences"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) { + wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); + _notebook = new wxNotebook (this, wxID_ANY); + s->Add (_notebook, 1); + + make_misc_panel (); + _notebook->AddPage (_misc_panel, _("Miscellaneous"), true); + make_servers_panel (); + _notebook->AddPage (_servers_panel, _("Encoding servers"), false); + make_tms_panel (); + _notebook->AddPage (_tms_panel, _("TMS"), false); + make_ab_panel (); + _notebook->AddPage (_ab_panel, _("A/B mode"), false); + + wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL); + overall_sizer->Add (s, 1, wxEXPAND | wxALL, 6); + + wxSizer* buttons = CreateSeparatedButtonSizer (wxOK); + if (buttons) { + overall_sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder()); + } + + SetSizer (overall_sizer); + overall_sizer->Layout (); + overall_sizer->SetSizeHints (this); +} + +void +ConfigDialog::make_misc_panel () +{ + _misc_panel = new wxPanel (_notebook); + wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); + _misc_panel->SetSizer (s); + wxFlexGridSizer* table = new wxFlexGridSizer (3, 6, 6); table->AddGrowableCol (1, 1); + s->Add (table, 1, wxALL | wxEXPAND, 8); - _set_language = new wxCheckBox (this, wxID_ANY, _("Set language")); + _set_language = new wxCheckBox (_misc_panel, wxID_ANY, _("Set language")); table->Add (_set_language, 1, wxEXPAND); - _language = new wxChoice (this, wxID_ANY); + _language = new wxChoice (_misc_panel, wxID_ANY); _language->Append (wxT ("English")); _language->Append (wxT ("Français")); _language->Append (wxT ("Italiano")); @@ -57,98 +92,33 @@ ConfigDialog::ConfigDialog (wxWindow* parent) table->Add (_language, 1, wxEXPAND); table->AddSpacer (0); - table->AddSpacer (0); - wxStaticText* restart = add_label_to_sizer (table, this, _("(restart DVD-o-matic to see language changes)")); + wxStaticText* restart = add_label_to_sizer (table, _misc_panel, _("(restart DCP-o-matic to see language changes)")); wxFont font = restart->GetFont(); font.SetStyle (wxFONTSTYLE_ITALIC); font.SetPointSize (font.GetPointSize() - 1); restart->SetFont (font); table->AddSpacer (0); - - add_label_to_sizer (table, this, _("TMS IP address")); - _tms_ip = new wxTextCtrl (this, wxID_ANY); - table->Add (_tms_ip, 1, wxEXPAND); table->AddSpacer (0); - add_label_to_sizer (table, this, _("TMS target path")); - _tms_path = new wxTextCtrl (this, wxID_ANY); - table->Add (_tms_path, 1, wxEXPAND); - table->AddSpacer (0); - - add_label_to_sizer (table, this, _("TMS user name")); - _tms_user = new wxTextCtrl (this, wxID_ANY); - table->Add (_tms_user, 1, wxEXPAND); - table->AddSpacer (0); - - add_label_to_sizer (table, this, _("TMS password")); - _tms_password = new wxTextCtrl (this, wxID_ANY); - table->Add (_tms_password, 1, wxEXPAND); - table->AddSpacer (0); - - add_label_to_sizer (table, this, _("Threads to use for encoding on this host")); - _num_local_encoding_threads = new wxSpinCtrl (this); + add_label_to_sizer (table, _misc_panel, _("Threads to use for encoding on this host")); + _num_local_encoding_threads = new wxSpinCtrl (_misc_panel); table->Add (_num_local_encoding_threads, 1, wxEXPAND); table->AddSpacer (0); - add_label_to_sizer (table, this, _("Default directory for new films")); + add_label_to_sizer (table, _misc_panel, _("Default directory for new films")); #ifdef __WXMSW__ - _default_directory = new DirPickerCtrl (this); + _default_directory = new DirPickerCtrl (_misc_panel); #else - _default_directory = new wxDirPickerCtrl (this, wxDD_DIR_MUST_EXIST); + _default_directory = new wxDirPickerCtrl (_misc_panel, wxDD_DIR_MUST_EXIST); #endif table->Add (_default_directory, 1, wxEXPAND); table->AddSpacer (0); - add_label_to_sizer (table, this, _("Default DCI name details")); - _default_dci_metadata_button = new wxButton (this, wxID_ANY, _("Edit...")); + add_label_to_sizer (table, _misc_panel, _("Default DCI name details")); + _default_dci_metadata_button = new wxButton (_misc_panel, wxID_ANY, _("Edit...")); table->Add (_default_dci_metadata_button); table->AddSpacer (1); - add_label_to_sizer (table, this, _("Reference scaler for A/B")); - _reference_scaler = new wxChoice (this, wxID_ANY); - vector const sc = Scaler::all (); - for (vector::const_iterator i = sc.begin(); i != sc.end(); ++i) { - _reference_scaler->Append (std_to_wx ((*i)->name ())); - } - - table->Add (_reference_scaler, 1, wxEXPAND); - table->AddSpacer (0); - - { - add_label_to_sizer (table, this, _("Reference filters for A/B")); - wxSizer* s = new wxBoxSizer (wxHORIZONTAL); - _reference_filters = new wxStaticText (this, wxID_ANY, wxT ("")); - s->Add (_reference_filters, 1, wxEXPAND); - _reference_filters_button = new wxButton (this, wxID_ANY, _("Edit...")); - s->Add (_reference_filters_button, 0); - table->Add (s, 1, wxEXPAND); - table->AddSpacer (0); - } - - add_label_to_sizer (table, this, _("Encoding Servers")); - _servers = new wxListCtrl (this, wxID_ANY, wxDefaultPosition, wxSize (220, 100), wxLC_REPORT | wxLC_SINGLE_SEL); - wxListItem ip; - ip.SetId (0); - ip.SetText (_("IP address")); - ip.SetWidth (120); - _servers->InsertColumn (0, ip); - ip.SetId (1); - ip.SetText (_("Threads")); - ip.SetWidth (80); - _servers->InsertColumn (1, ip); - table->Add (_servers, 1, wxEXPAND | wxALL); - - { - wxSizer* s = new wxBoxSizer (wxVERTICAL); - _add_server = new wxButton (this, wxID_ANY, _("Add")); - s->Add (_add_server); - _edit_server = new wxButton (this, wxID_ANY, _("Edit")); - s->Add (_edit_server); - _remove_server = new wxButton (this, wxID_ANY, _("Remove")); - s->Add (_remove_server); - table->Add (s, 0); - } - Config* config = Config::instance (); _set_language->SetValue (config->language ()); @@ -169,6 +139,47 @@ ConfigDialog::ConfigDialog (wxWindow* parent) _set_language->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (ConfigDialog::set_language_changed), 0, this); _language->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (ConfigDialog::language_changed), 0, this); + + _num_local_encoding_threads->SetRange (1, 128); + _num_local_encoding_threads->SetValue (config->num_local_encoding_threads ()); + _num_local_encoding_threads->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (ConfigDialog::num_local_encoding_threads_changed), 0, this); + + _default_directory->SetPath (std_to_wx (config->default_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())))); + _default_directory->Connect (wxID_ANY, wxEVT_COMMAND_DIRPICKER_CHANGED, wxCommandEventHandler (ConfigDialog::default_directory_changed), 0, this); + + _default_dci_metadata_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (ConfigDialog::edit_default_dci_metadata_clicked), 0, this); + +} + +void +ConfigDialog::make_tms_panel () +{ + _tms_panel = new wxPanel (_notebook); + wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); + _tms_panel->SetSizer (s); + + wxFlexGridSizer* table = new wxFlexGridSizer (2, 6, 6); + table->AddGrowableCol (1, 1); + s->Add (table, 1, wxALL | wxEXPAND, 8); + + add_label_to_sizer (table, _tms_panel, _("IP address")); + _tms_ip = new wxTextCtrl (_tms_panel, wxID_ANY); + table->Add (_tms_ip, 1, wxEXPAND); + + add_label_to_sizer (table, _tms_panel, _("Target path")); + _tms_path = new wxTextCtrl (_tms_panel, wxID_ANY); + table->Add (_tms_path, 1, wxEXPAND); + + add_label_to_sizer (table, _tms_panel, _("User name")); + _tms_user = new wxTextCtrl (_tms_panel, wxID_ANY); + table->Add (_tms_user, 1, wxEXPAND); + + add_label_to_sizer (table, _tms_panel, _("Password")); + _tms_password = new wxTextCtrl (_tms_panel, wxID_ANY); + table->Add (_tms_password, 1, wxEXPAND); + + Config* config = Config::instance (); + _tms_ip->SetValue (std_to_wx (config->tms_ip ())); _tms_ip->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (ConfigDialog::tms_ip_changed), 0, this); _tms_path->SetValue (std_to_wx (config->tms_path ())); @@ -177,22 +188,85 @@ ConfigDialog::ConfigDialog (wxWindow* parent) _tms_user->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (ConfigDialog::tms_user_changed), 0, this); _tms_password->SetValue (std_to_wx (config->tms_password ())); _tms_password->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (ConfigDialog::tms_password_changed), 0, this); +} - _num_local_encoding_threads->SetRange (1, 128); - _num_local_encoding_threads->SetValue (config->num_local_encoding_threads ()); - _num_local_encoding_threads->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (ConfigDialog::num_local_encoding_threads_changed), 0, this); +void +ConfigDialog::make_ab_panel () +{ + _ab_panel = new wxPanel (_notebook); + wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); + _ab_panel->SetSizer (s); - _default_directory->SetPath (std_to_wx (config->default_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())))); - _default_directory->Connect (wxID_ANY, wxEVT_COMMAND_DIRPICKER_CHANGED, wxCommandEventHandler (ConfigDialog::default_directory_changed), 0, this); + wxFlexGridSizer* table = new wxFlexGridSizer (3, 6, 6); + table->AddGrowableCol (1, 1); + s->Add (table, 1, wxALL, 8); + + add_label_to_sizer (table, _ab_panel, _("Reference scaler")); + _reference_scaler = new wxChoice (_ab_panel, wxID_ANY); + vector const sc = Scaler::all (); + for (vector::const_iterator i = sc.begin(); i != sc.end(); ++i) { + _reference_scaler->Append (std_to_wx ((*i)->name ())); + } - _default_dci_metadata_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (ConfigDialog::edit_default_dci_metadata_clicked), 0, this); + table->Add (_reference_scaler, 1, wxEXPAND); + table->AddSpacer (0); + { + add_label_to_sizer (table, _ab_panel, _("Reference filters")); + wxSizer* s = new wxBoxSizer (wxHORIZONTAL); + _reference_filters = new wxStaticText (_ab_panel, wxID_ANY, wxT ("")); + s->Add (_reference_filters, 1, wxEXPAND); + _reference_filters_button = new wxButton (_ab_panel, wxID_ANY, _("Edit...")); + s->Add (_reference_filters_button, 0); + table->Add (s, 1, wxEXPAND); + table->AddSpacer (0); + } + + Config* config = Config::instance (); + _reference_scaler->SetSelection (Scaler::as_index (config->reference_scaler ())); _reference_scaler->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (ConfigDialog::reference_scaler_changed), 0, this); pair p = Filter::ffmpeg_strings (config->reference_filters ()); _reference_filters->SetLabel (std_to_wx (p.first) + N_(" ") + std_to_wx (p.second)); _reference_filters_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (ConfigDialog::edit_reference_filters_clicked), 0, this); +} + +void +ConfigDialog::make_servers_panel () +{ + _servers_panel = new wxPanel (_notebook); + wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); + _servers_panel->SetSizer (s); + + wxFlexGridSizer* table = new wxFlexGridSizer (2, 6, 6); + table->AddGrowableCol (0, 1); + s->Add (table, 1, wxALL | wxEXPAND, 8); + + Config* config = Config::instance (); + + _servers = new wxListCtrl (_servers_panel, wxID_ANY, wxDefaultPosition, wxSize (220, 100), wxLC_REPORT | wxLC_SINGLE_SEL); + wxListItem ip; + ip.SetId (0); + ip.SetText (_("IP address")); + ip.SetWidth (120); + _servers->InsertColumn (0, ip); + ip.SetId (1); + ip.SetText (_("Threads")); + ip.SetWidth (80); + _servers->InsertColumn (1, ip); + table->Add (_servers, 1, wxEXPAND | wxALL); + + { + wxSizer* s = new wxBoxSizer (wxVERTICAL); + _add_server = new wxButton (_servers_panel, wxID_ANY, _("Add")); + s->Add (_add_server); + _edit_server = new wxButton (_servers_panel, wxID_ANY, _("Edit")); + s->Add (_edit_server); + _remove_server = new wxButton (_servers_panel, wxID_ANY, _("Remove")); + s->Add (_remove_server); + table->Add (s, 0); + } vector servers = config->servers (); for (vector::iterator i = servers.begin(); i != servers.end(); ++i) { @@ -207,18 +281,6 @@ ConfigDialog::ConfigDialog (wxWindow* parent) _servers->Connect (wxID_ANY, wxEVT_COMMAND_LIST_ITEM_DESELECTED, wxListEventHandler (ConfigDialog::server_selection_changed), 0, this); wxListEvent ev; server_selection_changed (ev); - - wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL); - overall_sizer->Add (table, 1, wxEXPAND | wxALL, 6); - - wxSizer* buttons = CreateSeparatedButtonSizer (wxOK); - if (buttons) { - overall_sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder()); - } - - SetSizer (overall_sizer); - overall_sizer->Layout (); - overall_sizer->SetSizeHints (this); } void diff --git a/src/wx/config_dialog.h b/src/wx/config_dialog.h index f6f3b3707..598279e86 100644 --- a/src/wx/config_dialog.h +++ b/src/wx/config_dialog.h @@ -18,7 +18,7 @@ */ /** @file src/config_dialog.h - * @brief A dialogue to edit DVD-o-matic configuration. + * @brief A dialogue to edit DCP-o-matic configuration. */ #include @@ -27,11 +27,12 @@ #include class DirPickerCtrl; +class wxNotebook; class ServerDescription; /** @class ConfigDialog - * @brief A dialogue to edit DVD-o-matic configuration. + * @brief A dialogue to edit DCP-o-matic configuration. */ class ConfigDialog : public wxDialog { @@ -59,6 +60,16 @@ private: void add_server_to_control (ServerDescription *); void setup_language_sensitivity (); + void make_misc_panel (); + void make_tms_panel (); + void make_ab_panel (); + void make_servers_panel (); + + wxNotebook* _notebook; + wxPanel* _misc_panel; + wxPanel* _tms_panel; + wxPanel* _ab_panel; + wxPanel* _servers_panel; wxCheckBox* _set_language; wxChoice* _language; wxTextCtrl* _tms_ip; -- cgit v1.2.3 From cc56fc111c742ed5ec072fa0bbe0b950150d40c1 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 3 May 2013 00:56:16 +0100 Subject: Configurable default format and content type (#133). --- src/lib/config.cc | 14 ++++++++++++++ src/lib/config.h | 20 ++++++++++++++++++++ src/lib/film.cc | 4 ++-- src/wx/config_dialog.cc | 50 ++++++++++++++++++++++++++++++++++++++++++++++++- src/wx/config_dialog.h | 4 ++++ 5 files changed, 89 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/lib/config.cc b/src/lib/config.cc index 5dce3748d..0e2e33a16 100644 --- a/src/lib/config.cc +++ b/src/lib/config.cc @@ -26,6 +26,8 @@ #include "server.h" #include "scaler.h" #include "filter.h" +#include "format.h" +#include "dcp_content_type.h" #include "sound_processor.h" #include "i18n.h" @@ -45,6 +47,8 @@ Config::Config () , _reference_scaler (Scaler::from_id (N_("bicubic"))) , _tms_path (N_(".")) , _sound_processor (SoundProcessor::from_id (N_("dolby_cp750"))) + , _default_format (0) + , _default_dcp_content_type (0) { _allowed_dcp_frame_rates.push_back (24); _allowed_dcp_frame_rates.push_back (25); @@ -96,6 +100,10 @@ Config::Config () _sound_processor = SoundProcessor::from_id (v); } else if (k == "language") { _language = v; + } else if (k == "default_format") { + _default_format = Format::from_metadata (v); + } else if (k == "default_dcp_content_type") { + _default_dcp_content_type = DCPContentType::from_dci_name (v); } _default_dci_metadata.read (k, v); @@ -154,6 +162,12 @@ Config::write () const if (_language) { f << "language " << _language.get() << "\n"; } + if (_default_format) { + f << "default_format " << _default_format->as_metadata() << "\n"; + } + if (_default_dcp_content_type) { + f << "default_dcp_content_type " << _default_dcp_content_type->dci_name() << "\n"; + } _default_dci_metadata.write (f); } diff --git a/src/lib/config.h b/src/lib/config.h index 011ca716f..6041045cf 100644 --- a/src/lib/config.h +++ b/src/lib/config.h @@ -33,6 +33,8 @@ class ServerDescription; class Scaler; class Filter; class SoundProcessor; +class Format; +class DCPContentType; /** @class Config * @brief A singleton class holding configuration. @@ -107,6 +109,14 @@ public: return _language; } + Format const * default_format () const { + return _default_format; + } + + DCPContentType const * default_dcp_content_type () const { + return _default_dcp_content_type; + } + /** @param n New number of local encoding threads */ void set_num_local_encoding_threads (int n) { _num_local_encoding_threads = n; @@ -169,6 +179,14 @@ public: void unset_language () { _language = boost::none; } + + void set_default_format (Format const * f) { + _default_format = f; + } + + void set_default_dcp_content_type (DCPContentType const * t) { + _default_dcp_content_type = t; + } void write () const; @@ -206,6 +224,8 @@ private: /** Default DCI metadata for newly-created Films */ DCIMetadata _default_dci_metadata; boost::optional _language; + Format const * _default_format; + DCPContentType const * _default_dcp_content_type; /** Singleton instance, or 0 */ static Config* _instance; diff --git a/src/lib/film.cc b/src/lib/film.cc index b0785df34..0ca374604 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -88,8 +88,8 @@ int const Film::state_version = 4; Film::Film (string d, bool must_exist) : _use_dci_name (true) , _trust_content_header (true) - , _dcp_content_type (0) - , _format (0) + , _dcp_content_type (Config::instance()->default_dcp_content_type ()) + , _format (Config::instance()->default_format ()) , _scaler (Scaler::from_id ("bicubic")) , _trim_start (0) , _trim_end (0) diff --git a/src/wx/config_dialog.cc b/src/wx/config_dialog.cc index 07866f6f4..a91bfd64c 100644 --- a/src/wx/config_dialog.cc +++ b/src/wx/config_dialog.cc @@ -31,6 +31,7 @@ #include "lib/format.h" #include "lib/scaler.h" #include "lib/filter.h" +#include "lib/dcp_content_type.h" #include "config_dialog.h" #include "wx_util.h" #include "filter_dialog.h" @@ -119,6 +120,16 @@ ConfigDialog::make_misc_panel () table->Add (_default_dci_metadata_button); table->AddSpacer (1); + add_label_to_sizer (table, _misc_panel, _("Default format")); + _default_format = new wxChoice (_misc_panel, wxID_ANY); + table->Add (_default_format); + table->AddSpacer (1); + + add_label_to_sizer (table, _misc_panel, _("Default content type")); + _default_dcp_content_type = new wxChoice (_misc_panel, wxID_ANY); + table->Add (_default_dcp_content_type); + table->AddSpacer (1); + Config* config = Config::instance (); _set_language->SetValue (config->language ()); @@ -149,6 +160,29 @@ ConfigDialog::make_misc_panel () _default_dci_metadata_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (ConfigDialog::edit_default_dci_metadata_clicked), 0, this); + vector fmt = Format::all (); + int n = 0; + for (vector::iterator i = fmt.begin(); i != fmt.end(); ++i) { + _default_format->Append (std_to_wx ((*i)->name ())); + if (*i == config->default_format ()) { + _default_format->SetSelection (n); + } + ++n; + } + + _default_format->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (ConfigDialog::default_format_changed), 0, this); + + vector const ct = DCPContentType::all (); + n = 0; + for (vector::const_iterator i = ct.begin(); i != ct.end(); ++i) { + _default_dcp_content_type->Append (std_to_wx ((*i)->pretty_name ())); + if (*i == config->default_dcp_content_type ()) { + _default_dcp_content_type->SetSelection (n); + } + ++n; + } + + _default_dcp_content_type->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (ConfigDialog::default_dcp_content_type_changed), 0, this); } void @@ -215,7 +249,7 @@ ConfigDialog::make_ab_panel () add_label_to_sizer (table, _ab_panel, _("Reference filters")); wxSizer* s = new wxBoxSizer (wxHORIZONTAL); _reference_filters = new wxStaticText (_ab_panel, wxID_ANY, wxT ("")); - s->Add (_reference_filters, 1, wxEXPAND); + s->Add (_reference_filters, 1, wxALIGN_CENTER_VERTICAL | wxEXPAND | wxALL, 6); _reference_filters_button = new wxButton (_ab_panel, wxID_ANY, _("Edit...")); s->Add (_reference_filters_button, 0); table->Add (s, 1, wxEXPAND); @@ -462,3 +496,17 @@ ConfigDialog::setup_language_sensitivity () { _language->Enable (_set_language->GetValue ()); } + +void +ConfigDialog::default_format_changed (wxCommandEvent &) +{ + vector fmt = Format::all (); + Config::instance()->set_default_format (fmt[_default_format->GetSelection()]); +} + +void +ConfigDialog::default_dcp_content_type_changed (wxCommandEvent &) +{ + vector ct = DCPContentType::all (); + Config::instance()->set_default_dcp_content_type (ct[_default_dcp_content_type->GetSelection()]); +} diff --git a/src/wx/config_dialog.h b/src/wx/config_dialog.h index 598279e86..c926b0937 100644 --- a/src/wx/config_dialog.h +++ b/src/wx/config_dialog.h @@ -56,6 +56,8 @@ private: void edit_server_clicked (wxCommandEvent &); void remove_server_clicked (wxCommandEvent &); void server_selection_changed (wxListEvent &); + void default_format_changed (wxCommandEvent &); + void default_dcp_content_type_changed (wxCommandEvent &); void add_server_to_control (ServerDescription *); void setup_language_sensitivity (); @@ -72,6 +74,8 @@ private: wxPanel* _servers_panel; wxCheckBox* _set_language; wxChoice* _language; + wxChoice* _default_format; + wxChoice* _default_dcp_content_type; wxTextCtrl* _tms_ip; wxTextCtrl* _tms_path; wxTextCtrl* _tms_user; -- cgit v1.2.3 From 3fc3aad8735903ced3dae65f764eb33e3f5b3f11 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 3 May 2013 10:01:36 +0100 Subject: Try to fix the filter / AVFrame ownership. --- src/lib/ffmpeg_decoder.cc | 8 +---- src/lib/filter_graph.cc | 42 +++++++++++++++++++------ src/lib/filter_graph.h | 27 ++++++++++++++-- src/lib/image.cc | 77 +++++++++++++--------------------------------- src/lib/image.h | 27 +--------------- test/pixel_formats_test.cc | 2 +- 6 files changed, 80 insertions(+), 103 deletions(-) (limited to 'src') diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index cd68e5294..982139515 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -506,12 +506,6 @@ FFmpegDecoder::filter_and_emit_video () return; } - if (_film->crop() == Crop() && _film->filters().empty()) { - /* No filter graph needed; just emit */ - emit_video (shared_ptr (new FrameImage (_frame, false)), false, bet * av_q2d (_format_context->streams[_video_stream]->time_base)); - return; - } - shared_ptr graph; { @@ -523,7 +517,7 @@ FFmpegDecoder::filter_and_emit_video () } if (i == _filter_graphs.end ()) { - graph.reset (new FilterGraph (_film, this, libdcp::Size (_frame->width, _frame->height), (AVPixelFormat) _frame->format)); + graph = filter_graph_factory (_film, this, libdcp::Size (_frame->width, _frame->height), (AVPixelFormat) _frame->format); _filter_graphs.push_back (graph); _film->log()->log (String::compose (N_("New graph for %1x%2, pixel format %3"), _frame->width, _frame->height, _frame->format)); } else { diff --git a/src/lib/filter_graph.cc b/src/lib/filter_graph.cc index 2624bc4d7..b0427a23d 100644 --- a/src/lib/filter_graph.cc +++ b/src/lib/filter_graph.cc @@ -44,18 +44,20 @@ using std::list; using boost::shared_ptr; using libdcp::Size; -/** Construct a FilterGraph for the settings in a film. +/** Construct a FFmpegFilterGraph for the settings in a film. * @param film Film. * @param decoder Decoder that we are using. * @param s Size of the images to process. * @param p Pixel format of the images to process. */ -FilterGraph::FilterGraph (shared_ptr film, FFmpegDecoder* decoder, libdcp::Size s, AVPixelFormat p) +FFmpegFilterGraph::FFmpegFilterGraph (shared_ptr film, FFmpegDecoder* decoder, libdcp::Size s, AVPixelFormat p) : _buffer_src_context (0) , _buffer_sink_context (0) , _size (s) , _pixel_format (p) { + _frame = av_frame_alloc (); + string filters = Filter::ffmpeg_strings (film->filters()).first; if (!filters.empty ()) { filters += N_(","); @@ -125,11 +127,16 @@ FilterGraph::FilterGraph (shared_ptr film, FFmpegDecoder* decoder, libdcp: /* XXX: leaking `inputs' / `outputs' ? */ } +FFmpegFilterGraph::~FFmpegFilterGraph () +{ + av_frame_free (&_frame); +} + /** Take an AVFrame and process it using our configured filters, returning a - * set of Images. + * set of Images. Caller handles memory management of the input frame. */ list > -FilterGraph::process (AVFrame* frame) +FFmpegFilterGraph::process (AVFrame* frame) { list > images; @@ -138,14 +145,11 @@ FilterGraph::process (AVFrame* frame) } while (1) { - AVFrame* frame = av_frame_alloc (); - if (av_buffersink_get_frame (_buffer_sink_context, frame) < 0) { - av_frame_free (&frame); + if (av_buffersink_get_frame (_buffer_sink_context, _frame) < 0) { break; } - /* This takes ownership of the AVFrame */ - images.push_back (shared_ptr (new FrameImage (frame, true))); + images.push_back (shared_ptr (new SimpleImage (_frame))); } return images; @@ -156,7 +160,25 @@ FilterGraph::process (AVFrame* frame) * @return true if this chain can process images with `s' and `p', otherwise false. */ bool -FilterGraph::can_process (libdcp::Size s, AVPixelFormat p) const +FFmpegFilterGraph::can_process (libdcp::Size s, AVPixelFormat p) const { return (_size == s && _pixel_format == p); } + +list > +EmptyFilterGraph::process (AVFrame* frame) +{ + list > im; + im.push_back (shared_ptr (new SimpleImage (frame))); + return im; +} + +shared_ptr +filter_graph_factory (shared_ptr film, FFmpegDecoder* decoder, libdcp::Size size, AVPixelFormat pixel_format) +{ + if (film->filters().empty() && film->crop() == Crop()) { + return shared_ptr (new EmptyFilterGraph); + } + + return shared_ptr (new FFmpegFilterGraph (film, decoder, size, pixel_format)); +} diff --git a/src/lib/filter_graph.h b/src/lib/filter_graph.h index 249b89851..2138943e4 100644 --- a/src/lib/filter_graph.h +++ b/src/lib/filter_graph.h @@ -30,13 +30,31 @@ class Image; class VideoFilter; class FFmpegDecoder; -/** @class FilterGraph +class FilterGraph +{ +public: + virtual bool can_process (libdcp::Size, AVPixelFormat) const = 0; + virtual std::list > process (AVFrame *) = 0; +}; + +class EmptyFilterGraph : public FilterGraph +{ +public: + bool can_process (libdcp::Size, AVPixelFormat) const { + return true; + } + + std::list > process (AVFrame *); +}; + +/** @class FFmpegFilterGraph * @brief A graph of FFmpeg filters. */ -class FilterGraph +class FFmpegFilterGraph : public FilterGraph { public: - FilterGraph (boost::shared_ptr film, FFmpegDecoder* decoder, libdcp::Size s, AVPixelFormat p); + FFmpegFilterGraph (boost::shared_ptr film, FFmpegDecoder* decoder, libdcp::Size s, AVPixelFormat p); + ~FFmpegFilterGraph (); bool can_process (libdcp::Size s, AVPixelFormat p) const; std::list > process (AVFrame * frame); @@ -46,6 +64,9 @@ private: AVFilterContext* _buffer_sink_context; libdcp::Size _size; ///< size of the images that this chain can process AVPixelFormat _pixel_format; ///< pixel format of the images that this chain can process + AVFrame* _frame; }; +boost::shared_ptr filter_graph_factory (boost::shared_ptr, FFmpegDecoder *, libdcp::Size, AVPixelFormat); + #endif diff --git a/src/lib/image.cc b/src/lib/image.cc index 1768be924..b166dfac6 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -469,10 +469,9 @@ SimpleImage::allocate () SimpleImage::SimpleImage (SimpleImage const & other) : Image (other) + , _size (other._size) + , _aligned (other._aligned) { - _size = other._size; - _aligned = other._aligned; - allocate (); for (int i = 0; i < components(); ++i) { @@ -486,6 +485,25 @@ SimpleImage::SimpleImage (SimpleImage const & other) } } +SimpleImage::SimpleImage (AVFrame* frame) + : Image (static_cast (frame->format)) + , _size (frame->width, frame->height) + , _aligned (true) +{ + allocate (); + + for (int i = 0; i < components(); ++i) { + uint8_t* p = _data[i]; + uint8_t* q = frame->data[i]; + for (int j = 0; j < lines(i); ++j) { + memcpy (p, q, _line_size[i]); + p += stride()[i]; + /* AVFrame's linesize is what we call `stride' */ + q += frame->linesize[i]; + } + } +} + SimpleImage::SimpleImage (shared_ptr other) : Image (*other.get()) { @@ -576,59 +594,6 @@ SimpleImage::aligned () const return _aligned; } -FrameImage::FrameImage (AVFrame* frame, bool own) - : Image (static_cast (frame->format)) - , _frame (frame) - , _own (own) -{ - _line_size = (int *) av_malloc (4 * sizeof (int)); - _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0; - - for (int i = 0; i < components(); ++i) { - _line_size[i] = size().width * bytes_per_pixel(i); - } -} - -FrameImage::~FrameImage () -{ - if (_own) { - av_frame_free (&_frame); - } - - av_free (_line_size); -} - -uint8_t ** -FrameImage::data () const -{ - return _frame->data; -} - -int * -FrameImage::line_size () const -{ - return _line_size; -} - -int * -FrameImage::stride () const -{ - /* AVFrame's `linesize' is what we call `stride' */ - return _frame->linesize; -} - -libdcp::Size -FrameImage::size () const -{ - return libdcp::Size (_frame->width, _frame->height); -} - -bool -FrameImage::aligned () const -{ - return true; -} - RGBPlusAlphaImage::RGBPlusAlphaImage (shared_ptr im) : SimpleImage (im->pixel_format(), im->size(), false) { diff --git a/src/lib/image.h b/src/lib/image.h index 16fbd28c2..70dacfaee 100644 --- a/src/lib/image.h +++ b/src/lib/image.h @@ -34,7 +34,6 @@ extern "C" { #include "util.h" class Scaler; -class RGBFrameImage; class SimpleImage; /** @class Image @@ -100,31 +99,6 @@ private: AVPixelFormat _pixel_format; ///< FFmpeg's way of describing the pixel format of this Image }; -/** @class FrameImage - * @brief An Image that is held in an AVFrame. - */ -class FrameImage : public Image -{ -public: - FrameImage (AVFrame *, bool); - ~FrameImage (); - - uint8_t ** data () const; - int * line_size () const; - int * stride () const; - libdcp::Size size () const; - bool aligned () const; - -private: - /* Not allowed */ - FrameImage (FrameImage const &); - FrameImage& operator= (FrameImage const &); - - AVFrame* _frame; - bool _own; - int* _line_size; -}; - /** @class SimpleImage * @brief An Image for which memory is allocated using a `simple' av_malloc(). */ @@ -132,6 +106,7 @@ class SimpleImage : public Image { public: SimpleImage (AVPixelFormat, libdcp::Size, bool); + SimpleImage (AVFrame *); SimpleImage (SimpleImage const &); SimpleImage (boost::shared_ptr); SimpleImage& operator= (SimpleImage const &); diff --git a/test/pixel_formats_test.cc b/test/pixel_formats_test.cc index e8ad725ff..84f2a33ce 100644 --- a/test/pixel_formats_test.cc +++ b/test/pixel_formats_test.cc @@ -65,7 +65,7 @@ BOOST_AUTO_TEST_CASE (pixel_formats_test) f->width = 640; f->height = 480; f->format = static_cast (i->format); - FrameImage t (f, true); + SimpleImage t (f); BOOST_CHECK_EQUAL(t.components(), i->components); BOOST_CHECK_EQUAL(t.lines(0), i->lines[0]); BOOST_CHECK_EQUAL(t.lines(1), i->lines[1]); -- cgit v1.2.3 From 1738f2e7336734190bed7e94ce3d691d4a9c9e4c Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 4 May 2013 11:08:46 +0100 Subject: Add config options for some of the DCP XML metadata (#122). --- src/lib/config.cc | 27 ++++++++++++++++++--------- src/lib/config.h | 10 ++++++++++ src/lib/writer.cc | 6 +++++- src/tools/makedcp.cc | 15 +-------------- src/wx/config_dialog.cc | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/wx/config_dialog.h | 6 ++++++ 6 files changed, 85 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/lib/config.cc b/src/lib/config.cc index 0e2e33a16..8c65e371a 100644 --- a/src/lib/config.cc +++ b/src/lib/config.cc @@ -104,6 +104,12 @@ Config::Config () _default_format = Format::from_metadata (v); } else if (k == "default_dcp_content_type") { _default_dcp_content_type = DCPContentType::from_dci_name (v); + } else if (k == "dcp_metadata_issuer") { + _dcp_metadata.issuer = v; + } else if (k == "dcp_metadata_creator") { + _dcp_metadata.creator = v; + } else if (k == "dcp_metadata_issue_date") { + _dcp_metadata.issue_date = v; } _default_dci_metadata.read (k, v); @@ -136,26 +142,26 @@ void Config::write () const { ofstream f (file().c_str ()); - f << N_("num_local_encoding_threads ") << _num_local_encoding_threads << N_("\n") - << N_("default_directory ") << _default_directory << N_("\n") - << N_("server_port ") << _server_port << N_("\n"); + f << "num_local_encoding_threads " << _num_local_encoding_threads << "\n" + << "default_directory " << _default_directory << "\n" + << "server_port " << _server_port << "\n"; if (_reference_scaler) { f << "reference_scaler " << _reference_scaler->id () << "\n"; } for (vector::const_iterator i = _reference_filters.begin(); i != _reference_filters.end(); ++i) { - f << N_("reference_filter ") << (*i)->id () << N_("\n"); + f << "reference_filter " << (*i)->id () << "\n"; } for (vector::const_iterator i = _servers.begin(); i != _servers.end(); ++i) { - f << N_("server ") << (*i)->as_metadata () << N_("\n"); + f << "server " << (*i)->as_metadata () << "\n"; } - f << N_("tms_ip ") << _tms_ip << N_("\n"); - f << N_("tms_path ") << _tms_path << N_("\n"); - f << N_("tms_user ") << _tms_user << N_("\n"); - f << N_("tms_password ") << _tms_password << N_("\n"); + f << "tms_ip " << _tms_ip << "\n"; + f << "tms_path " << _tms_path << "\n"; + f << "tms_user " << _tms_user << "\n"; + f << "tms_password " << _tms_password << "\n"; if (_sound_processor) { f << "sound_processor " << _sound_processor->id () << "\n"; } @@ -168,6 +174,9 @@ Config::write () const if (_default_dcp_content_type) { f << "default_dcp_content_type " << _default_dcp_content_type->dci_name() << "\n"; } + f << "dcp_metadata_issuer " << _dcp_metadata.issuer << "\n"; + f << "dcp_metadata_creator " << _dcp_metadata.creator << "\n"; + f << "dcp_metadata_issue_date " << _dcp_metadata.issue_date << "\n"; _default_dci_metadata.write (f); } diff --git a/src/lib/config.h b/src/lib/config.h index 6041045cf..a59cdcae0 100644 --- a/src/lib/config.h +++ b/src/lib/config.h @@ -27,6 +27,7 @@ #include #include #include +#include #include "dci_metadata.h" class ServerDescription; @@ -117,6 +118,10 @@ public: return _default_dcp_content_type; } + libdcp::XMLMetadata dcp_metadata () const { + return _dcp_metadata; + } + /** @param n New number of local encoding threads */ void set_num_local_encoding_threads (int n) { _num_local_encoding_threads = n; @@ -187,6 +192,10 @@ public: void set_default_dcp_content_type (DCPContentType const * t) { _default_dcp_content_type = t; } + + void set_dcp_metadata (libdcp::XMLMetadata m) { + _dcp_metadata = m; + } void write () const; @@ -226,6 +235,7 @@ private: boost::optional _language; Format const * _default_format; DCPContentType const * _default_dcp_content_type; + libdcp::XMLMetadata _dcp_metadata; /** Singleton instance, or 0 */ static Config* _instance; diff --git a/src/lib/writer.cc b/src/lib/writer.cc index ad81686d1..177e929ae 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -22,12 +22,14 @@ #include #include #include +#include #include "writer.h" #include "compose.hpp" #include "film.h" #include "format.h" #include "log.h" #include "dcp_video_frame.h" +#include "config.h" #include "i18n.h" @@ -320,7 +322,9 @@ Writer::finish () ) )); - dcp.write_xml (); + libdcp::XMLMetadata meta = Config::instance()->dcp_metadata (); + meta.set_issue_date_now (); + dcp.write_xml (meta); _film->log()->log (String::compose (N_("Wrote %1 FULL, %2 FAKE, %3 REPEAT; %4 pushed to disk"), _full_written, _fake_written, _repeat_written, _pushed_to_disk)); } diff --git a/src/tools/makedcp.cc b/src/tools/makedcp.cc index c594991a6..e73930d3c 100644 --- a/src/tools/makedcp.cc +++ b/src/tools/makedcp.cc @@ -20,7 +20,6 @@ #include #include #include -#include #include #include "format.h" #include "film.h" @@ -50,7 +49,6 @@ help (string n) << " -v, --version show DVD-o-matic version\n" << " -h, --help show this help\n" << " -d, --deps list DVD-o-matic dependency details and quit\n" - << " -t, --test run in test mode (repeatable UUID generation, timestamps etc.)\n" << " -n, --no-progress do not print progress to stdout\n" << " -r, --no-remote do not use any remote servers\n" << "\n" @@ -61,7 +59,6 @@ int main (int argc, char* argv[]) { string film_dir; - bool test_mode = false; bool progress = true; bool no_remote = false; int log_level = 0; @@ -72,14 +69,13 @@ main (int argc, char* argv[]) { "version", no_argument, 0, 'v'}, { "help", no_argument, 0, 'h'}, { "deps", no_argument, 0, 'd'}, - { "test", no_argument, 0, 't'}, { "no-progress", no_argument, 0, 'n'}, { "no-remote", no_argument, 0, 'r'}, { "log-level", required_argument, 0, 'l' }, { 0, 0, 0, 0 } }; - int c = getopt_long (argc, argv, "vhdtnrl:", long_options, &option_index); + int c = getopt_long (argc, argv, "vhdnrl:", long_options, &option_index); if (c == -1) { break; @@ -95,9 +91,6 @@ main (int argc, char* argv[]) case 'd': cout << dependency_version_summary () << "\n"; exit (EXIT_SUCCESS); - case 't': - test_mode = true; - break; case 'n': progress = false; break; @@ -130,11 +123,6 @@ main (int argc, char* argv[]) } cout << "\n"; - if (test_mode) { - libdcp::enable_test_mode (); - cout << dependency_version_summary() << "\n"; - } - shared_ptr film; try { film.reset (new Film (film_dir, true)); @@ -150,7 +138,6 @@ main (int argc, char* argv[]) cout << "A/B "; } cout << "DCP for " << film->name() << "\n"; - cout << "Test mode: " << (test_mode ? "yes" : "no") << "\n"; cout << "Content: " << film->content() << "\n"; pair const f = Filter::ffmpeg_strings (film->filters ()); cout << "Filters: " << f.first << " " << f.second << "\n"; diff --git a/src/wx/config_dialog.cc b/src/wx/config_dialog.cc index a91bfd64c..98657b666 100644 --- a/src/wx/config_dialog.cc +++ b/src/wx/config_dialog.cc @@ -53,6 +53,8 @@ ConfigDialog::ConfigDialog (wxWindow* parent) _notebook->AddPage (_misc_panel, _("Miscellaneous"), true); make_servers_panel (); _notebook->AddPage (_servers_panel, _("Encoding servers"), false); + make_metadata_panel (); + _notebook->AddPage (_metadata_panel, _("Metadata"), false); make_tms_panel (); _notebook->AddPage (_tms_panel, _("TMS"), false); make_ab_panel (); @@ -224,6 +226,33 @@ ConfigDialog::make_tms_panel () _tms_password->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (ConfigDialog::tms_password_changed), 0, this); } +void +ConfigDialog::make_metadata_panel () +{ + _metadata_panel = new wxPanel (_notebook); + wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); + _metadata_panel->SetSizer (s); + + wxFlexGridSizer* table = new wxFlexGridSizer (2, 6, 6); + table->AddGrowableCol (1, 1); + s->Add (table, 1, wxALL | wxEXPAND, 8); + + add_label_to_sizer (table, _metadata_panel, _("Issuer")); + _issuer = new wxTextCtrl (_metadata_panel, wxID_ANY); + table->Add (_issuer, 1, wxEXPAND); + + add_label_to_sizer (table, _metadata_panel, _("Creator")); + _creator = new wxTextCtrl (_metadata_panel, wxID_ANY); + table->Add (_creator, 1, wxEXPAND); + + Config* config = Config::instance (); + + _issuer->SetValue (std_to_wx (config->dcp_metadata().issuer)); + _issuer->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (ConfigDialog::issuer_changed), 0, this); + _creator->SetValue (std_to_wx (config->dcp_metadata().creator)); + _creator->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (ConfigDialog::creator_changed), 0, this); +} + void ConfigDialog::make_ab_panel () { @@ -510,3 +539,19 @@ ConfigDialog::default_dcp_content_type_changed (wxCommandEvent &) vector ct = DCPContentType::all (); Config::instance()->set_default_dcp_content_type (ct[_default_dcp_content_type->GetSelection()]); } + +void +ConfigDialog::issuer_changed (wxCommandEvent &) +{ + libdcp::XMLMetadata m = Config::instance()->dcp_metadata (); + m.issuer = wx_to_std (_issuer->GetValue ()); + Config::instance()->set_dcp_metadata (m); +} + +void +ConfigDialog::creator_changed (wxCommandEvent &) +{ + libdcp::XMLMetadata m = Config::instance()->dcp_metadata (); + m.creator = wx_to_std (_creator->GetValue ()); + Config::instance()->set_dcp_metadata (m); +} diff --git a/src/wx/config_dialog.h b/src/wx/config_dialog.h index c926b0937..526480912 100644 --- a/src/wx/config_dialog.h +++ b/src/wx/config_dialog.h @@ -58,12 +58,15 @@ private: void server_selection_changed (wxListEvent &); void default_format_changed (wxCommandEvent &); void default_dcp_content_type_changed (wxCommandEvent &); + void issuer_changed (wxCommandEvent &); + void creator_changed (wxCommandEvent &); void add_server_to_control (ServerDescription *); void setup_language_sensitivity (); void make_misc_panel (); void make_tms_panel (); + void make_metadata_panel (); void make_ab_panel (); void make_servers_panel (); @@ -72,6 +75,7 @@ private: wxPanel* _tms_panel; wxPanel* _ab_panel; wxPanel* _servers_panel; + wxPanel* _metadata_panel; wxCheckBox* _set_language; wxChoice* _language; wxChoice* _default_format; @@ -94,5 +98,7 @@ private: wxButton* _add_server; wxButton* _edit_server; wxButton* _remove_server; + wxTextCtrl* _issuer; + wxTextCtrl* _creator; }; -- cgit v1.2.3 From 8a1042b767e2604b0af4850dd69fd6a848fd6ffe Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 4 May 2013 16:52:48 +0100 Subject: Add FFmpeg content dialog; moving ffmpeg-specific things out of the film editor. --- src/lib/film.cc | 62 +--------------- src/lib/film.h | 11 +-- src/lib/playlist.cc | 11 +++ src/lib/playlist.h | 2 + src/wx/ffmpeg_content_dialog.cc | 138 +++++++++++++++++++++++++++++++++++ src/wx/ffmpeg_content_dialog.h | 40 ++++++++++ src/wx/film_editor.cc | 132 ++++----------------------------- src/wx/film_editor.h | 6 -- src/wx/imagemagick_content_dialog.cc | 13 +++- src/wx/imagemagick_content_dialog.h | 5 +- src/wx/wscript | 1 + 11 files changed, 225 insertions(+), 196 deletions(-) create mode 100644 src/wx/ffmpeg_content_dialog.cc create mode 100644 src/wx/ffmpeg_content_dialog.h (limited to 'src') diff --git a/src/lib/film.cc b/src/lib/film.cc index 8fed87122..7d1985d08 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -1154,66 +1154,10 @@ Film::content_length () const return _playlist->content_length (); } -vector -Film::ffmpeg_subtitle_streams () const -{ - shared_ptr f = _playlist->ffmpeg (); - if (f) { - return f->subtitle_streams (); - } - - return vector (); -} - -boost::optional -Film::ffmpeg_subtitle_stream () const -{ - shared_ptr f = _playlist->ffmpeg (); - if (f) { - return f->subtitle_stream (); - } - - return boost::none; -} - -vector -Film::ffmpeg_audio_streams () const -{ - shared_ptr f = _playlist->ffmpeg (); - if (f) { - return f->audio_streams (); - } - - return vector (); -} - -boost::optional -Film::ffmpeg_audio_stream () const -{ - shared_ptr f = _playlist->ffmpeg (); - if (f) { - return f->audio_stream (); - } - - return boost::none; -} - -void -Film::set_ffmpeg_subtitle_stream (FFmpegSubtitleStream s) -{ - shared_ptr f = _playlist->ffmpeg (); - if (f) { - f->set_subtitle_stream (s); - } -} - -void -Film::set_ffmpeg_audio_stream (FFmpegAudioStream s) +bool +Film::has_subtitles () const { - shared_ptr f = _playlist->ffmpeg (); - if (f) { - f->set_audio_stream (s); - } + return _playlist->has_subtitles (); } void diff --git a/src/lib/film.h b/src/lib/film.h index f4d7cde67..48b0d16c5 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -112,6 +112,8 @@ public: int audio_channels () const; int audio_frame_rate () const; bool has_audio () const; + + bool has_subtitles () const; float video_frame_rate () const; libdcp::Size video_size () const; @@ -119,17 +121,10 @@ public: ContentVideoFrame content_length () const; - std::vector ffmpeg_subtitle_streams () const; - boost::optional ffmpeg_subtitle_stream () const; - std::vector ffmpeg_audio_streams () const; - boost::optional ffmpeg_audio_stream () const; - - void set_ffmpeg_subtitle_stream (FFmpegSubtitleStream); - void set_ffmpeg_audio_stream (FFmpegAudioStream); - void set_loop (int); int loop () const; + enum TrimType { CPL, ENCODE diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index 72745f220..63b44f9d6 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -416,3 +416,14 @@ Playlist::ffmpeg () const return shared_ptr (); } + +bool +Playlist::has_subtitles () const +{ + shared_ptr fc = ffmpeg (); + if (!fc) { + return false; + } + + return !fc->subtitle_streams().empty(); +} diff --git a/src/lib/playlist.h b/src/lib/playlist.h index 935bbb2bd..e6acff694 100644 --- a/src/lib/playlist.h +++ b/src/lib/playlist.h @@ -82,6 +82,8 @@ public: return _audio_from; } + bool has_subtitles () const; + ContentList content () const { return _content; } diff --git a/src/wx/ffmpeg_content_dialog.cc b/src/wx/ffmpeg_content_dialog.cc new file mode 100644 index 000000000..540bae0a9 --- /dev/null +++ b/src/wx/ffmpeg_content_dialog.cc @@ -0,0 +1,138 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include "lib/ffmpeg_content.h" +#include "ffmpeg_content_dialog.h" +#include "wx_util.h" + +using std::vector; +using std::string; +using boost::shared_ptr; +using boost::lexical_cast; + +FFmpegContentDialog::FFmpegContentDialog (wxWindow* parent, shared_ptr content) + : wxDialog (parent, wxID_ANY, _("Video")) +{ + wxFlexGridSizer* grid = new wxFlexGridSizer (3, 6, 6); + grid->AddGrowableCol (1, 1); + + add_label_to_sizer (grid, this, _("Audio Stream")); + _audio_stream = new wxChoice (this, wxID_ANY); + grid->Add (_audio_stream, 1, wxEXPAND | wxALL, 6); + _audio_description = new wxStaticText (this, wxID_ANY, wxT ("")); + grid->Add (_audio_description, 1, wxALIGN_CENTER_VERTICAL | wxLEFT, 8); + + add_label_to_sizer (grid, this, "Subtitle stream"); + _subtitle_stream = new wxChoice (this, wxID_ANY); + grid->Add (_subtitle_stream, 1, wxEXPAND | wxALL, 6); + grid->AddSpacer (0); + + _audio_stream->Clear (); + vector a = content->audio_streams (); + for (vector::iterator i = a.begin(); i != a.end(); ++i) { + _audio_stream->Append (std_to_wx (i->name), new wxStringClientData (std_to_wx (lexical_cast (i->id)))); + } + + if (content->audio_stream()) { + checked_set (_audio_stream, lexical_cast (content->audio_stream()->id)); + } + + _subtitle_stream->Clear (); + vector s = content->subtitle_streams (); + for (vector::iterator i = s.begin(); i != s.end(); ++i) { + _subtitle_stream->Append (std_to_wx (i->name), new wxStringClientData (std_to_wx (lexical_cast (i->id)))); + } + + if (content->subtitle_stream()) { + checked_set (_subtitle_stream, lexical_cast (content->subtitle_stream()->id)); + } else { + _subtitle_stream->SetSelection (wxNOT_FOUND); + } + + wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL); + overall_sizer->Add (grid, 1, wxEXPAND | wxALL, 6); + + wxSizer* buttons = CreateSeparatedButtonSizer (wxOK); + if (buttons) { + overall_sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder()); + } + + SetSizer (overall_sizer); + overall_sizer->Layout (); + overall_sizer->SetSizeHints (this); + + _audio_stream->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FFmpegContentDialog::audio_stream_changed), 0, this); + _subtitle_stream->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FFmpegContentDialog::subtitle_stream_changed), 0, this); +} + +void +FFmpegContentDialog::audio_stream_changed (wxCommandEvent &) +{ + shared_ptr c = _content.lock (); + if (!c) { + return; + } + + vector a = c->audio_streams (); + vector::iterator i = a.begin (); + string const s = string_client_data (_audio_stream->GetClientObject (_audio_stream->GetSelection ())); + while (i != a.end() && lexical_cast (i->id) != s) { + ++i; + } + + if (i != a.end ()) { + c->set_audio_stream (*i); + } + + if (!c->audio_stream ()) { + _audio_description->SetLabel (wxT ("")); + } else { + wxString s; + if (c->audio_channels() == 1) { + s << _("1 channel"); + } else { + s << c->audio_channels() << wxT (" ") << _("channels"); + } + s << wxT (", ") << c->audio_frame_rate() << _("Hz"); + _audio_description->SetLabel (s); + } +} + + + +void +FFmpegContentDialog::subtitle_stream_changed (wxCommandEvent &) +{ + shared_ptr c = _content.lock (); + if (!c) { + return; + } + + vector a = c->subtitle_streams (); + vector::iterator i = a.begin (); + string const s = string_client_data (_subtitle_stream->GetClientObject (_subtitle_stream->GetSelection ())); + while (i != a.end() && lexical_cast (i->id) != s) { + ++i; + } + + if (i != a.end ()) { + c->set_subtitle_stream (*i); + } +} diff --git a/src/wx/ffmpeg_content_dialog.h b/src/wx/ffmpeg_content_dialog.h new file mode 100644 index 000000000..5251ad5da --- /dev/null +++ b/src/wx/ffmpeg_content_dialog.h @@ -0,0 +1,40 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include +#include + +class wxSpinCtrl; +class FFmpegContent; + +class FFmpegContentDialog : public wxDialog +{ +public: + FFmpegContentDialog (wxWindow *, boost::shared_ptr); + +private: + void audio_stream_changed (wxCommandEvent &); + void subtitle_stream_changed (wxCommandEvent &); + + boost::weak_ptr _content; + wxChoice* _audio_stream; + wxStaticText* _audio_description; + wxChoice* _subtitle_stream; +}; diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 4f08953b9..85c4f71f8 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -50,6 +50,7 @@ #include "scaler.h" #include "audio_dialog.h" #include "imagemagick_content_dialog.h" +#include "ffmpeg_content_dialog.h" #include "audio_mapping_view.h" using std::string; @@ -234,8 +235,6 @@ FilmEditor::connect_to_widgets () _subtitle_scale->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::subtitle_scale_changed), 0, this); _colour_lut->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::colour_lut_changed), 0, this); _j2k_bandwidth->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::j2k_bandwidth_changed), 0, this); - _ffmpeg_subtitle_stream->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::ffmpeg_subtitle_stream_changed), 0, this); - _ffmpeg_audio_stream->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::ffmpeg_audio_stream_changed), 0, this); _audio_gain->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::audio_gain_changed), 0, this); _audio_gain_calculate_button->Connect ( wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::audio_gain_calculate_button_clicked), 0, this @@ -420,16 +419,6 @@ FilmEditor::make_audio_panel () grid->Add (s); } - { - add_label_to_sizer (grid, _audio_panel, _("Audio Stream")); - wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); - _ffmpeg_audio_stream = new wxChoice (_audio_panel, wxID_ANY); - s->Add (_ffmpeg_audio_stream, 1); - _audio = new wxStaticText (_audio_panel, wxID_ANY, wxT ("")); - s->Add (_audio, 1, wxALIGN_CENTER_VERTICAL | wxLEFT, 8); - grid->Add (s, 1, wxEXPAND); - } - _audio_mapping = new AudioMappingView (_audio_panel); _audio_sizer->Add (_audio_mapping, 1, wxEXPAND | wxALL, 6); @@ -448,10 +437,8 @@ FilmEditor::make_subtitle_panel () _with_subtitles = new wxCheckBox (_subtitle_panel, wxID_ANY, _("With Subtitles")); grid->Add (_with_subtitles, 1); + grid->AddSpacer (0); - _ffmpeg_subtitle_stream = new wxChoice (_subtitle_panel, wxID_ANY); - grid->Add (_ffmpeg_subtitle_stream); - { add_label_to_sizer (grid, _subtitle_panel, _("Subtitle Offset")); wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); @@ -628,7 +615,6 @@ FilmEditor::film_changed (Film::Property p) setup_formats (); setup_format (); setup_subtitle_control_sensitivity (); - setup_streams (); setup_show_audio_sensitivity (); setup_length (); break; @@ -756,9 +742,7 @@ FilmEditor::film_content_changed (weak_ptr content, int property) if (property == FFmpegContentProperty::SUBTITLE_STREAMS) { setup_subtitle_control_sensitivity (); - setup_streams (); } else if (property == FFmpegContentProperty::AUDIO_STREAMS) { - setup_streams (); setup_show_audio_sensitivity (); } else if (property == VideoContentProperty::VIDEO_LENGTH || property == AudioContentProperty::AUDIO_LENGTH) { setup_length (); @@ -767,16 +751,8 @@ FilmEditor::film_content_changed (weak_ptr content, int property) setup_content_information (); } } else if (property == FFmpegContentProperty::AUDIO_STREAM) { - if (_film->ffmpeg_audio_stream()) { - checked_set (_ffmpeg_audio_stream, boost::lexical_cast (_film->ffmpeg_audio_stream()->id)); - } setup_dcp_name (); - setup_audio_details (); setup_show_audio_sensitivity (); - } else if (property == FFmpegContentProperty::SUBTITLE_STREAM) { - if (_film->ffmpeg_subtitle_stream()) { - checked_set (_ffmpeg_subtitle_stream, boost::lexical_cast (_film->ffmpeg_subtitle_stream()->id)); - } } } @@ -958,7 +934,6 @@ FilmEditor::set_things_sensitive (bool s) _bottom_crop->Enable (s); _filters_button->Enable (s); _scaler->Enable (s); - _ffmpeg_audio_stream->Enable (s); _dcp_content_type->Enable (s); _best_dcp_frame_rate->Enable (s); _dcp_frame_rate->Enable (s); @@ -1115,7 +1090,7 @@ FilmEditor::setup_subtitle_control_sensitivity () { bool h = false; if (_generally_sensitive && _film) { - h = !_film->ffmpeg_subtitle_streams().empty(); + h = !_film->has_subtitles (); } _with_subtitles->Enable (h); @@ -1125,7 +1100,6 @@ FilmEditor::setup_subtitle_control_sensitivity () j = _film->with_subtitles (); } - _ffmpeg_subtitle_stream->Enable (j); _subtitle_offset->Enable (j); _subtitle_scale->Enable (j); } @@ -1153,93 +1127,6 @@ FilmEditor::edit_dci_button_clicked (wxCommandEvent &) d->Destroy (); } -void -FilmEditor::setup_streams () -{ - if (!_film) { - return; - } - - _ffmpeg_audio_stream->Clear (); - vector a = _film->ffmpeg_audio_streams (); - for (vector::iterator i = a.begin(); i != a.end(); ++i) { - _ffmpeg_audio_stream->Append (std_to_wx (i->name), new wxStringClientData (std_to_wx (boost::lexical_cast (i->id)))); - } - - if (_film->ffmpeg_audio_stream()) { - checked_set (_ffmpeg_audio_stream, boost::lexical_cast (_film->ffmpeg_audio_stream()->id)); - } - - _ffmpeg_subtitle_stream->Clear (); - vector s = _film->ffmpeg_subtitle_streams (); - for (vector::iterator i = s.begin(); i != s.end(); ++i) { - _ffmpeg_subtitle_stream->Append (std_to_wx (i->name), new wxStringClientData (std_to_wx (boost::lexical_cast (i->id)))); - } - - if (_film->ffmpeg_subtitle_stream()) { - checked_set (_ffmpeg_subtitle_stream, boost::lexical_cast (_film->ffmpeg_subtitle_stream()->id)); - } else { - _ffmpeg_subtitle_stream->SetSelection (wxNOT_FOUND); - } -} - -void -FilmEditor::ffmpeg_audio_stream_changed (wxCommandEvent &) -{ - if (!_film) { - return; - } - - vector a = _film->ffmpeg_audio_streams (); - vector::iterator i = a.begin (); - string const s = string_client_data (_ffmpeg_audio_stream->GetClientObject (_ffmpeg_audio_stream->GetSelection ())); - while (i != a.end() && lexical_cast (i->id) != s) { - ++i; - } - - if (i != a.end ()) { - _film->set_ffmpeg_audio_stream (*i); - } -} - -void -FilmEditor::ffmpeg_subtitle_stream_changed (wxCommandEvent &) -{ - if (!_film) { - return; - } - - vector a = _film->ffmpeg_subtitle_streams (); - vector::iterator i = a.begin (); - string const s = string_client_data (_ffmpeg_subtitle_stream->GetClientObject (_ffmpeg_subtitle_stream->GetSelection ())); - while (i != a.end() && lexical_cast (i->id) != s) { - ++i; - } - - if (i != a.end ()) { - _film->set_ffmpeg_subtitle_stream (*i); - } -} - -void -FilmEditor::setup_audio_details () -{ - if (!_film->ffmpeg_audio_stream()) { - _audio->SetLabel (wxT ("")); - } else { - wxString s; - if (_film->audio_channels() == 1) { - s << _("1 channel"); - } else { - s << _film->audio_channels() << wxT (" ") << _("channels"); - } - s << wxT (", ") << _film->audio_frame_rate() << _("Hz"); - _audio->SetLabel (s); - } - - setup_notebook_size (); -} - void FilmEditor::active_jobs_changed (bool a) { @@ -1377,8 +1264,13 @@ FilmEditor::edit_content (shared_ptr c) ImageMagickContentDialog* d = new ImageMagickContentDialog (this, im); d->ShowModal (); d->Destroy (); + } - im->set_video_length (d->video_length() * 24); + shared_ptr ff = dynamic_pointer_cast (c); + if (ff) { + FFmpegContentDialog* d = new FFmpegContentDialog (this, ff); + d->ShowModal (); + d->Destroy (); } } @@ -1426,7 +1318,11 @@ FilmEditor::setup_content_button_sensitivity () shared_ptr selection = selected_content (); - _content_edit->Enable (selection && _generally_sensitive && dynamic_pointer_cast (selection)); + _content_edit->Enable ( + selection && _generally_sensitive && + (dynamic_pointer_cast (selection) || dynamic_pointer_cast (selection)) + ); + _content_remove->Enable (selection && _generally_sensitive); _content_earlier->Enable (selection && _generally_sensitive); _content_later->Enable (selection && _generally_sensitive); diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index 5944633a8..db657a7d3 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -88,8 +88,6 @@ private: void subtitle_scale_changed (wxCommandEvent &); void colour_lut_changed (wxCommandEvent &); void j2k_bandwidth_changed (wxCommandEvent &); - void ffmpeg_audio_stream_changed (wxCommandEvent &); - void ffmpeg_subtitle_stream_changed (wxCommandEvent &); void dcp_frame_rate_changed (wxCommandEvent &); void best_dcp_frame_rate_clicked (wxCommandEvent &); void edit_filters_clicked (wxCommandEvent &); @@ -103,8 +101,6 @@ private: void set_things_sensitive (bool); void setup_formats (); void setup_subtitle_control_sensitivity (); - void setup_streams (); - void setup_audio_details (); void setup_dcp_name (); void setup_show_audio_sensitivity (); void setup_scaling_description (); @@ -164,10 +160,8 @@ private: wxButton* _audio_gain_calculate_button; wxButton* _show_audio; wxSpinCtrl* _audio_delay; - wxChoice* _ffmpeg_audio_stream; AudioMappingView* _audio_mapping; wxCheckBox* _with_subtitles; - wxChoice* _ffmpeg_subtitle_stream; wxSpinCtrl* _subtitle_offset; wxSpinCtrl* _subtitle_scale; wxChoice* _colour_lut; diff --git a/src/wx/imagemagick_content_dialog.cc b/src/wx/imagemagick_content_dialog.cc index 726e4b8e2..24b92fdaf 100644 --- a/src/wx/imagemagick_content_dialog.cc +++ b/src/wx/imagemagick_content_dialog.cc @@ -26,6 +26,7 @@ using boost::shared_ptr; ImageMagickContentDialog::ImageMagickContentDialog (wxWindow* parent, shared_ptr content) : wxDialog (parent, wxID_ANY, _("Image")) + , _content (content) { wxFlexGridSizer* grid = new wxFlexGridSizer (3, 6, 6); grid->AddGrowableCol (1, 1); @@ -53,10 +54,16 @@ ImageMagickContentDialog::ImageMagickContentDialog (wxWindow* parent, shared_ptr overall_sizer->SetSizeHints (this); checked_set (_video_length, content->video_length () / 24); + _video_length->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (ImageMagickContentDialog::video_length_changed), 0, this); } -int -ImageMagickContentDialog::video_length () const +void +ImageMagickContentDialog::video_length_changed (wxCommandEvent &) { - return _video_length->GetValue (); + shared_ptr c = _content.lock (); + if (!c) { + return; + } + + c->set_video_length (_video_length->GetValue() * 24); } diff --git a/src/wx/imagemagick_content_dialog.h b/src/wx/imagemagick_content_dialog.h index 2fa955929..b22ff6817 100644 --- a/src/wx/imagemagick_content_dialog.h +++ b/src/wx/imagemagick_content_dialog.h @@ -27,8 +27,9 @@ class ImageMagickContentDialog : public wxDialog public: ImageMagickContentDialog (wxWindow *, boost::shared_ptr); - int video_length () const; - private: + void video_length_changed (wxCommandEvent &); + + boost::weak_ptr _content; wxSpinCtrl* _video_length; }; diff --git a/src/wx/wscript b/src/wx/wscript index 09bf40393..001e8469e 100644 --- a/src/wx/wscript +++ b/src/wx/wscript @@ -10,6 +10,7 @@ sources = """ config_dialog.cc dci_metadata_dialog.cc dir_picker_ctrl.cc + ffmpeg_content_dialog.cc film_editor.cc film_viewer.cc filter_dialog.cc -- cgit v1.2.3 From 9bb87e91c0930f16cf615cfc374089912440e5e0 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 4 May 2013 18:01:19 +0100 Subject: Add primitive description of what the playlist is doing. Add missing de-interleave of multi-channel audio sources. --- run/dcpomatic_cli | 12 +++++++++++ run/makedcp | 12 ----------- src/lib/film.cc | 6 ++++++ src/lib/film.h | 2 ++ src/lib/playlist.cc | 51 ++++++++++++++++++++++++++++++++++++++++++++++ src/lib/playlist.h | 2 ++ src/lib/sndfile_decoder.cc | 29 ++++++++++++++++++++++++-- src/lib/sndfile_decoder.h | 1 + src/wx/film_editor.cc | 30 ++++++++++++++++++++++----- src/wx/film_editor.h | 2 ++ 10 files changed, 128 insertions(+), 19 deletions(-) create mode 100755 run/dcpomatic_cli delete mode 100755 run/makedcp (limited to 'src') diff --git a/run/dcpomatic_cli b/run/dcpomatic_cli new file mode 100755 index 000000000..bf2f08015 --- /dev/null +++ b/run/dcpomatic_cli @@ -0,0 +1,12 @@ +#!/bin/bash + +export LD_LIBRARY_PATH=build/src/lib:$LD_LIBRARY_PATH:build/src +if [ "$1" == "--debug" ]; then + shift + gdb --args build/src/tools/dcpomatic_cli "$@" +elif [ "$1" == "--valgrind" ]; then + shift + valgrind --tool="memcheck" --leak-check=full --show-reachable=yes build/src/tools/dcpomatic_cli "$@" +else + build/src/tools/dcpomatic_cli "$@" +fi diff --git a/run/makedcp b/run/makedcp deleted file mode 100755 index f71345b66..000000000 --- a/run/makedcp +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -export LD_LIBRARY_PATH=build/src/lib:$LD_LIBRARY_PATH:build/src -if [ "$1" == "--debug" ]; then - shift - gdb --args build/src/tools/makedcp "$@" -elif [ "$1" == "--valgrind" ]; then - shift - valgrind --tool="memcheck" --leak-check=full --show-reachable=yes build/src/tools/makedcp "$@" -else - build/src/tools/makedcp "$@" -fi diff --git a/src/lib/film.cc b/src/lib/film.cc index 7d1985d08..2dc97c1b3 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -1160,6 +1160,12 @@ Film::has_subtitles () const return _playlist->has_subtitles (); } +string +Film::playlist_description () const +{ + return _playlist->description (); +} + void Film::set_audio_mapping (AudioMapping m) { diff --git a/src/lib/film.h b/src/lib/film.h index 48b0d16c5..8748e18f5 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -121,6 +121,8 @@ public: ContentVideoFrame content_length () const; + std::string playlist_description () const; + void set_loop (int); int loop () const; diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index 63b44f9d6..6913874b9 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -30,12 +30,15 @@ #include "imagemagick_content.h" #include "job.h" +#include "i18n.h" + using std::list; using std::cout; using std::vector; using std::min; using std::max; using std::string; +using std::stringstream; using boost::shared_ptr; using boost::weak_ptr; using boost::dynamic_pointer_cast; @@ -427,3 +430,51 @@ Playlist::has_subtitles () const return !fc->subtitle_streams().empty(); } + +string +Playlist::description () const +{ + stringstream s; + + if (_video.empty ()) { + s << _("There is no video.") << "\n"; + } else { + s << _("Video will come from "); + list >::const_iterator i = _video.begin(); + while (i != _video.end ()) { + s << (*i)->file().filename().string(); + ++i; + if (i != _video.end ()) { + s << ", "; + } + } + if (_video.size() > 1) { + s << " " << _("in sequence."); + } + s << "\n"; + } + + if (_audio.empty ()) { + s << _("There is no audio.") << "\n"; + } else { + if (_audio_from == AUDIO_FFMPEG) { + s << _("Audio will come from the video files.") << "\n"; + } else { + s << _("Audio will come from "); + list >::const_iterator i = _audio.begin(); + while (i != _audio.end ()) { + s << (*i)->file().filename().string(); + ++i; + if (i != _audio.end ()) { + s << ", "; + } + } + if (_audio.size() > 1) { + s << _(" run simultaneously."); + } + s << "\n"; + } + } + + return s.str (); +} diff --git a/src/lib/playlist.h b/src/lib/playlist.h index e6acff694..cea41ab32 100644 --- a/src/lib/playlist.h +++ b/src/lib/playlist.h @@ -88,6 +88,8 @@ public: return _content; } + std::string description () const; + boost::shared_ptr ffmpeg () const; std::list > video () const { diff --git a/src/lib/sndfile_decoder.cc b/src/lib/sndfile_decoder.cc index 9ba972e56..dd9e654c7 100644 --- a/src/lib/sndfile_decoder.cc +++ b/src/lib/sndfile_decoder.cc @@ -36,6 +36,7 @@ SndfileDecoder::SndfileDecoder (shared_ptr f, shared_ptrfile().string().c_str(), SFM_READ, &_info); if (!_sndfile) { @@ -49,6 +50,7 @@ SndfileDecoder::SndfileDecoder (shared_ptr f, shared_ptraudio_frame_rate() / 2; sf_count_t const this_time = min (block, _remaining); + + int const channels = _sndfile_content->audio_channels (); - shared_ptr audio (new AudioBuffers (_sndfile_content->audio_channels(), this_time)); - sf_read_float (_sndfile, audio->data(0), this_time); + shared_ptr audio (new AudioBuffers (channels, this_time)); + + if (_sndfile_content->audio_channels() == 1) { + /* No de-interleaving required */ + sf_read_float (_sndfile, audio->data(0), this_time); + } else { + /* Deinterleave */ + if (!_deinterleave_buffer) { + _deinterleave_buffer = new float[block * channels]; + } + sf_readf_float (_sndfile, _deinterleave_buffer, this_time); + vector out_ptr (channels); + for (int i = 0; i < channels; ++i) { + out_ptr[i] = audio->data(i); + } + float* in_ptr = _deinterleave_buffer; + for (int i = 0; i < this_time; ++i) { + for (int j = 0; j < channels; ++j) { + *out_ptr[j]++ = *in_ptr++; + } + } + } + audio->set_frames (this_time); Audio (audio, double(_done) / audio_frame_rate()); _done += this_time; diff --git a/src/lib/sndfile_decoder.h b/src/lib/sndfile_decoder.h index 1d212cc9b..64bd2f7f5 100644 --- a/src/lib/sndfile_decoder.h +++ b/src/lib/sndfile_decoder.h @@ -41,4 +41,5 @@ private: SF_INFO _info; ContentAudioFrame _done; ContentAudioFrame _remaining; + float* _deinterleave_buffer; }; diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 85c4f71f8..db3e03d78 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -88,6 +88,8 @@ FilmEditor::FilmEditor (shared_ptr f, wxWindow* parent) make_subtitle_panel (); _notebook->AddPage (_subtitle_panel, _("Subtitles"), false); + setup_formats (); + set_film (f); connect_to_widgets (); @@ -95,8 +97,6 @@ FilmEditor::FilmEditor (shared_ptr f, wxWindow* parent) bind (&FilmEditor::active_jobs_changed, this, _1) ); - setup_formats (); - SetSizerAndFit (s); } @@ -367,9 +367,12 @@ FilmEditor::make_content_panel () s->Add (b, 0, wxALL, 4); - _content_sizer->Add (s, 1, wxEXPAND | wxALL, 6); + _content_sizer->Add (s, 0.75, wxEXPAND | wxALL, 6); } + _content_information = new wxTextCtrl (_content_panel, wxID_ANY, wxT ("\n \n "), wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxTE_MULTILINE); + _content_sizer->Add (_content_information, 1, wxEXPAND | wxALL, 6); + wxBoxSizer* h = new wxBoxSizer (wxHORIZONTAL); _loop_content = new wxCheckBox (_content_panel, wxID_ANY, _("Loop everything")); h->Add (_loop_content, 0, wxALL, 6); @@ -378,8 +381,12 @@ FilmEditor::make_content_panel () add_label_to_sizer (h, _content_panel, _("times")); _content_sizer->Add (h, 0, wxALL, 6); - _content_information = new wxTextCtrl (_content_panel, wxID_ANY, wxT ("\n\n\n\n"), wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxTE_MULTILINE); - _content_sizer->Add (_content_information, 1, wxEXPAND | wxALL, 6); + _playlist_description = new wxStaticText (_content_panel, wxID_ANY, wxT ("\n \n \n \n ")); + _content_sizer->Add (_playlist_description, 0.25, wxEXPAND | wxALL, 6); + wxFont font = _playlist_description->GetFont(); + font.SetStyle(wxFONTSTYLE_ITALIC); + font.SetPointSize(font.GetPointSize() - 1); + _playlist_description->SetFont(font); _loop_count->SetRange (2, 1024); } @@ -1198,6 +1205,8 @@ FilmEditor::setup_content () /* Select the first item of content if non was selected before */ _content->SetItemState (0, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED); } + + setup_playlist_description (); } void @@ -1429,3 +1438,14 @@ FilmEditor::setup_loop_sensitivity () { _loop_count->Enable (_loop_content->GetValue ()); } + +void +FilmEditor::setup_playlist_description () +{ + if (!_film) { + _playlist_description->SetLabel (wxT ("")); + return; + } + + _playlist_description->SetLabel (std_to_wx (_film->playlist_description ())); +} diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index db657a7d3..baaeb46d7 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -112,6 +112,7 @@ private: void setup_content_information (); void setup_content_button_sensitivity (); void setup_loop_sensitivity (); + void setup_playlist_description (); void active_jobs_changed (bool); boost::shared_ptr selected_content (); @@ -144,6 +145,7 @@ private: wxTextCtrl* _content_information; wxCheckBox* _loop_content; wxSpinCtrl* _loop_count; + wxStaticText* _playlist_description; wxButton* _edit_dci_button; wxChoice* _format; wxStaticText* _format_description; -- cgit v1.2.3 From 0c5590dd0e3f367064a6e4d52835a609adf11a06 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 4 May 2013 18:47:33 +0100 Subject: Batch converter stub. --- run/dvdomatic_batch | 15 ++++ src/lib/util.cc | 2 +- src/lib/util.h | 2 +- src/tools/dvdomatic.cc | 46 +----------- src/tools/dvdomatic_batch.cc | 168 +++++++++++++++++++++++++++++++++++++++++++ src/tools/wscript | 2 +- src/wx/batch_view.cc | 33 +++++++++ src/wx/batch_view.h | 30 ++++++++ src/wx/wscript | 1 + src/wx/wx_util.cc | 38 ++++++++++ src/wx/wx_util.h | 1 + 11 files changed, 290 insertions(+), 48 deletions(-) create mode 100755 run/dvdomatic_batch create mode 100644 src/tools/dvdomatic_batch.cc create mode 100644 src/wx/batch_view.cc create mode 100644 src/wx/batch_view.h (limited to 'src') diff --git a/run/dvdomatic_batch b/run/dvdomatic_batch new file mode 100755 index 000000000..7b6ef93ae --- /dev/null +++ b/run/dvdomatic_batch @@ -0,0 +1,15 @@ +#!/bin/bash + +export LD_LIBRARY_PATH=build/src/lib:build/src/wx:build/src/asdcplib/src:$LD_LIBRARY_PATH +if [ "$1" == "--debug" ]; then + shift + gdb --args build/src/tools/dvdomatic_batch "$*" +elif [ "$1" == "--valgrind" ]; then + shift + valgrind --tool="memcheck" build/src/tools/dvdomatic_batch $* +elif [ "$1" == "--i18n" ]; then + shift + LANGUAGE=fr_FR.UTF8 LANG=fr_FR.UTF8 build/src/tools/dvdomatic_batch "$*" +else + build/src/tools/dvdomatic_batch +fi diff --git a/src/lib/util.cc b/src/lib/util.cc index 859aa6de7..be078a95f 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -274,7 +274,7 @@ mo_path () #endif void -dvdomatic_setup_i18n (string lang) +dvdomatic_setup_gettext_i18n (string lang) { #ifdef DVDOMATIC_POSIX lang += ".UTF8"; diff --git a/src/lib/util.h b/src/lib/util.h index 99670110e..d0c350a56 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -55,7 +55,7 @@ extern void stacktrace (std::ostream &, int); extern std::string dependency_version_summary (); extern double seconds (struct timeval); extern void dvdomatic_setup (); -extern void dvdomatic_setup_i18n (std::string); +extern void dvdomatic_setup_gettext_i18n (std::string); extern std::vector split_at_spaces_considering_quotes (std::string); extern std::string md5_digest (std::string); extern std::string md5_digest (void const *, int); diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index b161ac7e3..2740a0965 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -62,7 +62,6 @@ static shared_ptr film; static std::string log_level; static std::string film_to_load; static wxMenu* jobs_menu = 0; -static wxLocale* locale = 0; static void set_menu_sensitivity (); @@ -463,49 +462,6 @@ static const wxCmdLineEntryDesc command_line_description[] = { }; #endif -void -setup_i18n () -{ - int language = wxLANGUAGE_DEFAULT; - - ofstream f ("c:/users/carl hetherington/foo", std::ios::app); - f << "Hello.\n"; - - boost::optional config_lang = Config::instance()->language (); - if (config_lang && !config_lang->empty ()) { - f << "Configured language " << config_lang.get() << "\n"; - wxLanguageInfo const * li = wxLocale::FindLanguageInfo (std_to_wx (config_lang.get ())); - f << "LanguageInfo " << li << "\n"; - if (li) { - language = li->Language; - f << "language=" << language << " cf " << wxLANGUAGE_DEFAULT << " " << wxLANGUAGE_ENGLISH << "\n"; - } - } - - if (wxLocale::IsAvailable (language)) { - f << "Language is available.\n"; - locale = new wxLocale (language, wxLOCALE_LOAD_DEFAULT); - -#ifdef DVDOMATIC_WINDOWS - locale->AddCatalogLookupPathPrefix (std_to_wx (mo_path().string())); -#endif - - locale->AddCatalog (wxT ("libdvdomatic-wx")); - locale->AddCatalog (wxT ("dvdomatic")); - - if (!locale->IsOk()) { - f << "Locale is not ok.\n"; - delete locale; - locale = new wxLocale (wxLANGUAGE_ENGLISH); - language = wxLANGUAGE_ENGLISH; - } - } - - if (locale) { - dvdomatic_setup_i18n (wx_to_std (locale->GetCanonicalName ())); - } -} - class App : public wxApp { bool OnInit () @@ -526,7 +482,7 @@ class App : public wxApp hasn't yet been called and there aren't any scalers, filters etc. set up yet. */ - setup_i18n (); + dvdomatic_setup_i18n (); /* Set things up, including scalers / filters etc. which will now be internationalised correctly. diff --git a/src/tools/dvdomatic_batch.cc b/src/tools/dvdomatic_batch.cc new file mode 100644 index 000000000..102f29408 --- /dev/null +++ b/src/tools/dvdomatic_batch.cc @@ -0,0 +1,168 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include +#include "lib/version.h" +#include "lib/compose.hpp" +#include "lib/config.h" +#include "lib/util.h" +#include "wx/wx_util.h" +#include "wx/wx_ui_signaller.h" +#include "wx/batch_view.h" + +enum { + ID_file_quit = 1, + ID_help_about +}; + +void +setup_menu (wxMenuBar* m) +{ + wxMenu* file = new wxMenu; + file->Append (ID_file_quit, _("&Quit")); + + wxMenu* help = new wxMenu; + help->Append (ID_help_about, _("About")); + + m->Append (file, _("&File")); + m->Append (help, _("&Help")); +} + +class Frame : public wxFrame +{ +public: + Frame (wxString const & title) + : wxFrame (NULL, -1, title) + { + wxMenuBar* bar = new wxMenuBar; + setup_menu (bar); + SetMenuBar (bar); + + Connect (ID_file_quit, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::file_quit)); + Connect (ID_help_about, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::help_about)); + + wxPanel* panel = new wxPanel (this); + wxSizer* s = new wxBoxSizer (wxHORIZONTAL); + s->Add (panel, 1, wxEXPAND); + SetSizer (s); + + wxSizer* sizer = new wxBoxSizer (wxVERTICAL); + + BatchView* batch_view = new BatchView (panel); + sizer->Add (batch_view, 1, wxALL | wxEXPAND, 6); + + wxSizer* buttons = new wxBoxSizer (wxHORIZONTAL); + wxButton* add = new wxButton (panel, wxID_ANY, _("Add Film...")); + buttons->Add (add, 1, wxALL, 6); + wxButton* start = new wxButton (panel, wxID_ANY, _("Start...")); + buttons->Add (start, 1, wxALL, 6); + + sizer->Add (buttons, 0, wxALL, 6); + + panel->SetSizer (sizer); + } + +private: + void file_quit (wxCommandEvent &) + { + Close (true); + } + + void help_about (wxCommandEvent &) + { + wxAboutDialogInfo info; + info.SetName (_("DVD-o-matic Batch Converter")); + if (strcmp (dvdomatic_git_commit, "release") == 0) { + info.SetVersion (std_to_wx (String::compose ("version %1", dvdomatic_version))); + } else { + info.SetVersion (std_to_wx (String::compose ("version %1 git %2", dvdomatic_version, dvdomatic_git_commit))); + } + info.SetDescription (_("Free, open-source DCP generation from almost anything.")); + info.SetCopyright (_("(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen")); + + wxArrayString authors; + authors.Add (wxT ("Carl Hetherington")); + authors.Add (wxT ("Terrence Meiczinger")); + authors.Add (wxT ("Paul Davis")); + authors.Add (wxT ("Ole Laursen")); + info.SetDevelopers (authors); + + wxArrayString translators; + translators.Add (wxT ("Olivier Perriere")); + translators.Add (wxT ("Lilian Lefranc")); + translators.Add (wxT ("Thierry Journet")); + translators.Add (wxT ("Massimiliano Broggi")); + translators.Add (wxT ("Manuel AC")); + translators.Add (wxT ("Adam Klotblixt")); + info.SetTranslators (translators); + + info.SetWebSite (wxT ("http://carlh.net/software/dvdomatic")); + wxAboutBox (info); + } +}; + +class App : public wxApp +{ + bool OnInit () + { + if (!wxApp::OnInit()) { + return false; + } + +#ifdef DVDOMATIC_POSIX + unsetenv ("UBUNTU_MENUPROXY"); +#endif + + /* Enable i18n; this will create a Config object + to look for a force-configured language. This Config + object will be wrong, however, because dvdomatic_setup + hasn't yet been called and there aren't any scalers, filters etc. + set up yet. + */ + dvdomatic_setup_i18n (); + + /* Set things up, including scalers / filters etc. + which will now be internationalised correctly. + */ + dvdomatic_setup (); + + /* Force the configuration to be re-loaded correctly next + time it is needed. + */ + Config::drop (); + + Frame* f = new Frame (_("DVD-o-matic Batch Converter")); + SetTopWindow (f); + f->Maximize (); + f->Show (); + + ui_signaller = new wxUISignaller (this); + this->Connect (-1, wxEVT_IDLE, wxIdleEventHandler (App::idle)); + + return true; + } + + void idle (wxIdleEvent &) + { + ui_signaller->ui_idle (); + } +}; + +IMPLEMENT_APP (App) diff --git a/src/tools/wscript b/src/tools/wscript index 9f0f52152..f36f0abef 100644 --- a/src/tools/wscript +++ b/src/tools/wscript @@ -13,7 +13,7 @@ def build(bld): obj.target = t if not bld.env.DISABLE_GUI: - for t in ['dvdomatic', 'servomatic_gui']: + for t in ['dvdomatic', 'dvdomatic_batch', 'servomatic_gui']: obj = bld(features = 'cxx cxxprogram') obj.uselib = 'DCP OPENJPEG AVFORMAT AVFILTER AVCODEC AVUTIL SWSCALE POSTPROC' obj.includes = ['..'] diff --git a/src/wx/batch_view.cc b/src/wx/batch_view.cc new file mode 100644 index 000000000..bfe30d8fb --- /dev/null +++ b/src/wx/batch_view.cc @@ -0,0 +1,33 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "batch_view.h" + +BatchView::BatchView (wxWindow* parent) + : wxScrolledWindow (parent) +{ + _panel = new wxPanel (this); + wxSizer* sizer = new wxBoxSizer (wxVERTICAL); + sizer->Add (_panel, 1, wxEXPAND); + SetSizer (sizer); + + _table = new wxFlexGridSizer (5, 6, 6); + _table->AddGrowableCol (1, 1); + _panel->SetSizer (_table); +} diff --git a/src/wx/batch_view.h b/src/wx/batch_view.h new file mode 100644 index 000000000..6316ac745 --- /dev/null +++ b/src/wx/batch_view.h @@ -0,0 +1,30 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include + +class BatchView : public wxScrolledWindow +{ +public: + BatchView (wxWindow *); + +private: + wxPanel* _panel; + wxFlexGridSizer* _table; +}; diff --git a/src/wx/wscript b/src/wx/wscript index 42bb8ca88..f1c3d1a6a 100644 --- a/src/wx/wscript +++ b/src/wx/wscript @@ -6,6 +6,7 @@ import i18n sources = """ audio_dialog.cc audio_plot.cc + batch_view.cc config_dialog.cc dci_metadata_dialog.cc dir_picker_ctrl.cc diff --git a/src/wx/wx_util.cc b/src/wx/wx_util.cc index 77f5da293..1a7b73faf 100644 --- a/src/wx/wx_util.cc +++ b/src/wx/wx_util.cc @@ -25,6 +25,8 @@ #include #include #include "wx_util.h" +#include "config.h" +#include "util.h" using namespace std; using namespace boost; @@ -211,3 +213,39 @@ checked_set (wxRadioButton* widget, bool value) widget->SetValue (value); } } + +void +dvdomatic_setup_i18n () +{ + int language = wxLANGUAGE_DEFAULT; + + boost::optional config_lang = Config::instance()->language (); + if (config_lang && !config_lang->empty ()) { + wxLanguageInfo const * li = wxLocale::FindLanguageInfo (std_to_wx (config_lang.get ())); + if (li) { + language = li->Language; + } + } + + wxLocale* locale = 0; + if (wxLocale::IsAvailable (language)) { + locale = new wxLocale (language, wxLOCALE_LOAD_DEFAULT); + +#ifdef DVDOMATIC_WINDOWS + locale->AddCatalogLookupPathPrefix (std_to_wx (mo_path().string())); +#endif + + locale->AddCatalog (wxT ("libdvdomatic-wx")); + locale->AddCatalog (wxT ("dvdomatic")); + + if (!locale->IsOk()) { + delete locale; + locale = new wxLocale (wxLANGUAGE_ENGLISH); + language = wxLANGUAGE_ENGLISH; + } + } + + if (locale) { + dvdomatic_setup_gettext_i18n (wx_to_std (locale->GetCanonicalName ())); + } +} diff --git a/src/wx/wx_util.h b/src/wx/wx_util.h index b3ab706df..00a625e1c 100644 --- a/src/wx/wx_util.h +++ b/src/wx/wx_util.h @@ -36,6 +36,7 @@ extern wxStaticText* add_label_to_sizer (wxSizer *, wxWindow *, wxString, int pr extern wxStaticText* add_label_to_grid_bag_sizer (wxGridBagSizer *, wxWindow *, wxString, wxGBPosition, wxGBSpan span = wxDefaultSpan); extern std::string wx_to_std (wxString); extern wxString std_to_wx (std::string); +extern void dvdomatic_setup_i18n (); /** @class ThreadedStaticText * -- cgit v1.2.3 From ee191ec1dbea1fda4a93338c5a86e5f53c35efdc Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 4 May 2013 19:27:51 +0100 Subject: Missing i18n. --- src/wx/ffmpeg_content_dialog.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/wx/ffmpeg_content_dialog.cc b/src/wx/ffmpeg_content_dialog.cc index 540bae0a9..d1b7ffb1e 100644 --- a/src/wx/ffmpeg_content_dialog.cc +++ b/src/wx/ffmpeg_content_dialog.cc @@ -39,7 +39,7 @@ FFmpegContentDialog::FFmpegContentDialog (wxWindow* parent, shared_ptrAdd (_audio_description, 1, wxALIGN_CENTER_VERTICAL | wxLEFT, 8); - add_label_to_sizer (grid, this, "Subtitle stream"); + add_label_to_sizer (grid, this, _("Subtitle stream")); _subtitle_stream = new wxChoice (this, wxID_ANY); grid->Add (_subtitle_stream, 1, wxEXPAND | wxALL, 6); grid->AddSpacer (0); -- cgit v1.2.3 From db0ad7242d39f0fbae04bb6983021c60d57fdcf5 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 4 May 2013 20:58:31 +0100 Subject: Make batch converter basically work. --- src/lib/job.cc | 28 +++++++++++++++ src/lib/job.h | 4 +++ src/tools/dvdomatic.cc | 2 +- src/tools/dvdomatic_batch.cc | 85 ++++++++++++++++++++++++++++++++++++++++---- src/wx/batch_view.cc | 33 ----------------- src/wx/batch_view.h | 30 ---------------- src/wx/job_manager_view.cc | 50 ++++++++++++++++++++++---- src/wx/job_manager_view.h | 9 ++++- src/wx/wscript | 1 - 9 files changed, 162 insertions(+), 80 deletions(-) delete mode 100644 src/wx/batch_view.cc delete mode 100644 src/wx/batch_view.h (limited to 'src') diff --git a/src/lib/job.cc b/src/lib/job.cc index 1c66d87d3..9a5812fa7 100644 --- a/src/lib/job.cc +++ b/src/lib/job.cc @@ -26,6 +26,7 @@ #include #include "job.h" #include "util.h" +#include "cross.h" #include "i18n.h" @@ -155,6 +156,13 @@ Job::finished_cancelled () const return _state == FINISHED_CANCELLED; } +bool +Job::paused () const +{ + boost::mutex::scoped_lock lm (_state_mutex); + return _state == PAUSED; +} + /** Set the state of this job. * @param s New state. */ @@ -190,6 +198,10 @@ Job::set_progress (float p) _progress_unknown = false; _stack.back().normalised = p; boost::this_thread::interruption_point (); + + if (paused ()) { + dvdomatic_sleep (1); + } } /** @return fractional overall progress, or -1 if not known */ @@ -326,3 +338,19 @@ Job::cancel () _thread->interrupt (); _thread->join (); } + +void +Job::pause () +{ + if (running ()) { + set_state (PAUSED); + } +} + +void +Job::resume () +{ + if (paused ()) { + set_state (RUNNING); + } +} diff --git a/src/lib/job.h b/src/lib/job.h index fd036bce2..37fa56d20 100644 --- a/src/lib/job.h +++ b/src/lib/job.h @@ -47,6 +47,8 @@ public: virtual void run () = 0; void start (); + void pause (); + void resume (); void cancel (); bool is_new () const; @@ -55,6 +57,7 @@ public: bool finished_ok () const; bool finished_in_error () const; bool finished_cancelled () const; + bool paused () const; std::string error_summary () const; std::string error_details () const; @@ -79,6 +82,7 @@ protected: enum State { NEW, ///< the job hasn't been started yet RUNNING, ///< the job is running + PAUSED, ///< the job has been paused FINISHED_OK, ///< the job has finished successfully FINISHED_ERROR, ///< the job has finished in error FINISHED_CANCELLED ///< the job was cancelled diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 2740a0965..ff1560f0e 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -224,7 +224,7 @@ public: film_editor = new FilmEditor (film, panel); film_viewer = new FilmViewer (film, panel); - JobManagerView* job_manager_view = new JobManagerView (panel); + JobManagerView* job_manager_view = new JobManagerView (panel, static_cast (0)); _top_sizer = new wxBoxSizer (wxHORIZONTAL); _top_sizer->Add (film_editor, 0, wxALL, 6); diff --git a/src/tools/dvdomatic_batch.cc b/src/tools/dvdomatic_batch.cc index 102f29408..7a3d38d9c 100644 --- a/src/tools/dvdomatic_batch.cc +++ b/src/tools/dvdomatic_batch.cc @@ -18,17 +18,23 @@ */ #include +#include #include #include "lib/version.h" #include "lib/compose.hpp" #include "lib/config.h" #include "lib/util.h" +#include "lib/film.h" +#include "lib/job_manager.h" #include "wx/wx_util.h" #include "wx/wx_ui_signaller.h" -#include "wx/batch_view.h" +#include "wx/job_manager_view.h" + +using boost::shared_ptr; enum { - ID_file_quit = 1, + ID_file_add_film = 1, + ID_file_quit, ID_help_about }; @@ -36,6 +42,7 @@ void setup_menu (wxMenuBar* m) { wxMenu* file = new wxMenu; + file->Append (ID_file_add_film, _("&Add Film...")); file->Append (ID_file_quit, _("&Quit")); wxMenu* help = new wxMenu; @@ -55,6 +62,7 @@ public: setup_menu (bar); SetMenuBar (bar); + Connect (ID_file_add_film, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::file_add_film)); Connect (ID_file_quit, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::file_quit)); Connect (ID_help_about, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::help_about)); @@ -65,24 +73,60 @@ public: wxSizer* sizer = new wxBoxSizer (wxVERTICAL); - BatchView* batch_view = new BatchView (panel); - sizer->Add (batch_view, 1, wxALL | wxEXPAND, 6); + JobManagerView* job_manager_view = new JobManagerView (panel, JobManagerView::PAUSE); + sizer->Add (job_manager_view, 1, wxALL | wxEXPAND, 6); wxSizer* buttons = new wxBoxSizer (wxHORIZONTAL); wxButton* add = new wxButton (panel, wxID_ANY, _("Add Film...")); + add->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (Frame::add_film)); buttons->Add (add, 1, wxALL, 6); - wxButton* start = new wxButton (panel, wxID_ANY, _("Start...")); - buttons->Add (start, 1, wxALL, 6); sizer->Add (buttons, 0, wxALL, 6); panel->SetSizer (sizer); + + Connect (wxID_ANY, wxEVT_CLOSE_WINDOW, wxCloseEventHandler (Frame::close)); } private: + bool should_close () + { + if (!JobManager::instance()->work_to_do ()) { + return true; + } + + wxMessageDialog* d = new wxMessageDialog ( + 0, + _("There are unfinished jobs; are you sure you want to quit?"), + _("Unfinished jobs"), + wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION + ); + + bool const r = d->ShowModal() == wxID_YES; + d->Destroy (); + return r; + } + + void close (wxCloseEvent& ev) + { + if (!should_close ()) { + ev.Veto (); + return; + } + + ev.Skip (); + } + + void file_add_film (wxCommandEvent& ev) + { + add_film (ev); + } + void file_quit (wxCommandEvent &) { - Close (true); + if (should_close ()) { + Close (true); + } } void help_about (wxCommandEvent &) @@ -116,6 +160,33 @@ private: info.SetWebSite (wxT ("http://carlh.net/software/dvdomatic")); wxAboutBox (info); } + + void add_film (wxCommandEvent &) + { + wxDirDialog* c = new wxDirDialog (this, _("Select film to open"), wxStandardPaths::Get().GetDocumentsDir(), wxDEFAULT_DIALOG_STYLE | wxDD_DIR_MUST_EXIST); + int r; + while (1) { + r = c->ShowModal (); + if (r == wxID_OK && c->GetPath() == wxStandardPaths::Get().GetDocumentsDir()) { + error_dialog (this, _("You did not select a folder. Make sure that you select a folder before clicking Open.")); + } else { + break; + } + } + + if (r == wxID_OK) { + try { + shared_ptr film (new Film (wx_to_std (c->GetPath ()))); + film->make_dcp (); + } catch (std::exception& e) { + wxString p = c->GetPath (); + wxCharBuffer b = p.ToUTF8 (); + error_dialog (this, wxString::Format (_("Could not open film at %s (%s)"), p.data(), std_to_wx (e.what()).data())); + } + } + + c->Destroy (); + } }; class App : public wxApp diff --git a/src/wx/batch_view.cc b/src/wx/batch_view.cc deleted file mode 100644 index bfe30d8fb..000000000 --- a/src/wx/batch_view.cc +++ /dev/null @@ -1,33 +0,0 @@ -/* - Copyright (C) 2013 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include "batch_view.h" - -BatchView::BatchView (wxWindow* parent) - : wxScrolledWindow (parent) -{ - _panel = new wxPanel (this); - wxSizer* sizer = new wxBoxSizer (wxVERTICAL); - sizer->Add (_panel, 1, wxEXPAND); - SetSizer (sizer); - - _table = new wxFlexGridSizer (5, 6, 6); - _table->AddGrowableCol (1, 1); - _panel->SetSizer (_table); -} diff --git a/src/wx/batch_view.h b/src/wx/batch_view.h deleted file mode 100644 index 6316ac745..000000000 --- a/src/wx/batch_view.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - Copyright (C) 2013 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include - -class BatchView : public wxScrolledWindow -{ -public: - BatchView (wxWindow *); - -private: - wxPanel* _panel; - wxFlexGridSizer* _table; -}; diff --git a/src/wx/job_manager_view.cc b/src/wx/job_manager_view.cc index f7d2315cc..53be88ca7 100644 --- a/src/wx/job_manager_view.cc +++ b/src/wx/job_manager_view.cc @@ -34,15 +34,21 @@ using std::map; using boost::shared_ptr; /** Must be called in the GUI thread */ -JobManagerView::JobManagerView (wxWindow* parent) +JobManagerView::JobManagerView (wxWindow* parent, Buttons buttons) : wxScrolledWindow (parent) + , _buttons (buttons) { _panel = new wxPanel (this); wxSizer* sizer = new wxBoxSizer (wxVERTICAL); sizer->Add (_panel, 1, wxEXPAND); SetSizer (sizer); + + int N = 5; + if (buttons & PAUSE) { + ++N; + } - _table = new wxFlexGridSizer (5, 6, 6); + _table = new wxFlexGridSizer (N, 6, 6); _table->AddGrowableCol (1, 1); _panel->SetSizer (_table); @@ -78,21 +84,33 @@ JobManagerView::update () _table->Insert (index, m, 0, wxALIGN_CENTER_VERTICAL | wxALL, 6); JobRecord r; + int n = 1; r.finalised = false; r.gauge = new wxGauge (_panel, wxID_ANY, 100); - _table->Insert (index + 1, r.gauge, 1, wxEXPAND | wxLEFT | wxRIGHT); + _table->Insert (index + n, r.gauge, 1, wxEXPAND | wxLEFT | wxRIGHT); + ++n; r.message = new wxStaticText (_panel, wxID_ANY, std_to_wx ("")); - _table->Insert (index + 2, r.message, 1, wxALIGN_CENTER_VERTICAL | wxALL, 6); + _table->Insert (index + n, r.message, 1, wxALIGN_CENTER_VERTICAL | wxALL, 6); + ++n; r.cancel = new wxButton (_panel, wxID_ANY, _("Cancel")); r.cancel->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (JobManagerView::cancel_clicked), 0, this); - _table->Insert (index + 3, r.cancel, 1, wxALIGN_CENTER_VERTICAL | wxALL, 6); - + _table->Insert (index + n, r.cancel, 1, wxALIGN_CENTER_VERTICAL | wxALL, 6); + ++n; + + if (_buttons & PAUSE) { + r.pause = new wxButton (_panel, wxID_ANY, _("Pause")); + r.pause->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (JobManagerView::pause_clicked), 0, this); + _table->Insert (index + n, r.pause, 1, wxALIGN_CENTER_VERTICAL | wxALL, 6); + ++n; + } + r.details = new wxButton (_panel, wxID_ANY, _("Details...")); r.details->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (JobManagerView::details_clicked), 0, this); r.details->Enable (false); - _table->Insert (index + 4, r.details, 1, wxALIGN_CENTER_VERTICAL | wxALL, 6); + _table->Insert (index + n, r.details, 1, wxALIGN_CENTER_VERTICAL | wxALL, 6); + ++n; _job_records[*i] = r; } @@ -155,3 +173,21 @@ JobManagerView::cancel_clicked (wxCommandEvent& ev) } } } + +void +JobManagerView::pause_clicked (wxCommandEvent& ev) +{ + wxObject* o = ev.GetEventObject (); + for (map, JobRecord>::iterator i = _job_records.begin(); i != _job_records.end(); ++i) { + if (i->second.pause == o) { + if (i->first->paused()) { + i->first->resume (); + i->second.pause->SetLabel (_("Pause")); + } else { + i->first->pause (); + i->second.pause->SetLabel (_("Resume")); + } + } + } +} + diff --git a/src/wx/job_manager_view.h b/src/wx/job_manager_view.h index 72ac85c02..fc29eadb4 100644 --- a/src/wx/job_manager_view.h +++ b/src/wx/job_manager_view.h @@ -33,13 +33,18 @@ class Job; class JobManagerView : public wxScrolledWindow { public: - JobManagerView (wxWindow *); + enum Buttons { + PAUSE = 0x1, + }; + + JobManagerView (wxWindow *, Buttons); void update (); private: void periodic (wxTimerEvent &); void cancel_clicked (wxCommandEvent &); + void pause_clicked (wxCommandEvent &); void details_clicked (wxCommandEvent &); boost::shared_ptr _timer; @@ -49,9 +54,11 @@ private: wxGauge* gauge; wxStaticText* message; wxButton* cancel; + wxButton* pause; wxButton* details; bool finalised; }; std::map, JobRecord> _job_records; + Buttons _buttons; }; diff --git a/src/wx/wscript b/src/wx/wscript index f1c3d1a6a..42bb8ca88 100644 --- a/src/wx/wscript +++ b/src/wx/wscript @@ -6,7 +6,6 @@ import i18n sources = """ audio_dialog.cc audio_plot.cc - batch_view.cc config_dialog.cc dci_metadata_dialog.cc dir_picker_ctrl.cc -- cgit v1.2.3 From 8747970bc94161787d84d00835282ba8d3dc1135 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 5 May 2013 12:36:09 +0100 Subject: Fix broken layout with pause button. --- src/wx/job_manager_view.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/wx/job_manager_view.cc b/src/wx/job_manager_view.cc index 53be88ca7..5cd9f2e15 100644 --- a/src/wx/job_manager_view.cc +++ b/src/wx/job_manager_view.cc @@ -142,6 +142,9 @@ JobManagerView::update () } index += 5; + if (_buttons & PAUSE) { + ++index; + } } _table->Layout (); -- cgit v1.2.3 From 454a961e1a03f60cf05040b832c4f8f01b481fa7 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 6 May 2013 14:10:14 +0100 Subject: Add basic timeline window. --- src/lib/audio_content.cc | 6 ++ src/lib/audio_content.h | 2 + src/lib/content.h | 2 + src/lib/ffmpeg_content.cc | 6 ++ src/lib/ffmpeg_content.h | 1 + src/lib/film.cc | 7 ++ src/lib/film.h | 1 + src/lib/types.h | 1 + src/lib/video_content.cc | 6 ++ src/lib/video_content.h | 1 + src/wx/film_editor.cc | 13 ++++ src/wx/film_editor.h | 2 + src/wx/timeline.cc | 191 ++++++++++++++++++++++++++++++++++++++++++++++ src/wx/timeline.h | 37 +++++++++ src/wx/timeline_dialog.cc | 41 ++++++++++ src/wx/timeline_dialog.h | 34 +++++++++ src/wx/wscript | 2 + 17 files changed, 353 insertions(+) create mode 100644 src/wx/timeline.cc create mode 100644 src/wx/timeline.h create mode 100644 src/wx/timeline_dialog.cc create mode 100644 src/wx/timeline_dialog.h (limited to 'src') diff --git a/src/lib/audio_content.cc b/src/lib/audio_content.cc index 9968f4725..dfa48d97e 100644 --- a/src/lib/audio_content.cc +++ b/src/lib/audio_content.cc @@ -43,3 +43,9 @@ AudioContent::AudioContent (AudioContent const & o) { } + +Time +AudioContent::temporal_length () const +{ + return audio_length() / audio_frame_rate(); +} diff --git a/src/lib/audio_content.h b/src/lib/audio_content.h index 2362786d9..18107843c 100644 --- a/src/lib/audio_content.h +++ b/src/lib/audio_content.h @@ -45,6 +45,8 @@ public: virtual int audio_channels () const = 0; virtual ContentAudioFrame audio_length () const = 0; virtual int audio_frame_rate () const = 0; + + Time temporal_length () const; }; #endif diff --git a/src/lib/content.h b/src/lib/content.h index d39fc9e1a..e1cf41df0 100644 --- a/src/lib/content.h +++ b/src/lib/content.h @@ -25,6 +25,7 @@ #include #include #include +#include "types.h" namespace cxml { class Node; @@ -45,6 +46,7 @@ public: virtual std::string information () const = 0; virtual void as_xml (xmlpp::Node *) const; virtual boost::shared_ptr clone () const = 0; + virtual Time temporal_length () const = 0; boost::filesystem::path file () const { boost::mutex::scoped_lock lm (_mutex); diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index 719c4cb53..a61f777c8 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -280,3 +280,9 @@ FFmpegContent::clone () const { return shared_ptr (new FFmpegContent (*this)); } + +double +FFmpegContent::temporal_length () const +{ + return video_length() / video_frame_rate(); +} diff --git a/src/lib/ffmpeg_content.h b/src/lib/ffmpeg_content.h index 8bf4d42a5..6d7151498 100644 --- a/src/lib/ffmpeg_content.h +++ b/src/lib/ffmpeg_content.h @@ -89,6 +89,7 @@ public: std::string information () const; void as_xml (xmlpp::Node *) const; boost::shared_ptr clone () const; + double temporal_length () const; /* AudioContent */ int audio_channels () const; diff --git a/src/lib/film.cc b/src/lib/film.cc index 2dc97c1b3..a385625e7 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -1075,6 +1075,13 @@ Film::player () const return shared_ptr (new Player (shared_from_this (), _playlist)); } +shared_ptr +Film::playlist () const +{ + boost::mutex::scoped_lock lm (_state_mutex); + return _playlist; +} + ContentList Film::content () const { diff --git a/src/lib/film.h b/src/lib/film.h index 8748e18f5..e2f9b101a 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -103,6 +103,7 @@ public: bool have_dcp () const; boost::shared_ptr player () const; + boost::shared_ptr playlist () const; /* Proxies for some Playlist methods */ diff --git a/src/lib/types.h b/src/lib/types.h index c2bb9d853..f9e9b2f4b 100644 --- a/src/lib/types.h +++ b/src/lib/types.h @@ -29,6 +29,7 @@ class Content; typedef std::vector > ContentList; typedef int64_t ContentAudioFrame; typedef int ContentVideoFrame; +typedef double Time; /** @struct Crop * @brief A description of the crop of an image or video. diff --git a/src/lib/video_content.cc b/src/lib/video_content.cc index 9fb2b9bce..2af6ba908 100644 --- a/src/lib/video_content.cc +++ b/src/lib/video_content.cc @@ -104,3 +104,9 @@ VideoContent::information () const return s.str (); } + +Time +VideoContent::temporal_length () const +{ + return video_length() / video_frame_rate(); +} diff --git a/src/lib/video_content.h b/src/lib/video_content.h index 75e507d4d..b2ec87e2b 100644 --- a/src/lib/video_content.h +++ b/src/lib/video_content.h @@ -42,6 +42,7 @@ public: void as_xml (xmlpp::Node *) const; virtual std::string information () const; + Time temporal_length () const; ContentVideoFrame video_length () const { boost::mutex::scoped_lock lm (_mutex); diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index db3e03d78..c50782452 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -52,6 +52,7 @@ #include "imagemagick_content_dialog.h" #include "ffmpeg_content_dialog.h" #include "audio_mapping_view.h" +#include "timeline_dialog.h" using std::string; using std::cout; @@ -215,6 +216,7 @@ FilmEditor::connect_to_widgets () _content_edit->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_edit_clicked), 0, this); _content_earlier->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_earlier_clicked), 0, this); _content_later->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_later_clicked), 0, this); + _timeline_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::timeline_clicked), 0, this); _loop_content->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::loop_content_toggled), 0, this); _loop_count->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::loop_count_changed), 0, this); _left_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::left_crop_changed), 0, this); @@ -388,6 +390,9 @@ FilmEditor::make_content_panel () font.SetPointSize(font.GetPointSize() - 1); _playlist_description->SetFont(font); + _timeline_button = new wxButton (_content_panel, wxID_ANY, _("Timeline...")); + _content_sizer->Add (_timeline_button, 0, wxALL, 6); + _loop_count->SetRange (2, 1024); } @@ -1449,3 +1454,11 @@ FilmEditor::setup_playlist_description () _playlist_description->SetLabel (std_to_wx (_film->playlist_description ())); } + +void +FilmEditor::timeline_clicked (wxCommandEvent &) +{ + TimelineDialog* d = new TimelineDialog (this, _film->playlist ()); + d->ShowModal (); + d->Destroy (); +} diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index baaeb46d7..fddd213b9 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -93,6 +93,7 @@ private: void edit_filters_clicked (wxCommandEvent &); void loop_content_toggled (wxCommandEvent &); void loop_count_changed (wxCommandEvent &); + void timeline_clicked (wxCommandEvent &); /* Handle changes to the model */ void film_changed (Film::Property); @@ -145,6 +146,7 @@ private: wxTextCtrl* _content_information; wxCheckBox* _loop_content; wxSpinCtrl* _loop_count; + wxButton* _timeline_button; wxStaticText* _playlist_description; wxButton* _edit_dci_button; wxChoice* _format; diff --git a/src/wx/timeline.cc b/src/wx/timeline.cc new file mode 100644 index 000000000..828756362 --- /dev/null +++ b/src/wx/timeline.cc @@ -0,0 +1,191 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include +#include "timeline.h" +#include "wx_util.h" +#include "playlist.h" + +using std::list; +using std::cout; +using std::max; +using boost::shared_ptr; + +int const Timeline::_track_height = 64; + +Timeline::Timeline (wxWindow* parent, shared_ptr pl) + : wxPanel (parent) + , _playlist (pl) +{ + SetDoubleBuffered (true); + + Connect (wxID_ANY, wxEVT_PAINT, wxPaintEventHandler (Timeline::paint), 0, this); + + if (pl->audio_from() == Playlist::AUDIO_FFMPEG) { + SetMinSize (wxSize (640, _track_height * 2 + 96)); + } else { + SetMinSize (wxSize (640, _track_height * (max (1UL, pl->audio().size()) + 1) + 96)); + } +} + +template +int +plot_content_list ( + list > content, wxGraphicsContext* gc, int x, int y, double pixels_per_second, int track_height, wxString type, bool consecutive + ) +{ + Time t = 0; + for (typename list >::iterator i = content.begin(); i != content.end(); ++i) { + Time const len = (*i)->temporal_length (); + wxGraphicsPath path = gc->CreatePath (); + path.MoveToPoint (x + t * pixels_per_second, y); + path.AddLineToPoint (x + (t + len) * pixels_per_second, y); + path.AddLineToPoint (x + (t + len) * pixels_per_second, y + track_height); + path.AddLineToPoint (x + t * pixels_per_second, y + track_height); + path.AddLineToPoint (x + t * pixels_per_second, y); + gc->StrokePath (path); + gc->FillPath (path); + + wxString name = wxString::Format ("%s [%s]", std_to_wx ((*i)->file().filename().string()), type); + wxDouble name_width; + wxDouble name_height; + wxDouble name_descent; + wxDouble name_leading; + gc->GetTextExtent (name, &name_width, &name_height, &name_descent, &name_leading); + + gc->Clip (wxRegion (x + t * pixels_per_second, y, len * pixels_per_second, track_height)); + gc->DrawText (name, t * pixels_per_second + 12, y + track_height - name_height - 4); + gc->ResetClip (); + + if (consecutive) { + t += len; + } else { + y += track_height; + } + } + + if (consecutive) { + y += track_height; + } + + return y; +} + +void +Timeline::paint (wxPaintEvent &) +{ + wxPaintDC dc (this); + + shared_ptr pl = _playlist.lock (); + if (!pl) { + return; + } + + wxGraphicsContext* gc = wxGraphicsContext::Create (dc); + if (!gc) { + return; + } + + int const x_offset = 8; + int y = 8; + int const width = GetSize().GetWidth(); + double const pixels_per_second = (width - x_offset * 2) / (pl->content_length() / pl->video_frame_rate()); + + gc->SetFont (gc->CreateFont (*wxNORMAL_FONT)); + + gc->SetPen (*wxBLACK_PEN); +#if wxMAJOR_VERSION == 2 && wxMINOR_VERSION >= 9 + gc->SetPen (*wxThePenList->FindOrCreatePen (wxColour (0, 0, 0), 4, wxPENSTYLE_SOLID)); + gc->SetBrush (*wxTheBrushList->FindOrCreateBrush (wxColour (149, 121, 232, 255), wxBRUSHSTYLE_SOLID)); +#else + gc->SetPen (*wxThePenList->FindOrCreatePen (wxColour (0, 0, 0), 4, SOLID)); + gc->SetBrush (*wxTheBrushList->FindOrCreateBrush (wxColour (149, 121, 232, 255), SOLID)); +#endif + y = plot_content_list (pl->video (), gc, x_offset, y, pixels_per_second, _track_height, _("video"), true); + +#if wxMAJOR_VERSION == 2 && wxMINOR_VERSION >= 9 + gc->SetBrush (*wxTheBrushList->FindOrCreateBrush (wxColour (242, 92, 120, 255), wxBRUSHSTYLE_SOLID)); +#else + gc->SetBrush (*wxTheBrushList->FindOrCreateBrush (wxColour (242, 92, 120, 255), SOLID)); +#endif + y = plot_content_list (pl->audio (), gc, x_offset, y, pixels_per_second, _track_height, _("audio"), pl->audio_from() == Playlist::AUDIO_FFMPEG); + + /* Time axis */ + +#if wxMAJOR_VERSION == 2 && wxMINOR_VERSION >= 9 + gc->SetPen (*wxThePenList->FindOrCreatePen (wxColour (0, 0, 0), 1, wxPENSTYLE_SOLID)); +#else + gc->SetPen (*wxThePenList->FindOrCreatePen (wxColour (0, 0, 0), 1, SOLID)); +#endif + + int mark_interval = rint (128 / pixels_per_second); + if (mark_interval > 5) { + mark_interval -= mark_interval % 5; + } + if (mark_interval > 10) { + mark_interval -= mark_interval % 10; + } + if (mark_interval > 60) { + mark_interval -= mark_interval % 60; + } + if (mark_interval > 3600) { + mark_interval -= mark_interval % 3600; + } + + if (mark_interval < 1) { + mark_interval = 1; + } + + wxGraphicsPath path = gc->CreatePath (); + path.MoveToPoint (x_offset, y + 40); + path.AddLineToPoint (width, y + 40); + gc->StrokePath (path); + + double t = 0; + while ((t * pixels_per_second) < width) { + wxGraphicsPath path = gc->CreatePath (); + path.MoveToPoint (x_offset + t * pixels_per_second, y + 36); + path.AddLineToPoint (x_offset + t * pixels_per_second, y + 44); + gc->StrokePath (path); + + int tc = t; + int const h = tc / 3600; + tc -= h * 3600; + int const m = tc / 60; + tc -= m * 60; + int const s = tc; + + wxString str = wxString::Format ("%02d:%02d:%02d", h, m, s); + wxDouble str_width; + wxDouble str_height; + wxDouble str_descent; + wxDouble str_leading; + gc->GetTextExtent (str, &str_width, &str_height, &str_descent, &str_leading); + + int const tx = x_offset + t * pixels_per_second; + if ((tx + str_width) < width) { + gc->DrawText (str, x_offset + t * pixels_per_second, y + 60); + } + t += mark_interval; + } + + delete gc; +} + diff --git a/src/wx/timeline.h b/src/wx/timeline.h new file mode 100644 index 000000000..48aebc637 --- /dev/null +++ b/src/wx/timeline.h @@ -0,0 +1,37 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include +#include + +class Playlist; + +class Timeline : public wxPanel +{ +public: + Timeline (wxWindow *, boost::shared_ptr); + +private: + void paint (wxPaintEvent &); + + static int const _track_height; + + boost::weak_ptr _playlist; +}; diff --git a/src/wx/timeline_dialog.cc b/src/wx/timeline_dialog.cc new file mode 100644 index 000000000..5633c29e7 --- /dev/null +++ b/src/wx/timeline_dialog.cc @@ -0,0 +1,41 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include +#include "timeline_dialog.h" +#include "wx_util.h" +#include "playlist.h" + +using std::list; +using std::cout; +using boost::shared_ptr; + +TimelineDialog::TimelineDialog (wxWindow* parent, shared_ptr pl) + : wxDialog (parent, wxID_ANY, _("Timeline"), wxDefaultPosition, wxSize (640, 512), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) + , _timeline (this, pl) +{ + wxBoxSizer* sizer = new wxBoxSizer (wxVERTICAL); + + sizer->Add (&_timeline, 1, wxEXPAND | wxALL, 12); + + SetSizer (sizer); + sizer->Layout (); + sizer->SetSizeHints (this); +} diff --git a/src/wx/timeline_dialog.h b/src/wx/timeline_dialog.h new file mode 100644 index 000000000..e58de5540 --- /dev/null +++ b/src/wx/timeline_dialog.h @@ -0,0 +1,34 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include +#include +#include "timeline.h" + +class Playlist; + +class TimelineDialog : public wxDialog +{ +public: + TimelineDialog (wxWindow *, boost::shared_ptr); + +private: + Timeline _timeline; +}; diff --git a/src/wx/wscript b/src/wx/wscript index 001e8469e..c63ef128d 100644 --- a/src/wx/wscript +++ b/src/wx/wscript @@ -22,6 +22,8 @@ sources = """ new_film_dialog.cc properties_dialog.cc server_dialog.cc + timeline.cc + timeline_dialog.cc wx_util.cc wx_ui_signaller.cc """ -- cgit v1.2.3 From be3aa4b102205b58c33d7bdfbfee743b5f6a5255 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 6 May 2013 14:21:21 +0100 Subject: Make timeline non-modal. --- src/wx/film_editor.cc | 11 ++++++++--- src/wx/film_editor.h | 2 ++ src/wx/timeline.cc | 9 +++++++++ src/wx/timeline.h | 1 + 4 files changed, 20 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index c50782452..a4afb6d69 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -73,6 +73,7 @@ FilmEditor::FilmEditor (shared_ptr f, wxWindow* parent) : wxPanel (parent) , _generally_sensitive (true) , _audio_dialog (0) + , _timeline_dialog (0) { wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); _notebook = new wxNotebook (this, wxID_ANY); @@ -1458,7 +1459,11 @@ FilmEditor::setup_playlist_description () void FilmEditor::timeline_clicked (wxCommandEvent &) { - TimelineDialog* d = new TimelineDialog (this, _film->playlist ()); - d->ShowModal (); - d->Destroy (); + if (_timeline_dialog) { + _timeline_dialog->Destroy (); + _timeline_dialog = 0; + } + + _timeline_dialog = new TimelineDialog (this, _film->playlist ()); + _timeline_dialog->Show (); } diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index fddd213b9..9e9cfb831 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -34,6 +34,7 @@ class wxListEvent; class Film; class AudioDialog; class AudioMappingView; +class TimelineDialog; /** @class FilmEditor * @brief A wx widget to edit a film's metadata, and perform various functions. @@ -188,4 +189,5 @@ private: bool _generally_sensitive; AudioDialog* _audio_dialog; + TimelineDialog* _timeline_dialog; }; diff --git a/src/wx/timeline.cc b/src/wx/timeline.cc index 828756362..52707e45c 100644 --- a/src/wx/timeline.cc +++ b/src/wx/timeline.cc @@ -27,6 +27,7 @@ using std::list; using std::cout; using std::max; using boost::shared_ptr; +using boost::bind; int const Timeline::_track_height = 64; @@ -43,6 +44,9 @@ Timeline::Timeline (wxWindow* parent, shared_ptr pl) } else { SetMinSize (wxSize (640, _track_height * (max (1UL, pl->audio().size()) + 1) + 96)); } + + pl->Changed.connect (bind (&Timeline::playlist_changed, this)); + pl->ContentChanged.connect (bind (&Timeline::playlist_changed, this)); } template @@ -189,3 +193,8 @@ Timeline::paint (wxPaintEvent &) delete gc; } +void +Timeline::playlist_changed () +{ + Refresh (); +} diff --git a/src/wx/timeline.h b/src/wx/timeline.h index 48aebc637..1993eb9c2 100644 --- a/src/wx/timeline.h +++ b/src/wx/timeline.h @@ -30,6 +30,7 @@ public: private: void paint (wxPaintEvent &); + void playlist_changed (); static int const _track_height; -- cgit v1.2.3 From 930f0b02333ecc0a3a53fa57d943375daae99314 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 6 May 2013 14:35:22 +0100 Subject: Fix daft inefficiency in ImageMagickDecoder. --- src/lib/imagemagick_decoder.cc | 24 +++++++++++++----------- src/lib/imagemagick_decoder.h | 1 + 2 files changed, 14 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/lib/imagemagick_decoder.cc b/src/lib/imagemagick_decoder.cc index 3888347ca..dd18ad64e 100644 --- a/src/lib/imagemagick_decoder.cc +++ b/src/lib/imagemagick_decoder.cc @@ -38,18 +38,20 @@ ImageMagickDecoder::ImageMagickDecoder (shared_ptr f, shared_ptrfile().string()); - libdcp::Size const s = libdcp::Size (image->columns(), image->rows()); - delete image; + if (!_native_size) { + using namespace MagickCore; + Magick::Image* image = new Magick::Image (_imagemagick_content->file().string()); + _native_size = libdcp::Size (image->columns(), image->rows()); + delete image; + } - return s; + return _native_size.get (); } int @@ -70,17 +72,17 @@ ImageMagickDecoder::pass () _position++; return false; } - + Magick::Image* magick_image = new Magick::Image (_imagemagick_content->file().string ()); + _native_size = libdcp::Size (magick_image->columns(), magick_image->rows()); - libdcp::Size size = native_size (); - _image.reset (new SimpleImage (PIX_FMT_RGB24, size, false)); + _image.reset (new SimpleImage (PIX_FMT_RGB24, _native_size.get(), false)); using namespace MagickCore; uint8_t* p = _image->data()[0]; - for (int y = 0; y < size.height; ++y) { - for (int x = 0; x < size.width; ++x) { + for (int y = 0; y < _native_size->height; ++y) { + for (int x = 0; x < _native_size->width; ++x) { Magick::Color c = magick_image->pixelColor (x, y); *p++ = c.redQuantum() * 255 / QuantumRange; *p++ = c.greenQuantum() * 255 / QuantumRange; diff --git a/src/lib/imagemagick_decoder.h b/src/lib/imagemagick_decoder.h index e7c9dee9a..12a40976b 100644 --- a/src/lib/imagemagick_decoder.h +++ b/src/lib/imagemagick_decoder.h @@ -65,4 +65,5 @@ private: boost::shared_ptr _imagemagick_content; boost::shared_ptr _image; ContentVideoFrame _position; + mutable boost::optional _native_size; }; -- cgit v1.2.3 From 74040395aa25ade07f62f97d8a199b919b7487a2 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 6 May 2013 14:51:14 +0100 Subject: Re-use ImageMagickDecoders when possible. --- src/lib/imagemagick_decoder.h | 4 ++++ src/lib/player.cc | 17 +++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/lib/imagemagick_decoder.h b/src/lib/imagemagick_decoder.h index 12a40976b..cb68655ce 100644 --- a/src/lib/imagemagick_decoder.h +++ b/src/lib/imagemagick_decoder.h @@ -40,6 +40,10 @@ public: bool seek (double); bool pass (); + boost::shared_ptr content () const { + return _imagemagick_content; + } + protected: PixelFormat pixel_format () const; diff --git a/src/lib/player.cc b/src/lib/player.cc index a3d52f43e..d86437cd2 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -219,6 +219,8 @@ Player::seek_forward () void Player::setup_decoders () { + vector > old_video_decoders = _video_decoders; + _video_decoders.clear (); _video_decoder = 0; _audio_decoders.clear (); @@ -260,10 +262,21 @@ Player::setup_decoders () shared_ptr ic = dynamic_pointer_cast (*i); if (ic) { video_content = ic; - video_decoder.reset (new ImageMagickDecoder (_film, ic)); + + /* See if we can re-use an old ImageMagickDecoder */ + for (vector >::const_iterator i = old_video_decoders.begin(); i != old_video_decoders.end(); ++i) { + shared_ptr imd = dynamic_pointer_cast (*i); + if (imd && imd->content() == ic) { + video_decoder = *i; + } + } + + if (!video_decoder) { + video_decoder.reset (new ImageMagickDecoder (_film, ic)); + video_decoder->connect_video (shared_from_this ()); + } } - video_decoder->connect_video (shared_from_this ()); _video_decoders.push_back (video_decoder); _video_start.push_back (video_so_far); video_so_far += video_content->video_length() / video_content->video_frame_rate(); -- cgit v1.2.3 From 9bf304a86a3df6f4b10a572d657b5d7beb910582 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 6 May 2013 14:57:20 +0100 Subject: Remove somewhat pointless playlist description. --- src/lib/film.cc | 6 ------ src/lib/film.h | 2 -- src/lib/playlist.cc | 48 ------------------------------------------------ src/lib/playlist.h | 2 -- src/wx/film_editor.cc | 20 -------------------- src/wx/film_editor.h | 2 -- 6 files changed, 80 deletions(-) (limited to 'src') diff --git a/src/lib/film.cc b/src/lib/film.cc index a385625e7..b8102d315 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -1167,12 +1167,6 @@ Film::has_subtitles () const return _playlist->has_subtitles (); } -string -Film::playlist_description () const -{ - return _playlist->description (); -} - void Film::set_audio_mapping (AudioMapping m) { diff --git a/src/lib/film.h b/src/lib/film.h index e2f9b101a..18255a15e 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -122,8 +122,6 @@ public: ContentVideoFrame content_length () const; - std::string playlist_description () const; - void set_loop (int); int loop () const; diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index 6913874b9..f1dd881b3 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -430,51 +430,3 @@ Playlist::has_subtitles () const return !fc->subtitle_streams().empty(); } - -string -Playlist::description () const -{ - stringstream s; - - if (_video.empty ()) { - s << _("There is no video.") << "\n"; - } else { - s << _("Video will come from "); - list >::const_iterator i = _video.begin(); - while (i != _video.end ()) { - s << (*i)->file().filename().string(); - ++i; - if (i != _video.end ()) { - s << ", "; - } - } - if (_video.size() > 1) { - s << " " << _("in sequence."); - } - s << "\n"; - } - - if (_audio.empty ()) { - s << _("There is no audio.") << "\n"; - } else { - if (_audio_from == AUDIO_FFMPEG) { - s << _("Audio will come from the video files.") << "\n"; - } else { - s << _("Audio will come from "); - list >::const_iterator i = _audio.begin(); - while (i != _audio.end ()) { - s << (*i)->file().filename().string(); - ++i; - if (i != _audio.end ()) { - s << ", "; - } - } - if (_audio.size() > 1) { - s << _(" run simultaneously."); - } - s << "\n"; - } - } - - return s.str (); -} diff --git a/src/lib/playlist.h b/src/lib/playlist.h index cea41ab32..e6acff694 100644 --- a/src/lib/playlist.h +++ b/src/lib/playlist.h @@ -88,8 +88,6 @@ public: return _content; } - std::string description () const; - boost::shared_ptr ffmpeg () const; std::list > video () const { diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index a4afb6d69..a9aa155af 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -384,13 +384,6 @@ FilmEditor::make_content_panel () add_label_to_sizer (h, _content_panel, _("times")); _content_sizer->Add (h, 0, wxALL, 6); - _playlist_description = new wxStaticText (_content_panel, wxID_ANY, wxT ("\n \n \n \n ")); - _content_sizer->Add (_playlist_description, 0.25, wxEXPAND | wxALL, 6); - wxFont font = _playlist_description->GetFont(); - font.SetStyle(wxFONTSTYLE_ITALIC); - font.SetPointSize(font.GetPointSize() - 1); - _playlist_description->SetFont(font); - _timeline_button = new wxButton (_content_panel, wxID_ANY, _("Timeline...")); _content_sizer->Add (_timeline_button, 0, wxALL, 6); @@ -1211,8 +1204,6 @@ FilmEditor::setup_content () /* Select the first item of content if non was selected before */ _content->SetItemState (0, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED); } - - setup_playlist_description (); } void @@ -1445,17 +1436,6 @@ FilmEditor::setup_loop_sensitivity () _loop_count->Enable (_loop_content->GetValue ()); } -void -FilmEditor::setup_playlist_description () -{ - if (!_film) { - _playlist_description->SetLabel (wxT ("")); - return; - } - - _playlist_description->SetLabel (std_to_wx (_film->playlist_description ())); -} - void FilmEditor::timeline_clicked (wxCommandEvent &) { diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index 9e9cfb831..685e7864f 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -114,7 +114,6 @@ private: void setup_content_information (); void setup_content_button_sensitivity (); void setup_loop_sensitivity (); - void setup_playlist_description (); void active_jobs_changed (bool); boost::shared_ptr selected_content (); @@ -148,7 +147,6 @@ private: wxCheckBox* _loop_content; wxSpinCtrl* _loop_count; wxButton* _timeline_button; - wxStaticText* _playlist_description; wxButton* _edit_dci_button; wxChoice* _format; wxStaticText* _format_description; -- cgit v1.2.3 From 84be56b8107b812f16b6b244f8184c0983eaed6f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 6 May 2013 15:14:12 +0100 Subject: Try to fix win32 build. --- src/wx/timeline.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/wx/timeline.cc b/src/wx/timeline.cc index 52707e45c..7e0ecf27e 100644 --- a/src/wx/timeline.cc +++ b/src/wx/timeline.cc @@ -42,7 +42,7 @@ Timeline::Timeline (wxWindow* parent, shared_ptr pl) if (pl->audio_from() == Playlist::AUDIO_FFMPEG) { SetMinSize (wxSize (640, _track_height * 2 + 96)); } else { - SetMinSize (wxSize (640, _track_height * (max (1UL, pl->audio().size()) + 1) + 96)); + SetMinSize (wxSize (640, _track_height * (max (size_t (1), pl->audio().size()) + 1) + 96)); } pl->Changed.connect (bind (&Timeline::playlist_changed, this)); -- cgit v1.2.3 From fdf7a3a9d7dbac9fe41a2e96b47f1d053b7b0f76 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 6 May 2013 15:41:51 +0100 Subject: Try to fix lack of redraw on resize on Windows; also corrupted background to checkbox in AudioMappingView. --- src/wx/audio_dialog.cc | 2 +- src/wx/audio_mapping_view.cc | 2 ++ src/wx/timeline_dialog.cc | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/wx/audio_dialog.cc b/src/wx/audio_dialog.cc index 15d746839..d1d13ab78 100644 --- a/src/wx/audio_dialog.cc +++ b/src/wx/audio_dialog.cc @@ -29,7 +29,7 @@ using boost::bind; using boost::optional; AudioDialog::AudioDialog (wxWindow* parent) - : wxDialog (parent, wxID_ANY, _("Audio"), wxDefaultPosition, wxSize (640, 512), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) + : wxDialog (parent, wxID_ANY, _("Audio"), wxDefaultPosition, wxSize (640, 512), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxFULL_REPAINT_ON_RESIZE) , _plot (0) { wxBoxSizer* sizer = new wxBoxSizer (wxHORIZONTAL); diff --git a/src/wx/audio_mapping_view.cc b/src/wx/audio_mapping_view.cc index a5dacdfc2..878db3af2 100644 --- a/src/wx/audio_mapping_view.cc +++ b/src/wx/audio_mapping_view.cc @@ -59,6 +59,8 @@ public: void Draw (wxGrid& grid, wxGridCellAttr &, wxDC& dc, const wxRect& rect, int row, int col, bool) { + dc.Clear (); + wxRendererNative::Get().DrawCheckBox ( &grid, dc, rect, diff --git a/src/wx/timeline_dialog.cc b/src/wx/timeline_dialog.cc index 5633c29e7..7a75044c9 100644 --- a/src/wx/timeline_dialog.cc +++ b/src/wx/timeline_dialog.cc @@ -28,7 +28,7 @@ using std::cout; using boost::shared_ptr; TimelineDialog::TimelineDialog (wxWindow* parent, shared_ptr pl) - : wxDialog (parent, wxID_ANY, _("Timeline"), wxDefaultPosition, wxSize (640, 512), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) + : wxDialog (parent, wxID_ANY, _("Timeline"), wxDefaultPosition, wxSize (640, 512), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxFULL_REPAINT_ON_RESIZE) , _timeline (this, pl) { wxBoxSizer* sizer = new wxBoxSizer (wxVERTICAL); -- cgit v1.2.3 From 8431f12672beee3becda5d4a076e53b54deab432 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 6 May 2013 15:45:01 +0100 Subject: Try to disable subtitle stream choice if there are none. --- src/wx/ffmpeg_content_dialog.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/wx/ffmpeg_content_dialog.cc b/src/wx/ffmpeg_content_dialog.cc index d1b7ffb1e..8adff59f4 100644 --- a/src/wx/ffmpeg_content_dialog.cc +++ b/src/wx/ffmpeg_content_dialog.cc @@ -56,6 +56,9 @@ FFmpegContentDialog::FFmpegContentDialog (wxWindow* parent, shared_ptrClear (); vector s = content->subtitle_streams (); + if (s.empty ()) { + _subtitle_stream->Enable (false); + } for (vector::iterator i = s.begin(); i != s.end(); ++i) { _subtitle_stream->Append (std_to_wx (i->name), new wxStringClientData (std_to_wx (lexical_cast (i->id)))); } -- cgit v1.2.3 From 4aa97882908622eaaeeddebf60a6c4bb0d39e328 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 6 May 2013 16:08:15 +0100 Subject: Better attempt at clearing background of check boxes. --- src/wx/audio_mapping_view.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/wx/audio_mapping_view.cc b/src/wx/audio_mapping_view.cc index 878db3af2..2625d0962 100644 --- a/src/wx/audio_mapping_view.cc +++ b/src/wx/audio_mapping_view.cc @@ -59,7 +59,12 @@ public: void Draw (wxGrid& grid, wxGridCellAttr &, wxDC& dc, const wxRect& rect, int row, int col, bool) { - dc.Clear (); +#if wxMAJOR_VERSION == 2 && wxMINOR_VERSION >= 9 + dc.SetPen (*wxThePenList->FindOrCreatePen (wxColour (255, 255, 255), 0, wxPENSTYLE_SOLID)); +#else + dc.SetPen (*wxThePenList->FindOrCreatePen (wxColour (255, 255, 255), 0, SOLID)); +#endif + dc.DrawRectangle (rect); wxRendererNative::Get().DrawCheckBox ( &grid, -- cgit v1.2.3 From d8d14ced78729f6f1bee8347bd0adc4e68a9f5f7 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 6 May 2013 16:12:49 +0100 Subject: Fix resizing/redraw problems on Windows. --- src/wx/audio_dialog.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/wx/audio_dialog.cc b/src/wx/audio_dialog.cc index 39650d157..d12b5516f 100644 --- a/src/wx/audio_dialog.cc +++ b/src/wx/audio_dialog.cc @@ -29,7 +29,7 @@ using boost::bind; using boost::optional; AudioDialog::AudioDialog (wxWindow* parent) - : wxDialog (parent, wxID_ANY, _("Audio"), wxDefaultPosition, wxSize (640, 512), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) + : wxDialog (parent, wxID_ANY, _("Audio"), wxDefaultPosition, wxSize (640, 512), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxFULL_REPAINT_ON_RESIZE) , _plot (0) { wxBoxSizer* sizer = new wxBoxSizer (wxHORIZONTAL); -- cgit v1.2.3 From af671aa256ae0d2fa38a6740cea7fc0f6b45b5b8 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 7 May 2013 09:48:47 +0100 Subject: Fix typo preventing audio sync fixes when audio follows video. --- src/lib/matcher.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/matcher.cc b/src/lib/matcher.cc index 9924c003a..2723f2a2d 100644 --- a/src/lib/matcher.cc +++ b/src/lib/matcher.cc @@ -110,7 +110,7 @@ Matcher::process_audio (boost::shared_ptr b, double t) if (!_had_first_video) { /* No video yet; we must postpone these data until we have some */ _pending_audio.push_back (AudioRecord (b, t)); - } else if (this_is_first_audio && !_had_first_video) { + } else if (this_is_first_audio && _had_first_video) { /* First audio since we got video */ _pending_audio.push_back (AudioRecord (b, t)); fix_start (_first_input.get ()); -- cgit v1.2.3 From 4ff5c21a9c3c2ea8ab3a253ef5658e3ee91e0bea Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 7 May 2013 10:18:33 +0100 Subject: Fix another bit of incorrect logic (this_is_first_audio was inverted). Also try to add _audio_starts_with_video mode to Matcher. --- src/lib/matcher.cc | 28 ++++++++++++++++++++++------ src/lib/matcher.h | 6 ++++++ 2 files changed, 28 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/lib/matcher.cc b/src/lib/matcher.cc index 2723f2a2d..3776d4fbc 100644 --- a/src/lib/matcher.cc +++ b/src/lib/matcher.cc @@ -34,7 +34,6 @@ Matcher::Matcher (shared_ptr log, int sample_rate, float frames_per_second) , _frames_per_second (frames_per_second) , _video_frames (0) , _audio_frames (0) - , _had_first_video (false) , _had_first_audio (false) { @@ -52,8 +51,11 @@ Matcher::process_video (boost::shared_ptr image, bool same, boost:: _first_input = t; } - bool const this_is_first_video = !_had_first_video; - _had_first_video = true; + bool const this_is_first_video = !_first_video; + + if (!_first_video) { + _first_video = t; + } if (this_is_first_video && _had_first_audio) { /* First video since we got audio */ @@ -104,13 +106,13 @@ Matcher::process_audio (boost::shared_ptr b, double t) _first_input = t; } - bool const this_is_first_audio = _had_first_audio; + bool const this_is_first_audio = !_had_first_audio; _had_first_audio = true; - if (!_had_first_video) { + if (!_first_video) { /* No video yet; we must postpone these data until we have some */ _pending_audio.push_back (AudioRecord (b, t)); - } else if (this_is_first_audio && _had_first_video) { + } else if (this_is_first_audio && _first_video) { /* First audio since we got video */ _pending_audio.push_back (AudioRecord (b, t)); fix_start (_first_input.get ()); @@ -145,6 +147,11 @@ Matcher::fix_start (double first_video) match (first_video - _pending_audio.front().time); for (list::iterator i = _pending_audio.begin(); i != _pending_audio.end(); ++i) { + if (_audio_starts_with_video) { + assert (_first_video); + assert (_first_audio); + i->time += _first_video.get() - _first_audio.get(); + } process_audio (i->audio, i->time); } @@ -211,3 +218,12 @@ Matcher::repeat_last_video () ++_video_frames; } +/** Set `audio starts with video' behaviour. If this is enabled, + * audio time stamps are adjusted so that the first audio is synced + * with the first video. + */ +void +Matcher::set_audio_starts_with_video (bool a) +{ + _audio_starts_with_video = a; +} diff --git a/src/lib/matcher.h b/src/lib/matcher.h index 41aa373a4..aab6adad9 100644 --- a/src/lib/matcher.h +++ b/src/lib/matcher.h @@ -25,6 +25,9 @@ class Matcher : public Processor, public TimedAudioSink, public TimedVideoSink, { public: Matcher (boost::shared_ptr log, int sample_rate, float frames_per_second); + + void set_audio_starts_with_video (bool); + void process_video (boost::shared_ptr i, bool, boost::shared_ptr s, double); void process_audio (boost::shared_ptr, double); void process_end (); @@ -55,9 +58,12 @@ private: std::list _pending_audio; boost::optional _first_input; + boost::optional _first_video; boost::shared_ptr _last_image; boost::shared_ptr _last_subtitle; bool _had_first_video; bool _had_first_audio; + + bool _audio_starts_with_video; }; -- cgit v1.2.3 From 213f1b6c74585a16ea48bdeb550dbc6d11bb0f74 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 7 May 2013 10:20:51 +0100 Subject: Revert "Fix another bit of incorrect logic (this_is_first_audio was inverted). Also try to add _audio_starts_with_video mode to Matcher." This reverts commit 4ff5c21a9c3c2ea8ab3a253ef5658e3ee91e0bea. --- src/lib/matcher.cc | 28 ++++++---------------------- src/lib/matcher.h | 6 ------ 2 files changed, 6 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/lib/matcher.cc b/src/lib/matcher.cc index 3776d4fbc..2723f2a2d 100644 --- a/src/lib/matcher.cc +++ b/src/lib/matcher.cc @@ -34,6 +34,7 @@ Matcher::Matcher (shared_ptr log, int sample_rate, float frames_per_second) , _frames_per_second (frames_per_second) , _video_frames (0) , _audio_frames (0) + , _had_first_video (false) , _had_first_audio (false) { @@ -51,11 +52,8 @@ Matcher::process_video (boost::shared_ptr image, bool same, boost:: _first_input = t; } - bool const this_is_first_video = !_first_video; - - if (!_first_video) { - _first_video = t; - } + bool const this_is_first_video = !_had_first_video; + _had_first_video = true; if (this_is_first_video && _had_first_audio) { /* First video since we got audio */ @@ -106,13 +104,13 @@ Matcher::process_audio (boost::shared_ptr b, double t) _first_input = t; } - bool const this_is_first_audio = !_had_first_audio; + bool const this_is_first_audio = _had_first_audio; _had_first_audio = true; - if (!_first_video) { + if (!_had_first_video) { /* No video yet; we must postpone these data until we have some */ _pending_audio.push_back (AudioRecord (b, t)); - } else if (this_is_first_audio && _first_video) { + } else if (this_is_first_audio && _had_first_video) { /* First audio since we got video */ _pending_audio.push_back (AudioRecord (b, t)); fix_start (_first_input.get ()); @@ -147,11 +145,6 @@ Matcher::fix_start (double first_video) match (first_video - _pending_audio.front().time); for (list::iterator i = _pending_audio.begin(); i != _pending_audio.end(); ++i) { - if (_audio_starts_with_video) { - assert (_first_video); - assert (_first_audio); - i->time += _first_video.get() - _first_audio.get(); - } process_audio (i->audio, i->time); } @@ -218,12 +211,3 @@ Matcher::repeat_last_video () ++_video_frames; } -/** Set `audio starts with video' behaviour. If this is enabled, - * audio time stamps are adjusted so that the first audio is synced - * with the first video. - */ -void -Matcher::set_audio_starts_with_video (bool a) -{ - _audio_starts_with_video = a; -} diff --git a/src/lib/matcher.h b/src/lib/matcher.h index aab6adad9..41aa373a4 100644 --- a/src/lib/matcher.h +++ b/src/lib/matcher.h @@ -25,9 +25,6 @@ class Matcher : public Processor, public TimedAudioSink, public TimedVideoSink, { public: Matcher (boost::shared_ptr log, int sample_rate, float frames_per_second); - - void set_audio_starts_with_video (bool); - void process_video (boost::shared_ptr i, bool, boost::shared_ptr s, double); void process_audio (boost::shared_ptr, double); void process_end (); @@ -58,12 +55,9 @@ private: std::list _pending_audio; boost::optional _first_input; - boost::optional _first_video; boost::shared_ptr _last_image; boost::shared_ptr _last_subtitle; bool _had_first_video; bool _had_first_audio; - - bool _audio_starts_with_video; }; -- cgit v1.2.3 From 188a4c094775a0fa8b69722bba7c18ae3e2bb5d3 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 7 May 2013 10:21:12 +0100 Subject: Fix more incorrect logic. --- src/lib/matcher.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/matcher.cc b/src/lib/matcher.cc index 2723f2a2d..f8d5c5fcd 100644 --- a/src/lib/matcher.cc +++ b/src/lib/matcher.cc @@ -104,7 +104,7 @@ Matcher::process_audio (boost::shared_ptr b, double t) _first_input = t; } - bool const this_is_first_audio = _had_first_audio; + bool const this_is_first_audio = !_had_first_audio; _had_first_audio = true; if (!_had_first_video) { -- cgit v1.2.3 From c2930f166cad691fb5302d9924e109443bf2365f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 7 May 2013 14:33:04 +0100 Subject: 2.8 fixes. --- src/wx/audio_mapping_view.cc | 2 +- src/wx/timeline.cc | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/wx/audio_mapping_view.cc b/src/wx/audio_mapping_view.cc index 2625d0962..093d25b7c 100644 --- a/src/wx/audio_mapping_view.cc +++ b/src/wx/audio_mapping_view.cc @@ -62,7 +62,7 @@ public: #if wxMAJOR_VERSION == 2 && wxMINOR_VERSION >= 9 dc.SetPen (*wxThePenList->FindOrCreatePen (wxColour (255, 255, 255), 0, wxPENSTYLE_SOLID)); #else - dc.SetPen (*wxThePenList->FindOrCreatePen (wxColour (255, 255, 255), 0, SOLID)); + dc.SetPen (*wxThePenList->FindOrCreatePen (wxColour (255, 255, 255), 0, wxSOLID)); #endif dc.DrawRectangle (rect); diff --git a/src/wx/timeline.cc b/src/wx/timeline.cc index 7e0ecf27e..253903888 100644 --- a/src/wx/timeline.cc +++ b/src/wx/timeline.cc @@ -67,7 +67,7 @@ plot_content_list ( gc->StrokePath (path); gc->FillPath (path); - wxString name = wxString::Format ("%s [%s]", std_to_wx ((*i)->file().filename().string()), type); + wxString name = wxString::Format (wxT ("%s [%s]"), std_to_wx ((*i)->file().filename().string()).data(), type.data()); wxDouble name_width; wxDouble name_height; wxDouble name_descent; @@ -119,15 +119,15 @@ Timeline::paint (wxPaintEvent &) gc->SetPen (*wxThePenList->FindOrCreatePen (wxColour (0, 0, 0), 4, wxPENSTYLE_SOLID)); gc->SetBrush (*wxTheBrushList->FindOrCreateBrush (wxColour (149, 121, 232, 255), wxBRUSHSTYLE_SOLID)); #else - gc->SetPen (*wxThePenList->FindOrCreatePen (wxColour (0, 0, 0), 4, SOLID)); - gc->SetBrush (*wxTheBrushList->FindOrCreateBrush (wxColour (149, 121, 232, 255), SOLID)); + gc->SetPen (*wxThePenList->FindOrCreatePen (wxColour (0, 0, 0), 4, wxSOLID)); + gc->SetBrush (*wxTheBrushList->FindOrCreateBrush (wxColour (149, 121, 232, 255), wxSOLID)); #endif y = plot_content_list (pl->video (), gc, x_offset, y, pixels_per_second, _track_height, _("video"), true); #if wxMAJOR_VERSION == 2 && wxMINOR_VERSION >= 9 gc->SetBrush (*wxTheBrushList->FindOrCreateBrush (wxColour (242, 92, 120, 255), wxBRUSHSTYLE_SOLID)); #else - gc->SetBrush (*wxTheBrushList->FindOrCreateBrush (wxColour (242, 92, 120, 255), SOLID)); + gc->SetBrush (*wxTheBrushList->FindOrCreateBrush (wxColour (242, 92, 120, 255), wxSOLID)); #endif y = plot_content_list (pl->audio (), gc, x_offset, y, pixels_per_second, _track_height, _("audio"), pl->audio_from() == Playlist::AUDIO_FFMPEG); @@ -136,7 +136,7 @@ Timeline::paint (wxPaintEvent &) #if wxMAJOR_VERSION == 2 && wxMINOR_VERSION >= 9 gc->SetPen (*wxThePenList->FindOrCreatePen (wxColour (0, 0, 0), 1, wxPENSTYLE_SOLID)); #else - gc->SetPen (*wxThePenList->FindOrCreatePen (wxColour (0, 0, 0), 1, SOLID)); + gc->SetPen (*wxThePenList->FindOrCreatePen (wxColour (0, 0, 0), 1, wxSOLID)); #endif int mark_interval = rint (128 / pixels_per_second); @@ -176,7 +176,7 @@ Timeline::paint (wxPaintEvent &) tc -= m * 60; int const s = tc; - wxString str = wxString::Format ("%02d:%02d:%02d", h, m, s); + wxString str = wxString::Format (wxT ("%02d:%02d:%02d"), h, m, s); wxDouble str_width; wxDouble str_height; wxDouble str_descent; -- cgit v1.2.3 From 9fa643bdebdcb39cca4b529f13fdd0fbfd721d58 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 7 May 2013 20:25:36 +0100 Subject: Catch exceptions on loading config. --- src/lib/config.cc | 11 +++++++++++ src/lib/config.h | 1 + 2 files changed, 12 insertions(+) (limited to 'src') diff --git a/src/lib/config.cc b/src/lib/config.cc index b6f464717..3beb0aea6 100644 --- a/src/lib/config.cc +++ b/src/lib/config.cc @@ -61,7 +61,11 @@ Config::Config () _allowed_dcp_frame_rates.push_back (48); _allowed_dcp_frame_rates.push_back (50); _allowed_dcp_frame_rates.push_back (60); +} +void +Config::read () +{ if (!boost::filesystem::exists (file (false))) { read_old_metadata (); return; @@ -199,6 +203,13 @@ Config::instance () { if (_instance == 0) { _instance = new Config; + try { + _instance->read (); + } catch (...) { + /* configuration load failed; never mind, just + stick with the default. + */ + } } return _instance; diff --git a/src/lib/config.h b/src/lib/config.h index 05005e590..96aa4e449 100644 --- a/src/lib/config.h +++ b/src/lib/config.h @@ -213,6 +213,7 @@ public: private: Config (); std::string file (bool) const; + void read (); void read_old_metadata (); /** number of threads to use for J2K encoding on the local machine */ -- cgit v1.2.3 From eecad2ada9fe83ab90be735c2aa333dba73434b4 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 7 May 2013 20:53:44 +0100 Subject: Fix silly bug introduced when speeding up ImageMagick content. --- src/lib/player.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/player.cc b/src/lib/player.cc index d86437cd2..68a962cdd 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -78,7 +78,7 @@ Player::pass () if (_video && _video_decoder < _video_decoders.size ()) { /* Run video decoder; this may also produce audio */ - + if (_video_decoders[_video_decoder]->pass ()) { _video_decoder++; } @@ -257,6 +257,8 @@ Player::setup_decoders () audio_content = fc; video_decoder = fd; audio_decoder = fd; + + video_decoder->connect_video (shared_from_this ()); } shared_ptr ic = dynamic_pointer_cast (*i); -- cgit v1.2.3 From 1f4a21c0da3a917a5ff7743a577cc0f210fa86d8 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 7 May 2013 21:02:13 +0100 Subject: Stop SndfileDecoder with no audio emitting lots of silence. --- src/lib/sndfile_decoder.cc | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/lib/sndfile_decoder.cc b/src/lib/sndfile_decoder.cc index fdaf2eeaa..d70478a1b 100644 --- a/src/lib/sndfile_decoder.cc +++ b/src/lib/sndfile_decoder.cc @@ -102,14 +102,20 @@ SndfileDecoder::pass () sf_count_t const block = _audio_stream->sample_rate() / 2; shared_ptr audio (new AudioBuffers (_audio_stream->channels(), block)); sf_count_t const this_time = min (block, _frames - _done); + bool have_sound = false; for (size_t i = 0; i < _sndfiles.size(); ++i) { if (!_sndfiles[i]) { audio->make_silent (i); } else { sf_read_float (_sndfiles[i], audio->data(i), this_time); + have_sound = true; } } + if (!have_sound) { + return true; + } + audio->set_frames (this_time); Audio (audio, double(_done) / _audio_stream->sample_rate()); _done += this_time; -- cgit v1.2.3 From b66a082df05202f0119b16853f04034cf85ec80b Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 7 May 2013 23:03:06 +0100 Subject: Another attempt to fix matching and confusions about the delay line. --- src/lib/delay_line.cc | 2 +- src/lib/matcher.cc | 83 +++++++++++++++++++++++++++++---------------------- src/lib/matcher.h | 17 ++++++++++- 3 files changed, 64 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/lib/delay_line.cc b/src/lib/delay_line.cc index b0180800a..f6af6f9b1 100644 --- a/src/lib/delay_line.cc +++ b/src/lib/delay_line.cc @@ -50,7 +50,7 @@ void DelayLine::process_video (shared_ptr image, bool same, boost::shared_ptr sub, double t) { if (_seconds < 0) { - t += _seconds; + t -= _seconds; } Video (image, same, sub, t); diff --git a/src/lib/matcher.cc b/src/lib/matcher.cc index f8d5c5fcd..4acb82afa 100644 --- a/src/lib/matcher.cc +++ b/src/lib/matcher.cc @@ -48,45 +48,47 @@ Matcher::process_video (boost::shared_ptr image, bool same, boost:: _log->log(String::compose("Matcher video @ %1 [audio=%2, video=%3, pending_audio=%4]", t, _audio_frames, _video_frames, _pending_audio.size())); - if (!_first_input) { + if (!_first_input || t < _first_input.get()) { _first_input = t; } bool const this_is_first_video = !_had_first_video; _had_first_video = true; - if (this_is_first_video && _had_first_audio) { + if (!_had_first_audio) { + /* No audio yet; we must postpone these data until we have some */ + _pending_video.push_back (VideoRecord (image, same, sub, t)); + } else if (this_is_first_video && _had_first_audio) { /* First video since we got audio */ - fix_start (t); - } - - /* Video before audio is fine, since we can make up an arbitrary difference - with audio samples (contrasting with video which is quantised to frames) - */ + _pending_video.push_back (VideoRecord (image, same, sub, t)); + fix_start (); + } else { + /* Normal running */ - /* Difference between where this video is and where it should be */ - double const delta = t - _first_input.get() - _video_frames / _frames_per_second; - double const one_frame = 1 / _frames_per_second; - - if (delta > one_frame) { - /* Insert frames to make up the difference */ - int const extra = rint (delta / one_frame); - for (int i = 0; i < extra; ++i) { - repeat_last_video (); - _log->log (String::compose ("Extra video frame inserted at %1s", _video_frames / _frames_per_second)); + /* Difference between where this video is and where it should be */ + double const delta = t - _first_input.get() - _video_frames / _frames_per_second; + double const one_frame = 1 / _frames_per_second; + + if (delta > one_frame) { + /* Insert frames to make up the difference */ + int const extra = rint (delta / one_frame); + for (int i = 0; i < extra; ++i) { + repeat_last_video (); + _log->log (String::compose ("Extra video frame inserted at %1s", _video_frames / _frames_per_second)); + } } - } - if (delta > -one_frame) { - Video (image, same, sub); - ++_video_frames; - } else { - /* We are omitting a frame to keep things right */ - _log->log (String::compose ("Frame removed at %1s", t)); + if (delta > -one_frame) { + Video (image, same, sub); + ++_video_frames; + } else { + /* We are omitting a frame to keep things right */ + _log->log (String::compose ("Frame removed at %1s; delta %2; first input was at %3", t, delta, _first_input.get())); + } + + _last_image = image; + _last_subtitle = sub; } - - _last_image = image; - _last_subtitle = sub; } void @@ -95,12 +97,12 @@ Matcher::process_audio (boost::shared_ptr b, double t) _channels = b->channels (); _log->log (String::compose ( - "Matcher audio (%1 frames) @ %2 [video=%3, audio=%4, pending_audio=%5]", - b->frames(), t, _video_frames, _audio_frames, _pending_audio.size() + "Matcher audio (%1 frames) @ %2 [video=%3, audio=%4, pending_video=%5, pending_audio=%6]", + b->frames(), t, _video_frames, _audio_frames, _pending_video.size(), _pending_audio.size() ) ); - if (!_first_input) { + if (!_first_input || t < _first_input.get()) { _first_input = t; } @@ -113,9 +115,11 @@ Matcher::process_audio (boost::shared_ptr b, double t) } else if (this_is_first_audio && _had_first_video) { /* First audio since we got video */ _pending_audio.push_back (AudioRecord (b, t)); - fix_start (_first_input.get ()); + fix_start (); } else { - /* Normal running. We assume audio time stamps are consecutive */ + /* Normal running. We assume audio time stamps are consecutive, so there's no equivalent of + the checking / insertion of repeat frames that there is for video. + */ Audio (b); _audio_frames += b->frames (); } @@ -136,13 +140,20 @@ Matcher::process_end () } void -Matcher::fix_start (double first_video) +Matcher::fix_start () { + assert (!_pending_video.empty ()); assert (!_pending_audio.empty ()); + + _log->log (String::compose ("Fixing start; video at %1, audio at %2", _pending_video.front().time, _pending_audio.front().time)); + + match (_pending_video.front().time - _pending_audio.front().time); - _log->log (String::compose ("Fixing start; video at %1, audio at %2", first_video, _pending_audio.front().time)); + for (list::iterator i = _pending_video.begin(); i != _pending_video.end(); ++i) { + process_video (i->image, i->same, i->subtitle, i->time); + } - match (first_video - _pending_audio.front().time); + _pending_video.clear (); for (list::iterator i = _pending_audio.begin(); i != _pending_audio.end(); ++i) { process_audio (i->audio, i->time); diff --git a/src/lib/matcher.h b/src/lib/matcher.h index 41aa373a4..d6778da11 100644 --- a/src/lib/matcher.h +++ b/src/lib/matcher.h @@ -30,7 +30,7 @@ public: void process_end (); private: - void fix_start (double); + void fix_start (); void match (double); void repeat_last_video (); @@ -42,6 +42,20 @@ private: boost::optional _size; boost::optional _channels; + struct VideoRecord { + VideoRecord (boost::shared_ptr i, bool s, boost::shared_ptr u, double t) + : image (i) + , same (s) + , subtitle (u) + , time (t) + {} + + boost::shared_ptr image; + bool same; + boost::shared_ptr subtitle; + double time; + }; + struct AudioRecord { AudioRecord (boost::shared_ptr a, double t) : audio (a) @@ -52,6 +66,7 @@ private: double time; }; + std::list _pending_video; std::list _pending_audio; boost::optional _first_input; -- cgit v1.2.3 From 2eb2945c58f3c0f7bfd49e218458710978777699 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 7 May 2013 23:22:56 +0100 Subject: Basic auto-scroll of job view (#129). --- src/wx/job_manager_view.cc | 19 +++++++++++++++++++ src/wx/job_manager_view.h | 1 + 2 files changed, 20 insertions(+) (limited to 'src') diff --git a/src/wx/job_manager_view.cc b/src/wx/job_manager_view.cc index a7788ddd0..c339d26bb 100644 --- a/src/wx/job_manager_view.cc +++ b/src/wx/job_manager_view.cc @@ -79,6 +79,7 @@ JobManagerView::update () JobRecord r; r.finalised = false; + r.scroll_nudged = false; r.gauge = new wxGauge (_panel, wxID_ANY, 100); _table->Insert (index + 1, r.gauge, 1, wxEXPAND | wxLEFT | wxRIGHT); @@ -95,6 +96,7 @@ JobManagerView::update () _table->Insert (index + 4, r.details, 1, wxALIGN_CENTER_VERTICAL | wxALL, 6); _job_records[*i] = r; + } string const st = (*i)->status (); @@ -108,8 +110,25 @@ JobManagerView::update () checked_set (_job_records[*i].message, wx_to_std (_("Running"))); _job_records[*i].gauge->Pulse (); } + } + if (!_job_records[*i].scroll_nudged && ((*i)->running () || (*i)->finished())) { + int x, y; + _job_records[*i].gauge->GetPosition (&x, &y); + int px, py; + GetScrollPixelsPerUnit (&px, &py); + int vx, vy; + GetViewStart (&vx, &vy); + int sx, sy; + GetClientSize (&sx, &sy); + + if (y > (vy * py + sy / 2)) { + Scroll (-1, y / py); + _job_records[*i].scroll_nudged = true; + } + } + if ((*i)->finished() && !_job_records[*i].finalised) { checked_set (_job_records[*i].message, st); if (!(*i)->finished_cancelled()) { diff --git a/src/wx/job_manager_view.h b/src/wx/job_manager_view.h index 72ac85c02..6343d78af 100644 --- a/src/wx/job_manager_view.h +++ b/src/wx/job_manager_view.h @@ -51,6 +51,7 @@ private: wxButton* cancel; wxButton* details; bool finalised; + bool scroll_nudged; }; std::map, JobRecord> _job_records; -- cgit v1.2.3 From 83742c7e6edcf958e0820abc77c029f4ada4880f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 8 May 2013 16:58:19 +0100 Subject: Better fix for still (no sound) DCP crash. --- src/lib/encoder.cc | 4 ++++ src/lib/sndfile_decoder.cc | 6 ------ src/lib/transcoder.cc | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index cff9899ac..8549962ff 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -296,6 +296,10 @@ Encoder::process_video (shared_ptr image, bool same, boost::shared_ void Encoder::process_audio (shared_ptr data) { + if (!data->frames ()) { + return; + } + #if HAVE_SWRESAMPLE /* Maybe sample-rate convert */ if (_swr_context) { diff --git a/src/lib/sndfile_decoder.cc b/src/lib/sndfile_decoder.cc index d70478a1b..fdaf2eeaa 100644 --- a/src/lib/sndfile_decoder.cc +++ b/src/lib/sndfile_decoder.cc @@ -102,20 +102,14 @@ SndfileDecoder::pass () sf_count_t const block = _audio_stream->sample_rate() / 2; shared_ptr audio (new AudioBuffers (_audio_stream->channels(), block)); sf_count_t const this_time = min (block, _frames - _done); - bool have_sound = false; for (size_t i = 0; i < _sndfiles.size(); ++i) { if (!_sndfiles[i]) { audio->make_silent (i); } else { sf_read_float (_sndfiles[i], audio->data(i), this_time); - have_sound = true; } } - if (!have_sound) { - return true; - } - audio->set_frames (this_time); Audio (audio, double(_done) / _audio_stream->sample_rate()); _done += this_time; diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc index faafcaf8b..48cf402d7 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -56,7 +56,7 @@ Transcoder::Transcoder (shared_ptr f, DecodeOptions o, Job* j, shared_ptr< assert (_encoder); shared_ptr st = f->audio_stream(); - if (st) { + if (st && st->sample_rate ()) { _matcher.reset (new Matcher (f->log(), st->sample_rate(), f->source_frame_rate())); } _delay_line.reset (new DelayLine (f->log(), f->audio_delay() / 1000.0f)); -- cgit v1.2.3 From 6925163806c96442f624d0d60c696e3da5bc996e Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 8 May 2013 19:17:44 +0100 Subject: Couple of fixes to updating things when removing content. --- src/wx/film_editor.cc | 2 ++ src/wx/film_viewer.cc | 8 ++------ 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index a9aa155af..894e2ae2b 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -1204,6 +1204,8 @@ FilmEditor::setup_content () /* Select the first item of content if non was selected before */ _content->SetItemState (0, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED); } + + setup_content_information (); } void diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index e9a1a574b..03f0ca646 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -258,12 +258,8 @@ FilmViewer::paint_panel (wxPaintEvent &) void FilmViewer::slider_moved (wxScrollEvent &) { - if (!_film || !_player) { - return; - } - - if (_player->seek (_slider->GetValue() * _film->video_length() / (4096 * _film->video_frame_rate()))) { - return; + if (_film && _player) { + _player->seek (_slider->GetValue() * _film->video_length() / (4096 * _film->video_frame_rate())); } get_frame (); -- cgit v1.2.3 From 43e8e186cbce3c04ae4bcb4834fa9562771d3356 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 8 May 2013 19:21:51 +0100 Subject: Fix subtitle control visibility (#139). --- src/wx/film_editor.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 894e2ae2b..884904e51 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -1096,7 +1096,7 @@ FilmEditor::setup_subtitle_control_sensitivity () { bool h = false; if (_generally_sensitive && _film) { - h = !_film->has_subtitles (); + h = _film->has_subtitles (); } _with_subtitles->Enable (h); -- cgit v1.2.3 From 72d36df1174810d8d871a06d085b81b1652edf67 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 8 May 2013 19:25:08 +0100 Subject: Basic re-enabling of the properties window (#138). --- src/wx/properties_dialog.cc | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/wx/properties_dialog.cc b/src/wx/properties_dialog.cc index 06e245832..d20a58ca8 100644 --- a/src/wx/properties_dialog.cc +++ b/src/wx/properties_dialog.cc @@ -50,20 +50,13 @@ PropertiesDialog::PropertiesDialog (wxWindow* parent, shared_ptr film) _encoded = new ThreadedStaticText (this, _("counting..."), boost::bind (&PropertiesDialog::frames_already_encoded, this)); table->Add (_encoded, 1, wxALIGN_CENTER_VERTICAL); -#if 0 - if (_film->length()) { - _frames->SetLabel (std_to_wx (lexical_cast (_film->length().get()))); - FrameRateConversion frc (_film->source_frame_rate(), _film->dcp_frame_rate()); - int const dcp_length = _film->length().get() * frc.factor(); - double const disk = ((double) _film->j2k_bandwidth() / 8) * dcp_length / (_film->dcp_frame_rate() * 1073741824.0f); - stringstream s; - s << fixed << setprecision (1) << disk << wx_to_std (_("Gb")); - _disk->SetLabel (std_to_wx (s.str ())); - } else { - _frames->SetLabel (_("unknown")); - _disk->SetLabel (_("unknown")); - } -#endif + _frames->SetLabel (std_to_wx (lexical_cast (_film->video_length()))); + FrameRateConversion frc (_film->video_frame_rate(), _film->dcp_frame_rate()); + int const dcp_length = _film->video_length() * frc.factor(); + double const disk = ((double) _film->j2k_bandwidth() / 8) * dcp_length / (_film->dcp_frame_rate() * 1073741824.0f); + stringstream s; + s << fixed << setprecision (1) << disk << wx_to_std (_("Gb")); + _disk->SetLabel (std_to_wx (s.str ())); wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL); overall_sizer->Add (table, 0, wxALL, 6); @@ -87,9 +80,9 @@ PropertiesDialog::frames_already_encoded () const return ""; } -// if (_film->length()) { -// /* XXX: encoded_frames() should check which frames have been encoded */ -// u << " (" << (_film->encoded_frames() * 100 / _film->length().get()) << "%)"; -// } + if (_film->video_length()) { + /* XXX: encoded_frames() should check which frames have been encoded */ + u << " (" << (_film->encoded_frames() * 100 / _film->video_length()) << "%)"; + } return u.str (); } -- cgit v1.2.3 From fd040c2bd27fde35424a384174ecb56c643764cd Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 8 May 2013 20:37:53 +0100 Subject: Some tidying up. Do encode progress in the writer to improve progress bar movement with still-image DCPs (#130). --- src/lib/ab_transcoder.cc | 41 +++++++++++++---------------------------- src/lib/ab_transcoder.h | 2 -- src/lib/encoder.cc | 5 +++-- src/lib/encoder.h | 8 +++++--- src/lib/player.cc | 12 ------------ src/lib/player.h | 1 - src/lib/transcoder.cc | 11 ++++------- src/lib/transcoder.h | 4 +++- src/lib/writer.cc | 8 +++++++- src/lib/writer.h | 4 +++- 10 files changed, 38 insertions(+), 58 deletions(-) (limited to 'src') diff --git a/src/lib/ab_transcoder.cc b/src/lib/ab_transcoder.cc index 2e0d41e7d..f75491dce 100644 --- a/src/lib/ab_transcoder.cc +++ b/src/lib/ab_transcoder.cc @@ -47,27 +47,25 @@ using boost::dynamic_pointer_cast; * @param e Encoder to use. */ -ABTranscoder::ABTranscoder (shared_ptr a, shared_ptr b, shared_ptr j) - : _film_a (a) - , _film_b (b) - , _player_a (_film_a->player ()) - , _player_b (_film_b->player ()) +ABTranscoder::ABTranscoder (shared_ptr film_a, shared_ptr film_b, shared_ptr j) + : _player_a (film_a->player ()) + , _player_b (film_b->player ()) , _job (j) - , _encoder (new Encoder (_film_a)) - , _combiner (new Combiner (a->log())) + , _encoder (new Encoder (film_a, j)) + , _combiner (new Combiner (film_a->log())) { - _matcher.reset (new Matcher (_film_a->log(), _film_a->audio_frame_rate(), _film_a->video_frame_rate())); - _delay_line.reset (new DelayLine (_film_a->log(), _film_a->audio_delay() * _film_a->audio_frame_rate() / 1000)); - _gain.reset (new Gain (_film_a->log(), _film_a->audio_gain())); + _matcher.reset (new Matcher (film_a->log(), film_a->audio_frame_rate(), film_a->video_frame_rate())); + _delay_line.reset (new DelayLine (film_a->log(), film_a->audio_delay() * film_a->audio_frame_rate() / 1000)); + _gain.reset (new Gain (film_a->log(), film_a->audio_gain())); _player_a->Video.connect (bind (&Combiner::process_video, _combiner, _1, _2, _3, _4)); _player_b->Video.connect (bind (&Combiner::process_video_b, _combiner, _1, _2, _3, _4)); - int const trim_start = _film_a->trim_type() == Film::ENCODE ? _film_a->trim_start() : 0; - int const trim_end = _film_a->trim_type() == Film::ENCODE ? _film_a->trim_end() : 0; + int const trim_start = film_a->trim_type() == Film::ENCODE ? film_a->trim_start() : 0; + int const trim_end = film_a->trim_type() == Film::ENCODE ? film_a->trim_end() : 0; _trimmer.reset (new Trimmer ( - _film_a->log(), trim_start, trim_end, _film_a->content_length(), - _film_a->audio_frame_rate(), _film_a->video_frame_rate(), _film_a->dcp_frame_rate() + film_a->log(), trim_start, trim_end, film_a->content_length(), + film_a->audio_frame_rate(), film_a->video_frame_rate(), film_a->dcp_frame_rate() )); @@ -88,20 +86,7 @@ ABTranscoder::go () { _encoder->process_begin (); - bool done[2] = { false, false }; - - while (1) { - done[0] = _player_a->pass (); - done[1] = _player_b->pass (); - - if (_job) { - _player_a->set_progress (_job); - } - - if (done[0] && done[1]) { - break; - } - } + while (!_player_a->pass () || !_player_b->pass ()) {} _delay_line->process_end (); _matcher->process_end (); diff --git a/src/lib/ab_transcoder.h b/src/lib/ab_transcoder.h index 1fef66b88..134bce3e4 100644 --- a/src/lib/ab_transcoder.h +++ b/src/lib/ab_transcoder.h @@ -54,8 +54,6 @@ public: void go (); private: - boost::shared_ptr _film_a; - boost::shared_ptr _film_b; boost::shared_ptr _player_a; boost::shared_ptr _player_b; boost::shared_ptr _job; diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index c1d1041ae..d25e0d0f8 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -55,8 +55,9 @@ using boost::optional; int const Encoder::_history_size = 25; /** @param f Film that we are encoding */ -Encoder::Encoder (shared_ptr f) +Encoder::Encoder (shared_ptr f, shared_ptr j) : _film (f) + , _job (j) , _video_frames_in (0) , _video_frames_out (0) #ifdef HAVE_SWRESAMPLE @@ -127,7 +128,7 @@ Encoder::process_begin () } } - _writer.reset (new Writer (_film)); + _writer.reset (new Writer (_film, _job)); } diff --git a/src/lib/encoder.h b/src/lib/encoder.h index f95d42661..6cf5540c5 100644 --- a/src/lib/encoder.h +++ b/src/lib/encoder.h @@ -51,6 +51,7 @@ class ServerDescription; class DCPVideoFrame; class EncodedData; class Writer; +class Job; /** @class Encoder * @brief Encoder to J2K and WAV for DCP. @@ -62,11 +63,11 @@ class Writer; class Encoder : public VideoSink, public AudioSink { public: - Encoder (boost::shared_ptr f); + Encoder (boost::shared_ptr f, boost::shared_ptr); virtual ~Encoder (); /** Called to indicate that a processing run is about to begin */ - virtual void process_begin (); + void process_begin (); /** Call with a frame of video. * @param i Video frame image. @@ -79,7 +80,7 @@ public: void process_audio (boost::shared_ptr); /** Called when a processing run has finished */ - virtual void process_end (); + void process_end (); float current_encoding_rate () const; int video_frames_out () const; @@ -93,6 +94,7 @@ private: /** Film that we are encoding */ boost::shared_ptr _film; + boost::shared_ptr _job; /** Mutex for _time_history and _last_frame */ mutable boost::mutex _history_mutex; diff --git a/src/lib/player.cc b/src/lib/player.cc index 68a962cdd..95036cfe0 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -121,18 +121,6 @@ Player::pass () return done; } -void -Player::set_progress (shared_ptr job) -{ - /* Assume progress can be divined from how far through the video we are */ - - if (_video_decoder >= _video_decoders.size() || !_playlist->video_length()) { - return; - } - - job->set_progress ((_video_start[_video_decoder] + _video_decoders[_video_decoder]->video_frame()) / _playlist->video_length ()); -} - void Player::process_video (shared_ptr i, bool same, shared_ptr s, double t) { diff --git a/src/lib/player.h b/src/lib/player.h index 20b83bfdb..b6fb41f6e 100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@ -49,7 +49,6 @@ public: void disable_subtitles (); bool pass (); - void set_progress (boost::shared_ptr); bool seek (double); void seek_back (); void seek_forward (); diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc index 2e33931bd..f8fe0c8d5 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -36,6 +36,7 @@ #include "audio_decoder.h" #include "player.h" #include "trimmer.h" +#include "job.h" using std::string; using boost::shared_ptr; @@ -49,7 +50,7 @@ using boost::dynamic_pointer_cast; Transcoder::Transcoder (shared_ptr f, shared_ptr j) : _job (j) , _player (f->player ()) - , _encoder (new Encoder (f)) + , _encoder (new Encoder (f, j)) { _matcher.reset (new Matcher (f->log(), f->audio_frame_rate(), f->video_frame_rate())); _delay_line.reset (new DelayLine (f->log(), f->audio_delay() * f->audio_frame_rate() / 1000)); @@ -82,13 +83,9 @@ void Transcoder::go () { _encoder->process_begin (); - while (1) { - if (_player->pass ()) { - break; - } - _player->set_progress (_job); - } + while (!_player->pass ()) {} + _delay_line->process_end (); if (_matcher) { _matcher->process_end (); diff --git a/src/lib/transcoder.h b/src/lib/transcoder.h index 97ecaabfc..48b453fe4 100644 --- a/src/lib/transcoder.h +++ b/src/lib/transcoder.h @@ -17,6 +17,8 @@ */ +#include "types.h" + /** @file src/transcoder.h * * A decoder is selected according to the content type, and the encoder can be specified @@ -51,7 +53,7 @@ public: float current_encoding_rate () const; int video_frames_out () const; -protected: +private: /** A Job that is running this Transcoder, or 0 */ boost::shared_ptr _job; boost::shared_ptr _player; diff --git a/src/lib/writer.cc b/src/lib/writer.cc index b545848cb..c7d2cf8b4 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -34,6 +34,7 @@ #include "player.h" #include "audio_mapping.h" #include "config.h" +#include "job.h" #include "i18n.h" @@ -47,8 +48,9 @@ using boost::shared_ptr; int const Writer::_maximum_frames_in_memory = 8; -Writer::Writer (shared_ptr f) +Writer::Writer (shared_ptr f, shared_ptr j) : _film (f) + , _job (j) , _first_nonexistant_frame (0) , _thread (0) , _finish (false) @@ -202,6 +204,10 @@ try } } lock.lock (); + + if (_film->video_length ()) { + _job->set_progress (float(_full_written + _fake_written + _repeat_written) / _film->video_length()); + } ++_last_written_frame; } diff --git a/src/lib/writer.h b/src/lib/writer.h index beb16c7b9..62714edf3 100644 --- a/src/lib/writer.h +++ b/src/lib/writer.h @@ -26,6 +26,7 @@ class Film; class EncodedData; class AudioBuffers; +class Job; namespace libdcp { class MonoPictureAsset; @@ -63,7 +64,7 @@ bool operator== (QueueItem const & a, QueueItem const & b); class Writer : public ExceptionStore { public: - Writer (boost::shared_ptr); + Writer (boost::shared_ptr, boost::shared_ptr); bool can_fake_write (int) const; @@ -80,6 +81,7 @@ private: /** our Film */ boost::shared_ptr _film; + boost::shared_ptr _job; /** the first frame index that does not already exist in our MXF */ int _first_nonexistant_frame; -- cgit v1.2.3 From fae9d594f73fe32943ee21d0fe600fd8302c3102 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 9 May 2013 09:51:23 +0100 Subject: Merge pot files. --- src/lib/po/es_ES.po | 62 +++++++++++------------ src/lib/po/fr_FR.po | 62 +++++++++++------------ src/lib/po/it_IT.po | 62 +++++++++++------------ src/lib/po/sv_SE.po | 62 +++++++++++------------ src/tools/po/es_ES.po | 65 ++++++++++++------------ src/tools/po/fr_FR.po | 65 ++++++++++++------------ src/tools/po/it_IT.po | 63 +++++++++++++----------- src/tools/po/sv_SE.po | 63 +++++++++++++----------- src/wx/po/es_ES.po | 132 ++++++++++++++++++++++++++++++++++--------------- src/wx/po/fr_FR.po | 132 ++++++++++++++++++++++++++++++++++--------------- src/wx/po/it_IT.po | 133 +++++++++++++++++++++++++++++++++++--------------- src/wx/po/sv_SE.po | 133 +++++++++++++++++++++++++++++++++++--------------- 12 files changed, 632 insertions(+), 402 deletions(-) (limited to 'src') diff --git a/src/lib/po/es_ES.po b/src/lib/po/es_ES.po index 1608f3b0c..944505007 100644 --- a/src/lib/po/es_ES.po +++ b/src/lib/po/es_ES.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: LIBDVDOMATIC\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-22 15:06+0100\n" +"POT-Creation-Date: 2013-05-09 09:51+0100\n" "PO-Revision-Date: 2013-04-02 19:10-0500\n" "Last-Translator: Manuel AC \n" "Language-Team: Manuel AC \n" @@ -74,7 +74,7 @@ msgstr "Academy" msgid "Advertisement" msgstr "Publicidad" -#: src/lib/job.cc:72 +#: src/lib/job.cc:73 msgid "An error occurred whilst handling the file %1." msgstr "Ha ocurrido un error con el fichero %1." @@ -94,7 +94,7 @@ msgstr "Bicúbico" msgid "Bilinear" msgstr "Bilineal" -#: src/lib/job.cc:306 +#: src/lib/job.cc:318 msgid "Cancelled" msgstr "" @@ -107,7 +107,7 @@ msgid "Cannot resample audio as libswresample is not present" msgstr "" "No se puede redimensionar el sonido porque no se encuentra libswresample" -#: src/lib/util.cc:932 +#: src/lib/util.cc:960 msgid "Centre" msgstr "" @@ -139,16 +139,16 @@ msgstr "No se pudo escribir el fichero remoto (%1)" msgid "Cubic interpolating deinterlacer" msgstr "Desentrelazado por interpolación cúbica" -#: src/lib/util.cc:1007 +#: src/lib/util.cc:1035 msgid "DCP and source have the same rate.\n" msgstr "La fuente y el DCP tienen la misma velocidad.\n" -#: src/lib/util.cc:1017 +#: src/lib/util.cc:1045 #, fuzzy msgid "DCP will run at %1%% of the source speed.\n" msgstr "El DCP se reproducirá al %1%% de la velocidad de la fuente.\n" -#: src/lib/util.cc:1010 +#: src/lib/util.cc:1038 msgid "DCP will use every other frame of the source.\n" msgstr "El DCP usará fotogramas alternos de la fuente.\n" @@ -171,11 +171,11 @@ msgstr "Deringing filter" msgid "Dolby CP750" msgstr "Dolby CP750" -#: src/lib/util.cc:1012 +#: src/lib/util.cc:1040 msgid "Each source frame will be doubled in the DCP.\n" msgstr "Se doblará cada fotograma de la fuente en el DCP.\n" -#: src/lib/job.cc:304 +#: src/lib/job.cc:316 msgid "Error (%1)" msgstr "Error (%1)" @@ -247,7 +247,7 @@ msgstr "Horizontal deblocking filter" msgid "Horizontal deblocking filter A" msgstr "Horizontal deblocking filter A" -#: src/lib/job.cc:96 src/lib/job.cc:105 +#: src/lib/job.cc:97 src/lib/job.cc:106 msgid "" "It is not known what caused this error. The best idea is to report the " "problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" @@ -263,15 +263,15 @@ msgstr "Kernel deinterlacer" msgid "Lanczos" msgstr "Lanczos" -#: src/lib/util.cc:930 +#: src/lib/util.cc:958 msgid "Left" msgstr "" -#: src/lib/util.cc:934 +#: src/lib/util.cc:962 msgid "Left surround" msgstr "" -#: src/lib/util.cc:933 +#: src/lib/util.cc:961 msgid "Lfe (sub)" msgstr "" @@ -301,7 +301,7 @@ msgstr "Motion compensating deinterlacer" msgid "Noise reduction" msgstr "Reducción de ruido" -#: src/lib/job.cc:302 +#: src/lib/job.cc:314 msgid "OK (ran for %1)" msgstr "OK (ejecución %1)" @@ -321,15 +321,15 @@ msgstr "Anuncio de servicio público" msgid "Rating" msgstr "Clasificación" -#: src/lib/util.cc:500 +#: src/lib/util.cc:513 msgid "Rec 709" msgstr "Rec 709" -#: src/lib/util.cc:931 +#: src/lib/util.cc:959 msgid "Right" msgstr "" -#: src/lib/util.cc:935 +#: src/lib/util.cc:963 msgid "Right surround" msgstr "" @@ -373,7 +373,7 @@ msgstr "Temporal noise reducer" msgid "Test" msgstr "Test" -#: src/lib/job.cc:78 +#: src/lib/job.cc:79 msgid "" "The drive that the film is stored on is low in disc space. Free some more " "space and try again." @@ -393,7 +393,7 @@ msgstr "Codificar %1" msgid "Transitional" msgstr "Transitional" -#: src/lib/job.cc:104 +#: src/lib/job.cc:105 msgid "Unknown error" msgstr "Error desconocido" @@ -429,7 +429,7 @@ msgstr "Yet Another Deinterlacing Filter" msgid "cannot contain slashes" msgstr "no puede contener barras" -#: src/lib/util.cc:541 +#: src/lib/util.cc:554 msgid "connect timed out" msgstr "tiempo de conexión agotado" @@ -470,7 +470,7 @@ msgstr "no se pudo encontrar decodificador de subtítutlos" msgid "could not find video decoder" msgstr "no se pudo encontrar decodificador de vídeo" -#: src/lib/sndfile_decoder.cc:72 +#: src/lib/sndfile_decoder.cc:67 msgid "could not open external audio file for reading" msgstr "no se pudo leer el fichero externo de audio" @@ -505,11 +505,11 @@ msgstr "no se pudo abrir la sesión SSH" msgid "could not write to file %1 (%2)" msgstr "No se pudo escribir el fichero remoto (%1)" -#: src/lib/sndfile_decoder.cc:94 +#: src/lib/sndfile_decoder.cc:89 msgid "external audio files have differing lengths" msgstr "los ficheros externos de sonido tienen duraciones diferentes" -#: src/lib/sndfile_decoder.cc:76 +#: src/lib/sndfile_decoder.cc:71 msgid "external audio files must be mono" msgstr "los ficheros externos de sonido deben ser mono" @@ -521,23 +521,23 @@ msgstr "formato" msgid "frames per second" msgstr "fotogramas por segundo" -#: src/lib/util.cc:115 +#: src/lib/util.cc:128 msgid "hour" msgstr "hora" -#: src/lib/util.cc:112 src/lib/util.cc:117 +#: src/lib/util.cc:125 src/lib/util.cc:130 msgid "hours" msgstr "horas" -#: src/lib/util.cc:122 +#: src/lib/util.cc:135 msgid "minute" msgstr "minuto" -#: src/lib/util.cc:124 +#: src/lib/util.cc:137 msgid "minutes" msgstr "minutos" -#: src/lib/util.cc:684 +#: src/lib/util.cc:697 msgid "missing key %1 in key-value set" msgstr "falta la clave %1 en el par clave-valor" @@ -563,15 +563,15 @@ msgstr "todavía no se soportan subtítulos que no son en mapas de bits" #. / TRANSLATORS: remaining here follows an amount of time that is remaining #. / on an operation. -#: src/lib/job.cc:299 +#: src/lib/job.cc:311 msgid "remaining" msgstr "pendiente" -#: src/lib/util.cc:498 +#: src/lib/util.cc:511 msgid "sRGB" msgstr "sRGB" -#: src/lib/util.cc:127 +#: src/lib/util.cc:140 msgid "seconds" msgstr "segundos" diff --git a/src/lib/po/fr_FR.po b/src/lib/po/fr_FR.po index d1123d84b..174a25cff 100644 --- a/src/lib/po/fr_FR.po +++ b/src/lib/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-22 15:06+0100\n" +"POT-Creation-Date: 2013-05-09 09:51+0100\n" "PO-Revision-Date: 2013-03-20 00:39+0100\n" "Last-Translator: FreeDCP.net \n" "Language-Team: \n" @@ -73,7 +73,7 @@ msgstr "Academy" msgid "Advertisement" msgstr "Advertisement" -#: src/lib/job.cc:72 +#: src/lib/job.cc:73 msgid "An error occurred whilst handling the file %1." msgstr "Une erreur s'est produite lors du traitement du fichier %1." @@ -93,7 +93,7 @@ msgstr "Bicubique" msgid "Bilinear" msgstr "Bilinéaire" -#: src/lib/job.cc:306 +#: src/lib/job.cc:318 msgid "Cancelled" msgstr "" @@ -105,7 +105,7 @@ msgstr "" msgid "Cannot resample audio as libswresample is not present" msgstr "Ré-échantillonnage du son impossible : libswresample est absent" -#: src/lib/util.cc:932 +#: src/lib/util.cc:960 msgid "Centre" msgstr "" @@ -137,16 +137,16 @@ msgstr "Écriture vers fichier distant (%1) impossible" msgid "Cubic interpolating deinterlacer" msgstr "Désentrelacement cubique interpolé" -#: src/lib/util.cc:1007 +#: src/lib/util.cc:1035 msgid "DCP and source have the same rate.\n" msgstr "Le DCP et la source ont les mêmes cadences.\n" -#: src/lib/util.cc:1017 +#: src/lib/util.cc:1045 #, fuzzy msgid "DCP will run at %1%% of the source speed.\n" msgstr "La cadence du DCP sera %1%% par rapport à la source.\n" -#: src/lib/util.cc:1010 +#: src/lib/util.cc:1038 msgid "DCP will use every other frame of the source.\n" msgstr "Le DCP utilisera une image sur deux de la source.\n" @@ -169,11 +169,11 @@ msgstr "Filtre anti bourdonnement" msgid "Dolby CP750" msgstr "Dolby CP750" -#: src/lib/util.cc:1012 +#: src/lib/util.cc:1040 msgid "Each source frame will be doubled in the DCP.\n" msgstr "Chaque image source sera dupliquée dans le DCP.\n" -#: src/lib/job.cc:304 +#: src/lib/job.cc:316 msgid "Error (%1)" msgstr "Erreur (%1)" @@ -245,7 +245,7 @@ msgstr "Filtre dé-bloc horizontal" msgid "Horizontal deblocking filter A" msgstr "Filtre dé-bloc horizontal" -#: src/lib/job.cc:96 src/lib/job.cc:105 +#: src/lib/job.cc:97 src/lib/job.cc:106 msgid "" "It is not known what caused this error. The best idea is to report the " "problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" @@ -261,15 +261,15 @@ msgstr "Désentrelaceur noyau" msgid "Lanczos" msgstr "Lanczos" -#: src/lib/util.cc:930 +#: src/lib/util.cc:958 msgid "Left" msgstr "Gauche" -#: src/lib/util.cc:934 +#: src/lib/util.cc:962 msgid "Left surround" msgstr "Arrière gauche" -#: src/lib/util.cc:933 +#: src/lib/util.cc:961 msgid "Lfe (sub)" msgstr "Basses fréquences" @@ -299,7 +299,7 @@ msgstr "Désentrelaceur par compensation de mouvement" msgid "Noise reduction" msgstr "Réduction de bruit" -#: src/lib/job.cc:302 +#: src/lib/job.cc:314 msgid "OK (ran for %1)" msgstr "OK (processus %1)" @@ -319,15 +319,15 @@ msgstr "Public Service Announcement" msgid "Rating" msgstr "Classification" -#: src/lib/util.cc:500 +#: src/lib/util.cc:513 msgid "Rec 709" msgstr "Rec 709" -#: src/lib/util.cc:931 +#: src/lib/util.cc:959 msgid "Right" msgstr "Droite" -#: src/lib/util.cc:935 +#: src/lib/util.cc:963 msgid "Right surround" msgstr "Arrière droite" @@ -371,7 +371,7 @@ msgstr "Réduction de bruit temporel" msgid "Test" msgstr "Test" -#: src/lib/job.cc:78 +#: src/lib/job.cc:79 msgid "" "The drive that the film is stored on is low in disc space. Free some more " "space and try again." @@ -391,7 +391,7 @@ msgstr "Transcodage %1" msgid "Transitional" msgstr "Transitional" -#: src/lib/job.cc:104 +#: src/lib/job.cc:105 msgid "Unknown error" msgstr "Erreur inconnue" @@ -427,7 +427,7 @@ msgstr "Un autre filtre de désentrelacement" msgid "cannot contain slashes" msgstr "slash interdit" -#: src/lib/util.cc:541 +#: src/lib/util.cc:554 msgid "connect timed out" msgstr "temps de connexion expiré" @@ -467,7 +467,7 @@ msgstr "décodeur de sous-titre introuvable" msgid "could not find video decoder" msgstr "décodeur vidéo introuvable" -#: src/lib/sndfile_decoder.cc:72 +#: src/lib/sndfile_decoder.cc:67 msgid "could not open external audio file for reading" msgstr "lecture du fichier audio externe impossible" @@ -499,11 +499,11 @@ msgstr "démarrage de session SSH impossible" msgid "could not write to file %1 (%2)" msgstr "Écriture vers fichier distant (%1) impossible (%2)" -#: src/lib/sndfile_decoder.cc:94 +#: src/lib/sndfile_decoder.cc:89 msgid "external audio files have differing lengths" msgstr "Les fichiers audio externes ont des durées différentes" -#: src/lib/sndfile_decoder.cc:76 +#: src/lib/sndfile_decoder.cc:71 msgid "external audio files must be mono" msgstr "les fichiers audio externes doivent être en mono" @@ -515,23 +515,23 @@ msgstr "format" msgid "frames per second" msgstr "images par seconde" -#: src/lib/util.cc:115 +#: src/lib/util.cc:128 msgid "hour" msgstr "heure" -#: src/lib/util.cc:112 src/lib/util.cc:117 +#: src/lib/util.cc:125 src/lib/util.cc:130 msgid "hours" msgstr "heures" -#: src/lib/util.cc:122 +#: src/lib/util.cc:135 msgid "minute" msgstr "minute" -#: src/lib/util.cc:124 +#: src/lib/util.cc:137 msgid "minutes" msgstr "minutes" -#: src/lib/util.cc:684 +#: src/lib/util.cc:697 msgid "missing key %1 in key-value set" msgstr "clé %1 non sélectionnée" @@ -557,15 +557,15 @@ msgstr "sous-titres non-bitmap non supportés actuellement" #. / TRANSLATORS: remaining here follows an amount of time that is remaining #. / on an operation. -#: src/lib/job.cc:299 +#: src/lib/job.cc:311 msgid "remaining" msgstr "restant" -#: src/lib/util.cc:498 +#: src/lib/util.cc:511 msgid "sRGB" msgstr "sRGB" -#: src/lib/util.cc:127 +#: src/lib/util.cc:140 msgid "seconds" msgstr "secondes" diff --git a/src/lib/po/it_IT.po b/src/lib/po/it_IT.po index a3d35dec9..6a7486d82 100644 --- a/src/lib/po/it_IT.po +++ b/src/lib/po/it_IT.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-22 15:06+0100\n" +"POT-Creation-Date: 2013-05-09 09:51+0100\n" "PO-Revision-Date: 2013-04-28 10:26+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" @@ -73,7 +73,7 @@ msgstr "Academy" msgid "Advertisement" msgstr "Pubblicità" -#: src/lib/job.cc:72 +#: src/lib/job.cc:73 msgid "An error occurred whilst handling the file %1." msgstr "Errore durante l'elaborazione del file %1." @@ -93,7 +93,7 @@ msgstr "Bicubica" msgid "Bilinear" msgstr "Bilineare" -#: src/lib/job.cc:306 +#: src/lib/job.cc:318 msgid "Cancelled" msgstr "Cancellato" @@ -105,7 +105,7 @@ msgstr "Non posso gestire il formato di pixel %1 durante %2" msgid "Cannot resample audio as libswresample is not present" msgstr "Non posso ricampionare l'audio perchè libswresample non è presente" -#: src/lib/util.cc:932 +#: src/lib/util.cc:960 msgid "Centre" msgstr "Centro" @@ -137,15 +137,15 @@ msgstr "Non posso scrivere il file remoto (%1)" msgid "Cubic interpolating deinterlacer" msgstr "Deinterlacciatore cubico interpolato" -#: src/lib/util.cc:1007 +#: src/lib/util.cc:1035 msgid "DCP and source have the same rate.\n" msgstr "Il DCP e il sorgente hanno la stessa frequenza.\n" -#: src/lib/util.cc:1017 +#: src/lib/util.cc:1045 msgid "DCP will run at %1%% of the source speed.\n" msgstr "Il DCP andrà al %1%% della velocità del sorgente.\n" -#: src/lib/util.cc:1010 +#: src/lib/util.cc:1038 msgid "DCP will use every other frame of the source.\n" msgstr "Il DCP userà ogni altro fotogramma del sorgente.\n" @@ -168,11 +168,11 @@ msgstr "Filtro deringing" msgid "Dolby CP750" msgstr "Dolby CP750" -#: src/lib/util.cc:1012 +#: src/lib/util.cc:1040 msgid "Each source frame will be doubled in the DCP.\n" msgstr "Ogni fotogramma del sorgente sarà raddoppiato nel DCP.\n" -#: src/lib/job.cc:304 +#: src/lib/job.cc:316 msgid "Error (%1)" msgstr "Errore (%1)" @@ -244,7 +244,7 @@ msgstr "Filtro sblocco orizzontale" msgid "Horizontal deblocking filter A" msgstr "Filtro A sblocco orizzontale" -#: src/lib/job.cc:96 src/lib/job.cc:105 +#: src/lib/job.cc:97 src/lib/job.cc:106 msgid "" "It is not known what caused this error. The best idea is to report the " "problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" @@ -260,15 +260,15 @@ msgstr "Deinterlacciatore Kernel" msgid "Lanczos" msgstr "Lanczos" -#: src/lib/util.cc:930 +#: src/lib/util.cc:958 msgid "Left" msgstr "Sinistro" -#: src/lib/util.cc:934 +#: src/lib/util.cc:962 msgid "Left surround" msgstr "Surround sinistro" -#: src/lib/util.cc:933 +#: src/lib/util.cc:961 msgid "Lfe (sub)" msgstr "Lfe(sub)" @@ -298,7 +298,7 @@ msgstr "Dinterlacciatore compensativo di movimento" msgid "Noise reduction" msgstr "Riduzione del rumore" -#: src/lib/job.cc:302 +#: src/lib/job.cc:314 msgid "OK (ran for %1)" msgstr "OK (eseguito in %1)" @@ -318,15 +318,15 @@ msgstr "Annuncio di pubblico servizio" msgid "Rating" msgstr "Punteggio" -#: src/lib/util.cc:500 +#: src/lib/util.cc:513 msgid "Rec 709" msgstr "Rec 709" -#: src/lib/util.cc:931 +#: src/lib/util.cc:959 msgid "Right" msgstr "Destro" -#: src/lib/util.cc:935 +#: src/lib/util.cc:963 msgid "Right surround" msgstr "Surround destro" @@ -370,7 +370,7 @@ msgstr "Riduttore temporale di rumore" msgid "Test" msgstr "Prova" -#: src/lib/job.cc:78 +#: src/lib/job.cc:79 msgid "" "The drive that the film is stored on is low in disc space. Free some more " "space and try again." @@ -390,7 +390,7 @@ msgstr "Transcodifica %1" msgid "Transitional" msgstr "Di transizione" -#: src/lib/job.cc:104 +#: src/lib/job.cc:105 msgid "Unknown error" msgstr "Errore sconosciuto" @@ -426,7 +426,7 @@ msgstr "Altro filtro di deinterlacciamento" msgid "cannot contain slashes" msgstr "non può contenere barre" -#: src/lib/util.cc:541 +#: src/lib/util.cc:554 msgid "connect timed out" msgstr "connessione scaduta" @@ -466,7 +466,7 @@ msgstr "non riesco a trovare il decoder dei sottotitoli" msgid "could not find video decoder" msgstr "non riesco a trovare il decoder video" -#: src/lib/sndfile_decoder.cc:72 +#: src/lib/sndfile_decoder.cc:67 msgid "could not open external audio file for reading" msgstr "non riesco ad aprire il file dell'audio esterno per leggerlo" @@ -498,11 +498,11 @@ msgstr "non posso avviare la sessione SSH" msgid "could not write to file %1 (%2)" msgstr "non posso scrivere il file (%1)" -#: src/lib/sndfile_decoder.cc:94 +#: src/lib/sndfile_decoder.cc:89 msgid "external audio files have differing lengths" msgstr "i files dell'audio esterno hanno durata diversa" -#: src/lib/sndfile_decoder.cc:76 +#: src/lib/sndfile_decoder.cc:71 msgid "external audio files must be mono" msgstr "i files dell'audio esterno devono essere mono" @@ -514,23 +514,23 @@ msgstr "formato" msgid "frames per second" msgstr "fotogrammi al secondo" -#: src/lib/util.cc:115 +#: src/lib/util.cc:128 msgid "hour" msgstr "ora" -#: src/lib/util.cc:112 src/lib/util.cc:117 +#: src/lib/util.cc:125 src/lib/util.cc:130 msgid "hours" msgstr "ore" -#: src/lib/util.cc:122 +#: src/lib/util.cc:135 msgid "minute" msgstr "minuto" -#: src/lib/util.cc:124 +#: src/lib/util.cc:137 msgid "minutes" msgstr "minuti" -#: src/lib/util.cc:684 +#: src/lib/util.cc:697 msgid "missing key %1 in key-value set" msgstr "persa la chiave %1 tra i valori chiave" @@ -556,15 +556,15 @@ msgstr "sottotitoli non-bitmap non ancora supportati" #. / TRANSLATORS: remaining here follows an amount of time that is remaining #. / on an operation. -#: src/lib/job.cc:299 +#: src/lib/job.cc:311 msgid "remaining" msgstr "restano" -#: src/lib/util.cc:498 +#: src/lib/util.cc:511 msgid "sRGB" msgstr "sRGB" -#: src/lib/util.cc:127 +#: src/lib/util.cc:140 msgid "seconds" msgstr "secondi" diff --git a/src/lib/po/sv_SE.po b/src/lib/po/sv_SE.po index 11aeff987..58d336ef8 100644 --- a/src/lib/po/sv_SE.po +++ b/src/lib/po/sv_SE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-22 15:06+0100\n" +"POT-Creation-Date: 2013-05-09 09:51+0100\n" "PO-Revision-Date: 2013-04-10 15:35+0100\n" "Last-Translator: Adam Klotblixt \n" "Language-Team: \n" @@ -73,7 +73,7 @@ msgstr "Academy" msgid "Advertisement" msgstr "Reklam" -#: src/lib/job.cc:72 +#: src/lib/job.cc:73 msgid "An error occurred whilst handling the file %1." msgstr "Ett fel inträffade vid hantering av filen %1" @@ -93,7 +93,7 @@ msgstr "Bikubisk" msgid "Bilinear" msgstr "Bilinjär" -#: src/lib/job.cc:306 +#: src/lib/job.cc:318 msgid "Cancelled" msgstr "Avbruten" @@ -106,7 +106,7 @@ msgid "Cannot resample audio as libswresample is not present" msgstr "" "Kan inte omsampla ljudet eftersom libswresample inte finns tillgängligt" -#: src/lib/util.cc:932 +#: src/lib/util.cc:960 msgid "Centre" msgstr "Mitt" @@ -138,15 +138,15 @@ msgstr "Kunde inte skriva till fjärrfil (%1)" msgid "Cubic interpolating deinterlacer" msgstr "Kubiskt interpolerande avflätare" -#: src/lib/util.cc:1007 +#: src/lib/util.cc:1035 msgid "DCP and source have the same rate.\n" msgstr "DCP och källa har samma bildfrekvens.\n" -#: src/lib/util.cc:1017 +#: src/lib/util.cc:1045 msgid "DCP will run at %1%% of the source speed.\n" msgstr "DCP kommer att köras på %1%% av källans hastighet.\n" -#: src/lib/util.cc:1010 +#: src/lib/util.cc:1038 msgid "DCP will use every other frame of the source.\n" msgstr "DCP kommer att använda varannan bild från källan.\n" @@ -169,11 +169,11 @@ msgstr "Avringningsfilter" msgid "Dolby CP750" msgstr "Dolby CP750" -#: src/lib/util.cc:1012 +#: src/lib/util.cc:1040 msgid "Each source frame will be doubled in the DCP.\n" msgstr "Varje bild från källan kommer att användas två gånger i DCPn.\n" -#: src/lib/job.cc:304 +#: src/lib/job.cc:316 msgid "Error (%1)" msgstr "Fel (%1)" @@ -245,7 +245,7 @@ msgstr "Filter för horisontal kantighetsutjämning" msgid "Horizontal deblocking filter A" msgstr "Filter för horisontal kantighetsutjämning A" -#: src/lib/job.cc:96 src/lib/job.cc:105 +#: src/lib/job.cc:97 src/lib/job.cc:106 msgid "" "It is not known what caused this error. The best idea is to report the " "problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" @@ -261,15 +261,15 @@ msgstr "Kernel-avflätare" msgid "Lanczos" msgstr "Lanczos" -#: src/lib/util.cc:930 +#: src/lib/util.cc:958 msgid "Left" msgstr "Vänster" -#: src/lib/util.cc:934 +#: src/lib/util.cc:962 msgid "Left surround" msgstr "Vänster surround" -#: src/lib/util.cc:933 +#: src/lib/util.cc:961 msgid "Lfe (sub)" msgstr "Lfe (sub)" @@ -299,7 +299,7 @@ msgstr "Rörelsekompenserande avflätare" msgid "Noise reduction" msgstr "Brusreducering" -#: src/lib/job.cc:302 +#: src/lib/job.cc:314 msgid "OK (ran for %1)" msgstr "OK (kördes %1)" @@ -319,15 +319,15 @@ msgstr "Offentligt Servicemeddelande" msgid "Rating" msgstr "Klassificeringsklipp" -#: src/lib/util.cc:500 +#: src/lib/util.cc:513 msgid "Rec 709" msgstr "Rec 709" -#: src/lib/util.cc:931 +#: src/lib/util.cc:959 msgid "Right" msgstr "Höger" -#: src/lib/util.cc:935 +#: src/lib/util.cc:963 msgid "Right surround" msgstr "Höger surround" @@ -371,7 +371,7 @@ msgstr "Temporal brusreducering" msgid "Test" msgstr "Test" -#: src/lib/job.cc:78 +#: src/lib/job.cc:79 msgid "" "The drive that the film is stored on is low in disc space. Free some more " "space and try again." @@ -391,7 +391,7 @@ msgstr "Konvertera %1" msgid "Transitional" msgstr "Övergångsklipp" -#: src/lib/job.cc:104 +#: src/lib/job.cc:105 msgid "Unknown error" msgstr "Okänt fel" @@ -431,7 +431,7 @@ msgid "cannot contain slashes" msgstr "får inte innehålla snedstreck" # Svengelska -#: src/lib/util.cc:541 +#: src/lib/util.cc:554 #, fuzzy msgid "connect timed out" msgstr "uppkopplingen tajmade ur" @@ -472,7 +472,7 @@ msgstr "kunde inte hitta undertext-avkodare" msgid "could not find video decoder" msgstr "kunde inte hitta video-avkodare" -#: src/lib/sndfile_decoder.cc:72 +#: src/lib/sndfile_decoder.cc:67 msgid "could not open external audio file for reading" msgstr "kunde inte öppna extern audio-fil för läsning" @@ -504,11 +504,11 @@ msgstr "kunde inte starta SSH-session" msgid "could not write to file %1 (%2)" msgstr "kunde inte skriva till fil %1 (%2)" -#: src/lib/sndfile_decoder.cc:94 +#: src/lib/sndfile_decoder.cc:89 msgid "external audio files have differing lengths" msgstr "externa audio-filer har olika längder" -#: src/lib/sndfile_decoder.cc:76 +#: src/lib/sndfile_decoder.cc:71 msgid "external audio files must be mono" msgstr "externa audio-filer måste vara mono" @@ -520,23 +520,23 @@ msgstr "format" msgid "frames per second" msgstr "bilder per sekund" -#: src/lib/util.cc:115 +#: src/lib/util.cc:128 msgid "hour" msgstr "timme" -#: src/lib/util.cc:112 src/lib/util.cc:117 +#: src/lib/util.cc:125 src/lib/util.cc:130 msgid "hours" msgstr "timmar" -#: src/lib/util.cc:122 +#: src/lib/util.cc:135 msgid "minute" msgstr "minut" -#: src/lib/util.cc:124 +#: src/lib/util.cc:137 msgid "minutes" msgstr "minuter" -#: src/lib/util.cc:684 +#: src/lib/util.cc:697 msgid "missing key %1 in key-value set" msgstr "saknad nyckel %1 i nyckel-värde grupp" @@ -562,15 +562,15 @@ msgstr "icke-rastergrafiska undertexter stöds inte ännu" #. / TRANSLATORS: remaining here follows an amount of time that is remaining #. / on an operation. -#: src/lib/job.cc:299 +#: src/lib/job.cc:311 msgid "remaining" msgstr "återstående tid" -#: src/lib/util.cc:498 +#: src/lib/util.cc:511 msgid "sRGB" msgstr "sRGB" -#: src/lib/util.cc:127 +#: src/lib/util.cc:140 msgid "seconds" msgstr "sekunder" diff --git a/src/tools/po/es_ES.po b/src/tools/po/es_ES.po index 1739f97cd..30f568c98 100644 --- a/src/tools/po/es_ES.po +++ b/src/tools/po/es_ES.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVDOMATIC\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-22 15:06+0100\n" +"POT-Creation-Date: 2013-05-09 09:51+0100\n" "PO-Revision-Date: 2013-03-23 21:08-0500\n" "Last-Translator: Manuel AC \n" "Language-Team: Manuel AC \n" @@ -17,113 +17,118 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" -#: src/tools/dvdomatic.cc:179 +#: src/tools/dvdomatic.cc:178 msgid "&Analyse audio" msgstr "&Analizar audio" -#: src/tools/dvdomatic.cc:185 +#: src/tools/dvdomatic.cc:184 msgid "&Edit" msgstr "&Editar" -#: src/tools/dvdomatic.cc:184 +#: src/tools/dvdomatic.cc:183 msgid "&File" msgstr "&Archivo" -#: src/tools/dvdomatic.cc:187 +#: src/tools/dvdomatic.cc:186 msgid "&Help" msgstr "&Ayuda" -#: src/tools/dvdomatic.cc:186 +#: src/tools/dvdomatic.cc:185 msgid "&Jobs" msgstr "&Tareas" -#: src/tools/dvdomatic.cc:175 +#: src/tools/dvdomatic.cc:174 msgid "&Make DCP" msgstr "&Crear DCP" -#: src/tools/dvdomatic.cc:163 +#: src/tools/dvdomatic.cc:162 msgid "&Open..." msgstr "&Abrir..." -#: src/tools/dvdomatic.cc:172 +#: src/tools/dvdomatic.cc:171 msgid "&Preferences..." msgstr "&Preferencias..." -#: src/tools/dvdomatic.cc:167 +#: src/tools/dvdomatic.cc:166 msgid "&Properties..." msgstr "&Propiedades..." -#: src/tools/dvdomatic.cc:169 +#: src/tools/dvdomatic.cc:168 msgid "&Quit" msgstr "&Salir" -#: src/tools/dvdomatic.cc:165 +#: src/tools/dvdomatic.cc:164 msgid "&Save" msgstr "&Guardar" -#: src/tools/dvdomatic.cc:176 +#: src/tools/dvdomatic.cc:175 msgid "&Send DCP to TMS" msgstr "&Enviar DCP al TMS" -#: src/tools/dvdomatic.cc:419 +#: src/tools/dvdomatic.cc:426 msgid "" "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" msgstr "" "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" -#: src/tools/dvdomatic.cc:182 +#: src/tools/dvdomatic.cc:181 msgid "About" msgstr "Acerca de" -#: src/tools/dvdomatic.cc:538 +#: src/tools/dvdomatic.cc:502 #, fuzzy msgid "Could not load film %1 (%2)" msgstr "No se pudo cargar la película %s (%s)" -#: src/tools/dvdomatic.cc:341 +#: src/tools/dvdomatic.cc:348 #, c-format msgid "Could not open film at %s (%s)" msgstr "No se pudo cargar la película en %s (%s)" -#: src/tools/dvdomatic.cc:289 src/tools/dvdomatic.cc:412 -#: src/tools/dvdomatic.cc:542 +#: src/tools/dvdomatic.cc:288 src/tools/dvdomatic.cc:419 +#: src/tools/dvdomatic.cc:506 msgid "DVD-o-matic" msgstr "DVD-o-matic" -#: src/tools/dvdomatic.cc:77 +#: src/tools/dvdomatic.cc:76 msgid "Film changed" msgstr "Película cambiada" -#: src/tools/dvdomatic.cc:418 +#: src/tools/dvdomatic.cc:425 msgid "Free, open-source DCP generation from almost anything." msgstr "" "Generación de DCP a partir de casi cualquier fuente, libre y de código " "abierto." -#: src/tools/dvdomatic.cc:162 +#: src/tools/dvdomatic.cc:161 msgid "New..." msgstr "Nuevo..." -#: src/tools/dvdomatic.cc:177 +#: src/tools/dvdomatic.cc:176 msgid "S&how DCP" msgstr "&Mostrar DCP" -#: src/tools/dvdomatic.cc:76 +#: src/tools/dvdomatic.cc:75 #, c-format msgid "Save changes to film \"%s\" before closing?" msgstr "" -#: src/tools/dvdomatic.cc:321 +#: src/tools/dvdomatic.cc:328 msgid "Select film to open" msgstr "Selecciona la película a abrir" -#: src/tools/dvdomatic.cc:305 -#, fuzzy -msgid "The directory %1 already exists." -msgstr "La carpeta %s ya existe." +#: src/tools/dvdomatic.cc:307 +msgid "" +"The directory %1 already exists and is not empty. Are you sure you want to " +"use it?" +msgstr "" -#: src/tools/dvdomatic.cc:326 +#: src/tools/dvdomatic.cc:333 msgid "" "You did not select a folder. Make sure that you select a folder before " "clicking Open." msgstr "" + +#, fuzzy +#~ msgid "The directory %1 already exists." +#~ msgstr "La carpeta %s ya existe." diff --git a/src/tools/po/fr_FR.po b/src/tools/po/fr_FR.po index c1447f7e6..ed9baf084 100644 --- a/src/tools/po/fr_FR.po +++ b/src/tools/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-22 15:06+0100\n" +"POT-Creation-Date: 2013-05-09 09:51+0100\n" "PO-Revision-Date: 2013-03-13 22:33+0100\n" "Last-Translator: \n" "Language-Team: \n" @@ -16,111 +16,116 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: src/tools/dvdomatic.cc:179 +#: src/tools/dvdomatic.cc:178 msgid "&Analyse audio" msgstr "&Analyser le son" -#: src/tools/dvdomatic.cc:185 +#: src/tools/dvdomatic.cc:184 msgid "&Edit" msgstr "&Edition" -#: src/tools/dvdomatic.cc:184 +#: src/tools/dvdomatic.cc:183 msgid "&File" msgstr "&Fichier" -#: src/tools/dvdomatic.cc:187 +#: src/tools/dvdomatic.cc:186 msgid "&Help" msgstr "&Aide" -#: src/tools/dvdomatic.cc:186 +#: src/tools/dvdomatic.cc:185 msgid "&Jobs" msgstr "&Travaux" -#: src/tools/dvdomatic.cc:175 +#: src/tools/dvdomatic.cc:174 msgid "&Make DCP" msgstr "&Créer le DCP" -#: src/tools/dvdomatic.cc:163 +#: src/tools/dvdomatic.cc:162 msgid "&Open..." msgstr "&Ouvrir..." -#: src/tools/dvdomatic.cc:172 +#: src/tools/dvdomatic.cc:171 msgid "&Preferences..." msgstr "&Préférences..." -#: src/tools/dvdomatic.cc:167 +#: src/tools/dvdomatic.cc:166 msgid "&Properties..." msgstr "&Propriétés..." -#: src/tools/dvdomatic.cc:169 +#: src/tools/dvdomatic.cc:168 msgid "&Quit" msgstr "&Quitter" -#: src/tools/dvdomatic.cc:165 +#: src/tools/dvdomatic.cc:164 msgid "&Save" msgstr "&Enregistrer" -#: src/tools/dvdomatic.cc:176 +#: src/tools/dvdomatic.cc:175 msgid "&Send DCP to TMS" msgstr "&Envoyer le DCP dans le TMS" -#: src/tools/dvdomatic.cc:419 +#: src/tools/dvdomatic.cc:426 msgid "" "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" msgstr "" "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" -#: src/tools/dvdomatic.cc:182 +#: src/tools/dvdomatic.cc:181 msgid "About" msgstr "A Propos" -#: src/tools/dvdomatic.cc:538 +#: src/tools/dvdomatic.cc:502 #, fuzzy msgid "Could not load film %1 (%2)" msgstr "Impossible de charger le film %s (%s)" -#: src/tools/dvdomatic.cc:341 +#: src/tools/dvdomatic.cc:348 #, c-format msgid "Could not open film at %s (%s)" msgstr "Impossible d'ouvrir le film à %s (%s)" -#: src/tools/dvdomatic.cc:289 src/tools/dvdomatic.cc:412 -#: src/tools/dvdomatic.cc:542 +#: src/tools/dvdomatic.cc:288 src/tools/dvdomatic.cc:419 +#: src/tools/dvdomatic.cc:506 msgid "DVD-o-matic" msgstr "DVD-o-matic" -#: src/tools/dvdomatic.cc:77 +#: src/tools/dvdomatic.cc:76 msgid "Film changed" msgstr "Film changé" -#: src/tools/dvdomatic.cc:418 +#: src/tools/dvdomatic.cc:425 msgid "Free, open-source DCP generation from almost anything." msgstr "Création de DCP libre et open-source à partir de presque tout." -#: src/tools/dvdomatic.cc:162 +#: src/tools/dvdomatic.cc:161 msgid "New..." msgstr "Nouveau..." -#: src/tools/dvdomatic.cc:177 +#: src/tools/dvdomatic.cc:176 msgid "S&how DCP" msgstr "Voir le DCP" -#: src/tools/dvdomatic.cc:76 +#: src/tools/dvdomatic.cc:75 #, c-format msgid "Save changes to film \"%s\" before closing?" msgstr "" -#: src/tools/dvdomatic.cc:321 +#: src/tools/dvdomatic.cc:328 msgid "Select film to open" msgstr "Sélectionner le film à ouvrir" -#: src/tools/dvdomatic.cc:305 -#, fuzzy -msgid "The directory %1 already exists." -msgstr "Le dossier %s existe déjà." +#: src/tools/dvdomatic.cc:307 +msgid "" +"The directory %1 already exists and is not empty. Are you sure you want to " +"use it?" +msgstr "" -#: src/tools/dvdomatic.cc:326 +#: src/tools/dvdomatic.cc:333 msgid "" "You did not select a folder. Make sure that you select a folder before " "clicking Open." msgstr "" + +#, fuzzy +#~ msgid "The directory %1 already exists." +#~ msgstr "Le dossier %s existe déjà." diff --git a/src/tools/po/it_IT.po b/src/tools/po/it_IT.po index f0984946d..d1f0b01bb 100644 --- a/src/tools/po/it_IT.po +++ b/src/tools/po/it_IT.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-22 15:06+0100\n" +"POT-Creation-Date: 2013-05-09 09:51+0100\n" "PO-Revision-Date: 2013-04-28 10:31+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" @@ -17,109 +17,114 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" -#: src/tools/dvdomatic.cc:179 +#: src/tools/dvdomatic.cc:178 msgid "&Analyse audio" msgstr "&Analizza audio" -#: src/tools/dvdomatic.cc:185 +#: src/tools/dvdomatic.cc:184 msgid "&Edit" msgstr "&Modifica" -#: src/tools/dvdomatic.cc:184 +#: src/tools/dvdomatic.cc:183 msgid "&File" msgstr "&File" -#: src/tools/dvdomatic.cc:187 +#: src/tools/dvdomatic.cc:186 msgid "&Help" msgstr "&Aiuto" -#: src/tools/dvdomatic.cc:186 +#: src/tools/dvdomatic.cc:185 msgid "&Jobs" msgstr "&Lavori" -#: src/tools/dvdomatic.cc:175 +#: src/tools/dvdomatic.cc:174 msgid "&Make DCP" msgstr "&Crea DCP" -#: src/tools/dvdomatic.cc:163 +#: src/tools/dvdomatic.cc:162 msgid "&Open..." msgstr "&Apri..." -#: src/tools/dvdomatic.cc:172 +#: src/tools/dvdomatic.cc:171 msgid "&Preferences..." msgstr "&Preferenze..." -#: src/tools/dvdomatic.cc:167 +#: src/tools/dvdomatic.cc:166 msgid "&Properties..." msgstr "&Proprieta'..." -#: src/tools/dvdomatic.cc:169 +#: src/tools/dvdomatic.cc:168 msgid "&Quit" msgstr "&Esci" -#: src/tools/dvdomatic.cc:165 +#: src/tools/dvdomatic.cc:164 msgid "&Save" msgstr "&Salva" -#: src/tools/dvdomatic.cc:176 +#: src/tools/dvdomatic.cc:175 msgid "&Send DCP to TMS" msgstr "&Invia DCP a TMS" -#: src/tools/dvdomatic.cc:419 +#: src/tools/dvdomatic.cc:426 msgid "" "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" msgstr "" "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" -#: src/tools/dvdomatic.cc:182 +#: src/tools/dvdomatic.cc:181 msgid "About" msgstr "Informazioni" -#: src/tools/dvdomatic.cc:538 +#: src/tools/dvdomatic.cc:502 msgid "Could not load film %1 (%2)" msgstr "Non posso caricare il film %s (%s)" -#: src/tools/dvdomatic.cc:341 +#: src/tools/dvdomatic.cc:348 #, c-format msgid "Could not open film at %s (%s)" msgstr "Non posso aprire il film in %s (%s)" -#: src/tools/dvdomatic.cc:289 src/tools/dvdomatic.cc:412 -#: src/tools/dvdomatic.cc:542 +#: src/tools/dvdomatic.cc:288 src/tools/dvdomatic.cc:419 +#: src/tools/dvdomatic.cc:506 msgid "DVD-o-matic" msgstr "DVD-o-matic" -#: src/tools/dvdomatic.cc:77 +#: src/tools/dvdomatic.cc:76 msgid "Film changed" msgstr "Film modificato" -#: src/tools/dvdomatic.cc:418 +#: src/tools/dvdomatic.cc:425 msgid "Free, open-source DCP generation from almost anything." msgstr "Genera DCP da quasi tutto, free e open-source." -#: src/tools/dvdomatic.cc:162 +#: src/tools/dvdomatic.cc:161 msgid "New..." msgstr "Nuovo" -#: src/tools/dvdomatic.cc:177 +#: src/tools/dvdomatic.cc:176 msgid "S&how DCP" msgstr "&Mostra DCP" -#: src/tools/dvdomatic.cc:76 +#: src/tools/dvdomatic.cc:75 #, c-format msgid "Save changes to film \"%s\" before closing?" msgstr "Salvare i cambiamenti del film \"%s\" prima di chiudere?" -#: src/tools/dvdomatic.cc:321 +#: src/tools/dvdomatic.cc:328 msgid "Select film to open" msgstr "Seleziona il film da aprire" -#: src/tools/dvdomatic.cc:305 -msgid "The directory %1 already exists." -msgstr "La directory %s esiste gia'." +#: src/tools/dvdomatic.cc:307 +msgid "" +"The directory %1 already exists and is not empty. Are you sure you want to " +"use it?" +msgstr "" -#: src/tools/dvdomatic.cc:326 +#: src/tools/dvdomatic.cc:333 msgid "" "You did not select a folder. Make sure that you select a folder before " "clicking Open." msgstr "" + +#~ msgid "The directory %1 already exists." +#~ msgstr "La directory %s esiste gia'." diff --git a/src/tools/po/sv_SE.po b/src/tools/po/sv_SE.po index 8ae68853f..7e88f84b1 100644 --- a/src/tools/po/sv_SE.po +++ b/src/tools/po/sv_SE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-22 15:06+0100\n" +"POT-Creation-Date: 2013-05-09 09:51+0100\n" "PO-Revision-Date: 2013-04-09 10:12+0100\n" "Last-Translator: Adam Klotblixt \n" "Language-Team: \n" @@ -17,112 +17,117 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.5\n" -#: src/tools/dvdomatic.cc:179 +#: src/tools/dvdomatic.cc:178 msgid "&Analyse audio" msgstr "&Analysera audio" -#: src/tools/dvdomatic.cc:185 +#: src/tools/dvdomatic.cc:184 msgid "&Edit" msgstr "&Redigera" -#: src/tools/dvdomatic.cc:184 +#: src/tools/dvdomatic.cc:183 msgid "&File" msgstr "&Fil" -#: src/tools/dvdomatic.cc:187 +#: src/tools/dvdomatic.cc:186 msgid "&Help" msgstr "&Hjälp" -#: src/tools/dvdomatic.cc:186 +#: src/tools/dvdomatic.cc:185 msgid "&Jobs" msgstr "&Jobb" -#: src/tools/dvdomatic.cc:175 +#: src/tools/dvdomatic.cc:174 msgid "&Make DCP" msgstr "&Skapa DCP" -#: src/tools/dvdomatic.cc:163 +#: src/tools/dvdomatic.cc:162 msgid "&Open..." msgstr "&Öppna" -#: src/tools/dvdomatic.cc:172 +#: src/tools/dvdomatic.cc:171 msgid "&Preferences..." msgstr "&Inställningar" -#: src/tools/dvdomatic.cc:167 +#: src/tools/dvdomatic.cc:166 msgid "&Properties..." msgstr "&Egenskaper" -#: src/tools/dvdomatic.cc:169 +#: src/tools/dvdomatic.cc:168 msgid "&Quit" msgstr "&Avsluta" -#: src/tools/dvdomatic.cc:165 +#: src/tools/dvdomatic.cc:164 msgid "&Save" msgstr "&Spara" -#: src/tools/dvdomatic.cc:176 +#: src/tools/dvdomatic.cc:175 msgid "&Send DCP to TMS" msgstr "&Skicka DCP till TMS" -#: src/tools/dvdomatic.cc:419 +#: src/tools/dvdomatic.cc:426 msgid "" "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" msgstr "" "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" -#: src/tools/dvdomatic.cc:182 +#: src/tools/dvdomatic.cc:181 msgid "About" msgstr "Om" -#: src/tools/dvdomatic.cc:538 +#: src/tools/dvdomatic.cc:502 msgid "Could not load film %1 (%2)" msgstr "Kunde inte öppna filmen %1 (%2)" -#: src/tools/dvdomatic.cc:341 +#: src/tools/dvdomatic.cc:348 #, c-format msgid "Could not open film at %s (%s)" msgstr "Kunde inte öppna filmen vid %s (%s)" -#: src/tools/dvdomatic.cc:289 src/tools/dvdomatic.cc:412 -#: src/tools/dvdomatic.cc:542 +#: src/tools/dvdomatic.cc:288 src/tools/dvdomatic.cc:419 +#: src/tools/dvdomatic.cc:506 msgid "DVD-o-matic" msgstr "DVD-o-matic" -#: src/tools/dvdomatic.cc:77 +#: src/tools/dvdomatic.cc:76 msgid "Film changed" msgstr "Film ändrad" -#: src/tools/dvdomatic.cc:418 +#: src/tools/dvdomatic.cc:425 msgid "Free, open-source DCP generation from almost anything." msgstr "" "Fri, öppen-källkodsprogramvara för DCP-generering från nästan vad som helst." -#: src/tools/dvdomatic.cc:162 +#: src/tools/dvdomatic.cc:161 msgid "New..." msgstr "Ny..." -#: src/tools/dvdomatic.cc:177 +#: src/tools/dvdomatic.cc:176 msgid "S&how DCP" msgstr "&Visa DCP" -#: src/tools/dvdomatic.cc:76 +#: src/tools/dvdomatic.cc:75 #, fuzzy, c-format msgid "Save changes to film \"%s\" before closing?" msgstr "Spara ändringarna till filmen \"%1\" före avslut?" -#: src/tools/dvdomatic.cc:321 +#: src/tools/dvdomatic.cc:328 msgid "Select film to open" msgstr "Välj film att öppna" -#: src/tools/dvdomatic.cc:305 -msgid "The directory %1 already exists." -msgstr "Katalogen %1 finns redan." +#: src/tools/dvdomatic.cc:307 +msgid "" +"The directory %1 already exists and is not empty. Are you sure you want to " +"use it?" +msgstr "" -#: src/tools/dvdomatic.cc:326 +#: src/tools/dvdomatic.cc:333 msgid "" "You did not select a folder. Make sure that you select a folder before " "clicking Open." msgstr "" "Du har inte valt en folder. Se till att välja en folder innan du klickar på " "Öppna." + +#~ msgid "The directory %1 already exists." +#~ msgstr "Katalogen %1 finns redan." diff --git a/src/wx/po/es_ES.po b/src/wx/po/es_ES.po index 56c0856bd..efc8436c5 100644 --- a/src/wx/po/es_ES.po +++ b/src/wx/po/es_ES.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: libdvdomatic-wx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-22 15:06+0100\n" +"POT-Creation-Date: 2013-05-09 09:51+0100\n" "PO-Revision-Date: 2013-04-02 19:08-0500\n" "Last-Translator: Manuel AC \n" "Language-Team: Manuel AC \n" @@ -21,8 +21,8 @@ msgstr "" msgid "%" msgstr "%" -#: src/wx/config_dialog.cc:61 -msgid "(restart DVD-o-matic to see language changes)" +#: src/wx/config_dialog.cc:98 +msgid "(restart DCP-o-matic to see language changes)" msgstr "" #: src/wx/film_editor.cc:1276 @@ -33,7 +33,11 @@ msgstr "1 canal" msgid "A/B" msgstr "A/B" -#: src/wx/config_dialog.cc:143 +#: src/wx/config_dialog.cc:61 +msgid "A/B mode" +msgstr "" + +#: src/wx/config_dialog.cc:325 msgid "Add" msgstr "Añadir" @@ -79,7 +83,7 @@ msgstr "pero tengo que usar el fader a" msgid "Calculate..." msgstr "Calcular..." -#: src/wx/job_manager_view.cc:88 +#: src/wx/job_manager_view.cc:97 msgid "Cancel" msgstr "" @@ -123,6 +127,11 @@ msgstr "No se pudo establecer el contenido: %s" msgid "Create in folder" msgstr "Crear en carpeta" +#: src/wx/config_dialog.cc:244 +#, fuzzy +msgid "Creator" +msgstr "Crear en carpeta" + #: src/wx/film_editor.cc:1371 #, c-format msgid "Cropped to %dx%d (%.2f:1)\n" @@ -140,28 +149,38 @@ msgstr "Velocidad DCP" msgid "DCP Name" msgstr "Nombre DCP" -#: src/wx/wx_util.cc:61 +#: src/wx/config_dialog.cc:46 +#, fuzzy +msgid "DCP-o-matic Preferences" +msgstr "Preferencias DVD-o-matic" + +#: src/wx/wx_util.cc:63 src/wx/wx_util.cc:71 msgid "DVD-o-matic" msgstr "DVD-o-matic" -#: src/wx/config_dialog.cc:44 -msgid "DVD-o-matic Preferences" -msgstr "Preferencias DVD-o-matic" - #: src/wx/audio_dialog.cc:101 #, fuzzy, c-format msgid "DVD-o-matic audio - %s" msgstr "Audio DVD-o-matic - %1" -#: src/wx/config_dialog.cc:102 +#: src/wx/config_dialog.cc:120 msgid "Default DCI name details" msgstr "Detalles por defecto del nombre DCI" -#: src/wx/config_dialog.cc:93 +#: src/wx/config_dialog.cc:130 +#, fuzzy +msgid "Default content type" +msgstr "Tipo de contenido" + +#: src/wx/config_dialog.cc:111 msgid "Default directory for new films" msgstr "Carpeta por defecto para nuevas películas" -#: src/wx/film_editor.cc:116 src/wx/job_manager_view.cc:92 +#: src/wx/config_dialog.cc:125 +msgid "Default format" +msgstr "" + +#: src/wx/film_editor.cc:116 src/wx/job_manager_view.cc:109 msgid "Details..." msgstr "Detalles..." @@ -173,17 +192,18 @@ msgstr "Espacio requerido en disco" msgid "Duration" msgstr "Duración" -#: src/wx/config_dialog.cc:145 +#: src/wx/config_dialog.cc:327 msgid "Edit" msgstr "Editar" -#: src/wx/config_dialog.cc:103 src/wx/config_dialog.cc:122 +#: src/wx/config_dialog.cc:121 src/wx/config_dialog.cc:282 #: src/wx/film_editor.cc:312 msgid "Edit..." msgstr "Editar..." -#: src/wx/config_dialog.cc:128 -msgid "Encoding Servers" +#: src/wx/config_dialog.cc:55 +#, fuzzy +msgid "Encoding servers" msgstr "Servidores de codificación" #: src/wx/film_editor.cc:171 @@ -242,10 +262,14 @@ msgstr "Hz" msgid "I want to play this back at fader" msgstr "Quiero reproducir con el fader a" -#: src/wx/config_dialog.cc:132 +#: src/wx/config_dialog.cc:201 src/wx/config_dialog.cc:314 msgid "IP address" msgstr "Dirección IP" +#: src/wx/config_dialog.cc:240 +msgid "Issuer" +msgstr "" + #: src/wx/film_editor.cc:339 msgid "JPEG2000 bandwidth" msgstr "Ancho de banda JPEG2000" @@ -262,6 +286,14 @@ msgstr "Longitud" msgid "MBps" msgstr "MBps" +#: src/wx/config_dialog.cc:57 +msgid "Metadata" +msgstr "" + +#: src/wx/config_dialog.cc:53 +msgid "Miscellaneous" +msgstr "" + #: src/wx/dir_picker_ctrl.cc:52 msgid "My Documents" msgstr "Mis documentos" @@ -296,6 +328,15 @@ msgstr "Tipo de paquete (ej. OV)" msgid "Padded with black to %dx%d (%.2f:1)\n" msgstr "" +#: src/wx/config_dialog.cc:213 +#, fuzzy +msgid "Password" +msgstr "Clave del TMS" + +#: src/wx/job_manager_view.cc:103 src/wx/job_manager_view.cc:188 +msgid "Pause" +msgstr "" + #: src/wx/audio_dialog.cc:60 msgid "Peak" msgstr "Pico" @@ -316,23 +357,29 @@ msgstr "RMS" msgid "Rating (e.g. 15)" msgstr "Clasificación (ej. 16)" -#: src/wx/config_dialog.cc:118 -msgid "Reference filters for A/B" +#: src/wx/config_dialog.cc:278 +#, fuzzy +msgid "Reference filters" msgstr "Filtros de referencia para A/B" -#: src/wx/config_dialog.cc:107 -msgid "Reference scaler for A/B" +#: src/wx/config_dialog.cc:267 +#, fuzzy +msgid "Reference scaler" msgstr "Escalador de referencia para A/B" -#: src/wx/config_dialog.cc:147 +#: src/wx/config_dialog.cc:329 msgid "Remove" msgstr "Quitar" +#: src/wx/job_manager_view.cc:191 +msgid "Resume" +msgstr "" + #: src/wx/film_editor.cc:282 msgid "Right crop" msgstr "Recorte derecha" -#: src/wx/job_manager_view.cc:108 +#: src/wx/job_manager_view.cc:126 msgid "Running" msgstr "Ejecutando" @@ -357,7 +404,7 @@ msgstr "Seleccionar fichero de contenido" msgid "Server" msgstr "Servidor" -#: src/wx/config_dialog.cc:49 +#: src/wx/config_dialog.cc:87 msgid "Set language" msgstr "" @@ -393,27 +440,21 @@ msgstr "Escala del subtítulo" msgid "Subtitles" msgstr "Subtítulos" -#: src/wx/config_dialog.cc:68 -msgid "TMS IP address" -msgstr "Dirección IP del TMS" - -#: src/wx/config_dialog.cc:83 -msgid "TMS password" -msgstr "Clave del TMS" +#: src/wx/config_dialog.cc:59 +#, fuzzy +msgid "TMS" +msgstr "RMS" -#: src/wx/config_dialog.cc:73 -msgid "TMS target path" +#: src/wx/config_dialog.cc:205 +#, fuzzy +msgid "Target path" msgstr "Ruta en el TMS" -#: src/wx/config_dialog.cc:78 -msgid "TMS user name" -msgstr "Usuario del TMS" - #: src/wx/dci_metadata_dialog.cc:41 msgid "Territory (e.g. UK)" msgstr "Territorio (ej. ES)" -#: src/wx/config_dialog.cc:136 +#: src/wx/config_dialog.cc:318 msgid "Threads" msgstr "Hilos" @@ -421,7 +462,7 @@ msgstr "Hilos" msgid "Threads to use" msgstr "Hilos a utilizar" -#: src/wx/config_dialog.cc:88 +#: src/wx/config_dialog.cc:106 msgid "Threads to use for encoding on this host" msgstr "Hilos a utilizar para la codificación en esta máquina" @@ -466,6 +507,11 @@ msgstr "Usar el audio del contenido" msgid "Use external audio" msgstr "Usar audio externo" +#: src/wx/config_dialog.cc:209 +#, fuzzy +msgid "User name" +msgstr "Usar el nombre DCI" + #: src/wx/film_editor.cc:75 msgid "Video" msgstr "Vídeo" @@ -516,5 +562,11 @@ msgstr "s" msgid "unknown" msgstr "desconocido" +#~ msgid "TMS IP address" +#~ msgstr "Dirección IP del TMS" + +#~ msgid "TMS user name" +#~ msgstr "Usuario del TMS" + #~ msgid "Original Size" #~ msgstr "Tamaño original" diff --git a/src/wx/po/fr_FR.po b/src/wx/po/fr_FR.po index c7ef31f5a..cb2899a07 100644 --- a/src/wx/po/fr_FR.po +++ b/src/wx/po/fr_FR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-22 15:06+0100\n" +"POT-Creation-Date: 2013-05-09 09:51+0100\n" "PO-Revision-Date: 2013-03-20 00:34+0100\n" "Last-Translator: FreeDCP.net \n" "Language-Team: \n" @@ -20,8 +20,8 @@ msgstr "" msgid "%" msgstr "%" -#: src/wx/config_dialog.cc:61 -msgid "(restart DVD-o-matic to see language changes)" +#: src/wx/config_dialog.cc:98 +msgid "(restart DCP-o-matic to see language changes)" msgstr "" #: src/wx/film_editor.cc:1276 @@ -32,7 +32,11 @@ msgstr "1 canal" msgid "A/B" msgstr "A/B" -#: src/wx/config_dialog.cc:143 +#: src/wx/config_dialog.cc:61 +msgid "A/B mode" +msgstr "" + +#: src/wx/config_dialog.cc:325 msgid "Add" msgstr "Ajouter" @@ -78,7 +82,7 @@ msgstr "Je souhaite utiliser ce volume" msgid "Calculate..." msgstr "Calcul..." -#: src/wx/job_manager_view.cc:88 +#: src/wx/job_manager_view.cc:97 msgid "Cancel" msgstr "Annuler" @@ -122,6 +126,11 @@ msgstr "Sélectionner du contenu impossible : %s" msgid "Create in folder" msgstr "Créer dans le dossier" +#: src/wx/config_dialog.cc:244 +#, fuzzy +msgid "Creator" +msgstr "Créer dans le dossier" + #: src/wx/film_editor.cc:1371 #, c-format msgid "Cropped to %dx%d (%.2f:1)\n" @@ -139,28 +148,38 @@ msgstr "Cadence image du DCP" msgid "DCP Name" msgstr "Nom du DCP" -#: src/wx/wx_util.cc:61 +#: src/wx/config_dialog.cc:46 +#, fuzzy +msgid "DCP-o-matic Preferences" +msgstr "Préférences DVD-o-matic" + +#: src/wx/wx_util.cc:63 src/wx/wx_util.cc:71 msgid "DVD-o-matic" msgstr "DVD-o-matic" -#: src/wx/config_dialog.cc:44 -msgid "DVD-o-matic Preferences" -msgstr "Préférences DVD-o-matic" - #: src/wx/audio_dialog.cc:101 #, c-format msgid "DVD-o-matic audio - %s" msgstr "Son DVD-o-matic - %s" -#: src/wx/config_dialog.cc:102 +#: src/wx/config_dialog.cc:120 msgid "Default DCI name details" msgstr "Détails du nom DCI par défaut" -#: src/wx/config_dialog.cc:93 +#: src/wx/config_dialog.cc:130 +#, fuzzy +msgid "Default content type" +msgstr "Type de Contenu" + +#: src/wx/config_dialog.cc:111 msgid "Default directory for new films" msgstr "Dossier par défaut des nouveaux films" -#: src/wx/film_editor.cc:116 src/wx/job_manager_view.cc:92 +#: src/wx/config_dialog.cc:125 +msgid "Default format" +msgstr "" + +#: src/wx/film_editor.cc:116 src/wx/job_manager_view.cc:109 msgid "Details..." msgstr "Détails..." @@ -172,17 +191,18 @@ msgstr "Espace disque requis" msgid "Duration" msgstr "Durée" -#: src/wx/config_dialog.cc:145 +#: src/wx/config_dialog.cc:327 msgid "Edit" msgstr "Édition" -#: src/wx/config_dialog.cc:103 src/wx/config_dialog.cc:122 +#: src/wx/config_dialog.cc:121 src/wx/config_dialog.cc:282 #: src/wx/film_editor.cc:312 msgid "Edit..." msgstr "Éditer..." -#: src/wx/config_dialog.cc:128 -msgid "Encoding Servers" +#: src/wx/config_dialog.cc:55 +#, fuzzy +msgid "Encoding servers" msgstr "Serveurs d'encodage" #: src/wx/film_editor.cc:171 @@ -241,10 +261,14 @@ msgstr "Hz" msgid "I want to play this back at fader" msgstr "Je veux le jouer à ce volume" -#: src/wx/config_dialog.cc:132 +#: src/wx/config_dialog.cc:201 src/wx/config_dialog.cc:314 msgid "IP address" msgstr "Adresse IP" +#: src/wx/config_dialog.cc:240 +msgid "Issuer" +msgstr "" + #: src/wx/film_editor.cc:339 msgid "JPEG2000 bandwidth" msgstr "Qualité JPEG2000" @@ -261,6 +285,14 @@ msgstr "Longueur / durée" msgid "MBps" msgstr "MBps" +#: src/wx/config_dialog.cc:57 +msgid "Metadata" +msgstr "" + +#: src/wx/config_dialog.cc:53 +msgid "Miscellaneous" +msgstr "" + #: src/wx/dir_picker_ctrl.cc:52 msgid "My Documents" msgstr "Mes Documents" @@ -295,6 +327,15 @@ msgstr "Type de paquet (ex. OV)" msgid "Padded with black to %dx%d (%.2f:1)\n" msgstr "" +#: src/wx/config_dialog.cc:213 +#, fuzzy +msgid "Password" +msgstr "Mot de passe du TMS" + +#: src/wx/job_manager_view.cc:103 src/wx/job_manager_view.cc:188 +msgid "Pause" +msgstr "" + #: src/wx/audio_dialog.cc:60 msgid "Peak" msgstr "Crête" @@ -315,23 +356,29 @@ msgstr "RMS" msgid "Rating (e.g. 15)" msgstr "Rating (ex. 15)" -#: src/wx/config_dialog.cc:118 -msgid "Reference filters for A/B" +#: src/wx/config_dialog.cc:278 +#, fuzzy +msgid "Reference filters" msgstr "Filtres de référence pour A/B" -#: src/wx/config_dialog.cc:107 -msgid "Reference scaler for A/B" +#: src/wx/config_dialog.cc:267 +#, fuzzy +msgid "Reference scaler" msgstr "Échelle de référence pour A/B" -#: src/wx/config_dialog.cc:147 +#: src/wx/config_dialog.cc:329 msgid "Remove" msgstr "Supprimer" +#: src/wx/job_manager_view.cc:191 +msgid "Resume" +msgstr "" + #: src/wx/film_editor.cc:282 msgid "Right crop" msgstr "Découpe droite" -#: src/wx/job_manager_view.cc:108 +#: src/wx/job_manager_view.cc:126 msgid "Running" msgstr "Progression" @@ -356,7 +403,7 @@ msgstr "Sélectionner le fichier vidéo" msgid "Server" msgstr "Serveur" -#: src/wx/config_dialog.cc:49 +#: src/wx/config_dialog.cc:87 msgid "Set language" msgstr "" @@ -392,27 +439,21 @@ msgstr "Taille du sous-titre" msgid "Subtitles" msgstr "Sous-titres" -#: src/wx/config_dialog.cc:68 -msgid "TMS IP address" -msgstr "Adresse IP du TMS" - -#: src/wx/config_dialog.cc:83 -msgid "TMS password" -msgstr "Mot de passe du TMS" +#: src/wx/config_dialog.cc:59 +#, fuzzy +msgid "TMS" +msgstr "RMS" -#: src/wx/config_dialog.cc:73 -msgid "TMS target path" +#: src/wx/config_dialog.cc:205 +#, fuzzy +msgid "Target path" msgstr "Chemin d'accès du TMS" -#: src/wx/config_dialog.cc:78 -msgid "TMS user name" -msgstr "Nom d'utilisateur du TMS" - #: src/wx/dci_metadata_dialog.cc:41 msgid "Territory (e.g. UK)" msgstr "Territoire (ex. FR)" -#: src/wx/config_dialog.cc:136 +#: src/wx/config_dialog.cc:318 msgid "Threads" msgstr "Processus" @@ -420,7 +461,7 @@ msgstr "Processus" msgid "Threads to use" msgstr "Nombre de processus à utiliser" -#: src/wx/config_dialog.cc:88 +#: src/wx/config_dialog.cc:106 msgid "Threads to use for encoding on this host" msgstr "Nombre de processus à utiliser sur cet hôte" @@ -464,6 +505,11 @@ msgstr "Utiliser le son intégré" msgid "Use external audio" msgstr "Utiliser une source audio externe" +#: src/wx/config_dialog.cc:209 +#, fuzzy +msgid "User name" +msgstr "Utiliser le nom DCI" + #: src/wx/film_editor.cc:75 msgid "Video" msgstr "Vidéo" @@ -514,5 +560,11 @@ msgstr "s" msgid "unknown" msgstr "inconnu" +#~ msgid "TMS IP address" +#~ msgstr "Adresse IP du TMS" + +#~ msgid "TMS user name" +#~ msgstr "Nom d'utilisateur du TMS" + #~ msgid "Original Size" #~ msgstr "Taille Originale" diff --git a/src/wx/po/it_IT.po b/src/wx/po/it_IT.po index 2d4ee7fd7..37ee492fe 100644 --- a/src/wx/po/it_IT.po +++ b/src/wx/po/it_IT.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: IT VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-22 15:06+0100\n" +"POT-Creation-Date: 2013-05-09 09:51+0100\n" "PO-Revision-Date: 2013-04-28 10:27+0100\n" "Last-Translator: Maci \n" "Language-Team: \n" @@ -21,8 +21,9 @@ msgstr "" msgid "%" msgstr "%" -#: src/wx/config_dialog.cc:61 -msgid "(restart DVD-o-matic to see language changes)" +#: src/wx/config_dialog.cc:98 +#, fuzzy +msgid "(restart DCP-o-matic to see language changes)" msgstr "(riavviare DVD-o-matic per vedere i cambiamenti di lingua)" #: src/wx/film_editor.cc:1276 @@ -33,7 +34,11 @@ msgstr "1 canale" msgid "A/B" msgstr "A/B" -#: src/wx/config_dialog.cc:143 +#: src/wx/config_dialog.cc:61 +msgid "A/B mode" +msgstr "" + +#: src/wx/config_dialog.cc:325 msgid "Add" msgstr "Aggiungi" @@ -79,7 +84,7 @@ msgstr "Ma dovrò riprodurre con il fader a" msgid "Calculate..." msgstr "Calcola..." -#: src/wx/job_manager_view.cc:88 +#: src/wx/job_manager_view.cc:97 msgid "Cancel" msgstr "Annulla" @@ -123,6 +128,11 @@ msgstr "Non posso regolare il contenuto: %s" msgid "Create in folder" msgstr "Crea nella cartella" +#: src/wx/config_dialog.cc:244 +#, fuzzy +msgid "Creator" +msgstr "Crea nella cartella" + #: src/wx/film_editor.cc:1371 #, c-format msgid "Cropped to %dx%d (%.2f:1)\n" @@ -140,28 +150,38 @@ msgstr "Frequenza fotogrammi del DCP" msgid "DCP Name" msgstr "Nome del DCP" -#: src/wx/wx_util.cc:61 +#: src/wx/config_dialog.cc:46 +#, fuzzy +msgid "DCP-o-matic Preferences" +msgstr "Preferenze DVD-o-matic" + +#: src/wx/wx_util.cc:63 src/wx/wx_util.cc:71 msgid "DVD-o-matic" msgstr "DVD-o-matic" -#: src/wx/config_dialog.cc:44 -msgid "DVD-o-matic Preferences" -msgstr "Preferenze DVD-o-matic" - #: src/wx/audio_dialog.cc:101 #, c-format msgid "DVD-o-matic audio - %s" msgstr "Audio DVD-o-matic - %s" -#: src/wx/config_dialog.cc:102 +#: src/wx/config_dialog.cc:120 msgid "Default DCI name details" msgstr "Dettagli del nome di default DCI" -#: src/wx/config_dialog.cc:93 +#: src/wx/config_dialog.cc:130 +#, fuzzy +msgid "Default content type" +msgstr "Tipo di contenuto" + +#: src/wx/config_dialog.cc:111 msgid "Default directory for new films" msgstr "Directory di default per i nuovi films" -#: src/wx/film_editor.cc:116 src/wx/job_manager_view.cc:92 +#: src/wx/config_dialog.cc:125 +msgid "Default format" +msgstr "" + +#: src/wx/film_editor.cc:116 src/wx/job_manager_view.cc:109 msgid "Details..." msgstr "Dettagli" @@ -173,17 +193,18 @@ msgstr "Spazio su disco rischiesto" msgid "Duration" msgstr "Durata" -#: src/wx/config_dialog.cc:145 +#: src/wx/config_dialog.cc:327 msgid "Edit" msgstr "Modifica" -#: src/wx/config_dialog.cc:103 src/wx/config_dialog.cc:122 +#: src/wx/config_dialog.cc:121 src/wx/config_dialog.cc:282 #: src/wx/film_editor.cc:312 msgid "Edit..." msgstr "Modifica..." -#: src/wx/config_dialog.cc:128 -msgid "Encoding Servers" +#: src/wx/config_dialog.cc:55 +#, fuzzy +msgid "Encoding servers" msgstr "Servers di codifica" #: src/wx/film_editor.cc:171 @@ -242,10 +263,14 @@ msgstr "Hz" msgid "I want to play this back at fader" msgstr "Sto usando il fader a" -#: src/wx/config_dialog.cc:132 +#: src/wx/config_dialog.cc:201 src/wx/config_dialog.cc:314 msgid "IP address" msgstr "Indirizzo IP" +#: src/wx/config_dialog.cc:240 +msgid "Issuer" +msgstr "" + #: src/wx/film_editor.cc:339 msgid "JPEG2000 bandwidth" msgstr "Banda passante JPEG2000" @@ -262,6 +287,14 @@ msgstr "Lunghezza" msgid "MBps" msgstr "MBps" +#: src/wx/config_dialog.cc:57 +msgid "Metadata" +msgstr "" + +#: src/wx/config_dialog.cc:53 +msgid "Miscellaneous" +msgstr "" + #: src/wx/dir_picker_ctrl.cc:52 msgid "My Documents" msgstr "Documenti" @@ -296,6 +329,15 @@ msgstr "Tipo di Package (es. OV)" msgid "Padded with black to %dx%d (%.2f:1)\n" msgstr "Riempito con nero a %dx%d (%.2f:1)\n" +#: src/wx/config_dialog.cc:213 +#, fuzzy +msgid "Password" +msgstr "Password del TMS" + +#: src/wx/job_manager_view.cc:103 src/wx/job_manager_view.cc:188 +msgid "Pause" +msgstr "" + #: src/wx/audio_dialog.cc:60 msgid "Peak" msgstr "Picco" @@ -316,23 +358,29 @@ msgstr "RMS" msgid "Rating (e.g. 15)" msgstr "Classificazione (es. 15)" -#: src/wx/config_dialog.cc:118 -msgid "Reference filters for A/B" +#: src/wx/config_dialog.cc:278 +#, fuzzy +msgid "Reference filters" msgstr "Filtri di riferimento A/B" -#: src/wx/config_dialog.cc:107 -msgid "Reference scaler for A/B" +#: src/wx/config_dialog.cc:267 +#, fuzzy +msgid "Reference scaler" msgstr "Scalatura di riferimento A/B" -#: src/wx/config_dialog.cc:147 +#: src/wx/config_dialog.cc:329 msgid "Remove" msgstr "Rimuovi" +#: src/wx/job_manager_view.cc:191 +msgid "Resume" +msgstr "" + #: src/wx/film_editor.cc:282 msgid "Right crop" msgstr "Taglio a destra" -#: src/wx/job_manager_view.cc:108 +#: src/wx/job_manager_view.cc:126 msgid "Running" msgstr "In corso" @@ -357,7 +405,7 @@ msgstr "Seleziona il file con il contenuto" msgid "Server" msgstr "Server" -#: src/wx/config_dialog.cc:49 +#: src/wx/config_dialog.cc:87 msgid "Set language" msgstr "Seleziona la lingua" @@ -393,27 +441,21 @@ msgstr "Scala dei Sottotitoli" msgid "Subtitles" msgstr "Sottotitoli" -#: src/wx/config_dialog.cc:68 -msgid "TMS IP address" -msgstr "Indirizzo IP del TMS" - -#: src/wx/config_dialog.cc:83 -msgid "TMS password" -msgstr "Password del TMS" +#: src/wx/config_dialog.cc:59 +#, fuzzy +msgid "TMS" +msgstr "RMS" -#: src/wx/config_dialog.cc:73 -msgid "TMS target path" +#: src/wx/config_dialog.cc:205 +#, fuzzy +msgid "Target path" msgstr "Percorso di destinazione del TMS" -#: src/wx/config_dialog.cc:78 -msgid "TMS user name" -msgstr "Nome utente del TMS" - #: src/wx/dci_metadata_dialog.cc:41 msgid "Territory (e.g. UK)" msgstr "Nazione (es. UK)" -#: src/wx/config_dialog.cc:136 +#: src/wx/config_dialog.cc:318 msgid "Threads" msgstr "Threads" @@ -421,7 +463,7 @@ msgstr "Threads" msgid "Threads to use" msgstr "Threads da usare" -#: src/wx/config_dialog.cc:88 +#: src/wx/config_dialog.cc:106 msgid "Threads to use for encoding on this host" msgstr "Threads da usare per codificare su questo host" @@ -465,6 +507,11 @@ msgstr "Usa l'audio del contenuto" msgid "Use external audio" msgstr "Usa l'audio esterno" +#: src/wx/config_dialog.cc:209 +#, fuzzy +msgid "User name" +msgstr "Usa nome DCI" + #: src/wx/film_editor.cc:75 msgid "Video" msgstr "Video" @@ -515,5 +562,11 @@ msgstr "s" msgid "unknown" msgstr "sconosciuto" +#~ msgid "TMS IP address" +#~ msgstr "Indirizzo IP del TMS" + +#~ msgid "TMS user name" +#~ msgstr "Nome utente del TMS" + #~ msgid "Original Size" #~ msgstr "Dimensione Originale" diff --git a/src/wx/po/sv_SE.po b/src/wx/po/sv_SE.po index 4127d77f8..7c10aebcb 100644 --- a/src/wx/po/sv_SE.po +++ b/src/wx/po/sv_SE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DVD-o-matic\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-22 15:06+0100\n" +"POT-Creation-Date: 2013-05-09 09:51+0100\n" "PO-Revision-Date: 2013-04-09 10:13+0100\n" "Last-Translator: Adam Klotblixt \n" "Language-Team: \n" @@ -21,8 +21,9 @@ msgstr "" msgid "%" msgstr "%" -#: src/wx/config_dialog.cc:61 -msgid "(restart DVD-o-matic to see language changes)" +#: src/wx/config_dialog.cc:98 +#, fuzzy +msgid "(restart DCP-o-matic to see language changes)" msgstr "(starta om DVD-o-matic för att se språkändringar)" #: src/wx/film_editor.cc:1276 @@ -33,7 +34,11 @@ msgstr "1 kanal" msgid "A/B" msgstr "A/B" -#: src/wx/config_dialog.cc:143 +#: src/wx/config_dialog.cc:61 +msgid "A/B mode" +msgstr "" + +#: src/wx/config_dialog.cc:325 msgid "Add" msgstr "Lägg till" @@ -79,7 +84,7 @@ msgstr "Men jag måste använda mixervolym" msgid "Calculate..." msgstr "Beräkna..." -#: src/wx/job_manager_view.cc:88 +#: src/wx/job_manager_view.cc:97 msgid "Cancel" msgstr "Avbryt" @@ -123,6 +128,11 @@ msgstr "Kunde inte fastställa innehåll: %s" msgid "Create in folder" msgstr "Skapa i katalog" +#: src/wx/config_dialog.cc:244 +#, fuzzy +msgid "Creator" +msgstr "Skapa i katalog" + #: src/wx/film_editor.cc:1371 #, c-format msgid "Cropped to %dx%d (%.2f:1)\n" @@ -140,28 +150,38 @@ msgstr "DCP bildhastighet" msgid "DCP Name" msgstr "DCP Namn" -#: src/wx/wx_util.cc:61 +#: src/wx/config_dialog.cc:46 +#, fuzzy +msgid "DCP-o-matic Preferences" +msgstr "DVD-o-matic Inställningar" + +#: src/wx/wx_util.cc:63 src/wx/wx_util.cc:71 msgid "DVD-o-matic" msgstr "DVD-o-matic" -#: src/wx/config_dialog.cc:44 -msgid "DVD-o-matic Preferences" -msgstr "DVD-o-matic Inställningar" - #: src/wx/audio_dialog.cc:101 #, c-format msgid "DVD-o-matic audio - %s" msgstr "DVD-o-matic audio - %s" -#: src/wx/config_dialog.cc:102 +#: src/wx/config_dialog.cc:120 msgid "Default DCI name details" msgstr "Detaljer om förvalda DCI-namn" -#: src/wx/config_dialog.cc:93 +#: src/wx/config_dialog.cc:130 +#, fuzzy +msgid "Default content type" +msgstr "Innehållstyp" + +#: src/wx/config_dialog.cc:111 msgid "Default directory for new films" msgstr "Förvald katalog för nya filmer" -#: src/wx/film_editor.cc:116 src/wx/job_manager_view.cc:92 +#: src/wx/config_dialog.cc:125 +msgid "Default format" +msgstr "" + +#: src/wx/film_editor.cc:116 src/wx/job_manager_view.cc:109 msgid "Details..." msgstr "Detaljer..." @@ -173,17 +193,18 @@ msgstr "Diskutrymme som krävs" msgid "Duration" msgstr "Längd" -#: src/wx/config_dialog.cc:145 +#: src/wx/config_dialog.cc:327 msgid "Edit" msgstr "Redigera" -#: src/wx/config_dialog.cc:103 src/wx/config_dialog.cc:122 +#: src/wx/config_dialog.cc:121 src/wx/config_dialog.cc:282 #: src/wx/film_editor.cc:312 msgid "Edit..." msgstr "Redigera..." -#: src/wx/config_dialog.cc:128 -msgid "Encoding Servers" +#: src/wx/config_dialog.cc:55 +#, fuzzy +msgid "Encoding servers" msgstr "Kodningsservrar" #: src/wx/film_editor.cc:171 @@ -242,10 +263,14 @@ msgstr "Hz" msgid "I want to play this back at fader" msgstr "Jag vill spela upp detta med mixervolym" -#: src/wx/config_dialog.cc:132 +#: src/wx/config_dialog.cc:201 src/wx/config_dialog.cc:314 msgid "IP address" msgstr "IP-adress" +#: src/wx/config_dialog.cc:240 +msgid "Issuer" +msgstr "" + #: src/wx/film_editor.cc:339 msgid "JPEG2000 bandwidth" msgstr "JPEG2000 bandbredd" @@ -262,6 +287,14 @@ msgstr "Längd" msgid "MBps" msgstr "MBps" +#: src/wx/config_dialog.cc:57 +msgid "Metadata" +msgstr "" + +#: src/wx/config_dialog.cc:53 +msgid "Miscellaneous" +msgstr "" + #: src/wx/dir_picker_ctrl.cc:52 msgid "My Documents" msgstr "Mina Dokument" @@ -296,6 +329,15 @@ msgstr "Förpackningstyp (ex. OV)" msgid "Padded with black to %dx%d (%.2f:1)\n" msgstr "Svarta kanter tillagda för %dx%d (%.2f:1)\n" +#: src/wx/config_dialog.cc:213 +#, fuzzy +msgid "Password" +msgstr "TMS lösenord" + +#: src/wx/job_manager_view.cc:103 src/wx/job_manager_view.cc:188 +msgid "Pause" +msgstr "" + #: src/wx/audio_dialog.cc:60 msgid "Peak" msgstr "Topp" @@ -316,23 +358,29 @@ msgstr "RMS" msgid "Rating (e.g. 15)" msgstr "Klassificering (ex. 15)" -#: src/wx/config_dialog.cc:118 -msgid "Reference filters for A/B" +#: src/wx/config_dialog.cc:278 +#, fuzzy +msgid "Reference filters" msgstr "Referensfilter för A/B" -#: src/wx/config_dialog.cc:107 -msgid "Reference scaler for A/B" +#: src/wx/config_dialog.cc:267 +#, fuzzy +msgid "Reference scaler" msgstr "Referensomskalare för A/B" -#: src/wx/config_dialog.cc:147 +#: src/wx/config_dialog.cc:329 msgid "Remove" msgstr "Ta bort" +#: src/wx/job_manager_view.cc:191 +msgid "Resume" +msgstr "" + #: src/wx/film_editor.cc:282 msgid "Right crop" msgstr "Höger beskärning" -#: src/wx/job_manager_view.cc:108 +#: src/wx/job_manager_view.cc:126 msgid "Running" msgstr "Körs" @@ -357,7 +405,7 @@ msgstr "Välj innehållsfil" msgid "Server" msgstr "Server" -#: src/wx/config_dialog.cc:49 +#: src/wx/config_dialog.cc:87 msgid "Set language" msgstr "Välj språk" @@ -393,27 +441,21 @@ msgstr "Undertext Skalning" msgid "Subtitles" msgstr "Undertexter" -#: src/wx/config_dialog.cc:68 -msgid "TMS IP address" -msgstr "TMS IP-adress" - -#: src/wx/config_dialog.cc:83 -msgid "TMS password" -msgstr "TMS lösenord" +#: src/wx/config_dialog.cc:59 +#, fuzzy +msgid "TMS" +msgstr "RMS" -#: src/wx/config_dialog.cc:73 -msgid "TMS target path" +#: src/wx/config_dialog.cc:205 +#, fuzzy +msgid "Target path" msgstr "TMS målsökväg" -#: src/wx/config_dialog.cc:78 -msgid "TMS user name" -msgstr "TMS användarnamn" - #: src/wx/dci_metadata_dialog.cc:41 msgid "Territory (e.g. UK)" msgstr "Område (ex. SV)" -#: src/wx/config_dialog.cc:136 +#: src/wx/config_dialog.cc:318 msgid "Threads" msgstr "Trådar" @@ -421,7 +463,7 @@ msgstr "Trådar" msgid "Threads to use" msgstr "Antal trådar att använda" -#: src/wx/config_dialog.cc:88 +#: src/wx/config_dialog.cc:106 msgid "Threads to use for encoding on this host" msgstr "Antal trådar att använda vid kodning på denna maskin" @@ -466,6 +508,11 @@ msgstr "Använd innehållets audio" msgid "Use external audio" msgstr "Använd extern audio" +#: src/wx/config_dialog.cc:209 +#, fuzzy +msgid "User name" +msgstr "Använd DCI-namnet" + #: src/wx/film_editor.cc:75 msgid "Video" msgstr "Video" @@ -516,5 +563,11 @@ msgstr "s" msgid "unknown" msgstr "okänt" +#~ msgid "TMS IP address" +#~ msgstr "TMS IP-adress" + +#~ msgid "TMS user name" +#~ msgstr "TMS användarnamn" + #~ msgid "Original Size" #~ msgstr "Ursprunglig Storlek" -- cgit v1.2.3 From f08d36982bf940dbd59caf6f24a90c1429fca5f8 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 9 May 2013 21:32:58 +0100 Subject: Edit -> Properties and move timeline button. --- src/wx/film_editor.cc | 26 +++++++++++++------------- src/wx/film_editor.h | 10 +++++----- 2 files changed, 18 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 884904e51..ca43ffb8a 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -214,10 +214,10 @@ FilmEditor::connect_to_widgets () _content->Connect (wxID_ANY, wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler (FilmEditor::content_activated), 0, this); _content_add->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_add_clicked), 0, this); _content_remove->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_remove_clicked), 0, this); - _content_edit->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_edit_clicked), 0, this); + _content_properties->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_properties_clicked), 0, this); _content_earlier->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_earlier_clicked), 0, this); _content_later->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_later_clicked), 0, this); - _timeline_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::timeline_clicked), 0, this); + _content_timeline->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_timeline_clicked), 0, this); _loop_content->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::loop_content_toggled), 0, this); _loop_count->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::loop_count_changed), 0, this); _left_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::left_crop_changed), 0, this); @@ -361,12 +361,14 @@ FilmEditor::make_content_panel () b->Add (_content_add); _content_remove = new wxButton (_content_panel, wxID_ANY, _("Remove")); b->Add (_content_remove); - _content_edit = new wxButton (_content_panel, wxID_ANY, _("Edit...")); - b->Add (_content_edit); + _content_properties = new wxButton (_content_panel, wxID_ANY, _("Properties...")); + b->Add (_content_properties); _content_earlier = new wxButton (_content_panel, wxID_ANY, _("Earlier")); b->Add (_content_earlier); _content_later = new wxButton (_content_panel, wxID_ANY, _("Later")); b->Add (_content_later); + _content_timeline = new wxButton (_content_panel, wxID_ANY, _("Timeline...")); + b->Add (_content_timeline); s->Add (b, 0, wxALL, 4); @@ -384,9 +386,6 @@ FilmEditor::make_content_panel () add_label_to_sizer (h, _content_panel, _("times")); _content_sizer->Add (h, 0, wxALL, 6); - _timeline_button = new wxButton (_content_panel, wxID_ANY, _("Timeline...")); - _content_sizer->Add (_timeline_button, 0, wxALL, 6); - _loop_count->SetRange (2, 1024); } @@ -1250,22 +1249,22 @@ FilmEditor::content_activated (wxListEvent& ev) ContentList c = _film->content (); assert (ev.GetIndex() >= 0 && size_t (ev.GetIndex()) < c.size ()); - edit_content (c[ev.GetIndex()]); + content_properties (c[ev.GetIndex()]); } void -FilmEditor::content_edit_clicked (wxCommandEvent &) +FilmEditor::content_properties_clicked (wxCommandEvent &) { shared_ptr c = selected_content (); if (!c) { return; } - edit_content (c); + content_properties (c); } void -FilmEditor::edit_content (shared_ptr c) +FilmEditor::content_properties (shared_ptr c) { shared_ptr im = dynamic_pointer_cast (c); if (im) { @@ -1326,7 +1325,7 @@ FilmEditor::setup_content_button_sensitivity () shared_ptr selection = selected_content (); - _content_edit->Enable ( + _content_properties->Enable ( selection && _generally_sensitive && (dynamic_pointer_cast (selection) || dynamic_pointer_cast (selection)) ); @@ -1334,6 +1333,7 @@ FilmEditor::setup_content_button_sensitivity () _content_remove->Enable (selection && _generally_sensitive); _content_earlier->Enable (selection && _generally_sensitive); _content_later->Enable (selection && _generally_sensitive); + _content_timeline->Enable (_generally_sensitive); } shared_ptr @@ -1439,7 +1439,7 @@ FilmEditor::setup_loop_sensitivity () } void -FilmEditor::timeline_clicked (wxCommandEvent &) +FilmEditor::content_timeline_clicked (wxCommandEvent &) { if (_timeline_dialog) { _timeline_dialog->Destroy (); diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index 685e7864f..41f7bfd1b 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -69,7 +69,7 @@ private: void content_activated (wxListEvent &); void content_add_clicked (wxCommandEvent &); void content_remove_clicked (wxCommandEvent &); - void content_edit_clicked (wxCommandEvent &); + void content_properties_clicked (wxCommandEvent &); void content_earlier_clicked (wxCommandEvent &); void content_later_clicked (wxCommandEvent &); void imagemagick_video_length_changed (wxCommandEvent &); @@ -94,7 +94,7 @@ private: void edit_filters_clicked (wxCommandEvent &); void loop_content_toggled (wxCommandEvent &); void loop_count_changed (wxCommandEvent &); - void timeline_clicked (wxCommandEvent &); + void content_timeline_clicked (wxCommandEvent &); /* Handle changes to the model */ void film_changed (Film::Property); @@ -117,7 +117,7 @@ private: void active_jobs_changed (bool); boost::shared_ptr selected_content (); - void edit_content (boost::shared_ptr); + void content_properties (boost::shared_ptr); wxNotebook* _notebook; wxPanel* _film_panel; @@ -140,13 +140,13 @@ private: wxListCtrl* _content; wxButton* _content_add; wxButton* _content_remove; - wxButton* _content_edit; + wxButton* _content_properties; wxButton* _content_earlier; wxButton* _content_later; + wxButton* _content_timeline; wxTextCtrl* _content_information; wxCheckBox* _loop_content; wxSpinCtrl* _loop_count; - wxButton* _timeline_button; wxButton* _edit_dci_button; wxChoice* _format; wxStaticText* _format_description; -- cgit v1.2.3 From bdbddbe89d4996a39dc6e695f23a6457c03774ae Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 9 May 2013 22:54:07 +0100 Subject: Basic retained-mode-style canvas for timeline; allow selection. --- src/lib/types.cc | 25 ++++ src/lib/types.h | 2 + src/lib/util.cc | 16 --- src/wx/timeline.cc | 416 +++++++++++++++++++++++++++++++++++++++-------------- src/wx/timeline.h | 32 ++++- 5 files changed, 363 insertions(+), 128 deletions(-) (limited to 'src') diff --git a/src/lib/types.cc b/src/lib/types.cc index 1e0f48327..c077bad3e 100644 --- a/src/lib/types.cc +++ b/src/lib/types.cc @@ -19,6 +19,9 @@ #include "types.h" +using std::max; +using std::min; + bool operator== (Crop const & a, Crop const & b) { return (a.left == b.left && a.right == b.right && a.top == b.top && a.bottom == b.bottom); @@ -29,3 +32,25 @@ bool operator!= (Crop const & a, Crop const & b) return !(a == b); } + +/** @param other A Rect. + * @return The intersection of this with `other'. + */ +Rect +Rect::intersection (Rect const & other) const +{ + int const tx = max (x, other.x); + int const ty = max (y, other.y); + + return Rect ( + tx, ty, + min (x + width, other.x + other.width) - tx, + min (y + height, other.y + other.height) - ty + ); +} + +bool +Rect::contains (Position p) const +{ + return (p.x >= x && p.x <= (x + width) && p.y >= y && p.y <= (y + height)); +} diff --git a/src/lib/types.h b/src/lib/types.h index f9e9b2f4b..5e4826918 100644 --- a/src/lib/types.h +++ b/src/lib/types.h @@ -105,6 +105,8 @@ struct Rect } Rect intersection (Rect const & other) const; + + bool contains (Position) const; }; #endif diff --git a/src/lib/util.cc b/src/lib/util.cc index 6c8166143..5e957f923 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -608,22 +608,6 @@ Socket::read_uint32 () return ntohl (v); } -/** @param other A Rect. - * @return The intersection of this with `other'. - */ -Rect -Rect::intersection (Rect const & other) const -{ - int const tx = max (x, other.x); - int const ty = max (y, other.y); - - return Rect ( - tx, ty, - min (x + width, other.x + other.width) - tx, - min (y + height, other.y + other.height) - ty - ); -} - /** Round a number up to the nearest multiple of another number. * @param c Index. * @param s Array of numbers to round, indexed by c. diff --git a/src/wx/timeline.cc b/src/wx/timeline.cc index 253903888..731e72168 100644 --- a/src/wx/timeline.cc +++ b/src/wx/timeline.cc @@ -27,69 +27,260 @@ using std::list; using std::cout; using std::max; using boost::shared_ptr; +using boost::dynamic_pointer_cast; using boost::bind; -int const Timeline::_track_height = 64; - -Timeline::Timeline (wxWindow* parent, shared_ptr pl) - : wxPanel (parent) - , _playlist (pl) +class View { - SetDoubleBuffered (true); - - Connect (wxID_ANY, wxEVT_PAINT, wxPaintEventHandler (Timeline::paint), 0, this); +public: + View (Timeline& t) + : _timeline (t) + { - if (pl->audio_from() == Playlist::AUDIO_FFMPEG) { - SetMinSize (wxSize (640, _track_height * 2 + 96)); - } else { - SetMinSize (wxSize (640, _track_height * (max (size_t (1), pl->audio().size()) + 1) + 96)); } + + virtual void paint (wxGraphicsContext *) = 0; + virtual Rect bbox () const = 0; - pl->Changed.connect (bind (&Timeline::playlist_changed, this)); - pl->ContentChanged.connect (bind (&Timeline::playlist_changed, this)); -} +protected: + int time_x (Time t) const + { + return _timeline.tracks_position().x + t * _timeline.pixels_per_second(); + } + + Timeline& _timeline; +}; -template -int -plot_content_list ( - list > content, wxGraphicsContext* gc, int x, int y, double pixels_per_second, int track_height, wxString type, bool consecutive - ) +class ContentView : public View { - Time t = 0; - for (typename list >::iterator i = content.begin(); i != content.end(); ++i) { - Time const len = (*i)->temporal_length (); +public: + ContentView (Timeline& tl, boost::shared_ptr c, Time s, int t) + : View (tl) + , _content (c) + , _start (s) + , _track (t) + , _selected (false) + { + + } + + void paint (wxGraphicsContext* gc) + { + shared_ptr content = _content.lock (); + if (!content) { + return; + } + + Time const len = content->temporal_length (); + + gc->SetPen (*wxBLACK_PEN); + +#if wxMAJOR_VERSION == 2 && wxMINOR_VERSION >= 9 + gc->SetPen (*wxThePenList->FindOrCreatePen (wxColour (0, 0, 0), 4, wxPENSTYLE_SOLID)); + if (_selected) { + gc->SetBrush (*wxTheBrushList->FindOrCreateBrush (wxColour (200, 200, 200), wxBRUSHSTYLE_SOLID)); + } else { + gc->SetBrush (*wxTheBrushList->FindOrCreateBrush (colour(), wxBRUSHSTYLE_SOLID)); + } +#else + gc->SetPen (*wxThePenList->FindOrCreatePen (wxColour (0, 0, 0), 4, wxSOLID)); + if (_selected) { + gc->SetBrush (*wxTheBrushList->FindOrCreateBrush (wxColour (200, 200, 200), wxSOLID)); + } else { + gc->SetBrush (*wxTheBrushList->FindOrCreateBrush (colour(), wxSOLID)); + } +#endif + wxGraphicsPath path = gc->CreatePath (); - path.MoveToPoint (x + t * pixels_per_second, y); - path.AddLineToPoint (x + (t + len) * pixels_per_second, y); - path.AddLineToPoint (x + (t + len) * pixels_per_second, y + track_height); - path.AddLineToPoint (x + t * pixels_per_second, y + track_height); - path.AddLineToPoint (x + t * pixels_per_second, y); + path.MoveToPoint (time_x (_start), y_pos (_track)); + path.AddLineToPoint (time_x (_start + len), y_pos (_track)); + path.AddLineToPoint (time_x (_start + len), y_pos (_track + 1)); + path.AddLineToPoint (time_x (_start), y_pos (_track + 1)); + path.AddLineToPoint (time_x (_start), y_pos (_track)); gc->StrokePath (path); gc->FillPath (path); - wxString name = wxString::Format (wxT ("%s [%s]"), std_to_wx ((*i)->file().filename().string()).data(), type.data()); + wxString name = wxString::Format (wxT ("%s [%s]"), std_to_wx (content->file().filename().string()).data(), type().data()); wxDouble name_width; wxDouble name_height; wxDouble name_descent; wxDouble name_leading; gc->GetTextExtent (name, &name_width, &name_height, &name_descent, &name_leading); - gc->Clip (wxRegion (x + t * pixels_per_second, y, len * pixels_per_second, track_height)); - gc->DrawText (name, t * pixels_per_second + 12, y + track_height - name_height - 4); + gc->Clip (wxRegion (time_x (_start), y_pos (_track), len * _timeline.pixels_per_second(), _timeline.track_height())); + gc->DrawText (name, time_x (_start) + 12, y_pos (_track + 1) - name_height - 4); gc->ResetClip (); + } - if (consecutive) { - t += len; - } else { - y += track_height; + Rect bbox () const + { + shared_ptr content = _content.lock (); + if (!content) { + return Rect (); } + + return Rect (time_x (_start), y_pos (_track), content->temporal_length() * _timeline.pixels_per_second(), _timeline.track_height()); + } + + void set_selected (bool s) { + _selected = s; + _timeline.force_redraw (bbox ()); + } + + bool selected () const { + return _selected; } - if (consecutive) { - y += track_height; + virtual wxString type () const = 0; + virtual wxColour colour () const = 0; + +private: + + int y_pos (int t) const + { + return _timeline.tracks_position().y + t * _timeline.track_height(); + } + + boost::weak_ptr _content; + Time _start; + int _track; + bool _selected; +}; + +class AudioContentView : public ContentView +{ +public: + AudioContentView (Timeline& tl, boost::shared_ptr c, Time s, int t) + : ContentView (tl, c, s, t) + {} + +private: + wxString type () const + { + return _("audio"); + } + + wxColour colour () const + { + return wxColour (149, 121, 232, 255); + } +}; + +class VideoContentView : public ContentView +{ +public: + VideoContentView (Timeline& tl, boost::shared_ptr c, Time s, int t) + : ContentView (tl, c, s, t) + {} + +private: + + wxString type () const + { + return _("video"); + } + + wxColour colour () const + { + return wxColour (242, 92, 120, 255); + } +}; + +class TimeAxisView : public View +{ +public: + TimeAxisView (Timeline& tl, int y) + : View (tl) + , _y (y) + {} + + void paint (wxGraphicsContext* gc) + { +#if wxMAJOR_VERSION == 2 && wxMINOR_VERSION >= 9 + gc->SetPen (*wxThePenList->FindOrCreatePen (wxColour (0, 0, 0), 1, wxPENSTYLE_SOLID)); +#else + gc->SetPen (*wxThePenList->FindOrCreatePen (wxColour (0, 0, 0), 1, wxSOLID)); +#endif + + int mark_interval = rint (128 / _timeline.pixels_per_second ()); + if (mark_interval > 5) { + mark_interval -= mark_interval % 5; + } + if (mark_interval > 10) { + mark_interval -= mark_interval % 10; + } + if (mark_interval > 60) { + mark_interval -= mark_interval % 60; + } + if (mark_interval > 3600) { + mark_interval -= mark_interval % 3600; + } + + if (mark_interval < 1) { + mark_interval = 1; + } + + wxGraphicsPath path = gc->CreatePath (); + path.MoveToPoint (_timeline.x_offset(), _y); + path.AddLineToPoint (_timeline.width(), _y); + gc->StrokePath (path); + + Time t = 0; + while ((t * _timeline.pixels_per_second()) < _timeline.width()) { + wxGraphicsPath path = gc->CreatePath (); + path.MoveToPoint (time_x (t), _y - 4); + path.AddLineToPoint (time_x (t), _y + 4); + gc->StrokePath (path); + + int tc = t; + int const h = tc / 3600; + tc -= h * 3600; + int const m = tc / 60; + tc -= m * 60; + int const s = tc; + + wxString str = wxString::Format (wxT ("%02d:%02d:%02d"), h, m, s); + wxDouble str_width; + wxDouble str_height; + wxDouble str_descent; + wxDouble str_leading; + gc->GetTextExtent (str, &str_width, &str_height, &str_descent, &str_leading); + + int const tx = _timeline.x_offset() + t * _timeline.pixels_per_second(); + if ((tx + str_width) < _timeline.width()) { + gc->DrawText (str, time_x (t), _y + 16); + } + t += mark_interval; + } } - return y; + Rect bbox () const + { + return Rect (0, _y - 4, _timeline.width(), 24); + } + +private: + int _y; +}; + +Timeline::Timeline (wxWindow* parent, shared_ptr pl) + : wxPanel (parent) + , _playlist (pl) + , _pixels_per_second (0) +{ + SetDoubleBuffered (true); + + setup_pixels_per_second (); + + Connect (wxID_ANY, wxEVT_PAINT, wxPaintEventHandler (Timeline::paint), 0, this); + Connect (wxID_ANY, wxEVT_LEFT_DOWN, wxMouseEventHandler (Timeline::left_down), 0, this); + + SetMinSize (wxSize (640, tracks() * track_height() + 96)); + + playlist_changed (); + + pl->Changed.connect (bind (&Timeline::playlist_changed, this)); + pl->ContentChanged.connect (bind (&Timeline::playlist_changed, this)); } void @@ -107,94 +298,99 @@ Timeline::paint (wxPaintEvent &) return; } - int const x_offset = 8; - int y = 8; - int const width = GetSize().GetWidth(); - double const pixels_per_second = (width - x_offset * 2) / (pl->content_length() / pl->video_frame_rate()); - gc->SetFont (gc->CreateFont (*wxNORMAL_FONT)); - gc->SetPen (*wxBLACK_PEN); -#if wxMAJOR_VERSION == 2 && wxMINOR_VERSION >= 9 - gc->SetPen (*wxThePenList->FindOrCreatePen (wxColour (0, 0, 0), 4, wxPENSTYLE_SOLID)); - gc->SetBrush (*wxTheBrushList->FindOrCreateBrush (wxColour (149, 121, 232, 255), wxBRUSHSTYLE_SOLID)); -#else - gc->SetPen (*wxThePenList->FindOrCreatePen (wxColour (0, 0, 0), 4, wxSOLID)); - gc->SetBrush (*wxTheBrushList->FindOrCreateBrush (wxColour (149, 121, 232, 255), wxSOLID)); -#endif - y = plot_content_list (pl->video (), gc, x_offset, y, pixels_per_second, _track_height, _("video"), true); - -#if wxMAJOR_VERSION == 2 && wxMINOR_VERSION >= 9 - gc->SetBrush (*wxTheBrushList->FindOrCreateBrush (wxColour (242, 92, 120, 255), wxBRUSHSTYLE_SOLID)); -#else - gc->SetBrush (*wxTheBrushList->FindOrCreateBrush (wxColour (242, 92, 120, 255), wxSOLID)); -#endif - y = plot_content_list (pl->audio (), gc, x_offset, y, pixels_per_second, _track_height, _("audio"), pl->audio_from() == Playlist::AUDIO_FFMPEG); + /* XXX */ + _pixels_per_second = (width() - x_offset() * 2) / (pl->content_length() / pl->video_frame_rate()); - /* Time axis */ + for (list >::iterator i = _views.begin(); i != _views.end(); ++i) { + (*i)->paint (gc); + } -#if wxMAJOR_VERSION == 2 && wxMINOR_VERSION >= 9 - gc->SetPen (*wxThePenList->FindOrCreatePen (wxColour (0, 0, 0), 1, wxPENSTYLE_SOLID)); -#else - gc->SetPen (*wxThePenList->FindOrCreatePen (wxColour (0, 0, 0), 1, wxSOLID)); -#endif - - int mark_interval = rint (128 / pixels_per_second); - if (mark_interval > 5) { - mark_interval -= mark_interval % 5; + delete gc; +} + +void +Timeline::playlist_changed () +{ + shared_ptr pl = _playlist.lock (); + if (!pl) { + return; } - if (mark_interval > 10) { - mark_interval -= mark_interval % 10; + + _views.clear (); + + int track = 0; + Time time = 0; + list > vc = pl->video (); + for (list >::const_iterator i = vc.begin(); i != vc.end(); ++i) { + _views.push_back (shared_ptr (new VideoContentView (*this, *i, time, track))); + time += (*i)->temporal_length (); } - if (mark_interval > 60) { - mark_interval -= mark_interval % 60; + + ++track; + time = 0; + list > ac = pl->audio (); + for (list >::const_iterator i = ac.begin(); i != ac.end(); ++i) { + _views.push_back (shared_ptr (new AudioContentView (*this, *i, time, track))); + if (pl->audio_from() != Playlist::AUDIO_FFMPEG) { + ++track; + } else { + time += (*i)->temporal_length (); + } + } + + _views.push_back (shared_ptr (new TimeAxisView (*this, tracks() * track_height() + 32))); + + Refresh (); +} + +int +Timeline::tracks () const +{ + shared_ptr pl = _playlist.lock (); + if (!pl) { + return 0; } - if (mark_interval > 3600) { - mark_interval -= mark_interval % 3600; + + if (pl->audio_from() == Playlist::AUDIO_FFMPEG) { + return 2; } - if (mark_interval < 1) { - mark_interval = 1; - } + return 1 + max (size_t (1), pl->audio().size()); +} - wxGraphicsPath path = gc->CreatePath (); - path.MoveToPoint (x_offset, y + 40); - path.AddLineToPoint (width, y + 40); - gc->StrokePath (path); +void +Timeline::setup_pixels_per_second () +{ + shared_ptr pl = _playlist.lock (); + if (!pl) { + return; + } - double t = 0; - while ((t * pixels_per_second) < width) { - wxGraphicsPath path = gc->CreatePath (); - path.MoveToPoint (x_offset + t * pixels_per_second, y + 36); - path.AddLineToPoint (x_offset + t * pixels_per_second, y + 44); - gc->StrokePath (path); + /* XXX */ + _pixels_per_second = (width() - x_offset() * 2) / (pl->content_length() / pl->video_frame_rate()); +} - int tc = t; - int const h = tc / 3600; - tc -= h * 3600; - int const m = tc / 60; - tc -= m * 60; - int const s = tc; - - wxString str = wxString::Format (wxT ("%02d:%02d:%02d"), h, m, s); - wxDouble str_width; - wxDouble str_height; - wxDouble str_descent; - wxDouble str_leading; - gc->GetTextExtent (str, &str_width, &str_height, &str_descent, &str_leading); - - int const tx = x_offset + t * pixels_per_second; - if ((tx + str_width) < width) { - gc->DrawText (str, x_offset + t * pixels_per_second, y + 60); - } - t += mark_interval; +void +Timeline::left_down (wxMouseEvent& ev) +{ + list >::iterator i = _views.begin(); + Position const p (ev.GetX(), ev.GetY()); + while (i != _views.end() && !(*i)->bbox().contains (p)) { + ++i; } - delete gc; + for (list >::iterator j = _views.begin(); j != _views.end(); ++j) { + shared_ptr cv = dynamic_pointer_cast (*j); + if (cv) { + cv->set_selected (i == j); + } + } } void -Timeline::playlist_changed () +Timeline::force_redraw (Rect const & r) { - Refresh (); + RefreshRect (wxRect (r.x, r.y, r.width, r.height), false); } diff --git a/src/wx/timeline.h b/src/wx/timeline.h index 1993eb9c2..59800e7ad 100644 --- a/src/wx/timeline.h +++ b/src/wx/timeline.h @@ -20,19 +20,47 @@ #include #include #include +#include "util.h" class Playlist; +class View; class Timeline : public wxPanel { public: Timeline (wxWindow *, boost::shared_ptr); + void force_redraw (Rect const &); + + int x_offset () const { + return 8; + } + + int width () const { + return GetSize().GetWidth (); + } + + int track_height () const { + return 64; + } + + double pixels_per_second () const { + return _pixels_per_second; + } + + Position tracks_position () const { + return Position (8, 8); + } + + int tracks () const; + private: void paint (wxPaintEvent &); + void left_down (wxMouseEvent &); void playlist_changed (); + void setup_pixels_per_second (); - static int const _track_height; - boost::weak_ptr _playlist; + std::list > _views; + double _pixels_per_second; }; -- cgit v1.2.3 From f6c5598ba6b18d5be753139ea5a8f30781468afc Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 10 May 2013 11:12:45 +0100 Subject: Add missing files. --- dcpomatic_batch.desktop.in | 10 ++ src/tools/dcpomatic_batch.cc | 239 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 249 insertions(+) create mode 100644 dcpomatic_batch.desktop.in create mode 100644 src/tools/dcpomatic_batch.cc (limited to 'src') diff --git a/dcpomatic_batch.desktop.in b/dcpomatic_batch.desktop.in new file mode 100644 index 000000000..bab136e8a --- /dev/null +++ b/dcpomatic_batch.desktop.in @@ -0,0 +1,10 @@ +[Desktop Entry] +Encoding=UTF-8 +Version=1.0 +Type=Application +Terminal=false +Exec=@PREFIX@/bin/dcpomatic_batch +Name=DCP-o-matic Batch Converter +Icon=dcpomatic +Comment=DCP generator +Categories=AudioVideo;Video diff --git a/src/tools/dcpomatic_batch.cc b/src/tools/dcpomatic_batch.cc new file mode 100644 index 000000000..2b0826bc1 --- /dev/null +++ b/src/tools/dcpomatic_batch.cc @@ -0,0 +1,239 @@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include +#include +#include "lib/version.h" +#include "lib/compose.hpp" +#include "lib/config.h" +#include "lib/util.h" +#include "lib/film.h" +#include "lib/job_manager.h" +#include "wx/wx_util.h" +#include "wx/wx_ui_signaller.h" +#include "wx/job_manager_view.h" + +using boost::shared_ptr; + +enum { + ID_file_add_film = 1, + ID_file_quit, + ID_help_about +}; + +void +setup_menu (wxMenuBar* m) +{ + wxMenu* file = new wxMenu; + file->Append (ID_file_add_film, _("&Add Film...")); + file->Append (ID_file_quit, _("&Quit")); + + wxMenu* help = new wxMenu; + help->Append (ID_help_about, _("About")); + + m->Append (file, _("&File")); + m->Append (help, _("&Help")); +} + +class Frame : public wxFrame +{ +public: + Frame (wxString const & title) + : wxFrame (NULL, -1, title) + { + wxMenuBar* bar = new wxMenuBar; + setup_menu (bar); + SetMenuBar (bar); + + Connect (ID_file_add_film, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::file_add_film)); + Connect (ID_file_quit, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::file_quit)); + Connect (ID_help_about, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::help_about)); + + wxPanel* panel = new wxPanel (this); + wxSizer* s = new wxBoxSizer (wxHORIZONTAL); + s->Add (panel, 1, wxEXPAND); + SetSizer (s); + + wxSizer* sizer = new wxBoxSizer (wxVERTICAL); + + JobManagerView* job_manager_view = new JobManagerView (panel, JobManagerView::PAUSE); + sizer->Add (job_manager_view, 1, wxALL | wxEXPAND, 6); + + wxSizer* buttons = new wxBoxSizer (wxHORIZONTAL); + wxButton* add = new wxButton (panel, wxID_ANY, _("Add Film...")); + add->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (Frame::add_film)); + buttons->Add (add, 1, wxALL, 6); + + sizer->Add (buttons, 0, wxALL, 6); + + panel->SetSizer (sizer); + + Connect (wxID_ANY, wxEVT_CLOSE_WINDOW, wxCloseEventHandler (Frame::close)); + } + +private: + bool should_close () + { + if (!JobManager::instance()->work_to_do ()) { + return true; + } + + wxMessageDialog* d = new wxMessageDialog ( + 0, + _("There are unfinished jobs; are you sure you want to quit?"), + _("Unfinished jobs"), + wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION + ); + + bool const r = d->ShowModal() == wxID_YES; + d->Destroy (); + return r; + } + + void close (wxCloseEvent& ev) + { + if (!should_close ()) { + ev.Veto (); + return; + } + + ev.Skip (); + } + + void file_add_film (wxCommandEvent& ev) + { + add_film (ev); + } + + void file_quit (wxCommandEvent &) + { + if (should_close ()) { + Close (true); + } + } + + void help_about (wxCommandEvent &) + { + wxAboutDialogInfo info; + info.SetName (_("DCP-o-matic Batch Converter")); + if (strcmp (dcpomatic_git_commit, "release") == 0) { + info.SetVersion (std_to_wx (String::compose ("version %1", dcpomatic_version))); + } else { + info.SetVersion (std_to_wx (String::compose ("version %1 git %2", dcpomatic_version, dcpomatic_git_commit))); + } + info.SetDescription (_("Free, open-source DCP generation from almost anything.")); + info.SetCopyright (_("(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen")); + + wxArrayString authors; + authors.Add (wxT ("Carl Hetherington")); + authors.Add (wxT ("Terrence Meiczinger")); + authors.Add (wxT ("Paul Davis")); + authors.Add (wxT ("Ole Laursen")); + info.SetDevelopers (authors); + + wxArrayString translators; + translators.Add (wxT ("Olivier Perriere")); + translators.Add (wxT ("Lilian Lefranc")); + translators.Add (wxT ("Thierry Journet")); + translators.Add (wxT ("Massimiliano Broggi")); + translators.Add (wxT ("Manuel AC")); + translators.Add (wxT ("Adam Klotblixt")); + info.SetTranslators (translators); + + info.SetWebSite (wxT ("http://carlh.net/software/dcpomatic")); + wxAboutBox (info); + } + + void add_film (wxCommandEvent &) + { + wxDirDialog* c = new wxDirDialog (this, _("Select film to open"), wxStandardPaths::Get().GetDocumentsDir(), wxDEFAULT_DIALOG_STYLE | wxDD_DIR_MUST_EXIST); + int r; + while (1) { + r = c->ShowModal (); + if (r == wxID_OK && c->GetPath() == wxStandardPaths::Get().GetDocumentsDir()) { + error_dialog (this, _("You did not select a folder. Make sure that you select a folder before clicking Open.")); + } else { + break; + } + } + + if (r == wxID_OK) { + try { + shared_ptr film (new Film (wx_to_std (c->GetPath ()))); + film->make_dcp (); + } catch (std::exception& e) { + wxString p = c->GetPath (); + wxCharBuffer b = p.ToUTF8 (); + error_dialog (this, wxString::Format (_("Could not open film at %s (%s)"), p.data(), std_to_wx (e.what()).data())); + } + } + + c->Destroy (); + } +}; + +class App : public wxApp +{ + bool OnInit () + { + if (!wxApp::OnInit()) { + return false; + } + +#ifdef DCPOMATIC_POSIX + unsetenv ("UBUNTU_MENUPROXY"); +#endif + + /* Enable i18n; this will create a Config object + to look for a force-configured language. This Config + object will be wrong, however, because dcpomatic_setup + hasn't yet been called and there aren't any scalers, filters etc. + set up yet. + */ + dcpomatic_setup_i18n (); + + /* Set things up, including scalers / filters etc. + which will now be internationalised correctly. + */ + dcpomatic_setup (); + + /* Force the configuration to be re-loaded correctly next + time it is needed. + */ + Config::drop (); + + Frame* f = new Frame (_("DCP-o-matic Batch Converter")); + SetTopWindow (f); + f->Maximize (); + f->Show (); + + ui_signaller = new wxUISignaller (this); + this->Connect (-1, wxEVT_IDLE, wxIdleEventHandler (App::idle)); + + return true; + } + + void idle (wxIdleEvent &) + { + ui_signaller->ui_idle (); + } +}; + +IMPLEMENT_APP (App) -- cgit v1.2.3 From 540aac0bc5ca6cbf393c650e97236a9677124a30 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 10 May 2013 21:28:26 +0100 Subject: Remove gain/delay_line/matcher/trimmer. --- src/lib/ab_transcoder.cc | 35 +------- src/lib/ab_transcoder.h | 8 -- src/lib/delay_line.cc | 57 ------------- src/lib/delay_line.h | 34 -------- src/lib/gain.cc | 45 ---------- src/lib/gain.h | 31 ------- src/lib/matcher.cc | 213 ----------------------------------------------- src/lib/matcher.h | 63 -------------- src/lib/transcoder.cc | 34 +------- src/lib/transcoder.h | 8 -- src/lib/trimmer.cc | 115 ------------------------- src/lib/trimmer.h | 40 --------- src/lib/wscript | 4 - test/test.cc | 75 ----------------- 14 files changed, 4 insertions(+), 758 deletions(-) delete mode 100644 src/lib/delay_line.cc delete mode 100644 src/lib/delay_line.h delete mode 100644 src/lib/gain.cc delete mode 100644 src/lib/gain.h delete mode 100644 src/lib/matcher.cc delete mode 100644 src/lib/matcher.h delete mode 100644 src/lib/trimmer.cc delete mode 100644 src/lib/trimmer.h (limited to 'src') diff --git a/src/lib/ab_transcoder.cc b/src/lib/ab_transcoder.cc index f75491dce..91c4665a7 100644 --- a/src/lib/ab_transcoder.cc +++ b/src/lib/ab_transcoder.cc @@ -25,11 +25,7 @@ #include "job.h" #include "image.h" #include "player.h" -#include "matcher.h" -#include "delay_line.h" -#include "gain.h" #include "combiner.h" -#include "trimmer.h" /** @file src/ab_transcoder.cc * @brief A transcoder which uses one Film for the left half of the screen, and a different one @@ -54,44 +50,17 @@ ABTranscoder::ABTranscoder (shared_ptr film_a, shared_ptr film_b, sh , _encoder (new Encoder (film_a, j)) , _combiner (new Combiner (film_a->log())) { - _matcher.reset (new Matcher (film_a->log(), film_a->audio_frame_rate(), film_a->video_frame_rate())); - _delay_line.reset (new DelayLine (film_a->log(), film_a->audio_delay() * film_a->audio_frame_rate() / 1000)); - _gain.reset (new Gain (film_a->log(), film_a->audio_gain())); - _player_a->Video.connect (bind (&Combiner::process_video, _combiner, _1, _2, _3, _4)); _player_b->Video.connect (bind (&Combiner::process_video_b, _combiner, _1, _2, _3, _4)); - int const trim_start = film_a->trim_type() == Film::ENCODE ? film_a->trim_start() : 0; - int const trim_end = film_a->trim_type() == Film::ENCODE ? film_a->trim_end() : 0; - _trimmer.reset (new Trimmer ( - film_a->log(), trim_start, trim_end, film_a->content_length(), - film_a->audio_frame_rate(), film_a->video_frame_rate(), film_a->dcp_frame_rate() - )); - - - _combiner->connect_video (_delay_line); - _delay_line->connect_video (_matcher); - _matcher->connect_video (_trimmer); - _trimmer->connect_video (_encoder); - - _player_a->connect_audio (_delay_line); - _delay_line->connect_audio (_matcher); - _matcher->connect_audio (_gain); - _gain->connect_audio (_trimmer); - _trimmer->connect_audio (_encoder); + _combiner->connect_video (_encoder); + _player_a->connect_audio (_encoder); } void ABTranscoder::go () { _encoder->process_begin (); - while (!_player_a->pass () || !_player_b->pass ()) {} - - _delay_line->process_end (); - _matcher->process_end (); - _gain->process_end (); - _trimmer->process_end (); _encoder->process_end (); } - diff --git a/src/lib/ab_transcoder.h b/src/lib/ab_transcoder.h index 134bce3e4..54d7ed0be 100644 --- a/src/lib/ab_transcoder.h +++ b/src/lib/ab_transcoder.h @@ -31,12 +31,8 @@ class Encoder; class Image; class Log; class Film; -class Matcher; -class DelayLine; -class Gain; class Combiner; class Player; -class Trimmer; /** @class ABTranscoder * @brief A transcoder which uses one Film for the left half of the screen, and a different one @@ -59,9 +55,5 @@ private: boost::shared_ptr _job; boost::shared_ptr _encoder; boost::shared_ptr _combiner; - boost::shared_ptr _matcher; - boost::shared_ptr _delay_line; - boost::shared_ptr _gain; - boost::shared_ptr _trimmer; boost::shared_ptr _image; }; diff --git a/src/lib/delay_line.cc b/src/lib/delay_line.cc deleted file mode 100644 index b0180800a..000000000 --- a/src/lib/delay_line.cc +++ /dev/null @@ -1,57 +0,0 @@ -/* - Copyright (C) 2012 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include -#include -#include -#include -#include "delay_line.h" -#include "util.h" - -using std::min; -using boost::shared_ptr; - -/* @param seconds Delay in seconds, +ve to move audio later. - */ -DelayLine::DelayLine (shared_ptr log, double seconds) - : TimedAudioVideoProcessor (log) - , _seconds (seconds) -{ - -} - -void -DelayLine::process_audio (shared_ptr data, double t) -{ - if (_seconds > 0) { - t += _seconds; - } - - Audio (data, t); -} - -void -DelayLine::process_video (shared_ptr image, bool same, boost::shared_ptr sub, double t) -{ - if (_seconds < 0) { - t += _seconds; - } - - Video (image, same, sub, t); -} diff --git a/src/lib/delay_line.h b/src/lib/delay_line.h deleted file mode 100644 index 781dce88a..000000000 --- a/src/lib/delay_line.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - Copyright (C) 2012 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include -#include "processor.h" - -/** A delay line */ -class DelayLine : public TimedAudioVideoProcessor -{ -public: - DelayLine (boost::shared_ptr log, double); - - void process_video (boost::shared_ptr, bool, boost::shared_ptr, double); - void process_audio (boost::shared_ptr, double); - -private: - double _seconds; -}; diff --git a/src/lib/gain.cc b/src/lib/gain.cc deleted file mode 100644 index ccd779d71..000000000 --- a/src/lib/gain.cc +++ /dev/null @@ -1,45 +0,0 @@ -/* - Copyright (C) 2012 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include "gain.h" - -using boost::shared_ptr; - -/** @param gain gain in dB */ -Gain::Gain (shared_ptr log, float gain) - : AudioProcessor (log) - , _gain (gain) -{ - -} - -void -Gain::process_audio (shared_ptr b) -{ - if (_gain != 0) { - float const linear_gain = pow (10, _gain / 20); - for (int i = 0; i < b->channels(); ++i) { - for (int j = 0; j < b->frames(); ++j) { - b->data(i)[j] *= linear_gain; - } - } - } - - Audio (b); -} diff --git a/src/lib/gain.h b/src/lib/gain.h deleted file mode 100644 index 61fef5e85..000000000 --- a/src/lib/gain.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright (C) 2012 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include "processor.h" - -class Gain : public AudioProcessor -{ -public: - Gain (boost::shared_ptr log, float gain); - - void process_audio (boost::shared_ptr); - -private: - float _gain; -}; diff --git a/src/lib/matcher.cc b/src/lib/matcher.cc deleted file mode 100644 index c56a56301..000000000 --- a/src/lib/matcher.cc +++ /dev/null @@ -1,213 +0,0 @@ -/* - Copyright (C) 2012 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include "matcher.h" -#include "image.h" -#include "log.h" - -#include "i18n.h" - -using std::min; -using std::cout; -using std::list; -using boost::shared_ptr; - -Matcher::Matcher (shared_ptr log, int sample_rate, float frames_per_second) - : Processor (log) - , _sample_rate (sample_rate) - , _frames_per_second (frames_per_second) - , _video_frames (0) - , _audio_frames (0) - , _had_first_video (false) - , _had_first_audio (false) -{ - -} - -void -Matcher::process_video (shared_ptr image, bool same, boost::shared_ptr sub, double t) -{ - _pixel_format = image->pixel_format (); - _size = image->size (); - - _log->log(String::compose("Matcher video @ %1 [audio=%2, video=%3, pending_audio=%4]", t, _audio_frames, _video_frames, _pending_audio.size())); - - if (!_first_input) { - _first_input = t; - } - - bool const this_is_first_video = !_had_first_video; - _had_first_video = true; - - if (this_is_first_video && _had_first_audio) { - /* First video since we got audio */ - fix_start (t); - } - - /* Video before audio is fine, since we can make up an arbitrary difference - with audio samples (contrasting with video which is quantised to frames) - */ - - /* Difference between where this video is and where it should be */ - double const delta = t - _first_input.get() - _video_frames / _frames_per_second; - double const one_frame = 1 / _frames_per_second; - - if (delta > one_frame) { - /* Insert frames to make up the difference */ - int const extra = rint (delta / one_frame); - for (int i = 0; i < extra; ++i) { - repeat_last_video (); - _log->log (String::compose ("Extra video frame inserted at %1s", _video_frames / _frames_per_second)); - } - } - - if (delta > -one_frame) { - Video (image, same, sub); - ++_video_frames; - } else { - /* We are omitting a frame to keep things right */ - _log->log (String::compose ("Frame removed at %1s", t)); - } - - _last_image = image; - _last_subtitle = sub; -} - -void -Matcher::process_audio (shared_ptr b, double t) -{ - _channels = b->channels (); - - _log->log (String::compose ( - "Matcher audio (%1 frames) @ %2 [video=%3, audio=%4, pending_audio=%5]", - b->frames(), t, _video_frames, _audio_frames, _pending_audio.size() - ) - ); - - if (!_first_input) { - _first_input = t; - } - - bool const this_is_first_audio = _had_first_audio; - _had_first_audio = true; - - if (!_had_first_video) { - /* No video yet; we must postpone these data until we have some */ - _pending_audio.push_back (AudioRecord (b, t)); - } else if (this_is_first_audio && !_had_first_video) { - /* First audio since we got video */ - _pending_audio.push_back (AudioRecord (b, t)); - fix_start (_first_input.get ()); - } else { - /* Normal running. We assume audio time stamps are consecutive */ - Audio (b); - _audio_frames += b->frames (); - } -} - -void -Matcher::process_end () -{ - if (_audio_frames == 0 || !_pixel_format || !_size || !_channels) { - /* We won't do anything */ - return; - } - - _log->log (String::compose ("Matcher has seen %1 video frames (which equals %2 audio frames) and %3 audio frames", - _video_frames, video_frames_to_audio_frames (_video_frames, _sample_rate, _frames_per_second), _audio_frames)); - - match ((double (_audio_frames) / _sample_rate) - (double (_video_frames) / _frames_per_second)); -} - -void -Matcher::fix_start (double first_video) -{ - assert (!_pending_audio.empty ()); - - _log->log (String::compose ("Fixing start; video at %1, audio at %2", first_video, _pending_audio.front().time)); - - match (first_video - _pending_audio.front().time); - - for (list::iterator i = _pending_audio.begin(); i != _pending_audio.end(); ++i) { - process_audio (i->audio, i->time); - } - - _pending_audio.clear (); -} - -void -Matcher::match (double extra_video_needed) -{ - _log->log (String::compose ("Match %1", extra_video_needed)); - - if (extra_video_needed > 0) { - - /* Emit black video frames */ - - int const black_video_frames = ceil (extra_video_needed * _frames_per_second); - - _log->log (String::compose (N_("Emitting %1 frames of black video"), black_video_frames)); - - shared_ptr black (new SimpleImage (_pixel_format.get(), _size.get(), true)); - black->make_black (); - for (int i = 0; i < black_video_frames; ++i) { - Video (black, i != 0, shared_ptr()); - ++_video_frames; - } - - extra_video_needed -= black_video_frames / _frames_per_second; - } - - if (extra_video_needed < 0) { - - /* Emit silence */ - - int64_t to_do = -extra_video_needed * _sample_rate; - _log->log (String::compose (N_("Emitting %1 frames of silence"), to_do)); - - /* Do things in half second blocks as I think there may be limits - to what FFmpeg (and in particular the resampler) can cope with. - */ - int64_t const block = _sample_rate / 2; - shared_ptr b (new AudioBuffers (_channels.get(), block)); - b->make_silent (); - - while (to_do > 0) { - int64_t const this_time = min (to_do, block); - b->set_frames (this_time); - Audio (b); - _audio_frames += b->frames (); - to_do -= this_time; - } - } -} - -void -Matcher::repeat_last_video () -{ - if (!_last_image) { - shared_ptr im (new SimpleImage (_pixel_format.get(), _size.get(), true)); - im->make_black (); - _last_image = im; - } - - Video (_last_image, true, _last_subtitle); - ++_video_frames; -} - diff --git a/src/lib/matcher.h b/src/lib/matcher.h deleted file mode 100644 index 41aa373a4..000000000 --- a/src/lib/matcher.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - Copyright (C) 2012 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include -#include "processor.h" -#include "ffmpeg_compatibility.h" - -class Matcher : public Processor, public TimedAudioSink, public TimedVideoSink, public AudioSource, public VideoSource -{ -public: - Matcher (boost::shared_ptr log, int sample_rate, float frames_per_second); - void process_video (boost::shared_ptr i, bool, boost::shared_ptr s, double); - void process_audio (boost::shared_ptr, double); - void process_end (); - -private: - void fix_start (double); - void match (double); - void repeat_last_video (); - - int _sample_rate; - float _frames_per_second; - int _video_frames; - int64_t _audio_frames; - boost::optional _pixel_format; - boost::optional _size; - boost::optional _channels; - - struct AudioRecord { - AudioRecord (boost::shared_ptr a, double t) - : audio (a) - , time (t) - {} - - boost::shared_ptr audio; - double time; - }; - - std::list _pending_audio; - - boost::optional _first_input; - boost::shared_ptr _last_image; - boost::shared_ptr _last_subtitle; - - bool _had_first_video; - bool _had_first_audio; -}; diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc index f8fe0c8d5..d4c5210dc 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -29,13 +29,9 @@ #include "transcoder.h" #include "encoder.h" #include "film.h" -#include "matcher.h" -#include "delay_line.h" -#include "gain.h" #include "video_decoder.h" #include "audio_decoder.h" #include "player.h" -#include "trimmer.h" #include "job.h" using std::string; @@ -52,45 +48,19 @@ Transcoder::Transcoder (shared_ptr f, shared_ptr j) , _player (f->player ()) , _encoder (new Encoder (f, j)) { - _matcher.reset (new Matcher (f->log(), f->audio_frame_rate(), f->video_frame_rate())); - _delay_line.reset (new DelayLine (f->log(), f->audio_delay() * f->audio_frame_rate() / 1000)); - _gain.reset (new Gain (f->log(), f->audio_gain())); - - int const trim_start = f->trim_type() == Film::ENCODE ? f->trim_start() : 0; - int const trim_end = f->trim_type() == Film::ENCODE ? f->trim_end() : 0; - _trimmer.reset (new Trimmer ( - f->log(), trim_start, trim_end, f->content_length(), - f->audio_frame_rate(), f->video_frame_rate(), f->dcp_frame_rate() - )); - if (!f->with_subtitles ()) { _player->disable_subtitles (); } - _player->connect_video (_delay_line); - _delay_line->connect_video (_matcher); - _matcher->connect_video (_trimmer); - _trimmer->connect_video (_encoder); - - _player->connect_audio (_delay_line); - _delay_line->connect_audio (_matcher); - _matcher->connect_audio (_gain); - _gain->connect_audio (_trimmer); - _trimmer->connect_audio (_encoder); + _player->connect_video (_encoder); + _player->connect_audio (_encoder); } void Transcoder::go () { _encoder->process_begin (); - while (!_player->pass ()) {} - - _delay_line->process_end (); - if (_matcher) { - _matcher->process_end (); - } - _gain->process_end (); _encoder->process_end (); } diff --git a/src/lib/transcoder.h b/src/lib/transcoder.h index 48b453fe4..f7da3bd01 100644 --- a/src/lib/transcoder.h +++ b/src/lib/transcoder.h @@ -28,12 +28,8 @@ class Film; class Job; class Encoder; -class Matcher; class VideoFilter; -class Gain; -class DelayLine; class Player; -class Trimmer; /** @class Transcoder * @@ -58,8 +54,4 @@ private: boost::shared_ptr _job; boost::shared_ptr _player; boost::shared_ptr _encoder; - boost::shared_ptr _matcher; - boost::shared_ptr _delay_line; - boost::shared_ptr _gain; - boost::shared_ptr _trimmer; }; diff --git a/src/lib/trimmer.cc b/src/lib/trimmer.cc deleted file mode 100644 index b7afc9299..000000000 --- a/src/lib/trimmer.cc +++ /dev/null @@ -1,115 +0,0 @@ -/* - Copyright (C) 2013 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include -#include "trimmer.h" - -using std::cout; -using std::max; -using boost::shared_ptr; - -/** @param audio_sample_rate Audio sampling rate, or 0 if there is no audio */ -Trimmer::Trimmer ( - shared_ptr log, - int video_trim_start, - int video_trim_end, - int video_length, - int audio_sample_rate, - float frames_per_second, - int dcp_frames_per_second - ) - : AudioVideoProcessor (log) - , _video_start (video_trim_start) - , _video_end (video_length - video_trim_end) - , _video_in (0) - , _audio_in (0) -{ - FrameRateConversion frc (frames_per_second, dcp_frames_per_second); - - if (frc.skip) { - _video_start /= 2; - _video_end /= 2; - } else if (frc.repeat) { - _video_start *= 2; - _video_end *= 2; - } - - if (audio_sample_rate) { - _audio_start = video_frames_to_audio_frames (_video_start, audio_sample_rate, frames_per_second); - _audio_end = video_frames_to_audio_frames (_video_end, audio_sample_rate, frames_per_second); - } - - /* XXX: this is a hack; this flag means that no trim is happening at the end of the film, and I'm - using that to prevent audio trim being rounded to video trim, which breaks the current set - of regression tests. This could be removed if a) the regression tests are regenerated and b) - I can work out what DCP length should be. - */ - _no_trim = (_video_start == 0) && (_video_end == (video_length - video_trim_end)); -} - -void -Trimmer::process_video (shared_ptr image, bool same, shared_ptr sub) -{ - if (_no_trim || (_video_in >= _video_start && _video_in <= _video_end)) { - Video (image, same, sub); - } - - ++_video_in; -} - -void -Trimmer::process_audio (shared_ptr audio) -{ - if (_no_trim) { - Audio (audio); - return; - } - - int64_t offset = _audio_start - _audio_in; - if (offset > audio->frames()) { - _audio_in += audio->frames (); - return; - } - - if (offset < 0) { - offset = 0; - } - - int64_t length = _audio_end - max (_audio_in, _audio_start); - if (length < 0) { - _audio_in += audio->frames (); - return; - } - - if (length > (audio->frames() - offset)) { - length = audio->frames () - offset; - } - - _audio_in += audio->frames (); - - if (offset != 0 || length != audio->frames ()) { - shared_ptr copy (new AudioBuffers (audio)); - copy->move (offset, 0, length); - copy->set_frames (length); - audio = copy; - } - - Audio (audio); -} - diff --git a/src/lib/trimmer.h b/src/lib/trimmer.h deleted file mode 100644 index 98a118fb2..000000000 --- a/src/lib/trimmer.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - Copyright (C) 2013 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include "processor.h" - -class Trimmer : public AudioVideoProcessor -{ -public: - Trimmer (boost::shared_ptr, int, int, int, int, float, int); - - void process_video (boost::shared_ptr i, bool, boost::shared_ptr s); - void process_audio (boost::shared_ptr); - -private: - friend class trimmer_test; - - int _video_start; - int _video_end; - int _video_in; - int64_t _audio_start; - int64_t _audio_end; - int64_t _audio_in; - bool _no_trim; -}; diff --git a/src/lib/wscript b/src/lib/wscript index e53ac5a84..bce6c644c 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -18,7 +18,6 @@ sources = """ dcp_content_type.cc dcp_video_frame.cc decoder.cc - delay_line.cc dolby_cp750.cc encoder.cc examine_content_job.cc @@ -30,7 +29,6 @@ sources = """ film.cc filter.cc format.cc - gain.cc image.cc imagemagick_content.cc imagemagick_decoder.cc @@ -38,7 +36,6 @@ sources = """ job_manager.cc log.cc lut.cc - matcher.cc player.cc playlist.cc scp_dcp_job.cc @@ -52,7 +49,6 @@ sources = """ transcode_job.cc transcoder.cc types.cc - trimmer.cc ui_signaller.cc util.cc video_content.cc diff --git a/test/test.cc b/test/test.cc index 1cf651405..2c957fd35 100644 --- a/test/test.cc +++ b/test/test.cc @@ -40,7 +40,6 @@ #include "ffmpeg_decoder.h" #include "sndfile_decoder.h" #include "dcp_content_type.h" -#include "trimmer.h" #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MODULE dcpomatic_test #include @@ -124,80 +123,6 @@ BOOST_AUTO_TEST_CASE (make_black_test) } } -shared_ptr trimmer_test_last_video; -shared_ptr trimmer_test_last_audio; - -void -trimmer_test_video_helper (shared_ptr image, bool, shared_ptr) -{ - trimmer_test_last_video = image; -} - -void -trimmer_test_audio_helper (shared_ptr audio) -{ - trimmer_test_last_audio = audio; -} - -BOOST_AUTO_TEST_CASE (trimmer_passthrough_test) -{ - Trimmer trimmer (shared_ptr (), 0, 0, 200, 48000, 25, 25); - trimmer.Video.connect (bind (&trimmer_test_video_helper, _1, _2, _3)); - trimmer.Audio.connect (bind (&trimmer_test_audio_helper, _1)); - - shared_ptr video (new SimpleImage (PIX_FMT_RGB24, libdcp::Size (1998, 1080), true)); - shared_ptr audio (new AudioBuffers (6, 42 * 1920)); - - trimmer.process_video (video, false, shared_ptr ()); - trimmer.process_audio (audio); - - BOOST_CHECK_EQUAL (video.get(), trimmer_test_last_video.get()); - BOOST_CHECK_EQUAL (audio.get(), trimmer_test_last_audio.get()); - BOOST_CHECK_EQUAL (audio->frames(), trimmer_test_last_audio->frames()); -} - - -/** Test the audio handling of the Trimmer */ -BOOST_AUTO_TEST_CASE (trimmer_audio_test) -{ - Trimmer trimmer (shared_ptr (), 25, 75, 200, 48000, 25, 25); - - trimmer.Audio.connect (bind (&trimmer_test_audio_helper, _1)); - - /* 21 video frames-worth of audio frames; should be completely stripped */ - trimmer_test_last_audio.reset (); - shared_ptr audio (new AudioBuffers (6, 21 * 1920)); - trimmer.process_audio (audio); - BOOST_CHECK (trimmer_test_last_audio == 0); - - /* 42 more video frames-worth, 4 should be stripped from the start */ - audio.reset (new AudioBuffers (6, 42 * 1920)); - trimmer.process_audio (audio); - BOOST_CHECK (trimmer_test_last_audio); - BOOST_CHECK_EQUAL (trimmer_test_last_audio->frames(), 38 * 1920); - - /* 42 more video frames-worth, should be kept as-is */ - trimmer_test_last_audio.reset (); - audio.reset (new AudioBuffers (6, 42 * 1920)); - trimmer.process_audio (audio); - BOOST_CHECK (trimmer_test_last_audio); - BOOST_CHECK_EQUAL (trimmer_test_last_audio->frames(), 42 * 1920); - - /* 25 more video frames-worth, 5 should be trimmed from the end */ - trimmer_test_last_audio.reset (); - audio.reset (new AudioBuffers (6, 25 * 1920)); - trimmer.process_audio (audio); - BOOST_CHECK (trimmer_test_last_audio); - BOOST_CHECK_EQUAL (trimmer_test_last_audio->frames(), 20 * 1920); - - /* Now some more; all should be trimmed */ - trimmer_test_last_audio.reset (); - audio.reset (new AudioBuffers (6, 100 * 1920)); - trimmer.process_audio (audio); - BOOST_CHECK (trimmer_test_last_audio == 0); -} - - BOOST_AUTO_TEST_CASE (film_metadata_test) { setup_test_config (); -- cgit v1.2.3 From 145d1cf483f9ec554b3114db73d5be4def36027b Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 10 May 2013 21:35:57 +0100 Subject: Tidy filter_and_emit_video / decode_video_packet. --- src/lib/ffmpeg_decoder.cc | 89 +++++++++++++++++++++-------------------------- src/lib/ffmpeg_decoder.h | 3 +- 2 files changed, 41 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index d5285b73a..ef7c4487d 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -236,12 +236,8 @@ FFmpegDecoder::pass () /* XXX: should we reset _packet.data and size after each *_decode_* call? */ - int frame_finished; - if (_decode_video) { - while (avcodec_decode_video2 (_video_codec_context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) { - filter_and_emit_video (); - } + decode_video_packet (); } if (_ffmpeg_content->audio_stream() && _decode_audio) { @@ -254,18 +250,7 @@ FFmpegDecoder::pass () avcodec_get_frame_defaults (_frame); if (_packet.stream_index == _video_stream && _decode_video) { - - int frame_finished; - int const r = avcodec_decode_video2 (_video_codec_context, _frame, &frame_finished, &_packet); - if (r >= 0 && frame_finished) { - - if (r != _packet.size) { - _film->log()->log (String::compose (N_("Used only %1 bytes of %2 in packet"), r, _packet.size)); - } - - filter_and_emit_video (); - } - + decode_video_packet (); } else if (_ffmpeg_content->audio_stream() && _packet.stream_index == _ffmpeg_content->audio_stream()->id && _decode_audio) { decode_audio_packet (); } else if (_ffmpeg_content->subtitle_stream() && _packet.stream_index == _ffmpeg_content->subtitle_stream()->id && _decode_subtitles) { @@ -481,38 +466,6 @@ FFmpegDecoder::bytes_per_audio_sample () const return av_get_bytes_per_sample (audio_sample_format ()); } -void -FFmpegDecoder::filter_and_emit_video () -{ - boost::mutex::scoped_lock lm (_filter_graphs_mutex); - - shared_ptr graph; - - list >::iterator i = _filter_graphs.begin(); - while (i != _filter_graphs.end() && !(*i)->can_process (libdcp::Size (_frame->width, _frame->height), (AVPixelFormat) _frame->format)) { - ++i; - } - - if (i == _filter_graphs.end ()) { - graph.reset (new FilterGraph (_film, this, libdcp::Size (_frame->width, _frame->height), (AVPixelFormat) _frame->format)); - _filter_graphs.push_back (graph); - _film->log()->log (String::compose (N_("New graph for %1x%2, pixel format %3"), _frame->width, _frame->height, _frame->format)); - } else { - graph = *i; - } - - list > images = graph->process (_frame); - - for (list >::iterator i = images.begin(); i != images.end(); ++i) { - int64_t const bet = av_frame_get_best_effort_timestamp (_frame); - if (bet != AV_NOPTS_VALUE) { - emit_video (*i, false, bet * av_q2d (_format_context->streams[_video_stream]->time_base)); - } else { - _film->log()->log ("Dropping frame without PTS"); - } - } -} - bool FFmpegDecoder::seek (double p) { @@ -635,3 +588,41 @@ FFmpegDecoder::decode_audio_packet () } } } + +void +FFmpegDecoder::decode_video_packet () +{ + int frame_finished; + while (avcodec_decode_video2 (_video_codec_context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) { + boost::mutex::scoped_lock lm (_filter_graphs_mutex); + + shared_ptr graph; + + list >::iterator i = _filter_graphs.begin(); + while (i != _filter_graphs.end() && !(*i)->can_process (libdcp::Size (_frame->width, _frame->height), (AVPixelFormat) _frame->format)) { + ++i; + } + + if (i == _filter_graphs.end ()) { + graph.reset (new FilterGraph (_film, this, libdcp::Size (_frame->width, _frame->height), (AVPixelFormat) _frame->format)); + _filter_graphs.push_back (graph); + _film->log()->log (String::compose (N_("New graph for %1x%2, pixel format %3"), _frame->width, _frame->height, _frame->format)); + } else { + graph = *i; + } + + list > images = graph->process (_frame); + + for (list >::iterator i = images.begin(); i != images.end(); ++i) { + int64_t const bet = av_frame_get_best_effort_timestamp (_frame); + if (bet != AV_NOPTS_VALUE) { + emit_video (*i, false, bet * av_q2d (_format_context->streams[_video_stream]->time_base)); + } else { + _film->log()->log ("Dropping frame without PTS"); + } + } + } +} + + + diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h index 1e273752a..e6fa9cc82 100644 --- a/src/lib/ffmpeg_decoder.h +++ b/src/lib/ffmpeg_decoder.h @@ -92,13 +92,12 @@ private: int bytes_per_audio_sample () const; bool do_seek (double, bool, bool); - void filter_and_emit_video (); - void setup_general (); void setup_video (); void setup_audio (); void setup_subtitle (); + void decode_video_packet (); void decode_audio_packet (); void maybe_add_subtitle (); -- cgit v1.2.3 From e203e064cd2d550771a80d9a710140ed07e3d7a0 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 10 May 2013 21:49:39 +0100 Subject: Add comment. --- src/lib/ffmpeg_decoder.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index ef7c4487d..b857860bd 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -616,6 +616,9 @@ FFmpegDecoder::decode_video_packet () for (list >::iterator i = images.begin(); i != images.end(); ++i) { int64_t const bet = av_frame_get_best_effort_timestamp (_frame); if (bet != AV_NOPTS_VALUE) { + /* XXX: may need to insert extra frames / remove frames here ... + (as per old Matcher) + */ emit_video (*i, false, bet * av_q2d (_format_context->streams[_video_stream]->time_base)); } else { _film->log()->log ("Dropping frame without PTS"); @@ -623,6 +626,3 @@ FFmpegDecoder::decode_video_packet () } } } - - - -- cgit v1.2.3 From 76052960d07a611889967f5927e2adb0d867ea07 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 10 May 2013 21:55:06 +0100 Subject: Make libswresample mandatory. --- src/lib/encoder.cc | 12 ------------ src/lib/encoder.h | 6 ------ src/wx/film_editor.cc | 2 -- wscript | 10 +++------- 4 files changed, 3 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index d25e0d0f8..8e0d1cd91 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -60,9 +60,7 @@ Encoder::Encoder (shared_ptr f, shared_ptr j) , _job (j) , _video_frames_in (0) , _video_frames_out (0) -#ifdef HAVE_SWRESAMPLE , _swr_context (0) -#endif , _have_a_real_frame (false) , _terminate (false) { @@ -81,7 +79,6 @@ void Encoder::process_begin () { if (_film->has_audio() && _film->audio_frame_rate() != _film->target_audio_sample_rate()) { -#ifdef HAVE_SWRESAMPLE stringstream s; s << String::compose (N_("Will resample audio from %1 to %2"), _film->audio_frame_rate(), _film->target_audio_sample_rate()); @@ -107,13 +104,8 @@ Encoder::process_begin () ); swr_init (_swr_context); -#else - throw EncodeError (_("Cannot resample audio as libswresample is not present")); -#endif } else { -#ifdef HAVE_SWRESAMPLE _swr_context = 0; -#endif } for (int i = 0; i < Config::instance()->num_local_encoding_threads (); ++i) { @@ -135,7 +127,6 @@ Encoder::process_begin () void Encoder::process_end () { -#if HAVE_SWRESAMPLE if (_film->has_audio() && _swr_context) { shared_ptr out (new AudioBuffers (_film->audio_mapping().dcp_channels(), 256)); @@ -157,7 +148,6 @@ Encoder::process_end () swr_free (&_swr_context); } -#endif boost::mutex::scoped_lock lock (_mutex); @@ -306,7 +296,6 @@ Encoder::process_video (shared_ptr image, bool same, shared_ptr data) { -#if HAVE_SWRESAMPLE /* Maybe sample-rate convert */ if (_swr_context) { @@ -329,7 +318,6 @@ Encoder::process_audio (shared_ptr data) /* And point our variables at the resampled audio */ data = resampled; } -#endif _writer->write (data); } diff --git a/src/lib/encoder.h b/src/lib/encoder.h index 6cf5540c5..a3a484856 100644 --- a/src/lib/encoder.h +++ b/src/lib/encoder.h @@ -33,12 +33,8 @@ #include extern "C" { #include -} -#ifdef HAVE_SWRESAMPLE -extern "C" { #include } -#endif #include "util.h" #include "video_sink.h" #include "audio_sink.h" @@ -110,9 +106,7 @@ private: /** Number of video frames written for the DCP so far */ int _video_frames_out; -#if HAVE_SWRESAMPLE SwrContext* _swr_context; -#endif bool _have_a_real_frame; bool _terminate; diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index ca43ffb8a..528e3840f 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -810,7 +810,6 @@ FilmEditor::setup_frame_rate_description () if (_film->video_frame_rate()) { d << std_to_wx (FrameRateConversion (_film->video_frame_rate(), _film->dcp_frame_rate()).description); ++lines; -#ifdef HAVE_SWRESAMPLE if (_film->audio_frame_rate() && _film->audio_frame_rate() != _film->target_audio_sample_rate ()) { d << wxString::Format ( _("Audio will be resampled from %dHz to %dHz\n"), @@ -819,7 +818,6 @@ FilmEditor::setup_frame_rate_description () ); ++lines; } -#endif } for (int i = lines; i < 2; ++i) { diff --git a/wscript b/wscript index 169e46257..50d6d9040 100644 --- a/wscript +++ b/wscript @@ -62,7 +62,7 @@ def configure(conf): conf.check_cfg(package = 'libavcodec', args = '--cflags --libs', uselib_store = 'AVCODEC', mandatory = True) conf.check_cfg(package = 'libavutil', args = '--cflags --libs', uselib_store = 'AVUTIL', mandatory = True) conf.check_cfg(package = 'libswscale', args = '--cflags --libs', uselib_store = 'SWSCALE', mandatory = True) - conf.check_cfg(package = 'libswresample', args = '--cflags --libs', uselib_store = 'SWRESAMPLE', mandatory = False) + conf.check_cfg(package = 'libswresample', args = '--cflags --libs', uselib_store = 'SWRESAMPLE', mandatory = True) conf.check_cfg(package = 'libpostproc', args = '--cflags --libs', uselib_store = 'POSTPROC', mandatory = True) else: # This is hackio grotesquio for static builds (ie for .deb packages). We need to link some things @@ -87,14 +87,10 @@ def configure(conf): conf.env.STLIB_AVUTIL = ['avutil'] conf.env.HAVE_SWSCALE = 1 conf.env.STLIB_SWSCALE = ['swscale'] - conf.env.HAVE_SWRESAMPLE = 1 - conf.env.STLIB_SWRESAMPLE = ['swresample'] conf.env.HAVE_POSTPROC = 1 conf.env.STLIB_POSTPROC = ['postproc'] - - # This doesn't seem to be set up, and we need it otherwise resampling support - # won't be included. Hack upon a hack, obviously - conf.env.append_value('CXXFLAGS', ['-DHAVE_SWRESAMPLE=1']) + conf.env.HAVE_SWRESAMPLE = 1 + conv.env.STLIB_SWRESAMPLE = ['swresample'] conf.check_cfg(package = 'sndfile', args = '--cflags --libs', uselib_store = 'SNDFILE', mandatory = True) conf.check_cfg(package = 'glib-2.0', args = '--cflags --libs', uselib_store = 'GLIB', mandatory = True) -- cgit v1.2.3 From d683883c4dc25cb612f6d5feb1e772016182e722 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 10 May 2013 23:06:17 +0100 Subject: Move SRC (badly) to AudioDecoder. --- src/lib/audio_decoder.cc | 104 ++++++++++++++++++++++++++++++++++++++++++++- src/lib/audio_decoder.h | 12 +++++- src/lib/encoder.cc | 76 --------------------------------- src/lib/encoder.h | 2 - src/lib/ffmpeg_decoder.cc | 2 +- src/lib/sndfile_decoder.cc | 2 +- 6 files changed, 116 insertions(+), 82 deletions(-) (limited to 'src') diff --git a/src/lib/audio_decoder.cc b/src/lib/audio_decoder.cc index df13a984a..68554daf9 100644 --- a/src/lib/audio_decoder.cc +++ b/src/lib/audio_decoder.cc @@ -18,12 +18,114 @@ */ #include "audio_decoder.h" +#include "exceptions.h" +#include "log.h" +#include "i18n.h" + +using std::stringstream; using boost::optional; using boost::shared_ptr; -AudioDecoder::AudioDecoder (shared_ptr f) +AudioDecoder::AudioDecoder (shared_ptr f, shared_ptr c) : Decoder (f) + , _audio_content (c) { + if (_audio_content->audio_frame_rate() != _film->target_audio_sample_rate()) { + + stringstream s; + s << String::compose ("Will resample audio from %1 to %2", _audio_content->audio_frame_rate(), _film->target_audio_sample_rate()); + _film->log()->log (s.str ()); + + /* We will be using planar float data when we call the + resampler. As far as I can see, the audio channel + layout is not necessary for our purposes; it seems + only to be used get the number of channels and + decide if rematrixing is needed. It won't be, since + input and output layouts are the same. + */ + _swr_context = swr_alloc_set_opts ( + 0, + av_get_default_channel_layout (MAX_AUDIO_CHANNELS), + AV_SAMPLE_FMT_FLTP, + _film->target_audio_sample_rate(), + av_get_default_channel_layout (MAX_AUDIO_CHANNELS), + AV_SAMPLE_FMT_FLTP, + _audio_content->audio_frame_rate(), + 0, 0 + ); + + swr_init (_swr_context); + } else { + _swr_context = 0; + } +} + +AudioDecoder::~AudioDecoder () +{ + if (_swr_context) { + swr_free (&_swr_context); + } } + + +#if 0 +void +AudioDecoder::process_end () +{ + if (_film->has_audio() && _swr_context) { + + shared_ptr out (new AudioBuffers (_film->audio_mapping().dcp_channels(), 256)); + + while (1) { + int const frames = swr_convert (_swr_context, (uint8_t **) out->data(), 256, 0, 0); + + if (frames < 0) { + throw EncodeError (_("could not run sample-rate converter")); + } + + if (frames == 0) { + break; + } + + out->set_frames (frames); + _writer->write (out); + } + + } +} +#endif + +void +AudioDecoder::emit_audio (shared_ptr data, Time time) +{ + /* XXX: map audio to 5.1 */ + + /* Maybe sample-rate convert */ + if (_swr_context) { + + /* Compute the resampled frames count and add 32 for luck */ + int const max_resampled_frames = ceil ((int64_t) data->frames() * _film->target_audio_sample_rate() / _audio_content->audio_frame_rate()) + 32; + + shared_ptr resampled (new AudioBuffers (MAX_AUDIO_CHANNELS, max_resampled_frames)); + + /* Resample audio */ + int const resampled_frames = swr_convert ( + _swr_context, (uint8_t **) resampled->data(), max_resampled_frames, (uint8_t const **) data->data(), data->frames() + ); + + if (resampled_frames < 0) { + throw EncodeError (_("could not run sample-rate converter")); + } + + resampled->set_frames (resampled_frames); + + /* And point our variables at the resampled audio */ + data = resampled; + } + + Audio (data, time); +} + + diff --git a/src/lib/audio_decoder.h b/src/lib/audio_decoder.h index c393e95f1..8db16e369 100644 --- a/src/lib/audio_decoder.h +++ b/src/lib/audio_decoder.h @@ -26,6 +26,9 @@ #include "audio_source.h" #include "decoder.h" +extern "C" { +#include +} class AudioContent; @@ -35,7 +38,14 @@ class AudioContent; class AudioDecoder : public TimedAudioSource, public virtual Decoder { public: - AudioDecoder (boost::shared_ptr); + AudioDecoder (boost::shared_ptr, boost::shared_ptr); + ~AudioDecoder (); + + void emit_audio (boost::shared_ptr, Time); + +private: + boost::shared_ptr _audio_content; + SwrContext* _swr_context; }; #endif diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 8e0d1cd91..f91a2c4e2 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -60,7 +60,6 @@ Encoder::Encoder (shared_ptr f, shared_ptr j) , _job (j) , _video_frames_in (0) , _video_frames_out (0) - , _swr_context (0) , _have_a_real_frame (false) , _terminate (false) { @@ -78,36 +77,6 @@ Encoder::~Encoder () void Encoder::process_begin () { - if (_film->has_audio() && _film->audio_frame_rate() != _film->target_audio_sample_rate()) { - - stringstream s; - s << String::compose (N_("Will resample audio from %1 to %2"), _film->audio_frame_rate(), _film->target_audio_sample_rate()); - _film->log()->log (s.str ()); - - /* We will be using planar float data when we call the - resampler. As far as I can see, the audio channel - layout is not necessary for our purposes; it seems - only to be used get the number of channels and - decide if rematrixing is needed. It won't be, since - input and output layouts are the same. - */ - - _swr_context = swr_alloc_set_opts ( - 0, - av_get_default_channel_layout (_film->audio_mapping().dcp_channels ()), - AV_SAMPLE_FMT_FLTP, - _film->target_audio_sample_rate(), - av_get_default_channel_layout (_film->audio_mapping().dcp_channels ()), - AV_SAMPLE_FMT_FLTP, - _film->audio_frame_rate(), - 0, 0 - ); - - swr_init (_swr_context); - } else { - _swr_context = 0; - } - for (int i = 0; i < Config::instance()->num_local_encoding_threads (); ++i) { _threads.push_back (new boost::thread (boost::bind (&Encoder::encoder_thread, this, (ServerDescription *) 0))); } @@ -127,28 +96,6 @@ Encoder::process_begin () void Encoder::process_end () { - if (_film->has_audio() && _swr_context) { - - shared_ptr out (new AudioBuffers (_film->audio_mapping().dcp_channels(), 256)); - - while (1) { - int const frames = swr_convert (_swr_context, (uint8_t **) out->data(), 256, 0, 0); - - if (frames < 0) { - throw EncodeError (_("could not run sample-rate converter")); - } - - if (frames == 0) { - break; - } - - out->set_frames (frames); - _writer->write (out); - } - - swr_free (&_swr_context); - } - boost::mutex::scoped_lock lock (_mutex); _film->log()->log (String::compose (N_("Clearing queue of %1"), _queue.size ())); @@ -296,29 +243,6 @@ Encoder::process_video (shared_ptr image, bool same, shared_ptr data) { - /* Maybe sample-rate convert */ - if (_swr_context) { - - /* Compute the resampled frames count and add 32 for luck */ - int const max_resampled_frames = ceil ((int64_t) data->frames() * _film->target_audio_sample_rate() / _film->audio_frame_rate()) + 32; - - shared_ptr resampled (new AudioBuffers (_film->audio_mapping().dcp_channels(), max_resampled_frames)); - - /* Resample audio */ - int const resampled_frames = swr_convert ( - _swr_context, (uint8_t **) resampled->data(), max_resampled_frames, (uint8_t const **) data->data(), data->frames() - ); - - if (resampled_frames < 0) { - throw EncodeError (_("could not run sample-rate converter")); - } - - resampled->set_frames (resampled_frames); - - /* And point our variables at the resampled audio */ - data = resampled; - } - _writer->write (data); } diff --git a/src/lib/encoder.h b/src/lib/encoder.h index a3a484856..cce26efc8 100644 --- a/src/lib/encoder.h +++ b/src/lib/encoder.h @@ -106,8 +106,6 @@ private: /** Number of video frames written for the DCP so far */ int _video_frames_out; - SwrContext* _swr_context; - bool _have_a_real_frame; bool _terminate; std::list > _queue; diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index b857860bd..0e704bb14 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -66,7 +66,7 @@ boost::mutex FFmpegDecoder::_mutex; FFmpegDecoder::FFmpegDecoder (shared_ptr f, shared_ptr c, bool video, bool audio, bool subtitles) : Decoder (f) , VideoDecoder (f) - , AudioDecoder (f) + , AudioDecoder (f, c) , _ffmpeg_content (c) , _format_context (0) , _video_stream (-1) diff --git a/src/lib/sndfile_decoder.cc b/src/lib/sndfile_decoder.cc index dd9e654c7..dc22475cd 100644 --- a/src/lib/sndfile_decoder.cc +++ b/src/lib/sndfile_decoder.cc @@ -34,7 +34,7 @@ using boost::shared_ptr; SndfileDecoder::SndfileDecoder (shared_ptr f, shared_ptr c) : Decoder (f) - , AudioDecoder (f) + , AudioDecoder (f, c) , _sndfile_content (c) , _deinterleave_buffer (0) { -- cgit v1.2.3 From 0db016f90ae722fc8b72d465e21d9f153f72b340 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 10 May 2013 23:31:25 +0100 Subject: Remove Timed*Sink and Timed*Source> --- src/lib/audio_decoder.h | 2 +- src/lib/audio_sink.h | 9 +-------- src/lib/audio_source.cc | 26 +++----------------------- src/lib/audio_source.h | 16 ++-------------- src/lib/combiner.cc | 2 +- src/lib/combiner.h | 6 +++--- src/lib/encoder.cc | 4 ++-- src/lib/encoder.h | 4 ++-- src/lib/player.h | 2 +- src/lib/processor.h | 17 ----------------- src/lib/video_decoder.h | 2 +- src/lib/video_sink.h | 14 +------------- src/lib/video_source.cc | 26 +++----------------------- src/lib/video_source.h | 22 +--------------------- 14 files changed, 22 insertions(+), 130 deletions(-) (limited to 'src') diff --git a/src/lib/audio_decoder.h b/src/lib/audio_decoder.h index 8db16e369..1c7287a55 100644 --- a/src/lib/audio_decoder.h +++ b/src/lib/audio_decoder.h @@ -35,7 +35,7 @@ class AudioContent; /** @class AudioDecoder. * @brief Parent class for audio decoders. */ -class AudioDecoder : public TimedAudioSource, public virtual Decoder +class AudioDecoder : public AudioSource, public virtual Decoder { public: AudioDecoder (boost::shared_ptr, boost::shared_ptr); diff --git a/src/lib/audio_sink.h b/src/lib/audio_sink.h index ee39f9ee7..2e3ead005 100644 --- a/src/lib/audio_sink.h +++ b/src/lib/audio_sink.h @@ -24,14 +24,7 @@ class AudioSink { public: /** Call with some audio data */ - virtual void process_audio (boost::shared_ptr) = 0; -}; - -class TimedAudioSink -{ -public: - /** Call with some audio data */ - virtual void process_audio (boost::shared_ptr, double t) = 0; + virtual void process_audio (boost::shared_ptr, Time) = 0; }; #endif diff --git a/src/lib/audio_source.cc b/src/lib/audio_source.cc index 2867bcc24..e61721646 100644 --- a/src/lib/audio_source.cc +++ b/src/lib/audio_source.cc @@ -25,38 +25,18 @@ using boost::weak_ptr; using boost::bind; static void -process_audio_proxy (weak_ptr sink, shared_ptr audio) +process_audio_proxy (weak_ptr sink, shared_ptr audio, Time time) { shared_ptr p = sink.lock (); if (p) { - p->process_audio (audio); + p->process_audio (audio, time); } } void AudioSource::connect_audio (shared_ptr s) { - Audio.connect (bind (process_audio_proxy, weak_ptr (s), _1)); + Audio.connect (bind (process_audio_proxy, weak_ptr (s), _1, _2)); } -void -TimedAudioSource::connect_audio (shared_ptr s) -{ - Audio.connect (bind (process_audio_proxy, weak_ptr (s), _1)); -} - -static void -timed_process_audio_proxy (weak_ptr sink, shared_ptr audio, double t) -{ - shared_ptr p = sink.lock (); - if (p) { - p->process_audio (audio, t); - } -} - -void -TimedAudioSource::connect_audio (shared_ptr s) -{ - Audio.connect (bind (timed_process_audio_proxy, weak_ptr (s), _1, _2)); -} diff --git a/src/lib/audio_source.h b/src/lib/audio_source.h index c7f0a09ed..ef47e969b 100644 --- a/src/lib/audio_source.h +++ b/src/lib/audio_source.h @@ -25,31 +25,19 @@ #define DCPOMATIC_AUDIO_SOURCE_H #include +#include "types.h" class AudioBuffers; class AudioSink; -class TimedAudioSink; /** A class that emits audio data */ class AudioSource { public: /** Emitted when some audio data is ready */ - boost::signals2::signal)> Audio; + boost::signals2::signal, Time)> Audio; void connect_audio (boost::shared_ptr); }; - -/** A class that emits audio data with timestamps */ -class TimedAudioSource -{ -public: - /** Emitted when some audio data is ready */ - boost::signals2::signal, double)> Audio; - - void connect_audio (boost::shared_ptr); - void connect_audio (boost::shared_ptr); -}; - #endif diff --git a/src/lib/combiner.cc b/src/lib/combiner.cc index 367cefa7f..9f9461ec2 100644 --- a/src/lib/combiner.cc +++ b/src/lib/combiner.cc @@ -23,7 +23,7 @@ using boost::shared_ptr; Combiner::Combiner (shared_ptr log) - : TimedVideoProcessor (log) + : VideoProcessor (log) { } diff --git a/src/lib/combiner.h b/src/lib/combiner.h index 7ed316e26..062297f0d 100644 --- a/src/lib/combiner.h +++ b/src/lib/combiner.h @@ -28,13 +28,13 @@ * one image used for the left half of the screen and the other for * the right. */ -class Combiner : public TimedVideoProcessor +class Combiner : public VideoProcessor { public: Combiner (boost::shared_ptr log); - void process_video (boost::shared_ptr i, bool, boost::shared_ptr s, double); - void process_video_b (boost::shared_ptr i, bool, boost::shared_ptr s, double); + void process_video (boost::shared_ptr i, bool, boost::shared_ptr s, Time); + void process_video_b (boost::shared_ptr i, bool, boost::shared_ptr s, Time); private: /** The image that we are currently working on */ diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index f91a2c4e2..6cb384e20 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -178,7 +178,7 @@ Encoder::frame_done () } void -Encoder::process_video (shared_ptr image, bool same, shared_ptr sub) +Encoder::process_video (shared_ptr image, bool same, shared_ptr sub, Time) { FrameRateConversion frc (_film->video_frame_rate(), _film->dcp_frame_rate()); @@ -241,7 +241,7 @@ Encoder::process_video (shared_ptr image, bool same, shared_ptr data) +Encoder::process_audio (shared_ptr data, Time) { _writer->write (data); } diff --git a/src/lib/encoder.h b/src/lib/encoder.h index cce26efc8..b6d3663fd 100644 --- a/src/lib/encoder.h +++ b/src/lib/encoder.h @@ -70,10 +70,10 @@ public: * @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 i, bool same, boost::shared_ptr s); + void process_video (boost::shared_ptr i, bool same, boost::shared_ptr s, Time); /** Call with some audio data */ - void process_audio (boost::shared_ptr); + void process_audio (boost::shared_ptr, Time); /** Called when a processing run has finished */ void process_end (); diff --git a/src/lib/player.h b/src/lib/player.h index b6fb41f6e..b1be2f456 100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@ -39,7 +39,7 @@ class AudioContent; * @brief A class which can `play' a Playlist; emitting its audio and video. */ -class Player : public TimedVideoSource, public TimedAudioSource, public TimedVideoSink, public boost::enable_shared_from_this +class Player : public VideoSource, public AudioSource, public VideoSink, public boost::enable_shared_from_this { public: Player (boost::shared_ptr, boost::shared_ptr); diff --git a/src/lib/processor.h b/src/lib/processor.h index 7b7735faa..5dbafab7f 100644 --- a/src/lib/processor.h +++ b/src/lib/processor.h @@ -67,15 +67,6 @@ public: {} }; -class TimedAudioVideoProcessor : public Processor, public TimedVideoSource, public TimedVideoSink, public TimedAudioSource, public TimedAudioSink -{ -public: - TimedAudioVideoProcessor (boost::shared_ptr log) - : Processor (log) - {} -}; - - /** @class AudioProcessor * @brief A processor which handles just audio data. */ @@ -104,12 +95,4 @@ public: {} }; -class TimedVideoProcessor : public Processor, public TimedVideoSource, public TimedVideoSink -{ -public: - TimedVideoProcessor (boost::shared_ptr log) - : Processor (log) - {} -}; - #endif diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h index 0b05b2f71..88730f518 100644 --- a/src/lib/video_decoder.h +++ b/src/lib/video_decoder.h @@ -25,7 +25,7 @@ class VideoContent; -class VideoDecoder : public TimedVideoSource, public virtual Decoder +class VideoDecoder : public VideoSource, public virtual Decoder { public: VideoDecoder (boost::shared_ptr); diff --git a/src/lib/video_sink.h b/src/lib/video_sink.h index 6239bc557..2da42528c 100644 --- a/src/lib/video_sink.h +++ b/src/lib/video_sink.h @@ -34,19 +34,7 @@ public: * @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 i, bool same, boost::shared_ptr s) = 0; -}; - -class TimedVideoSink -{ -public: - /** Call with a frame of video. - * @param i Video frame image. - * @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. - * @param t Source timestamp. - */ - virtual void process_video (boost::shared_ptr i, bool same, boost::shared_ptr s, double t) = 0; + virtual void process_video (boost::shared_ptr i, bool same, boost::shared_ptr s, Time) = 0; }; #endif diff --git a/src/lib/video_source.cc b/src/lib/video_source.cc index 4d505f9fe..39043c860 100644 --- a/src/lib/video_source.cc +++ b/src/lib/video_source.cc @@ -25,11 +25,11 @@ using boost::weak_ptr; using boost::bind; static void -process_video_proxy (weak_ptr sink, shared_ptr i, bool same, shared_ptr s) +process_video_proxy (weak_ptr sink, shared_ptr image, bool same, shared_ptr sub, Time time) { shared_ptr p = sink.lock (); if (p) { - p->process_video (i, same, s); + p->process_video (image, same, sub, time); } } @@ -39,26 +39,6 @@ VideoSource::connect_video (shared_ptr s) /* If we bind, say, a Player (as the VideoSink) to a Decoder (which is owned by the Player) we create a cycle. Use a weak_ptr to break it. */ - Video.connect (bind (process_video_proxy, weak_ptr (s), _1, _2, _3)); + Video.connect (bind (process_video_proxy, weak_ptr (s), _1, _2, _3, _4)); } -void -TimedVideoSource::connect_video (shared_ptr s) -{ - Video.connect (bind (process_video_proxy, weak_ptr (s), _1, _2, _3)); -} - -static void -timed_process_video_proxy (weak_ptr sink, shared_ptr i, bool same, shared_ptr s, double t) -{ - shared_ptr p = sink.lock (); - if (p) { - p->process_video (i, same, s, t); - } -} - -void -TimedVideoSource::connect_video (shared_ptr s) -{ - Video.connect (bind (timed_process_video_proxy, weak_ptr (s), _1, _2, _3, _4)); -} diff --git a/src/lib/video_source.h b/src/lib/video_source.h index 9b4c9b4a2..7ad554480 100644 --- a/src/lib/video_source.h +++ b/src/lib/video_source.h @@ -29,7 +29,6 @@ #include "util.h" class VideoSink; -class TimedVideoSink; class Subtitle; class Image; @@ -45,28 +44,9 @@ public: * 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, bool, boost::shared_ptr)> Video; + boost::signals2::signal, bool, boost::shared_ptr, Time)> Video; void connect_video (boost::shared_ptr); }; -/** @class TimedVideoSource - * @param A class that emits video data with timestamps. - */ -class TimedVideoSource -{ -public: - - /** Emitted when a video frame is ready. - * First parameter is the video image. - * 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. - * Fourth parameter is the source timestamp of this frame. - */ - boost::signals2::signal, bool, boost::shared_ptr, double)> Video; - - void connect_video (boost::shared_ptr); - void connect_video (boost::shared_ptr); -}; - #endif -- cgit v1.2.3 From 6aea66f4331d0f543416acd55a7d99772e274414 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 13 May 2013 12:27:18 +0100 Subject: Updated fr_FR from Lilian. --- src/lib/po/fr_FR.po | 75 ++++++++++++++++++++++++------------------- src/tools/po/fr_FR.po | 25 ++++++--------- src/wx/po/fr_FR.po | 88 ++++++++++++++++++++++++++------------------------- 3 files changed, 98 insertions(+), 90 deletions(-) (limited to 'src') diff --git a/src/lib/po/fr_FR.po b/src/lib/po/fr_FR.po index 174a25cff..a6a72598f 100644 --- a/src/lib/po/fr_FR.po +++ b/src/lib/po/fr_FR.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-05-09 09:51+0100\n" -"PO-Revision-Date: 2013-03-20 00:39+0100\n" -"Last-Translator: FreeDCP.net \n" +"PO-Revision-Date: 2013-05-10 14:33+0100\n" +"Last-Translator: \n" "Language-Team: \n" "Language: \n" "MIME-Version: 1.0\n" @@ -55,7 +55,7 @@ msgstr "Débruitage 3D" #: src/lib/format.cc:79 msgid "4:3" -msgstr "" +msgstr "4:3" #: src/lib/format.cc:87 msgid "4:3 within Flat" @@ -95,11 +95,11 @@ msgstr "Bilinéaire" #: src/lib/job.cc:318 msgid "Cancelled" -msgstr "" +msgstr "Annulé" #: src/lib/exceptions.cc:60 msgid "Cannot handle pixel format %1 during %2" -msgstr "" +msgstr "Format du pixel %1 non géré par %2" #: src/lib/encoder.cc:101 msgid "Cannot resample audio as libswresample is not present" @@ -107,7 +107,7 @@ msgstr "Ré-échantillonnage du son impossible : libswresample est absent" #: src/lib/util.cc:960 msgid "Centre" -msgstr "" +msgstr "Centre" #: src/lib/scp_dcp_job.cc:109 msgid "Copy DCP to TMS" @@ -150,14 +150,24 @@ msgstr "La cadence du DCP sera %1%% par rapport à la source.\n" msgid "DCP will use every other frame of the source.\n" msgstr "Le DCP utilisera une image sur deux de la source.\n" -#: src/lib/filter.cc:68 src/lib/filter.cc:69 src/lib/filter.cc:70 -#: src/lib/filter.cc:71 src/lib/filter.cc:72 src/lib/filter.cc:73 +#: src/lib/filter.cc:68 +#: src/lib/filter.cc:69 +#: src/lib/filter.cc:70 +#: src/lib/filter.cc:71 +#: src/lib/filter.cc:72 +#: src/lib/filter.cc:73 msgid "De-blocking" msgstr "De-bloc" -#: src/lib/filter.cc:75 src/lib/filter.cc:76 src/lib/filter.cc:77 -#: src/lib/filter.cc:78 src/lib/filter.cc:79 src/lib/filter.cc:80 -#: src/lib/filter.cc:81 src/lib/filter.cc:82 src/lib/filter.cc:83 +#: src/lib/filter.cc:75 +#: src/lib/filter.cc:76 +#: src/lib/filter.cc:77 +#: src/lib/filter.cc:78 +#: src/lib/filter.cc:79 +#: src/lib/filter.cc:80 +#: src/lib/filter.cc:81 +#: src/lib/filter.cc:82 +#: src/lib/filter.cc:83 msgid "De-interlacing" msgstr "Désentrelacement" @@ -245,13 +255,10 @@ msgstr "Filtre dé-bloc horizontal" msgid "Horizontal deblocking filter A" msgstr "Filtre dé-bloc horizontal" -#: src/lib/job.cc:97 src/lib/job.cc:106 -msgid "" -"It is not known what caused this error. The best idea is to report the " -"problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" -msgstr "" -"Erreur indéterminée. Merci de rapporter le problème à la liste DVD-o-matic " -"(dvdomatic@carlh.net)" +#: src/lib/job.cc:97 +#: src/lib/job.cc:106 +msgid "It is not known what caused this error. The best idea is to report the problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)" +msgstr "Erreur indéterminée. Merci de rapporter le problème à la liste DVD-o-matic (dvdomatic@carlh.net)" #: src/lib/filter.cc:82 msgid "Kernel deinterlacer" @@ -285,8 +292,11 @@ msgstr "Désentrelaceur linéaire interpolé" msgid "Median deinterlacer" msgstr "Désentrelaceur médian" -#: src/lib/filter.cc:74 src/lib/filter.cc:85 src/lib/filter.cc:86 -#: src/lib/filter.cc:87 src/lib/filter.cc:90 +#: src/lib/filter.cc:74 +#: src/lib/filter.cc:85 +#: src/lib/filter.cc:86 +#: src/lib/filter.cc:87 +#: src/lib/filter.cc:90 msgid "Misc" msgstr "Divers" @@ -294,7 +304,9 @@ msgstr "Divers" msgid "Motion compensating deinterlacer" msgstr "Désentrelaceur par compensation de mouvement" -#: src/lib/filter.cc:84 src/lib/filter.cc:88 src/lib/filter.cc:89 +#: src/lib/filter.cc:84 +#: src/lib/filter.cc:88 +#: src/lib/filter.cc:89 #: src/lib/filter.cc:91 msgid "Noise reduction" msgstr "Réduction de bruit" @@ -372,12 +384,8 @@ msgid "Test" msgstr "Test" #: src/lib/job.cc:79 -msgid "" -"The drive that the film is stored on is low in disc space. Free some more " -"space and try again." -msgstr "" -"Le disque contenant le film est plein. Libérez de l'espace et essayez à " -"nouveau." +msgid "The drive that the film is stored on is low in disc space. Free some more space and try again." +msgstr "Le disque contenant le film est plein. Libérez de l'espace et essayez à nouveau." #: src/lib/dcp_content_type.cc:46 msgid "Trailer" @@ -481,9 +489,10 @@ msgstr "lecture du fichier impossible" #: src/lib/exceptions.cc:44 msgid "could not read from file %1 (%2)" -msgstr "Création du dossier distant %1 impossible (%2)" +msgstr "création du dossier distant %1 impossible (%2)" -#: src/lib/encoder.cc:137 src/lib/encoder.cc:314 +#: src/lib/encoder.cc:137 +#: src/lib/encoder.cc:314 msgid "could not run sample-rate converter" msgstr "conversion de la fréquence d'échantillonnage impossible" @@ -519,7 +528,8 @@ msgstr "images par seconde" msgid "hour" msgstr "heure" -#: src/lib/util.cc:125 src/lib/util.cc:130 +#: src/lib/util.cc:125 +#: src/lib/util.cc:130 msgid "hours" msgstr "heures" @@ -537,13 +547,14 @@ msgstr "clé %1 non sélectionnée" #: src/lib/exceptions.cc:54 msgid "missing required setting %1" -msgstr "" +msgstr "paramètre %1 manquant" #: src/lib/subtitle.cc:52 msgid "multi-part subtitles not yet supported" msgstr "sous-titres en plusieurs parties non supportés" -#: src/lib/film.cc:296 src/lib/film.cc:341 +#: src/lib/film.cc:296 +#: src/lib/film.cc:341 msgid "name" msgstr "nom" diff --git a/src/tools/po/fr_FR.po b/src/tools/po/fr_FR.po index ed9baf084..6b8f1e783 100644 --- a/src/tools/po/fr_FR.po +++ b/src/tools/po/fr_FR.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-05-09 09:51+0100\n" -"PO-Revision-Date: 2013-03-13 22:33+0100\n" +"PO-Revision-Date: 2013-05-10 14:09+0100\n" "Last-Translator: \n" "Language-Team: \n" "Language: \n" @@ -65,10 +65,8 @@ msgid "&Send DCP to TMS" msgstr "&Envoyer le DCP dans le TMS" #: src/tools/dvdomatic.cc:426 -msgid "" -"(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" -msgstr "" -"(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" +msgid "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" +msgstr "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen" #: src/tools/dvdomatic.cc:181 msgid "About" @@ -84,7 +82,8 @@ msgstr "Impossible de charger le film %s (%s)" msgid "Could not open film at %s (%s)" msgstr "Impossible d'ouvrir le film à %s (%s)" -#: src/tools/dvdomatic.cc:288 src/tools/dvdomatic.cc:419 +#: src/tools/dvdomatic.cc:288 +#: src/tools/dvdomatic.cc:419 #: src/tools/dvdomatic.cc:506 msgid "DVD-o-matic" msgstr "DVD-o-matic" @@ -108,23 +107,19 @@ msgstr "Voir le DCP" #: src/tools/dvdomatic.cc:75 #, c-format msgid "Save changes to film \"%s\" before closing?" -msgstr "" +msgstr "Enregistrer les changements du film \"%s\" avant de fermer ?" #: src/tools/dvdomatic.cc:328 msgid "Select film to open" msgstr "Sélectionner le film à ouvrir" #: src/tools/dvdomatic.cc:307 -msgid "" -"The directory %1 already exists and is not empty. Are you sure you want to " -"use it?" -msgstr "" +msgid "The directory %1 already exists and is not empty. Are you sure you want to use it?" +msgstr "Le dossier %1 existe et n'est pas vide. Etes-vous sûr de vouloir l'utiliser ?" #: src/tools/dvdomatic.cc:333 -msgid "" -"You did not select a folder. Make sure that you select a folder before " -"clicking Open." -msgstr "" +msgid "You did not select a folder. Make sure that you select a folder before clicking Open." +msgstr "Aucun dossier sélectionné. Selectionnez un dossier avant de cliquer sur Ouvrir" #, fuzzy #~ msgid "The directory %1 already exists." diff --git a/src/wx/po/fr_FR.po b/src/wx/po/fr_FR.po index cb2899a07..ad138d45a 100644 --- a/src/wx/po/fr_FR.po +++ b/src/wx/po/fr_FR.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: DVD-o-matic FRENCH\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-05-09 09:51+0100\n" -"PO-Revision-Date: 2013-03-20 00:34+0100\n" -"Last-Translator: FreeDCP.net \n" +"PO-Revision-Date: 2013-05-10 14:19+0100\n" +"Last-Translator: \n" "Language-Team: \n" "Language: \n" "MIME-Version: 1.0\n" @@ -22,7 +22,7 @@ msgstr "%" #: src/wx/config_dialog.cc:98 msgid "(restart DCP-o-matic to see language changes)" -msgstr "" +msgstr "(redémarrez DCP-o-matic pour voir les changements de langue)" #: src/wx/film_editor.cc:1276 msgid "1 channel" @@ -34,13 +34,14 @@ msgstr "A/B" #: src/wx/config_dialog.cc:61 msgid "A/B mode" -msgstr "" +msgstr "A/B mode" #: src/wx/config_dialog.cc:325 msgid "Add" msgstr "Ajouter" -#: src/wx/audio_dialog.cc:32 src/wx/film_editor.cc:77 +#: src/wx/audio_dialog.cc:32 +#: src/wx/film_editor.cc:77 msgid "Audio" msgstr "Audio" @@ -59,7 +60,7 @@ msgstr "Langue audio (ex. FR)" #: src/wx/film_editor.cc:824 #, c-format msgid "Audio will be resampled from %dHz to %dHz\n" -msgstr "" +msgstr "L'audio sera rééchantillonné de %dHz à %dHz\n" #: src/wx/job_wrapper.cc:38 #, c-format @@ -127,14 +128,13 @@ msgid "Create in folder" msgstr "Créer dans le dossier" #: src/wx/config_dialog.cc:244 -#, fuzzy msgid "Creator" -msgstr "Créer dans le dossier" +msgstr "Créateur" #: src/wx/film_editor.cc:1371 #, c-format msgid "Cropped to %dx%d (%.2f:1)\n" -msgstr "" +msgstr "Découpe de %dx%d (%.2f:1)\n" #: src/wx/dci_metadata_dialog.cc:28 msgid "DCI name" @@ -149,11 +149,11 @@ msgid "DCP Name" msgstr "Nom du DCP" #: src/wx/config_dialog.cc:46 -#, fuzzy msgid "DCP-o-matic Preferences" -msgstr "Préférences DVD-o-matic" +msgstr "Préférences de DCP-o-matic" -#: src/wx/wx_util.cc:63 src/wx/wx_util.cc:71 +#: src/wx/wx_util.cc:63 +#: src/wx/wx_util.cc:71 msgid "DVD-o-matic" msgstr "DVD-o-matic" @@ -167,9 +167,8 @@ msgid "Default DCI name details" msgstr "Détails du nom DCI par défaut" #: src/wx/config_dialog.cc:130 -#, fuzzy msgid "Default content type" -msgstr "Type de Contenu" +msgstr "Type de contenu par défaut" #: src/wx/config_dialog.cc:111 msgid "Default directory for new films" @@ -177,9 +176,10 @@ msgstr "Dossier par défaut des nouveaux films" #: src/wx/config_dialog.cc:125 msgid "Default format" -msgstr "" +msgstr "Format par défaut" -#: src/wx/film_editor.cc:116 src/wx/job_manager_view.cc:109 +#: src/wx/film_editor.cc:116 +#: src/wx/job_manager_view.cc:109 msgid "Details..." msgstr "Détails..." @@ -195,7 +195,8 @@ msgstr "Durée" msgid "Edit" msgstr "Édition" -#: src/wx/config_dialog.cc:121 src/wx/config_dialog.cc:282 +#: src/wx/config_dialog.cc:121 +#: src/wx/config_dialog.cc:282 #: src/wx/film_editor.cc:312 msgid "Edit..." msgstr "Éditer..." @@ -225,7 +226,8 @@ msgstr "Propriétés du film" msgid "Film name" msgstr "Nom du Film" -#: src/wx/film_editor.cc:307 src/wx/filter_dialog.cc:32 +#: src/wx/film_editor.cc:307 +#: src/wx/filter_dialog.cc:32 msgid "Filters" msgstr "Filtres" @@ -261,13 +263,14 @@ msgstr "Hz" msgid "I want to play this back at fader" msgstr "Je veux le jouer à ce volume" -#: src/wx/config_dialog.cc:201 src/wx/config_dialog.cc:314 +#: src/wx/config_dialog.cc:201 +#: src/wx/config_dialog.cc:314 msgid "IP address" msgstr "Adresse IP" #: src/wx/config_dialog.cc:240 msgid "Issuer" -msgstr "" +msgstr "Emetteur" #: src/wx/film_editor.cc:339 msgid "JPEG2000 bandwidth" @@ -287,11 +290,11 @@ msgstr "MBps" #: src/wx/config_dialog.cc:57 msgid "Metadata" -msgstr "" +msgstr "Métadonnées" #: src/wx/config_dialog.cc:53 msgid "Miscellaneous" -msgstr "" +msgstr "Divers" #: src/wx/dir_picker_ctrl.cc:52 msgid "My Documents" @@ -305,7 +308,8 @@ msgstr "Nom" msgid "New Film" msgstr "Nouveau Film" -#: src/wx/film_editor.cc:309 src/wx/film_editor.cc:671 +#: src/wx/film_editor.cc:309 +#: src/wx/film_editor.cc:671 msgid "None" msgstr "Aucun" @@ -316,7 +320,7 @@ msgstr "Cadence d'images originale" #: src/wx/film_editor.cc:1360 #, c-format msgid "Original video is %dx%d (%.2f:1)\n" -msgstr "" +msgstr "La vidéo originale est %dx%d (%.2f:1)\n" #: src/wx/dci_metadata_dialog.cc:57 msgid "Package Type (e.g. OV)" @@ -325,16 +329,16 @@ msgstr "Type de paquet (ex. OV)" #: src/wx/film_editor.cc:1392 #, c-format msgid "Padded with black to %dx%d (%.2f:1)\n" -msgstr "" +msgstr "Enveloppe noire de %dx%d (%.2f:1)\n" #: src/wx/config_dialog.cc:213 -#, fuzzy msgid "Password" -msgstr "Mot de passe du TMS" +msgstr "Mot de passe" -#: src/wx/job_manager_view.cc:103 src/wx/job_manager_view.cc:188 +#: src/wx/job_manager_view.cc:103 +#: src/wx/job_manager_view.cc:188 msgid "Pause" -msgstr "" +msgstr "Pause" #: src/wx/audio_dialog.cc:60 msgid "Peak" @@ -357,14 +361,12 @@ msgid "Rating (e.g. 15)" msgstr "Rating (ex. 15)" #: src/wx/config_dialog.cc:278 -#, fuzzy msgid "Reference filters" -msgstr "Filtres de référence pour A/B" +msgstr "Filtres de référence" #: src/wx/config_dialog.cc:267 -#, fuzzy msgid "Reference scaler" -msgstr "Échelle de référence pour A/B" +msgstr "Échelle de référence" #: src/wx/config_dialog.cc:329 msgid "Remove" @@ -372,7 +374,7 @@ msgstr "Supprimer" #: src/wx/job_manager_view.cc:191 msgid "Resume" -msgstr "" +msgstr "Reprendre" #: src/wx/film_editor.cc:282 msgid "Right crop" @@ -385,7 +387,7 @@ msgstr "Progression" #: src/wx/film_editor.cc:1384 #, c-format msgid "Scaled to %dx%d (%.2f:1)\n" -msgstr "" +msgstr "Mis à l'échelle de %dx%d (%.2f:1)\n" #: src/wx/film_editor.cc:319 msgid "Scaler" @@ -405,7 +407,7 @@ msgstr "Serveur" #: src/wx/config_dialog.cc:87 msgid "Set language" -msgstr "" +msgstr "Selectionnez la langue" #: src/wx/film_editor.cc:368 msgid "Show Audio..." @@ -445,9 +447,8 @@ msgid "TMS" msgstr "RMS" #: src/wx/config_dialog.cc:205 -#, fuzzy msgid "Target path" -msgstr "Chemin d'accès du TMS" +msgstr "Chemin d'accès" #: src/wx/dci_metadata_dialog.cc:41 msgid "Territory (e.g. UK)" @@ -506,9 +507,8 @@ msgid "Use external audio" msgstr "Utiliser une source audio externe" #: src/wx/config_dialog.cc:209 -#, fuzzy msgid "User name" -msgstr "Utiliser le nom DCI" +msgstr "Nom d'utilisateur" #: src/wx/film_editor.cc:75 msgid "Video" @@ -538,7 +538,8 @@ msgstr "encoder toutes les images mais lire seulement la sélection" msgid "encode only the subset" msgstr "encoder seulement la sélection" -#: src/wx/film_editor.cc:694 src/wx/film_editor.cc:697 +#: src/wx/film_editor.cc:694 +#: src/wx/film_editor.cc:697 msgid "frames" msgstr "images" @@ -549,14 +550,15 @@ msgstr "ms" #: src/wx/film_editor.cc:440 msgid "pixels" -msgstr "" +msgstr "pixels" #. / TRANSLATORS: `s' here is an abbreviation for seconds, the unit of time #: src/wx/film_editor.cc:197 msgid "s" msgstr "s" -#: src/wx/properties_dialog.cc:62 src/wx/properties_dialog.cc:63 +#: src/wx/properties_dialog.cc:62 +#: src/wx/properties_dialog.cc:63 msgid "unknown" msgstr "inconnu" -- cgit v1.2.3 From 21ce34c2cd04a2e7e133ff693b84c054182f4f91 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 16 May 2013 08:36:47 +0100 Subject: Compiles; strange hang on adding content to a film. --- src/lib/analyse_audio_job.cc | 4 +- src/lib/audio_buffers.cc | 222 +++++++++++++++++++++ src/lib/audio_buffers.h | 67 +++++++ src/lib/audio_content.cc | 6 - src/lib/audio_content.h | 5 +- src/lib/audio_decoder.cc | 14 +- src/lib/audio_decoder.h | 1 + src/lib/audio_mapping.cc | 51 ++--- src/lib/audio_mapping.h | 28 +-- src/lib/audio_sink.h | 2 + src/lib/combiner.cc | 4 +- src/lib/content.h | 2 +- src/lib/decoder.h | 1 - src/lib/encoder.cc | 17 +- src/lib/encoder.h | 2 - src/lib/ffmpeg_content.cc | 33 +++- src/lib/ffmpeg_content.h | 5 +- src/lib/ffmpeg_decoder.cc | 5 +- src/lib/film.cc | 188 ++++++------------ src/lib/film.h | 48 ++--- src/lib/format.cc | 3 +- src/lib/format.h | 2 +- src/lib/imagemagick_content.cc | 7 + src/lib/imagemagick_content.h | 1 + src/lib/player.cc | 338 +++++++++++++++----------------- src/lib/player.h | 53 ++--- src/lib/playlist.cc | 419 +++++++++++++--------------------------- src/lib/playlist.h | 77 +++----- src/lib/sndfile_content.cc | 14 +- src/lib/sndfile_content.h | 5 +- src/lib/sndfile_decoder.cc | 3 +- src/lib/subtitle.h | 2 +- src/lib/transcode_job.cc | 13 +- src/lib/types.h | 10 +- src/lib/util.cc | 227 +--------------------- src/lib/util.h | 50 +---- src/lib/video_content.cc | 6 - src/lib/video_content.h | 1 - src/lib/video_decoder.cc | 4 +- src/lib/writer.cc | 47 ++--- src/lib/wscript | 1 + src/wx/audio_dialog.cc | 4 - src/wx/audio_mapping_view.cc | 8 +- src/wx/ffmpeg_content_dialog.cc | 2 +- src/wx/film_editor.cc | 149 ++++---------- src/wx/film_editor.h | 6 - src/wx/film_viewer.cc | 18 +- src/wx/properties_dialog.cc | 10 +- src/wx/timeline.cc | 102 ++++------ src/wx/timeline.h | 16 +- src/wx/timeline_dialog.cc | 4 +- src/wx/timeline_dialog.h | 2 +- test/test.cc | 32 +-- wscript | 2 +- 54 files changed, 990 insertions(+), 1353 deletions(-) create mode 100644 src/lib/audio_buffers.cc create mode 100644 src/lib/audio_buffers.h (limited to 'src') diff --git a/src/lib/analyse_audio_job.cc b/src/lib/analyse_audio_job.cc index f3c55b208..0ed33827c 100644 --- a/src/lib/analyse_audio_job.cc +++ b/src/lib/analyse_audio_job.cc @@ -55,13 +55,13 @@ AnalyseAudioJob::run () player->Audio.connect (bind (&AnalyseAudioJob::audio, this, _1)); - _samples_per_point = max (int64_t (1), _film->audio_length() / _num_points); + _samples_per_point = max (int64_t (1), _film->time_to_audio_frames (_film->length()) / _num_points); _current.resize (MAX_AUDIO_CHANNELS); _analysis.reset (new AudioAnalysis (MAX_AUDIO_CHANNELS)); while (!player->pass()) { - set_progress (float (_done) / _film->audio_length ()); + set_progress (float (_done) / _film->time_to_audio_frames (_film->length ())); } _analysis->write (_film->audio_analysis_path ()); diff --git a/src/lib/audio_buffers.cc b/src/lib/audio_buffers.cc new file mode 100644 index 000000000..cd8fcd35b --- /dev/null +++ b/src/lib/audio_buffers.cc @@ -0,0 +1,222 @@ +/* + Copyright (C) 2012-2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include +#include +#include "audio_buffers.h" + +using std::bad_alloc; +using boost::shared_ptr; + +/** Construct an AudioBuffers. Audio data is undefined after this constructor. + * @param channels Number of channels. + * @param frames Number of frames to reserve space for. + */ +AudioBuffers::AudioBuffers (int channels, int frames) + : _channels (channels) + , _frames (frames) + , _allocated_frames (frames) +{ + _data = static_cast (malloc (_channels * sizeof (float *))); + if (!_data) { + throw bad_alloc (); + } + + for (int i = 0; i < _channels; ++i) { + _data[i] = static_cast (malloc (frames * sizeof (float))); + if (!_data[i]) { + throw bad_alloc (); + } + } +} + +/** Copy constructor. + * @param other Other AudioBuffers; data is copied. + */ +AudioBuffers::AudioBuffers (AudioBuffers const & other) + : _channels (other._channels) + , _frames (other._frames) + , _allocated_frames (other._frames) +{ + _data = static_cast (malloc (_channels * sizeof (float *))); + if (!_data) { + throw bad_alloc (); + } + + for (int i = 0; i < _channels; ++i) { + _data[i] = static_cast (malloc (_frames * sizeof (float))); + if (!_data[i]) { + throw bad_alloc (); + } + memcpy (_data[i], other._data[i], _frames * sizeof (float)); + } +} + +/* 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 other) + : _channels (other->_channels) + , _frames (other->_frames) + , _allocated_frames (other->_frames) +{ + _data = static_cast (malloc (_channels * sizeof (float *))); + if (!_data) { + throw bad_alloc (); + } + + for (int i = 0; i < _channels; ++i) { + _data[i] = static_cast (malloc (_frames * sizeof (float))); + if (!_data[i]) { + throw bad_alloc (); + } + memcpy (_data[i], other->_data[i], _frames * sizeof (float)); + } +} + +/** AudioBuffers destructor */ +AudioBuffers::~AudioBuffers () +{ + for (int i = 0; i < _channels; ++i) { + free (_data[i]); + } + + free (_data); +} + +/** @param c Channel index. + * @return Buffer for this channel. + */ +float* +AudioBuffers::data (int c) const +{ + assert (c >= 0 && c < _channels); + return _data[c]; +} + +/** Set the number of frames that these AudioBuffers will report themselves + * as having. + * @param f Frames; must be less than or equal to the number of allocated frames. + */ +void +AudioBuffers::set_frames (int f) +{ + assert (f <= _allocated_frames); + _frames = f; +} + +/** Make all samples on all channels silent */ +void +AudioBuffers::make_silent () +{ + for (int i = 0; i < _channels; ++i) { + make_silent (i); + } +} + +/** Make all samples on a given channel silent. + * @param c Channel. + */ +void +AudioBuffers::make_silent (int c) +{ + assert (c >= 0 && c < _channels); + + for (int i = 0; i < _frames; ++i) { + _data[c][i] = 0; + } +} + +/** Copy data from another AudioBuffers to this one. All channels are copied. + * @param from AudioBuffers to copy from; must have the same number of channels as this. + * @param frames_to_copy Number of frames to copy. + * @param read_offset Offset to read from in `from'. + * @param write_offset Offset to write to in `to'. + */ +void +AudioBuffers::copy_from (AudioBuffers const * from, int frames_to_copy, int read_offset, int write_offset) +{ + assert (from->channels() == channels()); + + assert (from); + assert (read_offset >= 0 && (read_offset + frames_to_copy) <= from->_allocated_frames); + assert (write_offset >= 0 && (write_offset + frames_to_copy) <= _allocated_frames); + + for (int i = 0; i < _channels; ++i) { + memcpy (_data[i] + write_offset, from->_data[i] + read_offset, frames_to_copy * sizeof(float)); + } +} + +/** Move audio data around. + * @param from Offset to move from. + * @param to Offset to move to. + * @param frames Number of frames to move. + */ + +void +AudioBuffers::move (int from, int to, int frames) +{ + if (frames == 0) { + return; + } + + assert (from >= 0); + assert (from < _frames); + assert (to >= 0); + assert (to < _frames); + assert (frames > 0); + assert (frames <= _frames); + assert ((from + frames) <= _frames); + assert ((to + frames) <= _frames); + + for (int i = 0; i < _channels; ++i) { + memmove (_data[i] + to, _data[i] + from, frames * sizeof(float)); + } +} + +/** Add data from from `from', `from_channel' to our channel `to_channel' */ +void +AudioBuffers::accumulate (AudioBuffers const * from, int from_channel, int to_channel) +{ + int const N = frames (); + assert (from->frames() == N); + + float* s = from->data (from_channel); + float* d = _data[to_channel]; + + for (int i = 0; i < N; ++i) { + *d++ += *s++; + } +} + +void +AudioBuffers::ensure_size (int frames) +{ + if (_allocated_frames >= frames) { + return; + } + + for (int i = 0; i < _channels; ++i) { + _data[i] = static_cast (realloc (_data[i], _frames * sizeof (float))); + if (!_data[i]) { + throw bad_alloc (); + } + } +} diff --git a/src/lib/audio_buffers.h b/src/lib/audio_buffers.h new file mode 100644 index 000000000..5e7b9fda4 --- /dev/null +++ b/src/lib/audio_buffers.h @@ -0,0 +1,67 @@ +/* + Copyright (C) 2012-2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include + +/** @class AudioBuffers + * @brief A class to hold multi-channel audio data in float format. + */ +class AudioBuffers +{ +public: + AudioBuffers (int channels, int frames); + AudioBuffers (AudioBuffers const &); + AudioBuffers (boost::shared_ptr); + ~AudioBuffers (); + + void ensure_size (int); + + float** data () const { + return _data; + } + + float* data (int) const; + + int channels () const { + return _channels; + } + + int frames () const { + return _frames; + } + + void set_frames (int f); + + void make_silent (); + void make_silent (int c); + + void copy_from (AudioBuffers const * from, int frames_to_copy, int read_offset, int write_offset); + void move (int from, int to, int frames); + void accumulate (AudioBuffers const *, int, int); + +private: + /** Number of channels */ + int _channels; + /** Number of frames (where a frame is one sample across all channels) */ + int _frames; + /** Number of frames that _data can hold */ + int _allocated_frames; + /** Audio data (so that, e.g. _data[2][6] is channel 2, sample 6) */ + float** _data; +}; diff --git a/src/lib/audio_content.cc b/src/lib/audio_content.cc index dfa48d97e..9968f4725 100644 --- a/src/lib/audio_content.cc +++ b/src/lib/audio_content.cc @@ -43,9 +43,3 @@ AudioContent::AudioContent (AudioContent const & o) { } - -Time -AudioContent::temporal_length () const -{ - return audio_length() / audio_frame_rate(); -} diff --git a/src/lib/audio_content.h b/src/lib/audio_content.h index 18107843c..87858488c 100644 --- a/src/lib/audio_content.h +++ b/src/lib/audio_content.h @@ -44,9 +44,8 @@ public: virtual int audio_channels () const = 0; virtual ContentAudioFrame audio_length () const = 0; - virtual int audio_frame_rate () const = 0; - - Time temporal_length () const; + virtual int content_audio_frame_rate () const = 0; + virtual int output_audio_frame_rate (boost::shared_ptr) const = 0; }; #endif diff --git a/src/lib/audio_decoder.cc b/src/lib/audio_decoder.cc index 68554daf9..e1c93ac77 100644 --- a/src/lib/audio_decoder.cc +++ b/src/lib/audio_decoder.cc @@ -18,6 +18,7 @@ */ #include "audio_decoder.h" +#include "audio_buffers.h" #include "exceptions.h" #include "log.h" @@ -30,11 +31,12 @@ using boost::shared_ptr; AudioDecoder::AudioDecoder (shared_ptr f, shared_ptr c) : Decoder (f) , _audio_content (c) + , _output_audio_frame_rate (_audio_content->output_audio_frame_rate (f)) { - if (_audio_content->audio_frame_rate() != _film->target_audio_sample_rate()) { + if (_audio_content->content_audio_frame_rate() != _output_audio_frame_rate) { stringstream s; - s << String::compose ("Will resample audio from %1 to %2", _audio_content->audio_frame_rate(), _film->target_audio_sample_rate()); + s << String::compose ("Will resample audio from %1 to %2", _audio_content->content_audio_frame_rate(), _output_audio_frame_rate); _film->log()->log (s.str ()); /* We will be using planar float data when we call the @@ -49,10 +51,10 @@ AudioDecoder::AudioDecoder (shared_ptr f, shared_ptrtarget_audio_sample_rate(), + _output_audio_frame_rate, av_get_default_channel_layout (MAX_AUDIO_CHANNELS), AV_SAMPLE_FMT_FLTP, - _audio_content->audio_frame_rate(), + _audio_content->content_audio_frame_rate(), 0, 0 ); @@ -74,7 +76,7 @@ AudioDecoder::~AudioDecoder () void AudioDecoder::process_end () { - if (_film->has_audio() && _swr_context) { + if (_swr_context) { shared_ptr out (new AudioBuffers (_film->audio_mapping().dcp_channels(), 256)); @@ -106,7 +108,7 @@ AudioDecoder::emit_audio (shared_ptr data, Time time) if (_swr_context) { /* Compute the resampled frames count and add 32 for luck */ - int const max_resampled_frames = ceil ((int64_t) data->frames() * _film->target_audio_sample_rate() / _audio_content->audio_frame_rate()) + 32; + int const max_resampled_frames = ceil ((int64_t) data->frames() * _output_audio_frame_rate / _audio_content->content_audio_frame_rate()) + 32; shared_ptr resampled (new AudioBuffers (MAX_AUDIO_CHANNELS, max_resampled_frames)); diff --git a/src/lib/audio_decoder.h b/src/lib/audio_decoder.h index 1c7287a55..94845ec23 100644 --- a/src/lib/audio_decoder.h +++ b/src/lib/audio_decoder.h @@ -46,6 +46,7 @@ public: private: boost::shared_ptr _audio_content; SwrContext* _swr_context; + int _output_audio_frame_rate; }; #endif diff --git a/src/lib/audio_mapping.cc b/src/lib/audio_mapping.cc index 7e28aa5c4..e1fa0c220 100644 --- a/src/lib/audio_mapping.cc +++ b/src/lib/audio_mapping.cc @@ -31,7 +31,7 @@ using boost::lexical_cast; using boost::dynamic_pointer_cast; void -AudioMapping::add (Channel c, libdcp::Channel d) +AudioMapping::add (int c, libdcp::Channel d) { _content_to_dcp.push_back (make_pair (c, d)); } @@ -40,7 +40,7 @@ AudioMapping::add (Channel c, libdcp::Channel d) int AudioMapping::dcp_channels () const { - for (list >::const_iterator i = _content_to_dcp.begin(); i != _content_to_dcp.end(); ++i) { + for (list >::const_iterator i = _content_to_dcp.begin(); i != _content_to_dcp.end(); ++i) { if (((int) i->second) >= 2) { return 6; } @@ -49,11 +49,11 @@ AudioMapping::dcp_channels () const return 2; } -list +list AudioMapping::dcp_to_content (libdcp::Channel d) const { - list c; - for (list >::const_iterator i = _content_to_dcp.begin(); i != _content_to_dcp.end(); ++i) { + list c; + for (list >::const_iterator i = _content_to_dcp.begin(); i != _content_to_dcp.end(); ++i) { if (i->second == d) { c.push_back (i->first); } @@ -62,11 +62,11 @@ AudioMapping::dcp_to_content (libdcp::Channel d) const return c; } -list +list AudioMapping::content_channels () const { - list c; - for (list >::const_iterator i = _content_to_dcp.begin(); i != _content_to_dcp.end(); ++i) { + list c; + for (list >::const_iterator i = _content_to_dcp.begin(); i != _content_to_dcp.end(); ++i) { if (find (c.begin(), c.end(), i->first) == c.end ()) { c.push_back (i->first); } @@ -76,10 +76,10 @@ AudioMapping::content_channels () const } list -AudioMapping::content_to_dcp (Channel c) const +AudioMapping::content_to_dcp (int c) const { list d; - for (list >::const_iterator i = _content_to_dcp.begin(); i != _content_to_dcp.end(); ++i) { + for (list >::const_iterator i = _content_to_dcp.begin(); i != _content_to_dcp.end(); ++i) { if (i->first == c) { d.push_back (i->second); } @@ -91,41 +91,18 @@ AudioMapping::content_to_dcp (Channel c) const void AudioMapping::as_xml (xmlpp::Node* node) const { - for (list >::const_iterator i = _content_to_dcp.begin(); i != _content_to_dcp.end(); ++i) { + for (list >::const_iterator i = _content_to_dcp.begin(); i != _content_to_dcp.end(); ++i) { xmlpp::Node* t = node->add_child ("Map"); - shared_ptr c = i->first.content.lock (); - t->add_child ("Content")->add_child_text (c->digest ()); - t->add_child ("ContentIndex")->add_child_text (lexical_cast (i->first.index)); + t->add_child ("ContentIndex")->add_child_text (lexical_cast (i->first)); t->add_child ("DCP")->add_child_text (lexical_cast (i->second)); } } void -AudioMapping::set_from_xml (ContentList const & content, shared_ptr node) +AudioMapping::set_from_xml (shared_ptr node) { list > const c = node->node_children ("Map"); for (list >::const_iterator i = c.begin(); i != c.end(); ++i) { - string const c = (*i)->string_child ("Content"); - ContentList::const_iterator j = content.begin (); - while (j != content.end() && (*j)->digest() != c) { - ++j; - } - - if (j == content.end ()) { - continue; - } - - shared_ptr ac = dynamic_pointer_cast (*j); - assert (ac); - - add (AudioMapping::Channel (ac, (*i)->number_child ("ContentIndex")), static_cast ((*i)->number_child ("DCP"))); + add ((*i)->number_child ("ContentIndex"), static_cast ((*i)->number_child ("DCP"))); } } - -bool -operator== (AudioMapping::Channel const & a, AudioMapping::Channel const & b) -{ - shared_ptr sa = a.content.lock (); - shared_ptr sb = b.content.lock (); - return sa == sb && a.index == b.index; -} diff --git a/src/lib/audio_mapping.h b/src/lib/audio_mapping.h index 248d2570e..3c471d3f4 100644 --- a/src/lib/audio_mapping.h +++ b/src/lib/audio_mapping.h @@ -30,33 +30,21 @@ class AudioMapping { public: void as_xml (xmlpp::Node *) const; - void set_from_xml (ContentList const &, boost::shared_ptr); - - struct Channel { - Channel (boost::weak_ptr c, int i) - : content (c) - , index (i) - {} - - boost::weak_ptr content; - int index; - }; - - void add (Channel, libdcp::Channel); + void set_from_xml (boost::shared_ptr); + + void add (int, libdcp::Channel); int dcp_channels () const; - std::list dcp_to_content (libdcp::Channel) const; - std::list > content_to_dcp () const { + std::list dcp_to_content (libdcp::Channel) const; + std::list > content_to_dcp () const { return _content_to_dcp; } - std::list content_channels () const; - std::list content_to_dcp (Channel) const; + std::list content_channels () const; + std::list content_to_dcp (int) const; private: - std::list > _content_to_dcp; + std::list > _content_to_dcp; }; -extern bool operator== (AudioMapping::Channel const &, AudioMapping::Channel const &); - #endif diff --git a/src/lib/audio_sink.h b/src/lib/audio_sink.h index 2e3ead005..1aad5edf9 100644 --- a/src/lib/audio_sink.h +++ b/src/lib/audio_sink.h @@ -20,6 +20,8 @@ #ifndef DCPOMATIC_AUDIO_SINK_H #define DCPOMATIC_AUDIO_SINK_H +class AudioBuffers; + class AudioSink { public: diff --git a/src/lib/combiner.cc b/src/lib/combiner.cc index 9f9461ec2..0afb9807a 100644 --- a/src/lib/combiner.cc +++ b/src/lib/combiner.cc @@ -33,7 +33,7 @@ Combiner::Combiner (shared_ptr log) * @param image Frame image. */ void -Combiner::process_video (shared_ptr image, bool, shared_ptr, double) +Combiner::process_video (shared_ptr image, bool, shared_ptr, Time) { _image.reset (new SimpleImage (image)); } @@ -43,7 +43,7 @@ Combiner::process_video (shared_ptr image, bool, shared_ptr image, bool, shared_ptr sub, double t) +Combiner::process_video_b (shared_ptr image, bool, shared_ptr sub, Time t) { /* Copy the right half of this image into our _image */ /* XXX: this should probably be in the Image class */ diff --git a/src/lib/content.h b/src/lib/content.h index e1cf41df0..9f465570b 100644 --- a/src/lib/content.h +++ b/src/lib/content.h @@ -46,7 +46,7 @@ public: virtual std::string information () const = 0; virtual void as_xml (xmlpp::Node *) const; virtual boost::shared_ptr clone () const = 0; - virtual Time temporal_length () const = 0; + virtual Time length (boost::shared_ptr) const = 0; boost::filesystem::path file () const { boost::mutex::scoped_lock lm (_mutex); diff --git a/src/lib/decoder.h b/src/lib/decoder.h index 02ccaa42b..ae0d0c671 100644 --- a/src/lib/decoder.h +++ b/src/lib/decoder.h @@ -29,7 +29,6 @@ #include #include #include -#include "util.h" #include "video_source.h" #include "audio_source.h" #include "film.h" diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 6cb384e20..95e98ab76 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -58,7 +58,6 @@ int const Encoder::_history_size = 25; Encoder::Encoder (shared_ptr f, shared_ptr j) : _film (f) , _job (j) - , _video_frames_in (0) , _video_frames_out (0) , _have_a_real_frame (false) , _terminate (false) @@ -180,13 +179,6 @@ Encoder::frame_done () void Encoder::process_video (shared_ptr image, bool same, shared_ptr sub, Time) { - FrameRateConversion frc (_film->video_frame_rate(), _film->dcp_frame_rate()); - - if (frc.skip && (_video_frames_in % 2)) { - ++_video_frames_in; - return; - } - boost::mutex::scoped_lock lock (_mutex); /* Wait until the queue has gone down a bit */ @@ -220,7 +212,7 @@ Encoder::process_video (shared_ptr image, bool same, shared_ptrformat()->dcp_size(), _film->format()->dcp_padding (_film), _film->subtitle_offset(), _film->subtitle_scale(), - _film->scaler(), _video_frames_out, _film->dcp_frame_rate(), s.second, + _film->scaler(), _video_frames_out, _film->dcp_video_frame_rate(), s.second, _film->colour_lut(), _film->j2k_bandwidth(), _film->log() ) @@ -230,14 +222,7 @@ Encoder::process_video (shared_ptr image, bool same, shared_ptrrepeat (_video_frames_out); - ++_video_frames_out; - frame_done (); - } } void diff --git a/src/lib/encoder.h b/src/lib/encoder.h index b6d3663fd..6815fa6f6 100644 --- a/src/lib/encoder.h +++ b/src/lib/encoder.h @@ -101,8 +101,6 @@ private: /** Number of frames that we should keep history for */ static int const _history_size; - /** Number of video frames received so far */ - ContentVideoFrame _video_frames_in; /** Number of video frames written for the DCP so far */ int _video_frames_out; diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index a61f777c8..55281ff9b 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -206,7 +206,7 @@ FFmpegContent::audio_length () const return 0; } - return video_frames_to_audio_frames (_video_length, audio_frame_rate(), video_frame_rate()); + return video_frames_to_audio_frames (_video_length, content_audio_frame_rate(), video_frame_rate()); } int @@ -220,7 +220,7 @@ FFmpegContent::audio_channels () const } int -FFmpegContent::audio_frame_rate () const +FFmpegContent::content_audio_frame_rate () const { if (!_audio_stream) { return 0; @@ -229,6 +229,28 @@ FFmpegContent::audio_frame_rate () const return _audio_stream->frame_rate; } +int +FFmpegContent::output_audio_frame_rate (shared_ptr film) const +{ + /* Resample to a DCI-approved sample rate */ + double t = dcp_audio_frame_rate (content_audio_frame_rate ()); + + FrameRateConversion frc (video_frame_rate(), film->dcp_video_frame_rate()); + + /* Compensate if the DCP is being run at a different frame rate + to the source; that is, if the video is run such that it will + look different in the DCP compared to the source (slower or faster). + skip/repeat doesn't come into effect here. + */ + + if (frc.change_speed) { + t *= video_frame_rate() * frc.factor() / film->dcp_video_frame_rate(); + cout << "-> " << t << "\n"; + } + + return rint (t); +} + bool operator== (FFmpegSubtitleStream const & a, FFmpegSubtitleStream const & b) { @@ -281,8 +303,9 @@ FFmpegContent::clone () const return shared_ptr (new FFmpegContent (*this)); } -double -FFmpegContent::temporal_length () const +Time +FFmpegContent::length (shared_ptr film) const { - return video_length() / video_frame_rate(); + FrameRateConversion frc (video_frame_rate (), film->dcp_video_frame_rate ()); + return video_length() * frc.factor() * TIME_HZ / film->dcp_video_frame_rate (); } diff --git a/src/lib/ffmpeg_content.h b/src/lib/ffmpeg_content.h index 6d7151498..540df041f 100644 --- a/src/lib/ffmpeg_content.h +++ b/src/lib/ffmpeg_content.h @@ -89,12 +89,13 @@ public: std::string information () const; void as_xml (xmlpp::Node *) const; boost::shared_ptr clone () const; - double temporal_length () const; + Time length (boost::shared_ptr) const; /* AudioContent */ int audio_channels () const; ContentAudioFrame audio_length () const; - int audio_frame_rate () const; + int content_audio_frame_rate () const; + int output_audio_frame_rate (boost::shared_ptr) const; std::vector subtitle_streams () const { boost::mutex::scoped_lock lm (_mutex); diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 0e704bb14..d21a93e29 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -48,6 +48,7 @@ extern "C" { #include "ffmpeg_decoder.h" #include "filter_graph.h" #include "subtitle.h" +#include "audio_buffers.h" #include "i18n.h" @@ -219,8 +220,10 @@ FFmpegDecoder::setup_subtitle () bool FFmpegDecoder::pass () { - int r = av_read_frame (_format_context, &_packet); + cout << "FFmpeg::pass\n"; + int r = av_read_frame (_format_context, &_packet); + if (r < 0) { if (r != AVERROR_EOF) { /* Maybe we should fail here, but for now we'll just finish off instead */ diff --git a/src/lib/film.cc b/src/lib/film.cc index b8102d315..646b114da 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -108,7 +108,7 @@ Film::Film (string d, bool must_exist) , _colour_lut (0) , _j2k_bandwidth (200000000) , _dci_metadata (Config::instance()->default_dci_metadata ()) - , _dcp_frame_rate (0) + , _dcp_video_frame_rate (0) , _dirty (false) { set_dci_date_today (); @@ -179,7 +179,7 @@ Film::Film (Film const & o) , _colour_lut (o._colour_lut) , _j2k_bandwidth (o._j2k_bandwidth) , _dci_metadata (o._dci_metadata) - , _dcp_frame_rate (o._dcp_frame_rate) + , _dcp_video_frame_rate (o._dcp_video_frame_rate) , _dci_date (o._dci_date) , _dirty (o._dirty) { @@ -198,7 +198,7 @@ Film::video_state_identifier () const s << format()->id() << "_" << _playlist->video_digest() << "_" << crop().left << "_" << crop().right << "_" << crop().top << "_" << crop().bottom - << "_" << _dcp_frame_rate + << "_" << _dcp_video_frame_rate << "_" << f.first << "_" << f.second << "_" << scaler()->id() << "_" << j2k_bandwidth() @@ -315,8 +315,8 @@ Film::make_dcp () throw MissingSettingError (_("format")); } - if (_playlist->content().empty ()) { - throw MissingSettingError (_("content")); + if (_playlist->regions().empty ()) { + throw StringError (_("You must add some content to the DCP before creating it")); } if (dcp_content_type() == 0) { @@ -450,9 +450,8 @@ Film::write_metadata () const root->add_child("ColourLUT")->add_child_text (boost::lexical_cast (_colour_lut)); root->add_child("J2KBandwidth")->add_child_text (boost::lexical_cast (_j2k_bandwidth)); _dci_metadata.as_xml (root->add_child ("DCIMetadata")); - root->add_child("DCPFrameRate")->add_child_text (boost::lexical_cast (_dcp_frame_rate)); + root->add_child("DCPVideoFrameRate")->add_child_text (boost::lexical_cast (_dcp_video_frame_rate)); root->add_child("DCIDate")->add_child_text (boost::gregorian::to_iso_string (_dci_date)); - _audio_mapping.as_xml (root->add_child("AudioMapping")); _playlist->as_xml (root->add_child ("Playlist")); doc.write_to_file_formatted (file ("metadata.xml")); @@ -524,11 +523,10 @@ Film::read_metadata () _colour_lut = f.number_child ("ColourLUT"); _j2k_bandwidth = f.number_child ("J2KBandwidth"); _dci_metadata = DCIMetadata (f.node_child ("DCIMetadata")); - _dcp_frame_rate = f.number_child ("DCPFrameRate"); + _dcp_video_frame_rate = f.number_child ("DCPVideoFrameRate"); _dci_date = boost::gregorian::from_undelimited_string (f.string_child ("DCIDate")); _playlist->set_from_xml (f.node_child ("Playlist")); - _audio_mapping.set_from_xml (_playlist->content(), f.node_child ("AudioMapping")); _dirty = false; } @@ -577,32 +575,6 @@ Film::file (string f) const return p.string (); } -/** @return The sampling rate that we will resample the audio to */ -int -Film::target_audio_sample_rate () const -{ - if (!has_audio ()) { - return 0; - } - - /* Resample to a DCI-approved sample rate */ - double t = dcp_audio_sample_rate (audio_frame_rate()); - - FrameRateConversion frc (video_frame_rate(), dcp_frame_rate()); - - /* Compensate if the DCP is being run at a different frame rate - to the source; that is, if the video is run such that it will - look different in the DCP compared to the source (slower or faster). - skip/repeat doesn't come into effect here. - */ - - if (frc.change_speed) { - t *= video_frame_rate() * frc.factor() / dcp_frame_rate(); - } - - return rint (t); -} - /** @return a DCI-compliant name for a DCP of this film */ string Film::dci_name (bool if_created_now) const @@ -649,22 +621,7 @@ Film::dci_name (bool if_created_now) const } } - switch (audio_channels ()) { - case 1: - d << "_10"; - break; - case 2: - d << "_20"; - break; - case 6: - d << "_51"; - break; - case 8: - d << "_71"; - break; - } - - d << "_2K"; + d << "_51_2K"; if (!dm.studio.empty ()) { d << "_" << dm.studio; @@ -738,11 +695,11 @@ Film::set_trust_content_headers (bool t) signal_changed (TRUST_CONTENT_HEADERS); - ContentList content = _playlist->content (); - if (!_trust_content_headers && !content.empty()) { + Playlist::RegionList regions = _playlist->regions (); + if (!_trust_content_headers && !regions.empty()) { /* We just said that we don't trust the content's header */ - for (ContentList::iterator i = content.begin(); i != content.end(); ++i) { - examine_content (*i); + for (Playlist::RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { + examine_content (i->content); } } } @@ -976,13 +933,13 @@ Film::set_dci_metadata (DCIMetadata m) void -Film::set_dcp_frame_rate (int f) +Film::set_dcp_video_frame_rate (int f) { { boost::mutex::scoped_lock lm (_state_mutex); - _dcp_frame_rate = f; + _dcp_video_frame_rate = f; } - signal_changed (DCP_FRAME_RATE); + signal_changed (DCP_VIDEO_FRAME_RATE); } void @@ -995,8 +952,7 @@ Film::signal_changed (Property p) switch (p) { case Film::CONTENT: - set_dcp_frame_rate (best_dcp_frame_rate (video_frame_rate ())); - set_audio_mapping (_playlist->default_audio_mapping ()); + set_dcp_video_frame_rate (_playlist->best_dcp_frame_rate ()); break; default: break; @@ -1082,10 +1038,10 @@ Film::playlist () const return _playlist; } -ContentList -Film::content () const +Playlist::RegionList +Film::regions () const { - return _playlist->content (); + return _playlist->regions (); } void @@ -1101,64 +1057,10 @@ Film::remove_content (shared_ptr c) _playlist->remove (c); } -void -Film::move_content_earlier (shared_ptr c) -{ - _playlist->move_earlier (c); -} - -void -Film::move_content_later (shared_ptr c) -{ - _playlist->move_later (c); -} - -ContentAudioFrame -Film::audio_length () const -{ - return _playlist->audio_length (); -} - -int -Film::audio_channels () const -{ - return _playlist->audio_channels (); -} - -int -Film::audio_frame_rate () const -{ - return _playlist->audio_frame_rate (); -} - -bool -Film::has_audio () const -{ - return _playlist->has_audio (); -} - -float -Film::video_frame_rate () const -{ - return _playlist->video_frame_rate (); -} - -libdcp::Size -Film::video_size () const +Time +Film::length () const { - return _playlist->video_size (); -} - -ContentVideoFrame -Film::video_length () const -{ - return _playlist->video_length (); -} - -ContentVideoFrame -Film::content_length () const -{ - return _playlist->content_length (); + return _playlist->length (shared_from_this ()); } bool @@ -1167,24 +1069,17 @@ Film::has_subtitles () const return _playlist->has_subtitles (); } -void -Film::set_audio_mapping (AudioMapping m) +OutputVideoFrame +Film::best_dcp_video_frame_rate () const { - { - boost::mutex::scoped_lock lm (_state_mutex); - _audio_mapping = m; - } - - signal_changed (AUDIO_MAPPING); + return _playlist->best_dcp_frame_rate (); } void Film::playlist_content_changed (boost::weak_ptr c, int p) { if (p == VideoContentProperty::VIDEO_FRAME_RATE) { - set_dcp_frame_rate (best_dcp_frame_rate (video_frame_rate ())); - } else if (p == AudioContentProperty::AUDIO_CHANNELS) { - set_audio_mapping (_playlist->default_audio_mapping ()); + set_dcp_video_frame_rate (_playlist->best_dcp_frame_rate ()); } if (ui_signaller) { @@ -1209,3 +1104,34 @@ Film::set_loop (int c) { _playlist->set_loop (c); } + +OutputAudioFrame +Film::time_to_audio_frames (Time t) const +{ + return t * dcp_audio_frame_rate () / TIME_HZ; +} + +OutputVideoFrame +Film::time_to_video_frames (Time t) const +{ + return t * dcp_video_frame_rate () / TIME_HZ; +} + +Time +Film::audio_frames_to_time (OutputAudioFrame f) const +{ + return f * TIME_HZ / dcp_audio_frame_rate (); +} + +Time +Film::video_frames_to_time (OutputVideoFrame f) const +{ + return f * TIME_HZ / dcp_video_frame_rate (); +} + +OutputAudioFrame +Film::dcp_audio_frame_rate () const +{ + /* XXX */ + return 48000; +} diff --git a/src/lib/film.h b/src/lib/film.h index 18255a15e..cfc55c0ac 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -36,7 +36,7 @@ #include "dci_metadata.h" #include "types.h" #include "ffmpeg_content.h" -#include "audio_mapping.h" +#include "playlist.h" class DCPContentType; class Format; @@ -48,7 +48,6 @@ class AnalyseAudioJob; class ExternalAudioStream; class Content; class Player; -class Playlist; /** @class Film * @brief A representation of some audio and video content, and details of @@ -87,8 +86,6 @@ public: std::string file (std::string f) const; std::string dir (std::string d) const; - int target_audio_sample_rate () const; - void write_metadata () const; libdcp::Size cropped_size (libdcp::Size) const; @@ -105,27 +102,24 @@ public: boost::shared_ptr player () const; boost::shared_ptr playlist () const; - /* Proxies for some Playlist methods */ + OutputAudioFrame dcp_audio_frame_rate () const; - ContentList content () const; + OutputAudioFrame time_to_audio_frames (Time) const; + OutputVideoFrame time_to_video_frames (Time) const; + Time video_frames_to_time (OutputVideoFrame) const; + Time audio_frames_to_time (OutputAudioFrame) const; - ContentAudioFrame audio_length () const; - int audio_channels () const; - int audio_frame_rate () const; - bool has_audio () const; + /* Proxies for some Playlist methods */ - bool has_subtitles () const; - - float video_frame_rate () const; - libdcp::Size video_size () const; - ContentVideoFrame video_length () const; + Playlist::RegionList regions () const; - ContentVideoFrame content_length () const; + Time length () const; + bool has_subtitles () const; + OutputVideoFrame best_dcp_video_frame_rate () const; void set_loop (int); int loop () const; - enum TrimType { CPL, ENCODE @@ -159,7 +153,7 @@ public: COLOUR_LUT, J2K_BANDWIDTH, DCI_METADATA, - DCP_FRAME_RATE, + DCP_VIDEO_FRAME_RATE, AUDIO_MAPPING }; @@ -271,14 +265,10 @@ public: return _dci_metadata; } - int dcp_frame_rate () const { - boost::mutex::scoped_lock lm (_state_mutex); - return _dcp_frame_rate; - } - - AudioMapping audio_mapping () const { + /* XXX: -> "video_frame_rate" */ + int dcp_video_frame_rate () const { boost::mutex::scoped_lock lm (_state_mutex); - return _audio_mapping; + return _dcp_video_frame_rate; } /* SET */ @@ -289,8 +279,6 @@ public: void set_trust_content_headers (bool); void add_content (boost::shared_ptr); void remove_content (boost::shared_ptr); - void move_content_earlier (boost::shared_ptr); - void move_content_later (boost::shared_ptr); void set_dcp_content_type (DCPContentType const *); void set_format (Format const *); void set_crop (Crop); @@ -312,9 +300,8 @@ public: void set_colour_lut (int); void set_j2k_bandwidth (int); void set_dci_metadata (DCIMetadata); - void set_dcp_frame_rate (int); + void set_dcp_video_frame_rate (int); void set_dci_date_today (); - void set_audio_mapping (AudioMapping); /** Emitted when some property has of the Film has changed */ mutable boost::signals2::signal Changed; @@ -398,10 +385,9 @@ private: /** DCI naming stuff */ DCIMetadata _dci_metadata; /** Frames per second to run our DCP at */ - int _dcp_frame_rate; + int _dcp_video_frame_rate; /** The date that we should use in a DCI name */ boost::gregorian::date _dci_date; - AudioMapping _audio_mapping; /** true if our state has changed since we last saved it */ mutable bool _dirty; diff --git a/src/lib/format.cc b/src/lib/format.cc index f5026c0da..688b22f16 100644 --- a/src/lib/format.cc +++ b/src/lib/format.cc @@ -208,7 +208,8 @@ VariableFormat::VariableFormat (libdcp::Size dcp, string id, string n, string d) float VariableFormat::ratio (shared_ptr f) const { - libdcp::Size const c = f->cropped_size (f->video_size ()); + /* XXX */ + libdcp::Size const c;// = f->cropped_size (f->video_size ()); return float (c.width) / c.height; } diff --git a/src/lib/format.h b/src/lib/format.h index d45a3a10a..29347a3fd 100644 --- a/src/lib/format.h +++ b/src/lib/format.h @@ -24,7 +24,7 @@ #include #include -#include "util.h" +#include class Film; diff --git a/src/lib/imagemagick_content.cc b/src/lib/imagemagick_content.cc index 9e5f00ba0..2e42e25f3 100644 --- a/src/lib/imagemagick_content.cc +++ b/src/lib/imagemagick_content.cc @@ -98,3 +98,10 @@ ImageMagickContent::set_video_length (ContentVideoFrame len) signal_changed (VideoContentProperty::VIDEO_LENGTH); } + +Time +ImageMagickContent::length (shared_ptr film) const +{ + FrameRateConversion frc (24, film->dcp_video_frame_rate ()); + return video_length() * frc.factor() * TIME_HZ / film->dcp_video_frame_rate (); +} diff --git a/src/lib/imagemagick_content.h b/src/lib/imagemagick_content.h index b1e7f9495..366049002 100644 --- a/src/lib/imagemagick_content.h +++ b/src/lib/imagemagick_content.h @@ -38,6 +38,7 @@ public: std::string summary () const; void as_xml (xmlpp::Node *) const; boost::shared_ptr clone () const; + Time length (boost::shared_ptr) const; void set_video_length (ContentVideoFrame); diff --git a/src/lib/player.cc b/src/lib/player.cc index 95036cfe0..9cc166204 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -27,9 +27,11 @@ #include "sndfile_content.h" #include "playlist.h" #include "job.h" +#include "image.h" using std::list; using std::cout; +using std::min; using std::vector; using boost::shared_ptr; using boost::weak_ptr; @@ -42,6 +44,11 @@ Player::Player (shared_ptr f, shared_ptr p) , _audio (true) , _subtitles (true) , _have_valid_decoders (false) + , _position (0) + , _audio_buffers (MAX_AUDIO_CHANNELS, 0) + , _last_video (0) + , _last_was_black (false) + , _last_audio (0) { _playlist->Changed.connect (bind (&Player::playlist_changed, this)); _playlist->ContentChanged.connect (bind (&Player::content_changed, this, _1, _2)); @@ -72,118 +79,118 @@ Player::pass () setup_decoders (); _have_valid_decoders = true; } - - bool done = true; - - if (_video && _video_decoder < _video_decoders.size ()) { - - /* Run video decoder; this may also produce audio */ - - if (_video_decoders[_video_decoder]->pass ()) { - _video_decoder++; - } - - if (_video_decoder < _video_decoders.size ()) { - done = false; - } - - } - - if (!_video && _audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG && _sequential_audio_decoder < _audio_decoders.size ()) { - - /* We're not producing video, so we may need to run FFmpeg content to get the audio */ - - if (_audio_decoders[_sequential_audio_decoder]->pass ()) { - _sequential_audio_decoder++; - } - - if (_sequential_audio_decoder < _audio_decoders.size ()) { - done = false; - } - - } - - if (_audio && _playlist->audio_from() == Playlist::AUDIO_SNDFILE) { - - /* We're getting audio from SndfileContent */ - - for (vector >::iterator i = _audio_decoders.begin(); i != _audio_decoders.end(); ++i) { - if (!(*i)->pass ()) { - done = false; - } - } - Audio (_audio_buffers, _audio_time.get()); - _audio_buffers.reset (); - _audio_time = boost::none; - } - - return done; + cout << "-> Player::pass\n"; + + /* Here we are just finding the active decoder with the earliest last emission time, then + calling pass on it. If there is no decoder, we skip our position on until there is. + Hence this method will cause video and audio to be emitted, and it is up to the + process_{video,audio} methods to tidy it up. + */ + + Time earliest_pos = TIME_MAX; + shared_ptr earliest; + Time next_wait = TIME_MAX; + + for (list >::iterator i = _decoders.begin(); i != _decoders.end(); ++i) { + Time const ts = (*i)->region.time; + Time const te = (*i)->region.time + (*i)->region.content->length (_film); + if (ts <= _position && te > _position) { + Time const pos = ts + (*i)->last; + if (pos < earliest_pos) { + earliest_pos = pos; + earliest = *i; + } + } + + if (ts > _position) { + next_wait = min (next_wait, ts - _position); + } + } + + if (earliest) { + earliest->decoder->pass (); + _position = earliest->last; + } else if (next_wait < TIME_MAX) { + _position += next_wait; + } else { + cout << "<- Player::pass\n"; + return true; + } + + cout << "<- Player::pass\n"; + return false; } void -Player::process_video (shared_ptr i, bool same, shared_ptr s, double t) +Player::process_video (shared_ptr rd, shared_ptr image, bool same, shared_ptr sub, Time time) { - Video (i, same, s, _video_start[_video_decoder] + t); + shared_ptr vd = dynamic_pointer_cast (rd->decoder); + + Time const global_time = rd->region.time + time; + while ((global_time - _last_video) > 1) { + /* Fill in with black */ + emit_black_frame (); + } + + Video (image, same, sub, global_time); + rd->last = time; + _last_video = global_time; + _last_was_black = false; } void -Player::process_audio (weak_ptr c, shared_ptr b, double t) +Player::process_audio (shared_ptr rd, shared_ptr audio, Time time) { - AudioMapping mapping = _film->audio_mapping (); - if (!_audio_buffers) { - _audio_buffers.reset (new AudioBuffers (mapping.dcp_channels(), b->frames ())); - _audio_buffers->make_silent (); - _audio_time = t; - if (_playlist->audio_from() == Playlist::AUDIO_FFMPEG) { - _audio_time = _audio_time.get() + _audio_start[_sequential_audio_decoder]; - } - } - - for (int i = 0; i < b->channels(); ++i) { - list dcp = mapping.content_to_dcp (AudioMapping::Channel (c, i)); - for (list::iterator j = dcp.begin(); j != dcp.end(); ++j) { - _audio_buffers->accumulate (b, i, static_cast (*j)); - } - } - - if (_playlist->audio_from() == Playlist::AUDIO_FFMPEG) { - /* We can just emit this audio now as it will all be here */ - Audio (_audio_buffers, t); - _audio_buffers.reset (); - _audio_time = boost::none; - } + /* XXX: mapping */ + + /* The time of this audio may indicate that some of our buffered audio is not going to + be added to any more, so it can be emitted. + */ + + if (time > _last_audio) { + /* We can emit some audio from our buffers */ + OutputAudioFrame const N = min (_film->time_to_audio_frames (time - _last_audio), static_cast (_audio_buffers.frames())); + shared_ptr emit (new AudioBuffers (_audio_buffers.channels(), N)); + emit->copy_from (&_audio_buffers, N, 0, 0); + Audio (emit, _last_audio); + _last_audio += _film->audio_frames_to_time (N); + + /* And remove it from our buffers */ + if (_audio_buffers.frames() > N) { + _audio_buffers.move (N, 0, _audio_buffers.frames() - N); + } + _audio_buffers.set_frames (_audio_buffers.frames() - N); + } + + /* Now accumulate the new audio into our buffers */ + + if (_audio_buffers.frames() == 0) { + /* We have no remaining data. Emit silence up to the start of this new data */ + if ((time - _last_audio) > 0) { + emit_silence (time - _last_audio); + } + } + + _audio_buffers.ensure_size (time - _last_audio + audio->frames()); + _audio_buffers.accumulate (audio.get(), 0, _film->time_to_audio_frames (time - _last_audio)); + rd->last = time + _film->audio_frames_to_time (audio->frames ()); } /** @return true on error */ bool -Player::seek (double t) +Player::seek (Time t) { if (!_have_valid_decoders) { setup_decoders (); _have_valid_decoders = true; } - if (_video_decoders.empty ()) { + if (_decoders.empty ()) { return true; } - /* Find the decoder that contains this position */ - _video_decoder = 0; - while (1) { - ++_video_decoder; - if (_video_decoder >= _video_decoders.size () || t < _video_start[_video_decoder]) { - --_video_decoder; - t -= _video_start[_video_decoder]; - break; - } - } - - if (_video_decoder < _video_decoders.size()) { - _video_decoders[_video_decoder]->seek (t); - } else { - return true; - } + /* XXX */ /* XXX: don't seek audio because we don't need to... */ @@ -207,106 +214,60 @@ Player::seek_forward () void Player::setup_decoders () { - vector > old_video_decoders = _video_decoders; + list > old_decoders = _decoders; - _video_decoders.clear (); - _video_decoder = 0; - _audio_decoders.clear (); - _sequential_audio_decoder = 0; + _decoders.clear (); - _video_start.clear(); - _audio_start.clear(); + Playlist::RegionList regions = _playlist->regions (); + for (Playlist::RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { - double video_so_far = 0; - double audio_so_far = 0; + shared_ptr rd (new RegionDecoder); + rd->region = *i; + + /* XXX: into content? */ - for (int l = 0; l < _playlist->loop(); ++l) { - list > vc = _playlist->video (); - for (list >::iterator i = vc.begin(); i != vc.end(); ++i) { - - shared_ptr video_content; - shared_ptr audio_content; - shared_ptr video_decoder; - shared_ptr audio_decoder; - - /* XXX: into content? */ + shared_ptr fc = dynamic_pointer_cast (i->content); + if (fc) { + shared_ptr fd (new FFmpegDecoder (_film, fc, _video, _audio, _subtitles)); - shared_ptr fc = dynamic_pointer_cast (*i); - if (fc) { - shared_ptr fd ( - new FFmpegDecoder ( - _film, fc, _video, - _audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG, - _subtitles - ) - ); - - video_content = fc; - audio_content = fc; - video_decoder = fd; - audio_decoder = fd; - - video_decoder->connect_video (shared_from_this ()); - } - - shared_ptr ic = dynamic_pointer_cast (*i); - if (ic) { - video_content = ic; - - /* See if we can re-use an old ImageMagickDecoder */ - for (vector >::const_iterator i = old_video_decoders.begin(); i != old_video_decoders.end(); ++i) { - shared_ptr imd = dynamic_pointer_cast (*i); - if (imd && imd->content() == ic) { - video_decoder = *i; - } - } + fd->Video.connect (bind (&Player::process_video, this, rd, _1, _2, _3, _4)); + fd->Audio.connect (bind (&Player::process_audio, this, rd, _1, _2)); - if (!video_decoder) { - video_decoder.reset (new ImageMagickDecoder (_film, ic)); - video_decoder->connect_video (shared_from_this ()); - } - } - - _video_decoders.push_back (video_decoder); - _video_start.push_back (video_so_far); - video_so_far += video_content->video_length() / video_content->video_frame_rate(); - - if (audio_decoder && _playlist->audio_from() == Playlist::AUDIO_FFMPEG) { - audio_decoder->Audio.connect (bind (&Player::process_audio, this, audio_content, _1, _2)); - _audio_decoders.push_back (audio_decoder); - _audio_start.push_back (audio_so_far); - audio_so_far += double(audio_content->audio_length()) / audio_content->audio_frame_rate(); - } + rd->decoder = fd; } - _video_decoder = 0; - _sequential_audio_decoder = 0; - - if (_playlist->audio_from() == Playlist::AUDIO_SNDFILE) { + shared_ptr ic = dynamic_pointer_cast (i->content); + if (ic) { + shared_ptr id; - list > ac = _playlist->audio (); - for (list >::iterator i = ac.begin(); i != ac.end(); ++i) { - - shared_ptr sc = dynamic_pointer_cast (*i); - assert (sc); - - shared_ptr d (new SndfileDecoder (_film, sc)); - d->Audio.connect (bind (&Player::process_audio, this, sc, _1, _2)); - _audio_decoders.push_back (d); - _audio_start.push_back (audio_so_far); + /* See if we can re-use an old ImageMagickDecoder */ + for (list >::const_iterator i = old_decoders.begin(); i != old_decoders.end(); ++i) { + shared_ptr imd = dynamic_pointer_cast ((*i)->decoder); + if (imd && imd->content() == ic) { + id = imd; + } + } + + if (!id) { + id.reset (new ImageMagickDecoder (_film, ic)); + id->Video.connect (bind (&Player::process_video, this, rd, _1, _2, _3, _4)); } + + rd->decoder = id; } - } -} -double -Player::last_video_time () const -{ - if (_video_decoder >= _video_decoders.size ()) { - return 0; + shared_ptr sc = dynamic_pointer_cast (i->content); + if (sc) { + shared_ptr sd (new SndfileDecoder (_film, sc)); + sd->Audio.connect (bind (&Player::process_audio, this, rd, _1, _2)); + + rd->decoder = sd; + } + + _decoders.push_back (rd); } - - return _video_start[_video_decoder] + _video_decoders[_video_decoder]->last_content_time (); + + _position = 0; } void @@ -327,3 +288,26 @@ Player::playlist_changed () { _have_valid_decoders = false; } + +void +Player::emit_black_frame () +{ + shared_ptr image (new SimpleImage (AV_PIX_FMT_RGB24, libdcp::Size (128, 128), true)); + Video (image, _last_was_black, shared_ptr (), _last_video); + _last_video += _film->video_frames_to_time (1); +} + +void +Player::emit_silence (Time t) +{ + OutputAudioFrame frames = _film->time_to_audio_frames (t); + while (frames) { + /* Do this in half-second chunks so we don't overwhelm anybody */ + OutputAudioFrame this_time = min (_film->dcp_audio_frame_rate() / 2, frames); + shared_ptr silence (new AudioBuffers (MAX_AUDIO_CHANNELS, this_time)); + silence->make_silent (); + Audio (silence, _last_audio); + _last_audio += _film->audio_frames_to_time (this_time); + frames -= this_time; + } +} diff --git a/src/lib/player.h b/src/lib/player.h index b1be2f456..c9bf2a00b 100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@ -27,19 +27,20 @@ #include "audio_source.h" #include "video_sink.h" #include "audio_sink.h" +#include "playlist.h" +#include "audio_buffers.h" -class VideoDecoder; -class AudioDecoder; class Job; class Film; class Playlist; class AudioContent; +class Decoder; /** @class Player * @brief A class which can `play' a Playlist; emitting its audio and video. */ -class Player : public VideoSource, public AudioSource, public VideoSink, public boost::enable_shared_from_this +class Player : public VideoSource, public AudioSource, public boost::enable_shared_from_this { public: Player (boost::shared_ptr, boost::shared_ptr); @@ -49,18 +50,34 @@ public: void disable_subtitles (); bool pass (); - bool seek (double); + bool seek (Time); void seek_back (); void seek_forward (); - double last_video_time () const; + Time last_video () const { + return _last_video; + } private: - void process_video (boost::shared_ptr i, bool same, boost::shared_ptr s, double); - void process_audio (boost::weak_ptr, boost::shared_ptr, double); + + struct RegionDecoder + { + RegionDecoder () + : last (0) + {} + + Playlist::Region region; + boost::shared_ptr decoder; + Time last; + }; + + void process_video (boost::shared_ptr, boost::shared_ptr, bool, boost::shared_ptr, Time); + void process_audio (boost::shared_ptr, boost::shared_ptr, Time); void setup_decoders (); void playlist_changed (); void content_changed (boost::weak_ptr, int); + void emit_black_frame (); + void emit_silence (Time); boost::shared_ptr _film; boost::shared_ptr _playlist; @@ -71,21 +88,13 @@ private: /** Our decoders are ready to go; if this is false the decoders must be (re-)created before they are used */ bool _have_valid_decoders; - /** Video decoders in order of presentation */ - std::vector > _video_decoders; - /** Start positions of each video decoder in seconds*/ - std::vector _video_start; - /** Index of current video decoder */ - size_t _video_decoder; - /** Audio decoders in order of presentation (if they are from FFmpeg) */ - std::vector > _audio_decoders; - /** Start positions of each audio decoder (if they are from FFmpeg) in seconds */ - std::vector _audio_start; - /** Current audio decoder index if we are running them sequentially; otherwise undefined */ - size_t _sequential_audio_decoder; - - boost::shared_ptr _audio_buffers; - boost::optional _audio_time; + std::list > _decoders; + + Time _position; + AudioBuffers _audio_buffers; + Time _last_video; + bool _last_was_black; + Time _last_audio; }; #endif diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index f1dd881b3..8f4a35ac2 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -29,6 +29,8 @@ #include "imagemagick_decoder.h" #include "imagemagick_content.h" #include "job.h" +#include "config.h" +#include "util.h" #include "i18n.h" @@ -39,171 +41,24 @@ using std::min; using std::max; using std::string; using std::stringstream; +using boost::optional; using boost::shared_ptr; using boost::weak_ptr; using boost::dynamic_pointer_cast; using boost::lexical_cast; Playlist::Playlist () - : _audio_from (AUDIO_FFMPEG) - , _loop (1) + : _loop (1) { } Playlist::Playlist (shared_ptr other) - : _audio_from (other->_audio_from) - , _loop (other->_loop) + : _loop (other->_loop) { - for (ContentList::const_iterator i = other->_content.begin(); i != other->_content.end(); ++i) { - _content.push_back ((*i)->clone ()); + for (RegionList::const_iterator i = other->_regions.begin(); i != other->_regions.end(); ++i) { + _regions.push_back (Region (i->content->clone(), i->time, this)); } - - setup (); -} - -void -Playlist::setup () -{ - _audio_from = AUDIO_FFMPEG; - - _video.clear (); - _audio.clear (); - - for (list::iterator i = _content_connections.begin(); i != _content_connections.end(); ++i) { - i->disconnect (); - } - - _content_connections.clear (); - - for (ContentList::const_iterator i = _content.begin(); i != _content.end(); ++i) { - - /* Video is video */ - shared_ptr vc = dynamic_pointer_cast (*i); - if (vc) { - _video.push_back (vc); - } - - /* FFmpegContent is audio if we are doing AUDIO_FFMPEG */ - shared_ptr fc = dynamic_pointer_cast (*i); - if (fc && _audio_from == AUDIO_FFMPEG) { - _audio.push_back (fc); - } - - /* SndfileContent trumps FFmpegContent for audio */ - shared_ptr sc = dynamic_pointer_cast (*i); - if (sc) { - if (_audio_from == AUDIO_FFMPEG) { - /* This is our fist SndfileContent; clear any FFmpegContent and - say that we are using Sndfile. - */ - _audio.clear (); - _audio_from = AUDIO_SNDFILE; - } - - _audio.push_back (sc); - } - - _content_connections.push_back ((*i)->Changed.connect (bind (&Playlist::content_changed, this, _1, _2))); - } -} - -/** @return Length of our audio */ -ContentAudioFrame -Playlist::audio_length () const -{ - ContentAudioFrame len = 0; - - switch (_audio_from) { - case AUDIO_FFMPEG: - /* FFmpeg content is sequential */ - for (list >::const_iterator i = _audio.begin(); i != _audio.end(); ++i) { - len += (*i)->audio_length (); - } - break; - case AUDIO_SNDFILE: - /* Sndfile content is simultaneous */ - for (list >::const_iterator i = _audio.begin(); i != _audio.end(); ++i) { - len = max (len, (*i)->audio_length ()); - } - break; - } - - return len * _loop; -} - -/** @return number of audio channels */ -int -Playlist::audio_channels () const -{ - int channels = 0; - - switch (_audio_from) { - case AUDIO_FFMPEG: - /* FFmpeg audio is sequential, so use the maximum channel count */ - for (list >::const_iterator i = _audio.begin(); i != _audio.end(); ++i) { - channels = max (channels, (*i)->audio_channels ()); - } - break; - case AUDIO_SNDFILE: - /* Sndfile audio is simultaneous, so it's the sum of the channel counts */ - for (list >::const_iterator i = _audio.begin(); i != _audio.end(); ++i) { - channels += (*i)->audio_channels (); - } - break; - } - - return channels; -} - -int -Playlist::audio_frame_rate () const -{ - if (_audio.empty ()) { - return 0; - } - - /* XXX: assuming that all content has the same rate */ - return _audio.front()->audio_frame_rate (); -} - -float -Playlist::video_frame_rate () const -{ - if (_video.empty ()) { - return 0; - } - - /* XXX: assuming all the same */ - return _video.front()->video_frame_rate (); -} - -libdcp::Size -Playlist::video_size () const -{ - if (_video.empty ()) { - return libdcp::Size (); - } - - /* XXX: assuming all the same */ - return _video.front()->video_size (); -} - -ContentVideoFrame -Playlist::video_length () const -{ - ContentVideoFrame len = 0; - for (list >::const_iterator i = _video.begin(); i != _video.end(); ++i) { - len += (*i)->video_length (); - } - - return len * _loop; -} - -bool -Playlist::has_audio () const -{ - return !_audio.empty (); } void @@ -212,62 +67,19 @@ Playlist::content_changed (weak_ptr c, int p) ContentChanged (c, p); } -AudioMapping -Playlist::default_audio_mapping () const -{ - AudioMapping m; - if (_audio.empty ()) { - return m; - } - - switch (_audio_from) { - case AUDIO_FFMPEG: - { - /* XXX: assumes all the same */ - if (_audio.front()->audio_channels() == 1) { - /* Map mono sources to centre */ - m.add (AudioMapping::Channel (_audio.front(), 0), libdcp::CENTRE); - } else { - int const N = min (_audio.front()->audio_channels (), MAX_AUDIO_CHANNELS); - /* Otherwise just start with a 1:1 mapping */ - for (int i = 0; i < N; ++i) { - m.add (AudioMapping::Channel (_audio.front(), i), (libdcp::Channel) i); - } - } - break; - } - - case AUDIO_SNDFILE: - { - int n = 0; - for (list >::const_iterator i = _audio.begin(); i != _audio.end(); ++i) { - for (int j = 0; j < (*i)->audio_channels(); ++j) { - m.add (AudioMapping::Channel (*i, j), (libdcp::Channel) n); - ++n; - if (n >= MAX_AUDIO_CHANNELS) { - break; - } - } - if (n >= MAX_AUDIO_CHANNELS) { - break; - } - } - break; - } - } - - return m; -} - string Playlist::audio_digest () const { string t; - for (list >::const_iterator i = _audio.begin(); i != _audio.end(); ++i) { - t += (*i)->digest (); + for (RegionList::const_iterator i = _regions.begin(); i != _regions.end(); ++i) { + if (!dynamic_pointer_cast (i->content)) { + continue; + } + + t += i->content->digest (); - shared_ptr fc = dynamic_pointer_cast (*i); + shared_ptr fc = dynamic_pointer_cast (i->content); if (fc) { t += lexical_cast (fc->audio_stream()->id); } @@ -283,9 +95,13 @@ Playlist::video_digest () const { string t; - for (list >::const_iterator i = _video.begin(); i != _video.end(); ++i) { - t += (*i)->digest (); - shared_ptr fc = dynamic_pointer_cast (*i); + for (RegionList::const_iterator i = _regions.begin(); i != _regions.end(); ++i) { + if (!dynamic_pointer_cast (i->content)) { + continue; + } + + t += i->content->digest (); + shared_ptr fc = dynamic_pointer_cast (i->content); if (fc && fc->subtitle_stream()) { t += fc->subtitle_stream()->id; } @@ -296,48 +112,22 @@ Playlist::video_digest () const return md5_digest (t.c_str(), t.length()); } -ContentVideoFrame -Playlist::content_length () const -{ - float const vfr = video_frame_rate() > 0 ? video_frame_rate() : 24; - int const afr = audio_frame_rate() > 0 ? audio_frame_rate() : 48000; - - return max ( - video_length(), - ContentVideoFrame (audio_length() * vfr / afr) - ); -} - void Playlist::set_from_xml (shared_ptr node) { - list > c = node->node_children ("Content"); + list > c = node->node_children ("Region"); for (list >::iterator i = c.begin(); i != c.end(); ++i) { - - string const type = (*i)->string_child ("Type"); - boost::shared_ptr c; - - if (type == "FFmpeg") { - c.reset (new FFmpegContent (*i)); - } else if (type == "ImageMagick") { - c.reset (new ImageMagickContent (*i)); - } else if (type == "Sndfile") { - c.reset (new SndfileContent (*i)); - } - - _content.push_back (c); + _regions.push_back (Region (*i, this)); } _loop = node->number_child ("Loop"); - - setup (); } void Playlist::as_xml (xmlpp::Node* node) { - for (ContentList::iterator i = _content.begin(); i != _content.end(); ++i) { - (*i)->as_xml (node->add_child ("Content")); + for (RegionList::iterator i = _regions.begin(); i != _regions.end(); ++i) { + i->as_xml (node->add_child ("Region")); } node->add_child("Loop")->add_child_text(lexical_cast (_loop)); @@ -346,87 +136,146 @@ Playlist::as_xml (xmlpp::Node* node) void Playlist::add (shared_ptr c) { - _content.push_back (c); - setup (); + _regions.push_back (Region (c, 0, this)); Changed (); } void Playlist::remove (shared_ptr c) { - ContentList::iterator i = find (_content.begin(), _content.end(), c); - if (i != _content.end ()) { - _content.erase (i); + RegionList::iterator i = _regions.begin (); + while (i != _regions.end() && i->content != c) { + ++i; } + + if (i != _regions.end ()) { + _regions.erase (i); + Changed (); + } +} - setup (); +void +Playlist::set_loop (int l) +{ + _loop = l; Changed (); } -void -Playlist::move_earlier (shared_ptr c) +bool +Playlist::has_subtitles () const { - ContentList::iterator i = find (_content.begin(), _content.end(), c); - if (i == _content.begin () || i == _content.end()) { - return; + for (RegionList::const_iterator i = _regions.begin(); i != _regions.end(); ++i) { + shared_ptr fc = dynamic_pointer_cast (i->content); + if (fc && !fc->subtitle_streams().empty()) { + return true; + } } - ContentList::iterator j = i; - --j; - - swap (*i, *j); - - setup (); - Changed (); + return false; } -void -Playlist::move_later (shared_ptr c) +Playlist::Region::Region (shared_ptr c, Time t, Playlist* p) + : content (c) + , time (t) { - ContentList::iterator i = find (_content.begin(), _content.end(), c); - if (i == _content.end()) { - return; - } + connection = c->Changed.connect (bind (&Playlist::content_changed, p, _1, _2)); +} - ContentList::iterator j = i; - ++j; - if (j == _content.end ()) { - return; +Playlist::Region::Region (shared_ptr node, Playlist* p) +{ + shared_ptr content_node = node->node_child ("Content"); + string const type = content_node->string_child ("Type"); + + if (type == "FFmpeg") { + content.reset (new FFmpegContent (content_node)); + } else if (type == "ImageMagick") { + content.reset (new ImageMagickContent (content_node)); + } else if (type == "Sndfile") { + content.reset (new SndfileContent (content_node)); } - swap (*i, *j); - - setup (); - Changed (); + time = node->number_child