Merge branch 'master' of ssh://git.carlh.net/home/carl/git/dcpomatic
authorCarl Hetherington <cth@carlh.net>
Fri, 27 Jul 2018 15:14:41 +0000 (16:14 +0100)
committerCarl Hetherington <cth@carlh.net>
Fri, 27 Jul 2018 15:14:41 +0000 (16:14 +0100)
12 files changed:
src/lib/hints.cc
src/lib/hints.h
src/lib/player.cc
src/lib/player.h
src/lib/util.h
src/tools/dcpomatic.cc
src/wx/closed_captions_dialog.cc
src/wx/closed_captions_dialog.h
src/wx/hints_dialog.cc
src/wx/hints_dialog.h
test/player_test.cc
wscript

index 31b2ad84922a0d4268d011f3cc96cbcdf15c2b03..943991d2bc584f839f2a1eff085218106b35f8cc 100644 (file)
@@ -30,6 +30,8 @@
 #include "audio_analysis.h"
 #include "compose.hpp"
 #include "util.h"
+#include "cross.h"
+#include "player.h"
 #include <dcp/raw_convert.h>
 #include <boost/foreach.hpp>
 #include <boost/algorithm/string.hpp>
@@ -44,12 +46,58 @@ using std::min;
 using std::max;
 using std::cout;
 using boost::shared_ptr;
+using boost::weak_ptr;
 using boost::optional;
+using boost::bind;
+
+Hints::Hints (weak_ptr<const Film> film)
+       : _film (film)
+       , _thread (0)
+       , _long_ccap (false)
+       , _overlap_ccap (false)
+       , _too_many_ccap_lines (false)
+{
+
+}
 
-vector<string>
-get_hints (shared_ptr<const Film> film)
+void
+Hints::stop_thread ()
 {
-       vector<string> hints;
+       if (_thread) {
+               try {
+                       _thread->interrupt ();
+                       _thread->join ();
+               } catch (...) {
+
+               }
+
+               delete _thread;
+               _thread = 0;
+       }
+}
+
+Hints::~Hints ()
+{
+       stop_thread ();
+}
+
+void
+Hints::start ()
+{
+       stop_thread ();
+       _long_ccap = false;
+       _overlap_ccap = false;
+       _too_many_ccap_lines = false;
+       _thread = new boost::thread (bind(&Hints::thread, this));
+}
+
+void
+Hints::thread ()
+{
+       shared_ptr<const Film> film = _film.lock ();
+       if (!film) {
+               return;
+       }
 
        ContentList content = film->content ();
 
@@ -70,16 +118,16 @@ get_hints (shared_ptr<const Film> film)
        }
 
        if (big_font_files) {
-               hints.push_back (_("You have specified a font file which is larger than 640kB.  This is very likely to cause problems on playback."));
+               hint (_("You have specified a font file which is larger than 640kB.  This is very likely to cause problems on playback."));
        }
 
        if (film->audio_channels() < 6) {
-               hints.push_back (_("Your DCP has fewer than 6 audio channels.  This may cause problems on some projectors."));
+               hint (_("Your DCP has fewer than 6 audio channels.  This may cause problems on some projectors."));
        }
 
        AudioProcessor const * ap = film->audio_processor();
        if (ap && (ap->id() == "stereo-5.1-upmix-a" || ap->id() == "stereo-5.1-upmix-b")) {
-               hints.push_back (_("You are using DCP-o-matic's stereo-to-5.1 upmixer.  This is experimental and may result in poor-quality audio.  If you continue, you should listen to the resulting DCP in a cinema to make sure that it sounds good."));
+               hint (_("You are using DCP-o-matic's stereo-to-5.1 upmixer.  This is experimental and may result in poor-quality audio.  If you continue, you should listen to the resulting DCP in a cinema to make sure that it sounds good."));
        }
 
        int flat_or_narrower = 0;
