Another macOS std::list boost::thread SNAFU.
[dcpomatic.git] / src / lib / hints.cc
index 6238aa991b7e6a2550f4518109694c3e932edc70..6cb037ed0afd2ebd6bb865734de77eebd455f33f 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2016-2018 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2016-2019 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
@@ -49,10 +49,10 @@ using boost::shared_ptr;
 using boost::weak_ptr;
 using boost::optional;
 using boost::bind;
+using namespace dcpomatic;
 
 Hints::Hints (weak_ptr<const Film> film)
        : _film (film)
-       , _thread (0)
        , _long_ccap (false)
        , _overlap_ccap (false)
        , _too_many_ccap_lines (false)
@@ -62,39 +62,24 @@ Hints::Hints (weak_ptr<const Film> film)
 }
 
 void
-Hints::stop_thread ()
+Hints::start ()
 {
-       if (_thread) {
-               try {
-                       {
-                               boost::mutex::scoped_lock lm (_mutex);
-                               _stop = true;
-                       }
-                       _thread->interrupt ();
-                       _thread->join ();
-               } catch (...) {
-
-               }
-
-               delete _thread;
-               _thread = 0;
-       }
+       _thread = boost::thread (bind(&Hints::thread, this));
 }
 
 Hints::~Hints ()
 {
-       stop_thread ();
-}
+       if (!_thread.joinable()) {
+               return;
+       }
 
-void
-Hints::start ()
-{
-       stop_thread ();
-       _long_ccap = false;
-       _overlap_ccap = false;
-       _too_many_ccap_lines = false;
-       _stop = false;
-       _thread = new boost::thread (bind(&Hints::thread, this));
+       try {
+               _stop = true;
+               _thread.interrupt ();
+               _thread.join ();
+       } catch (...) {
+
+       }
 }
 
 void
