From: Carl Hetherington Date: Fri, 26 Apr 2013 22:41:02 +0000 (+0100) Subject: Merge master; fix crash on new film. X-Git-Tag: v2.0.48~1337^2~412 X-Git-Url: https://main.carlh.net/gitweb/?p=dcpomatic.git;a=commitdiff_plain;h=f861018389acd9d277fe34d7621182b9b54f977f Merge master; fix crash on new film. --- f861018389acd9d277fe34d7621182b9b54f977f diff --cc builds/control-12.04-32 index d31a5e384,0f52d03ae..571beee51 --- a/builds/control-12.04-32 +++ b/builds/control-12.04-32 @@@ -10,6 -10,15 +10,15 @@@ Package: dcpomati 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 --cc builds/control-12.04-64 index 5d41558b6,fa4b4476e..77fbd9e8f --- a/builds/control-12.04-64 +++ b/builds/control-12.04-64 @@@ -10,6 -10,15 +10,15 @@@ Package: dcpomati 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 --cc builds/control-12.10-32 index 67933f2ed,0e5fc1f46..80b024e46 --- a/builds/control-12.10-32 +++ b/builds/control-12.10-32 @@@ -10,6 -10,14 +10,14 @@@ Package: dcpomati 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 --cc builds/control-12.10-64 index cddf80007,24e16b4b5..24e893c15 --- a/builds/control-12.10-64 +++ b/builds/control-12.10-64 @@@ -10,6 -10,15 +10,15 @@@ Package: dcpomati 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 --cc debian/rules index 7f7da5530,f2b2219be..175947019 --- a/debian/rules +++ b/debian/rules @@@ -20,5 -20,8 +20,8 @@@ 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 --cc src/lib/ab_transcoder.cc index c6ccfdc67,d8f13dae4..2e0d41e7d --- a/src/lib/ab_transcoder.cc +++ b/src/lib/ab_transcoder.cc @@@ -46,30 -50,60 +47,40 @@@ using boost::dynamic_pointer_cast * @param e Encoder to use. */ -ABTranscoder::ABTranscoder ( - shared_ptr a, shared_ptr b, DecodeOptions o, Job* j, shared_ptr e) +ABTranscoder::ABTranscoder (shared_ptr a, shared_ptr b, shared_ptr 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 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 @@@ -91,16 -131,12 +102,11 @@@ ABTranscoder::go ( 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 --cc src/lib/ab_transcoder.h index b1b01d724,4f1b14e48..1fef66b88 --- a/src/lib/ab_transcoder.h +++ b/src/lib/ab_transcoder.h @@@ -35,7 -39,7 +35,8 @@@ 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 diff --cc src/lib/audio_source.cc index 3dd3027ab,d77e89367..32b3deccf --- a/src/lib/audio_source.cc +++ b/src/lib/audio_source.cc @@@ -21,18 -21,8 +21,18 @@@ #include "audio_sink.h" using boost::shared_ptr; +using boost::weak_ptr; using boost::bind; +static void - process_audio_proxy (weak_ptr sink, shared_ptr audio) ++process_audio_proxy (weak_ptr sink, shared_ptr audio) +{ + shared_ptr p = sink.lock (); + if (p) { + p->process_audio (audio); + } +} + void AudioSource::connect_audio (shared_ptr s) { diff --cc src/lib/encoder.cc index f56440dd7,cff9899ac..c1d1041ae --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@@ -240,9 -231,9 +240,9 @@@ Encoder::frame_done ( } void - Encoder::process_video (shared_ptr image, bool same, shared_ptr sub) -Encoder::process_video (shared_ptr image, bool same, boost::shared_ptr sub) ++Encoder::process_video (shared_ptr image, bool same, shared_ptr sub) { - FrameRateConversion frc (_film->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; diff --cc src/lib/matcher.cc index edbb084de,9924c003a..c56a56301 --- a/src/lib/matcher.cc +++ b/src/lib/matcher.cc @@@ -41,7 -41,7 +41,7 @@@ Matcher::Matcher (shared_ptr log, } void - Matcher::process_video (shared_ptr image, bool same, boost::shared_ptr sub, double t) -Matcher::process_video (boost::shared_ptr image, bool same, boost::shared_ptr sub, double t) ++Matcher::process_video (shared_ptr image, bool same, boost::shared_ptr sub, double t) { _pixel_format = image->pixel_format (); _size = image->size (); @@@ -90,7 -90,7 +90,7 @@@ } void - Matcher::process_audio (shared_ptr b, double t) -Matcher::process_audio (boost::shared_ptr b, double t) ++Matcher::process_audio (shared_ptr b, double t) { _channels = b->channels (); diff --cc src/lib/player.cc index 7c75597ea,000000000..09f1f55a3 mode 100644,000000..100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@@ -1,319 -1,0 +1,323 @@@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "player.h" +#include "film.h" +#include "ffmpeg_decoder.h" +#include "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 f, shared_ptr 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 >::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) +{ + /* Assume progress can be divined from how far through the video we are */ + + if (_video_decoder >= _video_decoders.size() || !_playlist->video_length()) { + return; + } + + job->set_progress ((_video_start[_video_decoder] + _video_decoders[_video_decoder]->video_frame()) / _playlist->video_length ()); +} + +void - Player::process_video (shared_ptr i, bool same, shared_ptr s, double t) ++Player::process_video (shared_ptr i, bool same, shared_ptr s, double t) +{ + Video (i, same, s, _video_start[_video_decoder] + t); +} + +void - Player::process_audio (weak_ptr c, shared_ptr b, double t) ++Player::process_audio (weak_ptr c, shared_ptr 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 dcp = mapping.content_to_dcp (AudioMapping::Channel (c, i)); + for (list::iterator j = dcp.begin(); j != dcp.end(); ++j) { + _audio_buffers->accumulate (b, i, static_cast (*j)); + } + } + + if (_playlist->audio_from() == Playlist::AUDIO_FFMPEG) { + /* We can just emit this audio now as it will all be here */ + Audio (_audio_buffers, t); + _audio_buffers.reset (); + _audio_time = boost::none; + } +} + +/** @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 > vc = _playlist->video (); + for (list >::iterator i = vc.begin(); i != vc.end(); ++i) { + + shared_ptr video_content; + shared_ptr audio_content; + shared_ptr video_decoder; + shared_ptr audio_decoder; + + /* XXX: into content? */ + + shared_ptr fc = dynamic_pointer_cast (*i); + if (fc) { + shared_ptr fd ( + new FFmpegDecoder ( + _film, fc, _video, + _audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG, + _subtitles + ) + ); + + video_content = fc; + audio_content = fc; + video_decoder = fd; + audio_decoder = fd; + } + + shared_ptr ic = dynamic_pointer_cast (*i); + if (ic) { + video_content = ic; + video_decoder.reset (new ImageMagickDecoder (_film, ic)); + } + + video_decoder->connect_video (shared_from_this ()); + _video_decoders.push_back (video_decoder); + _video_start.push_back (video_so_far); + video_so_far += video_content->video_length() / video_content->video_frame_rate(); + + if (audio_decoder && _playlist->audio_from() == Playlist::AUDIO_FFMPEG) { + audio_decoder->Audio.connect (bind (&Player::process_audio, this, audio_content, _1, _2)); + _audio_decoders.push_back (audio_decoder); + _audio_start.push_back (audio_so_far); + audio_so_far += double(audio_content->audio_length()) / audio_content->audio_frame_rate(); + } + } + + _video_decoder = 0; + _sequential_audio_decoder = 0; + + if (_playlist->audio_from() == Playlist::AUDIO_SNDFILE) { + + list > ac = _playlist->audio (); + for (list >::iterator i = ac.begin(); i != ac.end(); ++i) { + + shared_ptr sc = dynamic_pointer_cast (*i); + assert (sc); + + shared_ptr d (new SndfileDecoder (_film, sc)); + d->Audio.connect (bind (&Player::process_audio, this, sc, _1, _2)); + _audio_decoders.push_back (d); + _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 w, int p) +{ + shared_ptr c = w.lock (); + if (!c) { + return; + } + + if (p == VideoContentProperty::VIDEO_LENGTH) { + if (dynamic_pointer_cast (c)) { + /* FFmpeg content length changes are serious; we need new decoders */ + _have_valid_decoders = false; + } + } +} + +void +Player::playlist_changed () +{ + _have_valid_decoders = false; +} diff --cc src/lib/player.h index 2069064d7,000000000..20b83bfdb mode 100644,000000..100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@@ -1,92 -1,0 +1,92 @@@ +/* + Copyright (C) 2013 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef DCPOMATIC_PLAYER_H +#define DCPOMATIC_PLAYER_H + +#include +#include +#include +#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 +{ +public: + Player (boost::shared_ptr, boost::shared_ptr); + + void disable_video (); + void disable_audio (); + void disable_subtitles (); + + bool pass (); + void set_progress (boost::shared_ptr); + bool seek (double); + void seek_back (); + void seek_forward (); + + double last_video_time () const; + +private: - void process_video (boost::shared_ptr i, bool same, boost::shared_ptr s, double); - void process_audio (boost::weak_ptr, boost::shared_ptr, double); ++ void process_video (boost::shared_ptr i, bool same, boost::shared_ptr s, double); ++ void process_audio (boost::weak_ptr, boost::shared_ptr, double); + void setup_decoders (); + void playlist_changed (); + void content_changed (boost::weak_ptr, int); + + boost::shared_ptr _film; + boost::shared_ptr _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 > _video_decoders; + /** Start positions of each video decoder in seconds*/ + std::vector _video_start; + /** Index of current video decoder */ + size_t _video_decoder; + /** Audio decoders in order of presentation (if they are from FFmpeg) */ + std::vector > _audio_decoders; + /** Start positions of each audio decoder (if they are from FFmpeg) in seconds */ + std::vector _audio_start; + /** Current audio decoder index if we are running them sequentially; otherwise undefined */ + size_t _sequential_audio_decoder; + + boost::shared_ptr _audio_buffers; + boost::optional _audio_time; +}; + +#endif diff --cc src/lib/po/es_ES.po index 5c8d642e3,1608f3b0c..7d2f8511e --- a/src/lib/po/es_ES.po +++ b/src/lib/po/es_ES.po @@@ -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 \n" "Language-Team: Manuel AC \n" @@@ -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" diff --cc src/lib/po/fr_FR.po index af6890d97,d1123d84b..7f3da788b --- a/src/lib/po/fr_FR.po +++ b/src/lib/po/fr_FR.po @@@ -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 \n" "Language-Team: \n" @@@ -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" diff --cc src/lib/po/it_IT.po index c1ca26ea3,5f9e9e862..1d7f57536 --- a/src/lib/po/it_IT.po +++ b/src/lib/po/it_IT.po @@@ -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" diff --cc src/lib/po/sv_SE.po index f89874e35,11aeff987..ff86e23af --- a/src/lib/po/sv_SE.po +++ b/src/lib/po/sv_SE.po @@@ -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-10 15:35+0100\n" "Last-Translator: Adam Klotblixt \n" "Language-Team: \n" @@@ -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" diff --cc src/lib/transcoder.cc index ea3f27ad8,faafcaf8b..2e33931bd --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@@ -34,7 -35,8 +34,8 @@@ #include "gain.h" #include "video_decoder.h" #include "audio_decoder.h" +#include "player.h" + #include "trimmer.h" using std::string; using boost::shared_ptr; @@@ -45,42 -47,88 +46,53 @@@ using boost::dynamic_pointer_cast * @param j Job that we are running under, or 0. * @param e Encoder to use. */ -Transcoder::Transcoder (shared_ptr f, DecodeOptions o, Job* j, shared_ptr e) +Transcoder::Transcoder (shared_ptr f, shared_ptr j) : _job (j) - , _encoder (e) - , _decoders (decoder_factory (f, o)) + , _player (f->player ()) + , _encoder (new Encoder (f)) { - assert (_encoder); - - shared_ptr 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 (_decoders.audio) != dynamic_pointer_cast (_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 (); } diff --cc src/lib/transcoder.h index ecc8ebf62,f5b8ae6e3..97ecaabfc --- a/src/lib/transcoder.h +++ b/src/lib/transcoder.h @@@ -29,10 -32,13 +29,11 @@@ 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. diff --cc src/lib/util.cc index 56932720c,859aa6de7..ec1fd47bd --- a/src/lib/util.cc +++ b/src/lib/util.cc @@@ -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. @@@ -366,16 -361,16 +367,16 @@@ md5_digest (void const * data, int size * @return MD5 digest of file's contents. */ string -md5_digest (string file) +md5_digest (boost::filesystem::path file) { - ifstream f (file.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]; @@@ -869,21 -889,6 +885,21 @@@ AudioBuffers::move (int from, int to, i } } +/** Add data from from `from', `from_channel' to our channel `to_channel' */ +void - AudioBuffers::accumulate (shared_ptr from, int from_channel, int to_channel) ++AudioBuffers::accumulate (shared_ptr from, int from_channel, int to_channel) +{ + int const N = frames (); + assert (from->frames() == N); + + float* s = from->data (from_channel); + float* d = _data[to_channel]; + + for (int i = 0; i < N; ++i) { + *d++ += *s++; + } +} + /** Trip an assert if the caller is not in the UI thread */ void ensure_ui_thread () diff --cc src/lib/util.h index 02cc742aa,99670110e..0edfe2076 --- a/src/lib/util.h +++ b/src/lib/util.h @@@ -182,7 -265,6 +183,7 @@@ public void copy_from (AudioBuffers* from, int frames_to_copy, int read_offset, int write_offset); void move (int from, int to, int frames); - void accumulate (boost::shared_ptr, int, int); ++ void accumulate (boost::shared_ptr, int, int); private: /** Number of channels */ diff --cc src/lib/video_source.cc index ccb76f020,539243402..2de4db68d --- a/src/lib/video_source.cc +++ b/src/lib/video_source.cc @@@ -21,18 -21,8 +21,18 @@@ #include "video_sink.h" using boost::shared_ptr; +using boost::weak_ptr; using boost::bind; +static void - process_video_proxy (weak_ptr sink, shared_ptr i, bool same, shared_ptr s) ++process_video_proxy (weak_ptr sink, shared_ptr i, bool same, shared_ptr s) +{ + shared_ptr p = sink.lock (); + if (p) { + p->process_video (i, same, s); + } +} + void VideoSource::connect_video (shared_ptr s) { diff --cc src/tools/dcpomatic_cli.cc index e2e1874c4,000000000..86c3cf4b1 mode 100644,000000..100644 --- a/src/tools/dcpomatic_cli.cc +++ b/src/tools/dcpomatic_cli.cc @@@ -1,217 -1,0 +1,217 @@@ +/* + Copyright (C) 2012 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include +#include +#include +#include +#include "format.h" +#include "film.h" +#include "filter.h" +#include "transcode_job.h" +#include "job_manager.h" +#include "ab_transcode_job.h" +#include "util.h" +#include "scaler.h" +#include "version.h" +#include "cross.h" +#include "config.h" +#include "log.h" + +using std::string; +using std::cerr; +using std::cout; +using std::vector; +using std::pair; +using std::list; +using boost::shared_ptr; + +static void +help (string n) +{ + cerr << "Syntax: " << n << " [OPTION] \n" + << " -v, --version show DCP-o-matic version\n" + << " -h, --help show this help\n" + << " -d, --deps list DCP-o-matic dependency details and quit\n" + << " -t, --test run in test mode (repeatable UUID generation, timestamps etc.)\n" + << " -n, --no-progress do not print progress to stdout\n" + << " -r, --no-remote do not use any remote servers\n" + << "\n" + << " is the film directory.\n"; +} + +int +main (int argc, char* argv[]) +{ + string film_dir; + bool test_mode = false; + bool progress = true; + bool no_remote = false; - int log_level = 1; ++ int 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 ()); + } + + cout << "DCP-o-matic " << dcpomatic_version << " git " << dcpomatic_git_commit; + char buf[256]; + if (gethostname (buf, 256) == 0) { + cout << " on " << buf; + } + cout << "\n"; + + if (test_mode) { + libdcp::enable_test_mode (); + cout << dependency_version_summary() << "\n"; + } + + shared_ptr film; + try { + film.reset (new Film (film_dir, true)); + } catch (std::exception& e) { + cerr << argv[0] << ": error reading film `" << film_dir << "' (" << e.what() << ")\n"; + exit (EXIT_FAILURE); + } + + film->log()->set_level ((Log::Level) log_level); + + cout << "\nMaking "; + if (film->ab()) { + cout << "A/B "; + } + cout << "DCP for " << film->name() << "\n"; + cout << "Test mode: " << (test_mode ? "yes" : "no") << "\n"; +// cout << "Content: " << film->content() << "\n"; + pair const f = Filter::ffmpeg_strings (film->filters ()); + cout << "Filters: " << f.first << " " << f.second << "\n"; + + film->make_dcp (); + + bool should_stop = false; + bool first = true; + bool error = false; + while (!should_stop) { + + dcpomatic_sleep (5); + + list > jobs = JobManager::instance()->get (); + + if (!first && progress) { + cout << "\033[" << jobs.size() << "A"; + cout.flush (); + } + + first = false; + + int unfinished = 0; + int finished_in_error = 0; + + for (list >::iterator i = jobs.begin(); i != jobs.end(); ++i) { + if (progress) { + cout << (*i)->name() << ": "; + + float const p = (*i)->overall_progress (); + + if (p >= 0) { + cout << (*i)->status() << " \n"; + } else { + cout << ": Running \n"; + } + } + + if (!(*i)->finished ()) { + ++unfinished; + } + + if ((*i)->finished_in_error ()) { + ++finished_in_error; + error = true; + } + + if (!progress && (*i)->finished_in_error ()) { + /* We won't see this error if we haven't been showing progress, + so show it now. + */ + cout << (*i)->status() << "\n"; + } + } + + if (unfinished == 0 || finished_in_error != 0) { + should_stop = true; + } + } + + return error ? EXIT_FAILURE : EXIT_SUCCESS; +} + + diff --cc src/tools/po/es_ES.po index d35f104c6,1739f97cd..346aa2b39 --- a/src/tools/po/es_ES.po +++ b/src/tools/po/es_ES.po @@@ -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 \n" "Language-Team: Manuel AC \n" diff --cc src/tools/po/fr_FR.po index ef2246992,c1447f7e6..8ce305ccf --- a/src/tools/po/fr_FR.po +++ b/src/tools/po/fr_FR.po @@@ -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" diff --cc src/tools/po/sv_SE.po index 4765c2d98,8ae68853f..69706d647 --- a/src/tools/po/sv_SE.po +++ b/src/tools/po/sv_SE.po @@@ -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 \n" "Language-Team: \n" diff --cc src/wx/film_viewer.cc index e742a3e41,4f2985a06..e9a1a574b --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@@ -300,7 -308,7 +300,7 @@@ FilmViewer::raw_to_display ( return; } - shared_ptr input = _raw_frame; - boost::shared_ptr input = _raw_frame; ++ shared_ptr input = _raw_frame; pair const s = Filter::ffmpeg_strings (_film->filters()); if (!s.second.empty ()) { diff --cc src/wx/film_viewer.h index 814a095af,ed5874fbc..02d862ca0 --- a/src/wx/film_viewer.h +++ b/src/wx/film_viewer.h @@@ -91,9 -71,10 +91,9 @@@ private wxToggleButton* _play_button; wxTimer _timer; - boost::shared_ptr _raw_frame; - Decoders _decoders; + boost::shared_ptr _raw_frame; boost::shared_ptr _raw_sub; - boost::shared_ptr _display_frame; + boost::shared_ptr _display_frame; /* The x offset at which we display the actual film content; this corresponds to the film's padding converted to our coordinates. */ diff --cc src/wx/po/es_ES.po index abb6b780f,56c0856bd..a193325e6 --- a/src/wx/po/es_ES.po +++ b/src/wx/po/es_ES.po @@@ -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 \n" "Language-Team: Manuel AC \n" @@@ -22,10 -22,10 +22,10 @@@ 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" diff --cc src/wx/po/fr_FR.po index 2aac7114c,c7ef31f5a..36ae4a925 --- a/src/wx/po/fr_FR.po +++ b/src/wx/po/fr_FR.po @@@ -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 \n" "Language-Team: \n" @@@ -21,10 -21,10 +21,10 @@@ 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" diff --cc src/wx/po/it_IT.po index 7b06495e8,c730a7ff7..f53c40b97 --- a/src/wx/po/it_IT.po +++ b/src/wx/po/it_IT.po @@@ -22,10 -22,10 +22,10 @@@ 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" diff --cc src/wx/po/sv_SE.po index 96fafadeb,4127d77f8..9ed7ee2be --- a/src/wx/po/sv_SE.po +++ b/src/wx/po/sv_SE.po @@@ -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 \n" "Language-Team: \n" @@@ -22,10 -22,10 +22,10 @@@ 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"