@@ -98,19 +146,19 @@ get_hints (shared_ptr<const Film> film)
        string const film_container = film->container()->id();
 
        if (scope && !flat_or_narrower && film_container == "185") {
-               hints.push_back (_("All of your content is in Scope (2.39:1) but your DCP's container is Flat (1.85:1).  This will letter-box your content inside a Flat (1.85:1) frame.  You may prefer to set your DCP's container to Scope (2.39:1) in the \"DCP\" tab."));
+               hint (_("All of your content is in Scope (2.39:1) but your DCP's container is Flat (1.85:1).  This will letter-box your content inside a Flat (1.85:1) frame.  You may prefer to set your DCP's container to Scope (2.39:1) in the \"DCP\" tab."));
        }
 
        if (!scope && flat_or_narrower && film_container == "239") {
-               hints.push_back (_("All of your content is at 1.85:1 or narrower but your DCP's container is Scope (2.39:1).  This will pillar-box your content inside a Flat (1.85:1) frame.  You may prefer to set your DCP's container to Flat (1.85:1) in the \"DCP\" tab."));
+               hint (_("All of your content is at 1.85:1 or narrower but your DCP's container is Scope (2.39:1).  This will pillar-box your content inside a Flat (1.85:1) frame.  You may prefer to set your DCP's container to Flat (1.85:1) in the \"DCP\" tab."));
        }
 
        if (film_container != "185" && film_container != "239" && film_container != "190") {
-               hints.push_back (_("Your DCP uses an unusual container ratio.  This may cause problems on some projectors.  If possible, use Flat or Scope for the DCP container ratio"));
+               hint (_("Your DCP uses an unusual container ratio.  This may cause problems on some projectors.  If possible, use Flat or Scope for the DCP container ratio"));
        }
 
        if (film->j2k_bandwidth() >= 245000000) {
-               hints.push_back (_("A few projectors have problems playing back very high bit-rate DCPs.  It is a good idea to drop the JPEG2000 bandwidth down to about 200Mbit/s; this is unlikely to have any visible effect on the image."));
+               hint (_("A few projectors have problems playing back very high bit-rate DCPs.  It is a good idea to drop the JPEG2000 bandwidth down to about 200Mbit/s; this is unlikely to have any visible effect on the image."));
        }
 
        if (film->interop() && film->video_frame_rate() != 24 && film->video_frame_rate() != 48) {
@@ -130,7 +178,7 @@ get_hints (shared_ptr<const Film> film)
                        h = _("You are set up for an Interop DCP at a frame rate which is not officially supported.  You are advised either to change the frame rate of your DCP or to make a SMPTE DCP instead (although SMPTE DCPs are not supported by all projectors).");
                }
 
-               hints.push_back (h);
+               hint (h);
        }
 
        optional<double> lowest_speed_up;
@@ -154,7 +202,7 @@ get_hints (shared_ptr<const Film> film)
        }
 
        if (worst_speed_up > 25.5/24.0) {
-               hints.push_back (_("There is a large difference between the frame rate of your DCP and that of some of your content.  This will cause your audio to play back at a much lower or higher pitch than it should.  You are advised to set your DCP frame rate to one closer to your content, provided that your target projection systems support your chosen DCP rate."));
+               hint (_("There is a large difference between the frame rate of your DCP and that of some of your content.  This will cause your audio to play back at a much lower or higher pitch than it should.  You are advised to set your DCP frame rate to one closer to your content, provided that your target projection systems support your chosen DCP rate."));
        }
 
        int vob = 0;
@@ -165,7 +213,7 @@ get_hints (shared_ptr<const Film> film)
        }
 
        if (vob > 1) {
-               hints.push_back (String::compose (_("You have %1 files that look like they are VOB files from DVD. You should join them to ensure smooth joins between the files."), vob));
+               hint (String::compose (_("You have %1 files that look like they are VOB files from DVD. You should join them to ensure smooth joins between the files."), vob));
        }
 
        int three_d = 0;