@@ -112,11 +97,9 @@ Hints::thread ()
                BOOST_FOREACH (shared_ptr<Content> i, content) {
                        BOOST_FOREACH (shared_ptr<TextContent> j, i->text) {
                                BOOST_FOREACH (shared_ptr<Font> k, j->fonts()) {
-                                       for (int l = 0; l < FontFiles::VARIANTS; ++l) {
-                                               optional<boost::filesystem::path> const p = k->file (static_cast<FontFiles::Variant>(l));
-                                               if (p && boost::filesystem::file_size (p.get()) >= (640 * 1024)) {
-                                                       big_font_files = true;
-                                               }
+                                       optional<boost::filesystem::path> const p = k->file ();
+                                       if (p && boost::filesystem::file_size(p.get()) >= (640 * 1024)) {
+                                               big_font_files = true;
                                        }
                                }
                        }
@@ -128,7 +111,7 @@ Hints::thread ()
        }
 
        if (film->audio_channels() < 6) {
-               hint (_("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.  You may want to set the DCP to have 6 channels.  It does not matter if your content has fewer channels, as DCP-o-matic will fill the extras with silence."));
        }
 
        AudioProcessor const * ap = film->audio_processor();
@@ -136,7 +119,7 @@ Hints::thread ()
                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;
+       int narrower_than_scope = 0;
        int scope = 0;
        BOOST_FOREACH (shared_ptr<const Content> i, content) {
                if (i->video) {
@@ -144,19 +127,19 @@ Hints::thread ()
                        if (r && r->id() == "239") {
                                ++scope;
                        } else if (r && r->id() != "239" && r->id() != "190") {
-                               ++flat_or_narrower;
+                               ++narrower_than_scope;
                        }
                }
        }
 
        string const film_container = film->container()->id();
 
-       if (scope && !flat_or_narrower && film_container == "185") {
+       if (scope && !narrower_than_scope && film_container == "185") {
                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") {
-               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 (!scope && narrower_than_scope && film_container == "239") {
+               hint (_("All of your content is 2.35:1 or narrower but your DCP's container is Scope (2.39:1).  This will pillar-box your content.  You may prefer to set your DCP's container to have the same ratio as your content."));
        }
 
        if (film_container != "185" && film_container != "239" && film_container != "190") {
@@ -167,24 +150,31 @@ Hints::thread ()
                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) {
-               string base = _("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.");
-               base += "  ";
-               pair<double, double> range24 = film->speed_up_range (24);
-               pair<double, double> range48 = film->speed_up_range (48);
-               pair<double, double> range (max (range24.first, range48.first), min (range24.second, range48.second));
-               string h;
-               if (range.second > (29.0/24)) {
-                       h = base;
-                       h += _("However, setting your DCP frame rate to 24 or 48 will cause a significant speed-up of your content, and SMPTE DCPs are not supported by all projectors.");
-               } else if (range.first < (24.0/29)) {
-                       h = base;
-                       h += _("However, setting your DCP frame rate to 24 or 48 will cause a significant slowdown of your content, and SMPTE DCPs are not supported by all projectors.");
-               } else {
-                       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).");
+       switch (film->video_frame_rate()) {
+       case 24:
+               /* Fine */
+               break;
+       case 25:
+       {
+               /* You might want to go to 24 */
+               string base = String::compose(_("You are set up for a DCP at a frame rate of %1 fps.  This frame rate is not supported by all projectors.  You may want to consider changing your frame rate to %2 fps."), 25, 24);
+               if (film->interop()) {
+                       base += "  ";
+                       base += _("If you do use 25fps you should change your DCP standard to SMPTE.");
                }
-
-               hint (h);
+               hint (base);
+               break;
+       }
+       case 30:
+               /* 30fps: we can't really offer any decent solutions */
+               hint (_("You are set up for a DCP frame rate of 30fps, which is not supported by all projectors.  Be aware that you may have compatibility problems."));
+               break;
+       case 48:
+       case 50:
+       case 60:
+               /* You almost certainly want to go to half frame rate */
+               hint (String::compose(_("You are set up for a DCP at a frame rate of %1 fps.  This frame rate is not supported by all projectors.  You are advised to change the DCP frame rate to %2 fps."), film->video_frame_rate(), film->video_frame_rate() / 2));
+               break;
        }
 
        optional<double> lowest_speed_up;
@@ -277,20 +267,21 @@ Hints::thread ()
        struct timeval last_pulse;
        gettimeofday (&last_pulse, 0);
 
-       while (!player->pass()) {
+       try {
+               while (!player->pass()) {
 
-               struct timeval now;
-               gettimeofday (&now, 0);
-               if ((seconds(now) - seconds(last_pulse)) > 1) {
-                       {
-                               boost::mutex::scoped_lock lm (_mutex);
+                       struct timeval now;
+                       gettimeofday (&now, 0);
+                       if ((seconds(now) - seconds(last_pulse)) > 1) {
                                if (_stop) {
                                        break;
                                }
+                               emit (bind (boost::ref(Pulse)));
+                               last_pulse = now;
                        }
-                       emit (bind (boost::ref(Pulse)));
-                       last_pulse = now;
                }
+       } catch (...) {
+               store_current ();
        }
 
        emit (bind(boost::ref(Finished)));
@@ -325,9 +316,13 @@ Hints::text (PlayerText text, TextType type, DCPTimePeriod period)
                _too_many_ccap_lines = true;
        }
 
-       if (!_overlap_ccap && _last && _last->overlap(period)) {
+       shared_ptr<const Film> film = _film.lock ();
+       DCPOMATIC_ASSERT (film);
+
+       /* XXX: maybe overlapping closed captions (i.e. different languages) are OK with Interop? */
+       if (film->interop() && !_overlap_ccap && _last && _last->overlap(period)) {
                _overlap_ccap = true;
-               hint (_("You have overlapping closed captions, which are not allowed."));
+               hint (_("You have overlapping closed captions, which are not allowed in Interop DCPs.  Change your DCP standard to SMPTE."));
        }
 
        _last = period;