Make DCP text track language properly optional and ignore bad values on imported...
authorCarl Hetherington <cth@carlh.net>
Fri, 9 Apr 2021 19:20:10 +0000 (21:20 +0200)
committerCarl Hetherington <cth@carlh.net>
Fri, 9 Apr 2021 19:20:10 +0000 (21:20 +0200)
src/lib/dcp_examiner.cc
src/lib/dcp_text_track.cc
src/lib/dcp_text_track.h
src/lib/reel_writer.cc
src/lib/subtitle_encoder.cc
src/wx/closed_captions_dialog.cc
src/wx/dcp_text_track_dialog.cc
src/wx/text_panel.cc
test/closed_caption_test.cc
test/subtitle_reel_test.cc

index a0bc487d9a8d0df4b1114acbcb2a4d3d2962eaad..ad2220fc08b856644872a938060585d124e79ea8 100644 (file)
@@ -193,7 +193,7 @@ DCPExaminer::DCPExaminer (shared_ptr<const DCPContent> content, bool tolerant)
                        }
 
                        _text_count[static_cast<int>(TextType::CLOSED_CAPTION)]++;
-                       _dcp_text_tracks.push_back (DCPTextTrack(j->annotation_text(), j->language().get_value_or(_("Unknown"))));
+                       _dcp_text_tracks.push_back (DCPTextTrack(j->annotation_text(), try_to_parse_language(j->language())));
                }
 
                if (i->main_markers ()) {
index 1c73870aa6c37ffd88b6ee00f8f3f8967d93e056..0bd75127541ac7be96abf6854426aaf46df06446 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2018-2021 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
 
 */
 
+
 #include "dcp_text_track.h"
 #include "compose.hpp"
 #include <string>
 
+#include "i18n.h"
+
+
 using std::string;
+using boost::optional;
+
 
 DCPTextTrack::DCPTextTrack (cxml::ConstNodePtr node)
 {
        name = node->string_child("Name");
-       language = node->string_child("Language");
+       if (auto lang = node->optional_string_child("Language")) {
+               language = dcp::LanguageTag(*lang);
+       }
 }
 
-DCPTextTrack::DCPTextTrack (string name_, string language_)
+
+DCPTextTrack::DCPTextTrack (string name_, optional<dcp::LanguageTag> language_)
        : name (name_)
        , language (language_)
 {
 
 }
 
+
 string
 DCPTextTrack::summary () const
 {
-       return String::compose("%1 (%2)", name, language);
+       return String::compose("%1 (%2)", name, language ? language->to_string() : _("Unknown"));
 }
 
 void
 DCPTextTrack::as_xml (xmlpp::Element* parent) const
 {
        parent->add_child("Name")->add_child_text(name);
-       parent->add_child("Language")->add_child_text(language);
+       if (language) {
+               parent->add_child("Language")->add_child_text(language->to_string());
+       }
 }
 
+
 bool
 operator== (DCPTextTrack const & a, DCPTextTrack const & b)
 {
        return a.name == b.name && a.language == b.language;
 }
 
+
 bool
 operator!= (DCPTextTrack const & a, DCPTextTrack const & b)
 {
        return !(a == b);
 }
 
+
 bool
 operator< (DCPTextTrack const & a, DCPTextTrack const & b)
 {
index e6a146b3b1b1f8f919f7a0e7aa5d69e0565e654c..b29d8c4894f2111e3c3bbfe005b91ef70717c13c 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2018-2021 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
 
 */
 
+
 #ifndef DCPOMATIC_DCP_TEXT_TRACK_H
 #define DCPOMATIC_DCP_TEXT_TRACK_H
 
+
 #include "warnings.h"
+#include <dcp/language_tag.h>
 #include <libcxml/cxml.h>
 DCPOMATIC_DISABLE_WARNINGS
 #include <libxml++/libxml++.h>
 DCPOMATIC_ENABLE_WARNINGS
 
+
 class DCPTextTrack
 {
 public:
        DCPTextTrack () {}
        DCPTextTrack (cxml::ConstNodePtr node);
-       DCPTextTrack (std::string name_, std::string language_);
+       DCPTextTrack (std::string name_, boost::optional<dcp::LanguageTag> language_);
 
        std::string name;
-       std::string language;
+       boost::optional<dcp::LanguageTag> language;
 
        std::string summary () const;
        void as_xml (xmlpp::Element* parent) const;
@@ -45,4 +49,5 @@ bool operator== (DCPTextTrack const & a, DCPTextTrack const & b);
 bool operator!= (DCPTextTrack const & a, DCPTextTrack const & b);
 bool operator< (DCPTextTrack const & a, DCPTextTrack const & b);
 
+
 #endif
index 3eb43161e45c413727be579636af0afa81d97a84..2d88d71620de995cf326cc2a6f0f4b2bd7f87d86 100644 (file)
@@ -653,8 +653,8 @@ ReelWriter::create_reel_text (
                        );
                DCPOMATIC_ASSERT (a);
                a->set_annotation_text (i.first.name);
-               if (!i.first.language.empty()) {
-                       a->set_language (dcp::LanguageTag(i.first.language));
+               if (i.first.language) {
+                       a->set_language (i.first.language.get());
                }
 
                ensure_closed_captions.erase (i.first);
@@ -667,8 +667,8 @@ ReelWriter::create_reel_text (
                        );
                DCPOMATIC_ASSERT (a);
                a->set_annotation_text (i.name);
-               if (!i.language.empty()) {
-                       a->set_language (dcp::LanguageTag(i.language));
+               if (i.language) {
+                       a->set_language (i.language.get());
                }
        }
 }
@@ -782,8 +782,8 @@ ReelWriter::empty_text_asset (TextType type, optional<DCPTextTrack> track) const
                s->set_movie_title (film()->name());
                if (type == TextType::OPEN_SUBTITLE) {
                        s->set_language (lang.first ? lang.first->to_string() : "Unknown");
-               } else if (!track->language.empty()) {
-                       s->set_language (track->language);
+               } else if (track->language) {
+                       s->set_language (track->language->to_string());
                }
                s->set_reel_number (raw_convert<string> (_reel_index + 1));
                asset = s;
@@ -793,8 +793,8 @@ ReelWriter::empty_text_asset (TextType type, optional<DCPTextTrack> track) const
                s->set_metadata (mxf_metadata());
                if (type == TextType::OPEN_SUBTITLE && lang.first) {
                        s->set_language (*lang.first);
-               } else if (track && !track->language.empty()) {
-                       s->set_language (dcp::LanguageTag(track->language));
+               } else if (track && track->language) {
+                       s->set_language (dcp::LanguageTag(track->language->to_string()));
                }
                s->set_edit_rate (dcp::Fraction (film()->video_frame_rate(), 1));
                s->set_reel_number (_reel_index + 1);
index b61876ad6568f0fada6deb82d304a556f3c987aa..66957270fe91d0d6d2cbef7e11dd4223842931b8 100644 (file)
@@ -149,8 +149,8 @@ SubtitleEncoder::text (PlayerText subs, TextType type, optional<DCPTextTrack> tr
                        s->set_content_title_text (_film->name());
                        if (lang.first) {
                                s->set_language (*lang.first);
-                       } else if (!track->language.empty()) {
-                               s->set_language (dcp::LanguageTag(track->language));
+                       } else if (track->language) {
+                               s->set_language (track->language.get());
                        }
                        s->set_edit_rate (dcp::Fraction (_film->video_frame_rate(), 1));
                        s->set_reel_number (_reel_index + 1);
index e386beccf1938462d181c36a9074d02d5986b92a..7fcfc0808667a4d0d0271cda359044da98c5a088 100644 (file)
@@ -249,7 +249,7 @@ ClosedCaptionsDialog::update_tracks (shared_ptr<const Film> film)
 
        _track->Clear ();
        for (auto const& i: _tracks) {
-               _track->Append (std_to_wx(String::compose("%1 (%2)", i.name, i.language)));
+               _track->Append (std_to_wx(String::compose("%1 (%2)", i.name, i.language ? i.language->to_string() : wx_to_std(_("Unknown")))));
        }
 
        if (_track->GetCount() > 0) {
index b884aba51e387c9f1cc7cfb48a8bc2561bfee4b4..be31de0cea0ad323bc9661d66c623831f6ca7bb5 100644 (file)
@@ -33,7 +33,7 @@ DCPTextTrackDialog::DCPTextTrackDialog (wxWindow* parent)
        add (_("Name"), true);
        add (_name = new wxTextCtrl (this, wxID_ANY, wxT(""), wxDefaultPosition, wxSize(300, -1)));
        add (_("Language"), true);
-       _language = new LanguageTagWidget (this, wxT(""), dcp::LanguageTag("en-US"));
+       _language = new LanguageTagWidget (this, wxT(""), boost::none);
        add (_language->sizer());
 
        layout ();
@@ -44,5 +44,5 @@ DCPTextTrack
 DCPTextTrackDialog::get () const
 {
        DCPOMATIC_ASSERT (_language->get());
-       return DCPTextTrack(wx_to_std(_name->GetValue()), _language->get()->to_string());
+       return DCPTextTrack(wx_to_std(_name->GetValue()), _language->get());
 }
index cdd61e109ab1b0a9dd5663fc50f290adc6709e01..8e6d5cd68cc198854588d670c3762b6f58a8b9a7 100644 (file)
@@ -343,7 +343,7 @@ TextPanel::update_dcp_tracks ()
                /* XXX: don't display the "magic" track which has empty name and language;
                   this is a nasty hack (see also Film::closed_caption_tracks)
                */
-               if (!i.name.empty() || !i.language.empty()) {
+               if (!i.name.empty() || i.language) {
                        _dcp_track->Append (std_to_wx(i.summary()));
                }
        }
index 2b80c812eba948008ad4cf86310e55c84cf38f55..bcb6f84a76d021c6f73af57def91cb8321136b1e 100644 (file)
@@ -75,11 +75,11 @@ BOOST_AUTO_TEST_CASE (closed_caption_test2)
        auto film = new_test_film2 ("closed_caption_test2", { content1, content2, content3 }, &cl);
 
        content1->only_text()->set_type (TextType::CLOSED_CAPTION);
-       content1->only_text()->set_dcp_track (DCPTextTrack("First track", "fr-FR"));
+       content1->only_text()->set_dcp_track (DCPTextTrack("First track", dcp::LanguageTag("fr-FR")));
        content2->only_text()->set_type (TextType::CLOSED_CAPTION);
-       content2->only_text()->set_dcp_track (DCPTextTrack("Second track", "de-DE"));
+       content2->only_text()->set_dcp_track (DCPTextTrack("Second track", dcp::LanguageTag("de-DE")));
        content3->only_text()->set_type (TextType::CLOSED_CAPTION);
-       content3->only_text()->set_dcp_track (DCPTextTrack("Third track", "it-IT"));
+       content3->only_text()->set_dcp_track (DCPTextTrack("Third track", dcp::LanguageTag("it-IT")));
 
        make_and_verify_dcp (
                film,
index bb924cb9a74d5d8b70b9cdecf8ed0d2c5ae8634a..4a2021ba96ed136ba45533b733507b6df62d8857 100644 (file)
@@ -157,13 +157,13 @@ BOOST_AUTO_TEST_CASE (closed_captions_in_all_reels_test)
        film->examine_and_add_content (ccap1);
        BOOST_REQUIRE (!wait_for_jobs());
        ccap1->text.front()->set_type (TextType::CLOSED_CAPTION);
-       ccap1->text.front()->set_dcp_track (DCPTextTrack("Test", "de-DE"));
+       ccap1->text.front()->set_dcp_track (DCPTextTrack("Test", dcp::LanguageTag("de-DE")));
 
        auto ccap2 = content_factory("test/data/15s.srt").front();
        film->examine_and_add_content (ccap2);
        BOOST_REQUIRE (!wait_for_jobs());
        ccap2->text.front()->set_type (TextType::CLOSED_CAPTION);
-       ccap2->text.front()->set_dcp_track (DCPTextTrack("Other", "en-GB"));
+       ccap2->text.front()->set_dcp_track (DCPTextTrack("Other", dcp::LanguageTag("en-GB")));
 
        make_and_verify_dcp (
                film,