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/external_audio_decoder.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib/external_audio_decoder.cc') 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) { -- 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/lib/external_audio_decoder.cc') 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 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/lib/external_audio_decoder.cc') 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 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/lib/external_audio_decoder.cc') 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 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/lib/external_audio_decoder.cc') 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 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/lib/external_audio_decoder.cc') 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