@@ -176,7 +224,7 @@ get_hints (shared_ptr<const Film> film)
        }
 
        if (three_d > 0 && !film->three_d()) {
-               hints.push_back (_("You are using 3D content but your DCP is set to 2D.  Set the DCP to 3D if you want to play it back on a 3D system (e.g. Real-D, MasterImage etc.)"));
+               hint (_("You are using 3D content but your DCP is set to 2D.  Set the DCP to 3D if you want to play it back on a 3D system (e.g. Real-D, MasterImage etc.)"));
        }
 
        boost::filesystem::path path = film->audio_analysis_path (film->playlist ());
@@ -200,11 +248,10 @@ get_hints (shared_ptr<const Film> film)
                        ch = ch.substr (0, ch.length() - 2);
 
                        if (!ch.empty ()) {
-                               hints.push_back (
-                                       String::compose (
-                                               _("Your audio level is very high (on %1).  You should reduce the gain of your audio content."),
-                                               ch
-                                               )
+                               hint (String::compose (
+                                             _("Your audio level is very high (on %1).  You should reduce the gain of your audio content."),
+                                             ch
+                                             )
                                        );
                        }
                } catch (OldFormatError& e) {
@@ -214,5 +261,52 @@ get_hints (shared_ptr<const Film> film)
                }
        }
 
-       return hints;
+       emit (bind(boost::ref(Progress), _("Examining closed captions")));
+
+       shared_ptr<Player> player (new Player (film, film->playlist ()));
+       player->set_ignore_video ();
+       player->set_ignore_audio ();
+       player->Text.connect (bind(&Hints::text, this, _1, _2, _3));
+       while (!player->pass ()) {
+               bind (boost::ref(Pulse));
+       }
+
+       emit (bind(boost::ref(Finished)));
+}
+
+void
+Hints::hint (string h)
+{
+       emit(bind(boost::ref(Hint), h));
+}
+
+void
+Hints::text (PlayerText text, TextType type, DCPTimePeriod period)
+{
+       if (type != TEXT_CLOSED_CAPTION) {
+               return;
+       }
+
+       int lines = text.text.size();
+       BOOST_FOREACH (StringText i, text.text) {
+               if (i.text().length() > CLOSED_CAPTION_LENGTH) {
+                       ++lines;
+                       if (!_long_ccap) {
+                               _long_ccap = true;
+                               hint (String::compose(_("Some of your closed captions have lines longer than %1 characters, so they will probably be word-wrapped."), CLOSED_CAPTION_LENGTH));
+                       }
+               }
+       }
+
+       if (!_too_many_ccap_lines && lines > CLOSED_CAPTION_LINES) {
+               hint (String::compose(_("Some of your closed captions span more than %1 lines, so they will be truncated."), CLOSED_CAPTION_LINES));
+               _too_many_ccap_lines = true;
+       }
+
+       if (!_overlap_ccap && _last && _last->overlap(period)) {
+               _overlap_ccap = true;
+               hint (_("You have overlapping closed captions, which are not allowed."));
+       }
+
+       _last = period;
 }
index 3a6850860c54da63110fc9c1ce4ac92a374449e6..6ee398c88c12d6edb77013ab1b8174eb54d1bdc2 100644 (file)
 
 */
 
-#include <boost/shared_ptr.hpp>
+#include "signaller.h"
+#include "player_text.h"
+#include "types.h"
+#include "dcpomatic_time.h"
+#include <boost/weak_ptr.hpp>
+#include <boost/signals2.hpp>
 #include <vector>
 #include <string>
 
 class Film;
 
