Merge master; fix crash on new film.
authorCarl Hetherington <cth@carlh.net>
Fri, 26 Apr 2013 22:41:02 +0000 (23:41 +0100)
committerCarl Hetherington <cth@carlh.net>
Fri, 26 Apr 2013 22:41:02 +0000 (23:41 +0100)
42 files changed:
1  2 
builds/control-12.04-32
builds/control-12.04-64
builds/control-12.10-32
builds/control-12.10-64
cscript
debian/rules
src/lib/ab_transcoder.cc
src/lib/ab_transcoder.h
src/lib/analyse_audio_job.cc
src/lib/audio_sink.h
src/lib/audio_source.cc
src/lib/audio_source.h
src/lib/encoder.cc
src/lib/encoder.h
src/lib/image.h
src/lib/matcher.cc
src/lib/player.cc
src/lib/player.h
src/lib/po/es_ES.po
src/lib/po/fr_FR.po
src/lib/po/it_IT.po
src/lib/po/sv_SE.po
src/lib/transcoder.cc
src/lib/transcoder.h
src/lib/util.cc
src/lib/util.h
src/lib/video_sink.h
src/lib/video_source.cc
src/lib/video_source.h
src/tools/dcpomatic_cli.cc
src/tools/po/es_ES.po
src/tools/po/fr_FR.po
src/tools/po/it_IT.po
src/tools/po/sv_SE.po
src/tools/servomatictest.cc
src/wx/film_viewer.cc
src/wx/film_viewer.h
src/wx/po/es_ES.po
src/wx/po/fr_FR.po
src/wx/po/it_IT.po
src/wx/po/sv_SE.po
test/test.cc

diff --combined builds/control-12.04-32
index d31a5e3844623f9343154bbd8a620fc24eef1e64,0f52d03ae4e984ba4297f2b5c0e765c92df10851..571beee510612921307009e578c4a7afe131b152
@@@ -1,15 -1,24 +1,24 @@@
 -Source: dvdomatic
 +Source: dcpomatic
  Section: video
  Priority: extra
  Maintainer: Carl Hetherington <cth@carlh.net>
  Build-Depends: debhelper (>= 8.0.0), python (>= 2.7.3), g++ (>= 4:4.6.3), pkg-config (>= 0.26), libwxgtk2.8-dev (>= 2.8.12.1), libssh-dev (>= 0.5.2), libboost-filesystem-dev (>= 1.46.0), libboost-thread-dev (>= 1.46.0), libsndfile1-dev (>= 1.0.25), libmagick++-dev (>= 8:6.6.9.7)
  Standards-Version: 3.9.3
 -Homepage: http://carlh.net/software/dvdomatic
 +Homepage: http://carlh.net/software/dcpomatic
  
 -Package: dvdomatic
 +Package: dcpomatic
  Architecture: i386
  Depends: libc6 (>= 2.15), libwxgtk2.8-0 (>= 2.8.12.1), libssh-4 (>= 0.5.2), libboost-filesystem1.46.1 (>= 1.46.1), libboost-thread1.46.1 (>= 1.46.1), libsndfile1 (>= 1.0.25), libmagick++4 (>= 8:6.6.9.7), libxml++2.6-2 (>= 2.34.1)
  Description: Generator of Digital Cinema Packages (DCPs)
 -  DVD-o-matic generates Digital Cinema Packages (DCPs) from video and audio
 +  DCP-o-matic generates Digital Cinema Packages (DCPs) from video and audio
    files (such as those from DVDs or Blu-Rays) for presentation on DCI-compliant
    digital projectors.
+ Package: dvdomatic-dbg
+ Architecture: i386
+ Section: debug
+ Priority: extra
+ Depends: ${dvdomatic:Depends}, ${misc:Depends}
+ Description: debugging symbols for dvdomatic
+   This package contains the debugging symbols for dvdomatic.
diff --combined builds/control-12.04-64
index 5d41558b61f34dd9e208aa8b801c484d3131088e,fa4b4476e77773708487f52073177edf0df8851c..77fbd9e8f47e7f56cd86f877cf565a70b908bd40
@@@ -1,15 -1,24 +1,24 @@@
 -Source: dvdomatic
 +Source: dcpomatic
  Section: video
  Priority: extra
  Maintainer: Carl Hetherington <cth@carlh.net>
  Build-Depends: debhelper (>= 8.0.0), python (>= 2.7.3), g++ (>= 4:4.6.3), pkg-config (>= 0.26), libwxgtk2.8-dev (>= 2.8.12.1), libssh-dev (>= 0.5.2), libboost-filesystem-dev (>= 1.46.0), libboost-thread-dev (>= 1.46.0), libsndfile1-dev (>= 1.0.25), libmagick++-dev (>= 8:6.6.9.7)
  Standards-Version: 3.9.3
 -Homepage: http://carlh.net/software/dvdomatic
 +Homepage: http://carlh.net/software/dcpomatic
  
 -Package: dvdomatic
 +Package: dcpomatic
  Architecture: amd64
  Depends: libc6 (>= 2.15), libwxgtk2.8-0 (>= 2.8.12.1), libssh-4 (>= 0.5.2), libboost-filesystem1.46.1 (>= 1.46.1), libboost-thread1.46.1 (>= 1.46.1), libsndfile1 (>= 1.0.25), libmagick++4 (>= 8:6.6.9.7), libxml++2.6-2 (>= 2.34.1)
  Description: Generator of Digital Cinema Packages (DCPs)
 -  DVD-o-matic generates Digital Cinema Packages (DCPs) from video and audio
 +  DCP-o-matic generates Digital Cinema Packages (DCPs) from video and audio
    files (such as those from DVDs or Blu-Rays) for presentation on DCI-compliant
    digital projectors.
+ Package: dvdomatic-dbg
+ Architecture: amd64
+ Section: debug
+ Priority: extra
+ Depends: ${dvdomatic:Depends}, ${misc:Depends}
+ Description: debugging symbols for dvdomatic
+   This package contains the debugging symbols for dvdomatic.
diff --combined builds/control-12.10-32
index 67933f2ed3e76b1743a29d1895901de758035d2b,0e5fc1f466ecfced9203d368b8343f0fc92b51fb..80b024e46a1e183017a2c5de6ddc6555c3ce1bdf
@@@ -1,15 -1,23 +1,23 @@@
 -Source: dvdomatic
 +Source: dcpomatic
  Section: video
  Priority: extra
  Maintainer: Carl Hetherington <cth@carlh.net>
  Build-Depends: debhelper (>= 8.0.0), python (>= 2.7.3), g++ (>= 4:4.6.3), pkg-config (>= 0.26), libwxgtk2.8-dev (>= 2.8.12.1), libssh-dev (>= 0.5.2), libboost-filesystem-dev (>= 1.46.0), libboost-thread-dev (>= 1.46.0), libsndfile1-dev (>= 1.0.25), libmagick++-dev (>= 8:6.6.9.7)
  Standards-Version: 3.9.3
 -Homepage: http://carlh.net/software/dvdomatic
 +Homepage: http://carlh.net/software/dcpomatic
  
 -Package: dvdomatic
 +Package: dcpomatic
  Architecture: i386
  Depends: libc6 (>= 2.15), libwxgtk2.8-0 (>= 2.8.12.1), libssh-4 (>= 0.5.2), libboost-filesystem1.49.0 (>= 1.49.0), libboost-thread1.49.0 (>= 1.49.0), libsndfile1 (>= 1.0.25), libmagick++5 (>= 8:6.7.7.10), libxml++2.6-2 (>= 2.34.2)
  Description: Generator of Digital Cinema Packages (DCPs)
 -  DVD-o-matic generates Digital Cinema Packages (DCPs) from video and audio
 +  DCP-o-matic generates Digital Cinema Packages (DCPs) from video and audio
    files (such as those from DVDs or Blu-Rays) for presentation on DCI-compliant
    digital projectors.
+ Package: dvdomatic-dbg
+ Architecture: i386
+ Section: debug
+ Priority: extra
+ Depends: ${dvdomatic:Depends}, ${misc:Depends}
+ Description: debugging symbols for dvdomatic
+   This package contains the debugging symbols for dvdomatic.
diff --combined builds/control-12.10-64
index cddf80007628ac5d45f4a0291bcbf06190762436,24e16b4b5afe3c21d3abb531e2d431fef0a0943e..24e893c157e5e19340a4843aaac7a98b35e2c625
@@@ -1,15 -1,24 +1,24 @@@
 -Source: dvdomatic
 +Source: dcpomatic
  Section: video
  Priority: extra
  Maintainer: Carl Hetherington <cth@carlh.net>
  Build-Depends: debhelper (>= 8.0.0), python (>= 2.7.3), g++ (>= 4:4.6.3), pkg-config (>= 0.26), libwxgtk2.8-dev (>= 2.8.12.1), libssh-dev (>= 0.5.2), libboost-filesystem-dev (>= 1.46.0), libboost-thread-dev (>= 1.46.0), libsndfile1-dev (>= 1.0.25), libmagick++-dev (>= 8:6.6.9.7)
  Standards-Version: 3.9.3
 -Homepage: http://carlh.net/software/dvdomatic
 +Homepage: http://carlh.net/software/dcpomatic
  
 -Package: dvdomatic
 +Package: dcpomatic
  Architecture: amd64
  Depends: libc6 (>= 2.15), libwxgtk2.8-0 (>= 2.8.12.1), libssh-4 (>= 0.5.2), libboost-filesystem1.49.0 (>= 1.49.0), libboost-thread1.49.0 (>= 1.49.0), libsndfile1 (>= 1.0.25), libmagick++5 (>= 8:6.7.7.10), libxml++2.6-2 (>= 2.34.2)
  Description: Generator of Digital Cinema Packages (DCPs)
 -  DVD-o-matic generates Digital Cinema Packages (DCPs) from video and audio
 +  DCP-o-matic generates Digital Cinema Packages (DCPs) from video and audio
    files (such as those from DVDs or Blu-Rays) for presentation on DCI-compliant
    digital projectors.
+ Package: dvdomatic-dbg
+ Architecture: amd64
+ Section: debug
+ Priority: extra
+ Depends: ${dvdomatic:Depends}, ${misc:Depends}
+ Description: debugging symbols for dvdomatic
+   This package contains the debugging symbols for dvdomatic.
diff --combined cscript
index cd60162d94324d720a42ce05004672419182f044,0111e9638db266ecdab5499b620497fa95a241f5..92157a5813d4a9a122870146aabcc413f3830e91
+++ b/cscript
@@@ -7,7 -7,6 +7,7 @@@ def dependencies(target)
          return ()
      else:
          return (('openjpeg-cdist', None),
 +                ('libcxml', None),
                  ('ffmpeg-cdist', '488d5d4496af5e3a3b9d31d6b221e8eeada6b77e'),
                  ('libdcp', 'v0.45'))
  
@@@ -43,26 -42,31 +43,31 @@@ def package(env, target, version)
          shutil.copyfile('builds/control-%s-%d' % (target.version, target.bits), 'debian/control')
          env.command('./waf dist')
          f = open('debian/files', 'w')
 -        print >>f,'dvdomatic_%s-1_%s.deb video extra' % (version, cpu)
 +        print >>f,'dcpomatic_%s-1_%s.deb video extra' % (version, cpu)
          shutil.rmtree('build/deb', ignore_errors=True)
  
          os.makedirs('build/deb')
          os.chdir('build/deb')
 -        shutil.move('../../dvdomatic-%s.tar.bz2' % version, 'dvdomatic_%s.orig.tar.bz2' % version)
 -        env.command('tar xjf dvdomatic_%s.orig.tar.bz2' % version)
 -        os.chdir('dvdomatic-%s' % version)
 +        shutil.move('../../dcpomatic-%s.tar.bz2' % version, 'dcpomatic_%s.orig.tar.bz2' % version)
 +        env.command('tar xjf dcpomatic_%s.orig.tar.bz2' % version)
 +        os.chdir('dcpomatic-%s' % version)
          env.command('dch -b -v %s-1 "New upstream release."' % version)
          env.set('CDIST_LINKFLAGS', env.get('LINKFLAGS'))
          env.set('CDIST_CXXFLAGS', env.get('CXXFLAGS'))
          env.set('CDIST_PKG_CONFIG_PATH', env.get('PKG_CONFIG_PATH'))
          env.command('dpkg-buildpackage')
-         return os.path.abspath(glob.glob('../*.deb')[0])
+         
+         debs = []
+         for p in glob.glob('../*.deb'):
+             debs.append(os.path.abspath(p))
+         return debs
  
  def make_pot(env):
      env.command('./waf pot')
 -    return [os.path.abspath('build/src/lib/libdvdomatic.pot'),
 -            os.path.abspath('build/src/wx/libdvdomatic-wx.pot'),
 -          os.path.abspath('build/src/tools/dvdomatic.pot')]
 +    return [os.path.abspath('build/src/lib/libdcpomatic.pot'),
 +            os.path.abspath('build/src/wx/libdcpomatic-wx.pot'),
 +          os.path.abspath('build/src/tools/dcpomatic.pot')]
  
  def make_manual(env):
      os.chdir('doc/manual')
diff --combined debian/rules
index 7f7da5530eddbb8d128f2ba9035454482dbe7844,f2b2219beb7c56829e770256c1810a3a68db03a7..17594701970869bd061c1f082cfdeb531c5607b0
  
  override_dh_auto_configure:
        LINKFLAGS=$(CDIST_LINKFLAGS) CXXFLAGS="$(CXXFLAGS) $(CDIST_CXXFLAGS)" PKG_CONFIG_PATH=$(CDIST_PKG_CONFIG_PATH) \
-                ./waf --nocache configure --prefix=/usr --static
+                ./waf --nocache configure --prefix=/usr --static --enable-debug
  
  override_dh_auto_build:
        ./waf --nocache build
  
  override_dh_auto_install:
 -      ./waf --nocache install --destdir=debian/dvdomatic
 +      ./waf --nocache install --destdir=debian/dcpomatic
  
+ .PHONY: override_dh_strip
+ override_dh_strip:
+       dh_strip --dbg-package=dvdomatic-dbg
diff --combined src/lib/ab_transcoder.cc
index c6ccfdc67e268492a9cae8eca5de06f53c7b3daf,d8f13dae4b7854afb0b1f4d97c70ab488f78ff2c..2e0d41e7de08f24c4bc83b6fb615cecf9cf9a0de
  #include <boost/shared_ptr.hpp>
  #include "ab_transcoder.h"
  #include "film.h"
 -#include "video_decoder.h"
 -#include "audio_decoder.h"
  #include "encoder.h"
  #include "job.h"
 -#include "options.h"
  #include "image.h"
 -#include "decoder_factory.h"
 +#include "player.h"
  #include "matcher.h"
  #include "delay_line.h"
  #include "gain.h"
  #include "combiner.h"
+ #include "trimmer.h"
  
  /** @file src/ab_transcoder.cc
   *  @brief A transcoder which uses one Film for the left half of the screen, and a different one
@@@ -46,30 -50,60 +47,40 @@@ using boost::dynamic_pointer_cast
   *  @param e Encoder to use.
   */
  
 -ABTranscoder::ABTranscoder (
 -      shared_ptr<Film> a, shared_ptr<Film> b, DecodeOptions o, Job* j, shared_ptr<Encoder> e)
 +ABTranscoder::ABTranscoder (shared_ptr<Film> a, shared_ptr<Film> b, shared_ptr<Job> j)
        : _film_a (a)
        , _film_b (b)
 +      , _player_a (_film_a->player ())
 +      , _player_b (_film_b->player ())
        , _job (j)
 -      , _encoder (e)
 +      , _encoder (new Encoder (_film_a))
        , _combiner (new Combiner (a->log()))
  {
 -      _da = decoder_factory (_film_a, o);
 -      _db = decoder_factory (_film_b, o);
 -
 -      shared_ptr<AudioStream> st = _film_a->audio_stream();
 -      if (st) {
 -              _matcher.reset (new Matcher (_film_a->log(), st->sample_rate(), _film_a->source_frame_rate()));
 -      }
 -      _delay_line.reset (new DelayLine (_film_a->log(), _film_a->audio_delay() / 1000.0f));
 +      _matcher.reset (new Matcher (_film_a->log(), _film_a->audio_frame_rate(), _film_a->video_frame_rate()));
 +      _delay_line.reset (new DelayLine (_film_a->log(), _film_a->audio_delay() * _film_a->audio_frame_rate() / 1000));
        _gain.reset (new Gain (_film_a->log(), _film_a->audio_gain()));
  
 -      int const sr = st ? st->sample_rate() : 0;
 +      _player_a->Video.connect (bind (&Combiner::process_video, _combiner, _1, _2, _3, _4));
 +      _player_b->Video.connect (bind (&Combiner::process_video_b, _combiner, _1, _2, _3, _4));
 +
+       int const trim_start = _film_a->trim_type() == Film::ENCODE ? _film_a->trim_start() : 0;
+       int const trim_end = _film_a->trim_type() == Film::ENCODE ? _film_a->trim_end() : 0;
+       _trimmer.reset (new Trimmer (
 -                              _film_a->log(), trim_start, trim_end, _film_a->length().get(),
 -                              sr, _film_a->source_frame_rate(), _film_a->dcp_frame_rate()
++                              _film_a->log(), trim_start, trim_end, _film_a->content_length(),
++                              _film_a->audio_frame_rate(), _film_a->video_frame_rate(), _film_a->dcp_frame_rate()
+                               ));
+       
 -      /* Set up the decoder to use the film's set streams */
 -      _da.video->set_subtitle_stream (_film_a->subtitle_stream ());
 -      _db.video->set_subtitle_stream (_film_a->subtitle_stream ());
 -      if (_film_a->audio_stream ()) {
 -              _da.audio->set_audio_stream (_film_a->audio_stream ());
 -      }
 -
 -      _da.video->Video.connect (bind (&Combiner::process_video, _combiner, _1, _2, _3, _4));
 -      _db.video->Video.connect (bind (&Combiner::process_video_b, _combiner, _1, _2, _3, _4));
        _combiner->connect_video (_delay_line);
 -      if (_matcher) {
 -              _delay_line->connect_video (_matcher);
 -              _matcher->connect_video (_trimmer);
 -      } else {
 -              _delay_line->connect_video (_trimmer);
 -      }
 +      _delay_line->connect_video (_matcher);
-       _matcher->connect_video (_encoder);
++      _matcher->connect_video (_trimmer);
+       _trimmer->connect_video (_encoder);
        
 -      _da.audio->connect_audio (_delay_line);
 -      if (_matcher) {
 -              _delay_line->connect_audio (_matcher);
 -              _matcher->connect_audio (_gain);
 -      } else {
 -              _delay_line->connect_audio (_gain);
 -      }
 +      _player_a->connect_audio (_delay_line);
 +      _delay_line->connect_audio (_matcher);
 +      _matcher->connect_audio (_gain);
-       _gain->connect_audio (_encoder);
+       _gain->connect_audio (_trimmer);
+       _trimmer->connect_audio (_encoder);
  }
  
  void
