From: Carl Hetherington Date: Fri, 9 Apr 2021 19:20:10 +0000 (+0200) Subject: Make DCP text track language properly optional and ignore bad values on imported... X-Git-Tag: v2.15.140~14 X-Git-Url: https://main.carlh.net/gitweb/?p=dcpomatic.git;a=commitdiff_plain;h=c27d14badb229c24533db65dbaee1939dce89455;hp=f10849bd52470a93f54bb90686aa9a3b1e72e796 Make DCP text track language properly optional and ignore bad values on imported DCPs (#1950). --- diff --git a/src/lib/dcp_examiner.cc b/src/lib/dcp_examiner.cc index a0bc487d9..ad2220fc0 100644 --- a/src/lib/dcp_examiner.cc +++ b/src/lib/dcp_examiner.cc @@ -193,7 +193,7 @@ DCPExaminer::DCPExaminer (shared_ptr content, bool tolerant) } _text_count[static_cast(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 ()) { diff --git a/src/lib/dcp_text_track.cc b/src/lib/dcp_text_track.cc index 1c73870aa..0bd751275 100644 --- a/src/lib/dcp_text_track.cc +++ b/src/lib/dcp_text_track.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2018 Carl Hetherington + Copyright (C) 2018-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,50 +18,65 @@ */ + #include "dcp_text_track.h" #include "compose.hpp" #include +#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 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) { diff --git a/src/lib/dcp_text_track.h b/src/lib/dcp_text_track.h index e6a146b3b..b29d8c489 100644 --- a/src/lib/dcp_text_track.h +++ b/src/lib/dcp_text_track.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2018 Carl Hetherington + Copyright (C) 2018-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,24 +18,28 @@ */ + #ifndef DCPOMATIC_DCP_TEXT_TRACK_H #define DCPOMATIC_DCP_TEXT_TRACK_H + #include "warnings.h" +#include #include DCPOMATIC_DISABLE_WARNINGS #include DCPOMATIC_ENABLE_WARNINGS + class DCPTextTrack { public: DCPTextTrack () {} DCPTextTrack (cxml::ConstNodePtr node); - DCPTextTrack (std::string name_, std::string language_); + DCPTextTrack (std::string name_, boost::optional language_); std::string name; - std::string language; + boost::optional 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 diff --git a/src/lib/reel_writer.cc b/src/lib/reel_writer.cc index 3eb43161e..2d88d7162 100644 --- a/src/lib/reel_writer.cc +++ b/src/lib/reel_writer.cc @@ -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 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 (_reel_index + 1)); asset = s; @@ -793,8 +793,8 @@ ReelWriter::empty_text_asset (TextType type, optional 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); diff --git a/src/lib/subtitle_encoder.cc b/src/lib/subtitle_encoder.cc index b61876ad6..66957270f 100644 --- a/src/lib/subtitle_encoder.cc +++ b/src/lib/subtitle_encoder.cc @@ -149,8 +149,8 @@ SubtitleEncoder::text (PlayerText subs, TextType type, optional 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); diff --git a/src/wx/closed_captions_dialog.cc b/src/wx/closed_captions_dialog.cc index e386beccf..7fcfc0808 100644 --- a/src/wx/closed_captions_dialog.cc +++ b/src/wx/closed_captions_dialog.cc @@ -249,7 +249,7 @@ ClosedCaptionsDialog::update_tracks (shared_ptr 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) { diff --git a/src/wx/dcp_text_track_dialog.cc b/src/wx/dcp_text_track_dialog.cc index b884aba51..be31de0ce 100644 --- a/src/wx/dcp_text_track_dialog.cc +++ b/src/wx/dcp_text_track_dialog.cc @@ -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()); } diff --git a/src/wx/text_panel.cc b/src/wx/text_panel.cc index cdd61e109..8e6d5cd68 100644 --- a/src/wx/text_panel.cc +++ b/src/wx/text_panel.cc @@ -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())); } } diff --git a/test/closed_caption_test.cc b/test/closed_caption_test.cc index 2b80c812e..bcb6f84a7 100644 --- a/test/closed_caption_test.cc +++ b/test/closed_caption_test.cc @@ -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, diff --git a/test/subtitle_reel_test.cc b/test/subtitle_reel_test.cc index bb924cb9a..4a2021ba9 100644 --- a/test/subtitle_reel_test.cc +++ b/test/subtitle_reel_test.cc @@ -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,