-std::vector<std::string> get_hints (boost::shared_ptr<const Film> film);
+class Hints : public Signaller
+{
+public:
+       Hints (boost::weak_ptr<const Film> film);
+       ~Hints ();
+
+       void start ();
+
+       boost::signals2::signal<void (std::string)> Hint;
+       boost::signals2::signal<void (std::string)> Progress;
+       boost::signals2::signal<void (void)> Pulse;
+       boost::signals2::signal<void (void)> Finished;
+
+private:
+       void thread ();
+       void stop_thread ();
+       void hint (std::string h);
+       void text (PlayerText text, TextType type, DCPTimePeriod period);
+
+       boost::weak_ptr<const Film> _film;
+       boost::thread* _thread;
+
+       bool _long_ccap;
+       bool _overlap_ccap;
+       bool _too_many_ccap_lines;
+       boost::optional<DCPTimePeriod> _last;
+};
index f8471c752cb1838ad5841af2eb068d04acc8b96c..bb0aef458153034bb9b26cc2cbdfaa3cec5ce857 100644 (file)
@@ -89,6 +89,7 @@ Player::Player (shared_ptr<const Film> film, shared_ptr<const Playlist> playlist
        , _playlist (playlist)
        , _have_valid_pieces (false)
        , _ignore_video (false)
+       , _ignore_audio (false)
        , _ignore_text (false)
        , _always_burn_open_subtitles (false)
        , _fast (false)
@@ -126,6 +127,11 @@ Player::setup_pieces ()
                        continue;
                }
 
+               if (_ignore_video && _ignore_audio && i->text.empty()) {
+                       /* We're only interested in text and this content has none */
+                       continue;
+               }
+
                shared_ptr<Decoder> decoder = decoder_factory (i, _film->log(), _fast);
                FrameRateChange frc (i->active_video_frame_rate(), _film->video_frame_rate());
 
@@ -138,6 +144,10 @@ Player::setup_pieces ()
                        decoder->video->set_ignore (true);
                }
 
