From: Carl Hetherington Date: Wed, 17 Feb 2021 16:33:35 +0000 (+0100) Subject: Assorted C++11 tidying. X-Git-Tag: v2.15.130~1 X-Git-Url: https://main.carlh.net/gitweb/?p=dcpomatic.git;a=commitdiff_plain;h=33e13c4053138930f4b2f59349e441c76111059d Assorted C++11 tidying. --- diff --git a/src/lib/content.cc b/src/lib/content.cc index 1682b863d..49ab944be 100644 --- a/src/lib/content.cc +++ b/src/lib/content.cc @@ -18,10 +18,12 @@ */ + /** @file src/lib/content.cc * @brief Content class. */ + #include "content.h" #include "change_signaller.h" #include "util.h" @@ -42,18 +44,21 @@ #include "i18n.h" -using std::string; -using std::list; + using std::cout; -using std::vector; +using std::list; +using std::make_shared; using std::max; using std::pair; using std::shared_ptr; +using std::string; +using std::vector; using boost::optional; -using dcp::raw_convert; using dcp::locale_convert; +using dcp::raw_convert; using namespace dcpomatic; + int const ContentProperty::PATH = 400; int const ContentProperty::POSITION = 401; int const ContentProperty::LENGTH = 402; @@ -61,33 +66,29 @@ int const ContentProperty::TRIM_START = 403; int const ContentProperty::TRIM_END = 404; int const ContentProperty::VIDEO_FRAME_RATE = 405; + Content::Content () - : _position (0) - , _trim_start (0) - , _trim_end (0) - , _change_signals_frequent (false) + : _change_signals_frequent (false) { } + Content::Content (DCPTime p) : _position (p) - , _trim_start (0) - , _trim_end (0) , _change_signals_frequent (false) { } + Content::Content (boost::filesystem::path p) - : _position (0) - , _trim_start (0) - , _trim_end (0) - , _change_signals_frequent (false) + : _change_signals_frequent (false) { add_path (p); } + Content::Content (cxml::ConstNodePtr node) : _change_signals_frequent (false) { @@ -109,10 +110,11 @@ Content::Content (cxml::ConstNodePtr node) _video_frame_rate = node->optional_number_child ("VideoFrameRate"); } -Content::Content (vector > c) - : _position (c.front()->position ()) - , _trim_start (c.front()->trim_start ()) - , _trim_end (c.back()->trim_end ()) + +Content::Content (vector> c) + : _position (c.front()->position()) + , _trim_start (c.front()->trim_start()) + , _trim_end (c.back()->trim_end()) , _video_frame_rate (c.front()->video_frame_rate()) , _change_signals_frequent (false) { @@ -143,6 +145,7 @@ Content::Content (vector > c) } } + void Content::as_xml (xmlpp::Node* node, bool with_paths) const { @@ -150,20 +153,21 @@ Content::as_xml (xmlpp::Node* node, bool with_paths) const if (with_paths) { for (size_t i = 0; i < _paths.size(); ++i) { - xmlpp::Element* p = node->add_child("Path"); + auto p = node->add_child("Path"); p->add_child_text (_paths[i].string()); p->set_attribute ("mtime", raw_convert(_last_write_times[i])); } } - node->add_child("Digest")->add_child_text (_digest); - node->add_child("Position")->add_child_text (raw_convert (_position.get ())); - node->add_child("TrimStart")->add_child_text (raw_convert (_trim_start.get ())); - node->add_child("TrimEnd")->add_child_text (raw_convert (_trim_end.get ())); + node->add_child("Digest")->add_child_text(_digest); + node->add_child("Position")->add_child_text(raw_convert(_position.get())); + node->add_child("TrimStart")->add_child_text(raw_convert(_trim_start.get())); + node->add_child("TrimEnd")->add_child_text(raw_convert(_trim_end.get())); if (_video_frame_rate) { - node->add_child("VideoFrameRate")->add_child_text (raw_convert (_video_frame_rate.get())); + node->add_child("VideoFrameRate")->add_child_text(raw_convert(_video_frame_rate.get())); } } + string Content::calculate_digest () const { @@ -178,6 +182,7 @@ Content::calculate_digest () const return digest_head_tail(p, 1000000) + raw_convert(boost::filesystem::file_size(p.front())); } + void Content::examine (shared_ptr, shared_ptr job) { @@ -198,6 +203,7 @@ Content::examine (shared_ptr, shared_ptr job) } } + void Content::signal_change (ChangeType c, int p) { @@ -212,6 +218,7 @@ Content::signal_change (ChangeType c, int p) } } + void Content::set_position (shared_ptr film, DCPTime p, bool force_emit) { @@ -244,6 +251,7 @@ Content::set_position (shared_ptr film, DCPTime p, bool force_emit) } } + void Content::set_trim_start (ContentTime t) { @@ -266,6 +274,7 @@ Content::set_trim_start (ContentTime t) } } + void Content::set_trim_end (ContentTime t) { @@ -288,9 +297,10 @@ Content::clone () const /* notes is unused here (we assume) */ list notes; - return content_factory (cxml::NodePtr(new cxml::Node(node)), Film::current_state_version, notes); + return content_factory (make_shared(node), Film::current_state_version, notes); } + string Content::technical_summary () const { @@ -301,6 +311,7 @@ Content::technical_summary () const return s; } + DCPTime Content::length_after_trim (shared_ptr film) const { @@ -311,6 +322,7 @@ Content::length_after_trim (shared_ptr film) const return length; } + /** @return string which changes when something about this content changes which affects * the appearance of its video. */ @@ -325,6 +337,7 @@ Content::identifier () const return buffer; } + bool Content::paths_valid () const { @@ -337,6 +350,7 @@ Content::paths_valid () const return true; } + void Content::set_paths (vector paths) { @@ -354,6 +368,7 @@ Content::set_paths (vector paths) } } + string Content::path_summary () const { @@ -369,6 +384,7 @@ Content::path_summary () const return s; } + /** @return a list of properties that might be interesting to the user */ list Content::user_properties (shared_ptr film) const @@ -378,6 +394,7 @@ Content::user_properties (shared_ptr film) const return p; } + /** @return DCP times of points within this content where a reel split could occur */ list Content::reel_split_points (shared_ptr) const @@ -390,6 +407,7 @@ Content::reel_split_points (shared_ptr) const return t; } + void Content::set_video_frame_rate (double r) { @@ -409,6 +427,7 @@ Content::set_video_frame_rate (double r) } } + void Content::unset_video_frame_rate () { @@ -420,6 +439,7 @@ Content::unset_video_frame_rate () } } + double Content::active_video_frame_rate (shared_ptr film) const { @@ -437,6 +457,7 @@ Content::active_video_frame_rate (shared_ptr film) const return film->active_frame_rate_change(position()).source; } + void Content::add_properties (shared_ptr, list& p) const { @@ -465,6 +486,7 @@ Content::add_properties (shared_ptr, list& p) const } } + /** Take settings from the given content if it is of the correct type */ void Content::take_settings_from (shared_ptr c) @@ -485,16 +507,18 @@ Content::take_settings_from (shared_ptr c) } } + shared_ptr Content::only_text () const { DCPOMATIC_ASSERT (text.size() < 2); - if (text.empty ()) { - return shared_ptr (); + if (text.empty()) { + return {}; } return text.front (); } + shared_ptr Content::text_of_original_type (TextType type) const { @@ -504,9 +528,10 @@ Content::text_of_original_type (TextType type) const } } - return shared_ptr (); + return {}; } + void Content::add_path (boost::filesystem::path p) { diff --git a/src/lib/content.h b/src/lib/content.h index eafadd3ec..b8626e212 100644 --- a/src/lib/content.h +++ b/src/lib/content.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2018 Carl Hetherington + Copyright (C) 2013-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,10 +18,12 @@ */ + /** @file src/lib/content.h * @brief Content class. */ + #ifndef DCPOMATIC_CONTENT_H #define DCPOMATIC_CONTENT_H @@ -59,19 +61,23 @@ public: static int const VIDEO_FRAME_RATE; }; + /** @class Content * @brief A piece of content represented by one or more files on disk. */ -class Content : public std::enable_shared_from_this, public Signaller, public boost::noncopyable +class Content : public std::enable_shared_from_this, public Signaller { public: explicit Content (); Content (dcpomatic::DCPTime); Content (boost::filesystem::path); Content (cxml::ConstNodePtr); - Content (std::vector >); + Content (std::vector>); virtual ~Content () {} + Content (Content const&) = delete; + Content& operator= (Content const&) = delete; + /** Examine the content to establish digest, frame rates and any other * useful metadata. * @param job Job to use to report progress, or 0. diff --git a/src/lib/ffmpeg_file_encoder.cc b/src/lib/ffmpeg_file_encoder.cc index 0378f5156..782df4d20 100644 --- a/src/lib/ffmpeg_file_encoder.cc +++ b/src/lib/ffmpeg_file_encoder.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2017-2018 Carl Hetherington + Copyright (C) 2017-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,6 +18,7 @@ */ + #include "ffmpeg_encoder.h" #include "film.h" #include "job.h" @@ -31,24 +32,27 @@ #include "i18n.h" -using std::string; -using std::runtime_error; + using std::cout; +using std::make_shared; using std::pair; +using std::runtime_error; using std::shared_ptr; -using boost::bind; +using std::string; using std::weak_ptr; +using boost::bind; using boost::optional; using namespace dcpomatic; #if BOOST_VERSION >= 106100 using namespace boost::placeholders; #endif + int FFmpegFileEncoder::_video_stream_index = 0; int FFmpegFileEncoder::_audio_stream_index_base = 1; -class ExportAudioStream : public boost::noncopyable +class ExportAudioStream { public: ExportAudioStream (string codec_name, int channels, int frame_rate, AVSampleFormat sample_format, AVFormatContext* format_context, int stream_index) @@ -98,6 +102,9 @@ DCPOMATIC_ENABLE_WARNINGS avcodec_close (_codec_context); } + ExportAudioStream (ExportAudioStream const&) = delete; + ExportAudioStream& operator= (ExportAudioStream const&) = delete; + int frame_size () const { return _codec_context->frame_size; } @@ -128,13 +135,13 @@ DCPOMATIC_ENABLE_WARNINGS { DCPOMATIC_ASSERT (size); - AVFrame* frame = av_frame_alloc (); + auto frame = av_frame_alloc (); DCPOMATIC_ASSERT (frame); int const buffer_size = av_samples_get_buffer_size (0, channels, size, _codec_context->sample_fmt, 0); DCPOMATIC_ASSERT (buffer_size >= 0); - void* samples = av_malloc (buffer_size); + auto samples = av_malloc (buffer_size); DCPOMATIC_ASSERT (samples); frame->nb_samples = size; @@ -220,13 +227,11 @@ FFmpegFileEncoder::FFmpegFileEncoder ( boost::filesystem::path output ) : _audio_stream_per_channel (audio_stream_per_channel) - , _video_options (0) , _audio_channels (channels) , _output (output) , _video_frame_size (video_frame_size) , _video_frame_rate (video_frame_rate) , _audio_frame_rate (audio_frame_rate) - , _audio_frames (0) { _pixel_format = pixel_format (format); @@ -267,7 +272,7 @@ FFmpegFileEncoder::FFmpegFileEncoder ( throw runtime_error (String::compose("could not open FFmpeg output file %1 (%2)", _output.string(), r)); } - AVDictionary* options = 0; + AVDictionary* options = nullptr; if (avformat_write_header (_format_context, &options) < 0) { throw runtime_error ("could not write header to FFmpeg output file"); @@ -301,6 +306,7 @@ FFmpegFileEncoder::pixel_format (ExportFormat format) return AV_PIX_FMT_YUV422P10; } + void FFmpegFileEncoder::setup_video () { @@ -348,8 +354,8 @@ FFmpegFileEncoder::setup_audio () for (int i = 0; i < streams; ++i) { _audio_streams.push_back( - shared_ptr( - new ExportAudioStream(_audio_codec_name, channels_per_stream, _audio_frame_rate, _sample_format, _format_context, _audio_stream_index_base + i) + make_shared( + _audio_codec_name, channels_per_stream, _audio_frame_rate, _sample_format, _format_context, _audio_stream_index_base + i ) ); } @@ -395,6 +401,7 @@ DCPOMATIC_ENABLE_WARNINGS av_write_trailer (_format_context); } + void FFmpegFileEncoder::video (shared_ptr video, DCPTime time) { @@ -450,6 +457,7 @@ DCPOMATIC_ENABLE_WARNINGS } + /** Called when the player gives us some audio */ void FFmpegFileEncoder::audio (shared_ptr audio) @@ -468,6 +476,7 @@ FFmpegFileEncoder::audio (shared_ptr audio) } } + void FFmpegFileEncoder::audio_frame (int size) { @@ -487,18 +496,21 @@ FFmpegFileEncoder::audio_frame (int size) _audio_frames += size; } + void FFmpegFileEncoder::subtitle (PlayerText, DCPTimePeriod) { } + void FFmpegFileEncoder::buffer_free (void* opaque, uint8_t* data) { reinterpret_cast(opaque)->buffer_free2(data); } + void FFmpegFileEncoder::buffer_free2 (uint8_t* data) { diff --git a/src/lib/ffmpeg_file_encoder.h b/src/lib/ffmpeg_file_encoder.h index d644a1939..8a727106a 100644 --- a/src/lib/ffmpeg_file_encoder.h +++ b/src/lib/ffmpeg_file_encoder.h @@ -18,9 +18,11 @@ */ + #ifndef DCPOMATIC_FFMPEG_FILE_ENCODER_H #define DCPOMATIC_FFMPEG_FILE_ENCODER_H + #include "encoder.h" #include "event_history.h" #include "audio_mapping.h" @@ -68,15 +70,15 @@ private: static void buffer_free(void* opaque, uint8_t* data); void buffer_free2(uint8_t* data); - AVCodec* _video_codec; - AVCodecContext* _video_codec_context; - std::vector > _audio_streams; + AVCodec* _video_codec = nullptr; + AVCodecContext* _video_codec_context = nullptr; + std::vector> _audio_streams; bool _audio_stream_per_channel; - AVFormatContext* _format_context; - AVStream* _video_stream; + AVFormatContext* _format_context = nullptr; + AVStream* _video_stream = nullptr; AVPixelFormat _pixel_format; AVSampleFormat _sample_format; - AVDictionary* _video_options; + AVDictionary* _video_options = nullptr; std::string _video_codec_name; std::string _audio_codec_name; int _audio_channels; @@ -86,14 +88,14 @@ private: int _video_frame_rate; int _audio_frame_rate; - int64_t _audio_frames; + int64_t _audio_frames = 0; std::shared_ptr _pending_audio; /** Store of shared_ptr to keep them alive whilst raw pointers into their data have been passed to FFmpeg. */ - std::map > _pending_images; + std::map> _pending_images; boost::mutex _pending_images_mutex; static int _video_stream_index; diff --git a/src/lib/log.cc b/src/lib/log.cc index f84cfd3a5..97b649893 100644 --- a/src/lib/log.cc +++ b/src/lib/log.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2015 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,10 +18,12 @@ */ + /** @file src/log.cc * @brief A very simple logging class. */ + #include "log.h" #include "cross.h" #include "config.h" @@ -39,11 +41,11 @@ using std::make_shared; Log::Log () - : _types (0) { } + void Log::log (shared_ptr e) { @@ -56,6 +58,7 @@ Log::log (shared_ptr e) do_log (e); } + /** @param n String to log */ void Log::log (string message, int type) @@ -71,6 +74,7 @@ Log::log (string message, int type) do_log (e); } + void Log::dcp_log (dcp::NoteType type, string m) { @@ -87,6 +91,7 @@ Log::dcp_log (dcp::NoteType type, string m) } } + void Log::set_types (int t) { diff --git a/src/lib/log.h b/src/lib/log.h index c71f8ab16..142e46223 100644 --- a/src/lib/log.h +++ b/src/lib/log.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,13 +18,16 @@ */ + #ifndef DCPOMATIC_LOG_H #define DCPOMATIC_LOG_H + /** @file src/log.h * @brief A very simple logging class. */ + #include "log_entry.h" #include #include @@ -32,15 +35,19 @@ #include #include + /** @class Log * @brief A very simple logging class. */ -class Log : public boost::noncopyable +class Log { public: Log (); virtual ~Log () {} + Log (Log const&) = delete; + Log& operator= (Log const&) = delete; + void log (std::shared_ptr entry); void log (std::string message, int type); void dcp_log (dcp::NoteType type, std::string message); @@ -67,7 +74,8 @@ private: virtual void do_log (std::shared_ptr entry) = 0; /** bit-field of log types which should be put into the log (others are ignored) */ - int _types; + int _types = 0; }; + #endif diff --git a/src/lib/nanomsg.cc b/src/lib/nanomsg.cc index 4cc071370..b66d966af 100644 --- a/src/lib/nanomsg.cc +++ b/src/lib/nanomsg.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2020 Carl Hetherington + Copyright (C) 2020-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,6 +18,7 @@ */ + #include "nanomsg.h" #include "dcpomatic_log.h" #include "exceptions.h" @@ -26,12 +27,15 @@ #include #include + using std::string; using std::runtime_error; using boost::optional; + #define NANOMSG_URL "ipc:///tmp/dcpomatic.ipc" + Nanomsg::Nanomsg (bool server) { _socket = nn_socket (AF_SP, NN_PAIR); @@ -49,6 +53,7 @@ Nanomsg::Nanomsg (bool server) } } + bool Nanomsg::send (string s, int timeout) { @@ -69,18 +74,20 @@ Nanomsg::send (string s, int timeout) return true; } + optional Nanomsg::get_from_pending () { if (_pending.empty()) { - return optional(); + return {}; } - string const l = _pending.back(); + auto const l = _pending.back(); _pending.pop_back(); return l; } + void Nanomsg::recv_and_parse (int flags) { @@ -108,6 +115,7 @@ Nanomsg::recv_and_parse (int flags) nn_freemsg (buf); } + optional Nanomsg::receive (int timeout) { @@ -115,7 +123,7 @@ Nanomsg::receive (int timeout) nn_setsockopt (_socket, NN_SOL_SOCKET, NN_RCVTIMEO, &timeout, sizeof(int)); } - optional l = get_from_pending (); + auto l = get_from_pending (); if (l) { return *l; } diff --git a/src/lib/nanomsg.h b/src/lib/nanomsg.h index 9bd87098b..e3e917c4b 100644 --- a/src/lib/nanomsg.h +++ b/src/lib/nanomsg.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2020 Carl Hetherington + Copyright (C) 2020-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,22 +18,26 @@ */ + #include #include #include -#include -class Nanomsg : public boost::noncopyable + +class Nanomsg { public: explicit Nanomsg (bool server); + NanoMsg (Nanomsg const&) = delete; + NanoMsg& operator= (Nanomsg const&) = delete; + /** Try to send a message, waiting for some timeout before giving up. * @param timeout Timeout in milliseconds, or -1 for infinite timeout. * @return true if the send happened, false if there was a timeout. */ bool send (std::string s, int timeout); - + /** Try to receive a message, waiting for some timeout before giving up. * @param timeout Timeout in milliseconds, or -1 for infinite timeout. * @return Empty if the timeout was reached, otherwise the received string. diff --git a/src/lib/state.cc b/src/lib/state.cc index dd48516f4..5f7e9a701 100644 --- a/src/lib/state.cc +++ b/src/lib/state.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2018-2020 Carl Hetherington + Copyright (C) 2018-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,16 +18,21 @@ */ + #include "state.h" #include "cross.h" #include + using std::string; + boost::optional State::override_path; + /** @param file State filename - * @return Full path to write @file to */ + * @return Full path to write @file to. + */ boost::filesystem::path State::path (string file, bool create_directories) { diff --git a/src/lib/state.h b/src/lib/state.h index 35a93f52d..f1ed775a2 100644 --- a/src/lib/state.h +++ b/src/lib/state.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2018 Carl Hetherington + Copyright (C) 2018-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,23 +18,30 @@ */ + #ifndef DCPOMATIC_STATE_H #define DCPOMATIC_STATE_H -#include + #include #include -class State : public boost::noncopyable + +class State { public: + State () {} virtual ~State () {} virtual void read () = 0; virtual void write () const = 0; + State (State const&) = delete; + State& operator= (State const&) = delete; + /** If set, this overrides the standard path (in home, Library, AppData or wherever) for config.xml, cinemas.xml etc. */ static boost::optional override_path; static boost::filesystem::path path (std::string file, bool create_directories = true); }; + #endif diff --git a/src/lib/update_checker.cc b/src/lib/update_checker.cc index 0fad330fd..29d41cd92 100644 --- a/src/lib/update_checker.cc +++ b/src/lib/update_checker.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2014-2015 Carl Hetherington + Copyright (C) 2014-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,6 +18,7 @@ */ + #include "update_checker.h" #include "version.h" #include "util.h" @@ -28,8 +29,10 @@ #include #include + #define BUFFER_SIZE 1024 + using std::cout; using std::min; using std::string; @@ -38,8 +41,10 @@ using boost::is_any_of; using boost::ends_with; using dcp::raw_convert; + /** Singleton instance */ -UpdateChecker* UpdateChecker::_instance = 0; +UpdateChecker* UpdateChecker::_instance = nullptr; + static size_t write_callback_wrapper (void* data, size_t size, size_t nmemb, void* user) @@ -47,17 +52,13 @@ write_callback_wrapper (void* data, size_t size, size_t nmemb, void* user) return reinterpret_cast(user)->write_callback (data, size, nmemb); } + /** Construct an UpdateChecker. This sets things up and starts a thread to * do the work. */ UpdateChecker::UpdateChecker () : _buffer (new char[BUFFER_SIZE]) - , _offset (0) - , _curl (0) - , _state (NOT_RUN) - , _emits (0) - , _to_do (0) - , _terminate (false) + , _state (State::NOT_RUN) { _curl = curl_easy_init (); @@ -70,6 +71,7 @@ UpdateChecker::UpdateChecker () curl_easy_setopt (_curl, CURLOPT_USERAGENT, agent.c_str ()); } + void UpdateChecker::start () { @@ -79,6 +81,7 @@ UpdateChecker::start () #endif } + UpdateChecker::~UpdateChecker () { boost::this_thread::disable_interruption dis; @@ -97,6 +100,7 @@ UpdateChecker::~UpdateChecker () delete[] _buffer; } + /** Start running the update check */ void UpdateChecker::run () @@ -106,6 +110,7 @@ UpdateChecker::run () _condition.notify_one (); } + void UpdateChecker::thread () { @@ -130,7 +135,7 @@ UpdateChecker::thread () int r = curl_easy_perform (_curl); if (r != CURLE_OK) { - set_state (FAILED); + set_state (State::FAILED); return; } @@ -161,16 +166,17 @@ UpdateChecker::thread () } if (_stable || _test) { - set_state (YES); + set_state (State::YES); } else { - set_state (NO); + set_state (State::NO); } } catch (...) { - set_state (FAILED); + set_state (State::FAILED); } } } + size_t UpdateChecker::write_callback (void* data, size_t size, size_t nmemb) { @@ -180,6 +186,7 @@ UpdateChecker::write_callback (void* data, size_t size, size_t nmemb) return t; } + void UpdateChecker::set_state (State s) { @@ -189,9 +196,10 @@ UpdateChecker::set_state (State s) _emits++; } - emit (boost::bind (boost::ref (StateChanged))); + emit (boost::bind(boost::ref(StateChanged))); } + UpdateChecker * UpdateChecker::instance () { @@ -203,6 +211,7 @@ UpdateChecker::instance () return _instance; } + bool UpdateChecker::version_less_than (string const & a, string const & b) { @@ -214,24 +223,24 @@ UpdateChecker::version_less_than (string const & a, string const & b) DCPOMATIC_ASSERT (ap.size() == 3 && bp.size() == 3); if (ap[0] != bp[0]) { - return raw_convert (ap[0]) < raw_convert (bp[0]); + return raw_convert(ap[0]) < raw_convert(bp[0]); } if (ap[1] != bp[1]) { - return raw_convert (ap[1]) < raw_convert (bp[1]); + return raw_convert(ap[1]) < raw_convert(bp[1]); } float am; if (ends_with (ap[2], "devel")) { - am = raw_convert (ap[2].substr (0, ap[2].length() - 5)) + 0.5; + am = raw_convert(ap[2].substr(0, ap[2].length() - 5)) + 0.5; } else { - am = raw_convert (ap[2]); + am = raw_convert(ap[2]); } float bm; if (ends_with (bp[2], "devel")) { - bm = raw_convert (bp[2].substr (0, bp[2].length() - 5)) + 0.5; + bm = raw_convert(bp[2].substr(0, bp[2].length() - 5)) + 0.5; } else { - bm = raw_convert (bp[2]); + bm = raw_convert(bp[2]); } return am < bm; diff --git a/src/lib/update_checker.h b/src/lib/update_checker.h index 78ca40303..a0845b194 100644 --- a/src/lib/update_checker.h +++ b/src/lib/update_checker.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Carl Hetherington + Copyright (C) 2014-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,10 +18,12 @@ */ -/** @file src/lib/update.h + +/** @file src/lib/update_checker.h * @brief UpdateChecker class. */ + #include "signaller.h" #include #include @@ -29,17 +31,22 @@ #include #include + struct update_checker_test; + /** Class to check for the existance of an update for DCP-o-matic on a remote server */ -class UpdateChecker : public Signaller, public boost::noncopyable +class UpdateChecker : public Signaller { public: ~UpdateChecker (); + UpdateChecker (UpdateChecker const &); + UpdateChecker& operator= (UpdateChecker const &); + void run (); - enum State { + enum class State { YES, ///< there is an update FAILED, ///< the check failed, so we don't know NO, ///< there is no update @@ -83,19 +90,19 @@ private: void thread (); char* _buffer; - int _offset; - CURL* _curl; + int _offset = 0; + CURL* _curl = nullptr; /** mutex to protect _state, _stable, _test and _emits */ mutable boost::mutex _data_mutex; State _state; boost::optional _stable; boost::optional _test; - int _emits; + int _emits = 0; boost::thread _thread; boost::mutex _process_mutex; boost::condition _condition; - int _to_do; - bool _terminate; + int _to_do = 0; + bool _terminate = false; }; diff --git a/src/lib/writer.cc b/src/lib/writer.cc index e47fa973b..ddb95151c 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2019 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,6 +18,7 @@ */ + #include "writer.h" #include "compose.hpp" #include "film.h" @@ -46,21 +47,24 @@ #include "i18n.h" + /* OS X strikes again */ #undef set_key -using std::make_pair; -using std::pair; -using std::string; -using std::list; + using std::cout; +using std::dynamic_pointer_cast; +using std::list; +using std::make_pair; +using std::make_shared; using std::map; -using std::min; using std::max; -using std::vector; +using std::min; +using std::pair; using std::shared_ptr; +using std::string; +using std::vector; using std::weak_ptr; -using std::dynamic_pointer_cast; using boost::optional; #if BOOST_VERSION >= 106100 using namespace boost::placeholders; @@ -84,19 +88,12 @@ ignore_progress (float) Writer::Writer (weak_ptr weak_film, weak_ptr j, bool text_only) : WeakConstFilm (weak_film) , _job (j) - , _finish (false) - , _queued_full_in_memory (0) /* These will be reset to sensible values when J2KEncoder is created */ , _maximum_frames_in_memory (8) , _maximum_queue_size (8) - , _full_written (0) - , _fake_written (0) - , _repeat_written (0) - , _pushed_to_disk (0) , _text_only (text_only) - , _have_subtitles (false) { - shared_ptr job = _job.lock (); + auto job = _job.lock (); int reel_index = 0; auto const reels = film()->reels(); @@ -123,6 +120,7 @@ Writer::Writer (weak_ptr weak_film, weak_ptr j, bool text_only) } } + void Writer::start () { @@ -134,6 +132,7 @@ Writer::start () } } + Writer::~Writer () { if (!_text_only) { @@ -141,6 +140,7 @@ Writer::~Writer () } } + /** Pass a video frame to the writer for writing to disk at some point. * This method can be called with frames out of order. * @param encoded JPEG2000-encoded data. @@ -160,7 +160,7 @@ Writer::write (shared_ptr encoded, Frame frame, Eyes eyes) } QueueItem qi; - qi.type = QueueItem::FULL; + qi.type = QueueItem::Type::FULL; qi.encoded = encoded; qi.reel = video_reel (frame); qi.frame = frame - _reels[qi.reel].start (); @@ -183,12 +183,14 @@ Writer::write (shared_ptr encoded, Frame frame, Eyes eyes) _empty_condition.notify_all (); } + bool Writer::can_repeat (Frame frame) const { return frame > _reels[video_reel(frame)].start(); } + /** Repeat the last frame that was written to a reel as a new frame. * @param frame Frame index within the DCP of the new (repeated) frame. * @param eyes Eyes that this repeated frame image is for. @@ -207,7 +209,7 @@ Writer::repeat (Frame frame, Eyes eyes) } QueueItem qi; - qi.type = QueueItem::REPEAT; + qi.type = QueueItem::Type::REPEAT; qi.reel = video_reel (frame); qi.frame = frame - _reels[qi.reel].start (); if (film()->three_d() && eyes == Eyes::BOTH) { @@ -224,6 +226,7 @@ Writer::repeat (Frame frame, Eyes eyes) _empty_condition.notify_all (); } + void Writer::fake_write (Frame frame, Eyes eyes) { @@ -241,7 +244,7 @@ Writer::fake_write (Frame frame, Eyes eyes) Frame const frame_in_reel = frame - _reels[reel].start (); QueueItem qi; - qi.type = QueueItem::FAKE; + qi.type = QueueItem::Type::FAKE; { shared_ptr info_file = film()->info_file_handle(_reels[reel].period(), true); @@ -264,6 +267,7 @@ Writer::fake_write (Frame frame, Eyes eyes) _empty_condition.notify_all (); } + /** Write some audio frames to the DCP. * @param audio Audio data. * @param time Time of this data within the DCP. @@ -347,7 +351,7 @@ Writer::have_sequenced_image_at_queue_head () } _queue.sort (); - QueueItem const & f = _queue.front(); + auto const & f = _queue.front(); return _last_written[f.reel].next(f); } @@ -413,7 +417,7 @@ try if (!_queue.empty() && !have_sequenced_image_at_queue_head()) { LOG_WARNING (N_("Finishing writer with a left-over queue of %1:"), _queue.size()); for (auto const& i: _queue) { - if (i.type == QueueItem::FULL) { + if (i.type == QueueItem::Type::FULL) { LOG_WARNING (N_("- type FULL, frame %1, eyes %2"), i.frame, (int) i.eyes); } else { LOG_WARNING (N_("- type FAKE, size %1, frame %2, eyes %3"), i.size, i.frame, (int) i.eyes); @@ -425,19 +429,19 @@ try /* Write any frames that we can write; i.e. those that are in sequence. */ while (have_sequenced_image_at_queue_head ()) { - QueueItem qi = _queue.front (); + auto qi = _queue.front (); _last_written[qi.reel].update (qi); _queue.pop_front (); - if (qi.type == QueueItem::FULL && qi.encoded) { + if (qi.type == QueueItem::Type::FULL && qi.encoded) { --_queued_full_in_memory; } lock.unlock (); - ReelWriter& reel = _reels[qi.reel]; + auto& reel = _reels[qi.reel]; switch (qi.type) { - case QueueItem::FULL: + case QueueItem::Type::FULL: LOG_DEBUG_ENCODE (N_("Writer FULL-writes %1 (%2)"), qi.frame, (int) qi.eyes); if (!qi.encoded) { qi.encoded.reset (new ArrayData(film()->j2c_path(qi.reel, qi.frame, qi.eyes, false))); @@ -445,12 +449,12 @@ try reel.write (qi.encoded, qi.frame, qi.eyes); ++_full_written; break; - case QueueItem::FAKE: + case QueueItem::Type::FAKE: LOG_DEBUG_ENCODE (N_("Writer FAKE-writes %1"), qi.frame); reel.fake_write (qi.size); ++_fake_written; break; - case QueueItem::REPEAT: + case QueueItem::Type::REPEAT: LOG_DEBUG_ENCODE (N_("Writer REPEAT-writes %1"), qi.frame); reel.repeat_write (qi.frame, qi.eyes); ++_repeat_written; @@ -468,8 +472,8 @@ try /* Find one from the back of the queue */ _queue.sort (); - list::reverse_iterator i = _queue.rbegin (); - while (i != _queue.rend() && (i->type != QueueItem::FULL || !i->encoded)) { + auto i = _queue.rbegin (); + while (i != _queue.rend() && (i->type != QueueItem::Type::FULL || !i->encoded)) { ++i; } @@ -503,6 +507,7 @@ catch (...) store_current (); } + void Writer::terminate_thread (bool can_throw) { @@ -544,18 +549,16 @@ Writer::finish (boost::filesystem::path output_dcp) dcp::DCP dcp (output_dcp); - shared_ptr cpl ( - new dcp::CPL ( - film()->dcp_name(), - film()->dcp_content_type()->libdcp_kind () - ) + auto cpl = make_shared( + film()->dcp_name(), + film()->dcp_content_type()->libdcp_kind() ); dcp.add (cpl); /* Calculate digests for each reel in parallel */ - shared_ptr job = _job.lock (); + auto job = _job.lock (); if (job) { job->sub (_("Computing digests")); } @@ -563,7 +566,7 @@ Writer::finish (boost::filesystem::path output_dcp) boost::asio::io_service service; boost::thread_group pool; - shared_ptr work (new boost::asio::io_service::work (service)); + auto work = make_shared(service); int const threads = max (1, Config::instance()->master_encoding_threads ()); @@ -595,12 +598,12 @@ Writer::finish (boost::filesystem::path output_dcp) /* Add metadata */ - string creator = Config::instance()->dcp_creator(); + auto creator = Config::instance()->dcp_creator(); if (creator.empty()) { creator = String::compose("DCP-o-matic %1 %2", dcpomatic_version, dcpomatic_git_commit); } - string issuer = Config::instance()->dcp_issuer(); + auto issuer = Config::instance()->dcp_issuer(); if (issuer.empty()) { issuer = String::compose("DCP-o-matic %1 %2", dcpomatic_version, dcpomatic_git_commit); } @@ -646,8 +649,7 @@ Writer::finish (boost::filesystem::path output_dcp) cpl->set_additional_subtitle_languages(std::vector(sl.begin() + 1, sl.end())); } - shared_ptr signer; - signer = Config::instance()->signer_chain (); + auto signer = Config::instance()->signer_chain(); /* We did check earlier, but check again here to be on the safe side */ string reason; if (!signer->valid (&reason)) { @@ -671,22 +673,23 @@ Writer::finish (boost::filesystem::path output_dcp) write_cover_sheet (output_dcp); } + void Writer::write_cover_sheet (boost::filesystem::path output_dcp) { - boost::filesystem::path const cover = film()->file("COVER_SHEET.txt"); - FILE* f = fopen_boost (cover, "w"); + auto const cover = film()->file("COVER_SHEET.txt"); + auto f = fopen_boost (cover, "w"); if (!f) { throw OpenFileError (cover, errno, OpenFileError::WRITE); } - string text = Config::instance()->cover_sheet (); + auto text = Config::instance()->cover_sheet (); boost::algorithm::replace_all (text, "$CPL_NAME", film()->name()); boost::algorithm::replace_all (text, "$TYPE", film()->dcp_content_type()->pretty_name()); boost::algorithm::replace_all (text, "$CONTAINER", film()->container()->container_nickname()); boost::algorithm::replace_all (text, "$AUDIO_LANGUAGE", film()->isdcf_metadata().audio_language); - vector subtitle_languages = film()->subtitle_languages(); + auto subtitle_languages = film()->subtitle_languages(); if (subtitle_languages.empty()) { boost::algorithm::replace_all (text, "$SUBTITLE_LANGUAGE", "None"); } else { @@ -695,22 +698,22 @@ Writer::write_cover_sheet (boost::filesystem::path output_dcp) boost::uintmax_t size = 0; for ( - boost::filesystem::recursive_directory_iterator i = boost::filesystem::recursive_directory_iterator(output_dcp); + auto i = boost::filesystem::recursive_directory_iterator(output_dcp); i != boost::filesystem::recursive_directory_iterator(); ++i) { - if (boost::filesystem::is_regular_file (i->path ())) { - size += boost::filesystem::file_size (i->path ()); + if (boost::filesystem::is_regular_file (i->path())) { + size += boost::filesystem::file_size (i->path()); } } if (size > (1000000000L)) { - boost::algorithm::replace_all (text, "$SIZE", String::compose ("%1GB", dcp::locale_convert (size / 1000000000.0, 1, true))); + boost::algorithm::replace_all (text, "$SIZE", String::compose("%1GB", dcp::locale_convert(size / 1000000000.0, 1, true))); } else { - boost::algorithm::replace_all (text, "$SIZE", String::compose ("%1MB", dcp::locale_convert (size / 1000000.0, 1, true))); + boost::algorithm::replace_all (text, "$SIZE", String::compose("%1MB", dcp::locale_convert(size / 1000000.0, 1, true))); } - pair ch = audio_channel_types (film()->mapped_audio_channels(), film()->audio_channels()); - string description = String::compose("%1.%2", ch.first, ch.second); + auto ch = audio_channel_types (film()->mapped_audio_channels(), film()->audio_channels()); + auto description = String::compose("%1.%2", ch.first, ch.second); if (description == "0.0") { description = _("None"); @@ -738,6 +741,7 @@ Writer::write_cover_sheet (boost::filesystem::path output_dcp) fclose (f); } + /** @param frame Frame index within the whole DCP. * @return true if we can fake-write this frame. */ @@ -753,13 +757,14 @@ Writer::can_fake_write (Frame frame) const parameters in the asset writer. */ - ReelWriter const & reel = _reels[video_reel(frame)]; + auto const & reel = _reels[video_reel(frame)]; /* Make frame relative to the start of the reel */ frame -= reel.start (); return (frame != 0 && frame < reel.first_nonexistant_frame()); } + /** @param track Closed caption track if type == TextType::CLOSED_CAPTION */ void Writer::write (PlayerText text, TextType type, optional track, DCPTimePeriod period) @@ -790,6 +795,7 @@ Writer::write (PlayerText text, TextType type, optional track, DCP (*reel)->write (text, type, track, period); } + void Writer::write (vector fonts) { @@ -809,6 +815,7 @@ Writer::write (vector fonts) } } + bool operator< (QueueItem const & a, QueueItem const & b) { @@ -823,12 +830,14 @@ operator< (QueueItem const & a, QueueItem const & b) return static_cast (a.eyes) < static_cast (b.eyes); } + bool operator== (QueueItem const & a, QueueItem const & b) { return a.reel == b.reel && a.frame == b.frame && a.eyes == b.eyes; } + void Writer::set_encoder_threads (int threads) { @@ -837,12 +846,14 @@ Writer::set_encoder_threads (int threads) _maximum_queue_size = threads * 16; } + void Writer::write (ReferencedReelAsset asset) { _reel_assets.push_back (asset); } + size_t Writer::video_reel (int frame) const { @@ -856,6 +867,7 @@ Writer::video_reel (int frame) const return i; } + void Writer::set_digest_progress (Job* job, float progress) { diff --git a/src/lib/writer.h b/src/lib/writer.h index e7409de31..14d4b7faa 100644 --- a/src/lib/writer.h +++ b/src/lib/writer.h @@ -18,10 +18,12 @@ */ + /** @file src/lib/writer.h * @brief Writer class. */ + #include "atmos_metadata.h" #include "types.h" #include "player_text.h" @@ -33,6 +35,7 @@ #include #include + namespace dcp { class Data; } @@ -47,17 +50,13 @@ class Job; class ReferencedReelAsset; class ReelWriter; + struct QueueItem { public: - QueueItem () - : size (0) - , reel (0) - , frame (0) - , eyes (Eyes::BOTH) - {} - - enum Type { + QueueItem () {} + + enum class Type { /** a normal frame with some JPEG200 data */ FULL, /** a frame whose data already exists in the MXF, @@ -71,18 +70,20 @@ public: /** encoded data for FULL */ std::shared_ptr encoded; /** size of data for FAKE */ - int size; + int size = 0; /** reel index */ - size_t reel; + size_t reel = 0; /** frame index within the reel */ - int frame; + int frame = 0; /** eyes for FULL, FAKE and REPEAT */ - Eyes eyes; + Eyes eyes = Eyes::BOTH; }; + bool operator< (QueueItem const & a, QueueItem const & b); bool operator== (QueueItem const & a, QueueItem const & b); + /** @class Writer * @brief Class to manage writing JPEG2000 and audio data to assets on disk. * @@ -94,12 +95,15 @@ bool operator== (QueueItem const & a, QueueItem const & b); * will sort it out. write() for AudioBuffers must be called in order. */ -class Writer : public ExceptionStore, public boost::noncopyable, public WeakConstFilm +class Writer : public ExceptionStore, public WeakConstFilm { public: Writer (std::weak_ptr, std::weak_ptr, bool text_only = false); ~Writer (); + Writer (Writer const &) = delete; + Writer& operator= (Writer const &) = delete; + void start (); bool can_fake_write (Frame) const; @@ -136,11 +140,11 @@ private: /** our thread */ boost::thread _thread; /** true if our thread should finish */ - bool _finish; + bool _finish = false; /** queue of things to write to disk */ std::list _queue; /** number of FULL frames whose JPEG200 data is currently held in RAM */ - int _queued_full_in_memory; + int _queued_full_in_memory = 0; /** mutex for thread state */ mutable boost::mutex _state_mutex; /** condition to manage thread wakeups when we have nothing to do */ @@ -178,14 +182,14 @@ private: std::vector _last_written; /** number of FULL written frames */ - int _full_written; + int _full_written = 0; /** number of FAKE written frames */ - int _fake_written; - int _repeat_written; + int _fake_written = 0; + int _repeat_written = 0; /** number of frames pushed to disk and then recovered due to the limit of frames to be held in memory. */ - int _pushed_to_disk; + int _pushed_to_disk = 0; bool _text_only; @@ -197,7 +201,7 @@ private: std::vector _fonts; /** true if any reel has any subtitles */ - bool _have_subtitles; + bool _have_subtitles = false; /** all closed caption tracks that we have on any reel */ std::set _have_closed_captions; }; diff --git a/src/tools/dcpomatic.cc b/src/tools/dcpomatic.cc index 559853c40..be172ed2d 100644 --- a/src/tools/dcpomatic.cc +++ b/src/tools/dcpomatic.cc @@ -1468,11 +1468,11 @@ private: return; } - if (uc->state() == UpdateChecker::YES) { + if (uc->state() == UpdateChecker::State::YES) { auto dialog = new UpdateDialog (this, uc->stable(), uc->test()); dialog->ShowModal (); dialog->Destroy (); - } else if (uc->state() == UpdateChecker::FAILED) { + } else if (uc->state() == UpdateChecker::State::FAILED) { error_dialog (this, _("The DCP-o-matic download server could not be contacted.")); } else { error_dialog (this, _("There are no new versions of DCP-o-matic available.")); diff --git a/src/tools/dcpomatic_player.cc b/src/tools/dcpomatic_player.cc index ea7351157..72ac93cc7 100644 --- a/src/tools/dcpomatic_player.cc +++ b/src/tools/dcpomatic_player.cc @@ -873,11 +873,11 @@ private: return; } - if (uc->state() == UpdateChecker::YES) { + if (uc->state() == UpdateChecker::State::YES) { auto dialog = new UpdateDialog (this, uc->stable (), uc->test ()); dialog->ShowModal (); dialog->Destroy (); - } else if (uc->state() == UpdateChecker::FAILED) { + } else if (uc->state() == UpdateChecker::State::FAILED) { error_dialog (this, _("The DCP-o-matic download server could not be contacted.")); } else { error_dialog (this, _("There are no new versions of DCP-o-matic available."));