summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2013-04-15 15:00:35 +0100
committerCarl Hetherington <cth@carlh.net>2013-04-15 15:00:35 +0100
commita00ebbc68438e84076c65e99d0e70403afb4407d (patch)
tree6ee2f535eeb6b592c740e117d1f8f8657d6bcce8 /src/lib
parent665bc942f86bd7a8aeb2b38f3e9c2cb6662e6edc (diff)
parent606b3f759238aa6c0d12de064b301bf36b428220 (diff)
Merge master.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/ab_transcoder.cc21
-rw-r--r--src/lib/analyse_audio_job.cc3
-rw-r--r--src/lib/audio_decoder.h2
-rw-r--r--src/lib/audio_sink.h7
-rw-r--r--src/lib/audio_source.cc6
-rw-r--r--src/lib/audio_source.h12
-rw-r--r--src/lib/combiner.cc10
-rw-r--r--src/lib/combiner.h8
-rw-r--r--src/lib/config.cc23
-rw-r--r--src/lib/config.h14
-rw-r--r--src/lib/dcp_video_frame.cc4
-rw-r--r--src/lib/dcp_video_frame.h4
-rw-r--r--src/lib/decoder_factory.cc6
-rw-r--r--src/lib/delay_line.cc4
-rw-r--r--src/lib/delay_line.h2
-rw-r--r--src/lib/encoder.cc14
-rw-r--r--src/lib/exceptions.cc63
-rw-r--r--src/lib/exceptions.h29
-rw-r--r--src/lib/film.cc160
-rw-r--r--src/lib/film.h38
-rw-r--r--src/lib/format.cc56
-rw-r--r--src/lib/format.h12
-rw-r--r--src/lib/gain.cc4
-rw-r--r--src/lib/gain.h4
-rw-r--r--src/lib/image.cc32
-rw-r--r--src/lib/imagemagick_decoder.h4
-rw-r--r--src/lib/job.cc30
-rw-r--r--src/lib/job.h14
-rw-r--r--src/lib/matcher.cc4
-rw-r--r--src/lib/matcher.h8
-rw-r--r--src/lib/po/es_ES.po626
-rw-r--r--src/lib/po/fr_FR.po626
-rw-r--r--src/lib/po/it_IT.po628
-rw-r--r--src/lib/po/sv_SE.po623
-rw-r--r--src/lib/processor.h46
-rw-r--r--src/lib/server.cc2
-rw-r--r--src/lib/server.h4
-rw-r--r--src/lib/sndfile_decoder.cc (renamed from src/lib/external_audio_decoder.cc)40
-rw-r--r--src/lib/sndfile_decoder.h (renamed from src/lib/external_audio_decoder.h)18
-rw-r--r--src/lib/stream.cc4
-rw-r--r--src/lib/transcode_job.cc3
-rw-r--r--src/lib/transcoder.cc10
-rw-r--r--src/lib/util.cc62
-rw-r--r--src/lib/util.h5
-rw-r--r--src/lib/video_decoder.h2
-rw-r--r--src/lib/video_sink.h12
-rw-r--r--src/lib/video_source.cc6
-rw-r--r--src/lib/video_source.h23
-rw-r--r--src/lib/writer.cc30
-rw-r--r--src/lib/wscript9
50 files changed, 3054 insertions, 323 deletions
diff --git a/src/lib/ab_transcoder.cc b/src/lib/ab_transcoder.cc
index 3af32f988..7db13afcc 100644
--- a/src/lib/ab_transcoder.cc
+++ b/src/lib/ab_transcoder.cc
@@ -40,6 +40,7 @@
using std::string;
using boost::shared_ptr;
+using boost::dynamic_pointer_cast;
/** @param a Film to use for the left half of the screen.
* @param b Film to use for the right half of the screen.
@@ -54,6 +55,7 @@ ABTranscoder::ABTranscoder (
, _film_b (b)
, _job (j)
, _encoder (e)
+ , _combiner (new Combiner (a->log()))
{
_da = decoder_factory (_film_a, o);
_db = decoder_factory (_film_b, o);
@@ -68,8 +70,8 @@ ABTranscoder::ABTranscoder (
_db.video->set_subtitle_stream (_film_a->subtitle_stream ());
_da.audio->set_audio_stream (_film_a->audio_stream ());
- _da.video->Video.connect (bind (&Combiner::process_video, _combiner, _1, _2, _3, _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));
_combiner->connect_video (_delay_line);
_delay_line->connect_video (_matcher);
@@ -85,17 +87,24 @@ void
ABTranscoder::go ()
{
_encoder->process_begin ();
+
+ bool done[3] = { false, false, false };
while (1) {
- bool const va = _da.video->pass ();
- bool const vb = _db.video->pass ();
- bool const a = _da.audio->pass ();
+ done[0] = _da.video->pass ();
+ done[1] = _db.video->pass ();
+
+ if (!done[2] && _da.audio && dynamic_pointer_cast<Decoder> (_da.audio) != dynamic_pointer_cast<Decoder> (_da.video)) {
+ done[2] = _da.audio->pass ();
+ } else {
+ done[2] = true;
+ }
if (_job) {
_da.video->set_progress (_job);
}
- if (va && vb && a) {
+ if (done[0] && done[1] && done[2]) {
break;
}
}
diff --git a/src/lib/analyse_audio_job.cc b/src/lib/analyse_audio_job.cc
index 41f918f34..43eecbcbd 100644
--- a/src/lib/analyse_audio_job.cc
+++ b/src/lib/analyse_audio_job.cc
@@ -29,6 +29,7 @@
using std::string;
using std::max;
+using std::min;
using std::cout;
using boost::shared_ptr;
@@ -67,7 +68,7 @@ AnalyseAudioJob::run ()
decoders.audio->Audio.connect (bind (&AnalyseAudioJob::audio, this, _1));
int64_t total_audio_frames = video_frames_to_audio_frames (_film->length().get(), _film->audio_stream()->sample_rate(), _film->source_frame_rate());
- _samples_per_point = total_audio_frames / _num_points;
+ _samples_per_point = max (int64_t (1), total_audio_frames / _num_points);
_current.resize (_film->audio_stream()->channels ());
_analysis.reset (new AudioAnalysis (_film->audio_stream()->channels()));
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<Film>, 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<AudioBuffers>) = 0;
};
-class TimedAudioSink
-{
-public:
- /** Call with some audio data */
- virtual void process_audio (boost::shared_ptr<AudioBuffers>, 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<AudioSink> s)
{
Audio.connect (bind (&AudioSink::process_audio, s, _1));
}
-
-void
-TimedAudioSource::connect_audio (shared_ptr<TimedAudioSink> 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<AudioSink>);
};
-
-/** A class that emits audio data with timestamps */
-class TimedAudioSource
-{
-public:
- /** Emitted when some audio data is ready */
- boost::signals2::signal<void (boost::shared_ptr<AudioBuffers>, double)> Audio;
-
- void connect_audio (boost::shared_ptr<TimedAudioSink>);
-};
-
#endif
diff --git a/src/lib/combiner.cc b/src/lib/combiner.cc
index e628f3a84..12ce4a96e 100644
--- a/src/lib/combiner.cc
+++ b/src/lib/combiner.cc
@@ -22,8 +22,8 @@
using boost::shared_ptr;
-Combiner::Combiner (Log* log)
- : Processor (log)
+Combiner::Combiner (shared_ptr<Log> log)
+ : VideoProcessor (log)
{
}
@@ -33,7 +33,7 @@ Combiner::Combiner (Log* log)
* @param image Frame image.
*/
void
-Combiner::process_video (shared_ptr<Image> image, bool, shared_ptr<Subtitle>, double)
+Combiner::process_video (shared_ptr<Image> image, bool, shared_ptr<Subtitle>)
{
_image = image;
}
@@ -43,7 +43,7 @@ Combiner::process_video (shared_ptr<Image> image, bool, shared_ptr<Subtitle>, do
* @param sub Subtitle (which will be put onto the whole frame)
*/
void
-Combiner::process_video_b (shared_ptr<Image> image, bool, shared_ptr<Subtitle> sub, double t)
+Combiner::process_video_b (shared_ptr<Image> image, bool, shared_ptr<Subtitle> 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> image, bool, shared_ptr<Subtitle> 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..68026eaff 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);
+ Combiner (boost::shared_ptr<Log> log);
- void process_video (boost::shared_ptr<Image> i, bool, boost::shared_ptr<Subtitle> s, double t);
- void process_video_b (boost::shared_ptr<Image> i, bool, boost::shared_ptr<Subtitle> s, double t);
+ void process_video (boost::shared_ptr<Image> i, bool, boost::shared_ptr<Subtitle> s);
+ void process_video_b (boost::shared_ptr<Image> i, bool, boost::shared_ptr<Subtitle> s);
private:
/** The image that we are currently working on */
diff --git a/src/lib/config.cc b/src/lib/config.cc
index f5273b875..5dce3748d 100644
--- a/src/lib/config.cc
+++ b/src/lib/config.cc
@@ -94,6 +94,8 @@ Config::Config ()
_tms_password = v;
} else if (k == N_("sound_processor")) {
_sound_processor = SoundProcessor::from_id (v);
+ } else if (k == "language") {
+ _language = v;
}
_default_dci_metadata.read (k, v);
@@ -128,8 +130,11 @@ Config::write () const
ofstream f (file().c_str ());
f << N_("num_local_encoding_threads ") << _num_local_encoding_threads << N_("\n")
<< N_("default_directory ") << _default_directory << N_("\n")
- << N_("server_port ") << _server_port << N_("\n")
- << N_("reference_scaler ") << _reference_scaler->id () << N_("\n");
+ << N_("server_port ") << _server_port << N_("\n");
+
+ if (_reference_scaler) {
+ f << "reference_scaler " << _reference_scaler->id () << "\n";
+ }
for (vector<Filter const *>::const_iterator i = _reference_filters.begin(); i != _reference_filters.end(); ++i) {
f << N_("reference_filter ") << (*i)->id () << N_("\n");
@@ -143,7 +148,12 @@ Config::write () const
f << N_("tms_path ") << _tms_path << N_("\n");
f << N_("tms_user ") << _tms_user << N_("\n");
f << N_("tms_password ") << _tms_password << N_("\n");
- f << N_("sound_processor ") << _sound_processor->id () << N_("\n");
+ if (_sound_processor) {
+ f << "sound_processor " << _sound_processor->id () << "\n";
+ }
+ if (_language) {
+ f << "language " << _language.get() << "\n";
+ }
_default_dci_metadata.write (f);
}
@@ -157,3 +167,10 @@ Config::default_directory_or (string a) const
return _default_directory;
}
+
+void
+Config::drop ()
+{
+ delete _instance;
+ _instance = 0;
+}
diff --git a/src/lib/config.h b/src/lib/config.h
index fed297ad0..011ca716f 100644
--- a/src/lib/config.h
+++ b/src/lib/config.h
@@ -103,6 +103,10 @@ public:
return _default_dci_metadata;
}
+ boost::optional<std::string> language () const {
+ return _language;
+ }
+
/** @param n New number of local encoding threads */
void set_num_local_encoding_threads (int n) {
_num_local_encoding_threads = n;
@@ -157,10 +161,19 @@ public:
void set_default_dci_metadata (DCIMetadata d) {
_default_dci_metadata = d;
}
+
+ void set_language (std::string l) {
+ _language = l;
+ }
+
+ void unset_language () {
+ _language = boost::none;
+ }
void write () const;
static Config* instance ();
+ static void drop ();
private:
Config ();
@@ -192,6 +205,7 @@ private:
std::list<int> _allowed_dcp_frame_rates;
/** Default DCI metadata for newly-created Films */
DCIMetadata _default_dci_metadata;
+ boost::optional<std::string> _language;
/** Singleton instance, or 0 */
static Config* _instance;
diff --git a/src/lib/dcp_video_frame.cc b/src/lib/dcp_video_frame.cc
index 67617c63c..d674393a9 100644
--- a/src/lib/dcp_video_frame.cc
+++ b/src/lib/dcp_video_frame.cc
@@ -70,7 +70,7 @@ using libdcp::Size;
* @param out Required size of output, in pixels (including any padding).
* @param s Scaler to use.
* @param p Number of pixels of padding either side of the image.
- * @param f Index of the frame within the DCP's intrinsic duration.
+ * @param f Index of the frame within the DCP.
* @param fps Frames per second of the Film's source.
* @param pp FFmpeg post-processing string to use.
* @param clut Colour look-up table to use (see Config::colour_lut_index ())
@@ -80,7 +80,7 @@ using libdcp::Size;
DCPVideoFrame::DCPVideoFrame (
shared_ptr<const Image> yuv, shared_ptr<Subtitle> sub,
Size out, int p, int subtitle_offset, float subtitle_scale,
- Scaler const * s, int f, int dcp_fps, string pp, int clut, int bw, Log* l
+ Scaler const * s, int f, int dcp_fps, string pp, int clut, int bw, shared_ptr<Log> l
)
: _input (yuv)
, _subtitle (sub)
diff --git a/src/lib/dcp_video_frame.h b/src/lib/dcp_video_frame.h
index 6794765ac..4ceb07d26 100644
--- a/src/lib/dcp_video_frame.h
+++ b/src/lib/dcp_video_frame.h
@@ -107,7 +107,7 @@ class DCPVideoFrame
public:
DCPVideoFrame (
boost::shared_ptr<const Image>, boost::shared_ptr<Subtitle>, libdcp::Size,
- int, int, float, Scaler const *, int, int, std::string, int, int, Log *
+ int, int, float, Scaler const *, int, int, std::string, int, int, boost::shared_ptr<Log>
);
virtual ~DCPVideoFrame ();
@@ -135,7 +135,7 @@ private:
int _colour_lut; ///< Colour look-up table to use
int _j2k_bandwidth; ///< J2K bandwidth to use
- Log* _log; ///< log
+ boost::shared_ptr<Log> _log; ///< log
opj_image_cmptparm_t _cmptparm[3]; ///< libopenjpeg's opj_image_cmptparm_t
opj_image* _image; ///< libopenjpeg's image container
diff --git a/src/lib/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<VideoDecoder> (new ImageMagickDecoder (f, o)),
- shared_ptr<AudioDecoder> (new ExternalAudioDecoder (f, o))
+ shared_ptr<AudioDecoder> (new SndfileDecoder (f, o))
);
}
@@ -56,5 +56,5 @@ decoder_factory (
return Decoders (fd, fd);
}
- return Decoders (fd, shared_ptr<AudioDecoder> (new ExternalAudioDecoder (f, o)));
+ return Decoders (fd, shared_ptr<AudioDecoder> (new SndfileDecoder (f, o)));
}
diff --git a/src/lib/delay_line.cc b/src/lib/delay_line.cc
index 924a1f082..c8e593a18 100644
--- a/src/lib/delay_line.cc
+++ b/src/lib/delay_line.cc
@@ -29,7 +29,7 @@ using boost::shared_ptr;
/* @param seconds Delay in seconds, +ve to move audio later.
*/
-DelayLine::DelayLine (Log* log, double seconds)
+DelayLine::DelayLine (shared_ptr<Log> log, double seconds)
: Processor (log)
, _seconds (seconds)
{
@@ -37,7 +37,7 @@ DelayLine::DelayLine (Log* log, double seconds)
}
void
-DelayLine::process_audio (shared_ptr<AudioBuffers> data, double t)
+DelayLine::process_audio (shared_ptr<AudioBuffers> data)
{
if (_seconds > 0) {
t += _seconds;
diff --git a/src/lib/delay_line.h b/src/lib/delay_line.h
index a52fb981c..7a8b11c69 100644
--- a/src/lib/delay_line.h
+++ b/src/lib/delay_line.h
@@ -24,7 +24,7 @@
class DelayLine : public Processor, public TimedAudioSink, public TimedAudioSource, public TimedVideoSink, public TimedVideoSource
{
public:
- DelayLine (Log* log, double);
+ DelayLine (boost::shared_ptr<Log> log, double);
void process_video (boost::shared_ptr<Image>, bool, boost::shared_ptr<Subtitle>, double);
void process_audio (boost::shared_ptr<AudioBuffers>, double);
diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc
index 687dfdd2b..7b338407e 100644
--- a/src/lib/encoder.cc
+++ b/src/lib/encoder.cc
@@ -244,9 +244,9 @@ Encoder::process_video (shared_ptr<Image> image, bool same, boost::shared_ptr<Su
/* Wait until the queue has gone down a bit */
while (_queue.size() >= _threads.size() * 2 && !_terminate) {
- TIMING (_("decoder sleeps with queue of %1"), _queue.size());
+ TIMING ("decoder sleeps with queue of %1", _queue.size());
_condition.wait (lock);
- TIMING (_("decoder wakes with queue of %1"), _queue.size());
+ TIMING ("decoder wakes with queue of %1", _queue.size());
}
if (_terminate) {
@@ -268,7 +268,7 @@ Encoder::process_video (shared_ptr<Image> image, bool same, boost::shared_ptr<Su
} else {
/* Queue this new frame for encoding */
pair<string, string> 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<DCPVideoFrame> (
new DCPVideoFrame (
image, sub, _film->format()->dcp_size(), _film->format()->dcp_padding (_film),
@@ -349,7 +349,7 @@ Encoder::encoder_thread (ServerDescription* server)
while (1) {
- TIMING (N_("encoder thread %1 sleeps"), boost::this_thread::get_id());
+ TIMING ("encoder thread %1 sleeps", boost::this_thread::get_id());
boost::mutex::scoped_lock lock (_mutex);
while (_queue.empty () && !_terminate) {
_condition.wait (lock);
@@ -359,7 +359,7 @@ Encoder::encoder_thread (ServerDescription* server)
return;
}
- TIMING (N_("encoder thread %1 wakes with queue of %2"), boost::this_thread::get_id(), _queue.size());
+ TIMING ("encoder thread %1 wakes with queue of %2", boost::this_thread::get_id(), _queue.size());
boost::shared_ptr<DCPVideoFrame> vf = _queue.front ();
_film->log()->log (String::compose (N_("Encoder thread %1 pops frame %2 from queue"), boost::this_thread::get_id(), vf->frame()), Log::VERBOSE);
_queue.pop_front ();
@@ -393,9 +393,9 @@ Encoder::encoder_thread (ServerDescription* server)
} else {
try {
- TIMING (N_("encoder thread %1 begins local encode of %2"), boost::this_thread::get_id(), vf->frame());
+ TIMING ("encoder thread %1 begins local encode of %2", boost::this_thread::get_id(), vf->frame());
encoded = vf->encode_locally ();
- TIMING (N_("encoder thread %1 finishes local encode of %2"), boost::this_thread::get_id(), vf->frame());
+ TIMING ("encoder thread %1 finishes local encode of %2", boost::this_thread::get_id(), vf->frame());
} catch (std::exception& e) {
_film->log()->log (String::compose (N_("Local encode failed (%1)"), e.what ()));
}
diff --git a/src/lib/exceptions.cc b/src/lib/exceptions.cc
new file mode 100644
index 000000000..bc6ac27c8
--- /dev/null
+++ b/src/lib/exceptions.cc
@@ -0,0 +1,63 @@
+/*
+ Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "exceptions.h"
+#include "compose.hpp"
+
+#include "i18n.h"
+
+using std::string;
+
+/** @param f File that we were trying to open */
+OpenFileError::OpenFileError (string f)
+ : FileError (String::compose (_("could not open file %1"), f), f)
+{
+
+}
+
+/** @param f File that we were trying to create */
+CreateFileError::CreateFileError (string f)
+ : FileError (String::compose (_("could not create file %1"), f), f)
+{
+
+}
+
+ReadFileError::ReadFileError (string f, int e)
+ : FileError ("", f)
+{
+ _what = String::compose (_("could not read from file %1 (%2)"), f, strerror (e));
+}
+
+WriteFileError::WriteFileError (std::string f, int e)
+ : FileError ("", f)
+{
+ _what = String::compose (_("could not write to file %1 (%2)"), f, strerror (e));
+}
+
+MissingSettingError::MissingSettingError (string s)
+ : SettingError (s, String::compose (_("missing required setting %1"), s))
+{
+
+}
+
+PixelFormatError::PixelFormatError (std::string o, AVPixelFormat f)
+ : StringError (String::compose (_("Cannot handle pixel format %1 during %2"), f, o))
+{
+
+}
diff --git a/src/lib/exceptions.h b/src/lib/exceptions.h
index 277355117..e45a62353 100644
--- a/src/lib/exceptions.h
+++ b/src/lib/exceptions.h
@@ -31,7 +31,6 @@
extern "C" {
#include <libavutil/pixfmt.h>
}
-#include "compose.hpp"
/** @class StringError
* @brief A parent class for exceptions using messages held in a std::string
@@ -113,9 +112,7 @@ class OpenFileError : public FileError
{
public:
/** @param f File that we were trying to open */
- OpenFileError (std::string f)
- : FileError ("could not open file " + f, f)
- {}
+ OpenFileError (std::string f);
};
/** @class CreateFileError.
@@ -125,9 +122,7 @@ class CreateFileError : public FileError
{
public:
/** @param f File that we were trying to create */
- CreateFileError (std::string f)
- : FileError ("could not create file " + f, f)
- {}
+ CreateFileError (std::string f);
};
@@ -140,11 +135,7 @@ public:
/** @param f File that we were trying to read from.
* @param e errno value, or 0.
*/
- ReadFileError (std::string f, int e = 0)
- : FileError ("", f)
- {
- _what = String::compose ("could not read from file %1 (%2)", f, strerror (e));
- }
+ ReadFileError (std::string f, int e = 0);
};
/** @class WriteFileError.
@@ -156,11 +147,7 @@ public:
/** @param f File that we were trying to write to.
* @param e errno value, or 0.
*/
- WriteFileError (std::string f, int e)
- : FileError ("", f)
- {
- _what = String::compose ("could not write to file %1 (%2)", f, strerror (e));
- }
+ WriteFileError (std::string f, int e);
};
/** @class SettingError.
@@ -195,9 +182,7 @@ class MissingSettingError : public SettingError
{
public:
/** @param s Name of setting that was required */
- MissingSettingError (std::string s)
- : SettingError (s, "missing required setting " + s)
- {}
+ MissingSettingError (std::string s);
};
/** @class BadSettingError
@@ -226,9 +211,7 @@ public:
class PixelFormatError : public StringError
{
public:
- PixelFormatError (std::string o, AVPixelFormat f)
- : StringError (String::compose ("Cannot handle pixel format %1 during %2", f, o))
- {}
+ PixelFormatError (std::string o, AVPixelFormat f);
};
class ExceptionStore
diff --git a/src/lib/film.cc b/src/lib/film.cc
index 8f545952b..a42b874e8 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"
@@ -93,6 +93,7 @@ Film::Film (string d, bool must_exist)
, _scaler (Scaler::from_id ("bicubic"))
, _trim_start (0)
, _trim_end (0)
+ , _trim_type (CPL)
, _dcp_ab (false)
, _use_content_audio (true)
, _audio_gain (0)
@@ -138,18 +139,19 @@ Film::Film (string d, bool must_exist)
}
}
- _external_audio_stream = ExternalAudioStream::create ();
+ _sndfile_stream = SndfileStream::create ();
if (must_exist) {
read_metadata ();
}
- _log = new FileLog (file ("log"));
+ _log.reset (new FileLog (file ("log")));
}
Film::Film (Film const & o)
: boost::enable_shared_from_this<Film> (o)
- , _log (0)
+ /* note: the copied film shares the original's log */
+ , _log (o._log)
, _directory (o._directory)
, _name (o._name)
, _use_dci_name (o._use_dci_name)
@@ -162,6 +164,7 @@ Film::Film (Film const & o)
, _scaler (o._scaler)
, _trim_start (o._trim_start)
, _trim_end (o._trim_end)
+ , _trim_type (o._trim_type)
, _dcp_ab (o._dcp_ab)
, _content_audio_stream (o._content_audio_stream)
, _external_audio (o._external_audio)
@@ -180,20 +183,19 @@ Film::Film (Film const & o)
, _dcp_frame_rate (o._dcp_frame_rate)
, _size (o._size)
, _length (o._length)
- , _dcp_intrinsic_duration (o._dcp_intrinsic_duration)
, _content_digest (o._content_digest)
, _content_audio_streams (o._content_audio_streams)
- , _external_audio_stream (o._external_audio_stream)
+ , _sndfile_stream (o._sndfile_stream)
, _subtitle_streams (o._subtitle_streams)
, _source_frame_rate (o._source_frame_rate)
, _dirty (o._dirty)
{
-
+
}
Film::~Film ()
{
- delete _log;
+
}
string
@@ -232,19 +234,47 @@ Film::info_dir () const
}
string
-Film::video_mxf_dir () const
+Film::internal_video_mxf_dir () const
{
boost::filesystem::path p;
return dir ("video");
}
string
-Film::video_mxf_filename () const
+Film::internal_video_mxf_filename () const
{
return video_state_identifier() + ".mxf";
}
string
+Film::dcp_video_mxf_filename () const
+{
+ return filename_safe_name() + "_video.mxf";
+}
+
+string
+Film::dcp_audio_mxf_filename () const
+{
+ return filename_safe_name() + "_audio.mxf";
+}
+
+string
+Film::filename_safe_name () const
+{
+ string const n = name ();
+ string o;
+ for (size_t i = 0; i < n.length(); ++i) {
+ if (isalnum (n[i])) {
+ o += n[i];
+ } else {
+ o += "_";
+ }
+ }
+
+ return o;
+}
+
+string
Film::audio_analysis_path () const
{
boost::filesystem::path p;
@@ -350,9 +380,12 @@ void
Film::analyse_audio_finished ()
{
ensure_ui_thread ();
- _analyse_audio_job.reset ();
- AudioAnalysisFinished ();
+ if (_analyse_audio_job->finished_ok ()) {
+ AudioAnalysisSucceeded ();
+ }
+
+ _analyse_audio_job.reset ();
}
void
@@ -425,6 +458,14 @@ Film::write_metadata () const
f << "scaler " << _scaler->id () << endl;
f << "trim_start " << _trim_start << endl;
f << "trim_end " << _trim_end << endl;
+ switch (_trim_type) {
+ case CPL:
+ f << "trim_type cpl\n";
+ break;
+ case ENCODE:
+ f << "trim_type encode\n";
+ break;
+ }
f << "dcp_ab " << (_dcp_ab ? "1" : "0") << endl;
if (_content_audio_stream) {
f << "selected_content_audio_stream " << _content_audio_stream->to_string() << endl;
@@ -450,14 +491,13 @@ Film::write_metadata () const
f << "width " << _size.width << endl;
f << "height " << _size.height << endl;
f << "length " << _length.get_value_or(0) << endl;
- f << "dcp_intrinsic_duration " << _dcp_intrinsic_duration.get_value_or(0) << endl;
f << "content_digest " << _content_digest << endl;
for (vector<shared_ptr<AudioStream> >::const_iterator i = _content_audio_streams.begin(); i != _content_audio_streams.end(); ++i) {
f << "content_audio_stream " << (*i)->to_string () << endl;
}
- f << "external_audio_stream " << _external_audio_stream->to_string() << endl;
+ f << "external_audio_stream " << _sndfile_stream->to_string() << endl;
for (vector<shared_ptr<SubtitleStream> >::const_iterator i = _subtitle_streams.begin(); i != _subtitle_streams.end(); ++i) {
f << "subtitle_stream " << (*i)->to_string () << endl;
@@ -539,6 +579,12 @@ Film::read_metadata ()
_trim_start = atoi (v.c_str ());
} else if ( ((!version || version < 2) && k == "dcp_trim_end") || k == "trim_end") {
_trim_end = atoi (v.c_str ());
+ } else if (k == "trim_type") {
+ if (v == "cpl") {
+ _trim_type = CPL;
+ } else if (v == "encode") {
+ _trim_type = ENCODE;
+ }
} else if (k == "dcp_ab") {
_dcp_ab = (v == "1");
} else if (k == "selected_content_audio_stream" || (!version && k == "selected_audio_stream")) {
@@ -591,17 +637,12 @@ Film::read_metadata ()
if (vv) {
_length = vv;
}
- } else if (k == "dcp_intrinsic_duration") {
- int const vv = atoi (v.c_str ());
- if (vv) {
- _dcp_intrinsic_duration = vv;
- }
} else if (k == "content_digest") {
_content_digest = v;
} else if (k == "content_audio_stream" || (!version && k == "audio_stream")) {
_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") {
@@ -758,70 +799,67 @@ Film::dci_name (bool if_created_now) const
fixed_name = fixed_name.substr (0, 14);
}
- d << fixed_name << "_";
+ d << fixed_name;
if (dcp_content_type()) {
- d << dcp_content_type()->dci_name() << "_";
+ d << "_" << dcp_content_type()->dci_name();
}
if (format()) {
- d << format()->dci_name() << "_";
+ d << "_" << format()->dci_name();
}
DCIMetadata const dm = dci_metadata ();
if (!dm.audio_language.empty ()) {
- d << dm.audio_language;
- if (!dm.subtitle_language.empty() && with_subtitles()) {
+ d << "_" << dm.audio_language;
+ if (!dm.subtitle_language.empty()) {
d << "-" << dm.subtitle_language;
} else {
d << "-XX";
}
-
- d << "_";
}
if (!dm.territory.empty ()) {
- d << dm.territory;
+ d << "_" << dm.territory;
if (!dm.rating.empty ()) {
d << "-" << dm.rating;
}
- d << "_";
}
switch (audio_channels()) {
case 1:
- d << "10_";
+ d << "_10";
break;
case 2:
- d << "20_";
+ d << "_20";
break;
case 6:
- d << "51_";
+ d << "_51";
break;
case 8:
- d << "71_";
+ d << "_71";
break;
}
- d << "2K_";
+ d << "_2K";
if (!dm.studio.empty ()) {
- d << dm.studio << "_";
+ d << "_" << dm.studio;
}
if (if_created_now) {
- d << boost::gregorian::to_iso_string (boost::gregorian::day_clock::local_day ()) << "_";
+ d << "_" << boost::gregorian::to_iso_string (boost::gregorian::day_clock::local_day ());
} else {
- d << boost::gregorian::to_iso_string (_dci_date) << "_";
+ d << "_" << boost::gregorian::to_iso_string (_dci_date);
}
if (!dm.facility.empty ()) {
- d << dm.facility << "_";
+ d << "_" << dm.facility;
}
if (!dm.package_type.empty ()) {
- d << dm.package_type;
+ d << "_" << dm.package_type;
}
return d.str ();
@@ -1103,6 +1141,16 @@ Film::set_trim_end (int t)
}
void
+Film::set_trim_type (TrimType t)
+{
+ {
+ boost::mutex::scoped_lock lm (_state_mutex);
+ _trim_type = t;
+ }
+ signal_changed (TRIM_TYPE);
+}
+
+void
Film::set_dcp_ab (bool a)
{
{
@@ -1130,9 +1178,9 @@ Film::set_external_audio (vector<string> a)
_external_audio = a;
}
- shared_ptr<ExternalAudioDecoder> decoder (new ExternalAudioDecoder (shared_from_this(), DecodeOptions()));
+ shared_ptr<SndfileDecoder> 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);
@@ -1291,16 +1339,6 @@ Film::unset_length ()
}
void
-Film::set_dcp_intrinsic_duration (int d)
-{
- {
- boost::mutex::scoped_lock lm (_state_mutex);
- _dcp_intrinsic_duration = d;
- }
- signal_changed (DCP_INTRINSIC_DURATION);
-}
-
-void
Film::set_content_digest (string d)
{
{
@@ -1377,7 +1415,7 @@ Film::audio_stream () const
return _content_audio_stream;
}
- return _external_audio_stream;
+ return _sndfile_stream;
}
string
@@ -1434,3 +1472,21 @@ Film::have_dcp () const
return true;
}
+
+bool
+Film::has_audio () const
+{
+ if (use_content_audio()) {
+ return audio_stream();
+ }
+
+ vector<string> const e = external_audio ();
+ for (vector<string>::const_iterator i = e.begin(); i != e.end(); ++i) {
+ if (!i->empty ()) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
diff --git a/src/lib/film.h b/src/lib/film.h
index 9921acbb4..dd0a83d94 100644
--- a/src/lib/film.h
+++ b/src/lib/film.h
@@ -64,10 +64,13 @@ public:
std::string info_dir () const;
std::string j2c_path (int f, bool t) const;
std::string info_path (int f) const;
- std::string video_mxf_dir () const;
- std::string video_mxf_filename () const;
+ std::string internal_video_mxf_dir () const;
+ std::string internal_video_mxf_filename () const;
std::string audio_analysis_path () const;
+ std::string dcp_video_mxf_filename () const;
+ std::string dcp_audio_mxf_filename () const;
+
void examine_content ();
void analyse_audio ();
void send_dcp_to_tms ();
@@ -77,7 +80,7 @@ public:
/** @return Logger.
* It is safe to call this from any thread.
*/
- Log* log () const {
+ boost::shared_ptr<Log> log () const {
return _log;
}
@@ -98,10 +101,6 @@ public:
std::string dci_name (bool if_created_now) const;
std::string dcp_name (bool if_created_now = false) const;
- boost::optional<int> dcp_intrinsic_duration () const {
- return _dcp_intrinsic_duration;
- }
-
/** @return true if our state has changed since we last saved it */
bool dirty () const {
return _dirty;
@@ -113,6 +112,11 @@ public:
bool have_dcp () const;
+ enum TrimType {
+ CPL,
+ ENCODE
+ };
+
/** Identifiers for the parts of our state;
used for signalling changes.
*/
@@ -129,6 +133,7 @@ public:
SCALER,
TRIM_START,
TRIM_END,
+ TRIM_TYPE,
DCP_AB,
CONTENT_AUDIO_STREAM,
EXTERNAL_AUDIO,
@@ -145,7 +150,6 @@ public:
DCI_METADATA,
SIZE,
LENGTH,
- DCP_INTRINSIC_DURATION,
CONTENT_AUDIO_STREAMS,
SUBTITLE_STREAMS,
SOURCE_FRAME_RATE,
@@ -215,6 +219,11 @@ public:
return _trim_end;
}
+ TrimType trim_type () const {
+ boost::mutex::scoped_lock lm (_state_mutex);
+ return _trim_type;
+ }
+
bool dcp_ab () const {
boost::mutex::scoped_lock lm (_state_mutex);
return _dcp_ab;
@@ -327,7 +336,7 @@ public:
}
boost::shared_ptr<AudioStream> audio_stream () const;
-
+ bool has_audio () const;
/* SET */
@@ -347,6 +356,7 @@ public:
void set_scaler (Scaler const *);
void set_trim_start (int);
void set_trim_end (int);
+ void set_trim_type (TrimType);
void set_dcp_ab (bool);
void set_content_audio_stream (boost::shared_ptr<AudioStream>);
void set_external_audio (std::vector<std::string>);
@@ -365,7 +375,6 @@ public:
void set_size (libdcp::Size);
void set_length (SourceFrame);
void unset_length ();
- void set_dcp_intrinsic_duration (int);
void set_content_digest (std::string);
void set_content_audio_streams (std::vector<boost::shared_ptr<AudioStream> >);
void set_subtitle_streams (std::vector<boost::shared_ptr<SubtitleStream> >);
@@ -374,7 +383,7 @@ public:
/** Emitted when some property has changed */
mutable boost::signals2::signal<void (Property)> Changed;
- boost::signals2::signal<void ()> AudioAnalysisFinished;
+ boost::signals2::signal<void ()> AudioAnalysisSucceeded;
/** Current version number of the state file */
static int const state_version;
@@ -382,7 +391,7 @@ public:
private:
/** Log to write to */
- Log* _log;
+ boost::shared_ptr<Log> _log;
/** Any running ExamineContentJob, or 0 */
boost::shared_ptr<ExamineContentJob> _examine_content_job;
@@ -393,6 +402,7 @@ private:
void examine_content_finished ();
void analyse_audio_finished ();
std::string video_state_identifier () const;
+ std::string filename_safe_name () const;
/** Complete path to directory containing the film metadata;
* must not be relative.
@@ -428,6 +438,7 @@ private:
int _trim_start;
/** Frames to trim off the end of the DCP */
int _trim_end;
+ TrimType _trim_type;
/** true to create an A/B comparison DCP, where the left half of the image
is the video without any filters or post-processing, and the right half
has the specified filters and post-processing.
@@ -477,13 +488,12 @@ private:
libdcp::Size _size;
/** The length of the source, in video frames (as far as we know) */
boost::optional<SourceFrame> _length;
- boost::optional<int> _dcp_intrinsic_duration;
/** MD5 digest of our content file */
std::string _content_digest;
/** The audio streams in our content */
std::vector<boost::shared_ptr<AudioStream> > _content_audio_streams;
/** A stream to represent possible external audio (will always exist) */
- boost::shared_ptr<AudioStream> _external_audio_stream;
+ boost::shared_ptr<AudioStream> _sndfile_stream;
/** the subtitle streams that we can use */
std::vector<boost::shared_ptr<SubtitleStream> > _subtitle_streams;
/** Frames per second of the source */
diff --git a/src/lib/format.cc b/src/lib/format.cc
index b506c7000..faadcd797 100644
--- a/src/lib/format.cc
+++ b/src/lib/format.cc
@@ -72,68 +72,59 @@ Format::setup_formats ()
{
/// TRANSLATORS: these are film picture aspect ratios; "Academy" means 1.37, "Flat" 1.85 and "Scope" 2.39.
_formats.push_back (
- new FixedFormat (119, libdcp::Size (1285, 1080), N_("119"), _("1.19"), N_("F"),
- _("Source scaled to 1.19:1")
+ new FixedFormat (119, libdcp::Size (1285, 1080), N_("119"), _("1.19"), N_("F")
));
_formats.push_back (
- new FixedFormat (133, libdcp::Size (1436, 1080), N_("133"), _("1.33"), N_("F"),
- _("Source scaled to 1.33:1")
+ new FixedFormat (133, libdcp::Size (1436, 1080), N_("133"), _("1.33"), N_("F")
));
_formats.push_back (
- new FixedFormat (138, libdcp::Size (1485, 1080), N_("138"), _("1.375"), N_("F"),
- _("Source scaled to 1.375:1")
+ new FixedFormat (138, libdcp::Size (1485, 1080), N_("138"), _("1.375"), N_("F")
));
_formats.push_back (
- new FixedFormat (133, libdcp::Size (1998, 1080), N_("133-in-flat"), _("4:3 within Flat"), N_("F"),
- _("Source scaled to 1.33:1 then pillarboxed to Flat")
+ new FixedFormat (133, libdcp::Size (1998, 1080), N_("133-in-flat"), _("4:3 within Flat"), N_("F")
));
_formats.push_back (
- new FixedFormat (137, libdcp::Size (1480, 1080), N_("137"), _("Academy"), N_("F"),
- _("Source scaled to 1.37:1 (Academy ratio)")
+ new FixedFormat (137, libdcp::Size (1480, 1080), N_("137"), _("Academy"), N_("F")
));
_formats.push_back (
- new FixedFormat (166, libdcp::Size (1793, 1080), N_("166"), _("1.66"), N_("F"),
- _("Source scaled to 1.66:1")
+ new FixedFormat (166, libdcp::Size (1793, 1080), N_("166"), _("1.66"), N_("F")
));
_formats.push_back (
- new FixedFormat (166, libdcp::Size (1998, 1080), N_("166-in-flat"), _("1.66 within Flat"), N_("F"),
- _("Source scaled to 1.66:1 then pillarboxed to Flat")
+ new FixedFormat (166, libdcp::Size (1998, 1080), N_("166-in-flat"), _("1.66 within Flat"), N_("F")
));
_formats.push_back (
- new FixedFormat (178, libdcp::Size (1998, 1080), N_("178-in-flat"), _("16:9 within Flat"), N_("F"),
- _("Source scaled to 1.78:1 then pillarboxed to Flat")
+ new FixedFormat (178, libdcp::Size (1998, 1080), N_("178-in-flat"), _("16:9 within Flat"), N_("F")
));
_formats.push_back (
- new FixedFormat (178, libdcp::Size (1920, 1080), N_("178"), _("16:9"), N_("F"),
- _("Source scaled to 1.78:1")
+ new FixedFormat (178, libdcp::Size (1920, 1080), N_("178"), _("16:9"), N_("F")
));
_formats.push_back (
- new FixedFormat (185, libdcp::Size (1998, 1080), N_("185"), _("Flat"), N_("F"),
- _("Source scaled to Flat (1.85:1)")
+ new FixedFormat (185, libdcp::Size (1998, 1080), N_("185"), _("Flat"), N_("F")
));
_formats.push_back (
- new FixedFormat (239, libdcp::Size (2048, 858), N_("239"), _("Scope"), N_("S"),
- _("Source scaled to Scope (2.39:1)")
+ new FixedFormat (178, libdcp::Size (2048, 858), N_("178-in-scope"), _("16:9 within Scope"), N_("S")
+ ));
+
+ _formats.push_back (
+ new FixedFormat (239, libdcp::Size (2048, 858), N_("239"), _("Scope"), N_("S")
));
_formats.push_back (
- new VariableFormat (libdcp::Size (1998, 1080), N_("var-185"), _("Flat without stretch"), N_("F"),
- _("Source scaled to fit Flat preserving its aspect ratio")
+ new VariableFormat (libdcp::Size (1998, 1080), N_("var-185"), _("Flat without stretch"), N_("F")
));
_formats.push_back (
- new VariableFormat (libdcp::Size (2048, 858), N_("var-239"), _("Scope without stretch"), N_("S"),
- _("Source scaled to fit Scope preserving its aspect ratio")
+ new VariableFormat (libdcp::Size (2048, 858), N_("var-239"), _("Scope without stretch"), N_("S")
));
}
@@ -195,8 +186,8 @@ Format::all ()
* @param id ID (e.g. 185)
* @param n Nick name (e.g. Flat)
*/
-FixedFormat::FixedFormat (int r, libdcp::Size dcp, string id, string n, string d, string e)
- : Format (dcp, id, n, d, e)
+FixedFormat::FixedFormat (int r, libdcp::Size dcp, string id, string n, string d)
+ : Format (dcp, id, n, d)
, _ratio (r)
{
@@ -208,7 +199,7 @@ FixedFormat::FixedFormat (int r, libdcp::Size dcp, string id, string n, string d
int
Format::dcp_padding (shared_ptr<const Film> f) const
{
- int p = rint ((_dcp_size.width - (_dcp_size.height * ratio_as_integer(f) / 100.0)) / 2.0);
+ int p = rint ((_dcp_size.width - (_dcp_size.height * ratio_as_float(f))) / 2.0);
/* This comes out -ve for Scope; bodge it */
if (p < 0) {
@@ -224,8 +215,8 @@ Format::container_ratio_as_float () const
return static_cast<float> (_dcp_size.width) / _dcp_size.height;
}
-VariableFormat::VariableFormat (libdcp::Size dcp, string id, string n, string d, string e)
- : Format (dcp, id, n, d, e)
+VariableFormat::VariableFormat (libdcp::Size dcp, string id, string n, string d)
+ : Format (dcp, id, n, d)
{
}
@@ -239,7 +230,8 @@ VariableFormat::ratio_as_integer (shared_ptr<const Film> f) const
float
VariableFormat::ratio_as_float (shared_ptr<const Film> f) const
{
- return float (f->size().width) / f->size().height;
+ libdcp::Size const c = f->cropped_size (f->size ());
+ return float (c.width) / c.height;
}
/** @return A name to be presented to the user */
diff --git a/src/lib/format.h b/src/lib/format.h
index 305524628..783ff25ce 100644
--- a/src/lib/format.h
+++ b/src/lib/format.h
@@ -31,12 +31,11 @@ class Film;
class Format
{
public:
- Format (libdcp::Size dcp, std::string id, std::string n, std::string d, std::string e)
+ Format (libdcp::Size dcp, std::string id, std::string n, std::string d)
: _dcp_size (dcp)
, _id (id)
, _nickname (n)
, _dci_name (d)
- , _description (e)
{}
/** @return the aspect ratio multiplied by 100
@@ -76,10 +75,6 @@ public:
return _dci_name;
}
- std::string description () const {
- return _description;
- }
-
std::string as_metadata () const;
static Format const * from_nickname (std::string n);
@@ -99,7 +94,6 @@ protected:
/** nickname (e.g. Flat, Scope) */
std::string _nickname;
std::string _dci_name;
- std::string _description;
private:
/** all available formats */
@@ -113,7 +107,7 @@ private:
class FixedFormat : public Format
{
public:
- FixedFormat (int, libdcp::Size, std::string, std::string, std::string, std::string);
+ FixedFormat (int, libdcp::Size, std::string, std::string, std::string);
int ratio_as_integer (boost::shared_ptr<const Film>) const {
return _ratio;
@@ -134,7 +128,7 @@ private:
class VariableFormat : public Format
{
public:
- VariableFormat (libdcp::Size, std::string, std::string, std::string, std::string);
+ VariableFormat (libdcp::Size, std::string, std::string, std::string);
int ratio_as_integer (boost::shared_ptr<const Film> f) const;
float ratio_as_float (boost::shared_ptr<const Film> f) const;
diff --git a/src/lib/gain.cc b/src/lib/gain.cc
index 35ce27cea..df7011d2e 100644
--- a/src/lib/gain.cc
+++ b/src/lib/gain.cc
@@ -22,8 +22,8 @@
using boost::shared_ptr;
/** @param gain gain in dB */
-Gain::Gain (Log* log, float gain)
- : Processor (log)
+Gain::Gain (shared_ptr<Log> log, float gain)
+ : AudioProcessor (log)
, _gain (gain)
{
diff --git a/src/lib/gain.h b/src/lib/gain.h
index 449473582..d462e5aee 100644
--- a/src/lib/gain.h
+++ b/src/lib/gain.h
@@ -19,10 +19,10 @@
#include "processor.h"
-class Gain : public Processor, public AudioSink, public AudioSource
+class Gain : public AudioProcessor
{
public:
- Gain (Log* log, float gain);
+ Gain (boost::shared_ptr<Log> log, float gain);
void process_audio (boost::shared_ptr<AudioBuffers>);
diff --git a/src/lib/image.cc b/src/lib/image.cc
index 268c08173..2355d22e5 100644
--- a/src/lib/image.cc
+++ b/src/lib/image.cc
@@ -75,6 +75,7 @@ Image::lines (int n) const
case PIX_FMT_YUV444P9LE:
case PIX_FMT_YUV444P10BE:
case PIX_FMT_YUV444P10LE:
+ case PIX_FMT_UYVY422:
return size().height;
default:
throw PixelFormatError (N_("lines()"), _pixel_format);
@@ -99,6 +100,7 @@ Image::components () const
return 3;
case PIX_FMT_RGB24:
case PIX_FMT_RGBA:
+ case PIX_FMT_UYVY422:
return 1;
default:
throw PixelFormatError (N_("components()"), _pixel_format);
@@ -211,6 +213,7 @@ Image::post_process (string pp, bool aligned) const
break;
case PIX_FMT_YUV422P10LE:
case PIX_FMT_YUV422P:
+ case PIX_FMT_UYVY422:
pp_format = PP_FORMAT_422;
break;
case PIX_FMT_YUV444P:
@@ -291,6 +294,9 @@ Image::swap_16 (uint16_t v)
void
Image::make_black ()
{
+ /* U/V black value for 8-bit colour */
+ static uint8_t const eight_bit_uv = (1 << 7) - 1;
+
/* U/V black value for 9-bit colour */
static uint16_t const nine_bit_uv = (1 << 8) - 1;
@@ -302,8 +308,8 @@ Image::make_black ()
case PIX_FMT_YUV422P:
case PIX_FMT_YUV444P:
memset (data()[0], 0, lines(0) * stride()[0]);
- memset (data()[1], 0x7f, lines(1) * stride()[1]);
- memset (data()[2], 0x7f, lines(2) * stride()[2]);
+ memset (data()[1], eight_bit_uv, lines(1) * stride()[1]);
+ memset (data()[2], eight_bit_uv, lines(2) * stride()[2]);
break;
case PIX_FMT_YUV422P9LE:
@@ -329,8 +335,24 @@ Image::make_black ()
memset (data()[0], 0, lines(0) * stride()[0]);
break;
+ case PIX_FMT_UYVY422:
+ {
+ int const Y = lines(0);
+ int const X = line_size()[0];
+ uint8_t* p = data()[0];
+ for (int y = 0; y < Y; ++y) {
+ for (int x = 0; x < X / 4; ++x) {
+ *p++ = eight_bit_uv; // Cb
+ *p++ = 0; // Y0
+ *p++ = eight_bit_uv; // Cr
+ *p++ = 0; // Y1
+ }
+ }
+ break;
+ }
+
default:
- assert (false);
+ throw PixelFormatError (N_("make_black()"), _pixel_format);
}
}
@@ -428,6 +450,8 @@ Image::bytes_per_pixel (int c) const
} else {
return 1;
}
+ case PIX_FMT_UYVY422:
+ return 2;
case PIX_FMT_YUV444P:
return 3;
case PIX_FMT_YUV444P9BE:
@@ -436,7 +460,7 @@ Image::bytes_per_pixel (int c) const
case PIX_FMT_YUV444P10BE:
return 6;
default:
- assert (false);
+ throw PixelFormatError (N_("bytes_per_pixel()"), _pixel_format);
}
return 0;
diff --git a/src/lib/imagemagick_decoder.h b/src/lib/imagemagick_decoder.h
index ca8e819d3..80a08f81f 100644
--- a/src/lib/imagemagick_decoder.h
+++ b/src/lib/imagemagick_decoder.h
@@ -49,10 +49,6 @@ public:
return 0;
}
- bool has_subtitles () const {
- return false;
- }
-
bool seek (double);
bool seek_to_last ();
diff --git a/src/lib/job.cc b/src/lib/job.cc
index 78a7a7577..1c66d87d3 100644
--- a/src/lib/job.cc
+++ b/src/lib/job.cc
@@ -38,6 +38,7 @@ using boost::shared_ptr;
*/
Job::Job (shared_ptr<Film> f)
: _film (f)
+ , _thread (0)
, _state (NEW)
, _start_time (0)
, _progress_unknown (false)
@@ -52,7 +53,7 @@ Job::start ()
{
set_state (RUNNING);
_start_time = time (0);
- boost::thread (boost::bind (&Job::run_wrapper, this));
+ _thread = new boost::thread (boost::bind (&Job::run_wrapper, this));
}
/** A wrapper for the ::run() method to catch exceptions */
@@ -81,6 +82,10 @@ Job::run_wrapper ()
}
set_error (e.what(), m);
+
+ } catch (boost::thread_interrupted &) {
+
+ set_state (FINISHED_CANCELLED);
} catch (std::exception& e) {
@@ -124,7 +129,7 @@ bool
Job::finished () const
{
boost::mutex::scoped_lock lm (_state_mutex);
- return _state == FINISHED_OK || _state == FINISHED_ERROR;
+ return _state == FINISHED_OK || _state == FINISHED_ERROR || _state == FINISHED_CANCELLED;
}
/** @return true if the job has finished successfully */
@@ -143,6 +148,13 @@ Job::finished_in_error () const
return _state == FINISHED_ERROR;
}
+bool
+Job::finished_cancelled () const
+{
+ boost::mutex::scoped_lock lm (_state_mutex);
+ return _state == FINISHED_CANCELLED;
+}
+
/** Set the state of this job.
* @param s New state.
*/
@@ -177,6 +189,7 @@ Job::set_progress (float p)
boost::mutex::scoped_lock lm (_progress_mutex);
_progress_unknown = false;
_stack.back().normalised = p;
+ boost::this_thread::interruption_point ();
}
/** @return fractional overall progress, or -1 if not known */
@@ -289,6 +302,8 @@ Job::status () const
s << String::compose (_("OK (ran for %1)"), seconds_to_hms (_ran_for));
} else if (finished_in_error ()) {
s << String::compose (_("Error (%1)"), error_summary());
+ } else if (finished_cancelled ()) {
+ s << _("Cancelled");
}
return s.str ();
@@ -300,3 +315,14 @@ Job::remaining_time () const
{
return elapsed_time() / overall_progress() - elapsed_time();
}
+
+void
+Job::cancel ()
+{
+ if (!_thread) {
+ return;
+ }
+
+ _thread->interrupt ();
+ _thread->join ();
+}
diff --git a/src/lib/job.h b/src/lib/job.h
index c98dbaea1..fd036bce2 100644
--- a/src/lib/job.h
+++ b/src/lib/job.h
@@ -28,6 +28,7 @@
#include <boost/thread/mutex.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/signals2.hpp>
+#include <boost/thread.hpp>
class Film;
@@ -46,12 +47,14 @@ public:
virtual void run () = 0;
void start ();
+ void cancel ();
bool is_new () const;
bool running () const;
bool finished () const;
bool finished_ok () const;
bool finished_in_error () const;
+ bool finished_cancelled () const;
std::string error_summary () const;
std::string error_details () const;
@@ -74,10 +77,11 @@ protected:
/** Description of a job's state */
enum State {
- NEW, ///< the job hasn't been started yet
- RUNNING, ///< the job is running
- FINISHED_OK, ///< the job has finished successfully
- FINISHED_ERROR ///< the job has finished in error
+ NEW, ///< the job hasn't been started yet
+ RUNNING, ///< the job is running
+ FINISHED_OK, ///< the job has finished successfully
+ FINISHED_ERROR, ///< the job has finished in error
+ FINISHED_CANCELLED ///< the job was cancelled
};
void set_state (State);
@@ -90,6 +94,8 @@ private:
void run_wrapper ();
+ boost::thread* _thread;
+
/** mutex for _state and _error */
mutable boost::mutex _state_mutex;
/** current state of the job */
diff --git a/src/lib/matcher.cc b/src/lib/matcher.cc
index a74eeabbb..69d12e2c4 100644
--- a/src/lib/matcher.cc
+++ b/src/lib/matcher.cc
@@ -28,8 +28,8 @@ using std::cout;
using std::list;
using boost::shared_ptr;
-Matcher::Matcher (Log* log, int sample_rate, float frames_per_second)
- : Processor (log)
+Matcher::Matcher (shared_ptr<Log> log, int sample_rate, float frames_per_second)
+ : AudioVideoProcessor (log)
, _sample_rate (sample_rate)
, _frames_per_second (frames_per_second)
, _video_frames (0)
diff --git a/src/lib/matcher.h b/src/lib/matcher.h
index a7054f540..4ec0a3e96 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<Image> i, bool, boost::shared_ptr<Subtitle> s, double t);
- void process_audio (boost::shared_ptr<AudioBuffers>, double t);
+ Matcher (boost::shared_ptr<Log> log, int sample_rate, float frames_per_second);
+ void process_video (boost::shared_ptr<Image> i, bool, boost::shared_ptr<Subtitle> s);
+ void process_audio (boost::shared_ptr<AudioBuffers>);
void process_end ();
private:
diff --git a/src/lib/po/es_ES.po b/src/lib/po/es_ES.po
new file mode 100644
index 000000000..17051bd98
--- /dev/null
+++ b/src/lib/po/es_ES.po
@@ -0,0 +1,626 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: LIBDVDOMATIC\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-04-09 11:14+0100\n"
+"PO-Revision-Date: 2013-04-02 19:10-0500\n"
+"Last-Translator: Manuel AC <manuel.acevedo@civantos.>\n"
+"Language-Team: Manuel AC <manuel.acevedo@civantos.com>\n"
+"Language: es-ES\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 1.5.5\n"
+
+#: src/lib/transcode_job.cc:87
+msgid "0%"
+msgstr "0%"
+
+#: src/lib/format.cc:75
+msgid "1.19"
+msgstr "1.19"
+
+#: src/lib/format.cc:79
+msgid "1.33"
+msgstr "1.33"
+
+#: src/lib/format.cc:83
+msgid "1.375"
+msgstr "1.375"
+
+#: src/lib/format.cc:95
+msgid "1.66"
+msgstr "1.66"
+
+#: src/lib/format.cc:99
+msgid "1.66 within Flat"
+msgstr "1.66 en Flat"
+
+#: src/lib/format.cc:107
+msgid "16:9"
+msgstr "16:9"
+
+#: src/lib/format.cc:103
+msgid "16:9 within Flat"
+msgstr "16:9 en Flat"
+
+#: src/lib/format.cc:115
+#, fuzzy
+msgid "16:9 within Scope"
+msgstr "16:9 en Flat"
+
+#: src/lib/filter.cc:88
+msgid "3D denoiser"
+msgstr "reducción de ruido 3D"
+
+#: src/lib/format.cc:87
+msgid "4:3 within Flat"
+msgstr "4:3 en Flat"
+
+#: src/lib/ab_transcode_job.cc:49
+msgid "A/B transcode %1"
+msgstr "Codificación A/B %1"
+
+#: src/lib/format.cc:91
+msgid "Academy"
+msgstr "Academy"
+
+#: src/lib/dcp_content_type.cc:53
+msgid "Advertisement"
+msgstr "Publicidad"
+
+#: src/lib/job.cc:72
+msgid "An error occurred whilst handling the file %1."
+msgstr "Ha ocurrido un error con el fichero %1."
+
+#: src/lib/analyse_audio_job.cc:49
+msgid "Analyse audio of %1"
+msgstr "Analizar audio de %1"
+
+#: src/lib/scaler.cc:64
+msgid "Area"
+msgstr "Área"
+
+#: src/lib/scaler.cc:62
+msgid "Bicubic"
+msgstr "Bicúbico"
+
+#: src/lib/scaler.cc:69
+msgid "Bilinear"
+msgstr "Bilineal"
+
+#: src/lib/job.cc:302
+msgid "Cancelled"
+msgstr ""
+
+#: src/lib/exceptions.cc:60
+msgid "Cannot handle pixel format %1 during %2"
+msgstr ""
+
+#: src/lib/encoder.cc:101
+msgid "Cannot resample audio as libswresample is not present"
+msgstr ""
+"No se puede redimensionar el sonido porque no se encuentra libswresample"
+
+#: src/lib/util.cc:932
+msgid "Centre"
+msgstr ""
+
+#: src/lib/scp_dcp_job.cc:109
+msgid "Copy DCP to TMS"
+msgstr "Copiar DCP al TMS"
+
+#: src/lib/scp_dcp_job.cc:128
+msgid "Could not connect to server %1 (%2)"
+msgstr "No se pudo conectar al servidor %1 (%2)"
+
+#: src/lib/scp_dcp_job.cc:150
+msgid "Could not create remote directory %1 (%2)"
+msgstr "No se pudo crear la carpeta remota %1 (%2)"
+
+#: src/lib/scp_dcp_job.cc:175
+msgid "Could not open %1 to send"
+msgstr "No se pudo abrir %1 para enviar"
+
+#: src/lib/scp_dcp_job.cc:145
+msgid "Could not start SCP session (%1)"
+msgstr "No se pudo iniciar la sesión SCP (%1)"
+
+#: src/lib/scp_dcp_job.cc:187
+msgid "Could not write to remote file (%1)"
+msgstr "No se pudo escribir el fichero remoto (%1)"
+
+#: src/lib/filter.cc:77
+msgid "Cubic interpolating deinterlacer"
+msgstr "Desentrelazado por interpolación cúbica"
+
+#: src/lib/util.cc:1007
+msgid "DCP and source have the same rate.\n"
+msgstr "La fuente y el DCP tienen la misma velocidad.\n"
+
+#: src/lib/util.cc:1017
+#, fuzzy
+msgid "DCP will run at %1%% of the source speed.\n"
+msgstr "El DCP se reproducirá al %1%% de la velocidad de la fuente.\n"
+
+#: src/lib/util.cc:1010
+msgid "DCP will use every other frame of the source.\n"
+msgstr "El DCP usará fotogramas alternos de la fuente.\n"
+
+#: src/lib/filter.cc:68 src/lib/filter.cc:69 src/lib/filter.cc:70
+#: src/lib/filter.cc:71 src/lib/filter.cc:72 src/lib/filter.cc:73
+msgid "De-blocking"
+msgstr "De-blocking"
+
+#: src/lib/filter.cc:75 src/lib/filter.cc:76 src/lib/filter.cc:77
+#: src/lib/filter.cc:78 src/lib/filter.cc:79 src/lib/filter.cc:80
+#: src/lib/filter.cc:81 src/lib/filter.cc:82 src/lib/filter.cc:83
+msgid "De-interlacing"
+msgstr "Desentrelazado"
+
+#: src/lib/filter.cc:74
+msgid "Deringing filter"
+msgstr "Deringing filter"
+
+#: src/lib/dolby_cp750.cc:27
+msgid "Dolby CP750"
+msgstr "Dolby CP750"
+
+#: src/lib/util.cc:1012
+msgid "Each source frame will be doubled in the DCP.\n"
+msgstr "Se doblará cada fotograma de la fuente en el DCP.\n"
+
+#: src/lib/job.cc:300
+msgid "Error (%1)"
+msgstr "Error (%1)"
+
+#: src/lib/examine_content_job.cc:55
+msgid "Examine content"
+msgstr "Examinar contenido"
+
+#: src/lib/examine_content_job.cc:58
+msgid "Examine content of %1"
+msgstr "Examinar contenido de %1"
+
+#: src/lib/filter.cc:72
+msgid "Experimental horizontal deblocking filter 1"
+msgstr "Experimental horizontal deblocking filter 1"
+
+#: src/lib/filter.cc:73
+msgid "Experimental vertical deblocking filter 1"
+msgstr "Experimental vertical deblocking filter 1"
+
+#: src/lib/filter.cc:79
+msgid "FFMPEG deinterlacer"
+msgstr "Desentrelazado FFMPEG"
+
+#: src/lib/filter.cc:80
+msgid "FIR low-pass deinterlacer"
+msgstr "Desentrelazado paso bajo FIR"
+
+#: src/lib/scp_dcp_job.cc:138
+msgid "Failed to authenticate with server (%1)"
+msgstr "Fallo al identificarse con el servidor (%1)"
+
+#: src/lib/scaler.cc:70
+msgid "Fast Bilinear"
+msgstr "Bilineal rápido"
+
+#: src/lib/dcp_content_type.cc:44
+msgid "Feature"
+msgstr "Película"
+
+#: src/lib/format.cc:111
+msgid "Flat"
+msgstr "Flat"
+
+#: src/lib/format.cc:123
+msgid "Flat without stretch"
+msgstr "Flat sin deformación"
+
+#: src/lib/filter.cc:85
+msgid "Force quantizer"
+msgstr "Force quantizer"
+
+#: src/lib/scaler.cc:65
+msgid "Gaussian"
+msgstr "Gaussiano"
+
+#: src/lib/filter.cc:86
+msgid "Gradient debander"
+msgstr "Gradient debander"
+
+#: src/lib/filter.cc:89
+msgid "High quality 3D denoiser"
+msgstr "Reductor de ruido 3D de alta calidad"
+
+#: src/lib/filter.cc:68
+msgid "Horizontal deblocking filter"
+msgstr "Horizontal deblocking filter"
+
+#: src/lib/filter.cc:70
+msgid "Horizontal deblocking filter A"
+msgstr "Horizontal deblocking filter A"
+
+#: src/lib/job.cc:92 src/lib/job.cc:101
+msgid ""
+"It is not known what caused this error. The best idea is to report the "
+"problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)"
+msgstr ""
+"Error desconocido. La mejor idea es informar del problema a la lista de "
+"correo de DVD-O-matic (dvdomatic@carlh.net)"
+
+#: src/lib/filter.cc:82
+msgid "Kernel deinterlacer"
+msgstr "Kernel deinterlacer"
+
+#: src/lib/scaler.cc:66
+msgid "Lanczos"
+msgstr "Lanczos"
+
+#: src/lib/util.cc:930
+msgid "Left"
+msgstr ""
+
+#: src/lib/util.cc:934
+msgid "Left surround"
+msgstr ""
+
+#: src/lib/util.cc:933
+msgid "Lfe (sub)"
+msgstr ""
+
+#: src/lib/filter.cc:75
+msgid "Linear blend deinterlacer"
+msgstr "Linear blend deinterlacer"
+
+#: src/lib/filter.cc:76
+msgid "Linear interpolating deinterlacer"
+msgstr "Linear interpolating deinterlacer"
+
+#: src/lib/filter.cc:78
+msgid "Median deinterlacer"
+msgstr "Median deinterlacer"
+
+#: src/lib/filter.cc:74 src/lib/filter.cc:85 src/lib/filter.cc:86
+#: src/lib/filter.cc:87 src/lib/filter.cc:90
+msgid "Misc"
+msgstr "Miscelánea"
+
+#: src/lib/filter.cc:81
+msgid "Motion compensating deinterlacer"
+msgstr "Motion compensating deinterlacer"
+
+#: src/lib/filter.cc:84 src/lib/filter.cc:88 src/lib/filter.cc:89
+#: src/lib/filter.cc:91
+msgid "Noise reduction"
+msgstr "Reducción de ruido"
+
+#: src/lib/job.cc:298
+msgid "OK (ran for %1)"
+msgstr "OK (ejecución %1)"
+
+#: src/lib/filter.cc:91
+msgid "Overcomplete wavelet denoiser"
+msgstr "Overcomplete wavelet denoiser"
+
+#: src/lib/dcp_content_type.cc:51
+msgid "Policy"
+msgstr "Policy"
+
+#: src/lib/dcp_content_type.cc:52
+msgid "Public Service Announcement"
+msgstr "Anuncio de servicio público"
+
+#: src/lib/dcp_content_type.cc:49
+msgid "Rating"
+msgstr "Clasificación"
+
+#: src/lib/util.cc:500
+msgid "Rec 709"
+msgstr "Rec 709"
+
+#: src/lib/util.cc:931
+msgid "Right"
+msgstr ""
+
+#: src/lib/util.cc:935
+msgid "Right surround"
+msgstr ""
+
+#: src/lib/scp_dcp_job.cc:133
+msgid "SSH error (%1)"
+msgstr "error SSH (%1)"
+
+#: src/lib/format.cc:119
+msgid "Scope"
+msgstr "Scope"
+
+#: src/lib/format.cc:127
+msgid "Scope without stretch"
+msgstr "Scope sin deformación"
+
+#: src/lib/dcp_content_type.cc:45
+msgid "Short"
+msgstr "Cortometraje"
+
+#: src/lib/scaler.cc:67
+msgid "Sinc"
+msgstr "Sinc"
+
+#: src/lib/scaler.cc:68
+msgid "Spline"
+msgstr "Spline"
+
+#: src/lib/dcp_content_type.cc:50
+msgid "Teaser"
+msgstr "Teaser"
+
+#: src/lib/filter.cc:90
+msgid "Telecine filter"
+msgstr "Filtro telecine"
+
+#: src/lib/filter.cc:84
+msgid "Temporal noise reducer"
+msgstr "Temporal noise reducer"
+
+#: src/lib/dcp_content_type.cc:47
+msgid "Test"
+msgstr "Test"
+
+#: src/lib/job.cc:77
+msgid ""
+"The drive that the film is stored on is low in disc space. Free some more "
+"space and try again."
+msgstr ""
+"En el dispositivo donde se encuentra la película queda poco espacio. Libere "
+"espacio en el disco y pruebe de nuevo."
+
+#: src/lib/dcp_content_type.cc:46
+msgid "Trailer"
+msgstr "Trailer"
+
+#: src/lib/transcode_job.cc:54
+msgid "Transcode %1"
+msgstr "Codificar %1"
+
+#: src/lib/dcp_content_type.cc:48
+msgid "Transitional"
+msgstr "Transitional"
+
+#: src/lib/job.cc:100
+msgid "Unknown error"
+msgstr "Error desconocido"
+
+#: src/lib/ffmpeg_decoder.cc:396
+msgid "Unrecognised audio sample format (%1)"
+msgstr "Formato de audio desconocido (%1)"
+
+#: src/lib/filter.cc:87
+msgid "Unsharp mask and Gaussian blur"
+msgstr "Máscara de desenfoque Gaussiano"
+
+#: src/lib/filter.cc:69
+msgid "Vertical deblocking filter"
+msgstr "Vertical deblocking filter"
+
+#: src/lib/filter.cc:71
+msgid "Vertical deblocking filter A"
+msgstr "Vertical deblocking filter A"
+
+#: src/lib/scp_dcp_job.cc:101
+msgid "Waiting"
+msgstr "Esperando"
+
+#: src/lib/scaler.cc:63
+msgid "X"
+msgstr "X"
+
+#: src/lib/filter.cc:83
+msgid "Yet Another Deinterlacing Filter"
+msgstr "Yet Another Deinterlacing Filter"
+
+#: src/lib/film.cc:263
+msgid "cannot contain slashes"
+msgstr "no puede contener barras"
+
+#: src/lib/util.cc:541
+msgid "connect timed out"
+msgstr "tiempo de conexión agotado"
+
+#: src/lib/scp_dcp_job.cc:119
+msgid "connecting"
+msgstr "conectando"
+
+#: src/lib/film.cc:300
+msgid "content"
+msgstr "contenido"
+
+#: src/lib/film.cc:304
+msgid "content type"
+msgstr "tipo de contenido"
+
+#: src/lib/scp_dcp_job.cc:168
+msgid "copying %1"
+msgstr "copiando %1"
+
+#: src/lib/exceptions.cc:36
+#, fuzzy
+msgid "could not create file %1"
+msgstr "No se pudo escribir el fichero remoto (%1)"
+
+#: src/lib/ffmpeg_decoder.cc:191
+msgid "could not find audio decoder"
+msgstr "no se encontró el decodificador de audio"
+
+#: src/lib/ffmpeg_decoder.cc:118
+msgid "could not find stream information"
+msgstr "no se pudo encontrar información del flujo"
+
+#: src/lib/ffmpeg_decoder.cc:210
+msgid "could not find subtitle decoder"
+msgstr "no se pudo encontrar decodificador de subtítutlos"
+
+#: src/lib/ffmpeg_decoder.cc:169
+msgid "could not find video decoder"
+msgstr "no se pudo encontrar decodificador de vídeo"
+
+#: src/lib/sndfile_decoder.cc:72
+msgid "could not open external audio file for reading"
+msgstr "no se pudo leer el fichero externo de audio"
+
+#: src/lib/exceptions.cc:29
+#, fuzzy
+msgid "could not open file %1"
+msgstr "no se pudo abrir el fichero para lectura"
+
+#: src/lib/dcp_video_frame.cc:388
+msgid "could not open file for reading"
+msgstr "no se pudo abrir el fichero para lectura"
+
+#: src/lib/exceptions.cc:44
+#, fuzzy
+msgid "could not read from file %1 (%2)"
+msgstr "No se pudo crear la carpeta remota %1 (%2)"
+
+#: src/lib/encoder.cc:137 src/lib/encoder.cc:314
+msgid "could not run sample-rate converter"
+msgstr "no se pudo ejecutar el conversor de velocidad"
+
+#: src/lib/scp_dcp_job.cc:86
+msgid "could not start SCP session (%1)"
+msgstr "no se pudo abrir la sesión SCP (%1)"
+
+#: src/lib/scp_dcp_job.cc:52
+msgid "could not start SSH session"
+msgstr "no se pudo abrir la sesión SSH"
+
+#: src/lib/exceptions.cc:50
+#, fuzzy
+msgid "could not write to file %1 (%2)"
+msgstr "No se pudo escribir el fichero remoto (%1)"
+
+#: src/lib/sndfile_decoder.cc:94
+msgid "external audio files have differing lengths"
+msgstr "los ficheros externos de sonido tienen duraciones diferentes"
+
+#: src/lib/sndfile_decoder.cc:76
+msgid "external audio files must be mono"
+msgstr "los ficheros externos de sonido deben ser mono"
+
+#: src/lib/film.cc:296
+msgid "format"
+msgstr "formato"
+
+#: src/lib/transcode_job.cc:100
+msgid "frames per second"
+msgstr "fotogramas por segundo"
+
+#: src/lib/util.cc:115
+msgid "hour"
+msgstr "hora"
+
+#: src/lib/util.cc:112 src/lib/util.cc:117
+msgid "hours"
+msgstr "horas"
+
+#: src/lib/util.cc:122
+msgid "minute"
+msgstr "minuto"
+
+#: src/lib/util.cc:124
+msgid "minutes"
+msgstr "minutos"
+
+#: src/lib/util.cc:684
+msgid "missing key %1 in key-value set"
+msgstr "falta la clave %1 en el par clave-valor"
+
+#: src/lib/exceptions.cc:54
+msgid "missing required setting %1"
+msgstr ""
+
+#: src/lib/subtitle.cc:52
+msgid "multi-part subtitles not yet supported"
+msgstr "todavía no se soportan subtítulos en múltiples partes"
+
+#: src/lib/film.cc:263 src/lib/film.cc:308
+msgid "name"
+msgstr "nombre"
+
+#: src/lib/imagemagick_decoder.cc:60
+msgid "no still image files found"
+msgstr "no se encuentran imágenes fijas"
+
+#: src/lib/subtitle.cc:58
+msgid "non-bitmap subtitles not yet supported"
+msgstr "todavía no se soportan subtítulos que no son en mapas de bits"
+
+#. / TRANSLATORS: remaining here follows an amount of time that is remaining
+#. / on an operation.
+#: src/lib/job.cc:295
+msgid "remaining"
+msgstr "pendiente"
+
+#: src/lib/util.cc:498
+msgid "sRGB"
+msgstr "sRGB"
+
+#: src/lib/util.cc:127
+msgid "seconds"
+msgstr "segundos"
+
+#: src/lib/film.cc:274
+msgid "still"
+msgstr "imagen fija"
+
+#: src/lib/film.cc:274
+msgid "video"
+msgstr "vídeo"
+
+#~ msgid "Source scaled to 1.19:1"
+#~ msgstr "Fuente escalada a 1.19:1"
+
+#~ msgid "Source scaled to 1.33:1"
+#~ msgstr "Fuente escalada a 1.33:1"
+
+#~ msgid "Source scaled to 1.33:1 then pillarboxed to Flat"
+#~ msgstr "Fuente escalada a 1.33:1 con bandas hasta Flat"
+
+#~ msgid "Source scaled to 1.375:1"
+#~ msgstr "Fuente escalada a 1.375:1"
+
+#~ msgid "Source scaled to 1.37:1 (Academy ratio)"
+#~ msgstr "Fuente escalada a 1.37:1 (Academy)"
+
+#~ msgid "Source scaled to 1.66:1"
+#~ msgstr "Fuente escalada a 1.66:1"
+
+#~ msgid "Source scaled to 1.66:1 then pillarboxed to Flat"
+#~ msgstr "Fuente escalada a 1.66:1 con bandas hasta Flat"
+
+#~ msgid "Source scaled to 1.78:1"
+#~ msgstr "Fuente escalada a 1.78:1"
+
+#~ msgid "Source scaled to 1.78:1 then pillarboxed to Flat"
+#~ msgstr "Fuente escalada a 1.78:1 con bandas hasta Flat"
+
+#~ msgid "Source scaled to Flat (1.85:1)"
+#~ msgstr "Fuente escalada a Flat (1.85:1)"
+
+#~ msgid "Source scaled to Scope (2.39:1)"
+#~ msgstr "Fuente escalada a Scope (2.39:1)"
+
+#~ msgid "Source scaled to fit Flat preserving its aspect ratio"
+#~ msgstr "Fuente escalada a Flat conservando el ratio de aspecto"
+
+#~ msgid "Source scaled to fit Scope preserving its aspect ratio"
+#~ msgstr "Fuente escalada a Scope conservando el ratio de aspecto"
+
+#~ msgid "adding to queue of %1"
+#~ msgstr "añadiendo a la cola de %1"
diff --git a/src/lib/po/fr_FR.po b/src/lib/po/fr_FR.po
new file mode 100644
index 000000000..d9d945b52
--- /dev/null
+++ b/src/lib/po/fr_FR.po
@@ -0,0 +1,626 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: DVD-o-matic FRENCH\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-04-09 11:14+0100\n"
+"PO-Revision-Date: 2013-03-20 00:39+0100\n"
+"Last-Translator: FreeDCP.net <freedcp.net@gmail.com>\n"
+"Language-Team: \n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: src/lib/transcode_job.cc:87
+msgid "0%"
+msgstr "0%"
+
+#: src/lib/format.cc:75
+msgid "1.19"
+msgstr "1.19"
+
+#: src/lib/format.cc:79
+msgid "1.33"
+msgstr "1.33"
+
+#: src/lib/format.cc:83
+msgid "1.375"
+msgstr "1.375"
+
+#: src/lib/format.cc:95
+msgid "1.66"
+msgstr "1.66"
+
+#: src/lib/format.cc:99
+msgid "1.66 within Flat"
+msgstr "1.66 dans Flat"
+
+#: src/lib/format.cc:107
+msgid "16:9"
+msgstr "16:9"
+
+#: src/lib/format.cc:103
+msgid "16:9 within Flat"
+msgstr "16:9 dans Flat"
+
+#: src/lib/format.cc:115
+#, fuzzy
+msgid "16:9 within Scope"
+msgstr "16:9 dans Flat"
+
+#: src/lib/filter.cc:88
+msgid "3D denoiser"
+msgstr "Débruitage 3D"
+
+#: src/lib/format.cc:87
+msgid "4:3 within Flat"
+msgstr "4:3 dans Flat"
+
+#: src/lib/ab_transcode_job.cc:49
+msgid "A/B transcode %1"
+msgstr "Transcodage A/B %1"
+
+#: src/lib/format.cc:91
+msgid "Academy"
+msgstr "Academy"
+
+#: src/lib/dcp_content_type.cc:53
+msgid "Advertisement"
+msgstr "Advertisement"
+
+#: src/lib/job.cc:72
+msgid "An error occurred whilst handling the file %1."
+msgstr "Une erreur s'est produite lors du traitement du fichier %1."
+
+#: src/lib/analyse_audio_job.cc:49
+msgid "Analyse audio of %1"
+msgstr "Analyse du son de %1"
+
+#: src/lib/scaler.cc:64
+msgid "Area"
+msgstr "Area"
+
+#: src/lib/scaler.cc:62
+msgid "Bicubic"
+msgstr "Bicubique"
+
+#: src/lib/scaler.cc:69
+msgid "Bilinear"
+msgstr "Bilinéaire"
+
+#: src/lib/job.cc:302
+msgid "Cancelled"
+msgstr ""
+
+#: src/lib/exceptions.cc:60
+msgid "Cannot handle pixel format %1 during %2"
+msgstr ""
+
+#: src/lib/encoder.cc:101
+msgid "Cannot resample audio as libswresample is not present"
+msgstr "Ré-échantillonnage du son impossible : libswresample est absent"
+
+#: src/lib/util.cc:932
+msgid "Centre"
+msgstr ""
+
+#: src/lib/scp_dcp_job.cc:109
+msgid "Copy DCP to TMS"
+msgstr "Copier le DCP dans le TMS"
+
+#: src/lib/scp_dcp_job.cc:128
+msgid "Could not connect to server %1 (%2)"
+msgstr "Connexion au serveur %1 (%2) impossible"
+
+#: src/lib/scp_dcp_job.cc:150
+msgid "Could not create remote directory %1 (%2)"
+msgstr "Création du dossier distant %1 (%2) impossible"
+
+#: src/lib/scp_dcp_job.cc:175
+msgid "Could not open %1 to send"
+msgstr "Ouverture de %1 pour envoi impossible"
+
+#: src/lib/scp_dcp_job.cc:145
+msgid "Could not start SCP session (%1)"
+msgstr "Démarrage de session SCP (%1) impossible"
+
+#: src/lib/scp_dcp_job.cc:187
+msgid "Could not write to remote file (%1)"
+msgstr "Écriture vers fichier distant (%1) impossible"
+
+#: src/lib/filter.cc:77
+msgid "Cubic interpolating deinterlacer"
+msgstr "Désentrelacement cubique interpolé"
+
+#: src/lib/util.cc:1007
+msgid "DCP and source have the same rate.\n"
+msgstr "Le DCP et la source ont les mêmes cadences.\n"
+
+#: src/lib/util.cc:1017
+#, fuzzy
+msgid "DCP will run at %1%% of the source speed.\n"
+msgstr "La cadence du DCP sera %1%% par rapport à la source.\n"
+
+#: src/lib/util.cc:1010
+msgid "DCP will use every other frame of the source.\n"
+msgstr "Le DCP utilisera une image sur deux de la source.\n"
+
+#: src/lib/filter.cc:68 src/lib/filter.cc:69 src/lib/filter.cc:70
+#: src/lib/filter.cc:71 src/lib/filter.cc:72 src/lib/filter.cc:73
+msgid "De-blocking"
+msgstr "De-bloc"
+
+#: src/lib/filter.cc:75 src/lib/filter.cc:76 src/lib/filter.cc:77
+#: src/lib/filter.cc:78 src/lib/filter.cc:79 src/lib/filter.cc:80
+#: src/lib/filter.cc:81 src/lib/filter.cc:82 src/lib/filter.cc:83
+msgid "De-interlacing"
+msgstr "Désentrelacement"
+
+#: src/lib/filter.cc:74
+msgid "Deringing filter"
+msgstr "Filtre anti bourdonnement"
+
+#: src/lib/dolby_cp750.cc:27
+msgid "Dolby CP750"
+msgstr "Dolby CP750"
+
+#: src/lib/util.cc:1012
+msgid "Each source frame will be doubled in the DCP.\n"
+msgstr "Chaque image source sera dupliquée dans le DCP.\n"
+
+#: src/lib/job.cc:300
+msgid "Error (%1)"
+msgstr "Erreur (%1)"
+
+#: src/lib/examine_content_job.cc:55
+msgid "Examine content"
+msgstr "Examen du contenu"
+
+#: src/lib/examine_content_job.cc:58
+msgid "Examine content of %1"
+msgstr "Examen du contenu de %1"
+
+#: src/lib/filter.cc:72
+msgid "Experimental horizontal deblocking filter 1"
+msgstr "Filtre dé-bloc horizontal 1"
+
+#: src/lib/filter.cc:73
+msgid "Experimental vertical deblocking filter 1"
+msgstr "Filtre dé-bloc vertical 1"
+
+#: src/lib/filter.cc:79
+msgid "FFMPEG deinterlacer"
+msgstr "Désentrelaceur FFMPEG"
+
+#: src/lib/filter.cc:80
+msgid "FIR low-pass deinterlacer"
+msgstr "Désentrelaceur passe-bas FIR"
+
+#: src/lib/scp_dcp_job.cc:138
+msgid "Failed to authenticate with server (%1)"
+msgstr "L'authentification du serveur (%1) a échouée"
+
+#: src/lib/scaler.cc:70
+msgid "Fast Bilinear"
+msgstr "Bilinéaire rapide"
+
+#: src/lib/dcp_content_type.cc:44
+msgid "Feature"
+msgstr "Feature"
+
+#: src/lib/format.cc:111
+msgid "Flat"
+msgstr "Flat"
+
+#: src/lib/format.cc:123
+msgid "Flat without stretch"
+msgstr "Flat sans déformation"
+
+#: src/lib/filter.cc:85
+msgid "Force quantizer"
+msgstr "Forcer la quantification"
+
+#: src/lib/scaler.cc:65
+msgid "Gaussian"
+msgstr "Gaussien"
+
+#: src/lib/filter.cc:86
+msgid "Gradient debander"
+msgstr "Corrections des bandes du dégradé"
+
+#: src/lib/filter.cc:89
+msgid "High quality 3D denoiser"
+msgstr "Débruiteur 3D haute qualité"
+
+#: src/lib/filter.cc:68
+msgid "Horizontal deblocking filter"
+msgstr "Filtre dé-bloc horizontal"
+
+#: src/lib/filter.cc:70
+msgid "Horizontal deblocking filter A"
+msgstr "Filtre dé-bloc horizontal"
+
+#: src/lib/job.cc:92 src/lib/job.cc:101
+msgid ""
+"It is not known what caused this error. The best idea is to report the "
+"problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)"
+msgstr ""
+"Erreur indéterminée. Merci de rapporter le problème à la liste DVD-o-matic "
+"(dvdomatic@carlh.net)"
+
+#: src/lib/filter.cc:82
+msgid "Kernel deinterlacer"
+msgstr "Désentrelaceur noyau"
+
+#: src/lib/scaler.cc:66
+msgid "Lanczos"
+msgstr "Lanczos"
+
+#: src/lib/util.cc:930
+msgid "Left"
+msgstr "Gauche"
+
+#: src/lib/util.cc:934
+msgid "Left surround"
+msgstr "Arrière gauche"
+
+#: src/lib/util.cc:933
+msgid "Lfe (sub)"
+msgstr "Basses fréquences"
+
+#: src/lib/filter.cc:75
+msgid "Linear blend deinterlacer"
+msgstr "Désentrelaceur par mélange interpolé"
+
+#: src/lib/filter.cc:76
+msgid "Linear interpolating deinterlacer"
+msgstr "Désentrelaceur linéaire interpolé"
+
+#: src/lib/filter.cc:78
+msgid "Median deinterlacer"
+msgstr "Désentrelaceur médian"
+
+#: src/lib/filter.cc:74 src/lib/filter.cc:85 src/lib/filter.cc:86
+#: src/lib/filter.cc:87 src/lib/filter.cc:90
+msgid "Misc"
+msgstr "Divers"
+
+#: src/lib/filter.cc:81
+msgid "Motion compensating deinterlacer"
+msgstr "Désentrelaceur par compensation de mouvement"
+
+#: src/lib/filter.cc:84 src/lib/filter.cc:88 src/lib/filter.cc:89
+#: src/lib/filter.cc:91
+msgid "Noise reduction"
+msgstr "Réduction de bruit"
+
+#: src/lib/job.cc:298
+msgid "OK (ran for %1)"
+msgstr "OK (processus %1)"
+
+#: src/lib/filter.cc:91
+msgid "Overcomplete wavelet denoiser"
+msgstr "Réduction de bruit par ondelettes"
+
+#: src/lib/dcp_content_type.cc:51
+msgid "Policy"
+msgstr "Policy"
+
+#: src/lib/dcp_content_type.cc:52
+msgid "Public Service Announcement"
+msgstr "Public Service Announcement"
+
+#: src/lib/dcp_content_type.cc:49
+msgid "Rating"
+msgstr "Classification"
+
+#: src/lib/util.cc:500
+msgid "Rec 709"
+msgstr "Rec 709"
+
+#: src/lib/util.cc:931
+msgid "Right"
+msgstr "Droite"
+
+#: src/lib/util.cc:935
+msgid "Right surround"
+msgstr "Arrière droite"
+
+#: src/lib/scp_dcp_job.cc:133
+msgid "SSH error (%1)"
+msgstr "Erreur SSH (%1)"
+
+#: src/lib/format.cc:119
+msgid "Scope"
+msgstr "Scope"
+
+#: src/lib/format.cc:127
+msgid "Scope without stretch"
+msgstr "Scope sans déformation"
+
+#: src/lib/dcp_content_type.cc:45
+msgid "Short"
+msgstr "Short"
+
+#: src/lib/scaler.cc:67
+msgid "Sinc"
+msgstr "Sinc"
+
+#: src/lib/scaler.cc:68
+msgid "Spline"
+msgstr "Spline"
+
+#: src/lib/dcp_content_type.cc:50
+msgid "Teaser"
+msgstr "Teaser"
+
+#: src/lib/filter.cc:90
+msgid "Telecine filter"
+msgstr "Filtre télécinéma"
+
+#: src/lib/filter.cc:84
+msgid "Temporal noise reducer"
+msgstr "Réduction de bruit temporel"
+
+#: src/lib/dcp_content_type.cc:47
+msgid "Test"
+msgstr "Test"
+
+#: src/lib/job.cc:77
+msgid ""
+"The drive that the film is stored on is low in disc space. Free some more "
+"space and try again."
+msgstr ""
+"Le disque contenant le film est plein. Libérez de l'espace et essayez à "
+"nouveau."
+
+#: src/lib/dcp_content_type.cc:46
+msgid "Trailer"
+msgstr "Trailer"
+
+#: src/lib/transcode_job.cc:54
+msgid "Transcode %1"
+msgstr "Transcodage %1"
+
+#: src/lib/dcp_content_type.cc:48
+msgid "Transitional"
+msgstr "Transitional"
+
+#: src/lib/job.cc:100
+msgid "Unknown error"
+msgstr "Erreur inconnue"
+
+#: src/lib/ffmpeg_decoder.cc:396
+msgid "Unrecognised audio sample format (%1)"
+msgstr "Échantillonnage audio (%1) inconnu"
+
+#: src/lib/filter.cc:87
+msgid "Unsharp mask and Gaussian blur"
+msgstr "Adoucissement et flou Gaussien"
+
+#: src/lib/filter.cc:69
+msgid "Vertical deblocking filter"
+msgstr "Filtre dé-bloc vertical"
+
+#: src/lib/filter.cc:71
+msgid "Vertical deblocking filter A"
+msgstr "Filtre dé-bloc vertical A"
+
+#: src/lib/scp_dcp_job.cc:101
+msgid "Waiting"
+msgstr "En cours"
+
+#: src/lib/scaler.cc:63
+msgid "X"
+msgstr "X"
+
+#: src/lib/filter.cc:83
+msgid "Yet Another Deinterlacing Filter"
+msgstr "Un autre filtre de désentrelacement"
+
+#: src/lib/film.cc:263
+msgid "cannot contain slashes"
+msgstr "slash interdit"
+
+#: src/lib/util.cc:541
+msgid "connect timed out"
+msgstr "temps de connexion expiré"
+
+#: src/lib/scp_dcp_job.cc:119
+msgid "connecting"
+msgstr "connexion"
+
+#: src/lib/film.cc:300
+msgid "content"
+msgstr "contenu"
+
+#: src/lib/film.cc:304
+msgid "content type"
+msgstr "type de contenu"
+
+#: src/lib/scp_dcp_job.cc:168
+msgid "copying %1"
+msgstr "copie de %1"
+
+#: src/lib/exceptions.cc:36
+msgid "could not create file %1"
+msgstr "Écriture vers fichier distant (%1) impossible"
+
+#: src/lib/ffmpeg_decoder.cc:191
+msgid "could not find audio decoder"
+msgstr "décodeur audio introuvable"
+
+#: src/lib/ffmpeg_decoder.cc:118
+msgid "could not find stream information"
+msgstr "information du flux introuvable"
+
+#: src/lib/ffmpeg_decoder.cc:210
+msgid "could not find subtitle decoder"
+msgstr "décodeur de sous-titre introuvable"
+
+#: src/lib/ffmpeg_decoder.cc:169
+msgid "could not find video decoder"
+msgstr "décodeur vidéo introuvable"
+
+#: src/lib/sndfile_decoder.cc:72
+msgid "could not open external audio file for reading"
+msgstr "lecture du fichier audio externe impossible"
+
+#: src/lib/exceptions.cc:29
+msgid "could not open file %1"
+msgstr "lecture du fichier (%1) impossible"
+
+#: src/lib/dcp_video_frame.cc:388
+msgid "could not open file for reading"
+msgstr "lecture du fichier impossible"
+
+#: src/lib/exceptions.cc:44
+msgid "could not read from file %1 (%2)"
+msgstr "Création du dossier distant %1 impossible (%2)"
+
+#: src/lib/encoder.cc:137 src/lib/encoder.cc:314
+msgid "could not run sample-rate converter"
+msgstr "conversion de la fréquence d'échantillonnage impossible"
+
+#: src/lib/scp_dcp_job.cc:86
+msgid "could not start SCP session (%1)"
+msgstr "démarrage de session SCP (%1) impossible"
+
+#: src/lib/scp_dcp_job.cc:52
+msgid "could not start SSH session"
+msgstr "démarrage de session SSH impossible"
+
+#: src/lib/exceptions.cc:50
+msgid "could not write to file %1 (%2)"
+msgstr "Écriture vers fichier distant (%1) impossible (%2)"
+
+#: src/lib/sndfile_decoder.cc:94
+msgid "external audio files have differing lengths"
+msgstr "Les fichiers audio externes ont des durées différentes"
+
+#: src/lib/sndfile_decoder.cc:76
+msgid "external audio files must be mono"
+msgstr "les fichiers audio externes doivent être en mono"
+
+#: src/lib/film.cc:296
+msgid "format"
+msgstr "format"
+
+#: src/lib/transcode_job.cc:100
+msgid "frames per second"
+msgstr "images par seconde"
+
+#: src/lib/util.cc:115
+msgid "hour"
+msgstr "heure"
+
+#: src/lib/util.cc:112 src/lib/util.cc:117
+msgid "hours"
+msgstr "heures"
+
+#: src/lib/util.cc:122
+msgid "minute"
+msgstr "minute"
+
+#: src/lib/util.cc:124
+msgid "minutes"
+msgstr "minutes"
+
+#: src/lib/util.cc:684
+msgid "missing key %1 in key-value set"
+msgstr "clé %1 non sélectionnée"
+
+#: src/lib/exceptions.cc:54
+msgid "missing required setting %1"
+msgstr ""
+
+#: src/lib/subtitle.cc:52
+msgid "multi-part subtitles not yet supported"
+msgstr "sous-titres en plusieurs parties non supportés"
+
+#: src/lib/film.cc:263 src/lib/film.cc:308
+msgid "name"
+msgstr "nom"
+
+#: src/lib/imagemagick_decoder.cc:60
+msgid "no still image files found"
+msgstr "aucune image fixe trouvée"
+
+#: src/lib/subtitle.cc:58
+msgid "non-bitmap subtitles not yet supported"
+msgstr "sous-titres non-bitmap non supportés actuellement"
+
+#. / TRANSLATORS: remaining here follows an amount of time that is remaining
+#. / on an operation.
+#: src/lib/job.cc:295
+msgid "remaining"
+msgstr "restant"
+
+#: src/lib/util.cc:498
+msgid "sRGB"
+msgstr "sRGB"
+
+#: src/lib/util.cc:127
+msgid "seconds"
+msgstr "secondes"
+
+#: src/lib/film.cc:274
+msgid "still"
+msgstr "fixe"
+
+#: src/lib/film.cc:274
+msgid "video"
+msgstr "vidéo"
+
+#~ msgid "Source scaled to 1.19:1"
+#~ msgstr "Source mise à l'échelle en 1.19:1"
+
+#~ msgid "Source scaled to 1.33:1"
+#~ msgstr "Source mise à l'échelle en 1.33:1"
+
+#~ msgid "Source scaled to 1.33:1 then pillarboxed to Flat"
+#~ msgstr "Source mise à l'échelle en 1.33:1 puis contenue dans Flat"
+
+#~ msgid "Source scaled to 1.375:1"
+#~ msgstr "Source mise à l'échelle en 1.375:1"
+
+#~ msgid "Source scaled to 1.37:1 (Academy ratio)"
+#~ msgstr "Source mise à l'échelle en 1.37:1 (ratio \"academy\")"
+
+#~ msgid "Source scaled to 1.66:1"
+#~ msgstr "Source mise à l'échelle en 1.66:1"
+
+#~ msgid "Source scaled to 1.66:1 then pillarboxed to Flat"
+#~ msgstr "Source mise à l'échelle en 1.66:1 puis contenue dans Flat"
+
+#~ msgid "Source scaled to 1.78:1"
+#~ msgstr "Source mise à l'échelle en 1.78:1"
+
+#~ msgid "Source scaled to 1.78:1 then pillarboxed to Flat"
+#~ msgstr "Source mise à l'échelle en 1.78:1 puis contenue dans Flat"
+
+#~ msgid "Source scaled to Flat (1.85:1)"
+#~ msgstr "Source mise à l'échelle en Flat (1.85:1)"
+
+#~ msgid "Source scaled to Scope (2.39:1)"
+#~ msgstr "Source mise à l'échelle en Scope (2.39:1)"
+
+#~ msgid "Source scaled to fit Flat preserving its aspect ratio"
+#~ msgstr "Source réduite en Flat afin de préserver ses dimensions"
+
+#~ msgid "Source scaled to fit Scope preserving its aspect ratio"
+#~ msgstr "Source réduite en Scope afin de préserver ses dimensions"
+
+#~ msgid "adding to queue of %1"
+#~ msgstr "Mise en file d'attente de %1"
+
+#~ msgid "decoder sleeps with queue of %1"
+#~ msgstr "décodeur en veille avec %1 en file d'attente"
+
+#~ msgid "decoder wakes with queue of %1"
+#~ msgstr "reprise du décodage avec %1 en file d'attente"
diff --git a/src/lib/po/it_IT.po b/src/lib/po/it_IT.po
new file mode 100644
index 000000000..992eda107
--- /dev/null
+++ b/src/lib/po/it_IT.po
@@ -0,0 +1,628 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: IT VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-04-09 11:14+0100\n"
+"PO-Revision-Date: 2013-04-03 15:04+0100\n"
+"Last-Translator: Maci <macibro@gmail.com>\n"
+"Language-Team: \n"
+"Language: Italiano\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 1.5.5\n"
+
+#: src/lib/transcode_job.cc:87
+msgid "0%"
+msgstr "0%"
+
+#: src/lib/format.cc:75
+msgid "1.19"
+msgstr "1.19"
+
+#: src/lib/format.cc:79
+msgid "1.33"
+msgstr "1.33"
+
+#: src/lib/format.cc:83
+msgid "1.375"
+msgstr "1.375"
+
+#: src/lib/format.cc:95
+msgid "1.66"
+msgstr "1.66"
+
+#: src/lib/format.cc:99
+msgid "1.66 within Flat"
+msgstr "1.66 all'interno di Flat"
+
+#: src/lib/format.cc:107
+msgid "16:9"
+msgstr "16:9"
+
+#: src/lib/format.cc:103
+msgid "16:9 within Flat"
+msgstr "16:9 all'interno di Flat"
+
+#: src/lib/format.cc:115
+#, fuzzy
+msgid "16:9 within Scope"
+msgstr "16:9 all'interno di Flat"
+
+#: src/lib/filter.cc:88
+msgid "3D denoiser"
+msgstr "Riduttore di rumore 3D"
+
+#: src/lib/format.cc:87
+msgid "4:3 within Flat"
+msgstr "4:3 all'interno di Flat"
+
+#: src/lib/ab_transcode_job.cc:49
+msgid "A/B transcode %1"
+msgstr "Transcodifica A/B %1"
+
+#: src/lib/format.cc:91
+msgid "Academy"
+msgstr "Academy"
+
+#: src/lib/dcp_content_type.cc:53
+msgid "Advertisement"
+msgstr "Pubblicità"
+
+#: src/lib/job.cc:72
+msgid "An error occurred whilst handling the file %1."
+msgstr "Errore durante l'elaborazione del file %1."
+
+#: src/lib/analyse_audio_job.cc:49
+msgid "Analyse audio of %1"
+msgstr "Analizzo l'audio di %1"
+
+#: src/lib/scaler.cc:64
+msgid "Area"
+msgstr "Area"
+
+#: src/lib/scaler.cc:62
+msgid "Bicubic"
+msgstr "Bicubica"
+
+#: src/lib/scaler.cc:69
+msgid "Bilinear"
+msgstr "Bilineare"
+
+#: src/lib/job.cc:302
+msgid "Cancelled"
+msgstr "Cancellato"
+
+#: src/lib/exceptions.cc:60
+msgid "Cannot handle pixel format %1 during %2"
+msgstr "Non posso gestire il formato di pixel %1 durante %2"
+
+#: src/lib/encoder.cc:101
+msgid "Cannot resample audio as libswresample is not present"
+msgstr "Non posso ricampionare l'audio perchè libswresample non è presente"
+
+#: src/lib/util.cc:932
+msgid "Centre"
+msgstr "Centro"
+
+#: src/lib/scp_dcp_job.cc:109
+msgid "Copy DCP to TMS"
+msgstr "Copia del DCP al TMS"
+
+#: src/lib/scp_dcp_job.cc:128
+msgid "Could not connect to server %1 (%2)"
+msgstr "Non posso connetermi al server %1 (%2)"
+
+#: src/lib/scp_dcp_job.cc:150
+msgid "Could not create remote directory %1 (%2)"
+msgstr "Non posso creare la directory remota %1 (%2)"
+
+#: src/lib/scp_dcp_job.cc:175
+msgid "Could not open %1 to send"
+msgstr "Non posso aprire %1 da inviare"
+
+#: src/lib/scp_dcp_job.cc:145
+msgid "Could not start SCP session (%1)"
+msgstr "Non posso avviare la sessione SCP (%1)"
+
+#: src/lib/scp_dcp_job.cc:187
+msgid "Could not write to remote file (%1)"
+msgstr "Non posso scrivere il file remoto (%1)"
+
+#: src/lib/filter.cc:77
+msgid "Cubic interpolating deinterlacer"
+msgstr "Deinterlacciatore cubico interpolato"
+
+#: src/lib/util.cc:1007
+msgid "DCP and source have the same rate.\n"
+msgstr "Il DCP e il sorgente hanno la stessa frequenza.\n"
+
+#: src/lib/util.cc:1017
+msgid "DCP will run at %1%% of the source speed.\n"
+msgstr "Il DCP andrà al %1%% della velocità del sorgente.\n"
+
+#: src/lib/util.cc:1010
+msgid "DCP will use every other frame of the source.\n"
+msgstr "Il DCP userà ogni altro fotogramma del sorgente.\n"
+
+#: src/lib/filter.cc:68 src/lib/filter.cc:69 src/lib/filter.cc:70
+#: src/lib/filter.cc:71 src/lib/filter.cc:72 src/lib/filter.cc:73
+msgid "De-blocking"
+msgstr "Sbloccaggio"
+
+#: src/lib/filter.cc:75 src/lib/filter.cc:76 src/lib/filter.cc:77
+#: src/lib/filter.cc:78 src/lib/filter.cc:79 src/lib/filter.cc:80
+#: src/lib/filter.cc:81 src/lib/filter.cc:82 src/lib/filter.cc:83
+msgid "De-interlacing"
+msgstr "De-interlacciamento"
+
+#: src/lib/filter.cc:74
+msgid "Deringing filter"
+msgstr "Filtro deringing"
+
+#: src/lib/dolby_cp750.cc:27
+msgid "Dolby CP750"
+msgstr "Dolby CP750"
+
+#: src/lib/util.cc:1012
+msgid "Each source frame will be doubled in the DCP.\n"
+msgstr "Ogni fotogramma del sorgente sarà raddoppiato nel DCP.\n"
+
+#: src/lib/job.cc:300
+msgid "Error (%1)"
+msgstr "Errore (%1)"
+
+#: src/lib/examine_content_job.cc:55
+msgid "Examine content"
+msgstr "Esamino il contenuto"
+
+#: src/lib/examine_content_job.cc:58
+msgid "Examine content of %1"
+msgstr "Esamo il contenuto di %1"
+
+#: src/lib/filter.cc:72
+msgid "Experimental horizontal deblocking filter 1"
+msgstr "Filtro di sblocco sperimentale orizzontale 1"
+
+#: src/lib/filter.cc:73
+msgid "Experimental vertical deblocking filter 1"
+msgstr "Filtro di sblocco sperimentale verticale 1"
+
+#: src/lib/filter.cc:79
+msgid "FFMPEG deinterlacer"
+msgstr "Deinterlacciatore FFMPEG"
+
+#: src/lib/filter.cc:80
+msgid "FIR low-pass deinterlacer"
+msgstr "Deinterlacciatore FIR low-pass"
+
+#: src/lib/scp_dcp_job.cc:138
+msgid "Failed to authenticate with server (%1)"
+msgstr "Autenticazione col server fallita (%1) "
+
+#: src/lib/scaler.cc:70
+msgid "Fast Bilinear"
+msgstr "Bilineare rapida"
+
+#: src/lib/dcp_content_type.cc:44
+msgid "Feature"
+msgstr "Caratteristica"
+
+#: src/lib/format.cc:111
+msgid "Flat"
+msgstr "Flat"
+
+#: src/lib/format.cc:123
+msgid "Flat without stretch"
+msgstr "Flat senza stiramento"
+
+#: src/lib/filter.cc:85
+msgid "Force quantizer"
+msgstr "Forza quantizzatore"
+
+#: src/lib/scaler.cc:65
+msgid "Gaussian"
+msgstr "Gaussiana"
+
+#: src/lib/filter.cc:86
+msgid "Gradient debander"
+msgstr "Gradiente debander"
+
+#: src/lib/filter.cc:89
+msgid "High quality 3D denoiser"
+msgstr "Riduttore di rumore 3D di alta qualità"
+
+#: src/lib/filter.cc:68
+msgid "Horizontal deblocking filter"
+msgstr "Filtro sblocco orizzontale"
+
+#: src/lib/filter.cc:70
+msgid "Horizontal deblocking filter A"
+msgstr "Filtro A sblocco orizzontale"
+
+#: src/lib/job.cc:92 src/lib/job.cc:101
+msgid ""
+"It is not known what caused this error. The best idea is to report the "
+"problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)"
+msgstr ""
+"Non sappiamo cosa ha causato questo errore. La cosa migliore è inviare un "
+"report del problema alla mailing list di DVD-o-matic (dvdomatic@carlh.net)"
+
+#: src/lib/filter.cc:82
+msgid "Kernel deinterlacer"
+msgstr "Deinterlacciatore Kernel"
+
+#: src/lib/scaler.cc:66
+msgid "Lanczos"
+msgstr "Lanczos"
+
+#: src/lib/util.cc:930
+msgid "Left"
+msgstr "Sinistro"
+
+#: src/lib/util.cc:934
+msgid "Left surround"
+msgstr "Surround sinistro"
+
+#: src/lib/util.cc:933
+msgid "Lfe (sub)"
+msgstr "Lfe(sub)"
+
+#: src/lib/filter.cc:75
+msgid "Linear blend deinterlacer"
+msgstr "Deinterlacciatore lineare miscelato"
+
+#: src/lib/filter.cc:76
+msgid "Linear interpolating deinterlacer"
+msgstr "Deinterlacciatore lineare interpolato"
+
+#: src/lib/filter.cc:78
+msgid "Median deinterlacer"
+msgstr "Deinterlacciatore mediano"
+
+#: src/lib/filter.cc:74 src/lib/filter.cc:85 src/lib/filter.cc:86
+#: src/lib/filter.cc:87 src/lib/filter.cc:90
+msgid "Misc"
+msgstr "Varie"
+
+#: src/lib/filter.cc:81
+msgid "Motion compensating deinterlacer"
+msgstr "Dinterlacciatore compensativo di movimento"
+
+#: src/lib/filter.cc:84 src/lib/filter.cc:88 src/lib/filter.cc:89
+#: src/lib/filter.cc:91
+msgid "Noise reduction"
+msgstr "Riduzione del rumore"
+
+#: src/lib/job.cc:298
+msgid "OK (ran for %1)"
+msgstr "OK (procede al %1)"
+
+#: src/lib/filter.cc:91
+msgid "Overcomplete wavelet denoiser"
+msgstr "Overcomplete wavelet denoiser"
+
+#: src/lib/dcp_content_type.cc:51
+msgid "Policy"
+msgstr "Politica"
+
+#: src/lib/dcp_content_type.cc:52
+msgid "Public Service Announcement"
+msgstr "Annuncio di pubblico servizio"
+
+#: src/lib/dcp_content_type.cc:49
+msgid "Rating"
+msgstr "Punteggio"
+
+#: src/lib/util.cc:500
+msgid "Rec 709"
+msgstr "Rec 709"
+
+#: src/lib/util.cc:931
+msgid "Right"
+msgstr "Destro"
+
+#: src/lib/util.cc:935
+msgid "Right surround"
+msgstr "Surround destro"
+
+#: src/lib/scp_dcp_job.cc:133
+msgid "SSH error (%1)"
+msgstr "Errore SSH (%1)"
+
+#: src/lib/format.cc:119
+msgid "Scope"
+msgstr "Scope"
+
+#: src/lib/format.cc:127
+msgid "Scope without stretch"
+msgstr "Scope senza stiramento"
+
+#: src/lib/dcp_content_type.cc:45
+msgid "Short"
+msgstr "Corto"
+
+#: src/lib/scaler.cc:67
+msgid "Sinc"
+msgstr "Sinc"
+
+#: src/lib/scaler.cc:68
+msgid "Spline"
+msgstr "Spline"
+
+#: src/lib/dcp_content_type.cc:50
+msgid "Teaser"
+msgstr "Teaser"
+
+#: src/lib/filter.cc:90
+msgid "Telecine filter"
+msgstr "Filtro telecinema"
+
+#: src/lib/filter.cc:84
+msgid "Temporal noise reducer"
+msgstr "Riduttore temporale di rumore"
+
+#: src/lib/dcp_content_type.cc:47
+msgid "Test"
+msgstr "Prova"
+
+#: src/lib/job.cc:77
+msgid ""
+"The drive that the film is stored on is low in disc space. Free some more "
+"space and try again."
+msgstr ""
+"Sul disco dove è memorizzato il film non c'è abbastanza spazio. Liberare "
+"altro spazio e riprovare."
+
+#: src/lib/dcp_content_type.cc:46
+msgid "Trailer"
+msgstr "Prossimamente"
+
+#: src/lib/transcode_job.cc:54
+msgid "Transcode %1"
+msgstr "Transcodifica %1"
+
+#: src/lib/dcp_content_type.cc:48
+msgid "Transitional"
+msgstr "Di transizione"
+
+#: src/lib/job.cc:100
+msgid "Unknown error"
+msgstr "Errore sconosciuto"
+
+#: src/lib/ffmpeg_decoder.cc:396
+msgid "Unrecognised audio sample format (%1)"
+msgstr "Formato di campionamento audio non riconosciuto (%1)"
+
+#: src/lib/filter.cc:87
+msgid "Unsharp mask and Gaussian blur"
+msgstr "Maschera unsharp e sfocatura Gaussiana"
+
+#: src/lib/filter.cc:69
+msgid "Vertical deblocking filter"
+msgstr "Filtro di sblocco verticale"
+
+#: src/lib/filter.cc:71
+msgid "Vertical deblocking filter A"
+msgstr "Filtro A di sblocco verticale"
+
+#: src/lib/scp_dcp_job.cc:101
+msgid "Waiting"
+msgstr "Aspetta"
+
+#: src/lib/scaler.cc:63
+msgid "X"
+msgstr "X"
+
+#: src/lib/filter.cc:83
+msgid "Yet Another Deinterlacing Filter"
+msgstr "Altro filtro di deinterlacciamento"
+
+#: src/lib/film.cc:263
+msgid "cannot contain slashes"
+msgstr "non può contenere barre"
+
+#: src/lib/util.cc:541
+msgid "connect timed out"
+msgstr "connessione scaduta"
+
+#: src/lib/scp_dcp_job.cc:119
+msgid "connecting"
+msgstr "mi sto connettendo"
+
+#: src/lib/film.cc:300
+msgid "content"
+msgstr "contenuto"
+
+#: src/lib/film.cc:304
+msgid "content type"
+msgstr "tipo di contenuto"
+
+#: src/lib/scp_dcp_job.cc:168
+msgid "copying %1"
+msgstr "copia %1"
+
+#: src/lib/exceptions.cc:36
+msgid "could not create file %1"
+msgstr "Non posso scrivere il file remoto (%1)"
+
+#: src/lib/ffmpeg_decoder.cc:191
+msgid "could not find audio decoder"
+msgstr "non riesco a trovare il decoder audio"
+
+#: src/lib/ffmpeg_decoder.cc:118
+msgid "could not find stream information"
+msgstr "non riesco a trovare informazioni sullo streaming"
+
+#: src/lib/ffmpeg_decoder.cc:210
+msgid "could not find subtitle decoder"
+msgstr "non riesco a trovare il decoder dei sottotitoli"
+
+#: src/lib/ffmpeg_decoder.cc:169
+msgid "could not find video decoder"
+msgstr "non riesco a trovare il decoder video"
+
+#: src/lib/sndfile_decoder.cc:72
+msgid "could not open external audio file for reading"
+msgstr "non riesco ad aprire il file dell'audio esterno per leggerlo"
+
+#: src/lib/exceptions.cc:29
+msgid "could not open file %1"
+msgstr "non riesco ad aprire il file per leggerlo"
+
+#: src/lib/dcp_video_frame.cc:388
+msgid "could not open file for reading"
+msgstr "non riesco ad aprire il file per leggerlo"
+
+#: src/lib/exceptions.cc:44
+msgid "could not read from file %1 (%2)"
+msgstr "Non posso creare la directory remota %1 (%2)"
+
+#: src/lib/encoder.cc:137 src/lib/encoder.cc:314
+msgid "could not run sample-rate converter"
+msgstr "non riesco a lanciare il convertitore della frequenza di campionamento"
+
+#: src/lib/scp_dcp_job.cc:86
+msgid "could not start SCP session (%1)"
+msgstr "non posso avviare la sessione SCP (%1)"
+
+#: src/lib/scp_dcp_job.cc:52
+msgid "could not start SSH session"
+msgstr "non posso avviare la sessione SSH"
+
+#: src/lib/exceptions.cc:50
+msgid "could not write to file %1 (%2)"
+msgstr "Non posso scrivere il file remoto (%1)"
+
+#: src/lib/sndfile_decoder.cc:94
+msgid "external audio files have differing lengths"
+msgstr "i files dell'audio esterno hanno durata diversa"
+
+#: src/lib/sndfile_decoder.cc:76
+msgid "external audio files must be mono"
+msgstr "i files dell'audio esterno devono essere mono"
+
+#: src/lib/film.cc:296
+msgid "format"
+msgstr "formato"
+
+#: src/lib/transcode_job.cc:100
+msgid "frames per second"
+msgstr "fotogrammi al secondo"
+
+#: src/lib/util.cc:115
+msgid "hour"
+msgstr "ora"
+
+#: src/lib/util.cc:112 src/lib/util.cc:117
+msgid "hours"
+msgstr "ore"
+
+#: src/lib/util.cc:122
+msgid "minute"
+msgstr "minuto"
+
+#: src/lib/util.cc:124
+msgid "minutes"
+msgstr "minuti"
+
+#: src/lib/util.cc:684
+msgid "missing key %1 in key-value set"
+msgstr "persa la chiave %1 tra i valori chiave"
+
+#: src/lib/exceptions.cc:54
+msgid "missing required setting %1"
+msgstr "persa la regolazione richiesta %1"
+
+#: src/lib/subtitle.cc:52
+msgid "multi-part subtitles not yet supported"
+msgstr "sottotitoli multi-part non ancora supportati"
+
+#: src/lib/film.cc:263 src/lib/film.cc:308
+msgid "name"
+msgstr "nome"
+
+#: src/lib/imagemagick_decoder.cc:60
+msgid "no still image files found"
+msgstr "file del fermo immagine non trovati"
+
+#: src/lib/subtitle.cc:58
+msgid "non-bitmap subtitles not yet supported"
+msgstr "sottotitoli non-bitmap non ancora supportati"
+
+#. / TRANSLATORS: remaining here follows an amount of time that is remaining
+#. / on an operation.
+#: src/lib/job.cc:295
+msgid "remaining"
+msgstr "restano"
+
+#: src/lib/util.cc:498
+msgid "sRGB"
+msgstr "sRGB"
+
+#: src/lib/util.cc:127
+msgid "seconds"
+msgstr "secondi"
+
+#: src/lib/film.cc:274
+msgid "still"
+msgstr "ancora"
+
+#: src/lib/film.cc:274
+msgid "video"
+msgstr "video"
+
+#~ msgid "Source scaled to 1.19:1"
+#~ msgstr "Sorgente scalato a 1.19:1"
+
+#~ msgid "Source scaled to 1.33:1"
+#~ msgstr "Sorgente scalato a 1.33:1"
+
+#~ msgid "Source scaled to 1.33:1 then pillarboxed to Flat"
+#~ msgstr "Sorgente scalato a 1.33:1 e poi inviato come Flat"
+
+#~ msgid "Source scaled to 1.375:1"
+#~ msgstr "Sorgente scalato a 1.375:1"
+
+#~ msgid "Source scaled to 1.37:1 (Academy ratio)"
+#~ msgstr "Sorgente scalato a 1.37:1 (Academy ratio)"
+
+#~ msgid "Source scaled to 1.66:1"
+#~ msgstr "Sorgente scalato a 1.66:1"
+
+#~ msgid "Source scaled to 1.66:1 then pillarboxed to Flat"
+#~ msgstr "Sorgente scalato a 1.66:1 e poi inviato come Flat"
+
+#~ msgid "Source scaled to 1.78:1"
+#~ msgstr "Sorgente scalato a 1.78:1"
+
+#~ msgid "Source scaled to 1.78:1 then pillarboxed to Flat"
+#~ msgstr "Sorgente scalato a 1.78:1 e poi inviato come Flat"
+
+#~ msgid "Source scaled to Flat (1.85:1)"
+#~ msgstr "Sorgente scalato a Flat (1.85:1)"
+
+#~ msgid "Source scaled to Scope (2.39:1)"
+#~ msgstr "Sorgente scalato a Scope (2.39:1)"
+
+#~ msgid "Source scaled to fit Flat preserving its aspect ratio"
+#~ msgstr ""
+#~ "Sorgente scalato per adattarsi a Flat mantentendo le sue proporzioni"
+
+#~ msgid "Source scaled to fit Scope preserving its aspect ratio"
+#~ msgstr ""
+#~ "Sorgente scalato per adattarsi a Scope mantentendo le sue proporzioni"
+
+#~ msgid "adding to queue of %1"
+#~ msgstr "aggiungo alla coda %1"
+
+#~ msgid "decoder sleeps with queue of %1"
+#~ msgstr "il decoder è in pausa con la coda di %1"
+
+#~ msgid "decoder wakes with queue of %1"
+#~ msgstr "il decoder riparte con la coda di %1"
diff --git a/src/lib/po/sv_SE.po b/src/lib/po/sv_SE.po
new file mode 100644
index 000000000..ef8109dfa
--- /dev/null
+++ b/src/lib/po/sv_SE.po
@@ -0,0 +1,623 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: DVD-o-matic\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-04-09 11:14+0100\n"
+"PO-Revision-Date: 2013-04-10 15:35+0100\n"
+"Last-Translator: Adam Klotblixt <adam.klotblixt@gmail.com>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 1.5.5\n"
+
+#: src/lib/transcode_job.cc:87
+msgid "0%"
+msgstr "0%"
+
+#: src/lib/format.cc:75
+msgid "1.19"
+msgstr "1,19"
+
+#: src/lib/format.cc:79
+msgid "1.33"
+msgstr "1,33"
+
+#: src/lib/format.cc:83
+msgid "1.375"
+msgstr "1,375"
+
+#: src/lib/format.cc:95
+msgid "1.66"
+msgstr "1,66"
+
+#: src/lib/format.cc:99
+msgid "1.66 within Flat"
+msgstr "1,66 innanför Flat"
+
+#: src/lib/format.cc:107
+msgid "16:9"
+msgstr "16:9"
+
+#: src/lib/format.cc:103
+msgid "16:9 within Flat"
+msgstr "16:9 innanför Flat"
+
+#: src/lib/format.cc:115
+msgid "16:9 within Scope"
+msgstr "16:9 innanför Scope"
+
+#: src/lib/filter.cc:88
+msgid "3D denoiser"
+msgstr "3D brusreducering"
+
+#: src/lib/format.cc:87
+msgid "4:3 within Flat"
+msgstr "4:3 innanför Flat"
+
+#: src/lib/ab_transcode_job.cc:49
+msgid "A/B transcode %1"
+msgstr "A/B konvertera %1"
+
+#: src/lib/format.cc:91
+msgid "Academy"
+msgstr "Academy"
+
+#: src/lib/dcp_content_type.cc:53
+msgid "Advertisement"
+msgstr "Reklam"
+
+#: src/lib/job.cc:72
+msgid "An error occurred whilst handling the file %1."
+msgstr "Ett fel inträffade vid hantering av filen %1"
+
+#: src/lib/analyse_audio_job.cc:49
+msgid "Analyse audio of %1"
+msgstr "Analysera %1s audio"
+
+#: src/lib/scaler.cc:64
+msgid "Area"
+msgstr "Yta"
+
+#: src/lib/scaler.cc:62
+msgid "Bicubic"
+msgstr "Bikubisk"
+
+#: src/lib/scaler.cc:69
+msgid "Bilinear"
+msgstr "Bilinjär"
+
+#: src/lib/job.cc:302
+msgid "Cancelled"
+msgstr "Avbruten"
+
+#: src/lib/exceptions.cc:60
+msgid "Cannot handle pixel format %1 during %2"
+msgstr "Kan inte hantera pixelformat %1 under %2"
+
+#: src/lib/encoder.cc:101
+msgid "Cannot resample audio as libswresample is not present"
+msgstr ""
+"Kan inte omsampla ljudet eftersom libswresample inte finns tillgängligt"
+
+#: src/lib/util.cc:932
+msgid "Centre"
+msgstr "Mitt"
+
+#: src/lib/scp_dcp_job.cc:109
+msgid "Copy DCP to TMS"
+msgstr "Kopiera DCP till TMS"
+
+#: src/lib/scp_dcp_job.cc:128
+msgid "Could not connect to server %1 (%2)"
+msgstr "Kunde inte ansluta till server %1 (%2)"
+
+#: src/lib/scp_dcp_job.cc:150
+msgid "Could not create remote directory %1 (%2)"
+msgstr "Kunde inte skapa fjärrkatalog %1 (%2)"
+
+#: src/lib/scp_dcp_job.cc:175
+msgid "Could not open %1 to send"
+msgstr "Kunde inte öppna %1 för att skicka"
+
+#: src/lib/scp_dcp_job.cc:145
+msgid "Could not start SCP session (%1)"
+msgstr "Kunde inte starta SCP-session (%1)"
+
+#: src/lib/scp_dcp_job.cc:187
+msgid "Could not write to remote file (%1)"
+msgstr "Kunde inte skriva till fjärrfil (%1)"
+
+#: src/lib/filter.cc:77
+msgid "Cubic interpolating deinterlacer"
+msgstr "Kubiskt interpolerande avflätare"
+
+#: src/lib/util.cc:1007
+msgid "DCP and source have the same rate.\n"
+msgstr "DCP och källa har samma bildfrekvens.\n"
+
+#: src/lib/util.cc:1017
+msgid "DCP will run at %1%% of the source speed.\n"
+msgstr "DCP kommer att köras på %1%% av källans hastighet.\n"
+
+#: src/lib/util.cc:1010
+msgid "DCP will use every other frame of the source.\n"
+msgstr "DCP kommer att använda varannan bild från källan.\n"
+
+#: src/lib/filter.cc:68 src/lib/filter.cc:69 src/lib/filter.cc:70
+#: src/lib/filter.cc:71 src/lib/filter.cc:72 src/lib/filter.cc:73
+msgid "De-blocking"
+msgstr "Kantighetsutjämning"
+
+#: src/lib/filter.cc:75 src/lib/filter.cc:76 src/lib/filter.cc:77
+#: src/lib/filter.cc:78 src/lib/filter.cc:79 src/lib/filter.cc:80
+#: src/lib/filter.cc:81 src/lib/filter.cc:82 src/lib/filter.cc:83
+msgid "De-interlacing"
+msgstr "Avflätning"
+
+#: src/lib/filter.cc:74
+msgid "Deringing filter"
+msgstr "Avringningsfilter"
+
+#: src/lib/dolby_cp750.cc:27
+msgid "Dolby CP750"
+msgstr "Dolby CP750"
+
+#: src/lib/util.cc:1012
+msgid "Each source frame will be doubled in the DCP.\n"
+msgstr "Varje bild från källan kommer att användas två gånger i DCPn.\n"
+
+#: src/lib/job.cc:300
+msgid "Error (%1)"
+msgstr "Fel (%1)"
+
+#: src/lib/examine_content_job.cc:55
+msgid "Examine content"
+msgstr "Undersök innehållet"
+
+#: src/lib/examine_content_job.cc:58
+msgid "Examine content of %1"
+msgstr "Undersök innehållet i %1"
+
+#: src/lib/filter.cc:72
+msgid "Experimental horizontal deblocking filter 1"
+msgstr "Experimentellt filter för horisontal kantighetsutjämning 1"
+
+#: src/lib/filter.cc:73
+msgid "Experimental vertical deblocking filter 1"
+msgstr "Experimentellt filter för vertikal kantighetsutjämning 1"
+
+#: src/lib/filter.cc:79
+msgid "FFMPEG deinterlacer"
+msgstr "FFMPEG avflätare"
+
+#: src/lib/filter.cc:80
+msgid "FIR low-pass deinterlacer"
+msgstr "FIR lågpass-avflätare"
+
+#: src/lib/scp_dcp_job.cc:138
+msgid "Failed to authenticate with server (%1)"
+msgstr "Misslyckades att autentisera med server (%1)"
+
+#: src/lib/scaler.cc:70
+msgid "Fast Bilinear"
+msgstr "Snabb bilinjär"
+
+#: src/lib/dcp_content_type.cc:44
+msgid "Feature"
+msgstr "Långfilm"
+
+#: src/lib/format.cc:111
+msgid "Flat"
+msgstr "Flat"
+
+#: src/lib/format.cc:123
+msgid "Flat without stretch"
+msgstr "Flat utan utsträckning"
+
+#: src/lib/filter.cc:85
+msgid "Force quantizer"
+msgstr "Tvinga kvantiserare"
+
+#: src/lib/scaler.cc:65
+msgid "Gaussian"
+msgstr "Gaussisk"
+
+#: src/lib/filter.cc:86
+msgid "Gradient debander"
+msgstr "Gradientutjämnare"
+
+#: src/lib/filter.cc:89
+msgid "High quality 3D denoiser"
+msgstr "Högkvalitets 3D-brusreducering"
+
+#: src/lib/filter.cc:68
+msgid "Horizontal deblocking filter"
+msgstr "Filter för horisontal kantighetsutjämning"
+
+#: src/lib/filter.cc:70
+msgid "Horizontal deblocking filter A"
+msgstr "Filter för horisontal kantighetsutjämning A"
+
+#: src/lib/job.cc:92 src/lib/job.cc:101
+msgid ""
+"It is not known what caused this error. The best idea is to report the "
+"problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)"
+msgstr ""
+"Det är inte känt vad som orsakade detta fel. Bästa sättet att rapportera "
+"problemet är till DVD-o-matics mejl-lista (dvdomatic@carlh.net)"
+
+#: src/lib/filter.cc:82
+msgid "Kernel deinterlacer"
+msgstr "Kernel-avflätare"
+
+#: src/lib/scaler.cc:66
+msgid "Lanczos"
+msgstr "Lanczos"
+
+#: src/lib/util.cc:930
+msgid "Left"
+msgstr "Vänster"
+
+#: src/lib/util.cc:934
+msgid "Left surround"
+msgstr "Vänster surround"
+
+#: src/lib/util.cc:933
+msgid "Lfe (sub)"
+msgstr "Lfe (sub)"
+
+#: src/lib/filter.cc:75
+msgid "Linear blend deinterlacer"
+msgstr "Linjär blandningsavflätare"
+
+#: src/lib/filter.cc:76
+msgid "Linear interpolating deinterlacer"
+msgstr "Linjär interpolationsavflätare"
+
+#: src/lib/filter.cc:78
+msgid "Median deinterlacer"
+msgstr "Median-avflätare"
+
+#: src/lib/filter.cc:74 src/lib/filter.cc:85 src/lib/filter.cc:86
+#: src/lib/filter.cc:87 src/lib/filter.cc:90
+msgid "Misc"
+msgstr "Diverse"
+
+#: src/lib/filter.cc:81
+msgid "Motion compensating deinterlacer"
+msgstr "Rörelsekompenserande avflätare"
+
+#: src/lib/filter.cc:84 src/lib/filter.cc:88 src/lib/filter.cc:89
+#: src/lib/filter.cc:91
+msgid "Noise reduction"
+msgstr "Brusreducering"
+
+#: src/lib/job.cc:298
+msgid "OK (ran for %1)"
+msgstr "OK (kördes %1)"
+
+#: src/lib/filter.cc:91
+msgid "Overcomplete wavelet denoiser"
+msgstr "Överkomplett wavelet-brusreducering"
+
+#: src/lib/dcp_content_type.cc:51
+msgid "Policy"
+msgstr "Policy"
+
+#: src/lib/dcp_content_type.cc:52
+msgid "Public Service Announcement"
+msgstr "Offentligt Servicemeddelande"
+
+#: src/lib/dcp_content_type.cc:49
+msgid "Rating"
+msgstr "Klassificeringsklipp"
+
+#: src/lib/util.cc:500
+msgid "Rec 709"
+msgstr "Rec 709"
+
+#: src/lib/util.cc:931
+msgid "Right"
+msgstr "Höger"
+
+#: src/lib/util.cc:935
+msgid "Right surround"
+msgstr "Höger surround"
+
+#: src/lib/scp_dcp_job.cc:133
+msgid "SSH error (%1)"
+msgstr "SSH fel (%1)"
+
+#: src/lib/format.cc:119
+msgid "Scope"
+msgstr "Scope"
+
+#: src/lib/format.cc:127
+msgid "Scope without stretch"
+msgstr "Scope utan utsträckning"
+
+#: src/lib/dcp_content_type.cc:45
+msgid "Short"
+msgstr "Kortfilm"
+
+#: src/lib/scaler.cc:67
+msgid "Sinc"
+msgstr "Sinc"
+
+#: src/lib/scaler.cc:68
+msgid "Spline"
+msgstr "Spline"
+
+#: src/lib/dcp_content_type.cc:50
+msgid "Teaser"
+msgstr "Teaser"
+
+#: src/lib/filter.cc:90
+msgid "Telecine filter"
+msgstr "Telecine-filter"
+
+#: src/lib/filter.cc:84
+msgid "Temporal noise reducer"
+msgstr "Temporal brusreducering"
+
+#: src/lib/dcp_content_type.cc:47
+msgid "Test"
+msgstr "Test"
+
+#: src/lib/job.cc:77
+msgid ""
+"The drive that the film is stored on is low in disc space. Free some more "
+"space and try again."
+msgstr ""
+"Enheten som filmen lagras på har för lite ledigt utrymme. Frigör utrymme och "
+"försök igen."
+
+#: src/lib/dcp_content_type.cc:46
+msgid "Trailer"
+msgstr "Trailer"
+
+#: src/lib/transcode_job.cc:54
+msgid "Transcode %1"
+msgstr "Konvertera %1"
+
+#: src/lib/dcp_content_type.cc:48
+msgid "Transitional"
+msgstr "Övergångsklipp"
+
+#: src/lib/job.cc:100
+msgid "Unknown error"
+msgstr "Okänt fel"
+
+# Svengelska
+#: src/lib/ffmpeg_decoder.cc:396
+#, fuzzy
+msgid "Unrecognised audio sample format (%1)"
+msgstr "Okänt audio-sampelformat (%1)"
+
+#: src/lib/filter.cc:87
+msgid "Unsharp mask and Gaussian blur"
+msgstr "Oskärpemask och Gaussisk suddighet"
+
+#: src/lib/filter.cc:69
+msgid "Vertical deblocking filter"
+msgstr "Filter för vertikal kantighetsutjämning"
+
+#: src/lib/filter.cc:71
+msgid "Vertical deblocking filter A"
+msgstr "Filter för vertikal kantighetsutjämning A"
+
+#: src/lib/scp_dcp_job.cc:101
+msgid "Waiting"
+msgstr "Väntar"
+
+#: src/lib/scaler.cc:63
+msgid "X"
+msgstr "X"
+
+# Filtret heter så, ska ej översättas
+#: src/lib/filter.cc:83
+msgid "Yet Another Deinterlacing Filter"
+msgstr "Yet Another Deinterlacing Filter"
+
+#: src/lib/film.cc:263
+msgid "cannot contain slashes"
+msgstr "får inte innehålla snedstreck"
+
+# Svengelska
+#: src/lib/util.cc:541
+#, fuzzy
+msgid "connect timed out"
+msgstr "uppkopplingen tajmade ur"
+
+#: src/lib/scp_dcp_job.cc:119
+msgid "connecting"
+msgstr "kopplar upp"
+
+#: src/lib/film.cc:300
+msgid "content"
+msgstr "innehåll"
+
+#: src/lib/film.cc:304
+msgid "content type"
+msgstr "innehållstyp"
+
+#: src/lib/scp_dcp_job.cc:168
+msgid "copying %1"
+msgstr "kopierar %1"
+
+#: src/lib/exceptions.cc:36
+msgid "could not create file %1"
+msgstr "kunde inte skapa fil %1"
+
+#: src/lib/ffmpeg_decoder.cc:191
+msgid "could not find audio decoder"
+msgstr "kunde inte hitta audio-avkodare"
+
+#: src/lib/ffmpeg_decoder.cc:118
+msgid "could not find stream information"
+msgstr "kunde inte hitta information om strömmen"
+
+#: src/lib/ffmpeg_decoder.cc:210
+msgid "could not find subtitle decoder"
+msgstr "kunde inte hitta undertext-avkodare"
+
+#: src/lib/ffmpeg_decoder.cc:169
+msgid "could not find video decoder"
+msgstr "kunde inte hitta video-avkodare"
+
+#: src/lib/sndfile_decoder.cc:72
+msgid "could not open external audio file for reading"
+msgstr "kunde inte öppna extern audio-fil för läsning"
+
+#: src/lib/exceptions.cc:29
+msgid "could not open file %1"
+msgstr "kunde inte öppna fil %1"
+
+#: src/lib/dcp_video_frame.cc:388
+msgid "could not open file for reading"
+msgstr "kunde inte öppna fil för läsning"
+
+#: src/lib/exceptions.cc:44
+msgid "could not read from file %1 (%2)"
+msgstr "kunde inte läsa från fil %1 (%2)"
+
+#: src/lib/encoder.cc:137 src/lib/encoder.cc:314
+msgid "could not run sample-rate converter"
+msgstr "kunde inte köra sampelhastighetskonverteraren"
+
+#: src/lib/scp_dcp_job.cc:86
+msgid "could not start SCP session (%1)"
+msgstr "kunde inte starta SCP-session (%1)"
+
+#: src/lib/scp_dcp_job.cc:52
+msgid "could not start SSH session"
+msgstr "kunde inte starta SSH-session"
+
+#: src/lib/exceptions.cc:50
+msgid "could not write to file %1 (%2)"
+msgstr "kunde inte skriva till fil %1 (%2)"
+
+#: src/lib/sndfile_decoder.cc:94
+msgid "external audio files have differing lengths"
+msgstr "externa audio-filer har olika längder"
+
+#: src/lib/sndfile_decoder.cc:76
+msgid "external audio files must be mono"
+msgstr "externa audio-filer måste vara mono"
+
+#: src/lib/film.cc:296
+msgid "format"
+msgstr "format"
+
+#: src/lib/transcode_job.cc:100
+msgid "frames per second"
+msgstr "bilder per sekund"
+
+#: src/lib/util.cc:115
+msgid "hour"
+msgstr "timme"
+
+#: src/lib/util.cc:112 src/lib/util.cc:117
+msgid "hours"
+msgstr "timmar"
+
+#: src/lib/util.cc:122
+msgid "minute"
+msgstr "minut"
+
+#: src/lib/util.cc:124
+msgid "minutes"
+msgstr "minuter"
+
+#: src/lib/util.cc:684
+msgid "missing key %1 in key-value set"
+msgstr "saknad nyckel %1 i nyckel-värde grupp"
+
+#: src/lib/exceptions.cc:54
+msgid "missing required setting %1"
+msgstr "saknad nödvändig inställning %1"
+
+#: src/lib/subtitle.cc:52
+msgid "multi-part subtitles not yet supported"
+msgstr "undertexter i flera delar stöds inte ännu"
+
+#: src/lib/film.cc:263 src/lib/film.cc:308
+msgid "name"
+msgstr "namn"
+
+#: src/lib/imagemagick_decoder.cc:60
+msgid "no still image files found"
+msgstr "inga stillbildsfiler hittade"
+
+#: src/lib/subtitle.cc:58
+msgid "non-bitmap subtitles not yet supported"
+msgstr "icke-rastergrafiska undertexter stöds inte ännu"
+
+#. / TRANSLATORS: remaining here follows an amount of time that is remaining
+#. / on an operation.
+#: src/lib/job.cc:295
+msgid "remaining"
+msgstr "återstående tid"
+
+#: src/lib/util.cc:498
+msgid "sRGB"
+msgstr "sRGB"
+
+#: src/lib/util.cc:127
+msgid "seconds"
+msgstr "sekunder"
+
+#: src/lib/film.cc:274
+msgid "still"
+msgstr "stillbild"
+
+#: src/lib/film.cc:274
+msgid "video"
+msgstr "video"
+
+#~ msgid "Source scaled to 1.19:1"
+#~ msgstr "Källan skalad till 1,19:1"
+
+#~ msgid "Source scaled to 1.33:1"
+#~ msgstr "Källan skalad till 1,33:1"
+
+#~ msgid "Source scaled to 1.33:1 then pillarboxed to Flat"
+#~ msgstr "Källan skalad till 1,33:1, med sorgkanter innanför Flat"
+
+#~ msgid "Source scaled to 1.375:1"
+#~ msgstr "Källan skalad till 1,375:1"
+
+#~ msgid "Source scaled to 1.37:1 (Academy ratio)"
+#~ msgstr "Källan skalad till 1,37:1 (Academy-förhållande)"
+
+#~ msgid "Source scaled to 1.66:1"
+#~ msgstr "Källan skalad till 1,66:1"
+
+#~ msgid "Source scaled to 1.66:1 then pillarboxed to Flat"
+#~ msgstr "Källan skalad till 1,66:1, med sorgkanter innanför Flat"
+
+#~ msgid "Source scaled to 1.78:1"
+#~ msgstr "Källan skalad till 1,78:1"
+
+#~ msgid "Source scaled to 1.78:1 then pillarboxed to Flat"
+#~ msgstr "Källan skalad till 1,78:1, med sorgkanter innanför Flat"
+
+#~ msgid "Source scaled to Flat (1.85:1)"
+#~ msgstr "Källan skalad till Flat (1,85:1)"
+
+#~ msgid "Source scaled to Scope (2.39:1)"
+#~ msgstr "Källan skalad till Scope (2,39:1)"
+
+#~ msgid "Source scaled to fit Flat preserving its aspect ratio"
+#~ msgstr ""
+#~ "Källan skalad för att rymmas inom Flat utan att ändra bildförhållandet"
+
+#~ msgid "Source scaled to fit Scope preserving its aspect ratio"
+#~ msgstr ""
+#~ "Källan skalad för att rymmas inom Scope utan att ändra bildförhållandet"
diff --git a/src/lib/processor.h b/src/lib/processor.h
index 863bfdbb5..1ba396f2f 100644
--- a/src/lib/processor.h
+++ b/src/lib/processor.h
@@ -40,7 +40,7 @@ public:
/** Construct a Processor.
* @param log Log to use.
*/
- Processor (Log* log)
+ Processor (boost::shared_ptr<Log> log)
: _log (log)
{}
@@ -50,7 +50,49 @@ public:
virtual void process_end () {}
protected:
- Log* _log; ///< log to write to
+ boost::shared_ptr<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 (boost::shared_ptr<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 (boost::shared_ptr<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 (boost::shared_ptr<Log> log)
+ : Processor (log)
+ {}
};
#endif
diff --git a/src/lib/server.cc b/src/lib/server.cc
index 76a25bfbb..9c5a77f68 100644
--- a/src/lib/server.cc
+++ b/src/lib/server.cc
@@ -77,7 +77,7 @@ ServerDescription::as_metadata () const
return s.str ();
}
-Server::Server (Log* log)
+Server::Server (shared_ptr<Log> log)
: _log (log)
{
diff --git a/src/lib/server.h b/src/lib/server.h
index 32ba8dc4b..89aeca626 100644
--- a/src/lib/server.h
+++ b/src/lib/server.h
@@ -76,7 +76,7 @@ private:
class Server
{
public:
- Server (Log* log);
+ Server (boost::shared_ptr<Log> log);
void run (int num_threads);
@@ -88,5 +88,5 @@ private:
std::list<boost::shared_ptr<Socket> > _queue;
boost::mutex _worker_mutex;
boost::condition _worker_condition;
- Log* _log;
+ boost::shared_ptr<Log> _log;
};
diff --git a/src/lib/external_audio_decoder.cc b/src/lib/sndfile_decoder.cc
index 50e5852c5..0e3e5e234 100644
--- a/src/lib/external_audio_decoder.cc
+++ b/src/lib/sndfile_decoder.cc
@@ -19,7 +19,7 @@
#include <iostream>
#include <sndfile.h>
-#include "external_audio_decoder.h"
+#include "sndfile_decoder.h"
#include "film.h"
#include "exceptions.h"
@@ -33,7 +33,7 @@ using std::cout;
using boost::shared_ptr;
using boost::optional;
-ExternalAudioDecoder::ExternalAudioDecoder (shared_ptr<Film> f, DecodeOptions o)
+SndfileDecoder::SndfileDecoder (shared_ptr<Film> f, DecodeOptions o)
: Decoder (f, o)
, AudioDecoder (f, o)
{
@@ -43,7 +43,7 @@ ExternalAudioDecoder::ExternalAudioDecoder (shared_ptr<Film> f, DecodeOptions o)
}
vector<SNDFILE*>
-ExternalAudioDecoder::open_files (sf_count_t & frames)
+SndfileDecoder::open_files (sf_count_t & frames)
{
vector<string> const files = _film->external_audio ();
@@ -79,8 +79,8 @@ ExternalAudioDecoder::open_files (sf_count_t & frames)
sndfiles.push_back (s);
if (first) {
- shared_ptr<ExternalAudioStream> st (
- new ExternalAudioStream (
+ shared_ptr<SndfileStream> st (
+ new SndfileStream (
info.samplerate, av_get_default_channel_layout (N)
)
);
@@ -101,7 +101,7 @@ ExternalAudioDecoder::open_files (sf_count_t & frames)
}
bool
-ExternalAudioDecoder::pass ()
+SndfileDecoder::pass ()
{
sf_count_t frames;
vector<SNDFILE*> sndfiles = open_files (frames);
@@ -115,7 +115,6 @@ ExternalAudioDecoder::pass ()
sf_count_t const block = _audio_stream->sample_rate() / 2;
shared_ptr<AudioBuffers> 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;
}
@@ -138,38 +136,38 @@ ExternalAudioDecoder::pass ()
}
void
-ExternalAudioDecoder::close_files (vector<SNDFILE*> const & sndfiles)
+SndfileDecoder::close_files (vector<SNDFILE*> const & sndfiles)
{
for (size_t i = 0; i < sndfiles.size(); ++i) {
sf_close (sndfiles[i]);
}
}
-shared_ptr<ExternalAudioStream>
-ExternalAudioStream::create ()
+shared_ptr<SndfileStream>
+SndfileStream::create ()
{
- return shared_ptr<ExternalAudioStream> (new ExternalAudioStream);
+ return shared_ptr<SndfileStream> (new SndfileStream);
}
-shared_ptr<ExternalAudioStream>
-ExternalAudioStream::create (string t, optional<int> v)
+shared_ptr<SndfileStream>
+SndfileStream::create (string t, optional<int> v)
{
if (!v) {
/* version < 1; no type in the string, and there's only FFmpeg streams anyway */
- return shared_ptr<ExternalAudioStream> ();
+ return shared_ptr<SndfileStream> ();
}
stringstream s (t);
string type;
s >> type;
if (type != N_("external")) {
- return shared_ptr<ExternalAudioStream> ();
+ return shared_ptr<SndfileStream> ();
}
- return shared_ptr<ExternalAudioStream> (new ExternalAudioStream (t, v));
+ return shared_ptr<SndfileStream> (new SndfileStream (t, v));
}
-ExternalAudioStream::ExternalAudioStream (string t, optional<int> v)
+SndfileStream::SndfileStream (string t, optional<int> v)
{
assert (v);
@@ -178,13 +176,13 @@ ExternalAudioStream::ExternalAudioStream (string t, optional<int> v)
s >> type >> _sample_rate >> _channel_layout;
}
-ExternalAudioStream::ExternalAudioStream ()
+SndfileStream::SndfileStream ()
{
}
string
-ExternalAudioStream::to_string () const
+SndfileStream::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/sndfile_decoder.h
index 6f010abb1..e16eab673 100644
--- a/src/lib/external_audio_decoder.h
+++ b/src/lib/sndfile_decoder.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net>
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
@@ -22,29 +22,29 @@
#include "audio_decoder.h"
#include "stream.h"
-class ExternalAudioStream : public AudioStream
+class SndfileStream : public AudioStream
{
public:
- ExternalAudioStream (int sample_rate, int64_t layout)
+ SndfileStream (int sample_rate, int64_t layout)
: AudioStream (sample_rate, layout)
{}
std::string to_string () const;
- static boost::shared_ptr<ExternalAudioStream> create ();
- static boost::shared_ptr<ExternalAudioStream> create (std::string t, boost::optional<int> v);
+ static boost::shared_ptr<SndfileStream> create ();
+ static boost::shared_ptr<SndfileStream> create (std::string t, boost::optional<int> v);
private:
friend class stream_test;
- ExternalAudioStream ();
- ExternalAudioStream (std::string t, boost::optional<int> v);
+ SndfileStream ();
+ SndfileStream (std::string t, boost::optional<int> v);
};
-class ExternalAudioDecoder : public AudioDecoder
+class SndfileDecoder : public AudioDecoder
{
public:
- ExternalAudioDecoder (boost::shared_ptr<Film>, DecodeOptions);
+ SndfileDecoder (boost::shared_ptr<Film>, DecodeOptions);
bool pass ();
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<int> 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/transcode_job.cc b/src/lib/transcode_job.cc
index f7cc500fe..234ebe051 100644
--- a/src/lib/transcode_job.cc
+++ b/src/lib/transcode_job.cc
@@ -68,10 +68,7 @@ TranscodeJob::run ()
set_progress (1);
set_state (FINISHED_OK);
- _film->set_dcp_intrinsic_duration (_encoder->video_frames_out ());
-
_film->log()->log (N_("Transcode job completed successfully"));
- _film->log()->log (String::compose (N_("DCP intrinsic duration is %1"), _encoder->video_frames_out()));
} catch (std::exception& e) {
diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc
index 8e5e15e7f..8046080de 100644
--- a/src/lib/transcoder.cc
+++ b/src/lib/transcoder.cc
@@ -38,7 +38,6 @@
#include "audio_decoder.h"
using std::string;
-using std::cout;
using boost::shared_ptr;
using boost::dynamic_pointer_cast;
@@ -64,9 +63,18 @@ Transcoder::Transcoder (shared_ptr<Film> f, DecodeOptions o, Job* j, shared_ptr<
_decoders.video->set_subtitle_stream (f->subtitle_stream ());
_decoders.audio->set_audio_stream (f->audio_stream ());
+<<<<<<< HEAD
_decoders.video->connect_video (_delay_line);
_delay_line->connect_video (_matcher);
_matcher->connect_video (_encoder);
+=======
+ if (_matcher) {
+ _decoders.video->connect_video (_matcher);
+ _matcher->connect_video (_encoder);
+ } else {
+ _decoders.video->connect_video (_encoder);
+ }
+>>>>>>> master
_decoders.audio->connect_audio (_delay_line);
_delay_line->connect_audio (_matcher);
diff --git a/src/lib/util.cc b/src/lib/util.cc
index 53bdb4c79..557e9a34b 100644
--- a/src/lib/util.cc
+++ b/src/lib/util.cc
@@ -235,9 +235,6 @@ seconds (struct timeval t)
void
dvdomatic_setup ()
{
- bindtextdomain ("libdvdomatic", LOCALE_PREFIX);
- setlocale (LC_ALL, "");
-
avfilter_register_all ();
Format::setup_formats ();
@@ -249,6 +246,51 @@ dvdomatic_setup ()
ui_thread = this_thread::get_id ();
}
+#ifdef DVDOMATIC_WINDOWS
+boost::filesystem::path
+mo_path ()
+{
+ wchar_t buffer[512];
+ GetModuleFileName (0, buffer, 512 * sizeof(wchar_t));
+ boost::filesystem::path p (buffer);
+ p = p.parent_path ();
+ p = p.parent_path ();
+ p /= "locale";
+ return p;
+}
+#endif
+
+void
+dvdomatic_setup_i18n (string lang)
+{
+#ifdef DVDOMATIC_POSIX
+ lang += ".UTF8";
+#endif
+
+ if (!lang.empty ()) {
+ /* Override our environment language; this is essential on
+ Windows.
+ */
+ char cmd[64];
+ snprintf (cmd, sizeof(cmd), "LANGUAGE=%s", lang.c_str ());
+ putenv (cmd);
+ snprintf (cmd, sizeof(cmd), "LANG=%s", lang.c_str ());
+ putenv (cmd);
+ }
+
+ setlocale (LC_ALL, "");
+ textdomain ("libdvdomatic");
+
+#ifdef DVDOMATIC_WINDOWS
+ bindtextdomain ("libdvdomatic", mo_path().string().c_str());
+ bind_textdomain_codeset ("libdvdomatic", "UTF8");
+#endif
+
+#ifdef DVDOMATIC_POSIX
+ bindtextdomain ("libdvdomatic", POSIX_LOCALE_PREFIX);
+#endif
+}
+
/** @param start Start position for the crop within the image.
* @param size Size of the cropped area.
* @return FFmpeg crop filter string.
@@ -885,12 +927,12 @@ audio_channel_name (int c)
enhancement channel (sub-woofer)./
*/
string const channels[] = {
- "Left",
- "Right",
- "Centre",
- "Lfe (sub)",
- "Left surround",
- "Right surround",
+ _("Left"),
+ _("Right"),
+ _("Centre"),
+ _("Lfe (sub)"),
+ _("Left surround"),
+ _("Right surround"),
};
return channels[c];
@@ -972,7 +1014,7 @@ FrameRateConversion::FrameRateConversion (float source, int dcp)
if (change_speed) {
float const pc = dcp * 100 / (source * factor());
- description += String::compose (_("DCP will run at %1%% of the source speed."), pc);
+ description += String::compose (_("DCP will run at %1%% of the source speed.\n"), pc);
}
}
}
diff --git a/src/lib/util.h b/src/lib/util.h
index ec67469c1..3d251cf06 100644
--- a/src/lib/util.h
+++ b/src/lib/util.h
@@ -30,6 +30,7 @@
#include <boost/shared_ptr.hpp>
#include <boost/asio.hpp>
#include <boost/optional.hpp>
+#include <boost/filesystem.hpp>
#include <libdcp/util.h>
extern "C" {
#include <libavcodec/avcodec.h>
@@ -54,11 +55,15 @@ extern void stacktrace (std::ostream &, int);
extern std::string dependency_version_summary ();
extern double seconds (struct timeval);
extern void dvdomatic_setup ();
+extern void dvdomatic_setup_i18n (std::string);
extern std::vector<std::string> split_at_spaces_considering_quotes (std::string);
extern std::string md5_digest (std::string);
extern std::string md5_digest (void const *, int);
extern void ensure_ui_thread ();
extern std::string audio_channel_name (int);
+#ifdef DVDOMATIC_WINDOWS
+extern boost::filesystem::path mo_path ();
+#endif
typedef int SourceFrame;
diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h
index 6e4fd48c0..f8612dff2 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<Film>, DecodeOptions);
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<Image> i, bool same, boost::shared_ptr<Subtitle> 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<Image> i, bool same, boost::shared_ptr<Subtitle> 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<VideoSink> s)
{
Video.connect (bind (&VideoSink::process_video, s, _1, _2, _3));
}
-
-void
-TimedVideoSource::connect_video (shared_ptr<TimedVideoSink> 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<VideoSink>);
};
-/** @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<void (boost::shared_ptr<Image>, bool, boost::shared_ptr<Subtitle>, double)> Video;
-
- void connect_video (boost::shared_ptr<TimedVideoSink>);
-};
-
#endif
diff --git a/src/lib/writer.cc b/src/lib/writer.cc
index 5a2f7c9a9..c6ce4711d 100644
--- a/src/lib/writer.cc
+++ b/src/lib/writer.cc
@@ -65,8 +65,8 @@ Writer::Writer (shared_ptr<Film> f)
_picture_asset.reset (
new libdcp::MonoPictureAsset (
- _film->video_mxf_dir (),
- _film->video_mxf_filename (),
+ _film->internal_video_mxf_dir (),
+ _film->internal_video_mxf_filename (),
_film->dcp_frame_rate (),
_film->format()->dcp_size ()
)
@@ -80,7 +80,7 @@ Writer::Writer (shared_ptr<Film> f)
_sound_asset.reset (
new libdcp::SoundAsset (
_film->dir (_film->dcp_name()),
- N_("audio.mxf"),
+ _film->dcp_audio_mxf_filename (),
_film->dcp_frame_rate (),
m.dcp_channels (),
dcp_audio_sample_rate (_film->audio_stream()->sample_rate())
@@ -261,27 +261,31 @@ Writer::finish ()
int const frames = _last_written_frame + 1;
int const duration = frames - _film->trim_start() - _film->trim_end();
- _film->set_dcp_intrinsic_duration (frames);
-
_picture_asset->set_entry_point (_film->trim_start ());
_picture_asset->set_duration (duration);
/* Hard-link the video MXF into the DCP */
boost::filesystem::path from;
- from /= _film->video_mxf_dir();
- from /= _film->video_mxf_filename();
+ from /= _film->internal_video_mxf_dir();
+ from /= _film->internal_video_mxf_filename();
boost::filesystem::path to;
to /= _film->dir (_film->dcp_name());
- to /= N_("video.mxf");
-
- boost::filesystem::create_hard_link (from, to);
+ to /= _film->dcp_video_mxf_filename ();
+
+ boost::system::error_code ec;
+ boost::filesystem::create_hard_link (from, to, ec);
+ if (ec) {
+ /* hard link failed; copy instead */
+ boost::filesystem::copy_file (from, to);
+ _film->log()->log ("Hard-link failed; fell back to copying");
+ }
/* And update the asset */
_picture_asset->set_directory (_film->dir (_film->dcp_name ()));
- _picture_asset->set_file_name (N_("video.mxf"));
+ _picture_asset->set_file_name (_film->dcp_video_mxf_filename ());
if (_sound_asset) {
_sound_asset->set_entry_point (_film->trim_start ());
@@ -335,8 +339,8 @@ Writer::check_existing_picture_mxf ()
{
/* Try to open the existing MXF */
boost::filesystem::path p;
- p /= _film->video_mxf_dir ();
- p /= _film->video_mxf_filename ();
+ p /= _film->internal_video_mxf_dir ();
+ p /= _film->internal_video_mxf_filename ();
FILE* mxf = fopen (p.string().c_str(), N_("rb"));
if (!mxf) {
return;
diff --git a/src/lib/wscript b/src/lib/wscript
index d36a24e7a..8e9d34706 100644
--- a/src/lib/wscript
+++ b/src/lib/wscript
@@ -20,7 +20,7 @@ sources = """
dolby_cp750.cc
encoder.cc
examine_content_job.cc
- external_audio_decoder.cc
+ exceptions.cc
filter_graph.cc
ffmpeg_compatibility.cc
ffmpeg_decoder.cc
@@ -38,6 +38,7 @@ sources = """
scp_dcp_job.cc
scaler.cc
server.cc
+ sndfile_decoder.cc
sound_processor.cc
stream.cc
subtitle.cc
@@ -46,7 +47,6 @@ sources = """
transcoder.cc
ui_signaller.cc
util.cc
- version.cc
video_decoder.cc
video_source.cc
writer.cc
@@ -67,10 +67,13 @@ def build(bld):
"""
if bld.env.TARGET_WINDOWS:
obj.uselib += ' WINSOCK2'
- obj.source = sources
+ obj.source = sources + " version.cc"
obj.target = 'dvdomatic'
i18n.po_to_mo(os.path.join('src', 'lib'), 'libdvdomatic', bld)
def pot(bld):
i18n.pot(os.path.join('src', 'lib'), sources, 'libdvdomatic')
+
+def pot_merge(bld):
+ i18n.pot_merge(os.path.join('src', 'lib'), 'libdvdomatic')