+               if (decoder->audio && _ignore_audio) {
+                       decoder->audio->set_ignore (true);
+               }
+
                if (_ignore_text) {
                        BOOST_FOREACH (shared_ptr<TextDecoder> i, decoder->text) {
                                i->set_ignore (true);
@@ -444,6 +454,14 @@ Player::set_ignore_video ()
 {
        boost::mutex::scoped_lock lm (_mutex);
        _ignore_video = true;
+       _have_valid_pieces = false;
+}
+
+void
+Player::set_ignore_audio ()
+{
+       _ignore_audio = true;
+       _have_valid_pieces = false;
 }
 
 void
index 4a91c4c529011434800afc2ed899397db2c6b3bd..a4fd80c161c565ccd4a47b210ca833b603c6132e 100644 (file)
@@ -79,6 +79,7 @@ public:
 
        void set_video_container_size (dcp::Size);
        void set_ignore_video ();
+       void set_ignore_audio ();
        void set_ignore_text ();
        void set_always_burn_open_subtitles ();
        void set_fast ();
@@ -161,6 +162,7 @@ private:
 
        /** true if the player should ignore all video; i.e. never produce any */
        bool _ignore_video;
+       bool _ignore_audio;
        /** true if the player should ignore all text; i.e. never produce any */
        bool _ignore_text;
        bool _always_burn_open_subtitles;
index 5ca198ebbcc8f61b46a4ebb6bb2cc5678cf6cb1b..d6fddcddafb7eac2b79422a49d1769da96260539 100644 (file)
@@ -57,6 +57,10 @@ namespace dcp {
 #define TEXT_FONT_ID "font"
 /** Largest KDM size (in bytes) that will be accepted */
 #define MAX_KDM_SIZE (256 * 1024)
+/** Number of lines that closed caption viewers will display */
+#define CLOSED_CAPTION_LINES 3
+/** Maximum line length of closed caption viewers */
+#define CLOSED_CAPTION_LENGTH 30
 
 extern std::string program_name;
 extern bool is_batch_converter;
index a97e12b6952f51f2dc00a28518ce678b5cc3c4b5..6972b35c4e1ac097a781bee3dacaf2fe481add6c 100644 (file)
@@ -636,7 +636,7 @@ private:
                        }
                }
 
-               if (!get_hints(_film).empty() && Config::instance()->show_hints_before_make_dcp()) {
+               if (Config::instance()->show_hints_before_make_dcp()) {
                        HintsDialog* hints = new HintsDialog (this, _film, false);
                        int const r = hints->ShowModal();
                        hints->Destroy ();
@@ -735,7 +735,7 @@ private:
                        return;
                }
 
-               if (!get_hints(_film).empty() && Config::instance()->show_hints_before_make_dcp()) {
+               if (Config::instance()->show_hints_before_make_dcp()) {
                        HintsDialog* hints = new HintsDialog (this, _film, false);
                        int const r = hints->ShowModal();
                        hints->Destroy ();
index 1e13f867a4dae952cb16c069fedb33f067834cce..ea7db88f02375ffb17bf29f993ece7f9038cf005 100644 (file)
@@ -29,9 +29,6 @@ using std::make_pair;
 using boost::shared_ptr;
 using boost::weak_ptr;
 
-int const ClosedCaptionsDialog::_num_lines = 3;
-int const ClosedCaptionsDialog::_num_chars_per_line = 30;
-
 ClosedCaptionsDialog::ClosedCaptionsDialog (wxWindow* parent)
        : wxDialog (parent, wxID_ANY, _("Closed captions"), wxDefaultPosition, wxDefaultSize,
 #ifdef DCPOMATIC_OSX
@@ -45,7 +42,7 @@ ClosedCaptionsDialog::ClosedCaptionsDialog (wxWindow* parent)
                )
 
 {
-       _lines.resize (_num_lines);
+       _lines.resize (CLOSED_CAPTION_LINES);
        Bind (wxEVT_PAINT, boost::bind (&ClosedCaptionsDialog::paint, this));
 }
 
@@ -58,16 +55,16 @@ ClosedCaptionsDialog::paint ()
        dc.SetTextForeground (*wxWHITE);
 
        /* Choose a font which fits vertically */
-       int const line_height = max (8, dc.GetSize().GetHeight() / _num_lines);
+       int const line_height = max (8, dc.GetSize().GetHeight() / CLOSED_CAPTION_LINES);
        wxFont font (*wxNORMAL_FONT);
        font.SetPixelSize (wxSize (0, line_height * 0.8));
        dc.SetFont (font);
 
-       for (int i = 0; i < _num_lines; ++i) {
-               wxString const good = _lines[i].Left (_num_chars_per_line);
+       for (int i = 0; i < CLOSED_CAPTION_LINES; ++i) {
+               wxString const good = _lines[i].Left (CLOSED_CAPTION_LENGTH);
                dc.DrawText (good, 8, line_height * i);
-               if (_lines[i].Length() > _num_chars_per_line) {
-                       wxString const bad = _lines[i].Right (_lines[i].Length() - _num_chars_per_line);
+               if (_lines[i].Length() > CLOSED_CAPTION_LENGTH) {
+                       wxString const bad = _lines[i].Right (_lines[i].Length() - CLOSED_CAPTION_LENGTH);
                        wxSize size = dc.GetTextExtent (good);
                        dc.SetTextForeground (*wxRED);
                        dc.DrawText (bad, 8 + size.GetWidth(), line_height * i);
@@ -112,7 +109,7 @@ ClosedCaptionsDialog::update (DCPTime time)
                }
        }
 
-       for (int j = 0; j < _num_lines; ++j) {
+       for (int j = 0; j < CLOSED_CAPTION_LINES; ++j) {
                _lines[j] = "";
        }
 
@@ -120,7 +117,7 @@ ClosedCaptionsDialog::update (DCPTime time)
 
        list<StringText>::const_iterator j = to_show.begin();
        int k = 0;
-       while (j != to_show.end() && k < _num_lines) {
+       while (j != to_show.end() && k < CLOSED_CAPTION_LINES) {
                _lines[k] = j->text();
                ++j;
                ++k;
index a599bc7036f8d048bb421a64fe30a9e974a506d8..be5b3664d4fb3c25e836d34c3b8f4b691c7ca32b 100644 (file)
@@ -38,6 +38,4 @@ private:
 
        std::vector<wxString> _lines;
        boost::weak_ptr<Player> _player;
-       static int const _num_lines;
-       static int const _num_chars_per_line;
 };
index 86a1602131fa9ab87b46c1aca4951cd991c4575b..1938e7cc4b0f45d55f842297c8ae5bfd7627d93d 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2018 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
 using std::max;
 using std::vector;
 using std::string;
+using std::cout;
 using boost::shared_ptr;
 using boost::optional;
+using boost::bind;
 using boost::dynamic_pointer_cast;
 
 HintsDialog::HintsDialog (wxWindow* parent, boost::weak_ptr<Film> film, bool ok)
        : wxDialog (parent, wxID_ANY, _("Hints"))
        , _film (film)
+       , _hints (new Hints (film))
 {
        wxBoxSizer* sizer = new wxBoxSizer (wxVERTICAL);
+
+       _gauge = new wxGauge (this, wxID_ANY, 100);
+       sizer->Add (_gauge, 0, wxALL | wxEXPAND, DCPOMATIC_SIZER_GAP);
+       _gauge_message = new wxStaticText (this, wxID_ANY, wxT(""));
+       sizer->Add (_gauge_message, 0, wxALL | wxEXPAND, DCPOMATIC_SIZER_GAP);
+
        _text = new wxRichTextCtrl (this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (400, 300), wxRE_READONLY);
        sizer->Add (_text, 1, wxEXPAND | wxALL, 6);
 
@@ -70,6 +79,11 @@ HintsDialog::HintsDialog (wxWindow* parent, boost::weak_ptr<Film> film, bool ok)
                _film_content_changed_connection = locked_film->ContentChanged.connect (boost::bind (&HintsDialog::film_changed, this));
        }
 
+       _hints->Hint.connect (bind (&HintsDialog::hint, this, _1));
+       _hints->Progress.connect (bind (&HintsDialog::progress, this, _1));
+       _hints->Pulse.connect (bind (&HintsDialog::pulse, this));
+       _hints->Finished.connect (bind (&HintsDialog::finished, this));
+
        film_changed ();
 }
 
@@ -77,19 +91,30 @@ void
 HintsDialog::film_changed ()
 {
        _text->Clear ();
+       _current.clear ();
 
        boost::shared_ptr<Film> film = _film.lock ();
        if (!film) {
                return;
        }
 
-       vector<string> hints = get_hints (film);
+       _gauge->Show ();
+       _gauge_message->Show ();
+       Layout ();
+       _gauge->SetValue (0);
+       update ();
+       _hints->start ();
+}
 
-       if (hints.empty ()) {
+void
+HintsDialog::update ()
+{
+       _text->Clear ();
+       if (_current.empty ()) {
                _text->WriteText (_("There are no hints: everything looks good!"));
        } else {
                _text->BeginStandardBullet (N_("standard/circle"), 1, 50);
-               BOOST_FOREACH (string i, hints) {
+               BOOST_FOREACH (string i, _current) {
                        _text->WriteText (std_to_wx (i));
                        _text->Newline ();
                }
@@ -97,8 +122,35 @@ HintsDialog::film_changed ()
        }
 }
 
+void
+HintsDialog::hint (string text)
+{
+       _current.push_back (text);
+       update ();
+}
+
 void
 HintsDialog::shut_up (wxCommandEvent& ev)
 {
        Config::instance()->set_show_hints_before_make_dcp (!ev.IsChecked());
 }
+
+void
+HintsDialog::pulse ()
+{
+       _gauge->Pulse ();
+}
+
+void
+HintsDialog::finished ()
+{
+       _gauge->Hide ();
+       _gauge_message->Hide ();
+       Layout ();
+}
+
+void
+HintsDialog::progress (string m)
+{
+       _gauge_message->SetLabel (std_to_wx(m));
+}
index c02cc8c85b0e196f71610e0718fe957f9b5594f6..06f979a74fde34d575dc07afed42354ce759dd12 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2018 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
@@ -24,6 +24,7 @@
 
 class wxRichTextCtrl;
 class Film;
+class Hints;
 
 class HintsDialog : public wxDialog
 {
@@ -33,9 +34,18 @@ public:
 private:
        void film_changed ();
        void shut_up (wxCommandEvent& ev);
+       void update ();
+       void hint (std::string text);
+       void pulse ();
+       void finished ();
+       void progress (std::string m);
 
        boost::weak_ptr<Film> _film;
+       wxGauge* _gauge;
+       wxStaticText* _gauge_message;
        wxRichTextCtrl* _text;
+       boost::shared_ptr<Hints> _hints;
+       std::list<std::string> _current;
 
        boost::signals2::scoped_connection _film_changed_connection;
        boost::signals2::scoped_connection _film_content_changed_connection;
index 7cc846affec8bc344776f736ff6c49fa4defcab7..605f3bddd1a0fc9207c24a7e5c0ef03064cfa316 100644 (file)
@@ -282,3 +282,42 @@ BOOST_AUTO_TEST_CASE (player_trim_test)
        film->make_dcp ();
        BOOST_REQUIRE (!wait_for_jobs ());
 }
+
+struct Sub {
+       PlayerText text;
+       TextType type;
+       DCPTimePeriod period;
+};
+
+static void
+store (list<Sub>* out, PlayerText text, TextType type, DCPTimePeriod period)
+{
+       Sub s;
+       s.text = text;
+       s.type = type;
+       s.period = period;
+       out->push_back (s);
+}
+
+/** Test ignoring both video and audio */
+BOOST_AUTO_TEST_CASE (player_ignore_video_and_audio_test)
+{
+       shared_ptr<Film> film = new_test_film2 ("player_ignore_video_and_audio_test");
+       shared_ptr<Content> ff = content_factory(film, private_data / "boon_telly.mkv").front();
+       film->examine_and_add_content (ff);
+       shared_ptr<Content> text = content_factory(film, "test/data/subrip.srt").front();
+       film->examine_and_add_content (text);
+       BOOST_REQUIRE (!wait_for_jobs());
+       text->only_text()->set_type (TEXT_CLOSED_CAPTION);
+       text->only_text()->set_use (true);
+
+       shared_ptr<Player> player (new Player(film, film->playlist()));
+       player->set_ignore_video ();
+       player->set_ignore_audio ();
+
+       list<Sub> out;
+       player->Text.connect (bind (&store, &out, _1, _2, _3));
+       while (!player->pass ()) {}
+
+       BOOST_CHECK_EQUAL (out.size(), 6);
+}
diff --git a/wscript b/wscript
index b11eea0959eedba4a71767943622f4ede5383e4b..755f300a1eddc847939d24285dfc5ae8c0ef609b 100644 (file)
--- a/wscript
+++ b/wscript
@@ -607,15 +607,15 @@ def configure(conf):
 
     Logs.pprint('YELLOW', '')
 
-def download_supporters():
+def download_supporters(can_fail):
     last_date = subprocess.Popen(shlex.split('git log -1 --format=%%ai %s' % last_version), stdout=subprocess.PIPE).communicate()[0]
     r = os.system('curl -f https://dcpomatic.com/supporters.cc?%s > src/wx/supporters.cc' % urlencode({"until": last_date.strip()}))
-    if (r >> 8) != 0:
+    if (r >> 8) != 0 and can_fail:
         raise Exception("Could not download supporters list")
 
 def build(bld):
     create_version_cc(VERSION, bld.env.CXXFLAGS)
-    download_supporters()
+    download_supporters(not bld.env.DEBUG)
 
     bld.recurse('src')
     bld.recurse('graphics')