*/
+
#include "audio_mapping.h"
#include "audio_processor.h"
#include "digester.h"
#include <boost/regex.hpp>
#include <iostream>
+
using std::list;
using std::cout;
using std::make_pair;
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.
setup (input_channels, output_channels);
}
+
void
AudioMapping::setup (int input_channels, int output_channels)
{
make_zero ();
}
+
void
AudioMapping::make_zero ()
{
}
}
+
struct ChannelRegex
{
ChannelRegex (string regex_, int channel_)
int channel;
};
+
void
AudioMapping::make_default (AudioProcessor const * processor, optional<boost::filesystem::path> filename)
{
}
}
+
AudioMapping::AudioMapping (cxml::ConstNodePtr node, int state_version)
{
if (state_version < 32) {
- setup (node->number_child<int> ("ContentChannels"), MAX_DCP_AUDIO_CHANNELS);
+ setup (node->number_child<int>("ContentChannels"), MAX_DCP_AUDIO_CHANNELS);
} else {
- setup (node->number_child<int> ("InputChannels"), node->number_child<int> ("OutputChannels"));
+ setup (node->number_child<int>("InputChannels"), node->number_child<int>("OutputChannels"));
}
if (state_version <= 5) {
return _gain[input_channel][output_channel];
}
+
void
AudioMapping::as_xml (xmlpp::Node* node) const
{
}
}
+
/** @return a string which is unique for a given AudioMapping configuration, for
* differentiation between different AudioMappings.
*/
return digester.get ();
}
+
list<int>
AudioMapping::mapped_output_channels () const
{
return mapped;
}
+
void
AudioMapping::unmap_all ()
{
*/
+
/** @file src/lib/audio_mapping.h
* @brief AudioMapping class.
*/
+
#ifndef DCPOMATIC_AUDIO_MAPPING_H
#define DCPOMATIC_AUDIO_MAPPING_H
+
#include <dcp/types.h>
#include <libcxml/cxml.h>
#include <vector>
+
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);
private:
void setup (int input_channels, int output_channels);
- int _input_channels;
- int _output_channels;
- std::vector<std::vector<float> > _gain;
+ int _input_channels = 0;
+ int _output_channels = 0;
+ std::vector<std::vector<float>> _gain;
};
+
#endif
/*
- Copyright (C) 2013-2017 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2013-2021 Carl Hetherington <cth@carlh.net>
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
*/
+
/** @file src/audio_merger.cc
* @brief AudioMerger class.
*/
+
#include "audio_merger.h"
#include "dcpomatic_time.h"
#include <iostream>
-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<pair<shared_ptr<AudioBuffers>, DCPTime> >
+list<pair<shared_ptr<AudioBuffers>, DCPTime>>
AudioMerger::pull (DCPTime time)
{
- list<pair<shared_ptr<AudioBuffers>, DCPTime> > out;
+ list<pair<shared_ptr<AudioBuffers>, DCPTime>> out;
list<Buffer> 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 */
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<AudioBuffers> audio(new AudioBuffers(i.audio, overlap, 0));
+ auto audio = make_shared<AudioBuffers>(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);
_buffers = new_buffers;
- for (list<pair<shared_ptr<AudioBuffers>, 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<const AudioBuffers> audio, DCPTime time)
/* Mix any overlapping parts of this new block with existing ones */
for (auto i: _buffers) {
- optional<DCPTimePeriod> 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());
list<DCPTimePeriod> 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<Buffer>::iterator before = _buffers.end();
- list<Buffer>::iterator after = _buffers.end();
- for (list<Buffer>::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;
}
}
/* Get the part of audio that we want to use */
- shared_ptr<AudioBuffers> part (new AudioBuffers(audio, frames(i.to) - frames(i.from), frames(DCPTime(i.from - time))));
+ auto part = make_shared<AudioBuffers>(audio, frames(i.to) - frames(i.from), frames(DCPTime(i.from - time)));
if (before == _buffers.end() && after == _buffers.end()) {
if (part->frames() > 0) {
}
}
+
void
AudioMerger::clear ()
{
/*
- Copyright (C) 2013-2017 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2013-2021 Carl Hetherington <cth@carlh.net>
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
*/
+
/** @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.
*/
public:
explicit AudioMerger (int frame_rate);
- std::list<std::pair<std::shared_ptr<AudioBuffers>, dcpomatic::DCPTime> > pull (dcpomatic::DCPTime time);
+ std::list<std::pair<std::shared_ptr<AudioBuffers>, dcpomatic::DCPTime>> pull (dcpomatic::DCPTime time);
void push (std::shared_ptr<const AudioBuffers> audio, dcpomatic::DCPTime time);
void clear ();
}
};
- class BufferComparator
- {
- public:
- bool operator() (AudioMerger::Buffer const & a, AudioMerger::Buffer const & b)
- {
- return a.time < b.time;
- }
- };
-
std::list<Buffer> _buffers;
int _frame_rate;
};
*/
+
/** @file src/lib/content_factory.cc
* @brief Methods to create content objects.
*/
+
#include "ffmpeg_content.h"
#include "audio_content.h"
#include "image_content.h"
#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.
shared_ptr<Content>
content_factory (cxml::ConstNodePtr node, int version, list<string>& notes)
{
- string const type = node->string_child ("Type");
+ auto const type = node->string_child ("Type");
std::shared_ptr<Content> content;
/* 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<int> ("AudioFrameRate"),
- node->number_child<Frame> ("AudioLength"),
- AudioMapping (node->node_child ("AudioMapping"), version)
- )
+ make_shared<FFmpegAudioStream>(
+ "Stream", 0,
+ node->number_child<int> ("AudioFrameRate"),
+ node->number_child<Frame> ("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<shared_ptr<Content> >
+list<shared_ptr<Content>>
content_factory (boost::filesystem::path path)
{
- list<shared_ptr<Content> > content;
+ list<shared_ptr<Content>> content;
if (boost::filesystem::is_directory (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;
}
}
if (image_files > 0 && sound_files == 0) {
- content.push_back (shared_ptr<Content> (new ImageContent(path)));
+ content.push_back (make_shared<ImageContent>(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<FFmpegContent> (new FFmpegContent(i->path())));
+ for (auto i: boost::filesystem::directory_iterator(path)) {
+ content.push_back (make_shared<FFmpegContent>(i.path()));
}
}
shared_ptr<Content> single;
- string ext = path.extension().string ();
+ auto ext = path.extension().string();
transform (ext.begin(), ext.end(), ext.begin(), ::tolower);
if (valid_image_file (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));
}
/*
- Copyright (C) 2013-2014 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2013-2021 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
*/
+
/** @file src/lib/content_factory.h
* @brief Methods to create content objects.
*/
+
#include <libcxml/cxml.h>
+
class Film;
class Content;
+
extern std::shared_ptr<Content> content_factory (cxml::ConstNodePtr, int, std::list<std::string> &);
-extern std::list<std::shared_ptr<Content> > content_factory (boost::filesystem::path);
+extern std::list<std::shared_ptr<Content>> content_factory (boost::filesystem::path);
/*
- Copyright (C) 2012-2018 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2021 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
*/
+
/** @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"
#include "i18n.h"
+
using std::string;
using std::vector;
using std::list;
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)
}
+
EncodeServer::~EncodeServer ()
{
boost::this_thread::disable_interruption dis;
} 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.
*/
{
Socket::ReadDigestScope ds (socket);
- uint32_t length = socket->read_uint32 ();
+ auto length = socket->read_uint32 ();
scoped_array<char> buffer (new char[length]);
- socket->read (reinterpret_cast<uint8_t*> (buffer.get()), length);
+ socket->read (reinterpret_cast<uint8_t*>(buffer.get()), length);
string s (buffer.get());
auto xml = make_shared<cxml::Document>("EncodingRequest");
return dcp_video_frame.index ();
}
+
void
EncodeServer::worker_thread ()
{
}
}
+
void
EncodeServer::run ()
{
Server::run ();
}
+
void
EncodeServer::broadcast_thread ()
try
store_current ();
}
+
void
EncodeServer::broadcast_received ()
{
}
}
+
void
EncodeServer::handle (shared_ptr<Socket> socket)
{
/*
- Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2021 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
*/
+
#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 <boost/thread.hpp>
#include <boost/thread/condition.hpp>
#include <string>
+
class Socket;
class Log;
+
/** @class EncodeServer
* @brief A class to run a server which can accept requests to perform JPEG2000
* encoding work.
void broadcast_received ();
boost::thread_group _worker_threads;
- std::list<std::shared_ptr<Socket> > _queue;
+ std::list<std::shared_ptr<Socket>> _queue;
boost::condition _full_condition;
boost::condition _empty_condition;
bool _verbose;
} _broadcast;
};
+
#endif
/*
- Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2021 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
*/
+
#include "log.h"
#include "compose.hpp"
#include "version.h"
#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.
return buffer;
}
+
/** Return a user-readable string summarising the versions of our dependencies */
static
string
return buffer;
}
+
list<string>
environment_info ()
{
#endif
#endif
- info.push_back (String::compose ("CPU: %1, %2 processors", cpu_info(), boost::thread::hardware_concurrency ()));
- list<pair<string, string> > const m = mount_info ();
- for (list<pair<string, string> >::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;
/*
- Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2021 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
*/
+
extern std::list<std::string> environment_info ();
/*
- Copyright (C) 2013-2019 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2013-2021 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
*/
+
#include "ffmpeg.h"
#include "ffmpeg_content.h"
#include "film.h"
#include "i18n.h"
+
using std::string;
using std::cout;
using std::cerr;
using dcp::raw_convert;
using namespace dcpomatic;
+
boost::mutex FFmpeg::_mutex;
+
FFmpeg::FFmpeg (std::shared_ptr<const FFmpegContent> 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);
avformat_close_input (&_format_context);
}
+
static int
avio_read_wrapper (void* data, uint8_t* buffer, int amount)
{
return reinterpret_cast<FFmpeg*>(data)->avio_read (buffer, amount);
}
+
static int64_t
avio_seek_wrapper (void* data, int64_t offset, int whence)
{
return reinterpret_cast<FFmpeg*>(data)->avio_seek (offset, whence);
}
+
void
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 ()
{
av_log_set_callback (FFmpeg::ffmpeg_log_callback);
_file_group.set_paths (_ffmpeg_content->paths ());
- _avio_buffer = static_cast<uint8_t*> (wrapped_av_malloc (_avio_buffer_size));
+ _avio_buffer = static_cast<uint8_t*> (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 ();
}
}
+
void
FFmpeg::setup_decoders ()
{
DCPOMATIC_ENABLE_WARNINGS
}
+
DCPOMATIC_DISABLE_WARNINGS
AVCodecContext *
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;
}
}
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)
{
return _file_group.seek (pos, whence);
}
+
FFmpegSubtitlePeriod
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
/*
- Copyright (C) 2013-2016 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2013-2021 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
*/
+
#ifndef DCPOMATIC_FFMPEG_H
#define DCPOMATIC_FFMPEG_H
+
#include "file_group.h"
#include "ffmpeg_subtitle_period.h"
#include "warnings.h"
DCPOMATIC_ENABLE_WARNINGS
#include <boost/thread/mutex.hpp>
+
struct AVFormatContext;
struct AVFrame;
struct AVIOContext;
class FFmpegAudioStream;
class Log;
+
class FFmpeg
{
public:
AVCodecContext* video_codec_context () const;
AVCodecContext* subtitle_codec_context () const;
dcpomatic::ContentTime pts_offset (
- std::vector<std::shared_ptr<FFmpegAudioStream> > audio_streams, boost::optional<dcpomatic::ContentTime> first_video, double video_frame_rate
+ std::vector<std::shared_ptr<FFmpegAudioStream>> audio_streams, boost::optional<dcpomatic::ContentTime> first_video, double video_frame_rate
) const;
static FFmpegSubtitlePeriod subtitle_period (AVSubtitle const & sub);
std::shared_ptr<const FFmpegContent> _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<int> _video_stream;
static std::weak_ptr<Log> _ffmpeg_log;
};
+
#endif
You should have received a copy of the GNU General Public License
along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
*/
#include "ffmpeg_content.h"
#include "i18n.h"
+
using std::string;
using std::vector;
using std::list;
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 <class T>
optional<T>
get_optional_enum (cxml::ConstNodePtr node, string name)
return static_cast<T>(*v);
}
+
FFmpegContent::FFmpegContent (cxml::ConstNodePtr node, int version, list<string>& notes)
: Content (node)
{
_bits_per_pixel = node->optional_number_child<int> ("BitsPerPixel");
}
-FFmpegContent::FFmpegContent (vector<shared_ptr<Content> > c)
+
+FFmpegContent::FFmpegContent (vector<shared_ptr<Content>> c)
: Content (c)
{
auto i = c.begin ();
_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) {
if (audio) {
audio->as_xml (node);
- for (auto i: audio->streams ()) {
+ for (auto i: audio->streams()) {
auto f = dynamic_pointer_cast<FFmpegAudioStream> (i);
DCPOMATIC_ASSERT (f);
f->as_xml (node->add_child("AudioStream"));
}
if (_first_video) {
- node->add_child("FirstVideo")->add_child_text (raw_convert<string> (_first_video.get().get()));
+ node->add_child("FirstVideo")->add_child_text(raw_convert<string>(_first_video.get().get()));
}
if (_color_range) {
- node->add_child("ColorRange")->add_child_text (raw_convert<string> (static_cast<int> (*_color_range)));
+ node->add_child("ColorRange")->add_child_text(raw_convert<string>(static_cast<int>(*_color_range)));
}
if (_color_primaries) {
- node->add_child("ColorPrimaries")->add_child_text (raw_convert<string> (static_cast<int> (*_color_primaries)));
+ node->add_child("ColorPrimaries")->add_child_text(raw_convert<string>(static_cast<int>(*_color_primaries)));
}
if (_color_trc) {
- node->add_child("ColorTransferCharacteristic")->add_child_text (raw_convert<string> (static_cast<int> (*_color_trc)));
+ node->add_child("ColorTransferCharacteristic")->add_child_text(raw_convert<string>(static_cast<int>(*_color_trc)));
}
if (_colorspace) {
- node->add_child("Colorspace")->add_child_text (raw_convert<string> (static_cast<int> (*_colorspace)));
+ node->add_child("Colorspace")->add_child_text(raw_convert<string>(static_cast<int>(*_colorspace)));
}
if (_bits_per_pixel) {
- node->add_child("BitsPerPixel")->add_child_text (raw_convert<string> (*_bits_per_pixel));
+ node->add_child("BitsPerPixel")->add_child_text(raw_convert<string>(*_bits_per_pixel));
}
}
+
void
FFmpegContent::examine (shared_ptr<const Film> film, shared_ptr<Job> job)
{
}
}
- if (!examiner->audio_streams().empty ()) {
+ if (!examiner->audio_streams().empty()) {
audio = make_shared<AudioContent>(this);
for (auto i: examiner->audio_streams()) {
}
}
+
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
{
);
}
+
void
FFmpegContent::set_subtitle_stream (shared_ptr<FFmpegSubtitleStream> 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<const Film> film) const
{
/* XXX: subtitle content? */
- return DCPTime();
+ return {};
}
+
DCPTime
FFmpegContent::approximate_length () const
{
return DCPTime::from_frames (longest, 24);
}
+
void
FFmpegContent::set_filters (vector<Filter const *> const & filters)
{
}
}
+
string
FFmpegContent::identifier () const
{
return s;
}
+
void
FFmpegContent::set_default_colour_conversion ()
{
}
}
+
void
FFmpegContent::add_properties (shared_ptr<const Film> film, list<UserProperty>& p) const
{
}
}
+
/** 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
ContentChangeSignaller cc (this, FFmpegContentProperty::SUBTITLE_STREAM);
}
-vector<shared_ptr<FFmpegAudioStream> >
+
+vector<shared_ptr<FFmpegAudioStream>>
FFmpegContent::ffmpeg_audio_streams () const
{
- vector<shared_ptr<FFmpegAudioStream> > fa;
+ vector<shared_ptr<FFmpegAudioStream>> fa;
if (audio) {
for (auto i: audio->streams()) {
- fa.push_back (dynamic_pointer_cast<FFmpegAudioStream> (i));
+ fa.push_back (dynamic_pointer_cast<FFmpegAudioStream>(i));
}
}
return fa;
}
+
void
FFmpegContent::take_settings_from (shared_ptr<const Content> c)
{
public:
FFmpegContent (boost::filesystem::path);
FFmpegContent (cxml::ConstNodePtr, int version, std::list<std::string> &);
- FFmpegContent (std::vector<std::shared_ptr<Content> >);
+ FFmpegContent (std::vector<std::shared_ptr<Content>>);
std::shared_ptr<FFmpegContent> shared_from_this () {
return std::dynamic_pointer_cast<FFmpegContent> (Content::shared_from_this ());
void set_filters (std::vector<Filter const *> const &);
- std::vector<std::shared_ptr<FFmpegSubtitleStream> > subtitle_streams () const {
+ std::vector<std::shared_ptr<FFmpegSubtitleStream>> subtitle_streams () const {
boost::mutex::scoped_lock lm (_mutex);
return _subtitle_streams;
}
return _subtitle_stream;
}
- std::vector<std::shared_ptr<FFmpegAudioStream> > ffmpeg_audio_streams () const;
+ std::vector<std::shared_ptr<FFmpegAudioStream>> ffmpeg_audio_streams () const;
std::vector<Filter const *> filters () const {
boost::mutex::scoped_lock lm (_mutex);
friend struct ffmpeg_pts_offset_test;
friend struct audio_sampling_rate_test;
- std::vector<std::shared_ptr<FFmpegSubtitleStream> > _subtitle_streams;
+ std::vector<std::shared_ptr<FFmpegSubtitleStream>> _subtitle_streams;
std::shared_ptr<FFmpegSubtitleStream> _subtitle_stream;
boost::optional<dcpomatic::ContentTime> _first_video;
/** Video filters that should be used when generating DCPs */
/*
- Copyright (C) 2014-2018 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2014-2021 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
*/
+
#include "player_text.h"
#include "font.h"
+
using std::list;
using std::shared_ptr;
using namespace dcpomatic;
+
void
-PlayerText::add_fonts (list<shared_ptr<Font> > fonts_)
+PlayerText::add_fonts (list<shared_ptr<Font>> fonts_)
{
for (auto i: fonts_) {
bool got = false;
/*
- Copyright (C) 2014-2018 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2014-2021 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
*/
+
#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<std::shared_ptr<dcpomatic::Font> > fonts_);
+ void add_fonts (std::list<std::shared_ptr<dcpomatic::Font>> fonts_);
std::list<std::shared_ptr<dcpomatic::Font> > fonts;
/** BitmapTexts, with their rectangles transformed as specified by their content */
std::list<StringText> string;
};
+
#endif
/*
- Copyright (C) 2014-2015 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2014-2021 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
*/
+
#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)
}
+
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<AudioProcessor>
UpmixerA::clone (int sampling_rate) const
{
- return shared_ptr<AudioProcessor> (new UpmixerA (sampling_rate));
+ return make_shared<UpmixerA>(sampling_rate);
}
+
shared_ptr<AudioBuffers>
UpmixerA::run (shared_ptr<const AudioBuffers> in, int channels)
{
/* Input L and R */
- shared_ptr<AudioBuffers> in_L = in->channel (0);
- shared_ptr<AudioBuffers> 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<AudioBuffers> 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<shared_ptr<AudioBuffers> > 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<AudioBuffers> out (new AudioBuffers (channels, in->frames ()));
+ vector<shared_ptr<AudioBuffers>> 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<AudioBuffers>(channels, in->frames());
int const N = min (channels, 6);
for (int i = 0; i < N; ++i) {
_rs.flush ();
}
+
void
UpmixerA::make_audio_mapping_default (AudioMapping& mapping) const
{
}
}
+
vector<NamedChannel>
UpmixerA::input_names () const
{
- vector<NamedChannel> 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)
+ };
}
*/
+
/** @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.
*/
/*
- Copyright (C) 2012-2018 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2021 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
*/
+
#include "compose.hpp"
#include "image.h"
#include "video_filter_graph.h"
#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)
}
+
/** Take an AVFrame and process it using our configured filters, returning a
* set of Images. Caller handles memory management of the input frame.
*/
-list<pair<shared_ptr<Image>, int64_t> >
+list<pair<shared_ptr<Image>, int64_t>>
VideoFilterGraph::process (AVFrame* frame)
{
- list<pair<shared_ptr<Image>, int64_t> > images;
+ list<pair<shared_ptr<Image>, int64_t>> images;
DCPOMATIC_DISABLE_WARNINGS
if (_copy) {
- images.push_back (make_pair (shared_ptr<Image> (new Image (frame)), av_frame_get_best_effort_timestamp (frame)));
+ images.push_back (make_pair(make_shared<Image>(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) {
break;
}
- images.push_back (make_pair (shared_ptr<Image> (new Image (_frame)), av_frame_get_best_effort_timestamp (_frame)));
+ images.push_back (make_pair(make_shared<Image>(_frame), av_frame_get_best_effort_timestamp (_frame)));
av_frame_unref (_frame);
}
}
return images;
}
+
/** @param s Image size.
* @param p Pixel format.
* @return true if this chain can process images with `s' and `p', otherwise false.
return (_size == s && _pixel_format == p);
}
+
string
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
{
/*
- Copyright (C) 2012-2018 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2021 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
*/
+
#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<std::pair<std::shared_ptr<Image>, int64_t> > process (AVFrame * frame);
+ std::list<std::pair<std::shared_ptr<Image>, int64_t>> process (AVFrame * frame);
protected:
std::string src_parameters () const;
/*
- Copyright (C) 2016-2020 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2016-2021 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
*/
+
#include "video_ring_buffers.h"
#include "player_video.h"
#include "compose.hpp"
#include <list>
#include <iostream>
+
using std::list;
using std::make_pair;
using std::cout;
using boost::optional;
using namespace dcpomatic;
+
void
VideoRingBuffers::put (shared_ptr<PlayerVideo> frame, DCPTime time)
{
boost::mutex::scoped_lock lm (_mutex);
- _data.push_back (make_pair (frame, time));
+ _data.push_back (make_pair(frame, time));
}
+
pair<shared_ptr<PlayerVideo>, DCPTime>
VideoRingBuffers::get ()
{
boost::mutex::scoped_lock lm (_mutex);
if (_data.empty ()) {
- return make_pair(shared_ptr<PlayerVideo>(), DCPTime());
+ return {};
}
- pair<shared_ptr<PlayerVideo>, DCPTime> const r = _data.front ();
+ auto const r = _data.front();
_data.pop_front ();
return r;
}
+
Frame
VideoRingBuffers::size () const
{
return _data.size ();
}
+
bool
VideoRingBuffers::empty () const
{
return _data.empty ();
}
+
void
VideoRingBuffers::clear ()
{
_data.clear ();
}
+
pair<size_t, string>
VideoRingBuffers::memory_used () const
{
boost::mutex::scoped_lock lm (_mutex);
size_t m = 0;
- for (list<pair<shared_ptr<PlayerVideo>, 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()));
}
VideoRingBuffers::reset_metadata (shared_ptr<const Film> film, dcp::Size player_video_container_size)
{
boost::mutex::scoped_lock lm (_mutex);
- for (list<pair<shared_ptr<PlayerVideo>, 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);
}
}
/*
- Copyright (C) 2016-2020 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2016-2021 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
*/
+
#include "dcpomatic_time.h"
#include "player_video.h"
#include "types.h"
private:
mutable boost::mutex _mutex;
- std::list<std::pair<std::shared_ptr<PlayerVideo>, dcpomatic::DCPTime> > _data;
+ std::list<std::pair<std::shared_ptr<PlayerVideo>, dcpomatic::DCPTime>> _data;
};
/*
- Copyright (C) 2013-2018 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2013-2021 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
*/
+
/** @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 <dcp/certificate.h>
#include <dcp/decrypted_kdm.h>
#include <getopt.h>
#include <iostream>
-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
"\t" << program_name << " -c \"Fred's Cinema\" -f now -d \"2 weeks\" -z my_great_movie\n\n";
}
+
static void
error (string m)
{
exit (EXIT_FAILURE);
}
+
static boost::posix_time::ptime
time_from_string (string t)
{
return boost::posix_time::time_from_string (t);
}
+
static boost::posix_time::time_duration
duration_from_string (string d)
{
exit (EXIT_FAILURE);
}
+
static bool
always_overwrite ()
{
return true;
}
+
void
write_files (
list<KDMWithMetadataPtr> kdms,
}
}
+
shared_ptr<Cinema>
find_cinema (string cinema_name)
{
- list<shared_ptr<Cinema> > cinemas = Config::instance()->cinemas ();
- list<shared_ptr<Cinema> >::const_iterator i = cinemas.begin();
+ auto cinemas = Config::instance()->cinemas ();
+ auto i = cinemas.begin();
while (
i != cinemas.end() &&
(*i)->name != cinema_name &&
return *i;
}
+
void
from_film (
- list<shared_ptr<Screen> > screens,
+ list<shared_ptr<Screen>> screens,
boost::filesystem::path film_dir,
bool verbose,
boost::filesystem::path output,
{
shared_ptr<Film> film;
try {
- film.reset (new Film (film_dir));
+ film = make_shared<Film>(film_dir);
film->read_metadata ();
if (verbose) {
cout << "Read film " << film->name () << "\n";
error ("more than one CPL found in film");
}
- boost::filesystem::path cpl = cpls.front().cpl_file;
+ auto cpl = cpls.front().cpl_file;
try {
list<KDMWithMetadataPtr> 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);
}
}
}
+
optional<dcp::EncryptedKDM>
sub_find_dkdm (shared_ptr<DKDMGroup> group, string cpl_id)
{
for (auto i: group->children()) {
- shared_ptr<DKDMGroup> g = dynamic_pointer_cast<DKDMGroup>(i);
+ auto g = dynamic_pointer_cast<DKDMGroup>(i);
if (g) {
- optional<dcp::EncryptedKDM> dkdm = sub_find_dkdm (g, cpl_id);
+ auto dkdm = sub_find_dkdm (g, cpl_id);
if (dkdm) {
return dkdm;
}
} else {
- shared_ptr<DKDM> d = dynamic_pointer_cast<DKDM>(i);
+ auto d = dynamic_pointer_cast<DKDM>(i);
assert (d);
if (d->dkdm().cpl_id() == cpl_id) {
return d->dkdm();
return optional<dcp::EncryptedKDM>();
}
+
optional<dcp::EncryptedKDM>
find_dkdm (string cpl_id)
{
return sub_find_dkdm (Config::instance()->dkdms(), cpl_id);
}
+
dcp::EncryptedKDM
kdm_from_dkdm (
dcp::DecryptedKDM dkdm,
)
{
/* Signer for new KDM */
- shared_ptr<const dcp::CertificateChain> signer = Config::instance()->signer_chain ();
+ auto signer = Config::instance()->signer_chain ();
if (!signer->valid ()) {
error ("signing certificate chain is invalid.");
}
return kdm.encrypt (signer, target, trusted_devices, formulation, disable_forensic_marking_picture, disable_forensic_marking_audio);
}
+
void
from_dkdm (
- list<shared_ptr<Screen> > screens,
+ list<shared_ptr<Screen>> screens,
dcp::DecryptedKDM dkdm,
bool verbose,
boost::filesystem::path output,
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(),
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<KDMWithMetadata>(name_values, i->cinema.get(), i->cinema->emails, kdm));
}
write_files (kdms, zip, output, container_name_format, filename_format, verbose);
} catch (FileError& e) {
}
}
+
void
dump_dkdm_group (shared_ptr<DKDMGroup> group, int indent)
{
cout << group->name() << "\n";
}
for (auto i: group->children()) {
- shared_ptr<DKDMGroup> g = dynamic_pointer_cast<DKDMGroup>(i);
+ auto g = dynamic_pointer_cast<DKDMGroup>(i);
if (g) {
dump_dkdm_group (g, indent + 2);
} else {
for (int j = 0; j < indent; ++j) {
cout << " ";
}
- shared_ptr<DKDM> d = dynamic_pointer_cast<DKDM>(i);
+ auto d = dynamic_pointer_cast<DKDM>(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<string> cinema_name;
shared_ptr<Cinema> cinema;
- string screen_description = "";
- list<shared_ptr<Screen> > screens;
+ string screen_description;
+ list<shared_ptr<Screen>> screens;
optional<dcp::EncryptedKDM> dkdm;
optional<boost::posix_time::ptime> valid_from;
optional<boost::posix_time::ptime> valid_to;
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));
(for lookup) and by creating a Cinema which the next Screen will be added to.
*/
cinema_name = optarg;
- cinema = shared_ptr<Cinema> (new Cinema (optarg, list<string>(), "", 0, 0));
+ cinema = make_shared<Cinema>(optarg, list<string>(), "", 0, 0);
break;
case 'S':
screen_description = optarg;
{
/* Make a new screen and add it to the current cinema */
dcp::CertificateChain chain (dcp::file_to_string(optarg));
- shared_ptr<Screen> screen (new Screen (screen_description, "", chain.leaf(), vector<TrustedDevice>()));
+ auto screen = make_shared<Screen>(screen_description, "", chain.leaf(), vector<TrustedDevice>());
if (cinema) {
cinema->add_screen (screen);
}
}
if (list_cinemas) {
- list<std::shared_ptr<Cinema> > cinemas = Config::instance()->cinemas ();
- for (list<std::shared_ptr<Cinema> >::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);
}
/*
- Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2018-2021 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
*/
+
#include "content_view.h"
#include "wx_util.h"
#include "lib/dcpomatic_assert.h"
#include <boost/optional.hpp>
#include <wx/progdlg.h>
-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)
{
AppendColumn (wxT(""), wxLIST_FORMAT_LEFT, 580);
}
+
shared_ptr<Content>
ContentView::selected () const
{
long int s = GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
if (s == -1) {
- return shared_ptr<Content>();
+ return {};
}
DCPOMATIC_ASSERT (s < int(_content.size()));
return _content[s];
}
+
void
ContentView::update ()
{
DeleteAllItems ();
_content.clear ();
- optional<path> 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<shared_ptr<ExamineContentJob> > jobs;
+ list<shared_ptr<ExamineContentJob>> jobs;
- for (directory_iterator i = directory_iterator(*dir); i != directory_iterator(); ++i) {
+ for (auto i: directory_iterator(*dir)) {
try {
progress.Pulse ();
shared_ptr<Content> 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<ExamineContentJob> job(new ExamineContentJob(shared_ptr<Film>(), content));
+ auto job = make_shared<ExamineContentJob>(shared_ptr<Film>(), content);
jm->add (job);
jobs.push_back (job);
}
}
}
+
void
ContentView::add (shared_ptr<Content> content)
{
SetItem(it);
}
+
shared_ptr<Content>
ContentView::get (string digest) const
{
}
}
- return shared_ptr<Content>();
+ return {};
}
/*
- Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2018-2021 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
*/
+
#include "lib/content_store.h"
#include "lib/warnings.h"
DCPOMATIC_DISABLE_WARNINGS
DCPOMATIC_ENABLE_WARNINGS
#include <vector>
+
class Content;
class Film;
+
class ContentView : public wxListCtrl, public ContentStore
{
public:
void add (std::shared_ptr<Content> content);
std::weak_ptr<Film> _film;
- std::vector<std::shared_ptr<Content> > _content;
+ std::vector<std::shared_ptr<Content>> _content;
};
/*
- Copyright (C) 2012-2017 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2021 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
You should have received a copy of the GNU General Public License
along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
*/
+
/** @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"
#include "lib/compose.hpp"
#include <iostream>
+
using std::string;
using std::list;
using std::map;
using namespace boost::placeholders;
#endif
+
/** @param parent Parent window.
* @param batch true to use BatchJobView, false to use NormalJobView.
*
, _batch (batch)
{
_panel = new wxPanel (this);
- wxSizer* sizer = new wxBoxSizer (wxVERTICAL);
+ auto sizer = new wxBoxSizer (wxVERTICAL);
sizer->Add (_panel, 1, wxEXPAND);
SetSizer (sizer);
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<Job> j)
{
- shared_ptr<Job> job = j.lock ();
+ auto job = j.lock ();
if (job) {
shared_ptr<JobView> 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);
job_list_changed ();
}
+
void
JobManagerView::periodic ()
{
- for (list<shared_ptr<JobView> >::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<shared_ptr<JobView> > new_job_records;
+ list<shared_ptr<JobView>> new_job_records;
for (auto i: JobManager::instance()->get()) {
/* Find this job's JobView */
job_list_changed ();
}
+
void
JobManagerView::job_list_changed ()
{
*/
+
/** @file src/job_manager_view.h
* @brief Class which is a wxPanel for showing the progress of jobs.
*/
std::shared_ptr<wxTimer> _timer;
bool _batch;
- std::list<std::shared_ptr<JobView> > _job_records;
+ std::list<std::shared_ptr<JobView>> _job_records;
};
/*
- Copyright (C) 2015-2020 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2015-2021 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
*/
+
#include "recipients_panel.h"
#include "wx_util.h"
#include "recipient_dialog.h"
#include <list>
#include <iostream>
-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;
#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);
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<DKDMRecipient> r (new DKDMRecipient(d->name(), d->notes(), d->recipient(), d->emails(), d->utc_offset_hour(), d->utc_offset_minute()));
+ auto r = std::make_shared<DKDMRecipient>(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);
}
return;
}
- pair<wxTreeItemId, shared_ptr<DKDMRecipient> > 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
);
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<shared_ptr<DKDMRecipient> >
+list<shared_ptr<DKDMRecipient>>
RecipientsPanel::recipients () const
{
- list<shared_ptr<DKDMRecipient> > r;
+ list<shared_ptr<DKDMRecipient>> 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 ();
_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;
}
/*
- Copyright (C) 2015-2020 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2015-2021 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
*/
+
#include "lib/dkdm_recipient.h"
#include "lib/warnings.h"
DCPOMATIC_DISABLE_WARNINGS
#include <list>
#include <map>
+
class DKDMRecipient;
+
class RecipientsPanel : public wxPanel
{
public:
void setup_sensitivity ();
- std::list<std::shared_ptr<DKDMRecipient> > recipients () const;
+ std::list<std::shared_ptr<DKDMRecipient>> recipients () const;
boost::signals2::signal<void ()> RecipientsChanged;
private:
wxButton* _remove_recipient;
wxTreeItemId _root;
- typedef std::map<wxTreeItemId, std::shared_ptr<DKDMRecipient> > RecipientMap;
+ typedef std::map<wxTreeItemId, std::shared_ptr<DKDMRecipient>> RecipientMap;
RecipientMap _recipients;
RecipientMap _selected;
/*
- Copyright (C) 2016-2018 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2016-2021 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
#include <wx/wx.h>
#include <wx/graphics.h>
+
using std::list;
-using std::min;
using std::max;
+using std::min;
+
TimelineLabelsView::TimelineLabelsView (Timeline& tl)
: TimelineView (tl)
_width += 24;
}
+
dcpomatic::Rect<int>
TimelineLabelsView::bbox () const
{
return dcpomatic::Rect<int> (0, 0, _width, _timeline.tracks() * _timeline.pixels_per_track());
}
+
void
-TimelineLabelsView::do_paint (wxGraphicsContext* gc, list<dcpomatic::Rect<int> >)
+TimelineLabelsView::do_paint (wxGraphicsContext* gc, list<dcpomatic::Rect<int>>)
{
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) {
}
}
+
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)
{
/*
- Copyright (C) 2016-2018 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2016-2021 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
*/
+
#include "timeline_view.h"
+
class wxWindow;
+
class TimelineLabelsView : public TimelineView
{
public:
void set_atmos (bool s);
private:
- void do_paint (wxGraphicsContext* gc, std::list<dcpomatic::Rect<int> > overlaps);
+ void do_paint (wxGraphicsContext* gc, std::list<dcpomatic::Rect<int>> overlaps);
int _width = 0;
int _video_tracks = 0;