summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2020-12-20 23:41:52 +0100
committerCarl Hetherington <cth@carlh.net>2020-12-22 02:37:53 +0100
commitddcd4f3ba0af3e9d49dbb68127317cd0d871a248 (patch)
tree1091683b8dcaf82cd517b844be1d76f290f88f50 /src/lib
parentbf4446523dd891049cabf1bcd68d20def57bc731 (diff)
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).
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/dcp_decoder.cc19
-rw-r--r--src/lib/dcp_decoder.h2
-rw-r--r--src/lib/dcp_encoder.cc7
-rw-r--r--src/lib/dcp_subtitle_decoder.cc28
-rw-r--r--src/lib/dcp_subtitle_decoder.h7
-rw-r--r--src/lib/decoder.h5
-rw-r--r--src/lib/font_data.h7
-rw-r--r--src/lib/hints.cc1
-rw-r--r--src/lib/player.cc16
-rw-r--r--src/lib/player.h4
-rw-r--r--src/lib/reel_writer.cc22
-rw-r--r--src/lib/reel_writer.h9
-rw-r--r--src/lib/string_text_file_decoder.cc14
-rw-r--r--src/lib/string_text_file_decoder.h2
-rw-r--r--src/lib/subtitle_encoder.cc10
-rw-r--r--src/lib/subtitle_encoder.h1
-rw-r--r--src/lib/writer.cc10
-rw-r--r--src/lib/writer.h6
18 files changed, 129 insertions, 41 deletions
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<FontData>
+DCPDecoder::fonts () const
+{
+ vector<FontData> data;
+ BOOST_FOREACH (shared_ptr<dcp::Reel> i, _reels) {
+ if (i->main_subtitle() && i->main_subtitle()->asset()) {
+ map<string, dcp::ArrayData> fm = i->main_subtitle()->asset()->font_data();
+ for (map<string, dcp::ArrayData>::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<dcpomatic::FontData> 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 <cth@carlh.net>
+ Copyright (C) 2012-2020 Carl Hetherington <cth@carlh.net>
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<shared_ptr<Font> > fonts = _player->get_subtitle_fonts ();
+ vector<FontData> fonts = _player->get_subtitle_fonts ();
if (fonts.size() > 1 && _film->interop()) {
/* Interop will ignore second and subsequent <LoadFont>s so don't even
write them as they upset some validators.
*/
- shared_ptr<Font> 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 <cth@carlh.net>
+ Copyright (C) 2014-2020 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
@@ -21,10 +21,14 @@
#include "dcp_subtitle_decoder.h"
#include "dcp_subtitle_content.h"
#include <dcp/interop_subtitle_asset.h>
+#include <dcp/load_font_node.h>
#include <iostream>
-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<const Film> film, shared_ptr<
first = content_time_period(*_next).from;
}
text.push_back (shared_ptr<TextDecoder> (new TextDecoder (this, content->only_text(), first)));
+
+ map<string, dcp::ArrayData> fm = c->font_data();
+ for (map<string, dcp::ArrayData>::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<dcp::LoadFontNode> 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<dcp::Subtitle> s) const
ContentTime::from_seconds (s->out().as_seconds ())
);
}
+
+
+vector<dcpomatic::FontData>
+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 <cth@carlh.net>
+ Copyright (C) 2014-2020 Carl Hetherington <cth@carlh.net>
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<dcpomatic::FontData> fonts () const;
+
private:
dcpomatic::ContentTimePeriod content_time_period (boost::shared_ptr<dcp::Subtitle> s) const;
std::list<boost::shared_ptr<dcp::Subtitle> > _subtitles;
std::list<boost::shared_ptr<dcp::Subtitle> >::const_iterator _next;
+
+ std::vector<dcpomatic::FontData> _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 <boost/utility.hpp>
@@ -61,6 +62,10 @@ public:
virtual void seek (dcpomatic::ContentTime time, bool accurate);
virtual dcpomatic::ContentTime position () const;
+
+ virtual std::vector<dcpomatic::FontData> fonts () const {
+ return std::vector<dcpomatic::FontData>();
+ }
};
#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 <dcp/array_data.h>
#include <boost/optional.hpp>
#include <string>
@@ -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<const Piece> piece, ContentTime t) const
return max (DCPTime (), DCPTime (t - piece->content->trim_start(), piece->frc) + piece->content->position());
}
-list<shared_ptr<Font> >
+vector<FontData>
Player::get_subtitle_fonts ()
{
boost::mutex::scoped_lock lm (_mutex);
- list<shared_ptr<Font> > fonts;
+ vector<FontData> fonts;
BOOST_FOREACH (shared_ptr<Piece> i, _pieces) {
- BOOST_FOREACH (shared_ptr<TextContent> j, i->content->text) {
- /* XXX: things may go wrong if there are duplicate font IDs
- with different font files.
- */
- list<shared_ptr<Font> > 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<FontData> 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<boost::shared_ptr<dcpomatic::Font> > get_subtitle_fonts ();
+ std::vector<dcpomatic::FontData> get_subtitle_fonts ();
std::list<ReferencedReelAsset> 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<dcp::Reel> reel,
list<ReferencedReelAsset> const & refs,
- list<shared_ptr<Font> > const & fonts,
+ vector<FontData> const & fonts,
+ dcp::ArrayData default_font,
shared_ptr<const Film> 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<Font> 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<dcp::InteropSubtitleAsset> (asset)) {
@@ -615,7 +618,7 @@ void
ReelWriter::create_reel_text (
shared_ptr<dcp::Reel> reel,
list<ReferencedReelAsset> const & refs,
- list<shared_ptr<Font> > const& fonts,
+ vector<FontData> const& fonts,
int64_t duration,
boost::filesystem::path output_dcp,
bool ensure_subtitles,
@@ -623,7 +626,7 @@ ReelWriter::create_reel_text (
) const
{
shared_ptr<dcp::ReelSubtitleAsset> subtitle = maybe_add_text<dcp::ReelSubtitleAsset> (
- _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<DCPTextTrack, shared_ptr<dcp::SubtitleAsset> >::const_iterator i = _closed_caption_assets.begin(); i != _closed_caption_assets.end(); ++i) {
shared_ptr<dcp::ReelClosedCaptionAsset> a = maybe_add_text<dcp::ReelClosedCaptionAsset> (
- 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<dcp::ReelClosedCaptionAsset> a = maybe_add_text<dcp::ReelClosedCaptionAsset> (
- 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<dcp::Reel> reel) const
shared_ptr<dcp::Reel>
ReelWriter::create_reel (
list<ReferencedReelAsset> const & refs,
- list<shared_ptr<Font> > const & fonts,
+ vector<FontData> const & fonts,
boost::filesystem::path output_dcp,
bool ensure_subtitles,
set<DCPTextTrack> 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 <boost/weak_ptr.hpp>
namespace dcpomatic {
- class Font;
+ class FontData;
}
class Film;
@@ -78,7 +78,7 @@ public:
void finish (boost::filesystem::path output_dcp);
boost::shared_ptr<dcp::Reel> create_reel (
std::list<ReferencedReelAsset> const & refs,
- std::list<boost::shared_ptr<dcpomatic::Font> > const & fonts,
+ std::vector<dcpomatic::FontData> const & fonts,
boost::filesystem::path output_dcp,
bool ensure_subtitles,
std::set<DCPTextTrack> ensure_closed_captions
@@ -111,7 +111,8 @@ private:
void create_reel_sound (boost::shared_ptr<dcp::Reel> reel, std::list<ReferencedReelAsset> const & refs) const;
void create_reel_text (
boost::shared_ptr<dcp::Reel> reel,
- std::list<ReferencedReelAsset> const & refs, std::list<boost::shared_ptr<dcpomatic::Font> > const& fonts,
+ std::list<ReferencedReelAsset> const & refs,
+ std::vector<dcpomatic::FontData> const& fonts,
int64_t duration,
boost::filesystem::path output_dcp,
bool ensure_subtitles,
@@ -132,6 +133,8 @@ private:
boost::weak_ptr<Job> _job;
bool _text_only;
+ dcp::ArrayData _default_font;
+
boost::shared_ptr<dcp::PictureAsset> _picture_asset;
/** picture asset writer, or 0 if we are not writing any picture because we already have one */
boost::shared_ptr<dcp::PictureAssetWriter> _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<FontData>
+StringTextFileDecoder::fonts () const
+{
+ vector<FontData> data;
+ BOOST_FOREACH (shared_ptr<TextDecoder> i, text) {
+ BOOST_FOREACH (shared_ptr<Font> 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<dcpomatic::FontData> 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 <cth@carlh.net>
+ Copyright (C) 2019-2020 Carl Hetherington <cth@carlh.net>
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<const Film> film, shared_ptr<Job> 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<dcpomatic::Font> 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<dcpomatic::DCPTime> _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<DCPTextTrack> track, DCP
}
void
-Writer::write (list<shared_ptr<Font> > fonts)
+Writer::write (vector<FontData> fonts)
{
/* Just keep a list of unique fonts and we'll deal with them in ::finish */
- BOOST_FOREACH (shared_ptr<Font> i, fonts) {
+ BOOST_FOREACH (FontData const& i, fonts) {
bool got = false;
- BOOST_FOREACH (shared_ptr<Font> 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<const AudioBuffers>, dcpomatic::DCPTime time);
void write (PlayerText text, TextType type, boost::optional<DCPTextTrack>, dcpomatic::DCPTimePeriod period);
- void write (std::list<boost::shared_ptr<dcpomatic::Font> > fonts);
+ void write (std::vector<dcpomatic::FontData> fonts);
void write (ReferencedReelAsset asset);
void write (boost::shared_ptr<const dcp::AtmosFrame> atmos, dcpomatic::DCPTime time, AtmosMetadata metadata);
void finish (boost::filesystem::path output_dcp);
@@ -196,7 +196,7 @@ private:
std::list<ReferencedReelAsset> _reel_assets;
- std::list<boost::shared_ptr<dcpomatic::Font> > _fonts;
+ std::vector<dcpomatic::FontData> _fonts;
/** true if any reel has any subtitles */
bool _have_subtitles;