From ddcd4f3ba0af3e9d49dbb68127317cd0d871a248 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 20 Dec 2020 23:41:52 +0100 Subject: [PATCH] Pass fonts from content around as FontData. i.e. as a block of memory rather than a file. Also, get the fonts from the decoder rather than the content. Together, these changes allow us to use fonts from SMPTE DCPs added as content. Before, fonts would be messed up in those cases (#1885). --- cscript | 4 ++-- src/lib/dcp_decoder.cc | 19 +++++++++++++++++++ src/lib/dcp_decoder.h | 2 ++ src/lib/dcp_encoder.cc | 7 ++++--- src/lib/dcp_subtitle_decoder.cc | 28 ++++++++++++++++++++++++++-- src/lib/dcp_subtitle_decoder.h | 7 ++++++- src/lib/decoder.h | 5 +++++ src/lib/font_data.h | 7 +++++++ src/lib/hints.cc | 1 + src/lib/player.cc | 16 +++++++--------- src/lib/player.h | 4 ++-- src/lib/reel_writer.cc | 22 +++++++++++++--------- src/lib/reel_writer.h | 9 ++++++--- src/lib/string_text_file_decoder.cc | 14 ++++++++++++++ src/lib/string_text_file_decoder.h | 2 ++ src/lib/subtitle_encoder.cc | 10 ++++++---- src/lib/subtitle_encoder.h | 1 + src/lib/writer.cc | 10 +++++----- src/lib/writer.h | 6 +++--- test/data | 2 +- 20 files changed, 132 insertions(+), 44 deletions(-) diff --git a/cscript b/cscript index 634f343e8..4ae6490ab 100644 --- a/cscript +++ b/cscript @@ -375,8 +375,8 @@ def dependencies(target, options): (target.platform == 'osx' and target.bits == 64) or (target.platform == 'windows')) else {} - deps.append(('libdcp', '2b522d0', cpp_lib_options)) - deps.append(('libsub', 'dcd8bf5', cpp_lib_options)) + deps.append(('libdcp', 'c6665c1', cpp_lib_options)) + deps.append(('libsub', '64eb116', cpp_lib_options)) deps.append(('leqm-nrt', 'carl')) deps.append(('rtaudio', 'carl')) # We get our OpenSSL libraries from the environment, but we diff --git a/src/lib/dcp_decoder.cc b/src/lib/dcp_decoder.cc index 758ddea26..17710a3bd 100644 --- a/src/lib/dcp_decoder.cc +++ b/src/lib/dcp_decoder.cc @@ -56,7 +56,9 @@ using std::list; using std::cout; +using std::map; using std::string; +using std::vector; using boost::shared_ptr; using boost::dynamic_pointer_cast; using boost::optional; @@ -487,3 +489,20 @@ DCPDecoder::position () const { return ContentTime::from_frames(_offset, _dcp_content->active_video_frame_rate(film())) + _next; } + + +vector +DCPDecoder::fonts () const +{ + vector data; + BOOST_FOREACH (shared_ptr i, _reels) { + if (i->main_subtitle() && i->main_subtitle()->asset()) { + map fm = i->main_subtitle()->asset()->font_data(); + for (map::const_iterator j = fm.begin(); j != fm.end(); ++j) { + data.push_back (FontData(j->first, j->second)); + } + } + } + return data; +} + diff --git a/src/lib/dcp_decoder.h b/src/lib/dcp_decoder.h index 1abe39a27..99bdb8bd4 100644 --- a/src/lib/dcp_decoder.h +++ b/src/lib/dcp_decoder.h @@ -59,6 +59,8 @@ public: bool pass (); void seek (dcpomatic::ContentTime t, bool accurate); + std::vector fonts () const; + std::string lazy_digest () const { return _lazy_digest; } diff --git a/src/lib/dcp_encoder.cc b/src/lib/dcp_encoder.cc index 1c5b00dd4..c530492cf 100644 --- a/src/lib/dcp_encoder.cc +++ b/src/lib/dcp_encoder.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2018 Carl Hetherington + Copyright (C) 2012-2020 Carl Hetherington This file is part of DCP-o-matic. @@ -46,6 +46,7 @@ using std::string; using std::cout; using std::list; +using std::vector; using boost::shared_ptr; using boost::weak_ptr; using boost::dynamic_pointer_cast; @@ -103,13 +104,13 @@ DCPEncoder::go () } if (_non_burnt_subtitles) { - list > fonts = _player->get_subtitle_fonts (); + vector fonts = _player->get_subtitle_fonts (); if (fonts.size() > 1 && _film->interop()) { /* Interop will ignore second and subsequent s so don't even write them as they upset some validators. */ - shared_ptr first = fonts.front (); + FontData first = fonts.front (); fonts.clear (); fonts.push_back (first); } diff --git a/src/lib/dcp_subtitle_decoder.cc b/src/lib/dcp_subtitle_decoder.cc index f34c495c0..16a738a51 100644 --- a/src/lib/dcp_subtitle_decoder.cc +++ b/src/lib/dcp_subtitle_decoder.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2014-2018 Carl Hetherington + Copyright (C) 2014-2020 Carl Hetherington This file is part of DCP-o-matic. @@ -21,10 +21,14 @@ #include "dcp_subtitle_decoder.h" #include "dcp_subtitle_content.h" #include +#include #include -using std::list; using std::cout; +using std::list; +using std::map; +using std::string; +using std::vector; using boost::shared_ptr; using boost::dynamic_pointer_cast; using boost::bind; @@ -43,6 +47,18 @@ DCPSubtitleDecoder::DCPSubtitleDecoder (shared_ptr film, shared_ptr< first = content_time_period(*_next).from; } text.push_back (shared_ptr (new TextDecoder (this, content->only_text(), first))); + + map fm = c->font_data(); + for (map::const_iterator j = fm.begin(); j != fm.end(); ++j) { + _fonts.push_back (FontData(j->first, j->second)); + } + + /* Add a default font for any LoadFont nodes in our file which we haven't yet found fonts for */ + BOOST_FOREACH (shared_ptr i, c->load_font_nodes()) { + if (fm.find(i->id) == fm.end()) { + _fonts.push_back (FontData(i->id, dcp::ArrayData(default_font_file()))); + } + } } void @@ -105,3 +121,11 @@ DCPSubtitleDecoder::content_time_period (shared_ptr s) const ContentTime::from_seconds (s->out().as_seconds ()) ); } + + +vector +DCPSubtitleDecoder::fonts () const +{ + return _fonts; +} + diff --git a/src/lib/dcp_subtitle_decoder.h b/src/lib/dcp_subtitle_decoder.h index 5bf6363ad..b53b88ded 100644 --- a/src/lib/dcp_subtitle_decoder.h +++ b/src/lib/dcp_subtitle_decoder.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Carl Hetherington + Copyright (C) 2014-2020 Carl Hetherington This file is part of DCP-o-matic. @@ -20,6 +20,7 @@ #include "text_decoder.h" #include "dcp_subtitle.h" +#include "font_data.h" class DCPSubtitleContent; @@ -31,9 +32,13 @@ public: bool pass (); void seek (dcpomatic::ContentTime time, bool accurate); + std::vector fonts () const; + private: dcpomatic::ContentTimePeriod content_time_period (boost::shared_ptr s) const; std::list > _subtitles; std::list >::const_iterator _next; + + std::vector _fonts; }; diff --git a/src/lib/decoder.h b/src/lib/decoder.h index 97de208b2..169d55553 100644 --- a/src/lib/decoder.h +++ b/src/lib/decoder.h @@ -27,6 +27,7 @@ #include "types.h" #include "film.h" +#include "font_data.h" #include "dcpomatic_time.h" #include "weak_film.h" #include @@ -61,6 +62,10 @@ public: virtual void seek (dcpomatic::ContentTime time, bool accurate); virtual dcpomatic::ContentTime position () const; + + virtual std::vector fonts () const { + return std::vector(); + } }; #endif diff --git a/src/lib/font_data.h b/src/lib/font_data.h index 90543bec9..686fca7c9 100644 --- a/src/lib/font_data.h +++ b/src/lib/font_data.h @@ -19,6 +19,10 @@ */ +#ifndef DCPOMATIC_FONT_DATA_H +#define DCPOMATIC_FONT_DATA_H + + #include #include #include @@ -51,3 +55,6 @@ extern bool operator!= (FontData const& a, FontData const& b); } + + +#endif diff --git a/src/lib/hints.cc b/src/lib/hints.cc index ffe6d8e73..9781f24bb 100644 --- a/src/lib/hints.cc +++ b/src/lib/hints.cc @@ -27,6 +27,7 @@ #include "text_content.h" #include "audio_processor.h" #include "font.h" +#include "font_data.h" #include "ratio.h" #include "audio_analysis.h" #include "compose.hpp" diff --git a/src/lib/player.cc b/src/lib/player.cc index 7899f2e83..dd11694ef 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -448,20 +448,18 @@ Player::content_time_to_dcp (shared_ptr piece, ContentTime t) const return max (DCPTime (), DCPTime (t - piece->content->trim_start(), piece->frc) + piece->content->position()); } -list > +vector Player::get_subtitle_fonts () { boost::mutex::scoped_lock lm (_mutex); - list > fonts; + vector fonts; BOOST_FOREACH (shared_ptr i, _pieces) { - BOOST_FOREACH (shared_ptr j, i->content->text) { - /* XXX: things may go wrong if there are duplicate font IDs - with different font files. - */ - list > f = j->fonts (); - copy (f.begin(), f.end(), back_inserter (fonts)); - } + /* XXX: things may go wrong if there are duplicate font IDs + with different font files. + */ + vector f = i->decoder->fonts (); + copy (f.begin(), f.end(), back_inserter(fonts)); } return fonts; diff --git a/src/lib/player.h b/src/lib/player.h index ea81ae939..c695e02cd 100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@ -45,7 +45,7 @@ namespace dcp { } namespace dcpomatic { - class Font; + class FontData; } class AtmosContent; @@ -79,7 +79,7 @@ public: bool pass (); void seek (dcpomatic::DCPTime time, bool accurate); - std::list > get_subtitle_fonts (); + std::vector get_subtitle_fonts (); std::list get_reel_assets (); dcp::Size video_container_size () const { boost::mutex::scoped_lock lm (_mutex); diff --git a/src/lib/reel_writer.cc b/src/lib/reel_writer.cc index 41de4481e..009b2dc15 100644 --- a/src/lib/reel_writer.cc +++ b/src/lib/reel_writer.cc @@ -25,7 +25,7 @@ #include "log.h" #include "dcpomatic_log.h" #include "digester.h" -#include "font.h" +#include "font_data.h" #include "compose.hpp" #include "config.h" #include "audio_buffers.h" @@ -192,6 +192,8 @@ ReelWriter::ReelWriter ( film()->contains_atmos_content() ); } + + _default_font = dcp::ArrayData(default_font_file()); } /** @param frame reel-relative frame */ @@ -444,7 +446,8 @@ maybe_add_text ( int64_t picture_duration, shared_ptr reel, list const & refs, - list > const & fonts, + vector const & fonts, + dcp::ArrayData default_font, shared_ptr film, DCPTimePeriod period, boost::filesystem::path output_dcp, @@ -457,8 +460,8 @@ maybe_add_text ( if (asset) { /* Add the font to the subtitle content */ - BOOST_FOREACH (shared_ptr j, fonts) { - asset->add_font (j->id(), j->file().get_value_or(default_font_file())); + BOOST_FOREACH (FontData const& j, fonts) { + asset->add_font (j.id, j.data.get_value_or(default_font)); } if (dynamic_pointer_cast (asset)) { @@ -615,7 +618,7 @@ void ReelWriter::create_reel_text ( shared_ptr reel, list const & refs, - list > const& fonts, + vector const& fonts, int64_t duration, boost::filesystem::path output_dcp, bool ensure_subtitles, @@ -623,7 +626,7 @@ ReelWriter::create_reel_text ( ) const { shared_ptr subtitle = maybe_add_text ( - _subtitle_asset, duration, reel, refs, fonts, film(), _period, output_dcp, _text_only + _subtitle_asset, duration, reel, refs, fonts, _default_font, film(), _period, output_dcp, _text_only ); if (subtitle) { @@ -639,6 +642,7 @@ ReelWriter::create_reel_text ( reel, refs, fonts, + _default_font, film(), _period, output_dcp, @@ -648,7 +652,7 @@ ReelWriter::create_reel_text ( for (map >::const_iterator i = _closed_caption_assets.begin(); i != _closed_caption_assets.end(); ++i) { shared_ptr a = maybe_add_text ( - i->second, duration, reel, refs, fonts, film(), _period, output_dcp, _text_only + i->second, duration, reel, refs, fonts, _default_font, film(), _period, output_dcp, _text_only ); DCPOMATIC_ASSERT (a); a->set_annotation_text (i->first.name); @@ -662,7 +666,7 @@ ReelWriter::create_reel_text ( /* Make empty tracks for anything we've been asked to ensure but that we haven't added */ BOOST_FOREACH (DCPTextTrack i, ensure_closed_captions) { shared_ptr a = maybe_add_text ( - empty_text_asset(TEXT_CLOSED_CAPTION, i), duration, reel, refs, fonts, film(), _period, output_dcp, _text_only + empty_text_asset(TEXT_CLOSED_CAPTION, i), duration, reel, refs, fonts, _default_font, film(), _period, output_dcp, _text_only ); DCPOMATIC_ASSERT (a); a->set_annotation_text (i.name); @@ -705,7 +709,7 @@ ReelWriter::create_reel_markers (shared_ptr reel) const shared_ptr ReelWriter::create_reel ( list const & refs, - list > const & fonts, + vector const & fonts, boost::filesystem::path output_dcp, bool ensure_subtitles, set ensure_closed_captions diff --git a/src/lib/reel_writer.h b/src/lib/reel_writer.h index 388494247..3d214878b 100644 --- a/src/lib/reel_writer.h +++ b/src/lib/reel_writer.h @@ -31,7 +31,7 @@ #include namespace dcpomatic { - class Font; + class FontData; } class Film; @@ -78,7 +78,7 @@ public: void finish (boost::filesystem::path output_dcp); boost::shared_ptr create_reel ( std::list const & refs, - std::list > const & fonts, + std::vector const & fonts, boost::filesystem::path output_dcp, bool ensure_subtitles, std::set ensure_closed_captions @@ -111,7 +111,8 @@ private: void create_reel_sound (boost::shared_ptr reel, std::list const & refs) const; void create_reel_text ( boost::shared_ptr reel, - std::list const & refs, std::list > const& fonts, + std::list const & refs, + std::vector const& fonts, int64_t duration, boost::filesystem::path output_dcp, bool ensure_subtitles, @@ -132,6 +133,8 @@ private: boost::weak_ptr _job; bool _text_only; + dcp::ArrayData _default_font; + boost::shared_ptr _picture_asset; /** picture asset writer, or 0 if we are not writing any picture because we already have one */ boost::shared_ptr _picture_asset_writer; diff --git a/src/lib/string_text_file_decoder.cc b/src/lib/string_text_file_decoder.cc index 4cf34a3a9..691734d7b 100644 --- a/src/lib/string_text_file_decoder.cc +++ b/src/lib/string_text_file_decoder.cc @@ -89,3 +89,17 @@ StringTextFileDecoder::content_time_period (sub::Subtitle s) const ContentTime::from_seconds (s.to.all_as_seconds()) ); } + + +vector +StringTextFileDecoder::fonts () const +{ + vector data; + BOOST_FOREACH (shared_ptr i, text) { + BOOST_FOREACH (shared_ptr j, i->content()->fonts()) { + data.push_back (FontData(j)); + } + } + return data; +} + diff --git a/src/lib/string_text_file_decoder.h b/src/lib/string_text_file_decoder.h index 0c1d31deb..c57f40d24 100644 --- a/src/lib/string_text_file_decoder.h +++ b/src/lib/string_text_file_decoder.h @@ -34,6 +34,8 @@ public: void seek (dcpomatic::ContentTime time, bool accurate); bool pass (); + std::vector fonts () const; + private: dcpomatic::ContentTimePeriod content_time_period (sub::Subtitle s) const; diff --git a/src/lib/subtitle_encoder.cc b/src/lib/subtitle_encoder.cc index b018dcfb4..473d0698b 100644 --- a/src/lib/subtitle_encoder.cc +++ b/src/lib/subtitle_encoder.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2019 Carl Hetherington + Copyright (C) 2019-2020 Carl Hetherington This file is part of DCP-o-matic. @@ -18,7 +18,7 @@ */ -#include "font.h" +#include "font_data.h" #include "subtitle_encoder.h" #include "player.h" #include "compose.hpp" @@ -81,6 +81,8 @@ SubtitleEncoder::SubtitleEncoder (shared_ptr film, shared_ptr j BOOST_FOREACH (dcpomatic::DCPTimePeriod i, film->reels()) { _reels.push_back (i); } + + _default_font = dcp::ArrayData (default_font_file()); } void @@ -114,8 +116,8 @@ SubtitleEncoder::go () } if (!_film->interop() || _include_font) { - BOOST_FOREACH (shared_ptr j, _player->get_subtitle_fonts()) { - i->first->add_font (j->id(), default_font_file()); + BOOST_FOREACH (dcpomatic::FontData j, _player->get_subtitle_fonts()) { + i->first->add_font (j.id, _default_font); } } diff --git a/src/lib/subtitle_encoder.h b/src/lib/subtitle_encoder.h index 6484d1b0b..70b924564 100644 --- a/src/lib/subtitle_encoder.h +++ b/src/lib/subtitle_encoder.h @@ -58,4 +58,5 @@ private: int _reel_index; boost::optional _last; dcpomatic::DCPTime _length; + dcp::ArrayData _default_font; }; diff --git a/src/lib/writer.cc b/src/lib/writer.cc index fcf084c56..77a6bb589 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -32,7 +32,7 @@ #include "cross.h" #include "audio_buffers.h" #include "version.h" -#include "font.h" +#include "font_data.h" #include "util.h" #include "reel_writer.h" #include "text_content.h" @@ -792,14 +792,14 @@ Writer::write (PlayerText text, TextType type, optional track, DCP } void -Writer::write (list > fonts) +Writer::write (vector fonts) { /* Just keep a list of unique fonts and we'll deal with them in ::finish */ - BOOST_FOREACH (shared_ptr i, fonts) { + BOOST_FOREACH (FontData const& i, fonts) { bool got = false; - BOOST_FOREACH (shared_ptr j, _fonts) { - if (*i == *j) { + BOOST_FOREACH (FontData const& j, _fonts) { + if (i == j) { got = true; } } diff --git a/src/lib/writer.h b/src/lib/writer.h index 52cb222e7..b924337dd 100644 --- a/src/lib/writer.h +++ b/src/lib/writer.h @@ -40,7 +40,7 @@ namespace dcp { } namespace dcpomatic { - class Font; + class FontData; } class Film; @@ -112,7 +112,7 @@ public: void repeat (Frame, Eyes); void write (boost::shared_ptr, dcpomatic::DCPTime time); void write (PlayerText text, TextType type, boost::optional, dcpomatic::DCPTimePeriod period); - void write (std::list > fonts); + void write (std::vector fonts); void write (ReferencedReelAsset asset); void write (boost::shared_ptr atmos, dcpomatic::DCPTime time, AtmosMetadata metadata); void finish (boost::filesystem::path output_dcp); @@ -196,7 +196,7 @@ private: std::list _reel_assets; - std::list > _fonts; + std::vector _fonts; /** true if any reel has any subtitles */ bool _have_subtitles; diff --git a/test/data b/test/data index 578c16ee9..8a1b08134 160000 --- a/test/data +++ b/test/data @@ -1 +1 @@ -Subproject commit 578c16ee95b416d4dcec31c72219dac91e632169 +Subproject commit 8a1b08134f51c1172abd177eb64a4c790f854833 -- 2.30.2