summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/create_cli.cc32
-rw-r--r--src/lib/create_cli.h1
-rw-r--r--src/lib/dcp_subtitle_content.cc13
-rw-r--r--src/lib/dcpomatic_socket.cc8
-rw-r--r--src/lib/hints.cc49
-rw-r--r--src/lib/util.cc22
-rw-r--r--src/lib/util.h1
7 files changed, 83 insertions, 43 deletions
diff --git a/src/lib/create_cli.cc b/src/lib/create_cli.cc
index 32834be23..3ef61fe11 100644
--- a/src/lib/create_cli.cc
+++ b/src/lib/create_cli.cc
@@ -85,6 +85,8 @@ help()
" --left-eye next piece of content is for the left eye\n"
" --right-eye next piece of content is for the right eye\n"
" --auto-crop next piece of content should be auto-cropped\n"
+ " --fill-crop next piece of content should be cropped to fit the container\n"
+ " (e.g. to crop the letterboxing from a scope-in-flat image)\n"
" --colourspace next piece of content is in the given colourspace: " + colour_conversions + "\n"
" --colorspace same as --colourspace\n"
" --channel <channel> next piece of content should be mapped to audio channel L, R, C, Lfe, Ls, Rs, BsL, BsR, HI, VI\n"
@@ -184,6 +186,7 @@ CreateCLI::CreateCLI(int argc, char* argv[])
optional<string> next_colour_conversion;
auto next_frame_type = VideoFrameType::TWO_D;
auto next_auto_crop = false;
+ auto next_fill_crop = false;
optional<dcp::Channel> channel;
optional<float> gain;
optional<float> fade_in;
@@ -225,6 +228,9 @@ CreateCLI::CreateCLI(int argc, char* argv[])
} else if (a == "--auto-crop") {
next_auto_crop = true;
claimed = true;
+ } else if (a == "--fill-crop") {
+ next_fill_crop = true;
+ claimed = true;
} else if (a == "--twok") {
_twok = true;
claimed = true;
@@ -331,6 +337,7 @@ CreateCLI::CreateCLI(int argc, char* argv[])
c.path = a;
c.frame_type = next_frame_type;
c.auto_crop = next_auto_crop;
+ c.fill_crop = next_fill_crop;
c.colour_conversion = next_colour_conversion;
c.channel = channel;
c.gain = gain;
@@ -341,6 +348,7 @@ CreateCLI::CreateCLI(int argc, char* argv[])
content.push_back(c);
next_frame_type = VideoFrameType::TWO_D;
next_auto_crop = false;
+ next_fill_crop = false;
next_colour_conversion = {};
channel = {};
gain = {};
@@ -555,6 +563,30 @@ CreateCLI::make_film(function<void (string)> error) const
video->set_crop(crop);
}
+ if (cli_content.fill_crop && video->size()) {
+ auto const source_ratio = video->size()->ratio();
+ Crop crop;
+ if (source_ratio < film->container().ratio()) {
+ /* Part to extract is wider than the source */
+ auto const height = video->size()->width / film->container().ratio();
+ crop.top = crop.bottom = (video->size()->height - height) / 2;
+ } else {
+ /* Container is wider than the source */
+ auto const width = video->size()->height * film->container().ratio();
+ crop.left = crop.right = (video->size()->width - width) / 2;
+ }
+
+ error(fmt::format(
+ "Cropped {} to {} left, {} right, {} top and {} bottom",
+ film_content->path(0).string(),
+ crop.left,
+ crop.right,
+ crop.top,
+ crop.bottom
+ ));
+
+ video->set_crop(crop);
+ }
if (cli_content.colour_conversion) {
video->set_colour_conversion(PresetColourConversion::from_id(*cli_content.colour_conversion).conversion);
}
diff --git a/src/lib/create_cli.h b/src/lib/create_cli.h
index 00abf85e5..cde8598cd 100644
--- a/src/lib/create_cli.h
+++ b/src/lib/create_cli.h
@@ -42,6 +42,7 @@ public:
boost::filesystem::path path;
VideoFrameType frame_type = VideoFrameType::TWO_D;
bool auto_crop = false;
+ bool fill_crop = false;
boost::optional<std::string> colour_conversion;
boost::optional<dcp::Channel> channel;
boost::optional<float> gain;
diff --git a/src/lib/dcp_subtitle_content.cc b/src/lib/dcp_subtitle_content.cc
index b285a78fe..ac8c4245b 100644
--- a/src/lib/dcp_subtitle_content.cc
+++ b/src/lib/dcp_subtitle_content.cc
@@ -38,6 +38,7 @@ using std::list;
using std::make_shared;
using std::shared_ptr;
using std::string;
+using std::vector;
using boost::optional;
using namespace dcpomatic;
@@ -45,7 +46,9 @@ using namespace dcpomatic;
DCPSubtitleContent::DCPSubtitleContent(boost::filesystem::path path)
: Content(path)
{
- text.push_back(make_shared<TextContent>(this, TextType::OPEN_SUBTITLE, TextType::OPEN_SUBTITLE));
+ text = vector<shared_ptr<TextContent>>{make_shared<TextContent>(this, TextType::OPEN_SUBTITLE, TextType::OPEN_SUBTITLE)};
+ /* Default to turning these subtitles on */
+ only_text()->set_use(true);
}
DCPSubtitleContent::DCPSubtitleContent(cxml::ConstNodePtr node, boost::optional<boost::filesystem::path> film_directory, int version)
@@ -63,20 +66,16 @@ DCPSubtitleContent::examine(shared_ptr<const Film> film, shared_ptr<Job> job, bo
auto subtitle_asset = load(path(0));
- auto iop = dynamic_pointer_cast<dcp::InteropTextAsset>(subtitle_asset);
- auto smpte = dynamic_pointer_cast<dcp::SMPTETextAsset>(subtitle_asset);
- if (smpte) {
+ if (auto smpte = dynamic_pointer_cast<dcp::SMPTETextAsset>(subtitle_asset)) {
set_video_frame_rate(film, smpte->edit_rate().numerator);
}
boost::mutex::scoped_lock lm(_mutex);
- /* Default to turning these subtitles on */
- only_text()->set_use(true);
-
_length = ContentTime::from_seconds(subtitle_asset->latest_text_out().as_seconds());
subtitle_asset->fix_empty_font_ids();
+ only_text()->clear_fonts();
add_fonts(only_text(), subtitle_asset);
}
diff --git a/src/lib/dcpomatic_socket.cc b/src/lib/dcpomatic_socket.cc
index d3bfbc309..876fa47d3 100644
--- a/src/lib/dcpomatic_socket.cc
+++ b/src/lib/dcpomatic_socket.cc
@@ -50,7 +50,11 @@ Socket::Socket (int timeout)
void
Socket::check ()
{
+#if BOOST_VERSION >= 108700
if (_deadline.expiry() <= std::chrono::system_clock::now()) {
+#else
+ if (_deadline.expires_at() <= std::chrono::system_clock::now()) {
+#endif
_socket.close();
_deadline.expires_at(std::chrono::time_point<std::chrono::system_clock>::max());
}
@@ -321,7 +325,11 @@ Socket::set_send_buffer_size (int size)
void
Socket::set_deadline_from_now(int seconds)
{
+#if BOOST_VERSION >= 108700
_deadline.expires_after(std::chrono::seconds(seconds));
+#else
+ _deadline.expires_from_now(std::chrono::seconds(seconds));
+#endif
}
void
diff --git a/src/lib/hints.cc b/src/lib/hints.cc
index 35eb640d4..90b88a6ef 100644
--- a/src/lib/hints.cc
+++ b/src/lib/hints.cc
@@ -44,16 +44,19 @@
#include <fmt/format.h>
#include <boost/algorithm/string.hpp>
#include <iostream>
+#include <numeric>
#include "i18n.h"
using std::cout;
using std::make_shared;
+using std::map;
using std::max;
using std::shared_ptr;
using std::string;
using std::weak_ptr;
+using std::vector;
using boost::optional;
using namespace dcpomatic;
#if BOOST_VERSION >= 106100
@@ -584,24 +587,42 @@ Hints::text(PlayerText text, TextType type, optional<DCPTextTrack> track, DCPTim
void
Hints::closed_caption(PlayerText text, DCPTimePeriod period)
{
- int lines = text.string.size();
- for (auto i: text.string) {
- if (utf8_strlen(i.text()) > MAX_CLOSED_CAPTION_LENGTH) {
- ++lines;
- if (!_long_ccap) {
- _long_ccap = true;
- hint(
- fmt::format(
- "At least one of your closed caption lines has more than {} characters. "
- "It is advisable to make each line {} characters at most in length.",
- MAX_CLOSED_CAPTION_LENGTH,
- MAX_CLOSED_CAPTION_LENGTH)
- );
+ map<float, vector<StringText>> lines;
+ for (auto const& line: text.string) {
+ bool added = false;
+ for (auto& existing: lines) {
+ if (std::abs(existing.first - line.v_position()) < dcp::ALIGN_EPSILON) {
+ existing.second.push_back(line);
+ added = true;
}
}
+ if (!added) {
+ lines[line.v_position()] = { line };
+ }
+ }
+
+ for (auto const& line: lines) {
+ int const length = std::accumulate(
+ line.second.begin(),
+ line.second.end(),
+ 0,
+ [](int acc, StringText const& text) {
+ return acc + dcp::utf8_strlen(text.text());
+ });
+
+ if (length > MAX_CLOSED_CAPTION_LENGTH && !_long_ccap) {
+ _long_ccap = true;
+ hint(
+ fmt::format(
+ "At least one of your closed caption lines has more than {} characters. "
+ "It is advisable to make each line {} characters at most in length.",
+ MAX_CLOSED_CAPTION_LENGTH,
+ MAX_CLOSED_CAPTION_LENGTH)
+ );
+ }
}
- if (!_too_many_ccap_lines && lines > MAX_CLOSED_CAPTION_LINES) {
+ if (!_too_many_ccap_lines && lines.size() > MAX_CLOSED_CAPTION_LINES) {
hint(fmt::format(_("Some of your closed captions span more than {} lines, so they will be truncated."), MAX_CLOSED_CAPTION_LINES));
_too_many_ccap_lines = true;
}
diff --git a/src/lib/util.cc b/src/lib/util.cc
index adc347ab1..60b93a0c4 100644
--- a/src/lib/util.cc
+++ b/src/lib/util.cc
@@ -171,7 +171,7 @@ time_to_hmsf(DCPTime time, Frame rate)
m -= h * 60;
char buffer[64];
- snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d.%02d", h, m, s, static_cast<int>(f));
+ snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d:%02d", h, m, s, static_cast<int>(f));
return buffer;
}
@@ -842,26 +842,6 @@ remap(shared_ptr<const AudioBuffers> input, int output_channels, AudioMapping ma
}
-size_t
-utf8_strlen(string s)
-{
- size_t const len = s.length();
- int N = 0;
- for (size_t i = 0; i < len; ++i) {
- unsigned char c = s[i];
- if ((c & 0xe0) == 0xc0) {
- ++i;
- } else if ((c & 0xf0) == 0xe0) {
- i += 2;
- } else if ((c & 0xf8) == 0xf0) {
- i += 3;
- }
- ++N;
- }
- return N;
-}
-
-
/** @param size Size of picture that the subtitle will be overlaid onto */
void
emit_subtitle_image(ContentTimePeriod period, dcp::TextImage sub, dcp::Size size, shared_ptr<TextDecoder> decoder)
diff --git a/src/lib/util.h b/src/lib/util.h
index aa003ff00..9863e5d94 100644
--- a/src/lib/util.h
+++ b/src/lib/util.h
@@ -84,7 +84,6 @@ extern std::string atmos_asset_filename(std::shared_ptr<dcp::AtmosAsset> asset,
extern std::string careful_string_filter(std::string s, std::wstring allowed = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_.+");
extern std::pair<int, int> audio_channel_types(std::list<int> mapped, int channels);
extern std::shared_ptr<AudioBuffers> remap(std::shared_ptr<const AudioBuffers> input, int output_channels, AudioMapping map);
-extern size_t utf8_strlen(std::string s);
extern void emit_subtitle_image(dcpomatic::ContentTimePeriod period, dcp::TextImage sub, dcp::Size size, std::shared_ptr<TextDecoder> decoder);
extern void copy_in_bits(boost::filesystem::path from, boost::filesystem::path to, std::function<void (float)>);
extern dcp::Size scale_for_display(dcp::Size s, dcp::Size display_container, dcp::Size film_container, PixelQuanta quanta);