X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Futil.cc;h=e2ce94dd9ea8f75eaf84a4841afe17298a99c211;hb=f660fe3f1be97f373318806a77b3ce3fcd53cb73;hp=667ee8ce95926f8c10bf24db3c71d2a41fa77b76;hpb=089b90439e745a218494e76b45e7df6215af01df;p=dcpomatic.git diff --git a/src/lib/util.cc b/src/lib/util.cc index 667ee8ce9..e2ce94dd9 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -46,6 +46,8 @@ #include #include #include +#include +#include extern "C" { #include #include @@ -63,6 +65,7 @@ extern "C" { #include "config.h" #include "ratio.h" #include "job.h" +#include "cross.h" #ifdef DCPOMATIC_WINDOWS #include "stack.hpp" #endif @@ -87,6 +90,7 @@ using std::istream; using std::numeric_limits; using std::pair; using std::ofstream; +using std::cout; using boost::shared_ptr; using boost::thread; using boost::lexical_cast; @@ -276,6 +280,15 @@ dcpomatic_setup () avfilter_register_all (); +#ifdef DCPOMATIC_OSX + /* Add our lib directory to the libltdl search path so that + xmlsec can find xmlsec1-openssl. + */ + boost::filesystem::path lib = app_contents (); + lib /= "lib"; + setenv ("LTDL_LIBRARY_PATH", lib.c_str (), 1); +#endif + libdcp::init (); Ratio::setup_ratios (); @@ -506,17 +519,27 @@ dcp_audio_frame_rate (int fs) Socket::Socket (int timeout) : _deadline (_io_service) , _socket (_io_service) + , _acceptor (0) , _timeout (timeout) { _deadline.expires_at (boost::posix_time::pos_infin); check (); } +Socket::~Socket () +{ + delete _acceptor; +} + void Socket::check () { if (_deadline.expires_at() <= boost::asio::deadline_timer::traits_type::now ()) { - _socket.close (); + if (_acceptor) { + _acceptor->cancel (); + } else { + _socket.close (); + } _deadline.expires_at (boost::posix_time::pos_infin); } @@ -527,7 +550,7 @@ Socket::check () * @param endpoint End-point to connect to. */ void -Socket::connect (boost::asio::ip::basic_resolver_entry const & endpoint) +Socket::connect (boost::asio::ip::tcp::endpoint endpoint) { _deadline.expires_from_now (boost::posix_time::seconds (_timeout)); boost::system::error_code ec = boost::asio::error::would_block; @@ -536,11 +559,35 @@ Socket::connect (boost::asio::ip::basic_resolver_entry con _io_service.run_one(); } while (ec == boost::asio::error::would_block); - if (ec || !_socket.is_open ()) { + if (ec) { + throw NetworkError (ec.message ()); + } + + if (!_socket.is_open ()) { throw NetworkError (_("connect timed out")); } } +void +Socket::accept (int port) +{ + _acceptor = new boost::asio::ip::tcp::acceptor (_io_service, boost::asio::ip::tcp::endpoint (boost::asio::ip::tcp::v4(), port)); + + _deadline.expires_from_now (boost::posix_time::seconds (_timeout)); + boost::system::error_code ec = boost::asio::error::would_block; + _acceptor->async_accept (_socket, boost::lambda::var(ec) = boost::lambda::_1); + do { + _io_service.run_one (); + } while (ec == boost::asio::error::would_block ); + + delete _acceptor; + _acceptor = 0; + + if (ec) { + throw NetworkError (ec.message ()); + } +} + /** Blocking write. * @param data Buffer to write. * @param size Number of bytes to write. @@ -732,7 +779,7 @@ audio_channel_name (int c) assert (MAX_AUDIO_CHANNELS == 6); /* TRANSLATORS: these are the names of audio channels; Lfe (sub) is the low-frequency - enhancement channel (sub-woofer)./ + enhancement channel (sub-woofer). */ string const channels[] = { _("Left"), @@ -748,24 +795,33 @@ audio_channel_name (int c) FrameRateConversion::FrameRateConversion (float source, int dcp) : skip (false) - , repeat (false) + , repeat (1) , change_speed (false) { - if (fabs (source / 2.0 - dcp) < (fabs (source - dcp))) { + if (fabs (source / 2.0 - dcp) < fabs (source - dcp)) { + /* The difference between source and DCP frame rate will be lower + (i.e. better) if we skip. + */ skip = true; } else if (fabs (source * 2 - dcp) < fabs (source - dcp)) { - repeat = true; + /* The difference between source and DCP frame rate would be better + if we repeated each frame once; it may be better still if we + repeated more than once. Work out the required repeat. + */ + repeat = round (dcp / source); } change_speed = !about_equal (source * factor(), dcp); - if (!skip && !repeat && !change_speed) { + if (!skip && repeat == 1 && !change_speed) { description = _("Content and DCP have the same rate.\n"); } else { if (skip) { description = _("DCP will use every other frame of the content.\n"); - } else if (repeat) { + } else if (repeat == 2) { description = _("Each content frame will be doubled in the DCP.\n"); + } else if (repeat > 2) { + description = String::compose (_("Each content frame will be repeated %1 more times in the DCP.\n"), repeat - 1); } if (change_speed) { @@ -807,7 +863,7 @@ tidy_for_filename (string f) { string t; for (size_t i = 0; i < f.length(); ++i) { - if (isalpha (f[i]) || f[i] == '_' || f[i] == '-') { + if (isalnum (f[i]) || f[i] == '_' || f[i] == '-') { t += f[i]; } else { t += '_'; @@ -816,4 +872,66 @@ tidy_for_filename (string f) return t; } + +shared_ptr +make_signer () +{ + boost::filesystem::path const sd = Config::instance()->signer_chain_directory (); + + /* Remake the chain if any of it is missing */ + + list files; + files.push_back ("ca.self-signed.pem"); + files.push_back ("intermediate.signed.pem"); + files.push_back ("leaf.signed.pem"); + files.push_back ("leaf.key"); + + list::const_iterator i = files.begin(); + while (i != files.end()) { + boost::filesystem::path p (sd); + p /= *i; + if (!boost::filesystem::exists (p)) { + boost::filesystem::remove_all (sd); + boost::filesystem::create_directories (sd); + libdcp::make_signer_chain (sd, openssl_path ()); + break; + } + + ++i; + } + + libdcp::CertificateChain chain; + + { + boost::filesystem::path p (sd); + p /= "ca.self-signed.pem"; + chain.add (shared_ptr (new libdcp::Certificate (p))); + } + + { + boost::filesystem::path p (sd); + p /= "intermediate.signed.pem"; + chain.add (shared_ptr (new libdcp::Certificate (p))); + } + + { + boost::filesystem::path p (sd); + p /= "leaf.signed.pem"; + chain.add (shared_ptr (new libdcp::Certificate (p))); + } + + boost::filesystem::path signer_key (sd); + signer_key /= "leaf.key"; + + return shared_ptr (new libdcp::Signer (chain, signer_key)); +} + +libdcp::Size +fit_ratio_within (float ratio, libdcp::Size full_frame) +{ + if (ratio < full_frame.ratio ()) { + return libdcp::Size (full_frame.height * ratio, full_frame.height); + } + return libdcp::Size (full_frame.width, full_frame.width / ratio); +}