Make it quicker to cancel an analyse subtitle job (#2486).
[dcpomatic.git] / src / lib / analyse_subtitles_job.cc
index b941824d6382fa0744c8b9e826f3e7ea45777893..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::string;
+
+using std::make_shared;
 using std::shared_ptr;
+using std::string;
 using std::weak_ptr;
 #if BOOST_VERSION >= 106100
 using namespace boost::placeholders;
 #endif
 
+
 AnalyseSubtitlesJob::AnalyseSubtitlesJob (shared_ptr<const Film> film, shared_ptr<Content> content)
        : Job (film)
        , _content (content)
@@ -62,12 +66,12 @@ AnalyseSubtitlesJob::json_name () const
 void
 AnalyseSubtitlesJob::run ()
 {
-       shared_ptr<Playlist> playlist (new Playlist());
-       shared_ptr<Content> content = _content.lock ();
+       auto playlist = make_shared<Playlist>();
+       auto content = _content.lock ();
        DCPOMATIC_ASSERT (content);
        playlist->add (_film, content);
 
-       shared_ptr<Player> player (new Player(_film, playlist));
+       auto player = make_shared<Player>(_film, playlist);
        player->set_ignore_audio ();
        player->set_fast ();
        player->set_play_referenced ();
@@ -76,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());
@@ -88,9 +94,9 @@ AnalyseSubtitlesJob::run ()
 
 
 void
-AnalyseSubtitlesJob::analyse (PlayerText text, TextType type)
+AnalyseSubtitlesJob::analyse(PlayerText const& text, TextType type)
 {
-       if (type != TEXT_OPEN_SUBTITLE) {
+       if (type != TextType::OPEN_SUBTITLE) {
                return;
        }
 
@@ -102,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 {