diff options
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/create_cli.cc | 32 | ||||
| -rw-r--r-- | src/lib/create_cli.h | 1 | ||||
| -rw-r--r-- | src/lib/dcp_subtitle_content.cc | 13 | ||||
| -rw-r--r-- | src/lib/dcpomatic_socket.cc | 8 | ||||
| -rw-r--r-- | src/lib/hints.cc | 49 | ||||
| -rw-r--r-- | src/lib/util.cc | 22 | ||||
| -rw-r--r-- | src/lib/util.h | 1 |
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); |
