/*
- Copyright (C) 2016-2021 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2016-2022 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
*/
-#include "dcp_content_type.h"
-#include "hints.h"
-#include "types.h"
-#include "film.h"
-#include "content.h"
-#include "video_content.h"
-#include "text_content.h"
-#include "audio_processor.h"
-#include "font.h"
-#include "font_data.h"
-#include "ratio.h"
+
#include "audio_analysis.h"
+#include "audio_content.h"
+#include "audio_processor.h"
#include "compose.hpp"
-#include "util.h"
+#include "config.h"
+#include "constants.h"
+#include "content.h"
#include "cross.h"
+#include "dcp_content_type.h"
+#include "film.h"
+#include "font.h"
+#include "hints.h"
+#include "maths_util.h"
#include "player.h"
+#include "ratio.h"
+#include "text_content.h"
+#include "video_content.h"
#include "writer.h"
#include <dcp/cpl.h>
#include <dcp/raw_convert.h>
#include "i18n.h"
+
using std::cout;
using std::make_shared;
using std::max;
-using std::min;
-using std::pair;
using std::shared_ptr;
using std::string;
-using std::vector;
using std::weak_ptr;
using boost::optional;
using boost::bind;
}
+
void
Hints::start ()
{
_thread = boost::thread (bind(&Hints::thread, this));
}
+
Hints::~Hints ()
{
boost::this_thread::disable_interruption dis;
{
auto const film_container = film()->container()->id();
if (film_container != "185" && film_container != "239") {
- 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"));
+ 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."));
}
}
for (auto i: film()->content()) {
for (auto j: i->text) {
for (auto k: j->fonts()) {
- optional<boost::filesystem::path> const p = k->file ();
+ auto const p = k->file ();
if (p && boost::filesystem::file_size(p.get()) >= (MAX_FONT_FILE_SIZE - SIZE_SLACK)) {
big_font_files = true;
}
{
int vob = 0;
for (auto i: film()->content()) {
- if (boost::algorithm::starts_with (i->path(0).filename().string(), "VTS_")) {
+ if (boost::algorithm::starts_with(i->path(0).filename().string(), "VTS_")) {
++vob;
}
}
ch = ch.substr (0, ch.length() - 2);
- if (!ch.empty ()) {
- hint (String::compose (
+ if (!ch.empty()) {
+ hint(String::compose(
_("Your audio level is very high (on %1). You should reduce the gain of your audio content."),
ch
)
void
Hints::thread ()
+try
{
+ start_of_thread ("Hints");
+
auto film = _film.lock ();
if (!film) {
return;
auto content = film->content ();
+ check_certificates ();
check_interop ();
check_big_font_files ();
check_few_audio_channels ();
check_ffec_and_ffmc_in_smpte_feature ();
check_out_of_range_markers ();
check_text_languages ();
+ check_audio_language ();
if (check_loudness_done) {
emit (bind(boost::ref(Progress), _("Examining subtitles and closed captions")));
emit (bind(boost::ref(Progress), _("Examining audio, subtitles and closed captions")));
}
- auto player = make_shared<Player>(film);
+ auto player = make_shared<Player>(film, Image::Alignment::COMPACT);
player->set_ignore_video ();
- if (check_loudness_done) {
+ if (check_loudness_done || _disable_audio_analysis) {
/* We don't need to analyse audio because we already loaded a suitable analysis */
player->set_ignore_audio ();
}
struct timeval last_pulse;
gettimeofday (&last_pulse, 0);
- try {
- while (!player->pass()) {
+ _writer->write (player->get_subtitle_fonts());
- struct timeval now;
- gettimeofday (&now, 0);
- if ((seconds(now) - seconds(last_pulse)) > 1) {
- if (_stop) {
- break;
- }
- emit (bind (boost::ref(Pulse)));
- last_pulse = now;
+ while (!player->pass()) {
+
+ struct timeval now;
+ gettimeofday (&now, 0);
+ if ((seconds(now) - seconds(last_pulse)) > 1) {
+ if (_stop) {
+ return;
}
+ emit (bind (boost::ref(Pulse)));
+ last_pulse = now;
}
- } catch (...) {
- store_current ();
}
if (!check_loudness_done) {
check_loudness ();
}
- _writer->write (player->get_subtitle_fonts());
if (_long_subtitle && !_very_long_subtitle) {
hint (_("At least one of your subtitle lines has more than 52 characters. It is recommended to make each line 52 characters at most in length."));
bool ccap_mxf_too_big = false;
bool subs_mxf_too_big = false;
- boost::filesystem::path dcp_dir = film->dir("hints") / dcpomatic::get_process_id();
+ auto dcp_dir = film->dir("hints") / dcpomatic::get_process_id();
boost::filesystem::remove_all (dcp_dir);
- try {
- _writer->finish (film->dir("hints") / dcpomatic::get_process_id());
- } catch (...) {
- store_current ();
- emit (bind(boost::ref(Finished)));
- return;
- }
+ _writer->finish (film->dir("hints") / dcpomatic::get_process_id());
dcp::DCP dcp (dcp_dir);
dcp.read ();
emit (bind(boost::ref(Finished)));
}
+catch (boost::thread_interrupted)
+{
+ /* The Hints object is being destroyed before it has finished, so just give up */
+}
+catch (...)
+{
+ store_current ();
+}
+
void
Hints::hint (string h)
}
}
}
+
+
+void
+Hints::check_audio_language ()
+{
+ auto content = film()->content();
+ auto mapped_audio =
+ std::find_if(content.begin(), content.end(), [](shared_ptr<const Content> c) {
+ return c->audio && !c->audio->mapping().mapped_output_channels().empty();
+ });
+
+ if (mapped_audio != content.end() && !film()->audio_language()) {
+ hint (_("Some of your content has audio but you have not set the audio language. It is advisable to set the audio language "
+ "in the \"DCP\" tab unless your audio has no spoken parts."));
+ }
+}
+
+
+void
+Hints::check_certificates ()
+{
+ auto bad = Config::instance()->check_certificates();
+ if (!bad) {
+ return;
+ }
+
+ switch (*bad) {
+ case Config::BAD_SIGNER_UTF8_STRINGS:
+ hint(_("The certificate chain that DCP-o-matic uses for signing DCPs and KDMs contains a small error "
+ "which will prevent DCPs from being validated correctly on some systems. You are advised to "
+ "re-create the signing certificate chain by clicking the \"Re-make certificates and key...\" "
+ "button in the Keys page of Preferences."));
+ break;
+ case Config::BAD_SIGNER_VALIDITY_TOO_LONG:
+ hint(_("The certificate chain that DCP-o-matic uses for signing DCPs and KDMs has a validity period "
+ "that is too long. This will cause problems playing back DCPs on some systems. "
+ "You are advised to re-create the signing certificate chain by clicking the "
+ "\"Re-make certificates and key...\" button in the Keys page of Preferences."));
+ break;
+ default:
+ /* Some bad situations can't happen here as DCP-o-matic would have refused to start until they are fixed */
+ break;
+ }
+}
+