@@@ -77,30 -111,32 +88,25 @@@ ABTranscoder::go (
  {
        _encoder->process_begin ();
  
 -      bool done[3] = { false, false, false };
 +      bool done[2] = { false, false };
        
        while (1) {
 -              done[0] = _da.video->pass ();
 -              done[1] = _db.video->pass ();
 -              
 -              if (!done[2] && _da.audio && dynamic_pointer_cast<Decoder> (_da.audio) != dynamic_pointer_cast<Decoder> (_da.video)) {
 -                      done[2] = _da.audio->pass ();
 -              } else {
 -                      done[2] = true;
 -              }
 -              
 +              done[0] = _player_a->pass ();
 +              done[1] = _player_b->pass ();
 +
                if (_job) {
 -                      _da.video->set_progress (_job);
 +                      _player_a->set_progress (_job);
                }
 -              
 -              if (done[0] && done[1] && done[2]) {
 +
 +              if (done[0] && done[1]) {
                        break;
                }
        }
-       if (_delay_line) {
-               _delay_line->process_end ();
-       }
-       if (_matcher) {
-               _matcher->process_end ();
-       }
-       if (_gain) {
-               _gain->process_end ();
-       }
+               
+       _delay_line->process_end ();
 -      if (_matcher) {
 -              _matcher->process_end ();
 -      }
++      _matcher->process_end ();
+       _gain->process_end ();
++      _trimmer->process_end ();
        _encoder->process_end ();
  }
                            
diff --combined src/lib/ab_transcoder.h
index b1b01d724f7b4818400122c7347aafe8d9f0bcad,4f1b14e48ef27bea3072510ae58088046c784ca0..1fef66b8870a3ae72de2d8a645e056d656239350
  #include <boost/shared_ptr.hpp>
  #include <stdint.h>
  #include "util.h"
 -#include "decoder_factory.h"
  
  class Job;
  class Encoder;
 -class VideoDecoder;
 -class AudioDecoder;
  class Image;
  class Log;
 -class Subtitle;
  class Film;
  class Matcher;
  class DelayLine;
  class Gain;
  class Combiner;
 +class Player;
+ class Trimmer;
  
  /** @class ABTranscoder
   *  @brief A transcoder which uses one Film for the left half of the screen, and a different one
@@@ -47,7 -51,9 +48,7 @@@ public
        ABTranscoder (
                boost::shared_ptr<Film> a,
                boost::shared_ptr<Film> b,
 -              DecodeOptions o,
 -              Job* j,
 -              boost::shared_ptr<Encoder> e
 +              boost::shared_ptr<Job> j
                );
        
        void go ();
  private:
        boost::shared_ptr<Film> _film_a;
        boost::shared_ptr<Film> _film_b;
 -      Job* _job;
 +      boost::shared_ptr<Player> _player_a;
 +      boost::shared_ptr<Player> _player_b;
 +      boost::shared_ptr<Job> _job;
        boost::shared_ptr<Encoder> _encoder;
 -      Decoders _da;
 -      Decoders _db;
        boost::shared_ptr<Combiner> _combiner;
        boost::shared_ptr<Matcher> _matcher;
        boost::shared_ptr<DelayLine> _delay_line;
        boost::shared_ptr<Gain> _gain;
+       boost::shared_ptr<Trimmer> _trimmer;
        boost::shared_ptr<Image> _image;
  };
index 50096d7c125f183d694d4534febbadb4f20f4739,88cd65fee64f0227d24960600b6664dc46721ae1..f3c55b208db152bd866eed8a44f550ff2c20c957
@@@ -21,7 -21,9 +21,7 @@@
  #include "analyse_audio_job.h"
  #include "compose.hpp"
  #include "film.h"
 -#include "options.h"
 -#include "decoder_factory.h"
 -#include "audio_decoder.h"
 +#include "player.h"
  
  #include "i18n.h"
  
@@@ -50,18 -52,29 +50,18 @@@ AnalyseAudioJob::name () cons
  void
  AnalyseAudioJob::run ()
  {
 -      if (!_film->audio_stream () || !_film->length()) {
 -              set_progress (1);
 -              set_state (FINISHED_ERROR);
 -              return;
 -      }
 -              
 -      DecodeOptions options;
 -      options.decode_video = false;
 -
 -      Decoders decoders = decoder_factory (_film, options);
 -      assert (decoders.audio);
 +      shared_ptr<Player> player = _film->player ();
 +      player->disable_video ();
        
 -      decoders.audio->set_audio_stream (_film->audio_stream ());
 -      decoders.audio->Audio.connect (bind (&AnalyseAudioJob::audio, this, _1));
 +      player->Audio.connect (bind (&AnalyseAudioJob::audio, this, _1));
  
 -      int64_t total_audio_frames = video_frames_to_audio_frames (_film->length().get(), _film->audio_stream()->sample_rate(), _film->source_frame_rate());
 -      _samples_per_point = max (int64_t (1), total_audio_frames / _num_points);
 +      _samples_per_point = max (int64_t (1), _film->audio_length() / _num_points);
  
 -      _current.resize (_film->audio_stream()->channels ());
 -      _analysis.reset (new AudioAnalysis (_film->audio_stream()->channels()));
 +      _current.resize (MAX_AUDIO_CHANNELS);
 +      _analysis.reset (new AudioAnalysis (MAX_AUDIO_CHANNELS));
                         
 -      while (!decoders.audio->pass()) {
 -              set_progress (float (_done) / total_audio_frames);
 +      while (!player->pass()) {
 +              set_progress (float (_done) / _film->audio_length ());
        }
  
        _analysis->write (_film->audio_analysis_path ());
@@@ -71,7 -84,7 +71,7 @@@
  }
  
  void
- AnalyseAudioJob::audio (shared_ptr<AudioBuffers> b)
+ AnalyseAudioJob::audio (shared_ptr<const AudioBuffers> b)
  {
        for (int i = 0; i < b->frames(); ++i) {
                for (int j = 0; j < b->channels(); ++j) {
diff --combined src/lib/audio_sink.h
index ba4b772c8a66b02057d070e8d014473479d76604,69b3a4b7522788d9739297506c1e135bd854328b..ee39f9ee749bcdd90ff00c2954d1d79c6baf6336
  
  */
  
 -#ifndef DVDOMATIC_AUDIO_SINK_H
 -#define DVDOMATIC_AUDIO_SINK_H
 +#ifndef DCPOMATIC_AUDIO_SINK_H
 +#define DCPOMATIC_AUDIO_SINK_H
  
  class AudioSink
  {
  public:
        /** Call with some audio data */
-       virtual void process_audio (boost::shared_ptr<AudioBuffers>) = 0;
+       virtual void process_audio (boost::shared_ptr<const AudioBuffers>) = 0;
  };
  
  class TimedAudioSink
  {
  public:
          /** Call with some audio data */
-         virtual void process_audio (boost::shared_ptr<AudioBuffers>, double t) = 0;
+         virtual void process_audio (boost::shared_ptr<const AudioBuffers>, double t) = 0;
  };
  
  #endif
diff --combined src/lib/audio_source.cc
index 3dd3027ab4650bd23fd4ef4fc8fd958438e5a7f4,d77e89367b059de70606d953be86f9ca50dae6ca..32b3deccfa4a887384d7c834eb1d9d2bcf0c039b
  #include "audio_sink.h"
  
  using boost::shared_ptr;
 +using boost::weak_ptr;
  using boost::bind;
  
- process_audio_proxy (weak_ptr<AudioSink> sink, shared_ptr<AudioBuffers> audio)
 +static void
++process_audio_proxy (weak_ptr<AudioSink> sink, shared_ptr<const AudioBuffers> audio)
 +{
 +      shared_ptr<AudioSink> p = sink.lock ();
 +      if (p) {
 +              p->process_audio (audio);
 +      }
 +}
 +
  void
  AudioSource::connect_audio (shared_ptr<AudioSink> s)
  {
 -      Audio.connect (bind (&AudioSink::process_audio, s, _1));
 +      Audio.connect (bind (process_audio_proxy, weak_ptr<AudioSink> (s), _1));
  }
  
  void
@@@ -44,3 -34,9 +44,9 @@@ TimedAudioSource::connect_audio (shared
  {
        Audio.connect (bind (&TimedAudioSink::process_audio, s, _1, _2));
  }
+ void
+ TimedAudioSource::connect_audio (shared_ptr<AudioSink> s)
+ {
+       Audio.connect (bind (&AudioSink::process_audio, s, _1));
+ }
diff --combined src/lib/audio_source.h
index dd248071651fbbc0e7c1b497e9cfcdf39c899970,c13f1636b521661055ed18eb3c5daf89aaa44948..c7f0a09ed762c438250e67394dc50ab33dcb0892
@@@ -21,8 -21,8 +21,8 @@@
   *  @brief Parent class for classes which emit audio data.
   */
  
 -#ifndef DVDOMATIC_AUDIO_SOURCE_H
 -#define DVDOMATIC_AUDIO_SOURCE_H
 +#ifndef DCPOMATIC_AUDIO_SOURCE_H
 +#define DCPOMATIC_AUDIO_SOURCE_H
  
  #include <boost/signals2.hpp>
  
@@@ -35,7 -35,7 +35,7 @@@ class AudioSourc
  {
  public:
        /** Emitted when some audio data is ready */
-       boost::signals2::signal<void (boost::shared_ptr<AudioBuffers>)> Audio;
+       boost::signals2::signal<void (boost::shared_ptr<const AudioBuffers>)> Audio;
  
        void connect_audio (boost::shared_ptr<AudioSink>);
  };
@@@ -46,8 -46,9 +46,9 @@@ class TimedAudioSourc
  {
  public:
        /** Emitted when some audio data is ready */
-       boost::signals2::signal<void (boost::shared_ptr<AudioBuffers>, double)> Audio;
+       boost::signals2::signal<void (boost::shared_ptr<const AudioBuffers>, double)> Audio;
  
+       void connect_audio (boost::shared_ptr<AudioSink>);
        void connect_audio (boost::shared_ptr<TimedAudioSink>);
  };
  
diff --combined src/lib/encoder.cc
index f56440dd7c1026bfb97f564410bb8c36512beac3,cff9899acb6151cc19990f372c0a091c7d63968f..c1d1041ae539f9cdab1f087291eb2d8d7104abbb
@@@ -27,6 -27,7 +27,6 @@@
  #include <libdcp/picture_asset.h>
  #include "encoder.h"
  #include "util.h"
 -#include "options.h"
  #include "film.h"
  #include "log.h"
  #include "exceptions.h"
@@@ -37,8 -38,6 +37,8 @@@
  #include "format.h"
  #include "cross.h"
  #include "writer.h"
 +#include "player.h"
 +#include "audio_mapping.h"
  
  #include "i18n.h"
  
@@@ -49,8 -48,7 +49,8 @@@ using std::vector
  using std::list;
  using std::cout;
  using std::make_pair;
 -using namespace boost;
 +using boost::shared_ptr;
 +using boost::optional;
  
  int const Encoder::_history_size = 25;
  
@@@ -79,29 -77,22 +79,29 @@@ Encoder::~Encoder (
  void
  Encoder::process_begin ()
  {
 -      if (_film->audio_stream() && _film->audio_stream()->sample_rate() != _film->target_audio_sample_rate()) {
 +      if (_film->has_audio() && _film->audio_frame_rate() != _film->target_audio_sample_rate()) {
  #ifdef HAVE_SWRESAMPLE
  
                stringstream s;
 -              s << String::compose (N_("Will resample audio from %1 to %2"), _film->audio_stream()->sample_rate(), _film->target_audio_sample_rate());
 +              s << String::compose (N_("Will resample audio from %1 to %2"), _film->audio_frame_rate(), _film->target_audio_sample_rate());
                _film->log()->log (s.str ());
  
 -              /* We will be using planar float data when we call the resampler */
 +              /* We will be using planar float data when we call the
 +                 resampler.  As far as I can see, the audio channel
 +                 layout is not necessary for our purposes; it seems
 +                 only to be used get the number of channels and
 +                 decide if rematrixing is needed.  It won't be, since
 +                 input and output layouts are the same.
 +              */
 +
                _swr_context = swr_alloc_set_opts (
                        0,
 -                      _film->audio_stream()->channel_layout(),
 +                      av_get_default_channel_layout (_film->audio_mapping().dcp_channels ()),
                        AV_SAMPLE_FMT_FLTP,
                        _film->target_audio_sample_rate(),
 -                      _film->audio_stream()->channel_layout(),
 +                      av_get_default_channel_layout (_film->audio_mapping().dcp_channels ()),
                        AV_SAMPLE_FMT_FLTP,
 -                      _film->audio_stream()->sample_rate(),
 +                      _film->audio_frame_rate(),
                        0, 0
                        );
                
@@@ -135,9 -126,9 +135,9 @@@ voi
  Encoder::process_end ()
  {
  #if HAVE_SWRESAMPLE   
 -      if (_film->audio_stream() && _film->audio_stream()->channels() && _swr_context) {
 +      if (_film->has_audio() && _swr_context) {
  
 -              shared_ptr<AudioBuffers> out (new AudioBuffers (_film->audio_stream()->channels(), 256));
 +              shared_ptr<AudioBuffers> out (new AudioBuffers (_film->audio_mapping().dcp_channels(), 256));
                        
                while (1) {
                        int const frames = swr_convert (_swr_context, (uint8_t **) out->data(), 256, 0, 0);
                        }
  
                        out->set_frames (frames);
 -                      write_audio (out);
 +                      _writer->write (out);
                }
  
                swr_free (&_swr_context);
   *  or 0 if not known.
   */
  float
 -Encoder::current_frames_per_second () const
 +Encoder::current_encoding_rate () const
  {
        boost::mutex::scoped_lock lock (_history_mutex);
        if (int (_time_history.size()) < _history_size) {
@@@ -240,9 -231,9 +240,9 @@@ Encoder::frame_done (
  }
  
  void
- Encoder::process_video (shared_ptr<Image> image, bool same, shared_ptr<Subtitle> sub)
 -Encoder::process_video (shared_ptr<const Image> image, bool same, boost::shared_ptr<Subtitle> sub)
++Encoder::process_video (shared_ptr<const Image> image, bool same, shared_ptr<Subtitle> sub)
  {
 -      FrameRateConversion frc (_film->source_frame_rate(), _film->dcp_frame_rate());
 +      FrameRateConversion frc (_film->video_frame_rate(), _film->dcp_frame_rate());
        
        if (frc.skip && (_video_frames_in % 2)) {
                ++_video_frames_in;
                /* Queue this new frame for encoding */
                pair<string, string> const s = Filter::ffmpeg_strings (_film->filters());
                TIMING ("adding to queue of %1", _queue.size ());
 -              _queue.push_back (boost::shared_ptr<DCPVideoFrame> (
 +              _queue.push_back (shared_ptr<DCPVideoFrame> (
                                          new DCPVideoFrame (
                                                  image, sub, _film->format()->dcp_size(), _film->format()->dcp_padding (_film),
                                                  _film->subtitle_offset(), _film->subtitle_scale(),
  }
  
  void
- Encoder::process_audio (shared_ptr<AudioBuffers> data)
+ Encoder::process_audio (shared_ptr<const AudioBuffers> data)
  {
  #if HAVE_SWRESAMPLE
        /* Maybe sample-rate convert */
        if (_swr_context) {
  
                /* Compute the resampled frames count and add 32 for luck */
 -              int const max_resampled_frames = ceil ((int64_t) data->frames() * _film->target_audio_sample_rate() / _film->audio_stream()->sample_rate()) + 32;
 +              int const max_resampled_frames = ceil ((int64_t) data->frames() * _film->target_audio_sample_rate() / _film->audio_frame_rate()) + 32;
  
 -              shared_ptr<AudioBuffers> resampled (new AudioBuffers (_film->audio_stream()->channels(), max_resampled_frames));
 +              shared_ptr<AudioBuffers> resampled (new AudioBuffers (_film->audio_mapping().dcp_channels(), max_resampled_frames));
  
                /* Resample audio */
                int const resampled_frames = swr_convert (
        }
  #endif
  
 -      write_audio (data);
 +      _writer->write (data);
  }
  
  void
@@@ -342,7 -333,9 +342,9 @@@ Encoder::terminate_threads (
        lock.unlock ();
  
        for (list<boost::thread *>::iterator i = _threads.begin(); i != _threads.end(); ++i) {
-               (*i)->join ();
+               if ((*i)->joinable ()) {
+                       (*i)->join ();
+               }
                delete *i;
        }
  }
@@@ -369,7 -362,7 +371,7 @@@ Encoder::encoder_thread (ServerDescript
                }
  
                TIMING ("encoder thread %1 wakes with queue of %2", boost::this_thread::get_id(), _queue.size());
 -              boost::shared_ptr<DCPVideoFrame> vf = _queue.front ();
 +              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 ();
                
                }
  
                if (remote_backoff > 0) {
 -                      dvdomatic_sleep (remote_backoff);
 +                      dcpomatic_sleep (remote_backoff);
                }
  
                lock.lock ();
                _condition.notify_all ();
        }
  }
 -
 -void
 -Encoder::write_audio (shared_ptr<const AudioBuffers> data)
 -{
 -      AudioMapping m (_film->audio_channels ());
 -      if (m.dcp_channels() != _film->audio_channels()) {
 -
 -              /* Remap (currently just for mono -> 5.1) */
 -
 -              shared_ptr<AudioBuffers> b (new AudioBuffers (m.dcp_channels(), data->frames ()));
 -              for (int i = 0; i < m.dcp_channels(); ++i) {
 -                      optional<int> s = m.dcp_to_source (static_cast<libdcp::Channel> (i));
 -                      if (!s) {
 -                              b->make_silent (i);
 -                      } else {
 -                              memcpy (b->data()[i], data->data()[s.get()], data->frames() * sizeof(float));
 -                      }
 -              }
 -
 -              data = b;
 -      }
 -
 -      _writer->write (data);
 -}
diff --combined src/lib/encoder.h
index 56007fd485f0ba04f2c1c6adff61acba516bef81,70e81a7e071d483f3ae6bad45faf5b76f9c8c797..f95d42661b1ed5d50442beed89c7238fa614f675
@@@ -17,8 -17,8 +17,8 @@@
  
  */
  
 -#ifndef DVDOMATIC_ENCODER_H
 -#define DVDOMATIC_ENCODER_H
 +#ifndef DCPOMATIC_ENCODER_H
 +#define DCPOMATIC_ENCODER_H
  
  /** @file src/encoder.h
   *  @brief Encoder to J2K and WAV for DCP.
@@@ -73,21 -73,23 +73,21 @@@ public
         *  @param same true if i is the same as the last time we were called.
         *  @param s A subtitle that should be on this frame, or 0.
         */
-       void process_video (boost::shared_ptr<Image> i, bool same, boost::shared_ptr<Subtitle> s);
+       void process_video (boost::shared_ptr<const Image> i, bool same, boost::shared_ptr<Subtitle> s);
  
        /** Call with some audio data */
-       void process_audio (boost::shared_ptr<AudioBuffers>);
+       void process_audio (boost::shared_ptr<const AudioBuffers>);
  
        /** Called when a processing run has finished */
        virtual void process_end ();
  
 -      float current_frames_per_second () const;
 +      float current_encoding_rate () const;
        int video_frames_out () const;
  
  private:
        
        void frame_done ();
        
 -      void write_audio (boost::shared_ptr<const AudioBuffers> data);
 -
        void encoder_thread (ServerDescription *);
        void terminate_threads ();
  
        static int const _history_size;
  
        /** Number of video frames received so far */
 -      SourceFrame _video_frames_in;
 +      ContentVideoFrame _video_frames_in;
        /** Number of video frames written for the DCP so far */
        int _video_frames_out;
  
diff --combined src/lib/image.h
index 1d7d75dfc9a32361541dd70d81d86feb59034dcc,62961a92e12d56cd5d9ac658bb12d1c47e27658d..de03d0e3f60485a8d316deb00cef21ad80bc92f7
@@@ -21,8 -21,8 +21,8 @@@
   *  @brief A set of classes to describe video images.
   */
  
 -#ifndef DVDOMATIC_IMAGE_H
 -#define DVDOMATIC_IMAGE_H
 +#ifndef DCPOMATIC_IMAGE_H
 +#define DCPOMATIC_IMAGE_H
  
  #include <string>
  #include <boost/shared_ptr.hpp>
@@@ -131,6 -131,7 +131,7 @@@ class SimpleImage : public Imag
  public:
        SimpleImage (AVPixelFormat, libdcp::Size, bool);
        SimpleImage (SimpleImage const &);
+       SimpleImage (boost::shared_ptr<const Image>);
        SimpleImage& operator= (SimpleImage const &);
        ~SimpleImage ();
  
diff --combined src/lib/matcher.cc
index edbb084de7ebd6e4a872cdaf3218a00ab5199d03,9924c003ae5b81298ef27653e5ba015d7d312307..c56a563015b6eb617bf38535ff81be81c7cffeb0
@@@ -41,7 -41,7 +41,7 @@@ Matcher::Matcher (shared_ptr<Log> log, 
  }
  
  void
- Matcher::process_video (shared_ptr<Image> image, bool same, boost::shared_ptr<Subtitle> sub, double t)
 -Matcher::process_video (boost::shared_ptr<const Image> image, bool same, boost::shared_ptr<Subtitle> sub, double t)
++Matcher::process_video (shared_ptr<const Image> image, bool same, boost::shared_ptr<Subtitle> sub, double t)
  {
        _pixel_format = image->pixel_format ();
        _size = image->size ();
  }
  
  void
- Matcher::process_audio (shared_ptr<AudioBuffers> b, double t)
 -Matcher::process_audio (boost::shared_ptr<const AudioBuffers> b, double t)
++Matcher::process_audio (shared_ptr<const AudioBuffers> b, double t)
  {
        _channels = b->channels ();
  
-       _log->log (String::compose ("Matcher audio @ %1 [video=%2, audio=%3, pending_audio=%4]", t, _video_frames, _audio_frames, _pending_audio.size()));
+       _log->log (String::compose (
+                          "Matcher audio (%1 frames) @ %2 [video=%3, audio=%4, pending_audio=%5]",
+                          b->frames(), t, _video_frames, _audio_frames, _pending_audio.size()
+                          )
+               );
  
        if (!_first_input) {
                _first_input = t;
@@@ -198,8 -202,9 +202,9 @@@ voi
  Matcher::repeat_last_video ()
  {
        if (!_last_image) {
-               _last_image.reset (new SimpleImage (_pixel_format.get(), _size.get(), true));
-               _last_image->make_black ();
+               shared_ptr<Image> im (new SimpleImage (_pixel_format.get(), _size.get(), true));
+               im->make_black ();
+               _last_image = im;
        }
  
        Video (_last_image, true, _last_subtitle);
diff --combined src/lib/player.cc
index 7c75597eac352ea77179c9d28625ef35e7cff7de,0000000000000000000000000000000000000000..09f1f55a32cdc3a909448d37642278d59b5961ea
mode 100644,000000..100644
--- /dev/null
@@@ -1,319 -1,0 +1,323 @@@
- Player::process_video (shared_ptr<Image> i, bool same, shared_ptr<Subtitle> s, double t)
 +/*
 +    Copyright (C) 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 "player.h"
 +#include "film.h"
 +#include "ffmpeg_decoder.h"
 +#include "ffmpeg_content.h"
 +#include "imagemagick_decoder.h"
 +#include "imagemagick_content.h"
 +#include "sndfile_decoder.h"
 +#include "sndfile_content.h"
 +#include "playlist.h"
 +#include "job.h"
 +
 +using std::list;
 +using std::cout;
 +using std::vector;
 +using boost::shared_ptr;
 +using boost::weak_ptr;
 +using boost::dynamic_pointer_cast;
 +
 +Player::Player (shared_ptr<const Film> f, shared_ptr<const Playlist> p)
 +      : _film (f)
 +      , _playlist (p)
 +      , _video (true)
 +      , _audio (true)
 +      , _subtitles (true)
 +      , _have_valid_decoders (false)
 +{
 +      _playlist->Changed.connect (bind (&Player::playlist_changed, this));
 +      _playlist->ContentChanged.connect (bind (&Player::content_changed, this, _1, _2));
 +}
 +
 +void
 +Player::disable_video ()
 +{
 +      _video = false;
 +}
 +
 +void
 +Player::disable_audio ()
 +{
 +      _audio = false;
 +}
 +
 +void
 +Player::disable_subtitles ()
 +{
 +      _subtitles = false;
 +}
 +
 +bool
 +Player::pass ()
 +{
 +      if (!_have_valid_decoders) {
 +              setup_decoders ();
 +              _have_valid_decoders = true;
 +      }
 +      
 +      bool done = true;
 +      
 +      if (_video && _video_decoder < _video_decoders.size ()) {
 +
 +              /* Run video decoder; this may also produce audio */
 +              
 +              if (_video_decoders[_video_decoder]->pass ()) {
 +                      _video_decoder++;
 +              }
 +              
 +              if (_video_decoder < _video_decoders.size ()) {
 +                      done = false;
 +              }
 +              
 +      }
 +
 +      if (!_video && _audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG && _sequential_audio_decoder < _audio_decoders.size ()) {
 +
 +              /* We're not producing video, so we may need to run FFmpeg content to get the audio */
 +              
 +              if (_audio_decoders[_sequential_audio_decoder]->pass ()) {
 +                      _sequential_audio_decoder++;
 +              }
 +              
 +              if (_sequential_audio_decoder < _audio_decoders.size ()) {
 +                      done = false;
 +              }
 +              
 +      }
 +
 +      if (_audio && _playlist->audio_from() == Playlist::AUDIO_SNDFILE) {
 +              
 +              /* We're getting audio from SndfileContent */
 +              
 +              for (vector<shared_ptr<AudioDecoder> >::iterator i = _audio_decoders.begin(); i != _audio_decoders.end(); ++i) {
 +                      if (!(*i)->pass ()) {
 +                              done = false;
 +                      }
 +              }
 +
 +              Audio (_audio_buffers, _audio_time.get());
 +              _audio_buffers.reset ();
 +              _audio_time = boost::none;
 +      }
 +
 +      return done;
 +}
 +
 +void
 +Player::set_progress (shared_ptr<Job> job)
 +{
 +      /* Assume progress can be divined from how far through the video we are */
 +
 +      if (_video_decoder >= _video_decoders.size() || !_playlist->video_length()) {
 +              return;
 +      }
 +
 +      job->set_progress ((_video_start[_video_decoder] + _video_decoders[_video_decoder]->video_frame()) / _playlist->video_length ());
 +}
 +
 +void
- Player::process_audio (weak_ptr<const AudioContent> c, shared_ptr<AudioBuffers> b, double t)
++Player::process_video (shared_ptr<const Image> i, bool same, shared_ptr<Subtitle> s, double t)
 +{
 +      Video (i, same, s, _video_start[_video_decoder] + t);
 +}
 +
 +void
++Player::process_audio (weak_ptr<const AudioContent> c, shared_ptr<const AudioBuffers> b, double t)
 +{
 +      AudioMapping mapping = _film->audio_mapping ();
 +      if (!_audio_buffers) {
 +              _audio_buffers.reset (new AudioBuffers (mapping.dcp_channels(), b->frames ()));
 +              _audio_buffers->make_silent ();
 +              _audio_time = t;
 +              if (_playlist->audio_from() == Playlist::AUDIO_FFMPEG) {
 +                      _audio_time = _audio_time.get() + _audio_start[_sequential_audio_decoder];
 +              }
 +      }
 +
 +      for (int i = 0; i < b->channels(); ++i) {
 +              list<libdcp::Channel> dcp = mapping.content_to_dcp (AudioMapping::Channel (c, i));
 +              for (list<libdcp::Channel>::iterator j = dcp.begin(); j != dcp.end(); ++j) {
 +                      _audio_buffers->accumulate (b, i, static_cast<int> (*j));
 +              }
 +      }
 +
 +      if (_playlist->audio_from() == Playlist::AUDIO_FFMPEG) {
 +              /* We can just emit this audio now as it will all be here */
 +              Audio (_audio_buffers, t);
 +              _audio_buffers.reset ();
 +              _audio_time = boost::none;
 +      }
 +}
 +
 +/** @return true on error */
 +bool
 +Player::seek (double t)
 +{
 +      if (!_have_valid_decoders) {
 +              setup_decoders ();
 +              _have_valid_decoders = true;
 +      }
 +
++      if (_video_decoders.empty ()) {
++              return true;
++      }
++
 +      /* Find the decoder that contains this position */
 +      _video_decoder = 0;
 +      while (1) {
 +              ++_video_decoder;
 +              if (_video_decoder >= _video_decoders.size () || t < _video_start[_video_decoder]) {
 +                      --_video_decoder;
 +                      t -= _video_start[_video_decoder];
 +                      break;
 +              }
 +      }
 +
 +      if (_video_decoder < _video_decoders.size()) {
 +              _video_decoders[_video_decoder]->seek (t);
 +      } else {
 +              return true;
 +      }
 +
 +      /* XXX: don't seek audio because we don't need to... */
 +
 +      return false;
 +}
 +
 +
 +void
 +Player::seek_back ()
 +{
 +      /* XXX */
 +}
 +
 +void
 +Player::seek_forward ()
 +{
 +      /* XXX */
 +}
 +
 +
 +void
 +Player::setup_decoders ()
 +{
 +      _video_decoders.clear ();
 +      _video_decoder = 0;
 +      _audio_decoders.clear ();
 +      _sequential_audio_decoder = 0;
 +
 +      _video_start.clear();
 +      _audio_start.clear();
 +
 +      double video_so_far = 0;
 +      double audio_so_far = 0;
 +      
 +      list<shared_ptr<const VideoContent> > vc = _playlist->video ();
 +      for (list<shared_ptr<const VideoContent> >::iterator i = vc.begin(); i != vc.end(); ++i) {
 +              
 +              shared_ptr<const VideoContent> video_content;
 +              shared_ptr<const AudioContent> audio_content;
 +              shared_ptr<VideoDecoder> video_decoder;
 +              shared_ptr<AudioDecoder> audio_decoder;
 +              
 +              /* XXX: into content? */
 +              
 +              shared_ptr<const FFmpegContent> fc = dynamic_pointer_cast<const FFmpegContent> (*i);
 +              if (fc) {
 +                      shared_ptr<FFmpegDecoder> fd (
 +                              new FFmpegDecoder (
 +                                      _film, fc, _video,
 +                                      _audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG,
 +                                      _subtitles
 +                                      )
 +                              );
 +                      
 +                      video_content = fc;
 +                      audio_content = fc;
 +                      video_decoder = fd;
 +                      audio_decoder = fd;
 +              }
 +              
 +              shared_ptr<const ImageMagickContent> ic = dynamic_pointer_cast<const ImageMagickContent> (*i);
 +              if (ic) {
 +                      video_content = ic;
 +                      video_decoder.reset (new ImageMagickDecoder (_film, ic));
 +              }
 +              
 +              video_decoder->connect_video (shared_from_this ());
 +              _video_decoders.push_back (video_decoder);
 +              _video_start.push_back (video_so_far);
 +              video_so_far += video_content->video_length() / video_content->video_frame_rate();
 +
 +              if (audio_decoder && _playlist->audio_from() == Playlist::AUDIO_FFMPEG) {
 +                      audio_decoder->Audio.connect (bind (&Player::process_audio, this, audio_content, _1, _2));
 +                      _audio_decoders.push_back (audio_decoder);
 +                      _audio_start.push_back (audio_so_far);
 +                      audio_so_far += double(audio_content->audio_length()) / audio_content->audio_frame_rate();
 +              }
 +      }
 +      
 +      _video_decoder = 0;
 +      _sequential_audio_decoder = 0;
 +
 +      if (_playlist->audio_from() == Playlist::AUDIO_SNDFILE) {
 +              
 +              list<shared_ptr<const AudioContent> > ac = _playlist->audio ();
 +              for (list<shared_ptr<const AudioContent> >::iterator i = ac.begin(); i != ac.end(); ++i) {
 +                      
 +                      shared_ptr<const SndfileContent> sc = dynamic_pointer_cast<const SndfileContent> (*i);
 +                      assert (sc);
 +                      
 +                      shared_ptr<AudioDecoder> d (new SndfileDecoder (_film, sc));
 +                      d->Audio.connect (bind (&Player::process_audio, this, sc, _1, _2));
 +                      _audio_decoders.push_back (d);
 +                      _audio_start.push_back (audio_so_far);
 +              }
 +      }
 +}
 +
 +double
 +Player::last_video_time () const
 +{
 +      return _video_start[_video_decoder] + _video_decoders[_video_decoder]->last_content_time ();
 +}
 +
 +void
 +Player::content_changed (weak_ptr<Content> w, int p)
 +{
 +      shared_ptr<Content> c = w.lock ();
 +      if (!c) {
 +              return;
 +      }
 +
 +      if (p == VideoContentProperty::VIDEO_LENGTH) {
 +              if (dynamic_pointer_cast<FFmpegContent> (c)) {
 +                      /* FFmpeg content length changes are serious; we need new decoders */
 +                      _have_valid_decoders = false;
 +              }
 +      }
 +}
 +
 +void
 +Player::playlist_changed ()
 +{
 +      _have_valid_decoders = false;
 +}
diff --combined src/lib/player.h
index 2069064d797d295c1a8dbaae09d2ae6061bbec5e,0000000000000000000000000000000000000000..20b83bfdb7c2468e702409fbc500286937553ec5
mode 100644,000000..100644
--- /dev/null
@@@ -1,92 -1,0 +1,92 @@@
-       void process_video (boost::shared_ptr<Image> i, bool same, boost::shared_ptr<Subtitle> s, double);
-       void process_audio (boost::weak_ptr<const AudioContent>, boost::shared_ptr<AudioBuffers>, double);
 +/*
 +    Copyright (C) 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.
 +
 +*/
 +
 +#ifndef DCPOMATIC_PLAYER_H
 +#define DCPOMATIC_PLAYER_H
 +
 +#include <list>
 +#include <boost/shared_ptr.hpp>
 +#include <boost/enable_shared_from_this.hpp>
 +#include "video_source.h"
 +#include "audio_source.h"
 +#include "video_sink.h"
 +#include "audio_sink.h"
 +
 +class VideoDecoder;
 +class AudioDecoder;
 +class Job;
 +class Film;
 +class Playlist;
 +class AudioContent;
 +
 +/** @class Player
 + *  @brief A class which can `play' a Playlist; emitting its audio and video.
 + */
 + 
 +class Player : public TimedVideoSource, public TimedAudioSource, public TimedVideoSink, public boost::enable_shared_from_this<Player>
 +{
 +public:
 +      Player (boost::shared_ptr<const Film>, boost::shared_ptr<const Playlist>);
 +
 +      void disable_video ();
 +      void disable_audio ();
 +      void disable_subtitles ();
 +
 +      bool pass ();
 +      void set_progress (boost::shared_ptr<Job>);
 +      bool seek (double);
 +      void seek_back ();
 +      void seek_forward ();
 +
 +      double last_video_time () const;
 +
 +private:
++      void process_video (boost::shared_ptr<const Image> i, bool same, boost::shared_ptr<Subtitle> s, double);
++      void process_audio (boost::weak_ptr<const AudioContent>, boost::shared_ptr<const AudioBuffers>, double);
 +      void setup_decoders ();
 +      void playlist_changed ();
 +      void content_changed (boost::weak_ptr<Content>, int);
 +
 +      boost::shared_ptr<const Film> _film;
 +      boost::shared_ptr<const Playlist> _playlist;
 +      
 +      bool _video;
 +      bool _audio;
 +      bool _subtitles;
 +
 +      /** Our decoders are ready to go; if this is false the decoders must be (re-)created before they are used */
 +      bool _have_valid_decoders;
 +      /** Video decoders in order of presentation */
 +      std::vector<boost::shared_ptr<VideoDecoder> > _video_decoders;
 +      /** Start positions of each video decoder in seconds*/
 +      std::vector<double> _video_start;
 +        /** Index of current video decoder */
 +      size_t _video_decoder;
 +        /** Audio decoders in order of presentation (if they are from FFmpeg) */
 +      std::vector<boost::shared_ptr<AudioDecoder> > _audio_decoders;
 +      /** Start positions of each audio decoder (if they are from FFmpeg) in seconds */
 +      std::vector<double> _audio_start;
 +      /** Current audio decoder index if we are running them sequentially; otherwise undefined */
 +      size_t _sequential_audio_decoder;
 +
 +      boost::shared_ptr<AudioBuffers> _audio_buffers;
 +      boost::optional<double> _audio_time;
 +};
 +
 +#endif
diff --combined src/lib/po/es_ES.po
index 5c8d642e3365cc5908971181a6b72b98831e2ad0,1608f3b0c8bc0efb661c6ce5aa459a5211a31f55..7d2f8511e002314ab866778bcdcd18ccffd2b1a9
@@@ -5,9 -5,9 +5,9 @@@
  #
  msgid ""
  msgstr ""
 -"Project-Id-Version: LIBDVDOMATIC\n"
 +"Project-Id-Version: LIBDCPOMATIC\n"
  "Report-Msgid-Bugs-To: \n"
- "POT-Creation-Date: 2013-04-09 11:14+0100\n"
+ "POT-Creation-Date: 2013-04-22 15:06+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"
@@@ -25,10 -25,6 +25,6 @@@ msgstr "0%
  msgid "1.19"
  msgstr "1.19"
  
- #: src/lib/format.cc:79
- msgid "1.33"
- msgstr "1.33"
  #: src/lib/format.cc:83
  msgid "1.375"
  msgstr "1.375"
@@@ -58,6 -54,10 +54,10 @@@ msgstr "16:9 en Flat
  msgid "3D denoiser"
  msgstr "reducción de ruido 3D"
  
+ #: src/lib/format.cc:79
+ msgid "4:3"
+ msgstr ""
  #: src/lib/format.cc:87
  msgid "4:3 within Flat"
  msgstr "4:3 en Flat"
@@@ -94,7 -94,7 +94,7 @@@ msgstr "Bicúbico
  msgid "Bilinear"
  msgstr "Bilineal"
  
- #: src/lib/job.cc:302
+ #: src/lib/job.cc:306
  msgid "Cancelled"
  msgstr ""
  
@@@ -175,7 -175,7 +175,7 @@@ msgstr "Dolby CP750
  msgid "Each source frame will be doubled in the DCP.\n"
  msgstr "Se doblará cada fotograma de la fuente en el DCP.\n"
  
- #: src/lib/job.cc:300
+ #: src/lib/job.cc:304
  msgid "Error (%1)"
  msgstr "Error (%1)"
  
@@@ -247,13 -247,13 +247,13 @@@ msgstr "Horizontal deblocking filter
  msgid "Horizontal deblocking filter A"
  msgstr "Horizontal deblocking filter A"
  
- #: src/lib/job.cc:92 src/lib/job.cc:101
+ #: src/lib/job.cc:96 src/lib/job.cc:105
  msgid ""
  "It is not known what caused this error.  The best idea is to report the "
 -"problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)"
 +"problem to the DCP-o-matic mailing list (dcpomatic@carlh.net)"
  msgstr ""
  "Error desconocido. La mejor idea es informar del problema a la lista de "
 -"correo de DVD-O-matic (dvdomatic@carlh.net)"
 +"correo de DCP-o-matic (dcpomatic@carlh.net)"
  
  #: src/lib/filter.cc:82
  msgid "Kernel deinterlacer"
@@@ -301,7 -301,7 +301,7 @@@ msgstr "Motion compensating deinterlace
  msgid "Noise reduction"
  msgstr "Reducción de ruido"
  
- #: src/lib/job.cc:298
+ #: src/lib/job.cc:302
  msgid "OK (ran for %1)"
  msgstr "OK (ejecución %1)"
  
@@@ -373,7 -373,7 +373,7 @@@ msgstr "Temporal noise reducer
  msgid "Test"
  msgstr "Test"
  
- #: src/lib/job.cc:77
+ #: src/lib/job.cc:78
  msgid ""
  "The drive that the film is stored on is low in disc space.  Free some more "
  "space and try again."
@@@ -393,11 -393,11 +393,11 @@@ msgstr "Codificar %1
  msgid "Transitional"
  msgstr "Transitional"
  
- #: src/lib/job.cc:100
+ #: src/lib/job.cc:104
  msgid "Unknown error"
  msgstr "Error desconocido"
  
- #: src/lib/ffmpeg_decoder.cc:396
+ #: src/lib/ffmpeg_decoder.cc:388
  msgid "Unrecognised audio sample format (%1)"
  msgstr "Formato de audio desconocido (%1)"
  
@@@ -425,7 -425,7 +425,7 @@@ msgstr "X
  msgid "Yet Another Deinterlacing Filter"
  msgstr "Yet Another Deinterlacing Filter"
  
- #: src/lib/film.cc:263
+ #: src/lib/film.cc:296
  msgid "cannot contain slashes"
  msgstr "no puede contener barras"
  
@@@ -437,11 -437,11 +437,11 @@@ msgstr "tiempo de conexión agotado
  msgid "connecting"
  msgstr "conectando"
  
- #: src/lib/film.cc:300
+ #: src/lib/film.cc:333
  msgid "content"
  msgstr "contenido"
  
- #: src/lib/film.cc:304
+ #: src/lib/film.cc:337
  msgid "content type"
  msgstr "tipo de contenido"
  
@@@ -454,19 -454,19 +454,19 @@@ msgstr "copiando %1
  msgid "could not create file %1"
  msgstr "No se pudo escribir el fichero remoto (%1)"
  
- #: src/lib/ffmpeg_decoder.cc:191
+ #: src/lib/ffmpeg_decoder.cc:187
  msgid "could not find audio decoder"
  msgstr "no se encontró el decodificador de audio"
  
- #: src/lib/ffmpeg_decoder.cc:118
+ #: src/lib/ffmpeg_decoder.cc:114
  msgid "could not find stream information"
  msgstr "no se pudo encontrar información del flujo"
  
- #: src/lib/ffmpeg_decoder.cc:210
+ #: src/lib/ffmpeg_decoder.cc:206
  msgid "could not find subtitle decoder"
  msgstr "no se pudo encontrar decodificador de subtítutlos"
  
- #: src/lib/ffmpeg_decoder.cc:169
+ #: src/lib/ffmpeg_decoder.cc:165
  msgid "could not find video decoder"
  msgstr "no se pudo encontrar decodificador de vídeo"
  
@@@ -513,7 -513,7 +513,7 @@@ msgstr "los ficheros externos de sonid
  msgid "external audio files must be mono"
  msgstr "los ficheros externos de sonido deben ser mono"
  
- #: src/lib/film.cc:296
+ #: src/lib/film.cc:329
  msgid "format"
  msgstr "formato"
  
@@@ -549,7 -549,7 +549,7 @@@ msgstr "
  msgid "multi-part subtitles not yet supported"
  msgstr "todavía no se soportan subtítulos en múltiples partes"
  
- #: src/lib/film.cc:263 src/lib/film.cc:308
+ #: src/lib/film.cc:296 src/lib/film.cc:341
  msgid "name"
  msgstr "nombre"
  
@@@ -563,7 -563,7 +563,7 @@@ msgstr "todavía no se soportan subtít
  
  #. / TRANSLATORS: remaining here follows an amount of time that is remaining
  #. / on an operation.
- #: src/lib/job.cc:295
+ #: src/lib/job.cc:299
  msgid "remaining"
  msgstr "pendiente"
  
@@@ -575,14 -575,17 +575,17 @@@ msgstr "sRGB
  msgid "seconds"
  msgstr "segundos"
  
- #: src/lib/film.cc:274
+ #: src/lib/film.cc:307
  msgid "still"
  msgstr "imagen fija"
  
- #: src/lib/film.cc:274
+ #: src/lib/film.cc:307
  msgid "video"
  msgstr "vídeo"
  
+ #~ msgid "1.33"
+ #~ msgstr "1.33"
  #~ msgid "Source scaled to 1.19:1"
  #~ msgstr "Fuente escalada a 1.19:1"
  
diff --combined src/lib/po/fr_FR.po
index af6890d97b1caab90ebd7245940620b35a31046d,d1123d84b755f08b7ef7b67f51b5faa4143ac0ab..7f3da788b2fc99389540b90b14fe107a380ba08f
@@@ -5,9 -5,9 +5,9 @@@
  #
  msgid ""
  msgstr ""
 -"Project-Id-Version: DVD-o-matic FRENCH\n"
 +"Project-Id-Version: DCP-o-matic FRENCH\n"
  "Report-Msgid-Bugs-To: \n"
- "POT-Creation-Date: 2013-04-09 11:14+0100\n"
+ "POT-Creation-Date: 2013-04-22 15:06+0100\n"
  "PO-Revision-Date: 2013-03-20 00:39+0100\n"
  "Last-Translator: FreeDCP.net <freedcp.net@gmail.com>\n"
  "Language-Team: \n"
@@@ -24,10 -24,6 +24,6 @@@ msgstr "0%
  msgid "1.19"
  msgstr "1.19"
  
- #: src/lib/format.cc:79
- msgid "1.33"
- msgstr "1.33"
  #: src/lib/format.cc:83
  msgid "1.375"
  msgstr "1.375"
@@@ -51,12 -47,16 +47,16 @@@ msgstr "16:9 dans Flat
  #: src/lib/format.cc:115
  #, fuzzy
  msgid "16:9 within Scope"
- msgstr "16:9 dans Flat"
+ msgstr "16:9 dans Scope"
  
  #: src/lib/filter.cc:88
  msgid "3D denoiser"
  msgstr "Débruitage 3D"
  
+ #: src/lib/format.cc:79
+ msgid "4:3"
+ msgstr ""
  #: src/lib/format.cc:87
  msgid "4:3 within Flat"
  msgstr "4:3 dans Flat"
@@@ -93,7 -93,7 +93,7 @@@ msgstr "Bicubique
  msgid "Bilinear"
  msgstr "Bilinéaire"
  
- #: src/lib/job.cc:302
+ #: src/lib/job.cc:306
  msgid "Cancelled"
  msgstr ""
  
@@@ -173,7 -173,7 +173,7 @@@ msgstr "Dolby CP750
  msgid "Each source frame will be doubled in the DCP.\n"
  msgstr "Chaque image source sera dupliquée dans le DCP.\n"
  
- #: src/lib/job.cc:300
+ #: src/lib/job.cc:304
  msgid "Error (%1)"
  msgstr "Erreur (%1)"
  
@@@ -245,13 -245,13 +245,13 @@@ msgstr "Filtre dé-bloc horizontal
  msgid "Horizontal deblocking filter A"
  msgstr "Filtre dé-bloc horizontal"
  
- #: src/lib/job.cc:92 src/lib/job.cc:101
+ #: src/lib/job.cc:96 src/lib/job.cc:105
  msgid ""
  "It is not known what caused this error.  The best idea is to report the "
 -"problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)"
 +"problem to the DCP-o-matic mailing list (dcpomatic@carlh.net)"
  msgstr ""
 -"Erreur indéterminée. Merci de rapporter le problème à la liste DVD-o-matic "
 -"(dvdomatic@carlh.net)"
 +"Erreur indéterminée. Merci de rapporter le problème à la liste DCP-o-matic "
 +"(dcpomatic@carlh.net)"
  
  #: src/lib/filter.cc:82
  msgid "Kernel deinterlacer"
@@@ -299,7 -299,7 +299,7 @@@ msgstr "Désentrelaceur par compensatio
  msgid "Noise reduction"
  msgstr "Réduction de bruit"
  
- #: src/lib/job.cc:298
+ #: src/lib/job.cc:302
  msgid "OK (ran for %1)"
  msgstr "OK (processus %1)"
  
@@@ -371,7 -371,7 +371,7 @@@ msgstr "Réduction de bruit temporel
  msgid "Test"
  msgstr "Test"
  
- #: src/lib/job.cc:77
+ #: src/lib/job.cc:78
  msgid ""
  "The drive that the film is stored on is low in disc space.  Free some more "
  "space and try again."
@@@ -391,11 -391,11 +391,11 @@@ msgstr "Transcodage %1
  msgid "Transitional"
  msgstr "Transitional"
  
- #: src/lib/job.cc:100
+ #: src/lib/job.cc:104
  msgid "Unknown error"
  msgstr "Erreur inconnue"
  
- #: src/lib/ffmpeg_decoder.cc:396
+ #: src/lib/ffmpeg_decoder.cc:388
  msgid "Unrecognised audio sample format (%1)"
  msgstr "Échantillonnage audio (%1) inconnu"
  
@@@ -423,7 -423,7 +423,7 @@@ msgstr "X
  msgid "Yet Another Deinterlacing Filter"
  msgstr "Un autre filtre de désentrelacement"
  
- #: src/lib/film.cc:263
+ #: src/lib/film.cc:296
  msgid "cannot contain slashes"
  msgstr "slash interdit"
  
@@@ -435,11 -435,11 +435,11 @@@ msgstr "temps de connexion expiré
  msgid "connecting"
  msgstr "connexion"
  
- #: src/lib/film.cc:300
+ #: src/lib/film.cc:333
  msgid "content"
  msgstr "contenu"
  
- #: src/lib/film.cc:304
+ #: src/lib/film.cc:337
  msgid "content type"
  msgstr "type de contenu"
  
@@@ -451,19 -451,19 +451,19 @@@ msgstr "copie de %1
  msgid "could not create file %1"
  msgstr "Écriture vers fichier distant (%1) impossible"
  
- #: src/lib/ffmpeg_decoder.cc:191
+ #: src/lib/ffmpeg_decoder.cc:187
  msgid "could not find audio decoder"
  msgstr "décodeur audio introuvable"
  
- #: src/lib/ffmpeg_decoder.cc:118
+ #: src/lib/ffmpeg_decoder.cc:114
  msgid "could not find stream information"
  msgstr "information du flux introuvable"
  
- #: src/lib/ffmpeg_decoder.cc:210
+ #: src/lib/ffmpeg_decoder.cc:206
  msgid "could not find subtitle decoder"
  msgstr "décodeur de sous-titre introuvable"
  
- #: src/lib/ffmpeg_decoder.cc:169
+ #: src/lib/ffmpeg_decoder.cc:165
  msgid "could not find video decoder"
  msgstr "décodeur vidéo introuvable"
  
@@@ -507,7 -507,7 +507,7 @@@ msgstr "Les fichiers audio externes on
  msgid "external audio files must be mono"
  msgstr "les fichiers audio externes doivent être en mono"
  
- #: src/lib/film.cc:296
+ #: src/lib/film.cc:329
  msgid "format"
  msgstr "format"
  
@@@ -543,7 -543,7 +543,7 @@@ msgstr "
  msgid "multi-part subtitles not yet supported"
  msgstr "sous-titres en plusieurs parties non supportés"
  
- #: src/lib/film.cc:263 src/lib/film.cc:308
+ #: src/lib/film.cc:296 src/lib/film.cc:341
  msgid "name"
  msgstr "nom"
  
@@@ -557,7 -557,7 +557,7 @@@ msgstr "sous-titres non-bitmap non supp
  
  #. / TRANSLATORS: remaining here follows an amount of time that is remaining
  #. / on an operation.
- #: src/lib/job.cc:295
+ #: src/lib/job.cc:299
  msgid "remaining"
  msgstr "restant"
  
@@@ -569,14 -569,17 +569,17 @@@ msgstr "sRGB
  msgid "seconds"
  msgstr "secondes"
  
- #: src/lib/film.cc:274
+ #: src/lib/film.cc:307
  msgid "still"
  msgstr "fixe"
  
- #: src/lib/film.cc:274
+ #: src/lib/film.cc:307
  msgid "video"
  msgstr "vidéo"
  
+ #~ msgid "1.33"
+ #~ msgstr "1.33"
  #~ msgid "Source scaled to 1.19:1"
  #~ msgstr "Source mise à l'échelle en 1.19:1"
  
diff --combined src/lib/po/it_IT.po
index c1ca26ea3b06db351940152d7e145e1bf8ad1db1,5f9e9e8627f0bd63f9d97539d97bc92a08254881..1d7f57536f1a8143de1555a6a9b6763d7fd59ad7
@@@ -7,7 -7,7 +7,7 @@@ msgid "
  msgstr ""
  "Project-Id-Version: IT VERSION\n"
  "Report-Msgid-Bugs-To: \n"
- "POT-Creation-Date: 2013-04-09 11:14+0100\n"
+ "POT-Creation-Date: 2013-04-22 15:06+0100\n"
  "PO-Revision-Date: 2013-04-03 15:04+0100\n"
  "Last-Translator: Maci <macibro@gmail.com>\n"
  "Language-Team: \n"
@@@ -25,10 -25,6 +25,6 @@@ msgstr "0%
  msgid "1.19"
  msgstr "1.19"
  
- #: src/lib/format.cc:79
- msgid "1.33"
- msgstr "1.33"
  #: src/lib/format.cc:83
  msgid "1.375"
  msgstr "1.375"
@@@ -58,6 -54,10 +54,10 @@@ msgstr "16:9 all'interno di Flat
  msgid "3D denoiser"
  msgstr "Riduttore di rumore 3D"
  
+ #: src/lib/format.cc:79
+ msgid "4:3"
+ msgstr ""
  #: src/lib/format.cc:87
  msgid "4:3 within Flat"
  msgstr "4:3 all'interno di  Flat"
@@@ -94,7 -94,7 +94,7 @@@ msgstr "Bicubica
  msgid "Bilinear"
  msgstr "Bilineare"
  
- #: src/lib/job.cc:302
+ #: src/lib/job.cc:306
  msgid "Cancelled"
  msgstr "Cancellato"
  
@@@ -173,7 -173,7 +173,7 @@@ msgstr "Dolby CP750
  msgid "Each source frame will be doubled in the DCP.\n"
  msgstr "Ogni fotogramma del sorgente sarà raddoppiato nel DCP.\n"
  
- #: src/lib/job.cc:300
+ #: src/lib/job.cc:304
  msgid "Error (%1)"
  msgstr "Errore (%1)"
  
@@@ -245,13 -245,13 +245,13 @@@ msgstr "Filtro sblocco orizzontale
  msgid "Horizontal deblocking filter A"
  msgstr "Filtro A sblocco orizzontale"
  
- #: src/lib/job.cc:92 src/lib/job.cc:101
+ #: src/lib/job.cc:96 src/lib/job.cc:105
  msgid ""
  "It is not known what caused this error.  The best idea is to report the "
 -"problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)"
 +"problem to the DCP-o-matic mailing list (dcpomatic@carlh.net)"
  msgstr ""
  "Non sappiamo cosa ha causato questo errore. La cosa migliore è inviare un "
 -"report del problema alla mailing list di DVD-o-matic (dvdomatic@carlh.net)"
 +"report del problema alla mailing list di DCP-o-matic (dcpomatic@carlh.net)"
  
  #: src/lib/filter.cc:82
  msgid "Kernel deinterlacer"
@@@ -299,7 -299,7 +299,7 @@@ msgstr "Dinterlacciatore compensativo d
  msgid "Noise reduction"
  msgstr "Riduzione del rumore"
  
- #: src/lib/job.cc:298
+ #: src/lib/job.cc:302
  msgid "OK (ran for %1)"
  msgstr "OK (procede al %1)"
  
@@@ -371,7 -371,7 +371,7 @@@ msgstr "Riduttore temporale di rumore
  msgid "Test"
  msgstr "Prova"
  
- #: src/lib/job.cc:77
+ #: src/lib/job.cc:78
  msgid ""
  "The drive that the film is stored on is low in disc space.  Free some more "
  "space and try again."
@@@ -391,11 -391,11 +391,11 @@@ msgstr "Transcodifica %1
  msgid "Transitional"
  msgstr "Di transizione"
  
- #: src/lib/job.cc:100
+ #: src/lib/job.cc:104
  msgid "Unknown error"
  msgstr "Errore sconosciuto"
  
- #: src/lib/ffmpeg_decoder.cc:396
+ #: src/lib/ffmpeg_decoder.cc:388
  msgid "Unrecognised audio sample format (%1)"
  msgstr "Formato di campionamento audio non riconosciuto (%1)"
  
@@@ -423,7 -423,7 +423,7 @@@ msgstr "X
  msgid "Yet Another Deinterlacing Filter"
  msgstr "Altro filtro di deinterlacciamento"
  
- #: src/lib/film.cc:263
+ #: src/lib/film.cc:296
  msgid "cannot contain slashes"
  msgstr "non può contenere barre"
  
@@@ -435,11 -435,11 +435,11 @@@ msgstr "connessione scaduta
  msgid "connecting"
  msgstr "mi sto connettendo"
  
- #: src/lib/film.cc:300
+ #: src/lib/film.cc:333
  msgid "content"
  msgstr "contenuto"
  
- #: src/lib/film.cc:304
+ #: src/lib/film.cc:337
  msgid "content type"
  msgstr "tipo di contenuto"
  
@@@ -451,19 -451,19 +451,19 @@@ msgstr "copia %1
  msgid "could not create file %1"
  msgstr "Non posso scrivere il file remoto (%1)"
  
- #: src/lib/ffmpeg_decoder.cc:191
+ #: src/lib/ffmpeg_decoder.cc:187
  msgid "could not find audio decoder"
  msgstr "non riesco a trovare il decoder audio"
  
- #: src/lib/ffmpeg_decoder.cc:118
+ #: src/lib/ffmpeg_decoder.cc:114
  msgid "could not find stream information"
  msgstr "non riesco a trovare informazioni sullo streaming"
  
- #: src/lib/ffmpeg_decoder.cc:210
+ #: src/lib/ffmpeg_decoder.cc:206
  msgid "could not find subtitle decoder"
  msgstr "non riesco a trovare il decoder dei sottotitoli"
  
- #: src/lib/ffmpeg_decoder.cc:169
+ #: src/lib/ffmpeg_decoder.cc:165
  msgid "could not find video decoder"
  msgstr "non riesco a trovare il decoder video"
  
@@@ -507,7 -507,7 +507,7 @@@ msgstr "i files dell'audio esterno hann
  msgid "external audio files must be mono"
  msgstr "i files dell'audio esterno devono essere mono"
  
- #: src/lib/film.cc:296
+ #: src/lib/film.cc:329
  msgid "format"
  msgstr "formato"
  
@@@ -543,7 -543,7 +543,7 @@@ msgstr "persa la regolazione richiesta 
  msgid "multi-part subtitles not yet supported"
  msgstr "sottotitoli multi-part non ancora supportati"
  
- #: src/lib/film.cc:263 src/lib/film.cc:308
+ #: src/lib/film.cc:296 src/lib/film.cc:341
  msgid "name"
  msgstr "nome"
  
@@@ -557,7 -557,7 +557,7 @@@ msgstr "sottotitoli non-bitmap non anco
  
  #. / TRANSLATORS: remaining here follows an amount of time that is remaining
  #. / on an operation.
- #: src/lib/job.cc:295
+ #: src/lib/job.cc:299
  msgid "remaining"
  msgstr "restano"
  
@@@ -569,14 -569,17 +569,17 @@@ msgstr "sRGB
  msgid "seconds"
  msgstr "secondi"
  
- #: src/lib/film.cc:274
+ #: src/lib/film.cc:307
  msgid "still"
  msgstr "ancora"
  
- #: src/lib/film.cc:274
+ #: src/lib/film.cc:307
  msgid "video"
  msgstr "video"
  
+ #~ msgid "1.33"
+ #~ msgstr "1.33"
  #~ msgid "Source scaled to 1.19:1"
  #~ msgstr "Sorgente scalato a 1.19:1"
  
diff --combined src/lib/po/sv_SE.po
index f89874e35e9b952399a227c4f8999a2bbec2d025,11aeff9871e61c744ea72aef84536c58fc0c0e59..ff86e23af926d175446fbe5258a912ddbaf6cbfd
@@@ -5,12 -5,13 +5,13 @@@
  #
  msgid ""
  msgstr ""
 -"Project-Id-Version: DVD-o-matic\n"
 +"Project-Id-Version: DCP-o-matic\n"
  "Report-Msgid-Bugs-To: \n"
- "POT-Creation-Date: 2013-04-09 11:14+0100\n"
+ "POT-Creation-Date: 2013-04-22 15:06+0100\n"
  "PO-Revision-Date: 2013-04-10 15:35+0100\n"
  "Last-Translator: Adam Klotblixt <adam.klotblixt@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"
@@@ -24,10 -25,6 +25,6 @@@ msgstr "0%
  msgid "1.19"
  msgstr "1,19"
  
- #: src/lib/format.cc:79
- msgid "1.33"
- msgstr "1,33"
  #: src/lib/format.cc:83
  msgid "1.375"
  msgstr "1,375"
@@@ -56,6 -53,10 +53,10 @@@ msgstr "16:9 innanför Scope
  msgid "3D denoiser"
  msgstr "3D brusreducering"
  
+ #: src/lib/format.cc:79
+ msgid "4:3"
+ msgstr ""
  #: src/lib/format.cc:87
  msgid "4:3 within Flat"
  msgstr "4:3 innanför Flat"
@@@ -92,7 -93,7 +93,7 @@@ msgstr "Bikubisk
  msgid "Bilinear"
  msgstr "Bilinjär"
  
- #: src/lib/job.cc:302
+ #: src/lib/job.cc:306
  msgid "Cancelled"
  msgstr "Avbruten"
  
@@@ -172,7 -173,7 +173,7 @@@ msgstr "Dolby CP750
  msgid "Each source frame will be doubled in the DCP.\n"
  msgstr "Varje bild från källan kommer att användas två gånger i DCPn.\n"
  
- #: src/lib/job.cc:300
+ #: src/lib/job.cc:304
  msgid "Error (%1)"
  msgstr "Fel (%1)"
  
@@@ -244,13 -245,13 +245,13 @@@ msgstr "Filter för horisontal kantighe
  msgid "Horizontal deblocking filter A"
  msgstr "Filter för horisontal kantighetsutjämning A"
  
- #: src/lib/job.cc:92 src/lib/job.cc:101
+ #: src/lib/job.cc:96 src/lib/job.cc:105
  msgid ""
  "It is not known what caused this error.  The best idea is to report the "
 -"problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)"
 +"problem to the DCP-o-matic mailing list (dcpomatic@carlh.net)"
  msgstr ""
  "Det är inte känt vad som orsakade detta fel. Bästa sättet att rapportera "
 -"problemet är till DVD-o-matics mejl-lista (dvdomatic@carlh.net)"
 +"problemet är till DCP-o-matics mejl-lista (dcpomatic@carlh.net)"
  
  #: src/lib/filter.cc:82
  msgid "Kernel deinterlacer"
@@@ -298,7 -299,7 +299,7 @@@ msgstr "Rörelsekompenserande avflätar
  msgid "Noise reduction"
  msgstr "Brusreducering"
  
- #: src/lib/job.cc:298
+ #: src/lib/job.cc:302
  msgid "OK (ran for %1)"
  msgstr "OK (kördes %1)"
  
@@@ -370,7 -371,7 +371,7 @@@ msgstr "Temporal brusreducering
  msgid "Test"
  msgstr "Test"
  
- #: src/lib/job.cc:77
+ #: src/lib/job.cc:78
  msgid ""
  "The drive that the film is stored on is low in disc space.  Free some more "
  "space and try again."
@@@ -390,12 -391,12 +391,12 @@@ msgstr "Konvertera %1
  msgid "Transitional"
  msgstr "Övergångsklipp"
  
- #: src/lib/job.cc:100
+ #: src/lib/job.cc:104
  msgid "Unknown error"
  msgstr "Okänt fel"
  
  # Svengelska
- #: src/lib/ffmpeg_decoder.cc:396
+ #: src/lib/ffmpeg_decoder.cc:388
  #, fuzzy
  msgid "Unrecognised audio sample format (%1)"
  msgstr "Okänt audio-sampelformat (%1)"
@@@ -425,7 -426,7 +426,7 @@@ msgstr "X
  msgid "Yet Another Deinterlacing Filter"
  msgstr "Yet Another Deinterlacing Filter"
  
- #: src/lib/film.cc:263
+ #: src/lib/film.cc:296
  msgid "cannot contain slashes"
  msgstr "får inte innehålla snedstreck"
  
@@@ -439,11 -440,11 +440,11 @@@ msgstr "uppkopplingen tajmade ur
  msgid "connecting"
  msgstr "kopplar upp"
  
- #: src/lib/film.cc:300
+ #: src/lib/film.cc:333
  msgid "content"
  msgstr "innehåll"
  
- #: src/lib/film.cc:304
+ #: src/lib/film.cc:337
  msgid "content type"
  msgstr "innehållstyp"
  
@@@ -455,19 -456,19 +456,19 @@@ msgstr "kopierar %1
  msgid "could not create file %1"
  msgstr "kunde inte skapa fil %1"
  
- #: src/lib/ffmpeg_decoder.cc:191
+ #: src/lib/ffmpeg_decoder.cc:187
  msgid "could not find audio decoder"
  msgstr "kunde inte hitta audio-avkodare"
  
- #: src/lib/ffmpeg_decoder.cc:118
+ #: src/lib/ffmpeg_decoder.cc:114
  msgid "could not find stream information"
  msgstr "kunde inte hitta information om strömmen"
  
- #: src/lib/ffmpeg_decoder.cc:210
+ #: src/lib/ffmpeg_decoder.cc:206
  msgid "could not find subtitle decoder"
  msgstr "kunde inte hitta undertext-avkodare"
  
- #: src/lib/ffmpeg_decoder.cc:169
+ #: src/lib/ffmpeg_decoder.cc:165
  msgid "could not find video decoder"
  msgstr "kunde inte hitta video-avkodare"
  
@@@ -511,7 -512,7 +512,7 @@@ msgstr "externa audio-filer har olika l
  msgid "external audio files must be mono"
  msgstr "externa audio-filer måste vara mono"
  
- #: src/lib/film.cc:296
+ #: src/lib/film.cc:329
  msgid "format"
  msgstr "format"
  
@@@ -547,7 -548,7 +548,7 @@@ msgstr "saknad nödvändig inställnin
  msgid "multi-part subtitles not yet supported"
  msgstr "undertexter i flera delar stöds inte ännu"
  
- #: src/lib/film.cc:263 src/lib/film.cc:308
+ #: src/lib/film.cc:296 src/lib/film.cc:341
  msgid "name"
  msgstr "namn"
  
@@@ -561,7 -562,7 +562,7 @@@ msgstr "icke-rastergrafiska undertexte
  
  #. / TRANSLATORS: remaining here follows an amount of time that is remaining
  #. / on an operation.
- #: src/lib/job.cc:295
+ #: src/lib/job.cc:299
  msgid "remaining"
  msgstr "återstående tid"
  
@@@ -573,14 -574,17 +574,17 @@@ msgstr "sRGB
  msgid "seconds"
  msgstr "sekunder"
  
- #: src/lib/film.cc:274
+ #: src/lib/film.cc:307
  msgid "still"
  msgstr "stillbild"
  
- #: src/lib/film.cc:274
+ #: src/lib/film.cc:307
  msgid "video"
  msgstr "video"
  
+ #~ msgid "1.33"
+ #~ msgstr "1,33"
  #~ msgid "Source scaled to 1.19:1"
  #~ msgstr "Källan skalad till 1,19:1"
  
diff --combined src/lib/transcoder.cc
index ea3f27ad8f94f10175e1b6e81237b5e1d6059c12,faafcaf8b593821fd6b5600f82f48b758192eeba..2e33931bd50872cc5edbb16c274af19e336a5bb1
  #include <boost/signals2.hpp>
  #include "transcoder.h"
  #include "encoder.h"
 -#include "decoder_factory.h"
  #include "film.h"
  #include "matcher.h"
  #include "delay_line.h"
 -#include "options.h"
  #include "gain.h"
  #include "video_decoder.h"
  #include "audio_decoder.h"
 +#include "player.h"
+ #include "trimmer.h"
  
  using std::string;
  using boost::shared_ptr;
@@@ -42,57 -44,91 +43,68 @@@ using boost::dynamic_pointer_cast
  
  /** Construct a transcoder using a Decoder that we create and a supplied Encoder.
   *  @param f Film that we are transcoding.
 - *  @param o Decode options.
   *  @param j Job that we are running under, or 0.
   *  @param e Encoder to use.
   */
 -Transcoder::Transcoder (shared_ptr<Film> f, DecodeOptions o, Job* j, shared_ptr<Encoder> e)
 +Transcoder::Transcoder (shared_ptr<Film> f, shared_ptr<Job> j)
        : _job (j)
 -      , _encoder (e)
 -      , _decoders (decoder_factory (f, o))
 +      , _player (f->player ())
 +      , _encoder (new Encoder (f))
  {
 -      assert (_encoder);
 -
 -      shared_ptr<AudioStream> st = f->audio_stream();
 -      if (st) {
 -              _matcher.reset (new Matcher (f->log(), st->sample_rate(), f->source_frame_rate()));
 -      }
 -      _delay_line.reset (new DelayLine (f->log(), f->audio_delay() / 1000.0f));
 +      _matcher.reset (new Matcher (f->log(), f->audio_frame_rate(), f->video_frame_rate()));
 +      _delay_line.reset (new DelayLine (f->log(), f->audio_delay() * f->audio_frame_rate() / 1000));
        _gain.reset (new Gain (f->log(), f->audio_gain()));
  
 -      int const sr = st ? st->sample_rate() : 0;
+       int const trim_start = f->trim_type() == Film::ENCODE ? f->trim_start() : 0;
+       int const trim_end = f->trim_type() == Film::ENCODE ? f->trim_end() : 0;
+       _trimmer.reset (new Trimmer (
 -                              f->log(), trim_start, trim_end, f->length().get_value_or(0),
 -                              sr, f->source_frame_rate(), f->dcp_frame_rate()
++                              f->log(), trim_start, trim_end, f->content_length(),
++                              f->audio_frame_rate(), f->video_frame_rate(), f->dcp_frame_rate()
+                               ));
 -
 -      /* Set up the decoder to use the film's set streams */
 -      _decoders.video->set_subtitle_stream (f->subtitle_stream ());
 -      if (f->audio_stream ()) {
 -          _decoders.audio->set_audio_stream (f->audio_stream ());
++      
 +      if (!f->with_subtitles ()) {
 +              _player->disable_subtitles ();
        }
  
 -      _decoders.video->connect_video (_delay_line);
 -      if (_matcher) {
 -              _delay_line->connect_video (_matcher);
 -              _matcher->connect_video (_trimmer);
 -      } else {
 -              _delay_line->connect_video (_trimmer);
 -      }
 +      _player->connect_video (_delay_line);
 +      _delay_line->connect_video (_matcher);
-       _matcher->connect_video (_encoder);
++      _matcher->connect_video (_trimmer);
+       _trimmer->connect_video (_encoder);
        
 -      _decoders.audio->connect_audio (_delay_line);
 -      if (_matcher) {
 -              _delay_line->connect_audio (_matcher);
 -              _matcher->connect_audio (_gain);
 -      } else {
 -              _delay_line->connect_audio (_gain);
 -      }
 +      _player->connect_audio (_delay_line);
 +      _delay_line->connect_audio (_matcher);
 +      _matcher->connect_audio (_gain);
-       _gain->connect_audio (_encoder);
+       _gain->connect_audio (_trimmer);
+       _trimmer->connect_audio (_encoder);
  }
  
 -/** Run the decoder, passing its output to the encoder, until the decoder
 - *  has no more data to present.
 - */
  void
  Transcoder::go ()
  {
        _encoder->process_begin ();
 -
 -      bool done[2] = { false, false };
 -      
        while (1) {
 -              if (!done[0]) {
 -                      done[0] = _decoders.video->pass ();
 -                      if (_job) {
 -                              _decoders.video->set_progress (_job);
 -                      }
 -              }
 -              
 -              if (!done[1] && _decoders.audio && dynamic_pointer_cast<Decoder> (_decoders.audio) != dynamic_pointer_cast<Decoder> (_decoders.video)) {
 -                      done[1] = _decoders.audio->pass ();
 -              } else {
 -                      done[1] = true;
 -              }
 -              
 -              if (done[0] && done[1]) {
 +              if (_player->pass ()) {
                        break;
                }
 +              _player->set_progress (_job);
        }
 -      
 +
        _delay_line->process_end ();
-       _matcher->process_end ();
+       if (_matcher) {
+               _matcher->process_end ();
+       }
        _gain->process_end ();
        _encoder->process_end ();
  }
 +
 +float
 +Transcoder::current_encoding_rate () const
 +{
 +      return _encoder->current_encoding_rate ();
 +}
 +
 +int
 +Transcoder::video_frames_out () const
 +{
 +      return _encoder->video_frames_out ();
 +}
diff --combined src/lib/transcoder.h
index ecc8ebf629a2b245a4c9b0ae22862aebed3fe96b,f5b8ae6e329d3892735bf5d5a4d36f1615c44fc5..97ecaabfc2a54b9ff48ae7dd8d7640da59fd489c
  */
  
  /** @file  src/transcoder.h
 - *  @brief A class which takes a Film and some Options, then uses those to transcode the film.
   *
   *  A decoder is selected according to the content type, and the encoder can be specified
   *  as a parameter to the constructor.
   */
  
 -#include "decoder_factory.h"
 -
  class Film;
  class Job;
  class Encoder;
  class Matcher;
  class VideoFilter;
  class Gain;
 -class VideoDecoder;
 -class AudioDecoder;
  class DelayLine;
 +class Player;
+ class Trimmer;
  
  /** @class Transcoder
 - *  @brief A class which takes a Film and some Options, then uses those to transcode the film.
   *
   *  A decoder is selected according to the content type, and the encoder can be specified
   *  as a parameter to the constructor.
@@@ -42,20 -48,26 +43,21 @@@ class Transcode
  public:
        Transcoder (
                boost::shared_ptr<Film> f,
 -              DecodeOptions o,
 -              Job* j,
 -              boost::shared_ptr<Encoder> e
 +              boost::shared_ptr<Job> j
                );
  
        void go ();
  
 -      boost::shared_ptr<VideoDecoder> video_decoder () const {
 -              return _decoders.video;
 -      }
 +      float current_encoding_rate () const;
 +      int video_frames_out () const;
  
  protected:
        /** A Job that is running this Transcoder, or 0 */
 -      Job* _job;
 -      /** The encoder that we will use */
 +      boost::shared_ptr<Job> _job;
 +      boost::shared_ptr<Player> _player;
        boost::shared_ptr<Encoder> _encoder;
 -      /** The decoders that we will use */
 -      Decoders _decoders;
        boost::shared_ptr<Matcher> _matcher;
        boost::shared_ptr<DelayLine> _delay_line;
        boost::shared_ptr<Gain> _gain;
+       boost::shared_ptr<Trimmer> _trimmer;
  };
diff --combined src/lib/util.cc
index 56932720c24a1c1f777a21cd11f08641e2918368,859aa6de7ddda8efa646ee695247023d40169a7a..ec1fd47bd7f03bdca133d791b6201d824f252cab
@@@ -27,7 -27,7 +27,7 @@@
  #include <iostream>
  #include <fstream>
  #include <climits>
 -#ifdef DVDOMATIC_POSIX
 +#ifdef DCPOMATIC_POSIX
  #include <execinfo.h>
  #include <cxxabi.h>
  #endif
@@@ -63,29 -63,24 +63,30 @@@ extern "C" 
  
  #include "i18n.h"
  
 -using std::cout;
  using std::string;
  using std::stringstream;
 -using std::list;
 +using std::setfill;
  using std::ostream;
 +using std::endl;
  using std::vector;
 +using std::hex;
 +using std::setw;
  using std::ifstream;
 -using std::istream;
 +using std::ios;
  using std::min;
  using std::max;
 +using std::list;
  using std::multimap;
 +using std::istream;
 +using std::numeric_limits;
  using std::pair;
  using boost::shared_ptr;
 +using boost::thread;
  using boost::lexical_cast;
+ using boost::optional;
  using libdcp::Size;
  
- thread::id ui_thread;
boost::thread::id ui_thread;
  
  /** Convert some number of seconds to a string representation
   *  in hours, minutes and seconds.
@@@ -105,9 -100,9 +106,9 @@@ seconds_to_hms (int s
        stringstream hms;
        hms << h << N_(":");
        hms.width (2);
-       hms << setfill ('0') << m << N_(":");
+       hms << std::setfill ('0') << m << N_(":");
        hms.width (2);
-       hms << setfill ('0') << s;
+       hms << std::setfill ('0') << s;
  
        return hms.str ();
  }
@@@ -148,7 -143,7 +149,7 @@@ seconds_to_approximate_hms (int s
        return ap.str ();
  }
  
 -#ifdef DVDOMATIC_POSIX
 +#ifdef DCPOMATIC_POSIX
  /** @param l Mangled C++ identifier.
   *  @return Demangled version.
   */
@@@ -203,7 -198,7 +204,7 @@@ stacktrace (ostream& out, int levels
       
        if (strings) {
                for (i = 0; i < size && (levels == 0 || i < size_t(levels)); i++) {
-                       out << N_("  ") << demangle (strings[i]) << endl;
+                       out << N_("  ") << demangle (strings[i]) << "\n";
                }
                
                free (strings);
@@@ -247,11 -242,11 +248,11 @@@ seconds (struct timeval t
        return t.tv_sec + (double (t.tv_usec) / 1e6);
  }
  
 -/** Call the required functions to set up DVD-o-matic's static arrays, etc.
 +/** Call the required functions to set up DCP-o-matic's static arrays, etc.
   *  Must be called from the UI thread, if there is one.
   */
  void
 -dvdomatic_setup ()
 +dcpomatic_setup ()
  {
        avfilter_register_all ();
        
        ui_thread = boost::this_thread::get_id ();
  }
  
 -#ifdef DVDOMATIC_WINDOWS
 +#ifdef DCPOMATIC_WINDOWS
  boost::filesystem::path
  mo_path ()
  {
  #endif
  
  void
 -dvdomatic_setup_i18n (string lang)
 +dcpomatic_setup_i18n (string lang)
  {
 -#ifdef DVDOMATIC_POSIX
 +#ifdef DCPOMATIC_POSIX
        lang += ".UTF8";
  #endif
  
        }
  
        setlocale (LC_ALL, "");
 -      textdomain ("libdvdomatic");
 +      textdomain ("libdcpomatic");
  
 -#ifdef DVDOMATIC_WINDOWS
 -      bindtextdomain ("libdvdomatic", mo_path().string().c_str());
 -      bind_textdomain_codeset ("libdvdomatic", "UTF8");
 +#ifdef DCPOMATIC_WINDOWS
 +      bindtextdomain ("libdcpomatic", mo_path().string().c_str());
 +      bind_textdomain_codeset ("libdcpomatic", "UTF8");
  #endif        
  
 -#ifdef DVDOMATIC_POSIX
 -      bindtextdomain ("libdvdomatic", POSIX_LOCALE_PREFIX);
 +#ifdef DCPOMATIC_POSIX
 +      bindtextdomain ("libdcpomatic", POSIX_LOCALE_PREFIX);
  #endif
  }
  
@@@ -356,7 -351,7 +357,7 @@@ md5_digest (void const * data, int size
        
        stringstream s;
        for (int i = 0; i < MD5_DIGEST_LENGTH; ++i) {
-               s << hex << setfill('0') << setw(2) << ((int) digest[i]);
+               s << std::hex << std::setfill('0') << std::setw(2) << ((int) digest[i]);
        }
  
        return s.str ();
   *  @return MD5 digest of file's contents.
   */
  string
 -md5_digest (string file)
 +md5_digest (boost::filesystem::path file)
  {
-       ifstream f (file.string().c_str(), ios::binary);
 -      ifstream f (file.c_str(), std::ios::binary);
++      ifstream f (file.string().c_str(), std::ios::binary);
        if (!f.good ()) {
 -              throw OpenFileError (file);
 +              throw OpenFileError (file.string());
        }
        
-       f.seekg (0, ios::end);
+       f.seekg (0, std::ios::end);
        int bytes = f.tellg ();
-       f.seekg (0, ios::beg);
+       f.seekg (0, std::ios::beg);
  
        int const buffer_size = 64 * 1024;
        char buffer[buffer_size];
  
        stringstream s;
        for (int i = 0; i < MD5_DIGEST_LENGTH; ++i) {
-               s << hex << setfill('0') << setw(2) << ((int) digest[i]);
+               s << std::hex << std::setfill('0') << std::setw(2) << ((int) digest[i]);
        }
  
        return s.str ();
@@@ -459,8 -454,8 +460,8 @@@ best_dcp_frame_rate (float source_fps
        }
  
        /* Pick the best one, bailing early if we hit an exact match */
-       float error = numeric_limits<float>::max ();
-       boost::optional<FrameRateCandidate> best;
+       float error = std::numeric_limits<float>::max ();
+       optional<FrameRateCandidate> best;
        list<FrameRateCandidate>::iterator i = candidates.begin();
        while (i != candidates.end()) {
                
@@@ -495,6 -490,16 +496,6 @@@ dcp_audio_sample_rate (int fs
        return 96000;
  }
  
 -bool operator== (Crop const & a, Crop const & b)
 -{
 -      return (a.left == b.left && a.right == b.right && a.top == b.top && a.bottom == b.bottom);
 -}
 -
 -bool operator!= (Crop const & a, Crop const & b)
 -{
 -      return !(a == b);
 -}
 -
  /** @param index Colour LUT index.
   *  @return Human-readable name.
   */
@@@ -769,6 -774,21 +770,21 @@@ AudioBuffers::AudioBuffers (AudioBuffer
        }
  }
  
+ /* XXX: it's a shame that this is a copy-and-paste of the above;
+    probably fixable with c++0x.
+ */
+ AudioBuffers::AudioBuffers (boost::shared_ptr<const AudioBuffers> other)
+       : _channels (other->_channels)
+       , _frames (other->_frames)
+       , _allocated_frames (other->_frames)
+ {
+       _data = new float*[_channels];
+       for (int i = 0; i < _channels; ++i) {
+               _data[i] = new float[_frames];
+               memcpy (_data[i], other->_data[i], _frames * sizeof (float));
+       }
+ }
  /** AudioBuffers destructor */
  AudioBuffers::~AudioBuffers ()
  {
@@@ -869,21 -889,6 +885,21 @@@ AudioBuffers::move (int from, int to, i
        }
  }
  
- AudioBuffers::accumulate (shared_ptr<AudioBuffers> from, int from_channel, int to_channel)
 +/** Add data from from `from', `from_channel' to our channel `to_channel' */
 +void
++AudioBuffers::accumulate (shared_ptr<const AudioBuffers> from, int from_channel, int to_channel)
 +{
 +      int const N = frames ();
 +      assert (from->frames() == N);
 +
 +      float* s = from->data (from_channel);
 +      float* d = _data[to_channel];
 +
 +      for (int i = 0; i < N; ++i) {
 +              *d++ += *s++;
 +      }
 +}
 +
  /** Trip an assert if the caller is not in the UI thread */
  void
  ensure_ui_thread ()
        assert (boost::this_thread::get_id() == ui_thread);
  }
  
 -/** @param v Source video frame.
 +/** @param v Content video frame.
   *  @param audio_sample_rate Source audio sample rate.
   *  @param frames_per_second Number of video frames per second.
   *  @return Equivalent number of audio frames for `v'.
   */
  int64_t
 -video_frames_to_audio_frames (SourceFrame v, float audio_sample_rate, float frames_per_second)
 +video_frames_to_audio_frames (ContentVideoFrame v, float audio_sample_rate, float frames_per_second)
  {
        return ((int64_t) v * audio_sample_rate / frames_per_second);
  }
  
 -/** @param f Filename.
 - *  @return true if this file is a still image, false if it is something else.
 - */
 -bool
 -still_image_file (string f)
 -{
 -      string ext = boost::filesystem::path(f).extension().string();
 -
 -      transform (ext.begin(), ext.end(), ext.begin(), ::tolower);
 -      
 -      return (ext == N_(".tif") || ext == N_(".tiff") || ext == N_(".jpg") || ext == N_(".jpeg") || ext == N_(".png") || ext == N_(".bmp"));
 -}
 -
  /** @return A pair containing CPU model name and the number of processors */
  pair<string, int>
  cpu_info ()
        pair<string, int> info;
        info.second = 0;
        
 -#ifdef DVDOMATIC_POSIX
 +#ifdef DCPOMATIC_POSIX
        ifstream f (N_("/proc/cpuinfo"));
        while (f.good ()) {
                string l;
@@@ -948,6 -966,58 +964,6 @@@ audio_channel_name (int c
        return channels[c];
  }
  
 -AudioMapping::AudioMapping (int c)
 -      : _source_channels (c)
 -{
 -
 -}
 -
 -optional<libdcp::Channel>
 -AudioMapping::source_to_dcp (int c) const
 -{
 -      if (c >= _source_channels) {
 -              return optional<libdcp::Channel> ();
 -      }
 -
 -      if (_source_channels == 1) {
 -              /* mono sources to centre */
 -              return libdcp::CENTRE;
 -      }
 -      
 -      return static_cast<libdcp::Channel> (c);
 -}
 -
 -optional<int>
 -AudioMapping::dcp_to_source (libdcp::Channel c) const
 -{
 -      if (_source_channels == 1) {
 -              if (c == libdcp::CENTRE) {
 -                      return 0;
 -              } else {
 -                      return optional<int> ();
 -              }
 -      }
 -
 -      if (static_cast<int> (c) >= _source_channels) {
 -              return optional<int> ();
 -      }
 -      
 -      return static_cast<int> (c);
 -}
 -
 -int
 -AudioMapping::dcp_channels () const
 -{
 -      if (_source_channels == 1) {
 -              /* The source is mono, so to put the mono channel into
 -                 the centre we need to generate a 5.1 soundtrack.
 -              */
 -              return 6;
 -      }
 -
 -      return _source_channels;
 -}
 -
  FrameRateConversion::FrameRateConversion (float source, int dcp)
        : skip (false)
        , repeat (false)
diff --combined src/lib/util.h
index 02cc742aa52f62a8fac1a467d1c7a44b310f8625,99670110edec6d4d47eaf6c4709c60d3be3e5f8c..0edfe2076b3bd8ce80f6077df102d1b3d2564f17
@@@ -22,8 -22,8 +22,8 @@@
   *  @brief Some utility functions and classes.
   */
  
 -#ifndef DVDOMATIC_UTIL_H
 -#define DVDOMATIC_UTIL_H
 +#ifndef DCPOMATIC_UTIL_H
 +#define DCPOMATIC_UTIL_H
  
  #include <string>
  #include <vector>
@@@ -37,9 -37,8 +37,9 @@@ extern "C" 
  #include <libavfilter/avfilter.h>
  }
  #include "compose.hpp"
 +#include "types.h"
  
 -#ifdef DVDOMATIC_DEBUG
 +#ifdef DCPOMATIC_DEBUG
  #define TIMING(...) _film->log()->microsecond_log (String::compose (__VA_ARGS__), Log::TIMING);
  #else
  #define TIMING(...)
@@@ -55,17 -54,19 +55,17 @@@ extern std::string seconds_to_approxima
  extern void stacktrace (std::ostream &, int);
  extern std::string dependency_version_summary ();
  extern double seconds (struct timeval);
 -extern void dvdomatic_setup ();
 -extern void dvdomatic_setup_i18n (std::string);
 +extern void dcpomatic_setup ();
 +extern void dcpomatic_setup_i18n (std::string);
  extern std::vector<std::string> split_at_spaces_considering_quotes (std::string);
 -extern std::string md5_digest (std::string);
 +extern std::string md5_digest (boost::filesystem::path);
  extern std::string md5_digest (void const *, int);
  extern void ensure_ui_thread ();
  extern std::string audio_channel_name (int);
 -#ifdef DVDOMATIC_WINDOWS
 +#ifdef DCPOMATIC_WINDOWS
  extern boost::filesystem::path mo_path ();
  #endif
  
 -typedef int SourceFrame;
 -
  struct FrameRateConversion
  {
        FrameRateConversion (float, int);
  
  int best_dcp_frame_rate (float);
  
 -enum ContentType {
 -      STILL, ///< content is still images
 -      VIDEO  ///< content is a video
 -};
 -
 -/** @struct Crop
 - *  @brief A description of the crop of an image or video.
 - */
 -struct Crop
 -{
 -      Crop () : left (0), right (0), top (0), bottom (0) {}
 -
 -      /** Number of pixels to remove from the left-hand side */
 -      int left;
 -      /** Number of pixels to remove from the right-hand side */
 -      int right;
 -      /** Number of pixels to remove from the top */
 -      int top;
 -      /** Number of pixels to remove from the bottom */
 -      int bottom;
 -};
 -
 -extern bool operator== (Crop const & a, Crop const & b);
 -extern bool operator!= (Crop const & a, Crop const & b);
 -
 -/** @struct Position
 - *  @brief A position.
 - */
 -struct Position
 -{
 -      Position ()
 -              : x (0)
 -              , y (0)
 -      {}
 -
 -      Position (int x_, int y_)
 -              : x (x_)
 -              , y (y_)
 -      {}
 -
 -      /** x coordinate */
 -      int x;
 -      /** y coordinate */
 -      int y;
 -};
 -
 -/** @struct Rect
 - *  @brief A rectangle.
 - */
 -struct Rect
 -{
 -      Rect ()
 -              : x (0)
 -              , y (0)
 -              , width (0)
 -              , height (0)
 -      {}
 -
 -      Rect (int x_, int y_, int w_, int h_)
 -              : x (x_)
 -              , y (y_)
 -              , width (w_)
 -              , height (h_)
 -      {}
 -
 -      int x;
 -      int y;
 -      int width;
 -      int height;
 -
 -      Position position () const {
 -              return Position (x, y);
 -      }
 -
 -      libdcp::Size size () const {
 -              return libdcp::Size (width, height);
 -      }
 -
 -      Rect intersection (Rect const & other) const;
 -};
 -
  extern std::string crop_string (Position, libdcp::Size);
  extern int dcp_audio_sample_rate (int);
  extern std::string colour_lut_index_to_name (int index);
@@@ -117,7 -199,7 +117,7 @@@ extern std::string get_optional_string 
  
  /** @class Socket
   *  @brief A class to wrap a boost::asio::ip::tcp::socket with some things
 - *  that are useful for DVD-o-matic.
 + *  that are useful for DCP-o-matic.
   *
   *  This class wraps some things that I could not work out how to do with boost;
   *  most notably, sync read/write calls with timeouts.
@@@ -159,6 -241,7 +159,7 @@@ class AudioBuffer
  public:
        AudioBuffers (int channels, int frames);
        AudioBuffers (AudioBuffers const &);
+       AudioBuffers (boost::shared_ptr<const AudioBuffers>);
        ~AudioBuffers ();
  
        float** data () const {
  
        void copy_from (AudioBuffers* from, int frames_to_copy, int read_offset, int write_offset);
        void move (int from, int to, int frames);
-       void accumulate (boost::shared_ptr<AudioBuffers>, int, int);
++      void accumulate (boost::shared_ptr<const AudioBuffers>, int, int);
  
  private:
        /** Number of channels */
        float** _data;
  };
  
 -class AudioMapping
 -{
 -public:
 -      AudioMapping (int);
 -
 -      boost::optional<libdcp::Channel> source_to_dcp (int c) const;
 -      boost::optional<int> dcp_to_source (libdcp::Channel c) const;
 -      int dcp_channels () const;
 -
 -private:
 -      int _source_channels;
 -};
 -
 -extern int64_t video_frames_to_audio_frames (SourceFrame v, float audio_sample_rate, float frames_per_second);
 -extern bool still_image_file (std::string);
 +extern int64_t video_frames_to_audio_frames (ContentVideoFrame v, float audio_sample_rate, float frames_per_second);
  extern std::pair<std::string, int> cpu_info ();
  
  class LocaleGuard
diff --combined src/lib/video_sink.h
index 167d3980eb020531457f8240ddc99803483f3343,0170c7350c90d1f1898c9a275b7d21556fc4c2e5..6239bc557ab68ac43b28f356372404a21566109b
@@@ -17,8 -17,8 +17,8 @@@
  
  */
  
 -#ifndef DVDOMATIC_VIDEO_SINK_H
 -#define DVDOMATIC_VIDEO_SINK_H
 +#ifndef DCPOMATIC_VIDEO_SINK_H
 +#define DCPOMATIC_VIDEO_SINK_H
  
  #include <boost/shared_ptr.hpp>
  #include "util.h"
@@@ -34,7 -34,7 +34,7 @@@ public
         *  @param same true if i is the same as last time we were called.
         *  @param s A subtitle that should be on this frame, or 0.
         */
-       virtual void process_video (boost::shared_ptr<Image> i, bool same, boost::shared_ptr<Subtitle> s) = 0;
+       virtual void process_video (boost::shared_ptr<const Image> i, bool same, boost::shared_ptr<Subtitle> s) = 0;
  };
  
  class TimedVideoSink
@@@ -46,7 -46,7 +46,7 @@@ public
         *  @param s A subtitle that should be on this frame, or 0.
         *  @param t Source timestamp.
         */
-       virtual void process_video (boost::shared_ptr<Image> i, bool same, boost::shared_ptr<Subtitle> s, double t) = 0;
+       virtual void process_video (boost::shared_ptr<const Image> i, bool same, boost::shared_ptr<Subtitle> s, double t) = 0;
  };
  
  #endif
diff --combined src/lib/video_source.cc
index ccb76f02018a45268ed74d22d1d3b344b53cfea5,539243402e0824f7551940fe0cb12d2313d77acf..2de4db68d75657a55a2a05f49a0a86914781f908
  #include "video_sink.h"
  
  using boost::shared_ptr;
 +using boost::weak_ptr;
  using boost::bind;
  
- process_video_proxy (weak_ptr<VideoSink> sink, shared_ptr<Image> i, bool same, shared_ptr<Subtitle> s)
 +static void
++process_video_proxy (weak_ptr<VideoSink> sink, shared_ptr<const Image> i, bool same, shared_ptr<Subtitle> s)
 +{
 +      shared_ptr<VideoSink> p = sink.lock ();
 +      if (p) {
 +              p->process_video (i, same, s);
 +      }
 +}
 +
  void
  VideoSource::connect_video (shared_ptr<VideoSink> s)
  {
 -      Video.connect (bind (&VideoSink::process_video, s, _1, _2, _3));
 +      /* If we bind, say, a Playlist (as the VideoSink) to a Decoder (which is owned
 +         by the Playlist) we create a cycle.  Use a weak_ptr to break it.
 +      */
 +      Video.connect (bind (process_video_proxy, boost::weak_ptr<VideoSink> (s), _1, _2, _3));
  }
  
  void
@@@ -47,3 -34,11 +47,11 @@@ TimedVideoSource::connect_video (shared
  {
        Video.connect (bind (&TimedVideoSink::process_video, s, _1, _2, _3, _4));
  }
+ void
+ TimedVideoSource::connect_video (shared_ptr<VideoSink> s)
+ {
+       Video.connect (bind (&VideoSink::process_video, s, _1, _2, _3));
+ }
+       
diff --combined src/lib/video_source.h
index d2aa045a715e858fa8854fc22a2ccda098aa7908,748cb6fe98b403cda07b939568ef8971eec7993a..9b4c9b4a2040db794a94b179da4e2c46dcdb7dc8
@@@ -21,8 -21,8 +21,8 @@@
   *  @brief Parent class for classes which emit video data.
   */
  
 -#ifndef DVDOMATIC_VIDEO_SOURCE_H
 -#define DVDOMATIC_VIDEO_SOURCE_H
 +#ifndef DCPOMATIC_VIDEO_SOURCE_H
 +#define DCPOMATIC_VIDEO_SOURCE_H
  
  #include <boost/shared_ptr.hpp>
  #include <boost/signals2.hpp>
@@@ -45,7 -45,7 +45,7 @@@ public
         *  Second parameter is true if the image is the same as the last one that was emitted.
         *  Third parameter is either 0 or a subtitle that should be on this frame.
         */
-       boost::signals2::signal<void (boost::shared_ptr<Image>, bool, boost::shared_ptr<Subtitle>)> Video;
+       boost::signals2::signal<void (boost::shared_ptr<const Image>, bool, boost::shared_ptr<Subtitle>)> Video;
  
        void connect_video (boost::shared_ptr<VideoSink>);
  };
@@@ -63,8 -63,9 +63,9 @@@ public
         *  Third parameter is either 0 or a subtitle that should be on this frame.
         *  Fourth parameter is the source timestamp of this frame.
         */
-       boost::signals2::signal<void (boost::shared_ptr<Image>, bool, boost::shared_ptr<Subtitle>, double)> Video;
+       boost::signals2::signal<void (boost::shared_ptr<const Image>, bool, boost::shared_ptr<Subtitle>, double)> Video;
  
+       void connect_video (boost::shared_ptr<VideoSink>);
        void connect_video (boost::shared_ptr<TimedVideoSink>);
  };
  
index e2e1874c4eb21461b8af9153b1dc84bddadbd33a,0000000000000000000000000000000000000000..86c3cf4b14881a3268a96758d9716242af373362
mode 100644,000000..100644
--- /dev/null
@@@ -1,217 -1,0 +1,217 @@@
-       int log_level = 1;
 +/*
 +    Copyright (C) 2012 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 <iostream>
 +#include <iomanip>
 +#include <getopt.h>
 +#include <libdcp/test_mode.h>
 +#include <libdcp/version.h>
 +#include "format.h"
 +#include "film.h"
 +#include "filter.h"
 +#include "transcode_job.h"
 +#include "job_manager.h"
 +#include "ab_transcode_job.h"
 +#include "util.h"
 +#include "scaler.h"
 +#include "version.h"
 +#include "cross.h"
 +#include "config.h"
 +#include "log.h"
 +
 +using std::string;
 +using std::cerr;
 +using std::cout;
 +using std::vector;
 +using std::pair;
 +using std::list;
 +using boost::shared_ptr;
 +
 +static void
 +help (string n)
 +{
 +      cerr << "Syntax: " << n << " [OPTION] <FILM>\n"
 +           << "  -v, --version      show DCP-o-matic version\n"
 +           << "  -h, --help         show this help\n"
 +           << "  -d, --deps         list DCP-o-matic dependency details and quit\n"
 +           << "  -t, --test         run in test mode (repeatable UUID generation, timestamps etc.)\n"
 +           << "  -n, --no-progress  do not print progress to stdout\n"
 +           << "  -r, --no-remote    do not use any remote servers\n"
 +           << "\n"
 +           << "<FILM> is the film directory.\n";
 +}
 +
 +int
 +main (int argc, char* argv[])
 +{
 +      string film_dir;
 +      bool test_mode = false;
 +      bool progress = true;
 +      bool no_remote = false;
++      int log_level = 0;
 +
 +      int option_index = 0;
 +      while (1) {
 +              static struct option long_options[] = {
 +                      { "version", no_argument, 0, 'v'},
 +                      { "help", no_argument, 0, 'h'},
 +                      { "deps", no_argument, 0, 'd'},
 +                      { "test", no_argument, 0, 't'},
 +                      { "no-progress", no_argument, 0, 'n'},
 +                      { "no-remote", no_argument, 0, 'r'},
 +                      { "log-level", required_argument, 0, 'l' },
 +                      { 0, 0, 0, 0 }
 +              };
 +
 +              int c = getopt_long (argc, argv, "vhdtnrl:", long_options, &option_index);
 +
 +              if (c == -1) {
 +                      break;
 +              }
 +
 +              switch (c) {
 +              case 'v':
 +                      cout << "dcpomatic version " << dcpomatic_version << " " << dcpomatic_git_commit << "\n";
 +                      exit (EXIT_SUCCESS);
 +              case 'h':
 +                      help (argv[0]);
 +                      exit (EXIT_SUCCESS);
 +              case 'd':
 +                      cout << dependency_version_summary () << "\n";
 +                      exit (EXIT_SUCCESS);
 +              case 't':
 +                      test_mode = true;
 +                      break;
 +              case 'n':
 +                      progress = false;
 +                      break;
 +              case 'r':
 +                      no_remote = true;
 +                      break;
 +              case 'l':
 +                      log_level = atoi (optarg);
 +                      break;
 +              }
 +      }
 +
 +      if (optind >= argc) {
 +              help (argv[0]);
 +              exit (EXIT_FAILURE);
 +      }
 +
 +      film_dir = argv[optind];
 +                      
 +      dcpomatic_setup ();
 +
 +      if (no_remote) {
 +              Config::instance()->set_servers (vector<ServerDescription*> ());
 +      }
 +
 +      cout << "DCP-o-matic " << dcpomatic_version << " git " << dcpomatic_git_commit;
 +      char buf[256];
 +      if (gethostname (buf, 256) == 0) {
 +              cout << " on " << buf;
 +      }
 +      cout << "\n";
 +
 +      if (test_mode) {
 +              libdcp::enable_test_mode ();
 +              cout << dependency_version_summary() << "\n";
 +      }
 +
 +      shared_ptr<Film> film;
 +      try {
 +              film.reset (new Film (film_dir, true));
 +      } catch (std::exception& e) {
 +              cerr << argv[0] << ": error reading film `" << film_dir << "' (" << e.what() << ")\n";
 +              exit (EXIT_FAILURE);
 +      }
 +
 +      film->log()->set_level ((Log::Level) log_level);
 +
 +      cout << "\nMaking ";
 +      if (film->ab()) {
 +              cout << "A/B ";
 +      }
 +      cout << "DCP for " << film->name() << "\n";
 +      cout << "Test mode: " << (test_mode ? "yes" : "no") << "\n";
 +//    cout << "Content: " << film->content() << "\n";
 +      pair<string, string> const f = Filter::ffmpeg_strings (film->filters ());
 +      cout << "Filters: " << f.first << " " << f.second << "\n";
 +
 +      film->make_dcp ();
 +
 +      bool should_stop = false;
 +      bool first = true;
 +      bool error = false;
 +      while (!should_stop) {
 +
 +              dcpomatic_sleep (5);
 +
 +              list<shared_ptr<Job> > jobs = JobManager::instance()->get ();
 +
 +              if (!first && progress) {
 +                      cout << "\033[" << jobs.size() << "A";
 +                      cout.flush ();
 +              }
 +
 +              first = false;
 +
 +              int unfinished = 0;
 +              int finished_in_error = 0;
 +
 +              for (list<shared_ptr<Job> >::iterator i = jobs.begin(); i != jobs.end(); ++i) {
 +                      if (progress) {
 +                              cout << (*i)->name() << ": ";
 +                              
 +                              float const p = (*i)->overall_progress ();
 +                              
 +                              if (p >= 0) {
 +                                      cout << (*i)->status() << "                         \n";
 +                              } else {
 +                                      cout << ": Running           \n";
 +                              }
 +                      }
 +
 +                      if (!(*i)->finished ()) {
 +                              ++unfinished;
 +                      }
 +
 +                      if ((*i)->finished_in_error ()) {
 +                              ++finished_in_error;
 +                              error = true;
 +                      }
 +
 +                      if (!progress && (*i)->finished_in_error ()) {
 +                              /* We won't see this error if we haven't been showing progress,
 +                                 so show it now.
 +                              */
 +                              cout << (*i)->status() << "\n";
 +                      }
 +              }
 +
 +              if (unfinished == 0 || finished_in_error != 0) {
 +                      should_stop = true;
 +              }
 +      }
 +
 +      return error ? EXIT_FAILURE : EXIT_SUCCESS;
 +}
 +
 +        
diff --combined src/tools/po/es_ES.po
index d35f104c6d2d79c683796eacc632aa0226810b5f,1739f97cd57fea0126924ed728ebba815994611a..346aa2b39d1ea2137cba34740f9980c82698e01e
@@@ -5,9 -5,9 +5,9 @@@
  #
  msgid ""
  msgstr ""
 -"Project-Id-Version: DVDOMATIC\n"
 +"Project-Id-Version: DCPOMATIC\n"
  "Report-Msgid-Bugs-To: \n"
- "POT-Creation-Date: 2013-04-09 11:14+0100\n"
+ "POT-Creation-Date: 2013-04-22 15:06+0100\n"
  "PO-Revision-Date: 2013-03-23 21:08-0500\n"
  "Last-Translator: Manuel AC <manuel.acevedo@civantos.>\n"
  "Language-Team: Manuel AC <manuel.acevedo@civantos.com>\n"
  "Content-Transfer-Encoding: 8bit\n"
  "X-Generator: Poedit 1.5.5\n"
  
 -#: src/tools/dvdomatic.cc:179
 +#: src/tools/dcpomatic.cc:177
  msgid "&Analyse audio"
  msgstr "&Analizar audio"
  
 -#: src/tools/dvdomatic.cc:185
 +#: src/tools/dcpomatic.cc:183
  msgid "&Edit"
  msgstr "&Editar"
  
 -#: src/tools/dvdomatic.cc:184
 +#: src/tools/dcpomatic.cc:182
  msgid "&File"
  msgstr "&Archivo"
  
 -#: src/tools/dvdomatic.cc:187
 +#: src/tools/dcpomatic.cc:185
  msgid "&Help"
  msgstr "&Ayuda"
  
 -#: src/tools/dvdomatic.cc:186
 +#: src/tools/dcpomatic.cc:184
  msgid "&Jobs"
  msgstr "&Tareas"
  
 -#: src/tools/dvdomatic.cc:175
 +#: src/tools/dcpomatic.cc:173
  msgid "&Make DCP"
  msgstr "&Crear DCP"
  
 -#: src/tools/dvdomatic.cc:163
 +#: src/tools/dcpomatic.cc:161
  msgid "&Open..."
  msgstr "&Abrir..."
  
 -#: src/tools/dvdomatic.cc:172
 +#: src/tools/dcpomatic.cc:170
  msgid "&Preferences..."
  msgstr "&Preferencias..."
  
 -#: src/tools/dvdomatic.cc:167
 +#: src/tools/dcpomatic.cc:165
  msgid "&Properties..."
  msgstr "&Propiedades..."
  
 -#: src/tools/dvdomatic.cc:169
 +#: src/tools/dcpomatic.cc:167
  msgid "&Quit"
  msgstr "&Salir"
  
 -#: src/tools/dvdomatic.cc:165
 +#: src/tools/dcpomatic.cc:163
  msgid "&Save"
  msgstr "&Guardar"
  
 -#: src/tools/dvdomatic.cc:176
 +#: src/tools/dcpomatic.cc:174
  msgid "&Send DCP to TMS"
  msgstr "&Enviar DCP al TMS"
  
 -#: src/tools/dvdomatic.cc:419
 +#: src/tools/dcpomatic.cc:417
  msgid ""
  "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen"
  msgstr ""
  "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen"
  
 -#: src/tools/dvdomatic.cc:182
 +#: src/tools/dcpomatic.cc:180
  msgid "About"
  msgstr "Acerca de"
  
 -#: src/tools/dvdomatic.cc:538
 +#: src/tools/dcpomatic.cc:527
  #, fuzzy
  msgid "Could not load film %1 (%2)"
  msgstr "No se pudo cargar la película %s (%s)"
  
 -#: src/tools/dvdomatic.cc:341
 +#: src/tools/dcpomatic.cc:339
  #, c-format
  msgid "Could not open film at %s (%s)"
  msgstr "No se pudo cargar la película en %s (%s)"
  
 -#: src/tools/dvdomatic.cc:289 src/tools/dvdomatic.cc:412
 -#: src/tools/dvdomatic.cc:542
 -msgid "DVD-o-matic"
 -msgstr "DVD-o-matic"
 +#: src/tools/dcpomatic.cc:287 src/tools/dcpomatic.cc:410
 +#: src/tools/dcpomatic.cc:531
 +msgid "DCP-o-matic"
 +msgstr "DCP-o-matic"
  
 -#: src/tools/dvdomatic.cc:77
 +#: src/tools/dcpomatic.cc:75
  msgid "Film changed"
  msgstr "Película cambiada"
  
 -#: src/tools/dvdomatic.cc:418
 +#: src/tools/dcpomatic.cc:416
  msgid "Free, open-source DCP generation from almost anything."
  msgstr ""
  "Generación de DCP a partir de casi cualquier fuente, libre y de código "
  "abierto."
  
 -#: src/tools/dvdomatic.cc:162
 +#: src/tools/dcpomatic.cc:160
  msgid "New..."
  msgstr "Nuevo..."
  
 -#: src/tools/dvdomatic.cc:177
 +#: src/tools/dcpomatic.cc:175
  msgid "S&how DCP"
  msgstr "&Mostrar DCP"
  
 -#: src/tools/dvdomatic.cc:76
 -#, c-format
 +#: src/tools/dcpomatic.cc:74
  msgid "Save changes to film \"%s\" before closing?"
  msgstr ""
  
 -#: src/tools/dvdomatic.cc:321
 +#: src/tools/dcpomatic.cc:319
  msgid "Select film to open"
  msgstr "Selecciona la película a abrir"
  
 -#: src/tools/dvdomatic.cc:305
 +#: src/tools/dcpomatic.cc:303
  #, fuzzy
  msgid "The directory %1 already exists."
  msgstr "La carpeta %s ya existe."
  
 -#: src/tools/dvdomatic.cc:326
 +#: src/tools/dcpomatic.cc:324
  msgid ""
  "You did not select a folder.  Make sure that you select a folder before "
  "clicking Open."
diff --combined src/tools/po/fr_FR.po
index ef2246992ceee39f118ebba1a20f2f1e50f8fc32,c1447f7e669c60f29a63248adab740e2d0e32cde..8ce305ccf8b66073c27892d6d64ff5da41001be4
@@@ -5,9 -5,9 +5,9 @@@
  #
  msgid ""
  msgstr ""
 -"Project-Id-Version: DVD-o-matic FRENCH\n"
 +"Project-Id-Version: DCP-o-matic FRENCH\n"
  "Report-Msgid-Bugs-To: \n"
- "POT-Creation-Date: 2013-04-09 11:14+0100\n"
+ "POT-Creation-Date: 2013-04-22 15:06+0100\n"
  "PO-Revision-Date: 2013-03-13 22:33+0100\n"
  "Last-Translator: \n"
  "Language-Team: \n"
  "Content-Type: text/plain; charset=UTF-8\n"
  "Content-Transfer-Encoding: 8bit\n"
  
 -#: src/tools/dvdomatic.cc:179
 +#: src/tools/dcpomatic.cc:177
  msgid "&Analyse audio"
  msgstr "&Analyser le son"
  
 -#: src/tools/dvdomatic.cc:185
 +#: src/tools/dcpomatic.cc:183
  msgid "&Edit"
  msgstr "&Edition"
  
 -#: src/tools/dvdomatic.cc:184
 +#: src/tools/dcpomatic.cc:182
  msgid "&File"
  msgstr "&Fichier"
  
 -#: src/tools/dvdomatic.cc:187
 +#: src/tools/dcpomatic.cc:185
  msgid "&Help"
  msgstr "&Aide"
  
 -#: src/tools/dvdomatic.cc:186
 +#: src/tools/dcpomatic.cc:184
  msgid "&Jobs"
  msgstr "&Travaux"
  
 -#: src/tools/dvdomatic.cc:175
 +#: src/tools/dcpomatic.cc:173
  msgid "&Make DCP"
  msgstr "&Créer le DCP"
  
 -#: src/tools/dvdomatic.cc:163
 +#: src/tools/dcpomatic.cc:161
  msgid "&Open..."
  msgstr "&Ouvrir..."
  
 -#: src/tools/dvdomatic.cc:172
 +#: src/tools/dcpomatic.cc:170
  msgid "&Preferences..."
  msgstr "&Préférences..."
  
 -#: src/tools/dvdomatic.cc:167
 +#: src/tools/dcpomatic.cc:165
  msgid "&Properties..."
  msgstr "&Propriétés..."
  
 -#: src/tools/dvdomatic.cc:169
 +#: src/tools/dcpomatic.cc:167
  msgid "&Quit"
  msgstr "&Quitter"
  
 -#: src/tools/dvdomatic.cc:165
 +#: src/tools/dcpomatic.cc:163
  msgid "&Save"
  msgstr "&Enregistrer"
  
 -#: src/tools/dvdomatic.cc:176
 +#: src/tools/dcpomatic.cc:174
  msgid "&Send DCP to TMS"
  msgstr "&Envoyer le DCP dans le TMS"
  
 -#: src/tools/dvdomatic.cc:419
 +#: src/tools/dcpomatic.cc:417
  msgid ""
  "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen"
  msgstr ""
  "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen"
  
 -#: src/tools/dvdomatic.cc:182
 +#: src/tools/dcpomatic.cc:180
  msgid "About"
  msgstr "A Propos"
  
 -#: src/tools/dvdomatic.cc:538
 +#: src/tools/dcpomatic.cc:527
  #, fuzzy
  msgid "Could not load film %1 (%2)"
  msgstr "Impossible de charger le film %s (%s)"
  
 -#: src/tools/dvdomatic.cc:341
 +#: src/tools/dcpomatic.cc:339
  #, c-format
  msgid "Could not open film at %s (%s)"
  msgstr "Impossible d'ouvrir le film à %s (%s)"
  
 -#: src/tools/dvdomatic.cc:289 src/tools/dvdomatic.cc:412
 -#: src/tools/dvdomatic.cc:542
 -msgid "DVD-o-matic"
 -msgstr "DVD-o-matic"
 +#: src/tools/dcpomatic.cc:287 src/tools/dcpomatic.cc:410
 +#: src/tools/dcpomatic.cc:531
 +msgid "DCP-o-matic"
 +msgstr "DCP-o-matic"
  
 -#: src/tools/dvdomatic.cc:77
 +#: src/tools/dcpomatic.cc:75
  msgid "Film changed"
  msgstr "Film changé"
  
 -#: src/tools/dvdomatic.cc:418
 +#: src/tools/dcpomatic.cc:416
  msgid "Free, open-source DCP generation from almost anything."
  msgstr "Création de DCP libre et open-source à partir de presque tout."
  
 -#: src/tools/dvdomatic.cc:162
 +#: src/tools/dcpomatic.cc:160
  msgid "New..."
  msgstr "Nouveau..."
  
 -#: src/tools/dvdomatic.cc:177
 +#: src/tools/dcpomatic.cc:175
  msgid "S&how DCP"
  msgstr "Voir le DCP"
  
 -#: src/tools/dvdomatic.cc:76
 -#, c-format
 +#: src/tools/dcpomatic.cc:74
  msgid "Save changes to film \"%s\" before closing?"
  msgstr ""
  
 -#: src/tools/dvdomatic.cc:321
 +#: src/tools/dcpomatic.cc:319
  msgid "Select film to open"
  msgstr "Sélectionner le film à ouvrir"
  
 -#: src/tools/dvdomatic.cc:305
 +#: src/tools/dcpomatic.cc:303
  #, fuzzy
  msgid "The directory %1 already exists."
  msgstr "Le dossier %s existe déjà."
  
 -#: src/tools/dvdomatic.cc:326
 +#: src/tools/dcpomatic.cc:324
  msgid ""
  "You did not select a folder.  Make sure that you select a folder before "
  "clicking Open."
diff --combined src/tools/po/it_IT.po
index 998f700591f82061ef8334da827f95cfe95b255c,1e0d8446a1ea08a1947c10b7e86bb7b0365d5d2a..13732129bb159802ca0eb15f200a7ce6ff09dd3f
@@@ -7,7 -7,7 +7,7 @@@ msgid "
  msgstr ""
  "Project-Id-Version: IT VERSION\n"
  "Report-Msgid-Bugs-To: \n"
- "POT-Creation-Date: 2013-04-09 11:14+0100\n"
+ "POT-Creation-Date: 2013-04-22 15:06+0100\n"
  "PO-Revision-Date: 2013-04-03 13:00+0100\n"
  "Last-Translator: Maci <macibro@gmail.com>\n"
  "Language-Team: \n"
  "Content-Transfer-Encoding: 8bit\n"
  "X-Generator: Poedit 1.5.5\n"
  
 -#: src/tools/dvdomatic.cc:179
 +#: src/tools/dcpomatic.cc:177
  msgid "&Analyse audio"
  msgstr "&Analizza audio"
  
 -#: src/tools/dvdomatic.cc:185
 +#: src/tools/dcpomatic.cc:183
  msgid "&Edit"
  msgstr "&Modifica"
  
 -#: src/tools/dvdomatic.cc:184
 +#: src/tools/dcpomatic.cc:182
  msgid "&File"
  msgstr "&File"
  
 -#: src/tools/dvdomatic.cc:187
 +#: src/tools/dcpomatic.cc:185
  msgid "&Help"
  msgstr "&Aiuto"
  
 -#: src/tools/dvdomatic.cc:186
 +#: src/tools/dcpomatic.cc:184
  msgid "&Jobs"
  msgstr "&Lavori"
  
 -#: src/tools/dvdomatic.cc:175
 +#: src/tools/dcpomatic.cc:173
  msgid "&Make DCP"
  msgstr "&Crea DCP"
  
 -#: src/tools/dvdomatic.cc:163
 +#: src/tools/dcpomatic.cc:161
  msgid "&Open..."
  msgstr "&Apri..."
  
 -#: src/tools/dvdomatic.cc:172
 +#: src/tools/dcpomatic.cc:170
  msgid "&Preferences..."
  msgstr "&Preferenze..."
  
 -#: src/tools/dvdomatic.cc:167
 +#: src/tools/dcpomatic.cc:165
  msgid "&Properties..."
  msgstr "&Proprieta'..."
  
 -#: src/tools/dvdomatic.cc:169
 +#: src/tools/dcpomatic.cc:167
  msgid "&Quit"
  msgstr "&Esci"
  
 -#: src/tools/dvdomatic.cc:165
 +#: src/tools/dcpomatic.cc:163
  msgid "&Save"
  msgstr "&Salva"
  
 -#: src/tools/dvdomatic.cc:176
 +#: src/tools/dcpomatic.cc:174
  msgid "&Send DCP to TMS"
  msgstr "&Invia DCP a TMS"
  
 -#: src/tools/dvdomatic.cc:419
 +#: src/tools/dcpomatic.cc:417
  msgid ""
  "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen"
  msgstr ""
  "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen"
  
 -#: src/tools/dvdomatic.cc:182
 +#: src/tools/dcpomatic.cc:180
  msgid "About"
  msgstr "Informazioni"
  
 -#: src/tools/dvdomatic.cc:538
 +#: src/tools/dcpomatic.cc:527
  msgid "Could not load film %1 (%2)"
  msgstr "Non posso caricare il film %s (%s)"
  
 -#: src/tools/dvdomatic.cc:341
 +#: src/tools/dcpomatic.cc:339
  #, c-format
  msgid "Could not open film at %s (%s)"
  msgstr "Non posso aprire il film in %s (%s)"
  
 -#: src/tools/dvdomatic.cc:289 src/tools/dvdomatic.cc:412
 -#: src/tools/dvdomatic.cc:542
 -msgid "DVD-o-matic"
 -msgstr "DVD-o-matic"
 +#: src/tools/dcpomatic.cc:287 src/tools/dcpomatic.cc:410
 +#: src/tools/dcpomatic.cc:531
 +msgid "DCP-o-matic"
 +msgstr "DCP-o-matic"
  
 -#: src/tools/dvdomatic.cc:77
 +#: src/tools/dcpomatic.cc:75
  msgid "Film changed"
  msgstr "Film modificato"
  
 -#: src/tools/dvdomatic.cc:418
 +#: src/tools/dcpomatic.cc:416
  msgid "Free, open-source DCP generation from almost anything."
  msgstr "Genera DCP da quasi tutto, free e open-source."
  
 -#: src/tools/dvdomatic.cc:162
 +#: src/tools/dcpomatic.cc:160
  msgid "New..."
  msgstr "Nuovo"
  
 -#: src/tools/dvdomatic.cc:177
 +#: src/tools/dcpomatic.cc:175
  msgid "S&how DCP"
  msgstr "&Mostra DCP"
  
 -#: src/tools/dvdomatic.cc:76
 -#, c-format
 +#: src/tools/dcpomatic.cc:74
  msgid "Save changes to film \"%s\" before closing?"
  msgstr "Salvare i cambiamenti del film \"%s\" prima di chiudere?"
  
 -#: src/tools/dvdomatic.cc:321
 +#: src/tools/dcpomatic.cc:319
  msgid "Select film to open"
  msgstr "Seleziona il film da aprire"
  
 -#: src/tools/dvdomatic.cc:305
 +#: src/tools/dcpomatic.cc:303
  msgid "The directory %1 already exists."
  msgstr "La directory %s esiste gia'."
  
 -#: src/tools/dvdomatic.cc:326
 +#: src/tools/dcpomatic.cc:324
  msgid ""
  "You did not select a folder.  Make sure that you select a folder before "
  "clicking Open."
diff --combined src/tools/po/sv_SE.po
index 4765c2d98f908c6b8590a1d71b0e47fe12a2e924,8ae68853f0eab39293fbe8c1b80336cb5b7fd262..69706d6479563932ca4cf325de84f006cbe85de5
@@@ -5,9 -5,9 +5,9 @@@
  #
  msgid ""
  msgstr ""
 -"Project-Id-Version: DVD-o-matic\n"
 +"Project-Id-Version: DCP-o-matic\n"
  "Report-Msgid-Bugs-To: \n"
- "POT-Creation-Date: 2013-04-09 11:14+0100\n"
+ "POT-Creation-Date: 2013-04-22 15:06+0100\n"
  "PO-Revision-Date: 2013-04-09 10:12+0100\n"
  "Last-Translator: Adam Klotblixt <adam.klotblixt@gmail.com>\n"
  "Language-Team: \n"
  "Content-Transfer-Encoding: 8bit\n"
  "X-Generator: Poedit 1.5.5\n"
  
 -#: src/tools/dvdomatic.cc:179
 +#: src/tools/dcpomatic.cc:177
  msgid "&Analyse audio"
  msgstr "&Analysera audio"
  
 -#: src/tools/dvdomatic.cc:185
 +#: src/tools/dcpomatic.cc:183
  msgid "&Edit"
  msgstr "&Redigera"
  
 -#: src/tools/dvdomatic.cc:184
 +#: src/tools/dcpomatic.cc:182
  msgid "&File"
  msgstr "&Fil"
  
 -#: src/tools/dvdomatic.cc:187
 +#: src/tools/dcpomatic.cc:185
  msgid "&Help"
  msgstr "&Hjälp"
  
 -#: src/tools/dvdomatic.cc:186
 +#: src/tools/dcpomatic.cc:184
  msgid "&Jobs"
  msgstr "&Jobb"
  
 -#: src/tools/dvdomatic.cc:175
 +#: src/tools/dcpomatic.cc:173
  msgid "&Make DCP"
  msgstr "&Skapa DCP"
  
 -#: src/tools/dvdomatic.cc:163
 +#: src/tools/dcpomatic.cc:161
  msgid "&Open..."
  msgstr "&Öppna"
  
 -#: src/tools/dvdomatic.cc:172
 +#: src/tools/dcpomatic.cc:170
  msgid "&Preferences..."
  msgstr "&Inställningar"
  
 -#: src/tools/dvdomatic.cc:167
 +#: src/tools/dcpomatic.cc:165
  msgid "&Properties..."
  msgstr "&Egenskaper"
  
 -#: src/tools/dvdomatic.cc:169
 +#: src/tools/dcpomatic.cc:167
  msgid "&Quit"
  msgstr "&Avsluta"
  
 -#: src/tools/dvdomatic.cc:165
 +#: src/tools/dcpomatic.cc:163
  msgid "&Save"
  msgstr "&Spara"
  
 -#: src/tools/dvdomatic.cc:176
 +#: src/tools/dcpomatic.cc:174
  msgid "&Send DCP to TMS"
  msgstr "&Skicka DCP till TMS"
  
 -#: src/tools/dvdomatic.cc:419
 +#: src/tools/dcpomatic.cc:417
  msgid ""
  "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen"
  msgstr ""
  "(C) 2012-2013 Carl Hetherington, Terrence Meiczinger, Paul Davis, Ole Laursen"
  
 -#: src/tools/dvdomatic.cc:182
 +#: src/tools/dcpomatic.cc:180
  msgid "About"
  msgstr "Om"
  
 -#: src/tools/dvdomatic.cc:538
 +#: src/tools/dcpomatic.cc:527
  msgid "Could not load film %1 (%2)"
  msgstr "Kunde inte öppna filmen %1 (%2)"
  
 -#: src/tools/dvdomatic.cc:341
 +#: src/tools/dcpomatic.cc:339
  #, c-format
  msgid "Could not open film at %s (%s)"
  msgstr "Kunde inte öppna filmen vid %s (%s)"
  
 -#: src/tools/dvdomatic.cc:289 src/tools/dvdomatic.cc:412
 -#: src/tools/dvdomatic.cc:542
 -msgid "DVD-o-matic"
 -msgstr "DVD-o-matic"
 +#: src/tools/dcpomatic.cc:287 src/tools/dcpomatic.cc:410
 +#: src/tools/dcpomatic.cc:531
 +msgid "DCP-o-matic"
 +msgstr "DCP-o-matic"
  
 -#: src/tools/dvdomatic.cc:77
 +#: src/tools/dcpomatic.cc:75
  msgid "Film changed"
  msgstr "Film ändrad"
  
 -#: src/tools/dvdomatic.cc:418
 +#: src/tools/dcpomatic.cc:416
  msgid "Free, open-source DCP generation from almost anything."
  msgstr ""
  "Fri, öppen-källkodsprogramvara för DCP-generering från nästan vad som helst."
  
 -#: src/tools/dvdomatic.cc:162
 +#: src/tools/dcpomatic.cc:160
  msgid "New..."
  msgstr "Ny..."
  
 -#: src/tools/dvdomatic.cc:177
 +#: src/tools/dcpomatic.cc:175
  msgid "S&how DCP"
  msgstr "&Visa DCP"
  
 -#: src/tools/dvdomatic.cc:76
 -#, fuzzy, c-format
 +#: src/tools/dcpomatic.cc:74
  msgid "Save changes to film \"%s\" before closing?"
 -msgstr "Spara ändringarna till filmen \"%1\" före avslut?"
 +msgstr "Spara ändringarna till filmen \"%s\" före avslut?"
  
 -#: src/tools/dvdomatic.cc:321
 +#: src/tools/dcpomatic.cc:319
  msgid "Select film to open"
  msgstr "Välj film att öppna"
  
 -#: src/tools/dvdomatic.cc:305
 +#: src/tools/dcpomatic.cc:303
  msgid "The directory %1 already exists."
  msgstr "Katalogen %1 finns redan."
  
 -#: src/tools/dvdomatic.cc:326
 +#: src/tools/dcpomatic.cc:324
  msgid ""
  "You did not select a folder.  Make sure that you select a folder before "
  "clicking Open."
index 42cc76871fb2f4dfc8b8337a341f3ddf44995787,5e1cf49b4b0b1e04faff88718f58801948492173..af176ac18e6b02ea011cc526bd3a4a581b49e128
  #include "scaler.h"
  #include "server.h"
  #include "dcp_video_frame.h"
 -#include "options.h"
  #include "decoder.h"
  #include "exceptions.h"
  #include "scaler.h"
  #include "log.h"
 -#include "decoder_factory.h"
  #include "video_decoder.h"
 +#include "player.h"
  
  using std::cout;
  using std::cerr;
@@@ -46,7 -47,7 +46,7 @@@ static shared_ptr<FileLog> log_ (new Fi
  static int frame = 0;
  
  void
- process_video (shared_ptr<Image> image, bool, shared_ptr<Subtitle> sub)
+ process_video (shared_ptr<const Image> image, bool, shared_ptr<Subtitle> sub)
  {
        shared_ptr<DCPVideoFrame> local (
                new DCPVideoFrame (
@@@ -145,19 -146,22 +145,19 @@@ main (int argc, char* argv[]
                exit (EXIT_FAILURE);
        }
  
 -      dvdomatic_setup ();
 +      dcpomatic_setup ();
  
        server = new ServerDescription (server_host, 1);
        shared_ptr<Film> film (new Film (film_dir, true));
  
 -      DecodeOptions opt;
 -      opt.decode_audio = false;
 -      opt.decode_subtitles = true;
 -      opt.video_sync = true;
 +      shared_ptr<Player> player = film->player ();
 +      player->disable_audio ();
  
 -      Decoders decoders = decoder_factory (film, opt);
        try {
 -              decoders.video->Video.connect (boost::bind (process_video, _1, _2, _3));
 +              player->Video.connect (boost::bind (process_video, _1, _2, _3));
                bool done = false;
                while (!done) {
 -                      done = decoders.video->pass ();
 +                      done = player->pass ();
                }
        } catch (std::exception& e) {
                cerr << "Error: " << e.what() << "\n";
diff --combined src/wx/film_viewer.cc
index e742a3e41b7ce9757f476fcd95abb1e4e7ccc97b,4f2985a061db3677ebfb6d0ed5c89bf2fd25c9f8..e9a1a574be01477b884e34a5eeb05e30684edbcc
  #include "lib/format.h"
  #include "lib/util.h"
  #include "lib/job_manager.h"
 -#include "lib/options.h"
  #include "lib/subtitle.h"
  #include "lib/image.h"
  #include "lib/scaler.h"
  #include "lib/exceptions.h"
  #include "lib/examine_content_job.h"
  #include "lib/filter.h"
 +#include "lib/player.h"
 +#include "lib/video_content.h"
 +#include "lib/ffmpeg_content.h"
 +#include "lib/imagemagick_content.h"
  #include "film_viewer.h"
  #include "wx_util.h"
  #include "video_decoder.h"
@@@ -48,8 -45,6 +48,8 @@@ using std::max
  using std::cout;
  using std::list;
  using boost::shared_ptr;
 +using boost::dynamic_pointer_cast;
 +using boost::weak_ptr;
  using libdcp::Size;
  
  FilmViewer::FilmViewer (shared_ptr<Film> f, wxWindow* p)
@@@ -119,22 -114,43 +119,22 @@@ FilmViewer::film_changed (Film::Propert
                break;
        case Film::CONTENT:
        {
 -              DecodeOptions o;
 -              o.decode_audio = false;
 -              o.decode_subtitles = true;
 -              o.video_sync = false;
 -
 -              try {
 -                      _decoders = decoder_factory (_film, o);
 -              } catch (StringError& e) {
 -                      error_dialog (this, wxString::Format (_("Could not open content file (%s)"), std_to_wx(e.what()).data()));
 -                      return;
 -              }
 -              
 -              if (_decoders.video == 0) {
 -                      break;
 -              }
 -              _decoders.video->Video.connect (bind (&FilmViewer::process_video, this, _1, _2, _3, _4));
 -              _decoders.video->OutputChanged.connect (boost::bind (&FilmViewer::decoder_changed, this));
 -              _decoders.video->set_subtitle_stream (_film->subtitle_stream());
                calculate_sizes ();
 -              get_frame ();
 -              _panel->Refresh ();
 -              _slider->Show (_film->content_type() == VIDEO);
 -              _play_button->Show (_film->content_type() == VIDEO);
 -              _v_sizer->Layout ();
 +              wxScrollEvent ev;
 +              slider_moved (ev);
                break;
        }
        case Film::WITH_SUBTITLES:
        case Film::SUBTITLE_OFFSET:
        case Film::SUBTITLE_SCALE:
 +              raw_to_display ();
 +              _panel->Refresh ();
 +              _panel->Update ();
 +              break;
        case Film::SCALER:
        case Film::FILTERS:
 -              update_from_raw ();
 -              break;
 -      case Film::SUBTITLE_STREAM:
 -              if (_decoders.video) {
 -                      _decoders.video->set_subtitle_stream (_film->subtitle_stream ());
 -              }
 +      case Film::CROP:
 +              update_from_decoder ();
                break;
        default:
                break;
@@@ -147,7 -163,7 +147,7 @@@ FilmViewer::set_film (shared_ptr<Film> 
        if (_film == f) {
                return;
        }
 -      
 +
        _film = f;
  
        _raw_frame.reset ();
                return;
        }
  
 +      _player = f->player ();
 +      _player->disable_audio ();
 +      /* Don't disable subtitles here as we may need them, and it's nice to be able to turn them
 +         on and off without needing obtain a new Player.
 +      */
 +      
 +      _player->Video.connect (bind (&FilmViewer::process_video, this, _1, _2, _3, _4));
 +      
        _film->Changed.connect (boost::bind (&FilmViewer::film_changed, this, _1));
 +      _film->ContentChanged.connect (boost::bind (&FilmViewer::film_content_changed, this, _1, _2));
  
        film_changed (Film::CONTENT);
        film_changed (Film::FORMAT);
        film_changed (Film::WITH_SUBTITLES);
        film_changed (Film::SUBTITLE_OFFSET);
        film_changed (Film::SUBTITLE_SCALE);
 -      film_changed (Film::SUBTITLE_STREAM);
  }
  
  void
 -FilmViewer::decoder_changed ()
 +FilmViewer::update_from_decoder ()
  {
 -      if (_decoders.video == 0 || _decoders.video->seek_to_last ()) {
 +      if (!_player || _player->seek (_player->last_video_time ())) {
                return;
        }
  
  void
  FilmViewer::timer (wxTimerEvent &)
  {
 -      if (!_film || !_decoders.video) {
 +      if (!_player) {
                return;
        }
        
  
        get_frame ();
  
 -      if (_film->length()) {
 -              int const new_slider_position = 4096 * _decoders.video->last_source_time() / (_film->length().get() / _film->source_frame_rate());
 +      if (_film->video_length()) {
 +              int const new_slider_position = 4096 * _player->last_video_time() / (_film->video_length() / _film->video_frame_rate());
                if (new_slider_position != _slider->GetValue()) {
                        _slider->SetValue (new_slider_position);
                }
@@@ -258,11 -266,11 +258,11 @@@ FilmViewer::paint_panel (wxPaintEvent &
  void
  FilmViewer::slider_moved (wxScrollEvent &)
  {
 -      if (!_film || !_film->length() || !_decoders.video) {
 +      if (!_film || !_player) {
                return;
        }
 -      
 -      if (_decoders.video->seek (_slider->GetValue() * _film->length().get() / (4096 * _film->source_frame_rate()))) {
 +
 +      if (_player->seek (_slider->GetValue() * _film->video_length() / (4096 * _film->video_frame_rate()))) {
                return;
        }
        
@@@ -300,7 -308,7 +300,7 @@@ FilmViewer::raw_to_display (
                return;
        }
  
-       shared_ptr<Image> input = _raw_frame;
 -      boost::shared_ptr<const Image> input = _raw_frame;
++      shared_ptr<const Image> input = _raw_frame;
  
        pair<string, string> const s = Filter::ffmpeg_strings (_film->filters());
        if (!s.second.empty ()) {
                   when working out the scale that we are applying.
                */
  
 -              Size const cropped_size = _film->cropped_size (_film->size ());
 +              Size const cropped_size = _film->cropped_size (_film->video_size ());
  
                Rect tx = subtitle_transformed_area (
                        float (_film_size.width) / cropped_size.width,
  void
  FilmViewer::calculate_sizes ()
  {
 -      if (!_film) {
 +      if (!_film || !_player) {
                return;
        }
  
@@@ -385,14 -393,14 +385,14 @@@ FilmViewer::check_play_state (
        }
        
        if (_play_button->GetValue()) {
 -              _timer.Start (1000 / _film->source_frame_rate());
 +              _timer.Start (1000 / _film->video_frame_rate());
        } else {
                _timer.Stop ();
        }
  }
  
  void
- FilmViewer::process_video (shared_ptr<Image> image, bool, shared_ptr<Subtitle> sub, double t)
+ FilmViewer::process_video (shared_ptr<const Image> image, bool, shared_ptr<Subtitle> sub, double t)
  {
        _raw_frame = image;
        _raw_sub = sub;
  
        _got_frame = true;
  
 -      double const fps = _decoders.video->frames_per_second ();
 +      double const fps = _film->video_frame_rate ();
        _frame->SetLabel (wxString::Format (wxT("%d"), int (rint (t * fps))));
  
        double w = t;
        _timecode->SetLabel (wxString::Format (wxT("%02d:%02d:%02d:%02d"), h, m, s, f));
  }
  
 +/** Get a new _raw_frame from the decoder and then do
 + *  raw_to_display ().
 + */
  void
  FilmViewer::get_frame ()
  {
        /* Clear our raw frame in case we don't get a new one */
        _raw_frame.reset ();
  
 -      if (_decoders.video == 0) {
 +      if (!_player) {
                _display_frame.reset ();
                return;
        }
 -      
 +
        try {
                _got_frame = false;
                while (!_got_frame) {
 -                      if (_decoders.video->pass ()) {
 +                      if (_player->pass ()) {
                                /* We didn't get a frame before the decoder gave up,
                                   so clear our display frame.
                                */
@@@ -467,24 -472,14 +467,24 @@@ FilmViewer::active_jobs_changed (bool a
        _play_button->Enable (!a);
  }
  
 +void
 +FilmViewer::film_content_changed (weak_ptr<Content>, int p)
 +{
 +      if (p == VideoContentProperty::VIDEO_LENGTH) {
 +              /* Force an update to our frame */
 +              wxScrollEvent ev;
 +              slider_moved (ev);
 +      }
 +}
 +
  void
  FilmViewer::back_clicked (wxCommandEvent &)
  {
 -      if (!_decoders.video) {
 +      if (!_player) {
                return;
        }
        
 -      _decoders.video->seek_back ();
 +      _player->seek_back ();
        get_frame ();
        _panel->Refresh ();
        _panel->Update ();
  void
  FilmViewer::forward_clicked (wxCommandEvent &)
  {
 -      if (!_decoders.video) {
 +      if (!_player) {
                return;
        }
  
 -      _decoders.video->seek_forward ();
 +      _player->seek_forward ();
        get_frame ();
        _panel->Refresh ();
        _panel->Update ();
diff --combined src/wx/film_viewer.h
index 814a095af374753ac17a596651e9397211b0b5e0,ed5874fbcc6f945d6285db27bbe74801998fb893..02d862ca0c42472dd8cefb6de594b116725e6a68
@@@ -23,6 -23,7 +23,6 @@@
  
  #include <wx/wx.h>
  #include "lib/film.h"
 -#include "lib/decoder_factory.h"
  
  class wxToggleButton;
  class FFmpegPlayer;
@@@ -32,25 -33,6 +32,25 @@@ class Subtitle
  
  /** @class FilmViewer
   *  @brief A wx widget to view a preview of a Film.
 + *
 + *  The film takes the following path through the viewer:
 + *
 + *  1.  get_frame() asks our _player to decode some data.  If it does, process_video()
 + *      will be called.
 + *
 + *  2.  process_video() takes the image and subtitle from the decoder (_raw_frame and _raw_sub)
 + *      and calls raw_to_display().
 + * 
 + *  3.  raw_to_display() copies _raw_frame to _display_frame, processing it and scaling it.
 + *
 + *  4.  calling _panel->Refresh() and _panel->Update() results in paint_panel() being called;
 + *      this creates frame_bitmap from _display_frame and blits it to the display.  It also
 + *      blits the subtitle, if required.
 + *
 + * update_from_decoder() asks the player to re-emit its current frame on the next pass(), and then
 + * starts from step #1.
 + *
 + * update_from_raw() starts at step #3, then calls _panel->Refresh and _panel->Update.
   */
  class FilmViewer : public wxPanel
  {
@@@ -61,17 -43,16 +61,17 @@@ public
  
  private:
        void film_changed (Film::Property);
 +      void film_content_changed (boost::weak_ptr<Content>, int);
        void paint_panel (wxPaintEvent &);
        void panel_sized (wxSizeEvent &);
        void slider_moved (wxScrollEvent &);
        void play_clicked (wxCommandEvent &);
        void timer (wxTimerEvent &);
-       void process_video (boost::shared_ptr<Image>, bool, boost::shared_ptr<Subtitle>, double);
+       void process_video (boost::shared_ptr<const Image>, bool, boost::shared_ptr<Subtitle>, double);
        void calculate_sizes ();
        void check_play_state ();
        void update_from_raw ();
 -      void decoder_changed ();
 +      void update_from_decoder ();
        void raw_to_display ();
        void get_frame ();
        void active_jobs_changed (bool);
@@@ -79,7 -60,6 +79,7 @@@
        void forward_clicked (wxCommandEvent &);
  
        boost::shared_ptr<Film> _film;
 +      boost::shared_ptr<Player> _player;
  
        wxSizer* _v_sizer;
        wxPanel* _panel;
        wxToggleButton* _play_button;
        wxTimer _timer;
  
-       boost::shared_ptr<Image> _raw_frame;
 -      Decoders _decoders;
+       boost::shared_ptr<const Image> _raw_frame;
        boost::shared_ptr<Subtitle> _raw_sub;
-       boost::shared_ptr<Image> _display_frame;
+       boost::shared_ptr<const Image> _display_frame;
        /* The x offset at which we display the actual film content; this corresponds
           to the film's padding converted to our coordinates.
        */
diff --combined src/wx/po/es_ES.po
index abb6b780f17b42fd9547d2cc179b35ce1c66dbb5,56c0856bdd20f4b7245470ce3be9d32e86864424..a193325e6c09ad55d08e2602b90ff4a875d114a2
@@@ -5,9 -5,9 +5,9 @@@
  #
  msgid ""
  msgstr ""
 -"Project-Id-Version: libdvdomatic-wx\n"
 +"Project-Id-Version: libdcpomatic-wx\n"
  "Report-Msgid-Bugs-To: \n"
- "POT-Creation-Date: 2013-04-09 11:14+0100\n"
+ "POT-Creation-Date: 2013-04-22 15:06+0100\n"
  "PO-Revision-Date: 2013-04-02 19:08-0500\n"
  "Last-Translator: Manuel AC <manuel.acevedo@civantos.>\n"
  "Language-Team: Manuel AC <manuel.acevedo@civantos.com>\n"
  "Content-Transfer-Encoding: 8bit\n"
  "X-Generator: Poedit 1.5.5\n"
  
- #: src/wx/film_editor.cc:445
+ #: src/wx/film_editor.cc:449
  msgid "%"
  msgstr "%"
  
  #: src/wx/config_dialog.cc:61
 -msgid "(restart DVD-o-matic to see language changes)"
 +msgid "(restart DCP-o-matic to see language changes)"
  msgstr ""
  
- #: src/wx/film_editor.cc:1269
+ #: src/wx/film_editor.cc:1276
  msgid "1 channel"
  msgstr "1 canal"
  
@@@ -41,11 -41,11 +41,11 @@@ msgstr "Añadir
  msgid "Audio"
  msgstr "Audio"
  
- #: src/wx/film_editor.cc:381
+ #: src/wx/film_editor.cc:385
  msgid "Audio Delay"
  msgstr "Retardo del audio"
  
- #: src/wx/film_editor.cc:369
+ #: src/wx/film_editor.cc:373
  msgid "Audio Gain"
  msgstr "Ganancia del audio"
  
@@@ -53,7 -53,7 +53,7 @@@
  msgid "Audio Language (e.g. EN)"
  msgstr "Idioma del audio (ej. ES)"
  
- #: src/wx/film_editor.cc:820
+ #: src/wx/film_editor.cc:824
  #, c-format
  msgid "Audio will be resampled from %dHz to %dHz\n"
  msgstr ""
@@@ -63,7 -63,7 +63,7 @@@
  msgid "Bad setting for %s (%s)"
  msgstr "Configuración erronea para %s (%s)"
  
- #: src/wx/film_editor.cc:288
+ #: src/wx/film_editor.cc:292
  msgid "Bottom crop"
  msgstr "Recortar abajo"
  
@@@ -75,7 -75,7 +75,7 @@@ msgstr "Explorar...
  msgid "But I have to use fader"
  msgstr "pero tengo que usar el fader a"
  
- #: src/wx/film_editor.cc:374
+ #: src/wx/film_editor.cc:378
  msgid "Calculate..."
  msgstr "Calcular..."
  
@@@ -87,7 -87,7 +87,7 @@@ msgstr "
  msgid "Channels"
  msgstr "Canales"
  
- #: src/wx/film_editor.cc:325
+ #: src/wx/film_editor.cc:329
  msgid "Colour look-up table"
  msgstr "Tabla de referencia de colores"
  
@@@ -99,7 -99,7 +99,7 @@@ msgstr "Contenido
  msgid "Content Type"
  msgstr "Tipo de contenido"
  
- #: src/wx/film_viewer.cc:415
+ #: src/wx/film_viewer.cc:451
  #, c-format
  msgid "Could not decode video for view (%s)"
  msgstr "No se pudo decodificar el vídeo para mostrarlo (%s)"
  msgid "Could not make DCP: %s"
  msgstr "No se pudo crear el DCP: %s"
  
- #: src/wx/film_viewer.cc:107
+ #: src/wx/film_viewer.cc:125
  #, c-format
  msgid "Could not open content file (%s)"
  msgstr "No se pudo abrir el fichero (%s)"
  
- #: src/wx/film_editor.cc:509
+ #: src/wx/film_editor.cc:513
  #, c-format
  msgid "Could not set content: %s"
  msgstr "No se pudo establecer el contenido: %s"
  msgid "Create in folder"
  msgstr "Crear en carpeta"
  
- #: src/wx/film_editor.cc:1363
+ #: src/wx/film_editor.cc:1371
  #, c-format
  msgid "Cropped to %dx%d (%.2f:1)\n"
  msgstr ""
@@@ -141,17 -141,17 +141,17 @@@ msgid "DCP Name
  msgstr "Nombre DCP"
  
  #: src/wx/wx_util.cc:61
 -msgid "DVD-o-matic"
 -msgstr "DVD-o-matic"
 +msgid "DCP-o-matic"
 +msgstr "DCP-o-matic"
  
  #: src/wx/config_dialog.cc:44
 -msgid "DVD-o-matic Preferences"
 -msgstr "Preferencias DVD-o-matic"
 +msgid "DCP-o-matic Preferences"
 +msgstr "Preferencias DCP-o-matic"
  
  #: src/wx/audio_dialog.cc:101
  #, fuzzy, c-format
 -msgid "DVD-o-matic audio - %s"
 -msgstr "Audio DVD-o-matic - %1"
 +msgid "DCP-o-matic audio - %s"
 +msgstr "Audio DCP-o-matic - %1"
  
  #: src/wx/config_dialog.cc:102
  msgid "Default DCI name details"
@@@ -178,7 -178,7 +178,7 @@@ msgid "Edit
  msgstr "Editar"
  
  #: src/wx/config_dialog.cc:103 src/wx/config_dialog.cc:122
- #: src/wx/film_editor.cc:308
+ #: src/wx/film_editor.cc:312
  msgid "Edit..."
  msgstr "Editar..."
  
  msgid "Encoding Servers"
  msgstr "Servidores de codificación"
  
- #: src/wx/film_editor.cc:176
+ #: src/wx/film_editor.cc:171
  msgid "End"
  msgstr "Fin"
  
@@@ -206,11 -206,11 +206,11 @@@ msgstr "Propiedades de la película
  msgid "Film name"
  msgstr "Nombre de la película"
  
- #: src/wx/film_editor.cc:303 src/wx/filter_dialog.cc:32
+ #: src/wx/film_editor.cc:307 src/wx/filter_dialog.cc:32
  msgid "Filters"
  msgstr "Filtros"
  
- #: src/wx/film_editor.cc:268
+ #: src/wx/film_editor.cc:272
  msgid "Format"
  msgstr "Formato"
  
@@@ -234,7 -234,7 +234,7 @@@ msgstr "Gb
  msgid "Host name or IP address"
  msgstr "Nombre o dirección IP"
  
- #: src/wx/film_editor.cc:1273
+ #: src/wx/film_editor.cc:1280
  msgid "Hz"
  msgstr "Hz"
  
@@@ -246,19 -246,19 +246,19 @@@ msgstr "Quiero reproducir con el fader 
  msgid "IP address"
  msgstr "Dirección IP"
  
- #: src/wx/film_editor.cc:335
+ #: src/wx/film_editor.cc:339
  msgid "JPEG2000 bandwidth"
  msgstr "Ancho de banda JPEG2000"
  
- #: src/wx/film_editor.cc:273
+ #: src/wx/film_editor.cc:277
  msgid "Left crop"
  msgstr "Recorte izquierda"
  
- #: src/wx/film_editor.cc:164
+ #: src/wx/film_editor.cc:159
  msgid "Length"
  msgstr "Longitud"
  
- #: src/wx/film_editor.cc:339
+ #: src/wx/film_editor.cc:343
  msgid "MBps"
  msgstr "MBps"
  
@@@ -274,7 -274,7 +274,7 @@@ msgstr "Nombre
  msgid "New Film"
  msgstr "Nueva película"
  
- #: src/wx/film_editor.cc:305 src/wx/film_editor.cc:667
+ #: src/wx/film_editor.cc:309 src/wx/film_editor.cc:671
  msgid "None"
  msgstr "Ninguno"
  
  msgid "Original Frame Rate"
  msgstr "Velocidad original"
  
- #: src/wx/film_editor.cc:159
- msgid "Original Size"
- msgstr "Tamaño original"
- #: src/wx/film_editor.cc:1352
+ #: src/wx/film_editor.cc:1360
  #, c-format
  msgid "Original video is %dx%d (%.2f:1)\n"
  msgstr ""
  msgid "Package Type (e.g. OV)"
  msgstr "Tipo de paquete (ej. OV)"
  
- #: src/wx/film_editor.cc:1384
+ #: src/wx/film_editor.cc:1392
  #, c-format
  msgid "Padded with black to %dx%d (%.2f:1)\n"
  msgstr ""
  msgid "Peak"
  msgstr "Pico"
  
- #: src/wx/film_viewer.cc:54
+ #: src/wx/film_viewer.cc:58
  msgid "Play"
  msgstr "Reproducir"
  
@@@ -332,7 -328,7 +328,7 @@@ msgstr "Escalador de referencia para A/
  msgid "Remove"
  msgstr "Quitar"
  
- #: src/wx/film_editor.cc:278
+ #: src/wx/film_editor.cc:282
  msgid "Right crop"
  msgstr "Recorte derecha"
  
  msgid "Running"
  msgstr "Ejecutando"
  
- #: src/wx/film_editor.cc:1376
+ #: src/wx/film_editor.cc:1384
  #, c-format
  msgid "Scaled to %dx%d (%.2f:1)\n"
  msgstr ""
  
- #: src/wx/film_editor.cc:315
+ #: src/wx/film_editor.cc:319
  msgid "Scaler"
  msgstr "Escalador"
  
- #: src/wx/film_editor.cc:407
+ #: src/wx/film_editor.cc:411
  msgid "Select Audio File"
  msgstr "Seleccionar fichero de audio"
  
@@@ -365,7 -361,7 +361,7 @@@ msgstr "Servidor
  msgid "Set language"
  msgstr ""
  
- #: src/wx/film_editor.cc:364
+ #: src/wx/film_editor.cc:368
  msgid "Show Audio..."
  msgstr "Mostrar audio..."
  
  msgid "Smoothing"
  msgstr "Suavizado"
  
- #: src/wx/film_editor.cc:173
+ #: src/wx/film_editor.cc:168
  msgid "Start"
  msgstr "Inicio"
  
@@@ -385,11 -381,11 +381,11 @@@ msgstr "Estudio (ej. TCF)
  msgid "Subtitle Language (e.g. FR)"
  msgstr "Idioma del subtítulo (ej. EN)"
  
- #: src/wx/film_editor.cc:432
+ #: src/wx/film_editor.cc:436
  msgid "Subtitle Offset"
  msgstr "Desplazamiento del subtítulo"
  
- #: src/wx/film_editor.cc:441
+ #: src/wx/film_editor.cc:445
  msgid "Subtitle Scale"
  msgstr "Escala del subtítulo"
  
@@@ -433,14 -429,19 +429,19 @@@ msgstr "Hilos a utilizar para la codifi
  msgid "Time"
  msgstr "Tiempo"
  
- #: src/wx/film_editor.cc:283
+ #: src/wx/film_editor.cc:287
  msgid "Top crop"
  msgstr "Recortar arriba"
  
- #: src/wx/film_editor.cc:171
+ #: src/wx/film_editor.cc:166
  msgid "Trim frames"
  msgstr "Recortar fotogramas"
  
+ #: src/wx/film_editor.cc:179
+ #, fuzzy
+ msgid "Trim method"
+ msgstr "Recortar fotogramas"
  #: src/wx/film_editor.cc:125
  msgid "Trust content's header"
  msgstr "Confiar en la cabecera del contenido"
@@@ -457,11 -458,11 +458,11 @@@ msgstr "Usar el nombre DCI
  msgid "Use best"
  msgstr "Usar la mejor"
  
- #: src/wx/film_editor.cc:391
+ #: src/wx/film_editor.cc:395
  msgid "Use content's audio"
  msgstr "Usar el audio del contenido"
  
- #: src/wx/film_editor.cc:401
+ #: src/wx/film_editor.cc:405
  msgid "Use external audio"
  msgstr "Usar audio externo"
  
  msgid "Video"
  msgstr "Vídeo"
  
- #: src/wx/film_editor.cc:424
+ #: src/wx/film_editor.cc:428
  msgid "With Subtitles"
  msgstr "Con subtítulos"
  
- #: src/wx/film_editor.cc:1271
+ #: src/wx/film_editor.cc:1278
  msgid "channels"
  msgstr "canales"
  
  msgid "counting..."
  msgstr "contando..."
  
- #: src/wx/film_editor.cc:373
+ #: src/wx/film_editor.cc:377
  msgid "dB"
  msgstr "dB"
  
- #: src/wx/film_editor.cc:696 src/wx/film_editor.cc:699
+ #: src/wx/film_editor.cc:212
+ msgid "encode all frames and play the subset"
+ msgstr ""
+ #: src/wx/film_editor.cc:213
+ msgid "encode only the subset"
+ msgstr ""
+ #: src/wx/film_editor.cc:694 src/wx/film_editor.cc:697
  msgid "frames"
  msgstr "fotogramas"
  
  #. / TRANSLATORS: this is an abbreviation for milliseconds, the unit of time
- #: src/wx/film_editor.cc:386
+ #: src/wx/film_editor.cc:390
  msgid "ms"
  msgstr "ms"
  
- #: src/wx/film_editor.cc:436
+ #: src/wx/film_editor.cc:440
  msgid "pixels"
  msgstr ""
  
@@@ -506,3 -515,6 +515,6 @@@ msgstr "s
  #: src/wx/properties_dialog.cc:62 src/wx/properties_dialog.cc:63
  msgid "unknown"
  msgstr "desconocido"
+ #~ msgid "Original Size"
+ #~ msgstr "Tamaño original"
diff --combined src/wx/po/fr_FR.po
index 2aac7114cb3ece6297a2365fdd9d0296ec7931f0,c7ef31f5ab7fd05fd8579a5ac19e0e0ac24d6441..36ae4a9252727678ed8e53a57c20177d451764c1
@@@ -5,9 -5,9 +5,9 @@@
  #
  msgid ""
  msgstr ""
 -"Project-Id-Version: DVD-o-matic FRENCH\n"
 +"Project-Id-Version: DCP-o-matic FRENCH\n"
  "Report-Msgid-Bugs-To: \n"
- "POT-Creation-Date: 2013-04-09 11:14+0100\n"
+ "POT-Creation-Date: 2013-04-22 15:06+0100\n"
  "PO-Revision-Date: 2013-03-20 00:34+0100\n"
  "Last-Translator: FreeDCP.net <freedcp.net@gmail.com>\n"
  "Language-Team: \n"
  "Content-Type: text/plain; charset=UTF-8\n"
  "Content-Transfer-Encoding: 8bit\n"
  
- #: src/wx/film_editor.cc:445
+ #: src/wx/film_editor.cc:449
  msgid "%"
  msgstr "%"
  
  #: src/wx/config_dialog.cc:61
 -msgid "(restart DVD-o-matic to see language changes)"
 +msgid "(restart DCP-o-matic to see language changes)"
  msgstr ""
  
- #: src/wx/film_editor.cc:1269
+ #: src/wx/film_editor.cc:1276
  msgid "1 channel"
  msgstr "1 canal"
  
@@@ -40,11 -40,11 +40,11 @@@ msgstr "Ajouter
  msgid "Audio"
  msgstr "Audio"
  
- #: src/wx/film_editor.cc:381
+ #: src/wx/film_editor.cc:385
  msgid "Audio Delay"
  msgstr "Délai audio"
  
- #: src/wx/film_editor.cc:369
+ #: src/wx/film_editor.cc:373
  msgid "Audio Gain"
  msgstr "Gain audio"
  
@@@ -52,7 -52,7 +52,7 @@@
  msgid "Audio Language (e.g. EN)"
  msgstr "Langue audio (ex. FR)"
  
- #: src/wx/film_editor.cc:820
+ #: src/wx/film_editor.cc:824
  #, c-format
  msgid "Audio will be resampled from %dHz to %dHz\n"
  msgstr ""
@@@ -62,7 -62,7 +62,7 @@@
  msgid "Bad setting for %s (%s)"
  msgstr "Mauvais paramètre pour %s (%s)"
  
- #: src/wx/film_editor.cc:288
+ #: src/wx/film_editor.cc:292
  msgid "Bottom crop"
  msgstr "Découpe bas"
  
@@@ -74,7 -74,7 +74,7 @@@ msgstr "Parcourir...
  msgid "But I have to use fader"
  msgstr "Je souhaite utiliser ce volume"
  
- #: src/wx/film_editor.cc:374
+ #: src/wx/film_editor.cc:378
  msgid "Calculate..."
  msgstr "Calcul..."
  
@@@ -86,7 -86,7 +86,7 @@@ msgstr "Annuler
  msgid "Channels"
  msgstr "Canaux"
  
- #: src/wx/film_editor.cc:325
+ #: src/wx/film_editor.cc:329
  msgid "Colour look-up table"
  msgstr "Espace colorimétrique"
  
@@@ -98,7 -98,7 +98,7 @@@ msgstr "Contenu
  msgid "Content Type"
  msgstr "Type de Contenu"
  
- #: src/wx/film_viewer.cc:415
+ #: src/wx/film_viewer.cc:451
  #, c-format
  msgid "Could not decode video for view (%s)"
  msgstr "Décodage de la vidéo pour visualisation impossible (%s)"
  msgid "Could not make DCP: %s"
  msgstr "Impossible de créer le DCP : %s"
  
- #: src/wx/film_viewer.cc:107
+ #: src/wx/film_viewer.cc:125
  #, c-format
  msgid "Could not open content file (%s)"
  msgstr "Ouverture du contenu impossible (%s)"
  
- #: src/wx/film_editor.cc:509
+ #: src/wx/film_editor.cc:513
  #, c-format
  msgid "Could not set content: %s"
  msgstr "Sélectionner du contenu impossible : %s"
  msgid "Create in folder"
  msgstr "Créer dans le dossier"
  
- #: src/wx/film_editor.cc:1363
+ #: src/wx/film_editor.cc:1371
  #, c-format
  msgid "Cropped to %dx%d (%.2f:1)\n"
  msgstr ""
@@@ -140,17 -140,17 +140,17 @@@ msgid "DCP Name
  msgstr "Nom du DCP"
  
  #: src/wx/wx_util.cc:61
 -msgid "DVD-o-matic"
 -msgstr "DVD-o-matic"
 +msgid "DCP-o-matic"
 +msgstr "DCP-o-matic"
  
  #: src/wx/config_dialog.cc:44
 -msgid "DVD-o-matic Preferences"
 -msgstr "Préférences DVD-o-matic"
 +msgid "DCP-o-matic Preferences"
 +msgstr "Préférences DCP-o-matic"
  
  #: src/wx/audio_dialog.cc:101
  #, c-format
 -msgid "DVD-o-matic audio - %s"
 -msgstr "Son DVD-o-matic  - %s"
 +msgid "DCP-o-matic audio - %s"
 +msgstr "Son DCP-o-matic  - %s"
  
  #: src/wx/config_dialog.cc:102
  msgid "Default DCI name details"
@@@ -177,7 -177,7 +177,7 @@@ msgid "Edit
  msgstr "Édition"
  
  #: src/wx/config_dialog.cc:103 src/wx/config_dialog.cc:122
- #: src/wx/film_editor.cc:308
+ #: src/wx/film_editor.cc:312
  msgid "Edit..."
  msgstr "Éditer..."
  
  msgid "Encoding Servers"
  msgstr "Serveurs d'encodage"
  
- #: src/wx/film_editor.cc:176
+ #: src/wx/film_editor.cc:171
  msgid "End"
  msgstr "Fin"
  
@@@ -205,11 -205,11 +205,11 @@@ msgstr "Propriétés du film
  msgid "Film name"
  msgstr "Nom du Film"
  
- #: src/wx/film_editor.cc:303 src/wx/filter_dialog.cc:32
+ #: src/wx/film_editor.cc:307 src/wx/filter_dialog.cc:32
  msgid "Filters"
  msgstr "Filtres"
  
- #: src/wx/film_editor.cc:268
+ #: src/wx/film_editor.cc:272
  msgid "Format"
  msgstr "Format"
  
@@@ -233,7 -233,7 +233,7 @@@ msgstr "Gb
  msgid "Host name or IP address"
  msgstr "Nom de l'hôte ou adresse IP"
  
- #: src/wx/film_editor.cc:1273
+ #: src/wx/film_editor.cc:1280
  msgid "Hz"
  msgstr "Hz"
  
@@@ -245,19 -245,19 +245,19 @@@ msgstr "Je veux le jouer à ce volume
  msgid "IP address"
  msgstr "Adresse IP"
  
- #: src/wx/film_editor.cc:335
+ #: src/wx/film_editor.cc:339
  msgid "JPEG2000 bandwidth"
  msgstr "Qualité JPEG2000"
  
- #: src/wx/film_editor.cc:273
+ #: src/wx/film_editor.cc:277
  msgid "Left crop"
  msgstr "Découpe gauche"
  
- #: src/wx/film_editor.cc:164
+ #: src/wx/film_editor.cc:159
  msgid "Length"
  msgstr "Longueur / durée"
  
- #: src/wx/film_editor.cc:339
+ #: src/wx/film_editor.cc:343
  msgid "MBps"
  msgstr "MBps"
  
@@@ -273,7 -273,7 +273,7 @@@ msgstr "Nom
  msgid "New Film"
  msgstr "Nouveau Film"
  
- #: src/wx/film_editor.cc:305 src/wx/film_editor.cc:667
+ #: src/wx/film_editor.cc:309 src/wx/film_editor.cc:671
  msgid "None"
  msgstr "Aucun"
  
  msgid "Original Frame Rate"
  msgstr "Cadence d'images originale"
  
- #: src/wx/film_editor.cc:159
- msgid "Original Size"
- msgstr "Taille Originale"
- #: src/wx/film_editor.cc:1352
+ #: src/wx/film_editor.cc:1360
  #, c-format
  msgid "Original video is %dx%d (%.2f:1)\n"
  msgstr ""
  msgid "Package Type (e.g. OV)"
  msgstr "Type de paquet (ex. OV)"
  
- #: src/wx/film_editor.cc:1384
+ #: src/wx/film_editor.cc:1392
  #, c-format
  msgid "Padded with black to %dx%d (%.2f:1)\n"
  msgstr ""
  msgid "Peak"
  msgstr "Crête"
  
- #: src/wx/film_viewer.cc:54
+ #: src/wx/film_viewer.cc:58
  msgid "Play"
  msgstr "Lecture"
  
@@@ -331,7 -327,7 +327,7 @@@ msgstr "Échelle de référence pour A/
  msgid "Remove"
  msgstr "Supprimer"
  
- #: src/wx/film_editor.cc:278
+ #: src/wx/film_editor.cc:282
  msgid "Right crop"
  msgstr "Découpe droite"
  
  msgid "Running"
  msgstr "Progression"
  
- #: src/wx/film_editor.cc:1376
+ #: src/wx/film_editor.cc:1384
  #, c-format
  msgid "Scaled to %dx%d (%.2f:1)\n"
  msgstr ""
  
- #: src/wx/film_editor.cc:315
+ #: src/wx/film_editor.cc:319
  msgid "Scaler"
  msgstr "Mise à l'échelle"
  
- #: src/wx/film_editor.cc:407
+ #: src/wx/film_editor.cc:411
  msgid "Select Audio File"
  msgstr "Sélectionner le fichier son"
  
@@@ -364,7 -360,7 +360,7 @@@ msgstr "Serveur
  msgid "Set language"
  msgstr ""
  
- #: src/wx/film_editor.cc:364
+ #: src/wx/film_editor.cc:368
  msgid "Show Audio..."
  msgstr "Analyser le son..."
  
  msgid "Smoothing"
  msgstr "Lissage"
  
- #: src/wx/film_editor.cc:173
+ #: src/wx/film_editor.cc:168
  msgid "Start"
  msgstr "Début"
  
@@@ -384,11 -380,11 +380,11 @@@ msgstr "Studio (ex. TCF)
  msgid "Subtitle Language (e.g. FR)"
  msgstr "Langue de sous-titres (ex. FR)"
  
- #: src/wx/film_editor.cc:432
+ #: src/wx/film_editor.cc:436
  msgid "Subtitle Offset"
  msgstr "Décalage du sous-titre"
  
- #: src/wx/film_editor.cc:441
+ #: src/wx/film_editor.cc:445
  msgid "Subtitle Scale"
  msgstr "Taille du sous-titre"
  
@@@ -432,14 -428,18 +428,18 @@@ msgstr "Nombre de processus à utilise
  msgid "Time"
  msgstr "Durée"
  
- #: src/wx/film_editor.cc:283
+ #: src/wx/film_editor.cc:287
  msgid "Top crop"
  msgstr "Découpe haut"
  
- #: src/wx/film_editor.cc:171
+ #: src/wx/film_editor.cc:166
  msgid "Trim frames"
  msgstr "Images coupées"
  
+ #: src/wx/film_editor.cc:179
+ msgid "Trim method"
+ msgstr "Méthod de découpage"
  #: src/wx/film_editor.cc:125
  msgid "Trust content's header"
  msgstr "Faire confiance à l'en-tête"
@@@ -456,11 -456,11 +456,11 @@@ msgstr "Utiliser le nom DCI
  msgid "Use best"
  msgstr "Automatique"
  
- #: src/wx/film_editor.cc:391
+ #: src/wx/film_editor.cc:395
  msgid "Use content's audio"
  msgstr "Utiliser le son intégré"
  
- #: src/wx/film_editor.cc:401
+ #: src/wx/film_editor.cc:405
  msgid "Use external audio"
  msgstr "Utiliser une source audio externe"
  
  msgid "Video"
  msgstr "Vidéo"
  
- #: src/wx/film_editor.cc:424
+ #: src/wx/film_editor.cc:428
  msgid "With Subtitles"
  msgstr "Avec sous-titres"
  
- #: src/wx/film_editor.cc:1271
+ #: src/wx/film_editor.cc:1278
  msgid "channels"
  msgstr "canaux"
  
  msgid "counting..."
  msgstr "calcul..."
  
- #: src/wx/film_editor.cc:373
+ #: src/wx/film_editor.cc:377
  msgid "dB"
  msgstr "dB"
  
- #: src/wx/film_editor.cc:696 src/wx/film_editor.cc:699
+ #: src/wx/film_editor.cc:212
+ msgid "encode all frames and play the subset"
+ msgstr "encoder toutes les images mais lire seulement la sélection"
+ #: src/wx/film_editor.cc:213
+ msgid "encode only the subset"
+ msgstr "encoder seulement la sélection"
+ #: src/wx/film_editor.cc:694 src/wx/film_editor.cc:697
  msgid "frames"
  msgstr "images"
  
  #. / TRANSLATORS: this is an abbreviation for milliseconds, the unit of time
- #: src/wx/film_editor.cc:386
+ #: src/wx/film_editor.cc:390
  msgid "ms"
  msgstr "ms"
  
- #: src/wx/film_editor.cc:436
+ #: src/wx/film_editor.cc:440
  msgid "pixels"
  msgstr ""
  
@@@ -505,3 -513,6 +513,6 @@@ msgstr "s
  #: src/wx/properties_dialog.cc:62 src/wx/properties_dialog.cc:63
  msgid "unknown"
  msgstr "inconnu"
+ #~ msgid "Original Size"
+ #~ msgstr "Taille Originale"
diff --combined src/wx/po/it_IT.po
index 7b06495e83959caddcc26491fc06aa905c72af7f,c730a7ff7c2256528588a48eef61c7717b2e9a0f..f53c40b977f8938fb4105c3dc4afeb382a80e4ba
@@@ -7,7 -7,7 +7,7 @@@ msgid "
  msgstr ""
  "Project-Id-Version: IT VERSION\n"
  "Report-Msgid-Bugs-To: \n"
- "POT-Creation-Date: 2013-04-09 11:14+0100\n"
+ "POT-Creation-Date: 2013-04-22 15:06+0100\n"
  "PO-Revision-Date: 2013-04-03 12:37+0100\n"
  "Last-Translator: Maci <macibro@gmail.com>\n"
  "Language-Team: \n"
  "Content-Transfer-Encoding: 8bit\n"
  "X-Generator: Poedit 1.5.5\n"
  
- #: src/wx/film_editor.cc:445
+ #: src/wx/film_editor.cc:449
  msgid "%"
  msgstr "%"
  
  #: src/wx/config_dialog.cc:61
 -msgid "(restart DVD-o-matic to see language changes)"
 -msgstr "(riavviare DVD-o-matic per vedere i cambiamenti di lingua)"
 +msgid "(restart DCP-o-matic to see language changes)"
 +msgstr "(riavviare DCP-o-matic per vedere i cambiamenti di lingua)"
  
- #: src/wx/film_editor.cc:1269
+ #: src/wx/film_editor.cc:1276
  msgid "1 channel"
  msgstr "Canale 1"
  
@@@ -41,11 -41,11 +41,11 @@@ msgstr "Aggiungi
  msgid "Audio"
  msgstr "Audio"
  
- #: src/wx/film_editor.cc:381
+ #: src/wx/film_editor.cc:385
  msgid "Audio Delay"
  msgstr "Ritardo dell'audio"
  
- #: src/wx/film_editor.cc:369
+ #: src/wx/film_editor.cc:373
  msgid "Audio Gain"
  msgstr "Guadagno dell'audio"
  
@@@ -53,7 -53,7 +53,7 @@@
  msgid "Audio Language (e.g. EN)"
  msgstr "Lingua dell'audio (es. EN)"
  
- #: src/wx/film_editor.cc:820
+ #: src/wx/film_editor.cc:824
  #, c-format
  msgid "Audio will be resampled from %dHz to %dHz\n"
  msgstr ""
@@@ -63,7 -63,7 +63,7 @@@
  msgid "Bad setting for %s (%s)"
  msgstr "Valore sbagliato per %s (%s)"
  
- #: src/wx/film_editor.cc:288
+ #: src/wx/film_editor.cc:292
  msgid "Bottom crop"
  msgstr "Taglio in basso"
  
@@@ -75,7 -75,7 +75,7 @@@ msgstr "Sfoglia...
  msgid "But I have to use fader"
  msgstr "Ma dovrò riprodurre con il fader a"
  
- #: src/wx/film_editor.cc:374
+ #: src/wx/film_editor.cc:378
  msgid "Calculate..."
  msgstr "Calcola..."
  
@@@ -87,7 -87,7 +87,7 @@@ msgstr "Annulla
  msgid "Channels"
  msgstr "Canali"
  
- #: src/wx/film_editor.cc:325
+ #: src/wx/film_editor.cc:329
  msgid "Colour look-up table"
  msgstr "Tabella per ricerca del colore"
  
@@@ -99,7 -99,7 +99,7 @@@ msgstr "Contenuto
  msgid "Content Type"
  msgstr "Tipo di contenuto"
  
- #: src/wx/film_viewer.cc:415
+ #: src/wx/film_viewer.cc:451
  #, c-format
  msgid "Could not decode video for view (%s)"
  msgstr "Non posso decodificare il video per guardarlo (%s)"
  msgid "Could not make DCP: %s"
  msgstr "Non posso creare il DCP: %s"
  
- #: src/wx/film_viewer.cc:107
+ #: src/wx/film_viewer.cc:125
  #, c-format
  msgid "Could not open content file (%s)"
  msgstr "Non posso aprire il file del contenuto (%s)"
  
- #: src/wx/film_editor.cc:509
+ #: src/wx/film_editor.cc:513
  #, c-format
  msgid "Could not set content: %s"
  msgstr "Non posso regolare il contenuto: %s"
  msgid "Create in folder"
  msgstr "Crea nella cartella"
  
- #: src/wx/film_editor.cc:1363
+ #: src/wx/film_editor.cc:1371
  #, c-format
  msgid "Cropped to %dx%d (%.2f:1)\n"
  msgstr ""
@@@ -141,17 -141,17 +141,17 @@@ msgid "DCP Name
  msgstr "Nome del DCP"
  
  #: src/wx/wx_util.cc:61
 -msgid "DVD-o-matic"
 -msgstr "DVD-o-matic"
 +msgid "DCP-o-matic"
 +msgstr "DCP-o-matic"
  
  #: src/wx/config_dialog.cc:44
 -msgid "DVD-o-matic Preferences"
 -msgstr "Preferenze DVD-o-matic"
 +msgid "DCP-o-matic Preferences"
 +msgstr "Preferenze DCP-o-matic"
  
  #: src/wx/audio_dialog.cc:101
  #, c-format
 -msgid "DVD-o-matic audio - %s"
 -msgstr "Audio DVD-o-matic - %s"
 +msgid "DCP-o-matic audio - %s"
 +msgstr "Audio DCP-o-matic - %s"
  
  #: src/wx/config_dialog.cc:102
  msgid "Default DCI name details"
@@@ -178,7 -178,7 +178,7 @@@ msgid "Edit
  msgstr "Modifica"
  
  #: src/wx/config_dialog.cc:103 src/wx/config_dialog.cc:122
- #: src/wx/film_editor.cc:308
+ #: src/wx/film_editor.cc:312
  msgid "Edit..."
  msgstr "Modifica..."
  
  msgid "Encoding Servers"
  msgstr "Servers di codifica"
  
- #: src/wx/film_editor.cc:176
+ #: src/wx/film_editor.cc:171
  msgid "End"
  msgstr "Fine"
  
@@@ -206,11 -206,11 +206,11 @@@ msgstr "Proprietà del film
  msgid "Film name"
  msgstr "Nome del film"
  
- #: src/wx/film_editor.cc:303 src/wx/filter_dialog.cc:32
+ #: src/wx/film_editor.cc:307 src/wx/filter_dialog.cc:32
  msgid "Filters"
  msgstr "Filtri"
  
- #: src/wx/film_editor.cc:268
+ #: src/wx/film_editor.cc:272
  msgid "Format"
  msgstr "Formato"
  
@@@ -234,7 -234,7 +234,7 @@@ msgstr "Gb
  msgid "Host name or IP address"
  msgstr "Nome dell'Host o indirizzo IP"
  
- #: src/wx/film_editor.cc:1273
+ #: src/wx/film_editor.cc:1280
  msgid "Hz"
  msgstr "Hz"
  
@@@ -246,19 -246,19 +246,19 @@@ msgstr "Sto usando il fader a
  msgid "IP address"
  msgstr "Indirizzo IP"
  
- #: src/wx/film_editor.cc:335
+ #: src/wx/film_editor.cc:339
  msgid "JPEG2000 bandwidth"
  msgstr "Banda passante JPEG2000"
  
- #: src/wx/film_editor.cc:273
+ #: src/wx/film_editor.cc:277
  msgid "Left crop"
  msgstr "Taglio a sinistra"
  
- #: src/wx/film_editor.cc:164
+ #: src/wx/film_editor.cc:159
  msgid "Length"
  msgstr "Lunghezza"
  
- #: src/wx/film_editor.cc:339
+ #: src/wx/film_editor.cc:343
  msgid "MBps"
  msgstr "MBps"
  
@@@ -274,7 -274,7 +274,7 @@@ msgstr "Nome
  msgid "New Film"
  msgstr "Nuovo Film"
  
- #: src/wx/film_editor.cc:305 src/wx/film_editor.cc:667
+ #: src/wx/film_editor.cc:309 src/wx/film_editor.cc:671
  msgid "None"
  msgstr "Nessuno"
  
  msgid "Original Frame Rate"
  msgstr "Frequenza fotogrammi originale"
  
- #: src/wx/film_editor.cc:159
- msgid "Original Size"
- msgstr "Dimensione Originale"
- #: src/wx/film_editor.cc:1352
+ #: src/wx/film_editor.cc:1360
  #, c-format
  msgid "Original video is %dx%d (%.2f:1)\n"
  msgstr ""
  msgid "Package Type (e.g. OV)"
  msgstr "Tipo di Package (es. OV)"
  
- #: src/wx/film_editor.cc:1384
+ #: src/wx/film_editor.cc:1392
  #, c-format
  msgid "Padded with black to %dx%d (%.2f:1)\n"
  msgstr ""
  msgid "Peak"
  msgstr "Picco"
  
- #: src/wx/film_viewer.cc:54
+ #: src/wx/film_viewer.cc:58
  msgid "Play"
  msgstr "Riproduci"
  
@@@ -332,7 -328,7 +328,7 @@@ msgstr "Scalatura di riferimento A/B
  msgid "Remove"
  msgstr "Rimuovi"
  
- #: src/wx/film_editor.cc:278
+ #: src/wx/film_editor.cc:282
  msgid "Right crop"
  msgstr "Taglio a destra"
  
  msgid "Running"
  msgstr "In corso"
  
- #: src/wx/film_editor.cc:1376
+ #: src/wx/film_editor.cc:1384
  #, c-format
  msgid "Scaled to %dx%d (%.2f:1)\n"
  msgstr ""
  
- #: src/wx/film_editor.cc:315
+ #: src/wx/film_editor.cc:319
  msgid "Scaler"
  msgstr "Scaler"
  
- #: src/wx/film_editor.cc:407
+ #: src/wx/film_editor.cc:411
  msgid "Select Audio File"
  msgstr "Seleziona file audio"
  
@@@ -365,7 -361,7 +361,7 @@@ msgstr "Server
  msgid "Set language"
  msgstr "Seleziona la lingua"
  
- #: src/wx/film_editor.cc:364
+ #: src/wx/film_editor.cc:368
  msgid "Show Audio..."
  msgstr "Mostra Audio..."
  
  msgid "Smoothing"
  msgstr "Levigatura"
  
- #: src/wx/film_editor.cc:173
+ #: src/wx/film_editor.cc:168
  msgid "Start"
  msgstr "Inizio"
  
@@@ -385,11 -381,11 +381,11 @@@ msgstr "Studio (es. TCF)
  msgid "Subtitle Language (e.g. FR)"
  msgstr "Lingua dei Sottotitoli (es. FR)"
  
- #: src/wx/film_editor.cc:432
+ #: src/wx/film_editor.cc:436
  msgid "Subtitle Offset"
  msgstr "Sfalsamento dei Sottotitoli"
  
- #: src/wx/film_editor.cc:441
+ #: src/wx/film_editor.cc:445
  msgid "Subtitle Scale"
  msgstr "Scala dei Sottotitoli"
  
@@@ -433,14 -429,19 +429,19 @@@ msgstr "Threads da usare per codificar
  msgid "Time"
  msgstr "Tempo"
  
- #: src/wx/film_editor.cc:283
+ #: src/wx/film_editor.cc:287
  msgid "Top crop"
  msgstr "Taglio in alto"
  
- #: src/wx/film_editor.cc:171
+ #: src/wx/film_editor.cc:166
  msgid "Trim frames"
  msgstr "Taglia fotogrammi"
  
+ #: src/wx/film_editor.cc:179
+ #, fuzzy
+ msgid "Trim method"
+ msgstr "Taglia fotogrammi"
  #: src/wx/film_editor.cc:125
  msgid "Trust content's header"
  msgstr "Conferma l'intestazione del contenuto"
@@@ -457,11 -458,11 +458,11 @@@ msgstr "Usa nome DCI
  msgid "Use best"
  msgstr "Usa la migliore"
  
- #: src/wx/film_editor.cc:391
+ #: src/wx/film_editor.cc:395
  msgid "Use content's audio"
  msgstr "Usa l'audio del contenuto"
  
- #: src/wx/film_editor.cc:401
+ #: src/wx/film_editor.cc:405
  msgid "Use external audio"
  msgstr "Usa l'audio esterno"
  
  msgid "Video"
  msgstr "Video"
  
- #: src/wx/film_editor.cc:424
+ #: src/wx/film_editor.cc:428
  msgid "With Subtitles"
  msgstr "Con Sottotitoli"
  
- #: src/wx/film_editor.cc:1271
+ #: src/wx/film_editor.cc:1278
  msgid "channels"
  msgstr "canali"
  
  msgid "counting..."
  msgstr "conteggio..."
  
- #: src/wx/film_editor.cc:373
+ #: src/wx/film_editor.cc:377
  msgid "dB"
  msgstr "dB"
  
- #: src/wx/film_editor.cc:696 src/wx/film_editor.cc:699
+ #: src/wx/film_editor.cc:212
+ msgid "encode all frames and play the subset"
+ msgstr ""
+ #: src/wx/film_editor.cc:213
+ msgid "encode only the subset"
+ msgstr ""
+ #: src/wx/film_editor.cc:694 src/wx/film_editor.cc:697
  msgid "frames"
  msgstr "fotogrammi"
  
  #. / TRANSLATORS: this is an abbreviation for milliseconds, the unit of time
- #: src/wx/film_editor.cc:386
+ #: src/wx/film_editor.cc:390
  msgid "ms"
  msgstr "ms"
  
- #: src/wx/film_editor.cc:436
+ #: src/wx/film_editor.cc:440
  msgid "pixels"
  msgstr ""
  
@@@ -506,3 -515,6 +515,6 @@@ msgstr "s
  #: src/wx/properties_dialog.cc:62 src/wx/properties_dialog.cc:63
  msgid "unknown"
  msgstr "sconosciuto"
+ #~ msgid "Original Size"
+ #~ msgstr "Dimensione Originale"
diff --combined src/wx/po/sv_SE.po
index 96fafadebf3be3f1b27b99ebe82bf08b1d41afcf,4127d77f872df6a830a49fff1cd5a8e25e9d32fc..9ed7ee2bee987350af06f5b6d379008fcbb41abd
@@@ -5,9 -5,9 +5,9 @@@
  #
  msgid ""
  msgstr ""
 -"Project-Id-Version: DVD-o-matic\n"
 +"Project-Id-Version: DCP-o-matic\n"
  "Report-Msgid-Bugs-To: \n"
- "POT-Creation-Date: 2013-04-09 11:14+0100\n"
+ "POT-Creation-Date: 2013-04-22 15:06+0100\n"
  "PO-Revision-Date: 2013-04-09 10:13+0100\n"
  "Last-Translator: Adam Klotblixt <adam.klotblixt@gmail.com>\n"
  "Language-Team: \n"
  "Content-Transfer-Encoding: 8bit\n"
  "X-Generator: Poedit 1.5.5\n"
  
- #: src/wx/film_editor.cc:445
+ #: src/wx/film_editor.cc:449
  msgid "%"
  msgstr "%"
  
  #: src/wx/config_dialog.cc:61
 -msgid "(restart DVD-o-matic to see language changes)"
 -msgstr "(starta om DVD-o-matic för att se språkändringar)"
 +msgid "(restart DCP-o-matic to see language changes)"
 +msgstr "(starta om DCP-o-matic för att se språkändringar)"
  
- #: src/wx/film_editor.cc:1269
+ #: src/wx/film_editor.cc:1276
  msgid "1 channel"
  msgstr "1 kanal"
  
@@@ -41,11 -41,11 +41,11 @@@ msgstr "Lägg till
  msgid "Audio"
  msgstr "Audio"
  
- #: src/wx/film_editor.cc:381
+ #: src/wx/film_editor.cc:385
  msgid "Audio Delay"
  msgstr "Audio Fördröjning"
  
- #: src/wx/film_editor.cc:369
+ #: src/wx/film_editor.cc:373
  msgid "Audio Gain"
  msgstr "Audio Förstärkning"
  
@@@ -53,7 -53,7 +53,7 @@@
  msgid "Audio Language (e.g. EN)"
  msgstr "Audio Språk (ex. SV)"
  
- #: src/wx/film_editor.cc:820
+ #: src/wx/film_editor.cc:824
  #, c-format
  msgid "Audio will be resampled from %dHz to %dHz\n"
  msgstr "Audio kommer att samplas om från %dHz till %dHz\n"
@@@ -63,7 -63,7 +63,7 @@@
  msgid "Bad setting for %s (%s)"
  msgstr "Felaktig inställning för %s (%s)"
  
- #: src/wx/film_editor.cc:288
+ #: src/wx/film_editor.cc:292
  msgid "Bottom crop"
  msgstr "Nedre beskärning"
  
@@@ -75,7 -75,7 +75,7 @@@ msgstr "Bläddra...
  msgid "But I have to use fader"
  msgstr "Men jag måste använda mixervolym"
  
- #: src/wx/film_editor.cc:374
+ #: src/wx/film_editor.cc:378
  msgid "Calculate..."
  msgstr "Beräkna..."
  
@@@ -87,7 -87,7 +87,7 @@@ msgstr "Avbryt
  msgid "Channels"
  msgstr "Kanaler"
  
- #: src/wx/film_editor.cc:325
+ #: src/wx/film_editor.cc:329
  msgid "Colour look-up table"
  msgstr "Färguppslagningstabell"
  
@@@ -99,7 -99,7 +99,7 @@@ msgstr "Innehåll
  msgid "Content Type"
  msgstr "Innehållstyp"
  
- #: src/wx/film_viewer.cc:415
+ #: src/wx/film_viewer.cc:451
  #, c-format
  msgid "Could not decode video for view (%s)"
  msgstr "Kunde inte avkoda video för visning (%s)"
  msgid "Could not make DCP: %s"
  msgstr "Kunde inte skapa DCP: %s"
  
- #: src/wx/film_viewer.cc:107
+ #: src/wx/film_viewer.cc:125
  #, c-format
  msgid "Could not open content file (%s)"
  msgstr "Kunde inte öppna innehållsfilen (%s)"
  
- #: src/wx/film_editor.cc:509
+ #: src/wx/film_editor.cc:513
  #, c-format
  msgid "Could not set content: %s"
  msgstr "Kunde inte fastställa innehåll: %s"
  msgid "Create in folder"
  msgstr "Skapa i katalog"
  
- #: src/wx/film_editor.cc:1363
+ #: src/wx/film_editor.cc:1371
  #, c-format
  msgid "Cropped to %dx%d (%.2f:1)\n"
  msgstr "Beskuren till %dx%d (%.2f:1)\n"
@@@ -141,17 -141,17 +141,17 @@@ msgid "DCP Name
  msgstr "DCP Namn"
  
  #: src/wx/wx_util.cc:61
 -msgid "DVD-o-matic"
 -msgstr "DVD-o-matic"
 +msgid "DCP-o-matic"
 +msgstr "DCP-o-matic"
  
  #: src/wx/config_dialog.cc:44
 -msgid "DVD-o-matic Preferences"
 -msgstr "DVD-o-matic Inställningar"
 +msgid "DCP-o-matic Preferences"
 +msgstr "DCP-o-matic Inställningar"
  
  #: src/wx/audio_dialog.cc:101
  #, c-format
 -msgid "DVD-o-matic audio - %s"
 -msgstr "DVD-o-matic audio - %s"
 +msgid "DCP-o-matic audio - %s"
 +msgstr "DCP-o-matic audio - %s"
  
  #: src/wx/config_dialog.cc:102
  msgid "Default DCI name details"
@@@ -178,7 -178,7 +178,7 @@@ msgid "Edit
  msgstr "Redigera"
  
  #: src/wx/config_dialog.cc:103 src/wx/config_dialog.cc:122
- #: src/wx/film_editor.cc:308
+ #: src/wx/film_editor.cc:312
  msgid "Edit..."
  msgstr "Redigera..."
  
  msgid "Encoding Servers"
  msgstr "Kodningsservrar"
  
- #: src/wx/film_editor.cc:176
+ #: src/wx/film_editor.cc:171
  msgid "End"
  msgstr "Slut"
  
@@@ -206,11 -206,11 +206,11 @@@ msgstr "Film Egenskaper
  msgid "Film name"
  msgstr "film namn"
  
- #: src/wx/film_editor.cc:303 src/wx/filter_dialog.cc:32
+ #: src/wx/film_editor.cc:307 src/wx/filter_dialog.cc:32
  msgid "Filters"
  msgstr "Filter"
  
- #: src/wx/film_editor.cc:268
+ #: src/wx/film_editor.cc:272
  msgid "Format"
  msgstr "Format"
  
@@@ -234,7 -234,7 +234,7 @@@ msgstr "Gb
  msgid "Host name or IP address"
  msgstr "Värd-namn eller IP-adress"
  
- #: src/wx/film_editor.cc:1273
+ #: src/wx/film_editor.cc:1280
  msgid "Hz"
  msgstr "Hz"
  
@@@ -246,19 -246,19 +246,19 @@@ msgstr "Jag vill spela upp detta med mi
  msgid "IP address"
  msgstr "IP-adress"
  
- #: src/wx/film_editor.cc:335
+ #: src/wx/film_editor.cc:339
  msgid "JPEG2000 bandwidth"
  msgstr "JPEG2000 bandbredd"
  
- #: src/wx/film_editor.cc:273
+ #: src/wx/film_editor.cc:277
  msgid "Left crop"
  msgstr "Vänster beskärning"
  
- #: src/wx/film_editor.cc:164
+ #: src/wx/film_editor.cc:159
  msgid "Length"
  msgstr "Längd"
  
- #: src/wx/film_editor.cc:339
+ #: src/wx/film_editor.cc:343
  msgid "MBps"
  msgstr "MBps"
  
@@@ -274,7 -274,7 +274,7 @@@ msgstr "Namn
  msgid "New Film"
  msgstr "Ny Film"
  
- #: src/wx/film_editor.cc:305 src/wx/film_editor.cc:667
+ #: src/wx/film_editor.cc:309 src/wx/film_editor.cc:671
  msgid "None"
  msgstr "Inget"
  
  msgid "Original Frame Rate"
  msgstr "Ursprunglig bildhastighet"
  
- #: src/wx/film_editor.cc:159
- msgid "Original Size"
- msgstr "Ursprunglig Storlek"
- #: src/wx/film_editor.cc:1352
+ #: src/wx/film_editor.cc:1360
  #, c-format
  msgid "Original video is %dx%d (%.2f:1)\n"
  msgstr "Original-videon är %dx%d (%.2f:1)\n"
  msgid "Package Type (e.g. OV)"
  msgstr "Förpackningstyp (ex. OV)"
  
- #: src/wx/film_editor.cc:1384
+ #: src/wx/film_editor.cc:1392
  #, c-format
  msgid "Padded with black to %dx%d (%.2f:1)\n"
  msgstr "Svarta kanter tillagda för %dx%d (%.2f:1)\n"
  msgid "Peak"
  msgstr "Topp"
  
- #: src/wx/film_viewer.cc:54
+ #: src/wx/film_viewer.cc:58
  msgid "Play"
  msgstr "Spela"
  
@@@ -332,7 -328,7 +328,7 @@@ msgstr "Referensomskalare för A/B
  msgid "Remove"
  msgstr "Ta bort"
  
- #: src/wx/film_editor.cc:278
+ #: src/wx/film_editor.cc:282
  msgid "Right crop"
  msgstr "Höger beskärning"
  
  msgid "Running"
  msgstr "Körs"
  
- #: src/wx/film_editor.cc:1376
+ #: src/wx/film_editor.cc:1384
  #, c-format
  msgid "Scaled to %dx%d (%.2f:1)\n"
  msgstr "Skalad till %dx%d (%.2f:1)\n"
  
- #: src/wx/film_editor.cc:315
+ #: src/wx/film_editor.cc:319
  msgid "Scaler"
  msgstr "Omskalare"
  
- #: src/wx/film_editor.cc:407
+ #: src/wx/film_editor.cc:411
  msgid "Select Audio File"
  msgstr "Välj audiofil"
  
@@@ -365,7 -361,7 +361,7 @@@ msgstr "Server
  msgid "Set language"
  msgstr "Välj språk"
  
- #: src/wx/film_editor.cc:364
+ #: src/wx/film_editor.cc:368
  msgid "Show Audio..."
  msgstr "Visa Audio..."
  
  msgid "Smoothing"
  msgstr "Utjämning"
  
- #: src/wx/film_editor.cc:173
+ #: src/wx/film_editor.cc:168
  msgid "Start"
  msgstr "Start"
  
@@@ -385,11 -381,11 +381,11 @@@ msgstr "Studio (ex. TCF)
  msgid "Subtitle Language (e.g. FR)"
  msgstr "Undertextspråk (ex. SV)"
  
- #: src/wx/film_editor.cc:432
+ #: src/wx/film_editor.cc:436
  msgid "Subtitle Offset"
  msgstr "Undertext Förskjutning"
  
- #: src/wx/film_editor.cc:441
+ #: src/wx/film_editor.cc:445
  msgid "Subtitle Scale"
  msgstr "Undertext Skalning"
  
@@@ -433,14 -429,19 +429,19 @@@ msgstr "Antal trådar att använda vid 
  msgid "Time"
  msgstr "Tid"
  
- #: src/wx/film_editor.cc:283
+ #: src/wx/film_editor.cc:287
  msgid "Top crop"
  msgstr "Övre beskärning"
  
- #: src/wx/film_editor.cc:171
+ #: src/wx/film_editor.cc:166
  msgid "Trim frames"
  msgstr "Skippa bilder"
  
+ #: src/wx/film_editor.cc:179
+ #, fuzzy
+ msgid "Trim method"
+ msgstr "Skippa bilder"
  #: src/wx/film_editor.cc:125
  msgid "Trust content's header"
  msgstr "Lita på källans information"
@@@ -457,11 -458,11 +458,11 @@@ msgstr "Använd DCI-namnet
  msgid "Use best"
  msgstr "Använd bästa"
  
- #: src/wx/film_editor.cc:391
+ #: src/wx/film_editor.cc:395
  msgid "Use content's audio"
  msgstr "Använd innehållets audio"
  
- #: src/wx/film_editor.cc:401
+ #: src/wx/film_editor.cc:405
  msgid "Use external audio"
  msgstr "Använd extern audio"
  
  msgid "Video"
  msgstr "Video"
  
- #: src/wx/film_editor.cc:424
+ #: src/wx/film_editor.cc:428
  msgid "With Subtitles"
  msgstr "Med Undertexter"
  
- #: src/wx/film_editor.cc:1271
+ #: src/wx/film_editor.cc:1278
  msgid "channels"
  msgstr "kanaler"
  
  msgid "counting..."
  msgstr "räknar..."
  
- #: src/wx/film_editor.cc:373
+ #: src/wx/film_editor.cc:377
  msgid "dB"
  msgstr "dB"
  
- #: src/wx/film_editor.cc:696 src/wx/film_editor.cc:699
+ #: src/wx/film_editor.cc:212
+ msgid "encode all frames and play the subset"
+ msgstr ""
+ #: src/wx/film_editor.cc:213
+ msgid "encode only the subset"
+ msgstr ""
+ #: src/wx/film_editor.cc:694 src/wx/film_editor.cc:697
  msgid "frames"
  msgstr "bilder"
  
  #. / TRANSLATORS: this is an abbreviation for milliseconds, the unit of time
- #: src/wx/film_editor.cc:386
+ #: src/wx/film_editor.cc:390
  msgid "ms"
  msgstr "ms"
  
- #: src/wx/film_editor.cc:436
+ #: src/wx/film_editor.cc:440
  msgid "pixels"
  msgstr "pixlar"
  
@@@ -506,3 -515,6 +515,6 @@@ msgstr "s
  #: src/wx/properties_dialog.cc:62 src/wx/properties_dialog.cc:63
  msgid "unknown"
  msgstr "okänt"
+ #~ msgid "Original Size"
+ #~ msgstr "Ursprunglig Storlek"
diff --combined test/test.cc
index 46fadd5703cb8eacb155b197337ba5ab41d4530a,496c915198818753036d2864656cd26aa75693e8..1cf6514050b7428d20a336de35f1200c85988ef1
  #include "scaler.h"
  #include "ffmpeg_decoder.h"
  #include "sndfile_decoder.h"
 +#include "dcp_content_type.h"
  #include "trimmer.h"
  #define BOOST_TEST_DYN_LINK
 -#define BOOST_TEST_MODULE dvdomatic_test
 +#define BOOST_TEST_MODULE dcpomatic_test
  #include <boost/test/unit_test.hpp>
  
  using std::string;
@@@ -90,7 -89,7 +90,7 @@@ new_test_film (string name
  BOOST_AUTO_TEST_CASE (make_black_test)
  {
        /* This needs to happen in the first test */
 -      dvdomatic_setup ();
 +      dcpomatic_setup ();
  
        libdcp::Size in_size (512, 512);
        libdcp::Size out_size (1024, 1024);
        }
  }
  
- shared_ptr<AudioBuffers> trimmer_test_last;
+ shared_ptr<const Image> trimmer_test_last_video;
+ shared_ptr<const AudioBuffers> trimmer_test_last_audio;
  
  void
- trimmer_test_helper (shared_ptr<AudioBuffers> audio)
+ trimmer_test_video_helper (shared_ptr<const Image> image, bool, shared_ptr<Subtitle>)
  {
-       trimmer_test_last = audio;
+       trimmer_test_last_video = image;
  }
  
+ void
+ trimmer_test_audio_helper (shared_ptr<const AudioBuffers> audio)
+ {
+       trimmer_test_last_audio = audio;
+ }
+ BOOST_AUTO_TEST_CASE (trimmer_passthrough_test)
+ {
+       Trimmer trimmer (shared_ptr<Log> (), 0, 0, 200, 48000, 25, 25);
+       trimmer.Video.connect (bind (&trimmer_test_video_helper, _1, _2, _3));
+       trimmer.Audio.connect (bind (&trimmer_test_audio_helper, _1));
+       shared_ptr<SimpleImage> video (new SimpleImage (PIX_FMT_RGB24, libdcp::Size (1998, 1080), true));
+       shared_ptr<AudioBuffers> audio (new AudioBuffers (6, 42 * 1920));
+       trimmer.process_video (video, false, shared_ptr<Subtitle> ());
+       trimmer.process_audio (audio);
+       BOOST_CHECK_EQUAL (video.get(), trimmer_test_last_video.get());
+       BOOST_CHECK_EQUAL (audio.get(), trimmer_test_last_audio.get());
+       BOOST_CHECK_EQUAL (audio->frames(), trimmer_test_last_audio->frames());
+ }
  /** Test the audio handling of the Trimmer */
- BOOST_AUTO_TEST_CASE (trimmer_test)
+ BOOST_AUTO_TEST_CASE (trimmer_audio_test)
  {
        Trimmer trimmer (shared_ptr<Log> (), 25, 75, 200, 48000, 25, 25);
  
-       trimmer.Audio.connect (bind (&trimmer_test_helper, _1));
+       trimmer.Audio.connect (bind (&trimmer_test_audio_helper, _1));
  
        /* 21 video frames-worth of audio frames; should be completely stripped */
-       trimmer_test_last.reset ();
+       trimmer_test_last_audio.reset ();
        shared_ptr<AudioBuffers> audio (new AudioBuffers (6, 21 * 1920));
        trimmer.process_audio (audio);
-       BOOST_CHECK (trimmer_test_last == 0);
+       BOOST_CHECK (trimmer_test_last_audio == 0);
  
        /* 42 more video frames-worth, 4 should be stripped from the start */
        audio.reset (new AudioBuffers (6, 42 * 1920));
        trimmer.process_audio (audio);
-       BOOST_CHECK (trimmer_test_last);
-       BOOST_CHECK_EQUAL (trimmer_test_last->frames(), 38 * 1920);
+       BOOST_CHECK (trimmer_test_last_audio);
+       BOOST_CHECK_EQUAL (trimmer_test_last_audio->frames(), 38 * 1920);
  
        /* 42 more video frames-worth, should be kept as-is */
-       trimmer_test_last.reset ();
+       trimmer_test_last_audio.reset ();
        audio.reset (new AudioBuffers (6, 42 * 1920));
        trimmer.process_audio (audio);
-       BOOST_CHECK (trimmer_test_last);
-       BOOST_CHECK_EQUAL (trimmer_test_last->frames(), 42 * 1920);
+       BOOST_CHECK (trimmer_test_last_audio);
+       BOOST_CHECK_EQUAL (trimmer_test_last_audio->frames(), 42 * 1920);
  
        /* 25 more video frames-worth, 5 should be trimmed from the end */
-       trimmer_test_last.reset ();
+       trimmer_test_last_audio.reset ();
        audio.reset (new AudioBuffers (6, 25 * 1920));
        trimmer.process_audio (audio);
-       BOOST_CHECK (trimmer_test_last);
-       BOOST_CHECK_EQUAL (trimmer_test_last->frames(), 20 * 1920);
+       BOOST_CHECK (trimmer_test_last_audio);
+       BOOST_CHECK_EQUAL (trimmer_test_last_audio->frames(), 20 * 1920);
  
        /* Now some more; all should be trimmed */
-       trimmer_test_last.reset ();
+       trimmer_test_last_audio.reset ();
        audio.reset (new AudioBuffers (6, 100 * 1920));
        trimmer.process_audio (audio);
-       BOOST_CHECK (trimmer_test_last == 0);
+       BOOST_CHECK (trimmer_test_last_audio == 0);
  }
  
  
@@@ -192,7 -216,7 +217,7 @@@ BOOST_AUTO_TEST_CASE (film_metadata_tes
        BOOST_CHECK (f->filters ().empty());
  
        f->set_name ("fred");
 -      BOOST_CHECK_THROW (f->set_content ("jim"), OpenFileError);
 +//    BOOST_CHECK_THROW (f->set_content ("jim"), OpenFileError);
        f->set_dcp_content_type (DCPContentType::from_pretty_name ("Short"));
        f->set_format (Format::from_nickname ("Flat"));
        f->set_left_crop (1);
        f->set_filters (f_filters);
        f->set_trim_start (42);
        f->set_trim_end (99);
 -      f->set_dcp_ab (true);
 +      f->set_ab (true);
        f->write_metadata ();
  
        stringstream s;
        BOOST_CHECK_EQUAL (g_filters.back(), Filter::from_id ("unsharp"));
        BOOST_CHECK_EQUAL (g->trim_start(), 42);
        BOOST_CHECK_EQUAL (g->trim_end(), 99);
 -      BOOST_CHECK_EQUAL (g->dcp_ab(), true);
 +      BOOST_CHECK_EQUAL (g->ab(), true);
        
        g->write_metadata ();
        BOOST_CHECK_EQUAL (::system (s.str().c_str ()), 0);
  }
  
 -BOOST_AUTO_TEST_CASE (stream_test)
 -{
 -      FFmpegAudioStream a ("ffmpeg 4 44100 1 hello there world", boost::optional<int> (1));
 -      BOOST_CHECK_EQUAL (a.id(), 4);
 -      BOOST_CHECK_EQUAL (a.sample_rate(), 44100);
 -      BOOST_CHECK_EQUAL (a.channel_layout(), 1);
 -      BOOST_CHECK_EQUAL (a.name(), "hello there world");
 -      BOOST_CHECK_EQUAL (a.to_string(), "ffmpeg 4 44100 1 hello there world");
 -
 -      SndfileStream e ("external 44100 1", boost::optional<int> (1));
 -      BOOST_CHECK_EQUAL (e.sample_rate(), 44100);
 -      BOOST_CHECK_EQUAL (e.channel_layout(), 1);
 -      BOOST_CHECK_EQUAL (e.to_string(), "external 44100 1");
 -
 -      SubtitleStream s ("5 a b c", boost::optional<int> (1));
 -      BOOST_CHECK_EQUAL (s.id(), 5);
 -      BOOST_CHECK_EQUAL (s.name(), "a b c");
 -
 -      shared_ptr<AudioStream> ff = audio_stream_factory ("ffmpeg 4 44100 1 hello there world", boost::optional<int> (1));
 -      shared_ptr<FFmpegAudioStream> cff = dynamic_pointer_cast<FFmpegAudioStream> (ff);
 -      BOOST_CHECK (cff);
 -      BOOST_CHECK_EQUAL (cff->id(), 4);
 -      BOOST_CHECK_EQUAL (cff->sample_rate(), 44100);
 -      BOOST_CHECK_EQUAL (cff->channel_layout(), 1);
 -      BOOST_CHECK_EQUAL (cff->name(), "hello there world");
 -      BOOST_CHECK_EQUAL (cff->to_string(), "ffmpeg 4 44100 1 hello there world");
 -
 -      shared_ptr<AudioStream> fe = audio_stream_factory ("external 44100 1", boost::optional<int> (1));
 -      BOOST_CHECK_EQUAL (fe->sample_rate(), 44100);
 -      BOOST_CHECK_EQUAL (fe->channel_layout(), 1);
 -      BOOST_CHECK_EQUAL (fe->to_string(), "external 44100 1");
 -}
 -
  BOOST_AUTO_TEST_CASE (format_test)
  {
        Format::setup_formats ();
        BOOST_CHECK_EQUAL (f->dcp_size().height, 858);
  }
  
 -/* Test VariableFormat-based scaling of content */
 -BOOST_AUTO_TEST_CASE (scaling_test)
 -{
 -      shared_ptr<Film> film (new Film (test_film_dir ("scaling_test").string(), false));
 -
 -      /* 4:3 ratio */
 -      film->set_size (libdcp::Size (320, 240));
 -
 -      /* This format should preserve aspect ratio of the source */
 -      Format const * format = Format::from_id ("var-185");
 -
 -      /* We should have enough padding that the result is 4:3,
 -         which would be 1440 pixels.
 -      */
 -      BOOST_CHECK_EQUAL (format->dcp_padding (film), (1998 - 1440) / 2);
 -      
 -      /* This crops it to 1.291666667 */
 -      film->set_left_crop (5);
 -      film->set_right_crop (5);
 -
 -      /* We should now have enough padding that the result is 1.29166667,
 -         which would be 1395 pixels.
 -      */
 -      BOOST_CHECK_EQUAL (format->dcp_padding (film), rint ((1998 - 1395) / 2.0));
 -}
 -
  BOOST_AUTO_TEST_CASE (util_test)
  {
        string t = "Hello this is a string \"with quotes\" and indeed without them";
@@@ -279,6 -362,17 +304,6 @@@ BOOST_AUTO_TEST_CASE (md5_digest_test
        BOOST_CHECK_THROW (md5_digest ("foobar"), OpenFileError);
  }
  
 -BOOST_AUTO_TEST_CASE (paths_test)
 -{
 -      shared_ptr<Film> f = new_test_film ("paths_test");
 -      f->set_directory ("build/test/a/b/c/d/e");
 -
 -      f->_content = "/foo/bar/baz";
 -      BOOST_CHECK_EQUAL (f->content_path(), "/foo/bar/baz");
 -      f->_content = "foo/bar/baz";
 -      BOOST_CHECK_EQUAL (f->content_path(), "build/test/a/b/c/d/e/foo/bar/baz");
 -}
 -
  void
  do_remote_encode (shared_ptr<DCPVideoFrame> frame, ServerDescription* description, shared_ptr<EncodedData> locally_encoded)
  {
@@@ -348,7 -442,7 +373,7 @@@ BOOST_AUTO_TEST_CASE (client_server_tes
        new thread (boost::bind (&Server::run, server, 2));
  
        /* Let the server get itself ready */
 -      dvdomatic_sleep (1);
 +      dcpomatic_sleep (1);
  
        ServerDescription description ("localhost", 2);
  
@@@ -370,14 -464,14 +395,14 @@@ BOOST_AUTO_TEST_CASE (make_dcp_test
  {
        shared_ptr<Film> film = new_test_film ("make_dcp_test");
        film->set_name ("test_film2");
 -      film->set_content ("../../../test/test.mp4");
 +//    film->set_content ("../../../test/test.mp4");
        film->set_format (Format::from_nickname ("Flat"));
        film->set_dcp_content_type (DCPContentType::from_pretty_name ("Test"));
        film->make_dcp ();
        film->write_metadata ();
  
        while (JobManager::instance()->work_to_do ()) {
 -              dvdomatic_sleep (1);
 +              dcpomatic_sleep (1);
        }
        
        BOOST_CHECK_EQUAL (JobManager::instance()->errors(), false);
@@@ -400,15 -494,15 +425,15 @@@ BOOST_AUTO_TEST_CASE (make_dcp_with_ran
  {
        shared_ptr<Film> film = new_test_film ("make_dcp_with_range_test");
        film->set_name ("test_film3");
 -      film->set_content ("../../../test/test.mp4");
 -      film->examine_content ();
 +//    film->set_content ("../../../test/test.mp4");
 +//    film->examine_content ();
        film->set_format (Format::from_nickname ("Flat"));
        film->set_dcp_content_type (DCPContentType::from_pretty_name ("Test"));
        film->set_trim_end (42);
        film->make_dcp ();
  
        while (JobManager::instance()->work_to_do() && !JobManager::instance()->errors()) {
 -              dvdomatic_sleep (1);
 +              dcpomatic_sleep (1);
        }
  
        BOOST_CHECK_EQUAL (JobManager::instance()->errors(), false);
@@@ -562,44 -656,44 +587,44 @@@ BOOST_AUTO_TEST_CASE (audio_sampling_ra
        Config::instance()->set_allowed_dcp_frame_rates (afr);
  
        shared_ptr<Film> f = new_test_film ("audio_sampling_rate_test");
 -      f->set_source_frame_rate (24);
 +//    f->set_source_frame_rate (24);
        f->set_dcp_frame_rate (24);
  
 -      f->set_content_audio_stream (shared_ptr<AudioStream> (new FFmpegAudioStream ("a", 42, 48000, 0)));
 +//    f->set_content_audio_stream (shared_ptr<AudioStream> (new FFmpegAudioStream ("a", 42, 48000, 0)));
        BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 48000);
  
 -      f->set_content_audio_stream (shared_ptr<AudioStream> (new FFmpegAudioStream ("a", 42, 44100, 0)));
 +//    f->set_content_audio_stream (shared_ptr<AudioStream> (new FFmpegAudioStream ("a", 42, 44100, 0)));
        BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 48000);
  
 -      f->set_content_audio_stream (shared_ptr<AudioStream> (new FFmpegAudioStream ("a", 42, 80000, 0)));
 +//    f->set_content_audio_stream (shared_ptr<AudioStream> (new FFmpegAudioStream ("a", 42, 80000, 0)));
        BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 96000);
  
 -      f->set_source_frame_rate (23.976);
 +//    f->set_source_frame_rate (23.976);
        f->set_dcp_frame_rate (best_dcp_frame_rate (23.976));
 -      f->set_content_audio_stream (shared_ptr<AudioStream> (new FFmpegAudioStream ("a", 42, 48000, 0)));
 +//    f->set_content_audio_stream (shared_ptr<AudioStream> (new FFmpegAudioStream ("a", 42, 48000, 0)));
        BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 47952);
  
 -      f->set_source_frame_rate (29.97);
 +//    f->set_source_frame_rate (29.97);
        f->set_dcp_frame_rate (best_dcp_frame_rate (29.97));
        BOOST_CHECK_EQUAL (f->dcp_frame_rate (), 30);
 -      f->set_content_audio_stream (shared_ptr<AudioStream> (new FFmpegAudioStream ("a", 42, 48000, 0)));
 +//    f->set_content_audio_stream (shared_ptr<AudioStream> (new FFmpegAudioStream ("a", 42, 48000, 0)));
        BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 47952);
  
 -      f->set_source_frame_rate (25);
 +//    f->set_source_frame_rate (25);
        f->set_dcp_frame_rate (24);
 -      f->set_content_audio_stream (shared_ptr<AudioStream> (new FFmpegAudioStream ("a", 42, 48000, 0)));
 +//    f->set_content_audio_stream (shared_ptr<AudioStream> (new FFmpegAudioStream ("a", 42, 48000, 0)));
        BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 50000);
  
 -      f->set_source_frame_rate (25);
 +//    f->set_source_frame_rate (25);
        f->set_dcp_frame_rate (24);
 -      f->set_content_audio_stream (shared_ptr<AudioStream> (new FFmpegAudioStream ("a", 42, 44100, 0)));
 +//    f->set_content_audio_stream (shared_ptr<AudioStream> (new FFmpegAudioStream ("a", 42, 44100, 0)));
        BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 50000);
  
        /* Check some out-there conversions (not the best) */
        
 -      f->set_source_frame_rate (14.99);
 +//    f->set_source_frame_rate (14.99);
        f->set_dcp_frame_rate (25);
 -      f->set_content_audio_stream (shared_ptr<AudioStream> (new FFmpegAudioStream ("a", 42, 16000, 0)));
 +//    f->set_content_audio_stream (shared_ptr<AudioStream> (new FFmpegAudioStream ("a", 42, 16000, 0)));
        /* The FrameRateConversion within target_audio_sample_rate should choose to double-up
           the 14.99 fps video to 30 and then run it slow at 25.
        */
@@@ -645,10 -739,10 +670,10 @@@ BOOST_AUTO_TEST_CASE (job_manager_test
        shared_ptr<TestJob> a (new TestJob (f));
  
        JobManager::instance()->add (a);
 -      dvdomatic_sleep (1);
 +      dcpomatic_sleep (1);
        BOOST_CHECK_EQUAL (a->running (), true);
        a->set_finished_ok ();
 -      dvdomatic_sleep (2);
 +      dcpomatic_sleep (2);
        BOOST_CHECK_EQUAL (a->finished_ok(), true);
  }