Make it quicker to cancel an analyse subtitle job (#2486).
[dcpomatic.git] / src / lib / analyse_subtitles_job.cc
index d95e859db8b44aedebb8de4668e1d9eb1c8c6361..d8d258ea54962af1d86c198242302690744feecb 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2020 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2020-2021 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
 
 */
 
+
 #include "analyse_subtitles_job.h"
-#include "playlist.h"
-#include "player.h"
-#include "subtitle_analysis.h"
 #include "bitmap_text.h"
+#include "image.h"
+#include "player.h"
+#include "playlist.h"
 #include "render_text.h"
+#include "subtitle_analysis.h"
 #include "text_content.h"
-#include "image.h"
 #include <iostream>
 
 #include "i18n.h"
 
+
 using std::make_shared;
 using std::shared_ptr;
 using std::string;
@@ -38,6 +40,7 @@ using std::weak_ptr;
 using namespace boost::placeholders;
 #endif
 
+
 AnalyseSubtitlesJob::AnalyseSubtitlesJob (shared_ptr<const Film> film, shared_ptr<Content> content)
        : Job (film)
        , _content (content)
@@ -77,7 +80,9 @@ AnalyseSubtitlesJob::run ()
        set_progress_unknown ();
 
        if (!content->text.empty()) {
-               while (!player->pass ()) {}
+               while (!player->pass ()) {
+                       boost::this_thread::interruption_point();
+               }
        }
 
        SubtitleAnalysis analysis (_bounding_box, content->text.front()->x_offset(), content->text.front()->y_offset());
@@ -89,7 +94,7 @@ AnalyseSubtitlesJob::run ()
 
 
 void
-AnalyseSubtitlesJob::analyse (PlayerText text, TextType type)
+AnalyseSubtitlesJob::analyse(PlayerText const& text, TextType type)
 {
        if (type != TextType::OPEN_SUBTITLE) {
                return;
@@ -103,14 +108,34 @@ AnalyseSubtitlesJob::analyse (PlayerText text, TextType type)
                }
        }
 
-       if (!text.string.empty()) {
-               /* We can provide dummy values for time and frame rate here as they are only used to calculate fades */
-               dcp::Size const frame = _film->frame_size();
-               for (auto i: render_text(text.string, text.fonts, frame, dcpomatic::DCPTime(), 24)) {
+       if (text.string.empty()) {
+               return;
+       }
+
+       /* We can provide dummy values for time and frame rate here as they are only used to calculate fades */
+       dcp::Size const frame = _film->frame_size();
+       std::vector<dcp::SubtitleStandard> override_standard;
+       if (_film->interop()) {
+               /* Since the film is Interop there is only one way the vpositions in the subs can be interpreted
+                * (we assume).
+                */
+               override_standard.push_back(dcp::SubtitleStandard::INTEROP);
+       } else {
+               /* We're using the great new SMPTE standard, which means there are two different ways that vposition
+                * could be interpreted; we will write SMPTE-2014 standard assets, but if the projection system uses
+                * SMPTE 20{07,10} instead they won't be placed how we intended.  To show the user this, make the
+                * bounding rectangle enclose both possibilities.
+                */
+               override_standard.push_back(dcp::SubtitleStandard::SMPTE_2007);
+               override_standard.push_back(dcp::SubtitleStandard::SMPTE_2014);
+       }
+
+       for (auto standard: override_standard) {
+               for (auto i: bounding_box(text.string, frame, standard)) {
                        dcpomatic::Rect<double> rect (
-                                       double(i.position.x) / frame.width, double(i.position.y) / frame.height,
-                                       double(i.image->size().width) / frame.width, double(i.image->size().height) / frame.height
-                                       );
+                               double(i.x) / frame.width, double(i.y) / frame.height,
+                               double(i.width) / frame.width, double(i.height) / frame.height
+                               );
                        if (!_bounding_box) {
                                _bounding_box = rect;
                        } else {