From: Carl Hetherington Date: Wed, 7 Apr 2021 20:15:01 +0000 (+0200) Subject: Assorted C++11/formatting cleanups. X-Git-Tag: v2.15.140~24 X-Git-Url: https://main.carlh.net/gitweb/?p=dcpomatic.git;a=commitdiff_plain;h=7bc2134d658778e04f1756c255e604b4ab5a5831 Assorted C++11/formatting cleanups. --- diff --git a/src/lib/audio_mapping.cc b/src/lib/audio_mapping.cc index 7734d168a..8b9f102a5 100644 --- a/src/lib/audio_mapping.cc +++ b/src/lib/audio_mapping.cc @@ -18,6 +18,7 @@ */ + #include "audio_mapping.h" #include "audio_processor.h" #include "digester.h" @@ -31,6 +32,7 @@ DCPOMATIC_ENABLE_WARNINGS #include #include + using std::list; using std::cout; using std::make_pair; @@ -44,12 +46,6 @@ using std::dynamic_pointer_cast; using boost::optional; using dcp::raw_convert; -AudioMapping::AudioMapping () - : _input_channels (0) - , _output_channels (0) -{ - -} /** Create an empty AudioMapping. * @param input_channels Number of input channels. @@ -60,6 +56,7 @@ AudioMapping::AudioMapping (int input_channels, int output_channels) setup (input_channels, output_channels); } + void AudioMapping::setup (int input_channels, int output_channels) { @@ -74,6 +71,7 @@ AudioMapping::setup (int input_channels, int output_channels) make_zero (); } + void AudioMapping::make_zero () { @@ -84,6 +82,7 @@ AudioMapping::make_zero () } } + struct ChannelRegex { ChannelRegex (string regex_, int channel_) @@ -95,6 +94,7 @@ struct ChannelRegex int channel; }; + void AudioMapping::make_default (AudioProcessor const * processor, optional filename) { @@ -145,12 +145,13 @@ AudioMapping::make_default (AudioProcessor const * processor, optionalnumber_child ("ContentChannels"), MAX_DCP_AUDIO_CHANNELS); + setup (node->number_child("ContentChannels"), MAX_DCP_AUDIO_CHANNELS); } else { - setup (node->number_child ("InputChannels"), node->number_child ("OutputChannels")); + setup (node->number_child("InputChannels"), node->number_child("OutputChannels")); } if (state_version <= 5) { @@ -216,6 +217,7 @@ AudioMapping::get (int input_channel, int output_channel) const return _gain[input_channel][output_channel]; } + void AudioMapping::as_xml (xmlpp::Node* node) const { @@ -232,6 +234,7 @@ AudioMapping::as_xml (xmlpp::Node* node) const } } + /** @return a string which is unique for a given AudioMapping configuration, for * differentiation between different AudioMappings. */ @@ -250,6 +253,7 @@ AudioMapping::digest () const return digester.get (); } + list AudioMapping::mapped_output_channels () const { @@ -271,6 +275,7 @@ AudioMapping::mapped_output_channels () const return mapped; } + void AudioMapping::unmap_all () { diff --git a/src/lib/audio_mapping.h b/src/lib/audio_mapping.h index 6bac0a7d8..4ef5aedb1 100644 --- a/src/lib/audio_mapping.h +++ b/src/lib/audio_mapping.h @@ -18,30 +18,35 @@ */ + /** @file src/lib/audio_mapping.h * @brief AudioMapping class. */ + #ifndef DCPOMATIC_AUDIO_MAPPING_H #define DCPOMATIC_AUDIO_MAPPING_H + #include #include #include + namespace xmlpp { class Node; } class AudioProcessor; + /** @class AudioMapping. * @brief A many-to-many mapping of audio channels. */ class AudioMapping { public: - AudioMapping (); + AudioMapping () {} AudioMapping (int input_channels, int output_channels); AudioMapping (cxml::ConstNodePtr, int); @@ -74,9 +79,10 @@ public: private: void setup (int input_channels, int output_channels); - int _input_channels; - int _output_channels; - std::vector > _gain; + int _input_channels = 0; + int _output_channels = 0; + std::vector> _gain; }; + #endif diff --git a/src/lib/audio_merger.cc b/src/lib/audio_merger.cc index 06eba098f..0bc1ad008 100644 --- a/src/lib/audio_merger.cc +++ b/src/lib/audio_merger.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2017 Carl Hetherington + Copyright (C) 2013-2021 Carl Hetherington This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,49 +17,59 @@ */ + /** @file src/audio_merger.cc * @brief AudioMerger class. */ + #include "audio_merger.h" #include "dcpomatic_time.h" #include -using std::pair; -using std::min; -using std::max; -using std::list; + using std::cout; +using std::list; using std::make_pair; +using std::make_shared; +using std::max; +using std::min; +using std::pair; using std::shared_ptr; using boost::optional; using namespace dcpomatic; + AudioMerger::AudioMerger (int frame_rate) : _frame_rate (frame_rate) { } + Frame AudioMerger::frames (DCPTime t) const { return t.frames_floor (_frame_rate); } + /** Pull audio up to a given time; after this call, no more data can be pushed * before the specified time. * @param time Time to pull up to. * @return Blocks of merged audio up to `time'. */ -list, DCPTime> > +list, DCPTime>> AudioMerger::pull (DCPTime time) { - list, DCPTime> > out; + list, DCPTime>> out; list new_buffers; - _buffers.sort (AudioMerger::BufferComparator()); + _buffers.sort ([](Buffer const& a, Buffer const& b) { + return a.time < b.time; + }); + for (auto i: _buffers) { if (i.period().to <= time) { /* Completely within the pull period */ @@ -70,7 +80,7 @@ AudioMerger::pull (DCPTime time) int32_t const overlap = frames(DCPTime(time - i.time)); /* Though time > i.time, overlap could be 0 if the difference in time is less than one frame */ if (overlap > 0) { - shared_ptr audio(new AudioBuffers(i.audio, overlap, 0)); + auto audio = make_shared(i.audio, overlap, 0); out.push_back (make_pair(audio, i.time)); i.audio->trim_start (overlap); i.time += DCPTime::from_frames(overlap, _frame_rate); @@ -86,13 +96,14 @@ AudioMerger::pull (DCPTime time) _buffers = new_buffers; - for (list, DCPTime> >::const_iterator i = out.begin(); i != out.end(); ++i) { - DCPOMATIC_ASSERT (i->first->frames() > 0); + for (auto const& i: out) { + DCPOMATIC_ASSERT (i.first->frames() > 0); } return out; } + /** Push some data into the merger at a given time */ void AudioMerger::push (std::shared_ptr audio, DCPTime time) @@ -103,7 +114,7 @@ AudioMerger::push (std::shared_ptr audio, DCPTime time) /* Mix any overlapping parts of this new block with existing ones */ for (auto i: _buffers) { - optional overlap = i.period().overlap (period); + auto overlap = i.period().overlap(period); if (overlap) { int32_t const offset = frames(DCPTime(overlap->from - i.time)); int32_t const frames_to_mix = frames(overlap->duration()); @@ -117,14 +128,14 @@ AudioMerger::push (std::shared_ptr audio, DCPTime time) list periods; for (auto i: _buffers) { - periods.push_back (i.period ()); + periods.push_back (i.period()); } /* Add the non-overlapping parts */ for (auto i: subtract(period, periods)) { - list::iterator before = _buffers.end(); - list::iterator after = _buffers.end(); - for (list::iterator j = _buffers.begin(); j != _buffers.end(); ++j) { + auto before = _buffers.end(); + auto after = _buffers.end(); + for (auto j = _buffers.begin(); j != _buffers.end(); ++j) { if (j->period().to == i.from) { before = j; } @@ -134,7 +145,7 @@ AudioMerger::push (std::shared_ptr audio, DCPTime time) } /* Get the part of audio that we want to use */ - shared_ptr part (new AudioBuffers(audio, frames(i.to) - frames(i.from), frames(DCPTime(i.from - time)))); + auto part = make_shared(audio, frames(i.to) - frames(i.from), frames(DCPTime(i.from - time))); if (before == _buffers.end() && after == _buffers.end()) { if (part->frames() > 0) { @@ -158,6 +169,7 @@ AudioMerger::push (std::shared_ptr audio, DCPTime time) } } + void AudioMerger::clear () { diff --git a/src/lib/audio_merger.h b/src/lib/audio_merger.h index adaf72f81..07e730ce2 100644 --- a/src/lib/audio_merger.h +++ b/src/lib/audio_merger.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2017 Carl Hetherington + Copyright (C) 2013-2021 Carl Hetherington This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,14 +17,17 @@ */ + /** @file src/audio_merger.h * @brief AudioMerger class. */ + #include "audio_buffers.h" #include "dcpomatic_time.h" #include "util.h" + /** @class AudioMerger. * @brief A class that can merge audio data from many sources. */ @@ -33,7 +36,7 @@ class AudioMerger public: explicit AudioMerger (int frame_rate); - std::list, dcpomatic::DCPTime> > pull (dcpomatic::DCPTime time); + std::list, dcpomatic::DCPTime>> pull (dcpomatic::DCPTime time); void push (std::shared_ptr audio, dcpomatic::DCPTime time); void clear (); @@ -69,15 +72,6 @@ private: } }; - class BufferComparator - { - public: - bool operator() (AudioMerger::Buffer const & a, AudioMerger::Buffer const & b) - { - return a.time < b.time; - } - }; - std::list _buffers; int _frame_rate; }; diff --git a/src/lib/content_factory.cc b/src/lib/content_factory.cc index c4e389c7c..e912589fc 100644 --- a/src/lib/content_factory.cc +++ b/src/lib/content_factory.cc @@ -18,10 +18,12 @@ */ + /** @file src/lib/content_factory.cc * @brief Methods to create content objects. */ + #include "ffmpeg_content.h" #include "audio_content.h" #include "image_content.h" @@ -43,11 +45,14 @@ #include "i18n.h" -using std::string; + using std::list; +using std::make_shared; using std::shared_ptr; +using std::string; using boost::optional; + /** Create a Content object from an XML node. * @param node XML description. * @param version XML state version. @@ -57,7 +62,7 @@ using boost::optional; shared_ptr content_factory (cxml::ConstNodePtr node, int version, list& notes) { - string const type = node->string_child ("Type"); + auto const type = node->string_child ("Type"); std::shared_ptr content; @@ -65,49 +70,48 @@ content_factory (cxml::ConstNodePtr node, int version, list& notes) /* SndfileContent is now handled by the FFmpeg code rather than by separate libsndfile-based code. */ - content.reset (new FFmpegContent (node, version, notes)); + content.reset (new FFmpegContent(node, version, notes)); } else if (type == "Image") { - content.reset (new ImageContent (node, version)); + content.reset (new ImageContent(node, version)); } else if (type == "Sndfile") { /* SndfileContent is now handled by the FFmpeg code rather than by separate libsndfile-based code. */ - content.reset (new FFmpegContent (node, version, notes)); + content.reset (new FFmpegContent(node, version, notes)); content->audio->set_stream ( - AudioStreamPtr ( - new FFmpegAudioStream ( - "Stream", 0, - node->number_child ("AudioFrameRate"), - node->number_child ("AudioLength"), - AudioMapping (node->node_child ("AudioMapping"), version) - ) + make_shared( + "Stream", 0, + node->number_child ("AudioFrameRate"), + node->number_child ("AudioLength"), + AudioMapping (node->node_child ("AudioMapping"), version) ) ); } else if (type == "SubRip" || type == "TextSubtitle") { - content.reset (new StringTextFileContent (node, version)); + content.reset (new StringTextFileContent(node, version)); } else if (type == "DCP") { - content.reset (new DCPContent (node, version)); + content.reset (new DCPContent(node, version)); } else if (type == "DCPSubtitle") { - content.reset (new DCPSubtitleContent (node, version)); + content.reset (new DCPSubtitleContent(node, version)); } else if (type == "VideoMXF") { - content.reset (new VideoMXFContent (node, version)); + content.reset (new VideoMXFContent(node, version)); } else if (type == "AtmosMXF") { - content.reset (new AtmosMXFContent (node, version)); + content.reset (new AtmosMXFContent(node, version)); } return content; } + /** Create some Content objects from a file or directory. * @param path File or directory. * @return Content objects. */ -list > +list> content_factory (boost::filesystem::path path) { - list > content; + list> content; if (boost::filesystem::is_directory (path)) { @@ -138,11 +142,11 @@ content_factory (boost::filesystem::path path) continue; } - if (valid_image_file (i->path ())) { + if (valid_image_file(i->path())) { ++image_files; } - if (valid_sound_file (i->path ())) { + if (valid_sound_file(i->path())) { ++sound_files; } @@ -150,10 +154,10 @@ content_factory (boost::filesystem::path path) } if (image_files > 0 && sound_files == 0) { - content.push_back (shared_ptr (new ImageContent(path))); + content.push_back (make_shared(path)); } else if (image_files == 0 && sound_files > 0) { - for (boost::filesystem::directory_iterator i(path); i != boost::filesystem::directory_iterator(); ++i) { - content.push_back (shared_ptr (new FFmpegContent(i->path()))); + for (auto i: boost::filesystem::directory_iterator(path)) { + content.push_back (make_shared(i.path())); } } @@ -161,7 +165,7 @@ content_factory (boost::filesystem::path path) shared_ptr single; - string ext = path.extension().string (); + auto ext = path.extension().string(); transform (ext.begin(), ext.end(), ext.begin(), ::tolower); if (valid_image_file (path)) { @@ -175,11 +179,11 @@ content_factory (boost::filesystem::path path) throw KDMAsContentError (); } single.reset (new DCPSubtitleContent(path)); - } else if (ext == ".mxf" && dcp::SMPTESubtitleAsset::valid_mxf (path)) { + } else if (ext == ".mxf" && dcp::SMPTESubtitleAsset::valid_mxf(path)) { single.reset (new DCPSubtitleContent(path)); - } else if (ext == ".mxf" && VideoMXFContent::valid_mxf (path)) { + } else if (ext == ".mxf" && VideoMXFContent::valid_mxf(path)) { single.reset (new VideoMXFContent(path)); - } else if (ext == ".mxf" && AtmosMXFContent::valid_mxf (path)) { + } else if (ext == ".mxf" && AtmosMXFContent::valid_mxf(path)) { single.reset (new AtmosMXFContent(path)); } diff --git a/src/lib/content_factory.h b/src/lib/content_factory.h index ab76a29dc..7da5435d5 100644 --- a/src/lib/content_factory.h +++ b/src/lib/content_factory.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2014 Carl Hetherington + Copyright (C) 2013-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,14 +18,18 @@ */ + /** @file src/lib/content_factory.h * @brief Methods to create content objects. */ + #include + class Film; class Content; + extern std::shared_ptr content_factory (cxml::ConstNodePtr, int, std::list &); -extern std::list > content_factory (boost::filesystem::path); +extern std::list> content_factory (boost::filesystem::path); diff --git a/src/lib/encode_server.cc b/src/lib/encode_server.cc index 891b8caac..24ba5bc45 100644 --- a/src/lib/encode_server.cc +++ b/src/lib/encode_server.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2018 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,11 +18,13 @@ */ + /** @file src/encode_server.cc * @brief Class to describe a server to which we can send * encoding work, and a class to implement such a server. */ + #include "encode_server.h" #include "util.h" #include "dcpomatic_socket.h" @@ -53,6 +55,7 @@ DCPOMATIC_ENABLE_WARNINGS #include "i18n.h" + using std::string; using std::vector; using std::list; @@ -69,6 +72,7 @@ using dcp::ArrayData; using dcp::Size; using dcp::raw_convert; + EncodeServer::EncodeServer (bool verbose, int num_threads) #if !defined(RUNNING_ON_VALGRIND) || RUNNING_ON_VALGRIND == 0 : Server (ENCODE_FRAME_PORT) @@ -81,6 +85,7 @@ EncodeServer::EncodeServer (bool verbose, int num_threads) } + EncodeServer::~EncodeServer () { boost::this_thread::disable_interruption dis; @@ -111,6 +116,7 @@ EncodeServer::~EncodeServer () } catch (...) {} } + /** @param after_read Filled in with gettimeofday() after reading the input from the network. * @param after_encode Filled in with gettimeofday() after encoding the image. */ @@ -119,9 +125,9 @@ EncodeServer::process (shared_ptr socket, struct timeval& after_read, st { Socket::ReadDigestScope ds (socket); - uint32_t length = socket->read_uint32 (); + auto length = socket->read_uint32 (); scoped_array buffer (new char[length]); - socket->read (reinterpret_cast (buffer.get()), length); + socket->read (reinterpret_cast(buffer.get()), length); string s (buffer.get()); auto xml = make_shared("EncodingRequest"); @@ -162,6 +168,7 @@ EncodeServer::process (shared_ptr socket, struct timeval& after_read, st return dcp_video_frame.index (); } + void EncodeServer::worker_thread () { @@ -226,6 +233,7 @@ EncodeServer::worker_thread () } } + void EncodeServer::run () { @@ -251,6 +259,7 @@ EncodeServer::run () Server::run (); } + void EncodeServer::broadcast_thread () try @@ -275,6 +284,7 @@ catch (...) store_current (); } + void EncodeServer::broadcast_received () { @@ -320,6 +330,7 @@ EncodeServer::broadcast_received () } } + void EncodeServer::handle (shared_ptr socket) { diff --git a/src/lib/encode_server.h b/src/lib/encode_server.h index d313a851d..6e24a1984 100644 --- a/src/lib/encode_server.h +++ b/src/lib/encode_server.h @@ -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,13 +18,16 @@ */ + #ifndef DCPOMATIC_ENCODE_SERVER_H #define DCPOMATIC_ENCODE_SERVER_H + /** @file src/encode_server.h * @brief EncodeServer class. */ + #include "server.h" #include "exception_store.h" #include @@ -32,9 +35,11 @@ #include #include + class Socket; class Log; + /** @class EncodeServer * @brief A class to run a server which can accept requests to perform JPEG2000 * encoding work. @@ -55,7 +60,7 @@ private: void broadcast_received (); boost::thread_group _worker_threads; - std::list > _queue; + std::list> _queue; boost::condition _full_condition; boost::condition _empty_condition; bool _verbose; @@ -77,4 +82,5 @@ private: } _broadcast; }; + #endif diff --git a/src/lib/environment_info.cc b/src/lib/environment_info.cc index 5b1f56f72..7a8fe68bc 100644 --- a/src/lib/environment_info.cc +++ b/src/lib/environment_info.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,6 +18,7 @@ */ + #include "log.h" #include "compose.hpp" #include "version.h" @@ -35,10 +36,12 @@ extern "C" { #include "i18n.h" -using std::string; + using std::list; using std::pair; using std::shared_ptr; +using std::string; + /** @param v Version as used by FFmpeg. * @return A string representation of v. @@ -52,6 +55,7 @@ ffmpeg_version_to_string (int v) return buffer; } + /** Return a user-readable string summarising the versions of our dependencies */ static string @@ -72,6 +76,7 @@ dependency_version_summary () return buffer; } + list environment_info () { @@ -133,10 +138,9 @@ environment_info () #endif #endif - info.push_back (String::compose ("CPU: %1, %2 processors", cpu_info(), boost::thread::hardware_concurrency ())); - list > const m = mount_info (); - for (list >::const_iterator i = m.begin(); i != m.end(); ++i) { - info.push_back (String::compose ("Mount: %1 %2", i->first, i->second)); + info.push_back (String::compose ("CPU: %1, %2 processors", cpu_info(), boost::thread::hardware_concurrency())); + for (auto const& i: mount_info()) { + info.push_back (String::compose("Mount: %1 %2", i.first, i.second)); } return info; diff --git a/src/lib/environment_info.h b/src/lib/environment_info.h index 1f4c9aba0..7e85f8df6 100644 --- a/src/lib/environment_info.h +++ b/src/lib/environment_info.h @@ -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,4 +18,5 @@ */ + extern std::list environment_info (); diff --git a/src/lib/ffmpeg.cc b/src/lib/ffmpeg.cc index f8398763e..eb131d434 100644 --- a/src/lib/ffmpeg.cc +++ b/src/lib/ffmpeg.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2019 Carl Hetherington + Copyright (C) 2013-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,6 +18,7 @@ */ + #include "ffmpeg.h" #include "ffmpeg_content.h" #include "film.h" @@ -41,6 +42,7 @@ extern "C" { #include "i18n.h" + using std::string; using std::cout; using std::cerr; @@ -50,20 +52,18 @@ using boost::optional; using dcp::raw_convert; using namespace dcpomatic; + boost::mutex FFmpeg::_mutex; + FFmpeg::FFmpeg (std::shared_ptr c) : _ffmpeg_content (c) - , _avio_buffer (0) - , _avio_buffer_size (4096) - , _avio_context (0) - , _format_context (0) - , _frame (0) { setup_general (); setup_decoders (); } + FFmpeg::~FFmpeg () { boost::mutex::scoped_lock lm (_mutex); @@ -78,18 +78,21 @@ DCPOMATIC_ENABLE_WARNINGS avformat_close_input (&_format_context); } + static int avio_read_wrapper (void* data, uint8_t* buffer, int amount) { return reinterpret_cast(data)->avio_read (buffer, amount); } + static int64_t avio_seek_wrapper (void* data, int64_t offset, int whence) { return reinterpret_cast(data)->avio_seek (offset, whence); } + void FFmpeg::ffmpeg_log_callback (void* ptr, int level, const char* fmt, va_list vl) { @@ -105,6 +108,7 @@ FFmpeg::ffmpeg_log_callback (void* ptr, int level, const char* fmt, va_list vl) dcpomatic_log->log (String::compose ("FFmpeg: %1", str), LogEntry::TYPE_GENERAL); } + void FFmpeg::setup_general () { @@ -114,7 +118,7 @@ FFmpeg::setup_general () av_log_set_callback (FFmpeg::ffmpeg_log_callback); _file_group.set_paths (_ffmpeg_content->paths ()); - _avio_buffer = static_cast (wrapped_av_malloc (_avio_buffer_size)); + _avio_buffer = static_cast (wrapped_av_malloc(_avio_buffer_size)); _avio_context = avio_alloc_context (_avio_buffer, _avio_buffer_size, 0, this, avio_read_wrapper, 0, avio_seek_wrapper); if (!_avio_context) { throw std::bad_alloc (); @@ -194,6 +198,7 @@ DCPOMATIC_ENABLE_WARNINGS } } + void FFmpeg::setup_decoders () { @@ -232,6 +237,7 @@ DCPOMATIC_DISABLE_WARNINGS DCPOMATIC_ENABLE_WARNINGS } + DCPOMATIC_DISABLE_WARNINGS AVCodecContext * FFmpeg::video_codec_context () const @@ -243,10 +249,11 @@ FFmpeg::video_codec_context () const return _format_context->streams[_video_stream.get()]->codec; } + AVCodecContext * FFmpeg::subtitle_codec_context () const { - if (!_ffmpeg_content->subtitle_stream ()) { + if (!_ffmpeg_content->subtitle_stream()) { return nullptr; } @@ -254,12 +261,14 @@ FFmpeg::subtitle_codec_context () const } DCPOMATIC_ENABLE_WARNINGS + int FFmpeg::avio_read (uint8_t* buffer, int const amount) { return _file_group.read (buffer, amount); } + int64_t FFmpeg::avio_seek (int64_t const pos, int whence) { @@ -270,6 +279,7 @@ FFmpeg::avio_seek (int64_t const pos, int whence) return _file_group.seek (pos, whence); } + FFmpegSubtitlePeriod FFmpeg::subtitle_period (AVSubtitle const & sub) { @@ -286,6 +296,7 @@ FFmpeg::subtitle_period (AVSubtitle const & sub) ); } + /** Compute the pts offset to use given a set of audio streams and some video details. * Sometimes these parameters will have just been determined by an Examiner, sometimes * they will have been retrieved from a piece of Content, hence the need for this method diff --git a/src/lib/ffmpeg.h b/src/lib/ffmpeg.h index fac8a2d84..5e1d0842e 100644 --- a/src/lib/ffmpeg.h +++ b/src/lib/ffmpeg.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2016 Carl Hetherington + Copyright (C) 2013-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,9 +18,11 @@ */ + #ifndef DCPOMATIC_FFMPEG_H #define DCPOMATIC_FFMPEG_H + #include "file_group.h" #include "ffmpeg_subtitle_period.h" #include "warnings.h" @@ -31,6 +33,7 @@ extern "C" { DCPOMATIC_ENABLE_WARNINGS #include + struct AVFormatContext; struct AVFrame; struct AVIOContext; @@ -39,6 +42,7 @@ class FFmpegContent; class FFmpegAudioStream; class Log; + class FFmpeg { public: @@ -56,20 +60,20 @@ protected: AVCodecContext* video_codec_context () const; AVCodecContext* subtitle_codec_context () const; dcpomatic::ContentTime pts_offset ( - std::vector > audio_streams, boost::optional first_video, double video_frame_rate + std::vector> audio_streams, boost::optional first_video, double video_frame_rate ) const; static FFmpegSubtitlePeriod subtitle_period (AVSubtitle const & sub); std::shared_ptr _ffmpeg_content; - uint8_t* _avio_buffer; - int _avio_buffer_size; - AVIOContext* _avio_context; + uint8_t* _avio_buffer = nullptr; + int _avio_buffer_size = 4096; + AVIOContext* _avio_context = nullptr; FileGroup _file_group; - AVFormatContext* _format_context; - AVFrame* _frame; + AVFormatContext* _format_context = nullptr; + AVFrame* _frame = nullptr; /** Index of video stream within AVFormatContext */ boost::optional _video_stream; @@ -88,4 +92,5 @@ private: static std::weak_ptr _ffmpeg_log; }; + #endif diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index b1bb632b1..516962936 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -16,6 +16,7 @@ You should have received a copy of the GNU General Public License along with DCP-o-matic. If not, see . + */ #include "ffmpeg_content.h" @@ -45,6 +46,7 @@ extern "C" { #include "i18n.h" + using std::string; using std::vector; using std::list; @@ -59,17 +61,20 @@ using boost::optional; using dcp::raw_convert; using namespace dcpomatic; + int const FFmpegContentProperty::SUBTITLE_STREAMS = 100; int const FFmpegContentProperty::SUBTITLE_STREAM = 101; int const FFmpegContentProperty::FILTERS = 102; int const FFmpegContentProperty::KDM = 103; + FFmpegContent::FFmpegContent (boost::filesystem::path p) : Content (p) { } + template optional get_optional_enum (cxml::ConstNodePtr node, string name) @@ -81,6 +86,7 @@ get_optional_enum (cxml::ConstNodePtr node, string name) return static_cast(*v); } + FFmpegContent::FFmpegContent (cxml::ConstNodePtr node, int version, list& notes) : Content (node) { @@ -125,7 +131,8 @@ FFmpegContent::FFmpegContent (cxml::ConstNodePtr node, int version, list _bits_per_pixel = node->optional_number_child ("BitsPerPixel"); } -FFmpegContent::FFmpegContent (vector > c) + +FFmpegContent::FFmpegContent (vector> c) : Content (c) { auto i = c.begin (); @@ -186,10 +193,11 @@ FFmpegContent::FFmpegContent (vector > c) _bits_per_pixel = ref->_bits_per_pixel; } + void FFmpegContent::as_xml (xmlpp::Node* node, bool with_paths) const { - node->add_child("Type")->add_child_text ("FFmpeg"); + node->add_child("Type")->add_child_text("FFmpeg"); Content::as_xml (node, with_paths); if (video) { @@ -199,7 +207,7 @@ FFmpegContent::as_xml (xmlpp::Node* node, bool with_paths) const if (audio) { audio->as_xml (node); - for (auto i: audio->streams ()) { + for (auto i: audio->streams()) { auto f = dynamic_pointer_cast (i); DCPOMATIC_ASSERT (f); f->as_xml (node->add_child("AudioStream")); @@ -225,26 +233,27 @@ FFmpegContent::as_xml (xmlpp::Node* node, bool with_paths) const } if (_first_video) { - node->add_child("FirstVideo")->add_child_text (raw_convert (_first_video.get().get())); + node->add_child("FirstVideo")->add_child_text(raw_convert(_first_video.get().get())); } if (_color_range) { - node->add_child("ColorRange")->add_child_text (raw_convert (static_cast (*_color_range))); + node->add_child("ColorRange")->add_child_text(raw_convert(static_cast(*_color_range))); } if (_color_primaries) { - node->add_child("ColorPrimaries")->add_child_text (raw_convert (static_cast (*_color_primaries))); + node->add_child("ColorPrimaries")->add_child_text(raw_convert(static_cast(*_color_primaries))); } if (_color_trc) { - node->add_child("ColorTransferCharacteristic")->add_child_text (raw_convert (static_cast (*_color_trc))); + node->add_child("ColorTransferCharacteristic")->add_child_text(raw_convert(static_cast(*_color_trc))); } if (_colorspace) { - node->add_child("Colorspace")->add_child_text (raw_convert (static_cast (*_colorspace))); + node->add_child("Colorspace")->add_child_text(raw_convert(static_cast(*_colorspace))); } if (_bits_per_pixel) { - node->add_child("BitsPerPixel")->add_child_text (raw_convert (*_bits_per_pixel)); + node->add_child("BitsPerPixel")->add_child_text(raw_convert(*_bits_per_pixel)); } } + void FFmpegContent::examine (shared_ptr film, shared_ptr job) { @@ -290,7 +299,7 @@ FFmpegContent::examine (shared_ptr film, shared_ptr job) } } - if (!examiner->audio_streams().empty ()) { + if (!examiner->audio_streams().empty()) { audio = make_shared(this); for (auto i: examiner->audio_streams()) { @@ -324,20 +333,22 @@ FFmpegContent::examine (shared_ptr film, shared_ptr job) } } + string FFmpegContent::summary () const { if (video && audio) { - return String::compose (_("%1 [movie]"), path_summary ()); + return String::compose (_("%1 [movie]"), path_summary()); } else if (video) { - return String::compose (_("%1 [video]"), path_summary ()); + return String::compose (_("%1 [video]"), path_summary()); } else if (audio) { - return String::compose (_("%1 [audio]"), path_summary ()); + return String::compose (_("%1 [audio]"), path_summary()); } return path_summary (); } + string FFmpegContent::technical_summary () const { @@ -372,6 +383,7 @@ FFmpegContent::technical_summary () const ); } + void FFmpegContent::set_subtitle_stream (shared_ptr s) { @@ -383,18 +395,21 @@ FFmpegContent::set_subtitle_stream (shared_ptr s) } } + bool operator== (FFmpegStream const & a, FFmpegStream const & b) { return a._id == b._id; } + bool operator!= (FFmpegStream const & a, FFmpegStream const & b) { return a._id != b._id; } + DCPTime FFmpegContent::full_length (shared_ptr film) const { @@ -413,9 +428,10 @@ FFmpegContent::full_length (shared_ptr film) const /* XXX: subtitle content? */ - return DCPTime(); + return {}; } + DCPTime FFmpegContent::approximate_length () const { @@ -433,6 +449,7 @@ FFmpegContent::approximate_length () const return DCPTime::from_frames (longest, 24); } + void FFmpegContent::set_filters (vector const & filters) { @@ -444,6 +461,7 @@ FFmpegContent::set_filters (vector const & filters) } } + string FFmpegContent::identifier () const { @@ -470,6 +488,7 @@ FFmpegContent::identifier () const return s; } + void FFmpegContent::set_default_colour_conversion () { @@ -505,6 +524,7 @@ FFmpegContent::set_default_colour_conversion () } } + void FFmpegContent::add_properties (shared_ptr film, list& p) const { @@ -649,6 +669,7 @@ FFmpegContent::add_properties (shared_ptr film, list& } } + /** Our subtitle streams have colour maps, which can be changed, but * they have no way of signalling that change. As a hack, we have this * method which callers can use when they've modified one of our subtitle @@ -661,20 +682,22 @@ FFmpegContent::signal_subtitle_stream_changed () ContentChangeSignaller cc (this, FFmpegContentProperty::SUBTITLE_STREAM); } -vector > + +vector> FFmpegContent::ffmpeg_audio_streams () const { - vector > fa; + vector> fa; if (audio) { for (auto i: audio->streams()) { - fa.push_back (dynamic_pointer_cast (i)); + fa.push_back (dynamic_pointer_cast(i)); } } return fa; } + void FFmpegContent::take_settings_from (shared_ptr c) { diff --git a/src/lib/ffmpeg_content.h b/src/lib/ffmpeg_content.h index fccc7ad99..df7b56edc 100644 --- a/src/lib/ffmpeg_content.h +++ b/src/lib/ffmpeg_content.h @@ -49,7 +49,7 @@ class FFmpegContent : public Content public: FFmpegContent (boost::filesystem::path); FFmpegContent (cxml::ConstNodePtr, int version, std::list &); - FFmpegContent (std::vector >); + FFmpegContent (std::vector>); std::shared_ptr shared_from_this () { return std::dynamic_pointer_cast (Content::shared_from_this ()); @@ -73,7 +73,7 @@ public: void set_filters (std::vector const &); - std::vector > subtitle_streams () const { + std::vector> subtitle_streams () const { boost::mutex::scoped_lock lm (_mutex); return _subtitle_streams; } @@ -83,7 +83,7 @@ public: return _subtitle_stream; } - std::vector > ffmpeg_audio_streams () const; + std::vector> ffmpeg_audio_streams () const; std::vector filters () const { boost::mutex::scoped_lock lm (_mutex); @@ -105,7 +105,7 @@ private: friend struct ffmpeg_pts_offset_test; friend struct audio_sampling_rate_test; - std::vector > _subtitle_streams; + std::vector> _subtitle_streams; std::shared_ptr _subtitle_stream; boost::optional _first_video; /** Video filters that should be used when generating DCPs */ diff --git a/src/lib/player_text.cc b/src/lib/player_text.cc index 5456b06c4..a3b7ec89f 100644 --- a/src/lib/player_text.cc +++ b/src/lib/player_text.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2014-2018 Carl Hetherington + Copyright (C) 2014-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,15 +18,18 @@ */ + #include "player_text.h" #include "font.h" + using std::list; using std::shared_ptr; using namespace dcpomatic; + void -PlayerText::add_fonts (list > fonts_) +PlayerText::add_fonts (list> fonts_) { for (auto i: fonts_) { bool got = false; diff --git a/src/lib/player_text.h b/src/lib/player_text.h index 232ba6516..cd4be984c 100644 --- a/src/lib/player_text.h +++ b/src/lib/player_text.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2014-2018 Carl Hetherington + Copyright (C) 2014-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,22 +18,26 @@ */ + #ifndef DCPOMATIC_PLAYER_CAPTION_H #define DCPOMATIC_PLAYER_CAPTION_H + #include "bitmap_text.h" #include "dcpomatic_time.h" #include "string_text.h" + namespace dcpomatic { class Font; } + /** A set of text (subtitle/CCAP) which span the same time period */ class PlayerText { public: - void add_fonts (std::list > fonts_); + void add_fonts (std::list> fonts_); std::list > fonts; /** BitmapTexts, with their rectangles transformed as specified by their content */ @@ -41,4 +45,5 @@ public: std::list string; }; + #endif diff --git a/src/lib/upmixer_a.cc b/src/lib/upmixer_a.cc index d8cfb4fff..f402b6691 100644 --- a/src/lib/upmixer_a.cc +++ b/src/lib/upmixer_a.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,16 +18,20 @@ */ + #include "upmixer_a.h" #include "audio_buffers.h" #include "audio_mapping.h" #include "i18n.h" -using std::string; + +using std::make_shared; using std::min; -using std::vector; using std::shared_ptr; +using std::string; +using std::vector; + UpmixerA::UpmixerA (int sampling_rate) : _left (0.02, 1900.0 / sampling_rate, 4800.0 / sampling_rate) @@ -40,52 +44,57 @@ UpmixerA::UpmixerA (int sampling_rate) } + string UpmixerA::name () const { return _("Stereo to 5.1 up-mixer A"); } + string UpmixerA::id () const { return N_("stereo-5.1-upmix-a"); } + int UpmixerA::out_channels () const { return 6; } + shared_ptr UpmixerA::clone (int sampling_rate) const { - return shared_ptr (new UpmixerA (sampling_rate)); + return make_shared(sampling_rate); } + shared_ptr UpmixerA::run (shared_ptr in, int channels) { /* Input L and R */ - shared_ptr in_L = in->channel (0); - shared_ptr in_R = in->channel (1); + auto in_L = in->channel (0); + auto in_R = in->channel (1); /* Mix of L and R; -6dB down in amplitude (3dB in terms of power) */ - shared_ptr in_LR = in_L->clone (); + auto in_LR = in_L->clone (); in_LR->accumulate_frames (in_R.get(), in_R->frames(), 0, 0); in_LR->apply_gain (-6); /* Run filters */ - vector > all_out; - all_out.push_back (_left.run (in_L)); - all_out.push_back (_right.run (in_R)); - all_out.push_back (_centre.run (in_LR)); - all_out.push_back (_lfe.run (in_LR)); - all_out.push_back (_ls.run (in_L)); - all_out.push_back (_rs.run (in_R)); - - shared_ptr out (new AudioBuffers (channels, in->frames ())); + vector> all_out; + all_out.push_back (_left.run(in_L)); + all_out.push_back (_right.run(in_R)); + all_out.push_back (_centre.run(in_LR)); + all_out.push_back (_lfe.run(in_LR)); + all_out.push_back (_ls.run(in_L)); + all_out.push_back (_rs.run(in_R)); + + auto out = make_shared(channels, in->frames()); int const N = min (channels, 6); for (int i = 0; i < N; ++i) { @@ -110,6 +119,7 @@ UpmixerA::flush () _rs.flush (); } + void UpmixerA::make_audio_mapping_default (AudioMapping& mapping) const { @@ -120,11 +130,12 @@ UpmixerA::make_audio_mapping_default (AudioMapping& mapping) const } } + vector UpmixerA::input_names () const { - vector n; - n.push_back (NamedChannel(_("Upmix L"), 0)); - n.push_back (NamedChannel(_("Upmix R"), 1)); - return n; + return { + NamedChannel(_("Upmix L"), 0), + NamedChannel(_("Upmix R"), 1) + }; } diff --git a/src/lib/upmixer_a.h b/src/lib/upmixer_a.h index 984b08095..b357616ef 100644 --- a/src/lib/upmixer_a.h +++ b/src/lib/upmixer_a.h @@ -18,13 +18,16 @@ */ + /** @file src/lib/upmixer_a.h * @brief UpmixerA class. */ + #include "audio_processor.h" #include "audio_filter.h" + /** @class UpmixerA * @brief Stereo to 5.1 upmixer algorithm by Gérald Maruccia. */ diff --git a/src/lib/video_filter_graph.cc b/src/lib/video_filter_graph.cc index b35fc14c1..f1141150b 100644 --- a/src/lib/video_filter_graph.cc +++ b/src/lib/video_filter_graph.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2018 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,6 +18,7 @@ */ + #include "compose.hpp" #include "image.h" #include "video_filter_graph.h" @@ -29,12 +30,15 @@ extern "C" { #include "i18n.h" + using std::list; -using std::pair; -using std::vector; -using std::string; using std::make_pair; +using std::make_shared; +using std::pair; using std::shared_ptr; +using std::string; +using std::vector; + VideoFilterGraph::VideoFilterGraph (dcp::Size s, AVPixelFormat p, dcp::Fraction r) : _size (s) @@ -44,21 +48,22 @@ VideoFilterGraph::VideoFilterGraph (dcp::Size s, AVPixelFormat p, dcp::Fraction } + /** Take an AVFrame and process it using our configured filters, returning a * set of Images. Caller handles memory management of the input frame. */ -list, int64_t> > +list, int64_t>> VideoFilterGraph::process (AVFrame* frame) { - list, int64_t> > images; + list, int64_t>> images; DCPOMATIC_DISABLE_WARNINGS if (_copy) { - images.push_back (make_pair (shared_ptr (new Image (frame)), av_frame_get_best_effort_timestamp (frame))); + images.push_back (make_pair(make_shared(frame), av_frame_get_best_effort_timestamp (frame))); } else { int r = av_buffersrc_write_frame (_buffer_src_context, frame); if (r < 0) { - throw DecodeError (String::compose (N_("could not push buffer into filter chain (%1)."), r)); + throw DecodeError (String::compose(N_("could not push buffer into filter chain (%1)."), r)); } while (true) { @@ -66,7 +71,7 @@ DCPOMATIC_DISABLE_WARNINGS break; } - images.push_back (make_pair (shared_ptr (new Image (_frame)), av_frame_get_best_effort_timestamp (_frame))); + images.push_back (make_pair(make_shared(_frame), av_frame_get_best_effort_timestamp (_frame))); av_frame_unref (_frame); } } @@ -75,6 +80,7 @@ DCPOMATIC_ENABLE_WARNINGS return images; } + /** @param s Image size. * @param p Pixel format. * @return true if this chain can process images with `s' and `p', otherwise false. @@ -85,6 +91,7 @@ VideoFilterGraph::can_process (dcp::Size s, AVPixelFormat p) const return (_size == s && _pixel_format == p); } + string VideoFilterGraph::src_parameters () const { @@ -99,23 +106,26 @@ VideoFilterGraph::src_parameters () const return buffer; } + void * VideoFilterGraph::sink_parameters () const { - AVBufferSinkParams* sink_params = av_buffersink_params_alloc (); - AVPixelFormat* pixel_fmts = new AVPixelFormat[2]; + auto sink_params = av_buffersink_params_alloc (); + auto pixel_fmts = new AVPixelFormat[2]; pixel_fmts[0] = _pixel_format; pixel_fmts[1] = AV_PIX_FMT_NONE; sink_params->pixel_fmts = pixel_fmts; return sink_params; } + string VideoFilterGraph::src_name () const { return "buffer"; } + string VideoFilterGraph::sink_name () const { diff --git a/src/lib/video_filter_graph.h b/src/lib/video_filter_graph.h index ba0284fb8..fb6c7eba1 100644 --- a/src/lib/video_filter_graph.h +++ b/src/lib/video_filter_graph.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2018 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,15 +18,17 @@ */ + #include "filter_graph.h" + class VideoFilterGraph : public FilterGraph { public: VideoFilterGraph (dcp::Size s, AVPixelFormat p, dcp::Fraction r); bool can_process (dcp::Size s, AVPixelFormat p) const; - std::list, int64_t> > process (AVFrame * frame); + std::list, int64_t>> process (AVFrame * frame); protected: std::string src_parameters () const; diff --git a/src/lib/video_ring_buffers.cc b/src/lib/video_ring_buffers.cc index 8c73aba25..63c52ee06 100644 --- a/src/lib/video_ring_buffers.cc +++ b/src/lib/video_ring_buffers.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2016-2020 Carl Hetherington + Copyright (C) 2016-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,12 +18,14 @@ */ + #include "video_ring_buffers.h" #include "player_video.h" #include "compose.hpp" #include #include + using std::list; using std::make_pair; using std::cout; @@ -33,25 +35,28 @@ using std::shared_ptr; using boost::optional; using namespace dcpomatic; + void VideoRingBuffers::put (shared_ptr frame, DCPTime time) { boost::mutex::scoped_lock lm (_mutex); - _data.push_back (make_pair (frame, time)); + _data.push_back (make_pair(frame, time)); } + pair, DCPTime> VideoRingBuffers::get () { boost::mutex::scoped_lock lm (_mutex); if (_data.empty ()) { - return make_pair(shared_ptr(), DCPTime()); + return {}; } - pair, DCPTime> const r = _data.front (); + auto const r = _data.front(); _data.pop_front (); return r; } + Frame VideoRingBuffers::size () const { @@ -59,6 +64,7 @@ VideoRingBuffers::size () const return _data.size (); } + bool VideoRingBuffers::empty () const { @@ -66,6 +72,7 @@ VideoRingBuffers::empty () const return _data.empty (); } + void VideoRingBuffers::clear () { @@ -73,13 +80,14 @@ VideoRingBuffers::clear () _data.clear (); } + pair VideoRingBuffers::memory_used () const { boost::mutex::scoped_lock lm (_mutex); size_t m = 0; - for (list, DCPTime> >::const_iterator i = _data.begin(); i != _data.end(); ++i) { - m += i->first->memory_used(); + for (auto const& i: _data) { + m += i.first->memory_used(); } return make_pair(m, String::compose("%1 frames", _data.size())); } @@ -89,8 +97,8 @@ void VideoRingBuffers::reset_metadata (shared_ptr film, dcp::Size player_video_container_size) { boost::mutex::scoped_lock lm (_mutex); - for (list, DCPTime> >::const_iterator i = _data.begin(); i != _data.end(); ++i) { - i->first->reset_metadata (film, player_video_container_size); + for (auto const& i: _data) { + i.first->reset_metadata (film, player_video_container_size); } } diff --git a/src/lib/video_ring_buffers.h b/src/lib/video_ring_buffers.h index 832837d94..444a49ea7 100644 --- a/src/lib/video_ring_buffers.h +++ b/src/lib/video_ring_buffers.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2016-2020 Carl Hetherington + Copyright (C) 2016-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,6 +18,7 @@ */ + #include "dcpomatic_time.h" #include "player_video.h" #include "types.h" @@ -46,5 +47,5 @@ public: private: mutable boost::mutex _mutex; - std::list, dcpomatic::DCPTime> > _data; + std::list, dcpomatic::DCPTime>> _data; }; diff --git a/src/tools/dcpomatic_kdm_cli.cc b/src/tools/dcpomatic_kdm_cli.cc index f21772a4d..bd4c4e623 100644 --- a/src/tools/dcpomatic_kdm_cli.cc +++ b/src/tools/dcpomatic_kdm_cli.cc @@ -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,17 +18,19 @@ */ + /** @file src/tools/dcpomatic_kdm_cli.cc * @brief Command-line program to generate KDMs. */ -#include "lib/film.h" + #include "lib/cinema.h" -#include "lib/kdm_with_metadata.h" #include "lib/config.h" -#include "lib/exceptions.h" -#include "lib/emailer.h" #include "lib/dkdm_wrapper.h" +#include "lib/emailer.h" +#include "lib/exceptions.h" +#include "lib/film.h" +#include "lib/kdm_with_metadata.h" #include "lib/screen.h" #include #include @@ -36,16 +38,18 @@ #include #include -using std::string; -using std::cout; + using std::cerr; +using std::cout; +using std::dynamic_pointer_cast; using std::list; -using std::vector; +using std::make_shared; using std::runtime_error; using std::shared_ptr; +using std::string; +using std::vector; using boost::optional; using boost::bind; -using std::dynamic_pointer_cast; #if BOOST_VERSION >= 106100 using namespace boost::placeholders; #endif @@ -81,6 +85,7 @@ help () "\t" << program_name << " -c \"Fred's Cinema\" -f now -d \"2 weeks\" -z my_great_movie\n\n"; } + static void error (string m) { @@ -88,6 +93,7 @@ error (string m) exit (EXIT_FAILURE); } + static boost::posix_time::ptime time_from_string (string t) { @@ -98,6 +104,7 @@ time_from_string (string t) return boost::posix_time::time_from_string (t); } + static boost::posix_time::time_duration duration_from_string (string d) { @@ -125,12 +132,14 @@ duration_from_string (string d) exit (EXIT_FAILURE); } + static bool always_overwrite () { return true; } + void write_files ( list kdms, @@ -165,11 +174,12 @@ write_files ( } } + shared_ptr find_cinema (string cinema_name) { - list > cinemas = Config::instance()->cinemas (); - list >::const_iterator i = cinemas.begin(); + auto cinemas = Config::instance()->cinemas (); + auto i = cinemas.begin(); while ( i != cinemas.end() && (*i)->name != cinema_name && @@ -186,9 +196,10 @@ find_cinema (string cinema_name) return *i; } + void from_film ( - list > screens, + list> screens, boost::filesystem::path film_dir, bool verbose, boost::filesystem::path output, @@ -204,7 +215,7 @@ from_film ( { shared_ptr film; try { - film.reset (new Film (film_dir)); + film = make_shared(film_dir); film->read_metadata (); if (verbose) { cout << "Read film " << film->name () << "\n"; @@ -222,12 +233,12 @@ from_film ( error ("more than one CPL found in film"); } - boost::filesystem::path cpl = cpls.front().cpl_file; + auto cpl = cpls.front().cpl_file; try { list kdms; for (auto i: screens) { - KDMWithMetadataPtr p = kdm_for_screen (film, cpl, i, valid_from, valid_to, formulation, disable_forensic_marking_picture, disable_forensic_marking_audio); + auto p = kdm_for_screen (film, cpl, i, valid_from, valid_to, formulation, disable_forensic_marking_picture, disable_forensic_marking_audio); if (p) { kdms.push_back (p); } @@ -245,18 +256,19 @@ from_film ( } } + optional sub_find_dkdm (shared_ptr group, string cpl_id) { for (auto i: group->children()) { - shared_ptr g = dynamic_pointer_cast(i); + auto g = dynamic_pointer_cast(i); if (g) { - optional dkdm = sub_find_dkdm (g, cpl_id); + auto dkdm = sub_find_dkdm (g, cpl_id); if (dkdm) { return dkdm; } } else { - shared_ptr d = dynamic_pointer_cast(i); + auto d = dynamic_pointer_cast(i); assert (d); if (d->dkdm().cpl_id() == cpl_id) { return d->dkdm(); @@ -267,12 +279,14 @@ sub_find_dkdm (shared_ptr group, string cpl_id) return optional(); } + optional find_dkdm (string cpl_id) { return sub_find_dkdm (Config::instance()->dkdms(), cpl_id); } + dcp::EncryptedKDM kdm_from_dkdm ( dcp::DecryptedKDM dkdm, @@ -286,7 +300,7 @@ kdm_from_dkdm ( ) { /* Signer for new KDM */ - shared_ptr signer = Config::instance()->signer_chain (); + auto signer = Config::instance()->signer_chain (); if (!signer->valid ()) { error ("signing certificate chain is invalid."); } @@ -307,9 +321,10 @@ kdm_from_dkdm ( return kdm.encrypt (signer, target, trusted_devices, formulation, disable_forensic_marking_picture, disable_forensic_marking_audio); } + void from_dkdm ( - list > screens, + list> screens, dcp::DecryptedKDM dkdm, bool verbose, boost::filesystem::path output, @@ -335,7 +350,7 @@ from_dkdm ( dcp::LocalTime begin(valid_from, i->cinema->utc_offset_hour(), i->cinema->utc_offset_minute()); dcp::LocalTime end(valid_to, i->cinema->utc_offset_hour(), i->cinema->utc_offset_minute()); - dcp::EncryptedKDM const kdm = kdm_from_dkdm( + auto const kdm = kdm_from_dkdm( dkdm, i->recipient.get(), i->trusted_device_thumbprints(), @@ -354,7 +369,7 @@ from_dkdm ( name_values['e'] = end.date() + " " + end.time_of_day(true, false); name_values['i'] = kdm.cpl_id(); - kdms.push_back (KDMWithMetadataPtr(new KDMWithMetadata(name_values, i->cinema.get(), i->cinema->emails, kdm))); + kdms.push_back (make_shared(name_values, i->cinema.get(), i->cinema->emails, kdm)); } write_files (kdms, zip, output, container_name_format, filename_format, verbose); } catch (FileError& e) { @@ -366,6 +381,7 @@ from_dkdm ( } } + void dump_dkdm_group (shared_ptr group, int indent) { @@ -376,29 +392,30 @@ dump_dkdm_group (shared_ptr group, int indent) cout << group->name() << "\n"; } for (auto i: group->children()) { - shared_ptr g = dynamic_pointer_cast(i); + auto g = dynamic_pointer_cast(i); if (g) { dump_dkdm_group (g, indent + 2); } else { for (int j = 0; j < indent; ++j) { cout << " "; } - shared_ptr d = dynamic_pointer_cast(i); + auto d = dynamic_pointer_cast(i); assert(d); cout << d->dkdm().cpl_id() << "\n"; } } } + int main (int argc, char* argv[]) { boost::filesystem::path output = "."; - dcp::NameFormat container_name_format = Config::instance()->kdm_container_name_format(); - dcp::NameFormat filename_format = Config::instance()->kdm_filename_format(); + auto container_name_format = Config::instance()->kdm_container_name_format(); + auto filename_format = Config::instance()->kdm_filename_format(); optional cinema_name; shared_ptr cinema; - string screen_description = ""; - list > screens; + string screen_description; + list> screens; optional dkdm; optional valid_from; optional valid_to; @@ -466,13 +483,13 @@ int main (int argc, char* argv[]) duration_string = optarg; break; case 'F': - if (string (optarg) == "modified-transitional-1") { + if (string(optarg) == "modified-transitional-1") { formulation = dcp::Formulation::MODIFIED_TRANSITIONAL_1; - } else if (string (optarg) == "multiple-modified-transitional-1") { + } else if (string(optarg) == "multiple-modified-transitional-1") { formulation = dcp::Formulation::MULTIPLE_MODIFIED_TRANSITIONAL_1; - } else if (string (optarg) == "dci-any") { + } else if (string(optarg) == "dci-any") { formulation = dcp::Formulation::DCI_ANY; - } else if (string (optarg) == "dci-specific") { + } else if (string(optarg) == "dci-specific") { formulation = dcp::Formulation::DCI_SPECIFIC; } else { error ("unrecognised KDM formulation " + string (optarg)); @@ -501,7 +518,7 @@ int main (int argc, char* argv[]) (for lookup) and by creating a Cinema which the next Screen will be added to. */ cinema_name = optarg; - cinema = shared_ptr (new Cinema (optarg, list(), "", 0, 0)); + cinema = make_shared(optarg, list(), "", 0, 0); break; case 'S': screen_description = optarg; @@ -510,7 +527,7 @@ int main (int argc, char* argv[]) { /* Make a new screen and add it to the current cinema */ dcp::CertificateChain chain (dcp::file_to_string(optarg)); - shared_ptr screen (new Screen (screen_description, "", chain.leaf(), vector())); + auto screen = make_shared(screen_description, "", chain.leaf(), vector()); if (cinema) { cinema->add_screen (screen); } @@ -533,9 +550,9 @@ int main (int argc, char* argv[]) } if (list_cinemas) { - list > cinemas = Config::instance()->cinemas (); - for (list >::const_iterator i = cinemas.begin(); i != cinemas.end(); ++i) { - cout << (*i)->name << " (" << Emailer::address_list ((*i)->emails) << ")\n"; + auto cinemas = Config::instance()->cinemas (); + for (auto i: cinemas) { + cout << i->name << " (" << Emailer::address_list (i->emails) << ")\n"; } exit (EXIT_SUCCESS); } diff --git a/src/wx/content_view.cc b/src/wx/content_view.cc index b3a66a7be..8055e2f2d 100644 --- a/src/wx/content_view.cc +++ b/src/wx/content_view.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2018 Carl Hetherington + Copyright (C) 2018-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,6 +18,7 @@ */ + #include "content_view.h" #include "wx_util.h" #include "lib/dcpomatic_assert.h" @@ -32,15 +33,18 @@ #include #include -using std::string; + using std::cout; +using std::dynamic_pointer_cast; using std::list; +using std::make_shared; using std::shared_ptr; +using std::string; using std::weak_ptr; using boost::optional; -using std::dynamic_pointer_cast; using namespace dcpomatic; + ContentView::ContentView (wxWindow* parent) : wxListCtrl (parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_NO_HEADER) { @@ -51,18 +55,20 @@ ContentView::ContentView (wxWindow* parent) AppendColumn (wxT(""), wxLIST_FORMAT_LEFT, 580); } + shared_ptr ContentView::selected () const { long int s = GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); if (s == -1) { - return shared_ptr(); + return {}; } DCPOMATIC_ASSERT (s < int(_content.size())); return _content[s]; } + void ContentView::update () { @@ -70,29 +76,29 @@ ContentView::update () DeleteAllItems (); _content.clear (); - optional dir = Config::instance()->player_content_directory(); + auto dir = Config::instance()->player_content_directory(); if (!dir || !boost::filesystem::is_directory(*dir)) { dir = home_directory (); } wxProgressDialog progress (_("DCP-o-matic"), _("Reading content directory")); - JobManager* jm = JobManager::instance (); + auto jm = JobManager::instance (); - list > jobs; + list> jobs; - for (directory_iterator i = directory_iterator(*dir); i != directory_iterator(); ++i) { + for (auto i: directory_iterator(*dir)) { try { progress.Pulse (); shared_ptr content; - if (is_directory(*i) && (is_regular_file(*i / "ASSETMAP") || is_regular_file(*i / "ASSETMAP.xml"))) { - content.reset (new DCPContent(*i)); - } else if (i->path().extension() == ".mp4" || i->path().extension() == ".ecinema") { - content = content_factory(*i).front(); + if (is_directory(i) && (is_regular_file(i / "ASSETMAP") || is_regular_file(i / "ASSETMAP.xml"))) { + content.reset (new DCPContent(i)); + } else if (i.path().extension() == ".mp4" || i.path().extension() == ".ecinema") { + content = content_factory(i).front(); } if (content) { - shared_ptr job(new ExamineContentJob(shared_ptr(), content)); + auto job = make_shared(shared_ptr(), content); jm->add (job); jobs.push_back (job); } @@ -125,6 +131,7 @@ ContentView::update () } } + void ContentView::add (shared_ptr content) { @@ -152,6 +159,7 @@ ContentView::add (shared_ptr content) SetItem(it); } + shared_ptr ContentView::get (string digest) const { @@ -161,5 +169,5 @@ ContentView::get (string digest) const } } - return shared_ptr(); + return {}; } diff --git a/src/wx/content_view.h b/src/wx/content_view.h index 0bbfffaa7..1ad7c541a 100644 --- a/src/wx/content_view.h +++ b/src/wx/content_view.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,6 +18,7 @@ */ + #include "lib/content_store.h" #include "lib/warnings.h" DCPOMATIC_DISABLE_WARNINGS @@ -25,9 +26,11 @@ DCPOMATIC_DISABLE_WARNINGS DCPOMATIC_ENABLE_WARNINGS #include + class Content; class Film; + class ContentView : public wxListCtrl, public ContentStore { public: @@ -42,5 +45,5 @@ private: void add (std::shared_ptr content); std::weak_ptr _film; - std::vector > _content; + std::vector> _content; }; diff --git a/src/wx/job_manager_view.cc b/src/wx/job_manager_view.cc index 6b341307d..19243393c 100644 --- a/src/wx/job_manager_view.cc +++ b/src/wx/job_manager_view.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2017 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -16,12 +16,15 @@ You should have received a copy of the GNU General Public License along with DCP-o-matic. If not, see . + */ + /** @file src/job_manager_view.cc * @brief Class generating a GTK widget to show the progress of jobs. */ + #include "job_manager_view.h" #include "batch_job_view.h" #include "normal_job_view.h" @@ -33,6 +36,7 @@ #include "lib/compose.hpp" #include + using std::string; using std::list; using std::map; @@ -45,6 +49,7 @@ using boost::bind; using namespace boost::placeholders; #endif + /** @param parent Parent window. * @param batch true to use BatchJobView, false to use NormalJobView. * @@ -55,7 +60,7 @@ JobManagerView::JobManagerView (wxWindow* parent, bool batch) , _batch (batch) { _panel = new wxPanel (this); - wxSizer* sizer = new wxBoxSizer (wxVERTICAL); + auto sizer = new wxBoxSizer (wxVERTICAL); sizer->Add (_panel, 1, wxEXPAND); SetSizer (sizer); @@ -66,24 +71,25 @@ JobManagerView::JobManagerView (wxWindow* parent, bool batch) SetScrollRate (0, 32); EnableScrolling (false, true); - Bind (wxEVT_TIMER, boost::bind (&JobManagerView::periodic, this)); + Bind (wxEVT_TIMER, boost::bind(&JobManagerView::periodic, this)); _timer.reset (new wxTimer (this)); _timer->Start (1000); - JobManager::instance()->JobAdded.connect (bind (&JobManagerView::job_added, this, _1)); - JobManager::instance()->JobsReordered.connect (bind (&JobManagerView::replace, this)); + JobManager::instance()->JobAdded.connect (bind(&JobManagerView::job_added, this, _1)); + JobManager::instance()->JobsReordered.connect (bind(&JobManagerView::replace, this)); } + void JobManagerView::job_added (weak_ptr j) { - shared_ptr job = j.lock (); + auto job = j.lock (); if (job) { shared_ptr v; if (_batch) { - v.reset (new BatchJobView (job, this, _panel, _table)); + v.reset (new BatchJobView(job, this, _panel, _table)); } else { - v.reset (new NormalJobView (job, this, _panel, _table)); + v.reset (new NormalJobView(job, this, _panel, _table)); } v->setup (); _job_records.push_back (v); @@ -93,20 +99,22 @@ JobManagerView::job_added (weak_ptr j) job_list_changed (); } + void JobManagerView::periodic () { - for (list >::iterator i = _job_records.begin(); i != _job_records.end(); ++i) { - (*i)->maybe_pulse (); + for (auto i: _job_records) { + i->maybe_pulse (); } } + void JobManagerView::replace () { /* Make a new version of _job_records which reflects the order in JobManager's job list */ - list > new_job_records; + list> new_job_records; for (auto i: JobManager::instance()->get()) { /* Find this job's JobView */ @@ -131,6 +139,7 @@ JobManagerView::replace () job_list_changed (); } + void JobManagerView::job_list_changed () { diff --git a/src/wx/job_manager_view.h b/src/wx/job_manager_view.h index 392d7504c..e960bc2f6 100644 --- a/src/wx/job_manager_view.h +++ b/src/wx/job_manager_view.h @@ -18,6 +18,7 @@ */ + /** @file src/job_manager_view.h * @brief Class which is a wxPanel for showing the progress of jobs. */ @@ -54,5 +55,5 @@ private: std::shared_ptr _timer; bool _batch; - std::list > _job_records; + std::list> _job_records; }; diff --git a/src/wx/recipients_panel.cc b/src/wx/recipients_panel.cc index e59293fe7..58a986ca4 100644 --- a/src/wx/recipients_panel.cc +++ b/src/wx/recipients_panel.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2015-2020 Carl Hetherington + Copyright (C) 2015-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,6 +18,7 @@ */ + #include "recipients_panel.h" #include "wx_util.h" #include "recipient_dialog.h" @@ -26,21 +27,23 @@ #include #include -using std::list; -using std::pair; + using std::cout; -using std::map; -using std::string; +using std::list; using std::make_pair; +using std::map; +using std::pair; using std::shared_ptr; +using std::string; using boost::optional; using namespace dcpomatic; + RecipientsPanel::RecipientsPanel (wxWindow* parent) : wxPanel (parent, wxID_ANY) , _ignore_selection_change (false) { - wxBoxSizer* sizer = new wxBoxSizer (wxVERTICAL); + auto sizer = new wxBoxSizer (wxVERTICAL); #ifdef __WXGTK3__ int const height = 30; @@ -55,13 +58,13 @@ RecipientsPanel::RecipientsPanel (wxWindow* parent) #endif sizer->Add (_search, 0, wxBOTTOM, DCPOMATIC_SIZER_GAP); - wxBoxSizer* targets = new wxBoxSizer (wxHORIZONTAL); + auto targets = new wxBoxSizer (wxHORIZONTAL); _targets = new wxTreeCtrl (this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTR_HIDE_ROOT | wxTR_MULTIPLE | wxTR_HAS_BUTTONS | wxTR_LINES_AT_ROOT); targets->Add (_targets, 1, wxEXPAND | wxRIGHT, DCPOMATIC_SIZER_GAP); add_recipients (); - wxBoxSizer* target_buttons = new wxBoxSizer (wxVERTICAL); + auto target_buttons = new wxBoxSizer (wxVERTICAL); _add_recipient = new Button (this, _("Add...")); target_buttons->Add (_add_recipient, 1, wxEXPAND | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP); @@ -122,9 +125,9 @@ RecipientsPanel::add_recipient (shared_ptr r) void RecipientsPanel::add_recipient_clicked () { - RecipientDialog* d = new RecipientDialog (GetParent(), _("Add recipient")); + auto d = new RecipientDialog (GetParent(), _("Add recipient")); if (d->ShowModal() == wxID_OK) { - shared_ptr r (new DKDMRecipient(d->name(), d->notes(), d->recipient(), d->emails(), d->utc_offset_hour(), d->utc_offset_minute())); + auto r = std::make_shared(d->name(), d->notes(), d->recipient(), d->emails(), d->utc_offset_hour(), d->utc_offset_minute()); Config::instance()->add_dkdm_recipient (r); add_recipient (r); } @@ -140,9 +143,9 @@ RecipientsPanel::edit_recipient_clicked () return; } - pair > c = *_selected.begin(); + auto c = *_selected.begin(); - RecipientDialog* d = new RecipientDialog ( + auto d = new RecipientDialog ( GetParent(), _("Edit recipient"), c.second->name, c.second->notes, c.second->emails, c.second->utc_offset_hour, c.second->utc_offset_minute, c.second->recipient ); @@ -163,22 +166,22 @@ RecipientsPanel::edit_recipient_clicked () void RecipientsPanel::remove_recipient_clicked () { - for (RecipientMap::iterator i = _selected.begin(); i != _selected.end(); ++i) { - Config::instance()->remove_dkdm_recipient (i->second); - _targets->Delete (i->first); + for (auto const& i: _selected) { + Config::instance()->remove_dkdm_recipient (i.second); + _targets->Delete (i.first); } selection_changed (); } -list > +list> RecipientsPanel::recipients () const { - list > r; + list> r; - for (RecipientMap::const_iterator i = _selected.begin(); i != _selected.end(); ++i) { - r.push_back (i->second); + for (auto const& i: _selected) { + r.push_back (i.second); } r.sort (); @@ -240,10 +243,10 @@ RecipientsPanel::search_changed () _ignore_selection_change = true; - for (RecipientMap::const_iterator i = _selected.begin(); i != _selected.end(); ++i) { + for (auto const& i: _selected) { /* The wxTreeItemIds will now be different, so we must search by recipient */ - RecipientMap::const_iterator j = _recipients.begin (); - while (j != _recipients.end() && j->second != i->second) { + auto j = _recipients.begin (); + while (j != _recipients.end() && j->second != i.second) { ++j; } diff --git a/src/wx/recipients_panel.h b/src/wx/recipients_panel.h index d224eed1b..aacfccd9a 100644 --- a/src/wx/recipients_panel.h +++ b/src/wx/recipients_panel.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2015-2020 Carl Hetherington + Copyright (C) 2015-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,6 +18,7 @@ */ + #include "lib/dkdm_recipient.h" #include "lib/warnings.h" DCPOMATIC_DISABLE_WARNINGS @@ -29,8 +30,10 @@ DCPOMATIC_ENABLE_WARNINGS #include #include + class DKDMRecipient; + class RecipientsPanel : public wxPanel { public: @@ -39,7 +42,7 @@ public: void setup_sensitivity (); - std::list > recipients () const; + std::list> recipients () const; boost::signals2::signal RecipientsChanged; private: @@ -59,7 +62,7 @@ private: wxButton* _remove_recipient; wxTreeItemId _root; - typedef std::map > RecipientMap; + typedef std::map> RecipientMap; RecipientMap _recipients; RecipientMap _selected; diff --git a/src/wx/timeline_labels_view.cc b/src/wx/timeline_labels_view.cc index b0bd8acbb..4450fef05 100644 --- a/src/wx/timeline_labels_view.cc +++ b/src/wx/timeline_labels_view.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2016-2018 Carl Hetherington + Copyright (C) 2016-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -24,9 +24,11 @@ #include #include + using std::list; -using std::min; using std::max; +using std::min; + TimelineLabelsView::TimelineLabelsView (Timeline& tl) : TimelineView (tl) @@ -47,17 +49,19 @@ TimelineLabelsView::TimelineLabelsView (Timeline& tl) _width += 24; } + dcpomatic::Rect TimelineLabelsView::bbox () const { return dcpomatic::Rect (0, 0, _width, _timeline.tracks() * _timeline.pixels_per_track()); } + void -TimelineLabelsView::do_paint (wxGraphicsContext* gc, list >) +TimelineLabelsView::do_paint (wxGraphicsContext* gc, list>) { int const h = _timeline.pixels_per_track (); - gc->SetFont (gc->CreateFont(wxNORMAL_FONT->Bold(), wxColour (0, 0, 0))); + gc->SetFont (gc->CreateFont(wxNORMAL_FONT->Bold(), wxColour(0, 0, 0))); int fy = 0; if (_video_tracks) { @@ -84,24 +88,28 @@ TimelineLabelsView::do_paint (wxGraphicsContext* gc, list > } } + void TimelineLabelsView::set_video_tracks (int n) { _video_tracks = n; } + void TimelineLabelsView::set_audio_tracks (int n) { _audio_tracks = n; } + void TimelineLabelsView::set_text_tracks (int n) { _text_tracks = n; } + void TimelineLabelsView::set_atmos (bool s) { diff --git a/src/wx/timeline_labels_view.h b/src/wx/timeline_labels_view.h index 88094f2c4..2ff1fa6a8 100644 --- a/src/wx/timeline_labels_view.h +++ b/src/wx/timeline_labels_view.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2016-2018 Carl Hetherington + Copyright (C) 2016-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,10 +18,13 @@ */ + #include "timeline_view.h" + class wxWindow; + class TimelineLabelsView : public TimelineView { public: @@ -35,7 +38,7 @@ public: void set_atmos (bool s); private: - void do_paint (wxGraphicsContext* gc, std::list > overlaps); + void do_paint (wxGraphicsContext* gc, std::list> overlaps); int _width = 0; int _video_tracks = 0;