+}
+
+
+static
+bool
+subtitle_mxf_too_big (shared_ptr<dcp::SubtitleAsset> asset)
+{
+ return asset && asset->file() && boost::filesystem::file_size(*asset->file()) >= (MAX_TEXT_MXF_SIZE - SIZE_SLACK);
+}
+
+
+void
+Hints::thread ()
+{
+ shared_ptr<const Film> film = _film.lock ();
+ if (!film) {
+ return;
+ }
+
+ ContentList content = film->content ();
+
+ check_big_font_files ();
+ check_few_audio_channels ();
+ check_upmixers ();
+ check_incorrect_container ();
+ check_unusual_container ();
+ check_high_j2k_bandwidth ();
+ check_frame_rate ();
+ check_speed_up ();
+ check_vob ();
+ check_3d_in_2d ();
+ check_loudness ();
+ check_ffec_and_ffmc_in_smpte_feature ();
+
+ emit (bind(boost::ref(Progress), _("Examining closed captions")));
+
+ 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, _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 ();
+ }
+
+ _writer->write (player->get_subtitle_fonts());
+
+ bool ccap_xml_too_big = false;
+ bool ccap_mxf_too_big = false;
+ bool subs_mxf_too_big = false;
+
+ boost::filesystem::path 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;
+ }
+
+ dcp::DCP dcp (dcp_dir);
+ dcp.read ();
+ DCPOMATIC_ASSERT (dcp.cpls().size() == 1);
+ for (auto reel: dcp.cpls().front()->reels()) {
+ for (auto ccap: reel->closed_captions()) {
+ if (ccap->asset() && ccap->asset()->xml_as_string().length() > static_cast<size_t>(MAX_CLOSED_CAPTION_XML_SIZE - SIZE_SLACK) && !ccap_xml_too_big) {
+ hint (_(
+ "At least one of your closed caption files' XML part is larger than " MAX_CLOSED_CAPTION_XML_SIZE_TEXT
+ ". You should divide the DCP into shorter reels."
+ ));
+ ccap_xml_too_big = true;
+ }
+ if (subtitle_mxf_too_big(ccap->asset()) && !ccap_mxf_too_big) {
+ hint (_(
+ "At least one of your closed caption files is larger than " MAX_TEXT_MXF_SIZE_TEXT
+ " in total. You should divide the DCP into shorter reels."
+ ));
+ ccap_mxf_too_big = true;
+ }
+ }
+ if (reel->main_subtitle() && subtitle_mxf_too_big(reel->main_subtitle()->asset()) && !subs_mxf_too_big) {
+ hint (_(
+ "At least one of your subtitle files is larger than " MAX_TEXT_MXF_SIZE_TEXT " in total. "
+ "You should divide the DCP into shorter reels."
+ ));
+ subs_mxf_too_big = true;
+ }
+ }
+ boost::filesystem::remove_all (dcp_dir);
+
+ emit (bind(boost::ref(Finished)));
+}
+
+void
+Hints::hint (string h)
+{
+ emit(bind(boost::ref(Hint), h));
+}
+
+void
+Hints::text (PlayerText text, TextType type, optional<DCPTextTrack> track, DCPTimePeriod period)
+{
+ _writer->write (text, type, track, period);
+
+ switch (type) {
+ case TEXT_CLOSED_CAPTION:
+ closed_caption (text, period);
+ break;
+ case TEXT_OPEN_SUBTITLE:
+ open_subtitle (text, period);
+ break;
+ default:
+ break;
+ }
+}
+