/*
- 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.
using boost::weak_ptr;
using boost::optional;
using boost::bind;
+using namespace dcpomatic;
+#if BOOST_VERSION >= 106100
+using namespace boost::placeholders;
+#endif
Hints::Hints (weak_ptr<const Film> film)
: _film (film)
- , _thread (0)
, _long_ccap (false)
, _overlap_ccap (false)
, _too_many_ccap_lines (false)
+ , _stop (false)
{
}
void
-Hints::stop_thread ()
+Hints::start ()
{
- if (_thread) {
- try {
- _thread->interrupt ();
- _thread->join ();
- } catch (...) {
-
- }
-
- delete _thread;
- _thread = 0;
- }
+ _thread = boost::thread (bind(&Hints::thread, this));
}
Hints::~Hints ()
{
- stop_thread ();
-}
+ boost::this_thread::disable_interruption dis;
-void
-Hints::start ()
-{
- stop_thread ();
- _long_ccap = false;
- _overlap_ccap = false;
- _too_many_ccap_lines = false;
- _thread = new boost::thread (bind(&Hints::thread, this));
+ try {
+ _stop = true;
+ _thread.interrupt ();
+ _thread.join ();
+ } catch (...) {}
}
void
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;
}
}
}
}
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();
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) {
- Ratio const * r = i->video->scale().ratio ();
+ Ratio const * r = Ratio::nearest_from_ratio(i->video->scaled_size(film->frame_size()).ratio());
if (r && r->id() == "239") {
++scope;
- } else if (r && r->id() != "239" && r->id() != "190") {
- ++flat_or_narrower;
+ } else if (r && r->id() != "239" && r->id() != "235" && r->id() != "190") {
+ ++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 narrower than 1.90:1 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") {
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;
for (size_t i = 0; i < sample_peak.size(); ++i) {
float const peak = max (sample_peak[i].peak, true_peak.empty() ? 0 : true_peak[i]);
- float const peak_dB = 20 * log10 (peak) + an->gain_correction (film->playlist ());
+ float const peak_dB = linear_to_db(peak) + an->gain_correction(film->playlist());
if (peak_dB > -3) {
ch += dcp::raw_convert<string> (short_audio_channel_name (i)) + ", ";
}
emit (bind(boost::ref(Progress), _("Examining closed captions")));
- shared_ptr<Player> player (new Player (film, film->playlist ()));
+ shared_ptr<Player> player (new Player(film));
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));
+ player->Text.connect (bind(&Hints::text, this, _1, _2, _4));
+
+ struct timeval last_pulse;
+ gettimeofday (&last_pulse, 0);
+
+ try {
+ while (!player->pass()) {
+
+ struct timeval now;
+ gettimeofday (&now, 0);
+ if ((seconds(now) - seconds(last_pulse)) > 1) {
+ if (_stop) {
+ break;
+ }
+ emit (bind (boost::ref(Pulse)));
+ last_pulse = now;
+ }
+ }
+ } catch (...) {
+ store_current ();
}
emit (bind(boost::ref(Finished)));
return;
}
- int lines = text.text.size();
- BOOST_FOREACH (StringText i, text.text) {
- if (i.text().length() > CLOSED_CAPTION_LENGTH) {
+ int lines = text.string.size();
+ BOOST_FOREACH (StringText i, text.string) {
+ if (utf8_strlen(i.text()) > CLOSED_CAPTION_LENGTH) {
++lines;
if (!_long_ccap) {
_long_ccap = true;
_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 is not allowed."));
+ hint (_("You have overlapping closed captions, which are not allowed in Interop DCPs. Change your DCP standard to SMPTE."));
}
_last = period;