print('%{_bindir}/dcpomatic2_playlist', file=f)
print('%{_bindir}/dcpomatic2_openssl', file=f)
print('%{_bindir}/dcpomatic2_combiner', file=f)
- if options['variant'] == 'swaroop-studio':
- print('%{_bindir}/dcpomatic2_ecinema', file=f)
- print('%{_bindir}/dcpomatic2_uuid', file=f)
if os.path.exists(os.path.join(tools, "dcpomatic2_disk")):
print('%{_bindir}/dcpomatic2_disk', file=f)
print('%{_bindir}/dcpomatic2_disk_writer', file=f)
def build(bld):
desktops = []
- if bld.env.VARIANT != 'swaroop-theater':
- obj = bld(features='subst')
- obj.source = 'dcpomatic.desktop.in'
- obj.target = 'dcpomatic2.desktop'
- obj.INSTALL_PREFIX = bld.env.INSTALL_PREFIX
- obj.VERSION = bld.env.VERSION
- desktops.append(obj.target)
- obj = bld(features='subst')
- obj.source = 'dcpomatic_batch.desktop.in'
- obj.target = 'dcpomatic2_batch.desktop'
- obj.INSTALL_PREFIX = bld.env.INSTALL_PREFIX
- obj.VERSION = bld.env.VERSION
- desktops.append(obj.target)
+ obj = bld(features='subst')
+ obj.source = 'dcpomatic.desktop.in'
+ obj.target = 'dcpomatic2.desktop'
+ obj.INSTALL_PREFIX = bld.env.INSTALL_PREFIX
+ obj.VERSION = bld.env.VERSION
+ desktops.append(obj.target)
- obj = bld(features='subst')
- obj.source = 'dcpomatic_server.desktop.in'
- obj.target = 'dcpomatic2_server.desktop'
- obj.INSTALL_PREFIX = bld.env.INSTALL_PREFIX
- obj.VERSION = bld.env.VERSION
- desktops.append(obj.target)
+ obj = bld(features='subst')
+ obj.source = 'dcpomatic_batch.desktop.in'
+ obj.target = 'dcpomatic2_batch.desktop'
+ obj.INSTALL_PREFIX = bld.env.INSTALL_PREFIX
+ obj.VERSION = bld.env.VERSION
+ desktops.append(obj.target)
+ obj = bld(features='subst')
+ obj.source = 'dcpomatic_server.desktop.in'
+ obj.target = 'dcpomatic2_server.desktop'
+ obj.INSTALL_PREFIX = bld.env.INSTALL_PREFIX
+ obj.VERSION = bld.env.VERSION
+ desktops.append(obj.target)
+
+ obj = bld(features='subst')
+ obj.source = 'dcpomatic_kdm.desktop.in'
+ obj.target = 'dcpomatic2_kdm.desktop'
+ obj.INSTALL_PREFIX = bld.env.INSTALL_PREFIX
+ obj.VERSION = bld.env.VERSION
+ desktops.append(obj.target)
+
+ if bld.env.ENABLE_DISK:
obj = bld(features='subst')
- obj.source = 'dcpomatic_kdm.desktop.in'
- obj.target = 'dcpomatic2_kdm.desktop'
+ obj.source = 'dcpomatic_disk.desktop.in'
+ obj.target = 'dcpomatic2_disk.desktop'
obj.INSTALL_PREFIX = bld.env.INSTALL_PREFIX
obj.VERSION = bld.env.VERSION
desktops.append(obj.target)
- if bld.env.ENABLE_DISK:
- obj = bld(features='subst')
- obj.source = 'dcpomatic_disk.desktop.in'
- obj.target = 'dcpomatic2_disk.desktop'
- obj.INSTALL_PREFIX = bld.env.INSTALL_PREFIX
- obj.VERSION = bld.env.VERSION
- desktops.append(obj.target)
-
obj = bld(features='subst')
obj.source = 'dcpomatic_player.desktop.in'
obj.target = 'dcpomatic2_player.desktop'
from __future__ import print_function
import os
-def write_installer(bits, dcpomatic_version, debug, variant, disk):
+def write_installer(bits, dcpomatic_version, debug, disk):
tools = [
('batch', 'Batch Converter'),
def build(bld):
- write_installer(32, bld.env.VERSION, bld.env.DEBUG, bld.env.VARIANT, bld.env.ENABLE_DISK)
- write_installer(64, bld.env.VERSION, bld.env.DEBUG, bld.env.VARIANT, bld.env.ENABLE_DISK)
+ write_installer(32, bld.env.VERSION, bld.env.DEBUG, bld.env.ENABLE_DISK)
+ write_installer(64, bld.env.VERSION, bld.env.DEBUG, bld.env.ENABLE_DISK)
+++ /dev/null
-/*
- Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- DCP-o-matic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- 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/>.
-
-*/
-
-#ifdef DCPOMATIC_VARIANT_SWAROOP
-
-#include "checker.h"
-#include "config.h"
-#include "cross.h"
-
-using boost::bind;
-using boost::ref;
-
-Checker::Checker (int period)
- : _terminate (false)
- , _ok (true)
- , _period (period)
-{
-
-}
-
-void
-Checker::run ()
-{
- _thread = boost::thread (boost::bind(&Checker::thread, this));
-}
-
-Checker::~Checker ()
-{
- boost::this_thread::disable_interruption dis;
-
- {
- boost::mutex::scoped_lock lm (_mutex);
- _terminate = true;
- }
-
- _thread.interrupt ();
- try {
- _thread.join ();
- } catch (...) {}
-}
-
-void
-Checker::thread ()
-{
- while (true) {
- boost::mutex::scoped_lock lm (_mutex);
- if (_terminate) {
- break;
- }
-
- bool const was_ok = _ok;
- _ok = check();
- if (was_ok != _ok) {
- emit (bind(boost::ref(StateChanged)));
- }
-
- lm.unlock ();
- dcpomatic_sleep_seconds (_period);
- }
-}
-
-bool
-Checker::ok () const
-{
- boost::mutex::scoped_lock lm (_mutex);
- return _ok;
-}
-
-#endif
+++ /dev/null
-/*
- Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- DCP-o-matic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- 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/lib/checker.h
- * @brief Checker class.
- */
-
-#ifndef DCPOMATIC_CHECKER_H
-#define DCPOMATIC_CHECKER_H
-
-#include "signaller.h"
-#include <boost/signals2.hpp>
-
-/** Parent for classes which check some condition every so often and signal
- * when the state of the condition changes.
- */
-class Checker : public Signaller, public boost::noncopyable
-{
-public:
- virtual ~Checker ();
-
- void run ();
-
- bool ok () const;
-
- /** Emitted when the state of our condition changes */
- boost::signals2::signal<void (void)> StateChanged;
-
-protected:
-
- Checker (int period);
-
- /** @return true if the condition is `ok', otherwise false */
- virtual bool check () const = 0;
-
-private:
-
- void thread ();
-
- boost::thread _thread;
- mutable boost::mutex _mutex;
- bool _terminate;
- bool _ok;
- /** check period in seconds */
- int _period;
-};
-
-#endif
_player_playlist_directory = boost::none;
_player_kdm_directory = boost::none;
_audio_mapping = boost::none;
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- _player_background_image = boost::none;
- _kdm_server_url = "http://localhost:8000/{CPL}";
- _player_watermark_theatre = "";
- _player_watermark_period = 1;
- _player_watermark_duration = 50;
- _player_lock_file = boost::none;
- _signer_chain_path = "signer";
- _decryption_chain_path = "decryption";
-#endif
_allowed_dcp_frame_rates.clear ();
_allowed_dcp_frame_rates.push_back (24);
Config::read ()
try
{
-#if defined(DCPOMATIC_VARIANT_SWAROOP) && defined(DCPOMATIC_LINUX)
- if (geteuid() == 0) {
- /* Take ownership of the config file if we're root */
- chown (config_file().string().c_str(), 0, 0);
- chmod (config_file().string().c_str(), 0644);
- }
-#endif
-
cxml::Document f ("Config");
f.read_file (config_file ());
}
cxml::NodePtr signer = f.optional_node_child ("Signer");
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- if (signer && signer->node_children().size() == 1) {
- /* The content of <Signer> is a path to a file; if it's relative it's in the same
- directory as .config. */
- _signer_chain_path = signer->content();
- if (_signer_chain_path.is_relative()) {
- _signer_chain = read_swaroop_chain (path(_signer_chain_path.string()));
- } else {
- _signer_chain = read_swaroop_chain (_signer_chain_path);
- }
- } else {
- /* <Signer> is not present or has children: ignore it and remake. */
- _signer_chain = create_certificate_chain ();
- }
-#else
if (signer) {
shared_ptr<dcp::CertificateChain> c (new dcp::CertificateChain ());
/* Read the signing certificates and private key in from the config file */
/* Make a new set of signing certificates and key */
_signer_chain = create_certificate_chain ();
}
-#endif
cxml::NodePtr decryption = f.optional_node_child ("Decryption");
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- if (decryption && decryption->node_children().size() == 1) {
- /* The content of <Decryption> is a path to a file; if it's relative, it's in the same
- directory as .config. */
- _decryption_chain_path = decryption->content();
- if (_decryption_chain_path.is_relative()) {
- _decryption_chain = read_swaroop_chain (path(_decryption_chain_path.string()));
- } else {
- _decryption_chain = read_swaroop_chain (_decryption_chain_path);
- }
- } else {
- /* <Decryption> is not present or has more children: ignore it and remake. */
- _decryption_chain = create_certificate_chain ();
- }
-#else
if (decryption) {
shared_ptr<dcp::CertificateChain> c (new dcp::CertificateChain ());
BOOST_FOREACH (cxml::NodePtr i, decryption->node_children ("Certificate")) {
} else {
_decryption_chain = create_certificate_chain ();
}
-#endif
/* These must be done before we call Bad as that might set one
of the nags.
_audio_mapping = AudioMapping (f.node_child("AudioMapping"), Film::current_state_version);
}
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- _player_background_image = f.optional_string_child("PlayerBackgroundImage");
- _kdm_server_url = f.optional_string_child("KDMServerURL").get_value_or("http://localhost:8000/{CPL}");
- _player_watermark_theatre = f.optional_string_child("PlayerWatermarkTheatre").get_value_or("");
- _player_watermark_period = f.optional_number_child<int>("PlayerWatermarkPeriod").get_value_or(1);
- _player_watermark_duration = f.optional_number_child<int>("PlayerWatermarkDuration").get_value_or(150);
- BOOST_FOREACH (cxml::ConstNodePtr i, f.node_children("RequiredMonitor")) {
- _required_monitors.push_back(Monitor(i));
- }
- _player_lock_file = f.optional_string_child("PlayerLockFile");
-#endif
-
if (boost::filesystem::exists (_cinemas_file)) {
cxml::Document f ("Cinemas");
f.read_file (_cinemas_file);
root->add_child("Win32Console")->add_child_text (_win32_console ? "1" : "0");
#endif
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- if (_signer_chain_path.is_relative()) {
- write_swaroop_chain (_signer_chain, path(_signer_chain_path.string()));
- } else {
- write_swaroop_chain (_signer_chain, _signer_chain_path);
- }
- root->add_child("Signer")->add_child_text(_signer_chain_path.string());
-#else
/* [XML] Signer Certificate chain and private key to use when signing DCPs and KDMs. Should contain <code><Certificate></code>
tags in order and a <code><PrivateKey></code> tag all containing PEM-encoded certificates or private keys as appropriate.
*/
signer->add_child("Certificate")->add_child_text (i.certificate (true));
}
signer->add_child("PrivateKey")->add_child_text (_signer_chain->key().get ());
-#endif
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- if (_decryption_chain_path.is_relative()) {
- write_swaroop_chain (_decryption_chain, path(_decryption_chain_path.string()));
- } else {
- write_swaroop_chain (_decryption_chain, _decryption_chain_path);
- }
- root->add_child("Decryption")->add_child_text(_decryption_chain_path.string());
-#else
/* [XML] Decryption Certificate chain and private key to use when decrypting KDMs */
xmlpp::Element* decryption = root->add_child ("Decryption");
DCPOMATIC_ASSERT (_decryption_chain);
decryption->add_child("Certificate")->add_child_text (i.certificate (true));
}
decryption->add_child("PrivateKey")->add_child_text (_decryption_chain->key().get ());
-#endif
/* [XML] History Filename of DCP to present in the <guilabel>File</guilabel> menu of the GUI; there can be more than one
of these tags.
if (_audio_mapping) {
_audio_mapping->as_xml (root->add_child("AudioMapping"));
}
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- if (_player_background_image) {
- root->add_child("PlayerBackgroundImage")->add_child_text(_player_background_image->string());
- }
- root->add_child("KDMServerURL")->add_child_text(_kdm_server_url);
- root->add_child("PlayerWatermarkTheatre")->add_child_text(_player_watermark_theatre);
- root->add_child("PlayerWatermarkPeriod")->add_child_text(raw_convert<string>(_player_watermark_period));
- root->add_child("PlayerWatermarkDuration")->add_child_text(raw_convert<string>(_player_watermark_duration));
- BOOST_FOREACH (Monitor i, _required_monitors) {
- i.as_xml(root->add_child("RequiredMonitor"));
- }
- if (_player_lock_file) {
- root->add_child("PlayerLockFile")->add_child_text(_player_lock_file->string());
- }
-#endif
try {
string const s = doc.write_to_string_formatted ();
HISTORY,
SHOW_EXPERIMENTAL_AUDIO_PROCESSORS,
AUDIO_MAPPING,
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- PLAYER_BACKGROUND_IMAGE,
-#endif
OTHER
};
AudioMapping audio_mapping (int output_channels);
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- boost::optional<boost::filesystem::path> player_background_image () const {
- return _player_background_image;
- }
-
- std::string kdm_server_url () const {
- return _kdm_server_url;
- }
-
- std::string player_watermark_theatre () const {
- return _player_watermark_theatre;
- }
-
- int player_watermark_period () const {
- return _player_watermark_period;
- }
-
- int player_watermark_duration () const {
- return _player_watermark_duration;
- }
-
- std::vector<Monitor> required_monitors () const {
- return _required_monitors;
- }
-
- boost::optional<boost::filesystem::path> player_lock_file () const {
- return _player_lock_file;
- }
-#endif
-
/* SET (mostly) */
void set_master_encoding_threads (int n) {
void set_audio_mapping (AudioMapping m);
void set_audio_mapping_to_default ();
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- void set_player_background_image (boost::filesystem::path p) {
- maybe_set (_player_background_image, p, PLAYER_BACKGROUND_IMAGE);
- }
-
- void unset_player_background_image () {
- if (!_player_background_image) {
- return;
- }
- _player_background_image = boost::none;
- changed (PLAYER_BACKGROUND_IMAGE);
- }
-
- void set_kdm_server_url (std::string s) {
- maybe_set (_kdm_server_url, s);
- }
-
- void set_player_watermark_theatre (std::string p) {
- maybe_set (_player_watermark_theatre, p);
- }
-
- void set_player_watermark_period (int minutes) {
- maybe_set (_player_watermark_period, minutes);
- }
-
- void set_player_watermark_duration (int milliseconds) {
- maybe_set (_player_watermark_duration, milliseconds);
- }
-
- void set_required_monitors (std::vector<Monitor> monitors) {
- maybe_set (_required_monitors, monitors);
- }
-
- void set_player_lock_file (boost::filesystem::path p) {
- maybe_set (_player_lock_file, p);
- }
-
- void unset_player_lock_file () {
- if (!_player_lock_file) {
- return;
- }
- _player_lock_file = boost::none;
- changed ();
- }
-#endif
-
void changed (Property p = OTHER);
boost::signals2::signal<void (Property)> Changed;
/** Emitted if read() failed on an existing Config file. There is nothing
std::string _notification_bcc;
std::string _notification_email;
boost::shared_ptr<const dcp::CertificateChain> _signer_chain;
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- boost::filesystem::path _signer_chain_path;
-#endif
/** Chain used to decrypt KDMs; the leaf of this chain is the target
* certificate for making KDMs given to DCP-o-matic.
*/
boost::shared_ptr<const dcp::CertificateChain> _decryption_chain;
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- boost::filesystem::path _decryption_chain_path;
-#endif
/** true to check for updates on startup */
bool _check_for_updates;
bool _check_for_test_updates;
boost::optional<boost::filesystem::path> _player_playlist_directory;
boost::optional<boost::filesystem::path> _player_kdm_directory;
boost::optional<AudioMapping> _audio_mapping;
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- boost::optional<boost::filesystem::path> _player_background_image;
- std::string _kdm_server_url;
- std::string _player_watermark_theatre;
- /** watermark period in minutes */
- int _player_watermark_period;
- /** watermark duration in milliseconds */
- int _player_watermark_duration;
- std::vector<Monitor> _required_monitors;
- /** a file which, if specified, must be present for the player to work */
- boost::optional<boost::filesystem::path> _player_lock_file;
-#endif
static int const _current_version;
+++ /dev/null
-/*
- Copyright (C) 2019 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- DCP-o-matic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- 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/>.
-
-*/
-
-#ifdef DCPOMATIC_VARIANT_SWAROOP
-
-#include "encrypted_ecinema_kdm.h"
-#include "decrypted_ecinema_kdm.h"
-#include "ecinema_kdm_data.h"
-#include "exceptions.h"
-#include "compose.hpp"
-#include <dcp/key.h>
-#include <dcp/util.h>
-#include <dcp/certificate.h>
-#include <openssl/rsa.h>
-#include <openssl/pem.h>
-#include <openssl/err.h>
-
-using std::string;
-using std::runtime_error;
-using dcp::Certificate;
-using boost::optional;
-
-DecryptedECinemaKDM::DecryptedECinemaKDM (string id, string name, dcp::Key content_key, optional<dcp::LocalTime> not_valid_before, optional<dcp::LocalTime> not_valid_after)
- : _id (id)
- , _name (name)
- , _content_key (content_key)
- , _not_valid_before (not_valid_before)
- , _not_valid_after (not_valid_after)
-{
-
-}
-
-DecryptedECinemaKDM::DecryptedECinemaKDM (EncryptedECinemaKDM kdm, string private_key)
- : _id (kdm.id())
- , _name (kdm.name())
-{
- /* Read the private key */
-
- BIO* bio = BIO_new_mem_buf (const_cast<char *> (private_key.c_str()), -1);
- if (!bio) {
- throw runtime_error ("could not create memory BIO");
- }
-
- RSA* rsa = PEM_read_bio_RSAPrivateKey (bio, 0, 0, 0);
- if (!rsa) {
- throw FileError ("could not read RSA private key file", private_key);
- }
-
- uint8_t value[RSA_size(rsa)];
- int const len = RSA_private_decrypt (kdm.data().size(), kdm.data().data().get(), value, rsa, RSA_PKCS1_OAEP_PADDING);
- if (len == -1) {
- throw KDMError (ERR_error_string(ERR_get_error(), 0), "");
- }
-
- if (len != ECINEMA_KDM_KEY_LENGTH && len != (ECINEMA_KDM_KEY_LENGTH + ECINEMA_KDM_NOT_VALID_BEFORE_LENGTH + ECINEMA_KDM_NOT_VALID_AFTER_LENGTH)) {
- throw KDMError (
- "Unexpected data block size in ECinema KDM.",
- String::compose("Size was %1; expected %2 or %3", ECINEMA_KDM_KEY_LENGTH, ECINEMA_KDM_KEY_LENGTH + ECINEMA_KDM_NOT_VALID_BEFORE_LENGTH + ECINEMA_KDM_NOT_VALID_AFTER_LENGTH)
- );
- }
-
- _content_key = dcp::Key (value + ECINEMA_KDM_KEY, ECINEMA_KDM_KEY_LENGTH);
- if (len > ECINEMA_KDM_KEY_LENGTH) {
- uint8_t* p = value + ECINEMA_KDM_NOT_VALID_BEFORE;
- string b;
- for (int i = 0; i < ECINEMA_KDM_NOT_VALID_BEFORE_LENGTH; ++i) {
- b += *p++;
- }
- _not_valid_before = dcp::LocalTime (b);
- string a;
- for (int i = 0; i < ECINEMA_KDM_NOT_VALID_AFTER_LENGTH; ++i) {
- a += *p++;
- }
- _not_valid_after = dcp::LocalTime (a);
- }
-}
-
-EncryptedECinemaKDM
-DecryptedECinemaKDM::encrypt (Certificate recipient)
-{
- return EncryptedECinemaKDM (_id, _name, _content_key, _not_valid_before, _not_valid_after, recipient);
-}
-
-#endif
+++ /dev/null
-/*
- Copyright (C) 2019 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- DCP-o-matic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- 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/>.
-
-*/
-
-#ifdef DCPOMATIC_VARIANT_SWAROOP
-
-#include "encrypted_ecinema_kdm.h"
-#include <dcp/key.h>
-#include <dcp/data.h>
-#include <dcp/certificate.h>
-
-class DecryptedECinemaKDM
-{
-public:
- DecryptedECinemaKDM (std::string id, std::string name, dcp::Key content_key, boost::optional<dcp::LocalTime> not_valid_before, boost::optional<dcp::LocalTime> not_valid_after);
- DecryptedECinemaKDM (EncryptedECinemaKDM kdm, std::string private_key);
-
- EncryptedECinemaKDM encrypt (dcp::Certificate recipient);
-
- std::string id () const {
- return _id;
- }
-
- std::string name () const {
- return _name;
- }
-
- dcp::Key key () const {
- return _content_key;
- }
-
- boost::optional<dcp::LocalTime> not_valid_before () const {
- return _not_valid_before;
- }
-
- boost::optional<dcp::LocalTime> not_valid_after () const {
- return _not_valid_after;
- }
-
-private:
- std::string _id;
- std::string _name;
- /** unenecrypted content key */
- dcp::Key _content_key;
- boost::optional<dcp::LocalTime> _not_valid_before;
- boost::optional<dcp::LocalTime> _not_valid_after;
-};
-
-#endif
name_values['e'] = end.date() + " " + end.time_of_day(true, false);
name_values['i'] = kdm.cpl_id();
- return KDMWithMetadataPtr(new DCPKDMWithMetadata(name_values, 0, recipient->emails, kdm));
+ return KDMWithMetadataPtr(new KDMWithMetadata(name_values, 0, recipient->emails, kdm));
}
{
if (node->name() == "DKDM") {
return shared_ptr<DKDM> (new DKDM (dcp::EncryptedKDM (node->content ())));
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- } else if (node->name() == "ECinemaDKDM") {
- return shared_ptr<ECinemaDKDM> (new ECinemaDKDM(EncryptedECinemaKDM(node->content())));
-#endif
} else if (node->name() == "DKDMGroup") {
shared_ptr<DKDMGroup> group (new DKDMGroup (node->string_attribute ("Name")));
BOOST_FOREACH (cxml::ConstNodePtr i, node->node_children()) {
node->add_child("DKDM")->add_child_text (_dkdm.as_xml ());
}
-#ifdef DCPOMATIC_VARIANT_SWAROOP
-string
-ECinemaDKDM::name () const
-{
- return String::compose ("%1 (%2)", _dkdm.name(), _dkdm.id());
-}
-
-void
-ECinemaDKDM::as_xml (xmlpp::Element* node) const
-{
- node->add_child("ECinemaDKDM")->add_child_text (_dkdm.as_xml());
-}
-#endif
-
void
DKDMGroup::as_xml (xmlpp::Element* node) const
{
*/
-#ifdef DCPOMATIC_VARIANT_SWAROOP
-#include "encrypted_ecinema_kdm.h"
-#endif
#include <dcp/encrypted_kdm.h>
#include <libcxml/cxml.h>
#include <boost/enable_shared_from_this.hpp>
dcp::EncryptedKDM _dkdm;
};
-#ifdef DCPOMATIC_VARIANT_SWAROOP
-class ECinemaDKDM : public DKDMBase
-{
-public:
- explicit ECinemaDKDM (EncryptedECinemaKDM k)
- : _dkdm (k)
- {}
-
- std::string name () const;
- void as_xml (xmlpp::Element *) const;
-
- EncryptedECinemaKDM dkdm () const {
- return _dkdm;
- }
-
-private:
- EncryptedECinemaKDM _dkdm;
-};
-#endif
-
class DKDMGroup : public DKDMBase
{
public:
+++ /dev/null
-/*
- Copyright (C) 2019 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- DCP-o-matic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- 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/>.
-
-*/
-
-#ifdef DCPOMATIC_VARIANT_SWAROOP
-
-#include "encrypted_ecinema_kdm.h"
-#include "ecinema_kdm_data.h"
-#include "exceptions.h"
-#include "cross.h"
-#include <dcp/key.h>
-#include <dcp/certificate.h>
-#include <dcp/util.h>
-#include <libcxml/cxml.h>
-#include <libxml++/libxml++.h>
-#include <openssl/rsa.h>
-#include <openssl/err.h>
-#include <iostream>
-
-using std::cout;
-using std::string;
-using boost::shared_ptr;
-using boost::optional;
-using dcp::Certificate;
-
-EncryptedECinemaKDM::EncryptedECinemaKDM (string id, string name, dcp::Key content_key, optional<dcp::LocalTime> not_valid_before, optional<dcp::LocalTime> not_valid_after, Certificate recipient)
- : _id (id)
- , _name (name)
-{
- RSA* rsa = recipient.public_key ();
- _data = dcp::Data (RSA_size(rsa));
-
- int input_size = ECINEMA_KDM_KEY_LENGTH;
- if (not_valid_before && not_valid_after) {
- input_size += ECINEMA_KDM_NOT_VALID_BEFORE_LENGTH + ECINEMA_KDM_NOT_VALID_AFTER_LENGTH;
- }
-
- dcp::Data input (input_size);
- memcpy (input.data().get(), content_key.value(), ECINEMA_KDM_KEY_LENGTH);
- if (not_valid_before && not_valid_after) {
- memcpy (input.data().get() + ECINEMA_KDM_NOT_VALID_BEFORE, not_valid_before->as_string().c_str(), ECINEMA_KDM_NOT_VALID_BEFORE_LENGTH);
- memcpy (input.data().get() + ECINEMA_KDM_NOT_VALID_AFTER, not_valid_after->as_string().c_str(), ECINEMA_KDM_NOT_VALID_AFTER_LENGTH);
- }
-
- int const N = RSA_public_encrypt (input_size, input.data().get(), _data.data().get(), rsa, RSA_PKCS1_OAEP_PADDING);
- if (N == -1) {
- throw KDMError ("Could not encrypt ECinema KDM", ERR_error_string(ERR_get_error(), 0));
- }
-
-}
-
-EncryptedECinemaKDM::EncryptedECinemaKDM (string xml)
-{
- cxml::Document doc ("ECinemaSecurityMessage");
- doc.read_string (xml);
- _id = doc.string_child ("Id");
- _name = doc.string_child ("Name");
- _data = dcp::Data (256);
- int const len = dcp::base64_decode (doc.string_child("Data"), _data.data().get(), _data.size());
- _data.set_size (len);
-}
-
-string
-EncryptedECinemaKDM::as_xml () const
-{
- string key;
-
- /* Lazy overallocation */
- char out[_data.size() * 2];
- Kumu::base64encode (_data.data().get(), _data.size(), out, _data.size() * 2);
- int const N = strlen (out);
- string lines;
- for (int i = 0; i < N; ++i) {
- if (i > 0 && (i % 64) == 0) {
- lines += "\n";
- }
- lines += out[i];
- }
-
- xmlpp::Document document;
- xmlpp::Element* root = document.create_root_node ("ECinemaSecurityMessage");
- root->add_child("Id")->add_child_text(_id);
- root->add_child("Name")->add_child_text(_name);
- root->add_child("Data")->add_child_text(lines);
- return document.write_to_string ("UTF-8");
-}
-
-void
-EncryptedECinemaKDM::as_xml (boost::filesystem::path path) const
-{
- FILE* f = fopen_boost (path, "w");
- string const x = as_xml ();
- fwrite (x.c_str(), 1, x.length(), f);
- fclose (f);
-}
-
-#endif
+++ /dev/null
-/*
- Copyright (C) 2019 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- DCP-o-matic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- 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/>.
-
-*/
-
-#ifdef DCPOMATIC_VARIANT_SWAROOP
-
-#ifndef DCPOMATIC_ENCRYPTED_ECINEMA_KDM_H
-#define DCPOMATIC_ENCRYPTED_ECINEMA_KDM_H
-
-#include <dcp/key.h>
-#include <dcp/data.h>
-#include <dcp/certificate.h>
-#include <dcp/local_time.h>
-#include <boost/optional.hpp>
-
-class DecryptedECinemaKDM;
-
-class EncryptedECinemaKDM
-{
-public:
- explicit EncryptedECinemaKDM (std::string xml);
-
- std::string as_xml () const;
- void as_xml (boost::filesystem::path out) const;
-
- std::string id () const {
- return _id;
- }
-
- std::string name () const {
- return _name;
- }
-
- dcp::Data data () const {
- return _data;
- }
-
-private:
- friend class DecryptedECinemaKDM;
-
- EncryptedECinemaKDM (std::string id, std::string name, dcp::Key key, boost::optional<dcp::LocalTime> not_valid_before, boost::optional<dcp::LocalTime> not_valid_after, dcp::Certificate recipient);
-
- std::string _id;
- std::string _name;
- /** encrypted data */
- dcp::Data _data;
-};
-
-#endif
-
-#endif
#include "dcpomatic_log.h"
#include "ffmpeg_subtitle_stream.h"
#include "ffmpeg_audio_stream.h"
-#include "decrypted_ecinema_kdm.h"
#include "digester.h"
#include "compose.hpp"
#include "config.h"
_format_context->pb = _avio_context;
AVDictionary* options = 0;
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- if (_ffmpeg_content->kdm()) {
- DecryptedECinemaKDM kdm (_ffmpeg_content->kdm().get(), Config::instance()->decryption_chain()->key().get());
- av_dict_set (&options, "decryption_key", kdm.key().hex().c_str(), 0);
- }
-#endif
-
int e = avformat_open_input (&_format_context, 0, 0, &options);
if (e < 0) {
throw OpenFileError (_ffmpeg_content->path(0).string(), e, OpenFileError::READ);
#include "exceptions.h"
#include "frame_rate_change.h"
#include "text_content.h"
-#include "decrypted_ecinema_kdm.h"
#include <dcp/raw_convert.h>
#include <libcxml/cxml.h>
extern "C" {
FFmpegContent::FFmpegContent (boost::filesystem::path p)
: Content (p)
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- , _encrypted (false)
-#endif
{
}
_color_trc = get_optional_enum<AVColorTransferCharacteristic>(node, "ColorTransferCharacteristic");
_colorspace = get_optional_enum<AVColorSpace>(node, "Colorspace");
_bits_per_pixel = node->optional_number_child<int> ("BitsPerPixel");
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- _encrypted = node->optional_bool_child("Encrypted").get_value_or(false);
-#endif
}
FFmpegContent::FFmpegContent (vector<shared_ptr<Content> > c)
_color_trc = ref->_color_trc;
_colorspace = ref->_colorspace;
_bits_per_pixel = ref->_bits_per_pixel;
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- _encrypted = ref->_encrypted;
-#endif
}
void
if (_bits_per_pixel) {
node->add_child("BitsPerPixel")->add_child_text (raw_convert<string> (*_bits_per_pixel));
}
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- if (_encrypted) {
- node->add_child("Encypted")->add_child_text ("1");
- }
-#endif
}
void
text.push_back (shared_ptr<TextContent> (new TextContent (this, TEXT_OPEN_SUBTITLE, TEXT_UNKNOWN)));
_subtitle_stream = _subtitle_streams.front ();
}
-
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- _encrypted = first_path.extension() == ".ecinema";
-#endif
}
if (examiner->has_video ()) {
set_video_frame_rate (24000.0 / 1001);
video->set_length (video->length() * 24.0 / 30);
}
-
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- _id = examiner->id ();
-#endif
}
string
_filters = fc->_filters;
}
-#ifdef DCPOMATIC_VARIANT_SWAROOP
-void
-FFmpegContent::add_kdm (EncryptedECinemaKDM kdm)
-{
- ChangeSignaller<Content> cc (this, FFmpegContentProperty::KDM);
- boost::mutex::scoped_lock lm (_mutex);
- _kdm = kdm;
-
-}
-
-bool
-FFmpegContent::kdm_timing_window_valid () const
-{
- if (!_kdm) {
- return true;
- }
-
- DCPOMATIC_ASSERT (Config::instance()->decryption_chain()->key());
-
- DecryptedECinemaKDM decrypted (*_kdm, *Config::instance()->decryption_chain()->key());
-
- dcp::LocalTime now;
- return (!decrypted.not_valid_before() || *decrypted.not_valid_before() < now) &&
- (!decrypted.not_valid_after() || now < *decrypted.not_valid_after());
-}
-
-#endif
#ifndef DCPOMATIC_FFMPEG_CONTENT_H
#define DCPOMATIC_FFMPEG_CONTENT_H
-#ifdef DCPOMATIC_VARIANT_SWAROOP
-#include "encrypted_ecinema_kdm.h"
-#endif
#include "content.h"
#include "audio_stream.h"
void signal_subtitle_stream_changed ();
-#ifdef DCPOMATIC_VARIANT_SWAROOP
-
- bool encrypted () const {
- boost::mutex::scoped_lock lm (_mutex);
- return _encrypted;
- }
-
- void add_kdm (EncryptedECinemaKDM kdm);
-
- boost::optional<EncryptedECinemaKDM> kdm () const {
- return _kdm;
- }
-
- boost::optional<std::string> id () const {
- return _id;
- }
-
- bool kdm_timing_window_valid () const;
-
-#endif
-
private:
void add_properties (boost::shared_ptr<const Film> film, std::list<UserProperty> &) const;
boost::optional<AVColorTransferCharacteristic> _color_trc;
boost::optional<AVColorSpace> _colorspace;
boost::optional<int> _bits_per_pixel;
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- bool _encrypted;
- boost::optional<EncryptedECinemaKDM> _kdm;
- boost::optional<std::string> _id;
-#endif
};
#endif
bool
FFmpegDecoder::pass ()
{
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- if (_ffmpeg_content->encrypted() && !_ffmpeg_content->kdm()) {
- return true;
- }
-#endif
-
int r = av_read_frame (_format_context, &_packet);
/* AVERROR_INVALIDDATA can apparently be returned sometimes even when av_read_frame
bool split_reels,
bool audio_stream_per_channel,
int x264_crf
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- , optional<dcp::Key> key
- , optional<string> id
-#endif
)
: Encoder (film, job)
, _history (200)
_film->three_d(),
filename,
extension
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- , key
- , id
-#endif
)
);
}
bool three_d,
boost::filesystem::path output,
string extension
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- , optional<dcp::Key> key
- , optional<string> id
-#endif
)
{
if (three_d) {
_encoders[EYES_LEFT] = shared_ptr<FFmpegFileEncoder>(
new FFmpegFileEncoder(
video_frame_size, video_frame_rate, audio_frame_rate, channels, format,
- audio_stream_per_channel, x264_crf, String::compose("%1_%2%3", output.string(), _("L"), extension)
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- , key, id
-#endif
- )
+ audio_stream_per_channel, x264_crf, String::compose("%1_%2%3", output.string(), _("L"), extension))
);
/// TRANSLATORS: R here is an abbreviation for "right", to indicate the right-eye part of a 3D export
_encoders[EYES_RIGHT] = shared_ptr<FFmpegFileEncoder>(
new FFmpegFileEncoder(
video_frame_size, video_frame_rate, audio_frame_rate, channels, format,
- audio_stream_per_channel, x264_crf, String::compose("%1_%2%3", output.string(), _("R"), extension)
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- , key, id
-#endif
- )
+ audio_stream_per_channel, x264_crf, String::compose("%1_%2%3", output.string(), _("R"), extension))
);
} else {
_encoders[EYES_BOTH] = shared_ptr<FFmpegFileEncoder>(
new FFmpegFileEncoder(
video_frame_size, video_frame_rate, audio_frame_rate, channels, format,
- audio_stream_per_channel, x264_crf, String::compose("%1%2", output.string(), extension)
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- , key, id
-#endif
- )
+ audio_stream_per_channel, x264_crf, String::compose("%1%2", output.string(), extension))
);
}
}
bool split_reels,
bool audio_stream_per_channel,
int x264_crf
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- , boost::optional<dcp::Key> key
- , boost::optional<std::string> id
-#endif
);
void go ();
bool three_d,
boost::filesystem::path output,
std::string extension
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- , boost::optional<dcp::Key> key
- , boost::optional<std::string> id
-#endif
);
boost::shared_ptr<FFmpegFileEncoder> get (Eyes eyes) const;
_pulldown = true;
LOG_GENERAL_NC("Suggest that this may be 2:3 pull-down (soft telecine)");
}
-
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- AVDictionaryEntry* e = av_dict_get (_format_context->metadata, SWAROOP_ID_TAG, 0, 0);
- if (e) {
- _id = e->value;
- }
-#endif
}
return _pulldown;
}
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- boost::optional<std::string> id () const {
- return _id;
- }
-#endif
-
private:
void video_packet (AVCodecContext *, std::string& temporal_reference);
void audio_packet (AVCodecContext *, boost::shared_ptr<FFmpegAudioStream>);
boost::optional<double> _rotation;
bool _pulldown;
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- boost::optional<std::string> _id;
-#endif
-
struct SubtitleStart
{
SubtitleStart (std::string id_, bool image_, dcpomatic::ContentTime time_)
bool audio_stream_per_channel,
int x264_crf,
boost::filesystem::path output
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- , optional<dcp::Key> key
- , optional<string> id
-#endif
)
: _audio_stream_per_channel (audio_stream_per_channel)
, _video_options (0)
DCPOMATIC_ASSERT (false);
}
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- int r = avformat_alloc_output_context2 (&_format_context, av_guess_format("mov", 0, 0), 0, 0);
-#else
int r = avformat_alloc_output_context2 (&_format_context, 0, 0, _output.string().c_str());
-#endif
if (!_format_context) {
throw runtime_error (String::compose("could not allocate FFmpeg format context (%1)", r));
}
AVDictionary* options = 0;
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- if (key) {
- av_dict_set (&options, "encryption_key", key->hex().c_str(), 0);
- /* XXX: is this OK? */
- av_dict_set (&options, "encryption_kid", "00000000000000000000000000000000", 0);
- av_dict_set (&options, "encryption_scheme", "cenc-aes-ctr", 0);
- }
-
- if (id) {
- if (av_dict_set(&_format_context->metadata, SWAROOP_ID_TAG, id->c_str(), 0) < 0) {
- throw runtime_error ("Could not write ID to output");
- }
- }
-#endif
-
if (avformat_write_header (_format_context, &options) < 0) {
throw runtime_error ("could not write header to FFmpeg output file");
}
bool audio_stream_per_channel,
int x264_crf,
boost::filesystem::path output
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- , boost::optional<dcp::Key> key
- , boost::optional<std::string> id
-#endif
);
~FFmpegFileEncoder ();
#ifndef DCPOMATIC_KDM_WITH_METADATA_H
#define DCPOMATIC_KDM_WITH_METADATA_H
-#ifdef DCPOMATIC_VARIANT_SWAROOP
-#include "encrypted_ecinema_kdm.h"
-#endif
#include <dcp/encrypted_kdm.h>
#include <dcp/name_format.h>
#include <boost/shared_ptr.hpp>
class KDMWithMetadata
{
public:
- KDMWithMetadata (dcp::NameFormat::Map const& name_values, void const* group, std::list<std::string> emails)
+ KDMWithMetadata (dcp::NameFormat::Map const& name_values, void const* group, std::list<std::string> emails, dcp::EncryptedKDM kdm)
: _name_values (name_values)
, _group (group)
, _emails (emails)
+ , _kdm (kdm)
{}
- virtual ~KDMWithMetadata () {}
+ std::string kdm_as_xml () const {
+ return _kdm.as_xml ();
+ }
- virtual std::string kdm_as_xml () const = 0;
- virtual void kdm_as_xml (boost::filesystem::path out) const = 0;
+ void kdm_as_xml (boost::filesystem::path out) const {
+ return _kdm.as_xml (out);
+ }
dcp::NameFormat::Map const& name_values () const {
return _name_values;
dcp::NameFormat::Map _name_values;
void const* _group;
std::list<std::string> _emails;
+ dcp::EncryptedKDM _kdm;
};
std::string cpl_name
);
-
-template <class T>
-class SpecialKDMWithMetadata : public KDMWithMetadata
-{
-public:
- SpecialKDMWithMetadata (dcp::NameFormat::Map const& name_values, void const* group, std::list<std::string> emails, T k)
- : KDMWithMetadata (name_values, group, emails)
- , kdm (k)
- {}
-
- std::string kdm_as_xml () const {
- return kdm.as_xml ();
- }
-
- void kdm_as_xml (boost::filesystem::path out) const {
- return kdm.as_xml (out);
- }
-
- T kdm;
-};
-
-typedef SpecialKDMWithMetadata<dcp::EncryptedKDM> DCPKDMWithMetadata;
-#ifdef DCPOMATIC_VARIANT_SWAROOP
-typedef SpecialKDMWithMetadata<EncryptedECinemaKDM> ECinemaKDMWithMetadata;
-#endif
-
#endif
+++ /dev/null
-/*
- Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- DCP-o-matic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- 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/>.
-
-*/
-
-#ifdef DCPOMATIC_VARIANT_SWAROOP
-
-#include "lock_file_checker.h"
-#include "config.h"
-#include "cross.h"
-
-using boost::bind;
-using boost::ref;
-
-LockFileChecker* LockFileChecker::_instance = 0;
-
-LockFileChecker::LockFileChecker ()
- : Checker (10)
-{
-
-}
-
-bool
-LockFileChecker::check () const
-{
- return !Config::instance()->player_lock_file() || boost::filesystem::is_regular_file(Config::instance()->player_lock_file().get());
-}
-
-LockFileChecker *
-LockFileChecker::instance ()
-{
- if (!_instance) {
- _instance = new LockFileChecker ();
- }
-
- return _instance;
-}
-
-#endif
+++ /dev/null
-/*
- Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- DCP-o-matic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- 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 "checker.h"
-#include <boost/signals2.hpp>
-
-class LockFileChecker : public Checker
-{
-public:
- LockFileChecker ();
-
- static LockFileChecker* instance ();
-
-protected:
- bool check () const;
-
-private:
- static LockFileChecker* _instance;
-};
+++ /dev/null
-/*
- Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- DCP-o-matic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- 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/>.
-
-*/
-
-#ifdef DCPOMATIC_VARIANT_SWAROOP
-
-#include "monitor_checker.h"
-#include "config.h"
-#include "cross.h"
-
-MonitorChecker* MonitorChecker::_instance = 0;
-
-MonitorChecker::MonitorChecker ()
- : Checker (60)
-{
-
-}
-
-bool
-MonitorChecker::check () const
-{
- return Config::instance()->required_monitors().empty() || get_monitors() == Config::instance()->required_monitors();
-}
-
-
-MonitorChecker *
-MonitorChecker::instance ()
-{
- if (!_instance) {
- _instance = new MonitorChecker ();
- }
-
- return _instance;
-}
-
-#endif
+++ /dev/null
-/*
- Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- DCP-o-matic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- 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 "checker.h"
-#include <boost/signals2.hpp>
-
-class MonitorChecker : public Checker
-{
-public:
- MonitorChecker ();
-
- static MonitorChecker* instance ();
-
-protected:
- bool check () const;
-
-private:
- static MonitorChecker* _instance;
-};
boost::optional<ColourConversion> _colour_conversion;
VideoRange _video_range;
boost::optional<PositionImage> _text;
- /** Content that we came from. This is so that reset_metadata() can work, and also
- * for variant:swaroop's non-skippable ads.
- */
+ /** Content that we came from. This is so that reset_metadata() can work. */
boost::weak_ptr<Content> _content;
/** Video frame that we came from. Again, this is for reset_metadata() */
boost::optional<Frame> _video_frame;
name_values['e'] = end.date() + " " + end.time_of_day(true, false);
name_values['i'] = kdm.cpl_id();
- return KDMWithMetadataPtr(new DCPKDMWithMetadata(name_values, cinema.get(), cinema ? cinema->emails : list<string>(), kdm));
+ return KDMWithMetadataPtr(new KDMWithMetadata(name_values, cinema.get(), cinema ? cinema->emails : list<string>(), kdm));
}
+++ /dev/null
-/*
- Copyright (C) 2018-2019 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- DCP-o-matic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- 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 "swaroop_spl.h"
-#include "content_store.h"
-#include <libcxml/cxml.h>
-#include <dcp/raw_convert.h>
-#include <libxml++/libxml++.h>
-#include <boost/foreach.hpp>
-#include <iostream>
-
-using std::cout;
-using std::string;
-using boost::shared_ptr;
-using dcp::raw_convert;
-
-void
-SPL::read (boost::filesystem::path path, ContentStore* store)
-{
- _path = path;
-
- _spl.clear ();
- _missing = false;
- cxml::Document doc ("SPL");
- doc.read_file (path);
- _id = doc.string_child("Id");
- BOOST_FOREACH (cxml::ConstNodePtr i, doc.node_children("Entry")) {
- shared_ptr<Content> c = store->get(i->string_child("Digest"));
- if (c) {
- add (SPLEntry(c, i));
- } else {
- _missing = true;
- }
- }
-
- _allowed_shows = doc.optional_number_child<int>("AllowedShows");
-}
-
-void
-SPL::write (boost::filesystem::path path) const
-{
- _path = path;
-
- xmlpp::Document doc;
- xmlpp::Element* root = doc.create_root_node ("SPL");
- root->add_child("Id")->add_child_text (_id);
- BOOST_FOREACH (SPLEntry i, _spl) {
- i.as_xml (root->add_child("Entry"));
- }
- if (_allowed_shows) {
- root->add_child("AllowedShows")->add_child_text(raw_convert<string>(*_allowed_shows));
- }
- doc.write_to_file_formatted (path.string());
-}
+++ /dev/null
-/*
- Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- DCP-o-matic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- 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/>.
-
-*/
-
-#ifndef DCPOMATIC_SPL_H
-#define DCPOMATIC_SPL_H
-
-#include "swaroop_spl_entry.h"
-#include <dcp/util.h>
-
-class ContentStore;
-
-class SPL
-{
-public:
- SPL ()
- : _id (dcp::make_uuid())
- , _missing (false)
- {}
-
- void add (SPLEntry e) {
- _spl.push_back (e);
- }
-
- void remove (std::size_t index) {
- _spl.erase (_spl.begin() + index);
- }
-
- std::vector<SPLEntry> const & get () const {
- return _spl;
- }
-
- SPLEntry & operator[] (std::size_t index) {
- return _spl[index];
- }
-
- SPLEntry const & operator[] (std::size_t index) const {
- return _spl[index];
- }
-
- void read (boost::filesystem::path path, ContentStore* store);
- void write (boost::filesystem::path path) const;
-
- std::string id () const {
- return _id;
- }
-
- boost::optional<boost::filesystem::path> path () const {
- return _path;
- }
-
- std::string name () const {
- if (!_path) {
- return "";
- }
- return _path->filename().string();
- }
-
- bool missing () const {
- return _missing;
- }
-
- boost::optional<int> allowed_shows () const {
- return _allowed_shows;
- }
-
- bool have_allowed_shows () const {
- return !_allowed_shows || *_allowed_shows > 0;
- }
-
- void set_allowed_shows (int s) {
- _allowed_shows = s;
- }
-
- void unset_allowed_shows () {
- _allowed_shows = boost::optional<int>();
- }
-
- void decrement_allowed_shows () {
- if (_allowed_shows) {
- (*_allowed_shows)--;
- }
-
- }
-
-private:
- std::string _id;
- mutable boost::optional<boost::filesystem::path> _path;
- std::vector<SPLEntry> _spl;
- /** true if any content was missing when read() was last called on this SPL */
- bool _missing;
- /** number of times left that the player will allow this playlist to be played (unset means infinite shows) */
- boost::optional<int> _allowed_shows;
-};
-
-#endif
+++ /dev/null
-/*
- Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- DCP-o-matic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- 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 "swaroop_spl_entry.h"
-#include "dcp_content.h"
-#include "dcpomatic_assert.h"
-#include <libxml++/libxml++.h>
-
-using boost::shared_ptr;
-using boost::dynamic_pointer_cast;
-
-SPLEntry::SPLEntry (shared_ptr<Content> content)
- : skippable (false)
- , disable_timeline (false)
- , stop_after_play (false)
-{
- construct (content);
-}
-
-SPLEntry::SPLEntry (shared_ptr<Content> content, cxml::ConstNodePtr node)
- : skippable (node->bool_child("Skippable"))
- , disable_timeline (node->bool_child("DisableTimeline"))
- , stop_after_play (node->bool_child("StopAfterPlay"))
-{
- construct (content);
-}
-
-void
-SPLEntry::construct (shared_ptr<Content> c)
-{
- content = c;
- shared_ptr<DCPContent> dcp = dynamic_pointer_cast<DCPContent> (content);
- digest = content->digest ();
- if (dcp) {
- name = dcp->name ();
- DCPOMATIC_ASSERT (dcp->cpl());
- id = *dcp->cpl();
- kind = dcp->content_kind().get_value_or(dcp::FEATURE);
- type = DCP;
- encrypted = dcp->encrypted ();
- } else {
- name = content->path(0).filename().string();
- type = ECINEMA;
- kind = dcp::FEATURE;
- }
-}
-
-void
-SPLEntry::as_xml (xmlpp::Element* e)
-{
- e->add_child("Digest")->add_child_text(digest);
- e->add_child("Skippable")->add_child_text(skippable ? "1" : "0");
- e->add_child("DisableTimeline")->add_child_text(disable_timeline ? "1" : "0");
- e->add_child("StopAfterPlay")->add_child_text(stop_after_play ? "1" : "0");
-}
+++ /dev/null
-/*
- Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- DCP-o-matic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- 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/>.
-
-*/
-
-#ifndef DCPOMATIC_SWAROOP_SPL_ENTRY_H
-#define DCPOMATIC_SWAROOP_SPL_ENTRY_H
-
-#include <libcxml/cxml.h>
-#include <dcp/types.h>
-#include <boost/shared_ptr.hpp>
-
-namespace xmlpp {
- class Element;
-}
-
-class Content;
-
-class SPLEntry
-{
-public:
- SPLEntry (boost::shared_ptr<Content> content);
- SPLEntry (boost::shared_ptr<Content> content, cxml::ConstNodePtr node);
-
- void as_xml (xmlpp::Element* e);
-
- boost::shared_ptr<Content> content;
- std::string name;
- /** Digest of this content */
- std::string digest;
- /** CPL ID or something else for MP4 (?) */
- std::string id;
- dcp::ContentKind kind;
- enum Type {
- DCP,
- ECINEMA
- };
- Type type;
- bool encrypted;
- bool skippable;
- bool disable_timeline;
- bool stop_after_play;
-
-private:
- void construct (boost::shared_ptr<Content> content);
-};
-
-#endif
free (buffer);
}
-#ifdef DCPOMATIC_VARIANT_SWAROOP
-
-/* Make up a key from the machine UUID */
-dcp::Data
-key_from_uuid ()
-{
- dcp::Data key (dcpomatic::crypto_key_length());
- memset (key.data().get(), 0, key.size());
- string const magic = command_and_read ("dcpomatic2_uuid");
- strncpy ((char *) key.data().get(), magic.c_str(), dcpomatic::crypto_key_length());
- return key;
-}
-
-/* swaroop chain file format:
- *
- * 0 [int16_t] IV length
- * 2 [int16_t] cert #1 length, or 0 for none
- * 4 [int16_t] cert #2 length, or 0 for none
- * 6 [int16_t] cert #3 length, or 0 for none
- * 8 [int16_t] cert #4 length, or 0 for none
- * 10 [int16_t] cert #5 length, or 0 for none
- * 12 [int16_t] cert #6 length, or 0 for none
- * 14 [int16_t] cert #7 length, or 0 for none
- * 16 [int16_t] cert #8 length, or 0 for none
- * 16 [int16_t] private key length
- * 20 IV
- * cert #1
- * cert #2
- * cert #3
- * cert #4
- * cert #5
- * cert #6
- * cert #7
- * cert #8
- * private key
- */
-
-struct __attribute__ ((packed)) Header_ {
- int16_t iv_length;
- int16_t cert_length[8];
- int16_t private_key_length;
-};
-
-typedef struct Header_ Header;
-
-shared_ptr<dcp::CertificateChain>
-read_swaroop_chain (boost::filesystem::path path)
-{
- dcp::Data data (path);
- Header* header = (Header *) data.data().get();
- uint8_t* p = data.data().get() + sizeof(Header);
-
- dcp::Data iv (p, header->iv_length);
- p += iv.size();
-
- shared_ptr<dcp::CertificateChain> cc (new dcp::CertificateChain());
- for (int i = 0; i < 8; ++i) {
- if (header->cert_length[i] == 0) {
- break;
- }
- dcp::Data c(p, header->cert_length[i]);
- p += c.size();
- cc->add (dcp::Certificate(dcpomatic::decrypt(c, key_from_uuid(), iv)));
- }
-
- dcp::Data k (p, header->private_key_length);
- cc->set_key (dcpomatic::decrypt(k, key_from_uuid(), iv));
- return cc;
-}
-
-void
-write_swaroop_chain (shared_ptr<const dcp::CertificateChain> chain, boost::filesystem::path output)
-{
- scoped_array<uint8_t> buffer (new uint8_t[65536]);
- Header* header = (Header *) buffer.get();
- memset (header, 0, sizeof(Header));
- uint8_t* p = buffer.get() + sizeof(Header);
-
- dcp::Data iv = dcpomatic::random_iv ();
- header->iv_length = iv.size ();
- memcpy (p, iv.data().get(), iv.size());
- p += iv.size();
-
- int N = 0;
- BOOST_FOREACH (dcp::Certificate i, chain->root_to_leaf()) {
- dcp::Data e = dcpomatic::encrypt (i.certificate(true), key_from_uuid(), iv);
- memcpy (p, e.data().get(), e.size());
- p += e.size();
- DCPOMATIC_ASSERT (N < 8);
- header->cert_length[N] = e.size ();
- ++N;
- }
-
- dcp::Data k = dcpomatic::encrypt (chain->key().get(), key_from_uuid(), iv);
- memcpy (p, k.data().get(), k.size());
- p += k.size();
- header->private_key_length = k.size ();
-
- FILE* f = fopen_boost (output, "wb");
- checked_fwrite (buffer.get(), p - buffer.get(), f, output);
- fclose (f);
-}
-
-#endif
-
double
db_to_linear (double db)
{
#define CLOSED_CAPTION_LINES 3
/** Maximum line length of closed caption viewers */
#define CLOSED_CAPTION_LENGTH 30
-/* We are mis-using genre here, as only some metadata tags are written/read.
- I tried the use_metadata_tags option but it didn't seem to make any difference.
-*/
-#define SWAROOP_ID_TAG "genre"
extern std::string program_name;
extern bool is_batch_converter;
extern void emit_subtitle_image (dcpomatic::ContentTimePeriod period, dcp::SubtitleImage sub, dcp::Size size, boost::shared_ptr<TextDecoder> decoder);
extern bool show_jobs_on_console (bool progress);
extern void copy_in_bits (boost::filesystem::path from, boost::filesystem::path to, boost::function<void (float)>);
-#ifdef DCPOMATIC_VARIANT_SWAROOP
-extern boost::shared_ptr<dcp::CertificateChain> read_swaroop_chain (boost::filesystem::path path);
-extern void write_swaroop_chain (boost::shared_ptr<const dcp::CertificateChain> chain, boost::filesystem::path output);
-#endif
extern dcp::Size scale_for_display (dcp::Size s, dcp::Size display_container, dcp::Size film_container);
extern dcp::DecryptedKDM decrypt_kdm_with_helpful_error (dcp::EncryptedKDM kdm);
extern boost::filesystem::path default_font_file ();
text_content.cc
text_decoder.cc
case_insensitive_sorter.cc
- checker.cc
check_content_change_job.cc
cinema.cc
cinema_sound_processor.cc
decoder.cc
decoder_factory.cc
decoder_part.cc
- decrypted_ecinema_kdm.cc
digester.cc
dkdm_recipient.cc
dkdm_wrapper.cc
encode_server.cc
encode_server_finder.cc
encoded_log_entry.cc
- encrypted_ecinema_kdm.cc
environment_info.cc
event_history.cc
examine_content_job.cc
json_server.cc
kdm_with_metadata.cc
kdm_recipient.cc
- lock_file_checker.cc
log.cc
log_entry.cc
mid_side_decoder.cc
- monitor_checker.cc
overlaps.cc
player.cc
player_text.cc
obj.source = sources + ' version.cc'
- if bld.env.VARIANT == 'swaroop-theater' or bld.env.VARIANT == 'swaroop-studio':
- obj.source += ' swaroop_spl.cc swaroop_spl_entry.cc'
-
if bld.env.ENABLE_DISK:
obj.source += ' copy_to_drive_job.cc nanomsg.cc'
obj.uselib += ' LWEXT4 NANOMSG'
shared_ptr<TranscodeJob> job (new TranscodeJob (_film));
job->set_encoder (
shared_ptr<FFmpegEncoder> (
- new FFmpegEncoder (_film, job, d->path(), d->format(), d->mixdown_to_stereo(), d->split_reels(), d->split_streams(), d->x264_crf()
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- , optional<dcp::Key>(), optional<string>()
-#endif
- )
+ new FFmpegEncoder (_film, job, d->path(), d->format(), d->mixdown_to_stereo(), d->split_reels(), d->split_streams(), d->x264_crf())
)
);
JobManager::instance()->add (job);
#include "lib/cinema.h"
#include "lib/dkdm_wrapper.h"
#include "lib/cross.h"
-#ifdef DCPOMATIC_VARIANT_SWAROOP
-#include "lib/decrypted_ecinema_kdm.h"
-#endif
#include <dcp/encrypted_kdm.h>
#include <dcp/decrypted_kdm.h>
#include <dcp/exceptions.h>
list<KDMWithMetadataPtr> kdms;
string title;
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- shared_ptr<ECinemaDKDM> ecinema_dkdm = boost::dynamic_pointer_cast<ECinemaDKDM> (dkdm_base);
- if (ecinema_dkdm) {
- DecryptedECinemaKDM decrypted (ecinema_dkdm->dkdm(), Config::instance()->decryption_chain()->key().get());
- title = decrypted.name ();
-
- BOOST_FOREACH (shared_ptr<Screen> i, _screens->screens()) {
-
- if (!i->recipient) {
- continue;
- }
-
- dcp::LocalTime begin(_timing->from(), i->cinema->utc_offset_hour(), i->cinema->utc_offset_minute());
- dcp::LocalTime end(_timing->until(), i->cinema->utc_offset_hour(), i->cinema->utc_offset_minute());
-
- DecryptedECinemaKDM kdm (
- decrypted.id(),
- decrypted.name(),
- decrypted.key(),
- begin,
- end
- );
-
- dcp::NameFormat::Map name_values;
- name_values['c'] = i->cinema->name;
- name_values['s'] = i->name;
- name_values['f'] = title;
- name_values['b'] = begin.date() + " " + begin.time_of_day(true, false);
- name_values['e'] = end.date() + " " + end.time_of_day(true, false);
- name_values['i'] = kdm.id();
-
- /* Encrypt */
- kdms.push_back (
- KDMWithMetadataPtr(
- new ECinemaKDMWithMetadata(name_values, i->cinema, kdm.encrypt(i->recipient.get()))
- )
- );
- }
- }
-#endif
-
shared_ptr<DKDM> dkdm = boost::dynamic_pointer_cast<DKDM> (dkdm_base);
if (dkdm) {
/* Encrypt */
kdms.push_back (
KDMWithMetadataPtr(
- new DCPKDMWithMetadata(name_values, i->cinema.get(), i->cinema->emails, encrypted)
+ new KDMWithMetadata(name_values, i->cinema.get(), i->cinema->emails, encrypted)
)
);
}
shared_ptr<const dcp::CertificateChain> chain = Config::instance()->decryption_chain();
DCPOMATIC_ASSERT (chain->key());
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- try {
- cxml::Document test_doc;
- string const xml_string = dcp::file_to_string (wx_to_std(d->GetPath()), MAX_KDM_SIZE);
- test_doc.read_string (xml_string);
- if (test_doc.root_name() == "ECinemaSecurityMessage") {
- EncryptedECinemaKDM ekdm(xml_string);
- /* Decrypt the DKDM to make sure that we can */
- DecryptedECinemaKDM dkdm(ekdm, chain->key().get());
-
- shared_ptr<DKDMBase> new_dkdm(new ECinemaDKDM(ekdm));
- shared_ptr<DKDMGroup> group = dynamic_pointer_cast<DKDMGroup> (selected_dkdm());
- if (!group) {
- group = Config::instance()->dkdms();
- }
- add_dkdm_model (new_dkdm, group);
- add_dkdm_view (new_dkdm);
- d->Destroy ();
- return;
- }
- } catch (KDMError& e) {
- error_dialog (
- this, "Could not read file as a KDM. Perhaps it is badly formatted, created with the wrong certificate, or not a KDM at all.",
- std_to_wx(e.what())
- );
- d->Destroy ();
- return;
- } catch (dcp::MiscError& e) {
- error_dialog (
- this,
- _("Could not read file as a KDM. It is much too large. Make sure you are loading a DKDM (XML) file."),
- std_to_wx(e.what())
- );
- d->Destroy ();
- return;
- }
-#endif
-
try {
dcp::EncryptedKDM ekdm(dcp::file_to_string (wx_to_std (d->GetPath ()), MAX_KDM_SIZE));
/* Decrypt the DKDM to make sure that we can */
name_values['e'] = end.date() + " " + end.time_of_day(true, false);
name_values['i'] = kdm.cpl_id();
- kdms.push_back (KDMWithMetadataPtr(new DCPKDMWithMetadata(name_values, i->cinema.get(), i->cinema->emails, kdm)));
+ kdms.push_back (KDMWithMetadataPtr(new KDMWithMetadata(name_values, i->cinema.get(), i->cinema->emails, kdm)));
}
write_files (kdms, zip, output, container_name_format, filename_format, verbose);
} catch (FileError& e) {
#include "wx/verify_dcp_dialog.h"
#include "wx/standard_controls.h"
#include "wx/playlist_controls.h"
-#ifdef DCPOMATIC_VARIANT_SWAROOP
-#include "wx/swaroop_controls.h"
-#endif
#include "wx/timer_display.h"
#include "wx/system_information_dialog.h"
#include "wx/player_stress_tester.h"
#include "lib/server.h"
#include "lib/dcpomatic_socket.h"
#include "lib/scoped_temporary.h"
-#include "lib/monitor_checker.h"
-#include "lib/lock_file_checker.h"
#include "lib/ffmpeg_content.h"
#include "lib/dcpomatic_log.h"
#include "lib/file_log.h"
_overall_panel = new wxPanel (this, wxID_ANY);
_viewer.reset (new FilmViewer (_overall_panel));
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- SwaroopControls* sc = new SwaroopControls (_overall_panel, _viewer);
- _controls = sc;
- sc->ResetFilm.connect (bind(&DOMFrame::reset_film_weak, this, _1));
-#else
if (Config::instance()->player_mode() == Config::PLAYER_MODE_DUAL) {
PlaylistControls* pc = new PlaylistControls (_overall_panel, _viewer);
_controls = pc;
} else {
_controls = new StandardControls (_overall_panel, _viewer, false);
}
-#endif
_viewer->set_dcp_decode_reduction (Config::instance()->decode_reduction ());
_viewer->PlaybackPermitted.connect (bind(&DOMFrame::playback_permitted, this));
_viewer->Started.connect (bind(&DOMFrame::playback_started, this, _1));
reset_film ();
UpdateChecker::instance()->StateChanged.connect (boost::bind (&DOMFrame::update_checker_state_changed, this));
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- MonitorChecker::instance()->StateChanged.connect(boost::bind(&DOMFrame::monitor_checker_state_changed, this));
- MonitorChecker::instance()->run ();
- LockFileChecker::instance()->StateChanged.connect(boost::bind(&DOMFrame::lock_checker_state_changed, this));
- LockFileChecker::instance()->run ();
-#endif
setup_screen ();
_stress.LoadDCP.connect (boost::bind(&DOMFrame::load_dcp, this, _1));
-
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- sc->check_restart ();
-#endif
- }
-
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- void monitor_checker_state_changed ()
- {
- if (!MonitorChecker::instance()->ok()) {
- _viewer->stop ();
- error_dialog (this, _("The required display devices are not connected correctly."));
- }
}
- void lock_checker_state_changed ()
- {
- if (!LockFileChecker::instance()->ok()) {
- _viewer->stop ();
- error_dialog (this, _("The lock file is not present."));
- }
- }
-#endif
-
void setup_main_sizer (Config::PlayerMode mode)
{
_main_sizer->Detach (_viewer->panel());
bool playback_permitted ()
{
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- if (!MonitorChecker::instance()->ok()) {
- error_dialog (this, _("The required display devices are not connected correctly."));
- return false;
- }
- if (!LockFileChecker::instance()->ok()) {
- error_dialog (this, _("The lock file is not present."));
- return false;
- }
-#endif
if (!_film || !Config::instance()->respect_kdm_validity_periods()) {
return true;
}
}
}
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- BOOST_FOREACH (shared_ptr<Content> i, _film->content()) {
- shared_ptr<FFmpegContent> c = dynamic_pointer_cast<FFmpegContent>(i);
- if (c && !c->kdm_timing_window_valid()) {
- ok = false;
- }
- }
-#endif
-
if (!ok) {
error_dialog (this, _("The KDM does not allow playback of this content at this time."));
}
void playback_stopped (DCPTime time)
{
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- try {
- boost::filesystem::remove (Config::path("position"));
- } catch (...) {
- /* Never mind */
- }
-#endif
-
_controls->log (wxString::Format("playback-stopped %s", time.timecode(_film->video_frame_rate()).c_str()));
}
if (!ok || !report_errors_from_last_job(this)) {
return;
}
-#ifndef DCPOMATIC_VARIANT_SWAROOP
Config::instance()->add_to_player_history (dir);
-#endif
} catch (dcp::ReadError& e) {
error_dialog (this, wxString::Format(_("Could not load a DCP from %s"), std_to_wx(dir.string())), std_to_wx(e.what()));
} catch (DCPError& e) {
optional<int> c = Config::instance()->decode_reduction();
_view_cpl = view->Append(ID_view_cpl, _("CPL"), _cpl_menu);
view->AppendSeparator();
-#ifndef DCPOMATIC_VARIANT_SWAROOP
_view_full_screen = view->AppendCheckItem(ID_view_full_screen, _("Full screen\tF11"));
_view_dual_screen = view->AppendCheckItem(ID_view_dual_screen, _("Dual screen\tShift+F11"));
-#endif
setup_menu ();
view->AppendSeparator();
view->Append(ID_view_closed_captions, _("Closed captions..."));
if (d->ShowModal() == wxID_OK) {
DCPOMATIC_ASSERT (_film);
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- shared_ptr<FFmpegContent> ffmpeg = boost::dynamic_pointer_cast<FFmpegContent>(_film->content().front());
- if (ffmpeg) {
- try {
- ffmpeg->add_kdm (EncryptedECinemaKDM(dcp::file_to_string(wx_to_std(d->GetPath()), MAX_KDM_SIZE)));
- } catch (exception& e) {
- error_dialog (this, wxString::Format(_("Could not load KDM.")), std_to_wx(e.what()));
- d->Destroy();
- return;
- }
- }
-#endif
shared_ptr<DCPContent> dcp = boost::dynamic_pointer_cast<DCPContent>(_film->content().front());
-#ifndef DCPOMATIC_VARIANT_SWAROOP
DCPOMATIC_ASSERT (dcp);
-#endif
try {
if (dcp) {
dcp->add_kdm (dcp::EncryptedKDM(dcp::file_to_string(wx_to_std(d->GetPath()), MAX_KDM_SIZE)));
+++ /dev/null
-/*
- Copyright (C) 2018-2019 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- DCP-o-matic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- 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 "lib/version.h"
-#include "lib/decrypted_ecinema_kdm.h"
-#include "lib/config.h"
-#include "lib/util.h"
-#include "lib/film.h"
-#include "lib/dcp_content.h"
-#include "lib/job_manager.h"
-#include "lib/cross.h"
-#include "lib/transcode_job.h"
-#include "lib/ffmpeg_encoder.h"
-#include "lib/signal_manager.h"
-#include "lib/video_content.h"
-#include "lib/ratio.h"
-#include <dcp/key.h>
-extern "C" {
-#include <libavformat/avformat.h>
-#include <libavutil/aes_ctr.h>
-}
-#include <boost/filesystem.hpp>
-#include <boost/optional.hpp>
-#include <openssl/rand.h>
-#include <getopt.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <string>
-#include <iostream>
-
-using std::string;
-using std::cerr;
-using std::cout;
-using std::ofstream;
-using boost::optional;
-using boost::shared_ptr;
-
-static void convert_dcp (
- boost::filesystem::path input,
- boost::filesystem::path output_file,
- boost::optional<boost::filesystem::path> kdm,
- int crf
- );
-static void convert_ffmpeg (boost::filesystem::path input, boost::filesystem::path output_file, string format);
-static void write_kdm (string id, boost::filesystem::path name, dcp::Key key);
-
-static void
-help (string n)
-{
- cerr << "Syntax: " << n << " [OPTION] <FILE>|<DIRECTORY>\n"
- << " -v, --version show DCP-o-matic version\n"
- << " -h, --help show this help\n"
- << " -o, --output output directory\n"
- << " -f, --format output format (mov or mp4; defaults to mov)\n"
- << " -k, --kdm DCP KDM filename (if required)\n"
- << " -c, --crf quality (CRF) when transcoding from DCP (0 is best, 51 is worst, defaults to 23)\n"
- << "\n"
- << "<FILE> is an unencrypted .mp4 file; <DIRECTORY> is a DCP directory.\n";
-}
-
-int
-main (int argc, char* argv[])
-{
- optional<boost::filesystem::path> output;
- optional<string> format;
- optional<boost::filesystem::path> kdm;
- int crf = 23;
-
- int option_index = 0;
- while (true) {
- static struct option long_options[] = {
- { "version", no_argument, 0, 'v' },
- { "help", no_argument, 0, 'h' },
- { "output", required_argument, 0, 'o' },
- { "format", required_argument, 0, 'f' },
- { "kdm", required_argument, 0, 'k' },
- { "crf", required_argument, 0, 'c' },
- };
-
- int c = getopt_long (argc, argv, "vho:f:k:c:", long_options, &option_index);
-
- if (c == -1) {
- break;
- }
-
- switch (c) {
- case 'v':
- cout << "dcpomatic version " << dcpomatic_version << " " << dcpomatic_git_commit << "\n";
- exit (EXIT_SUCCESS);
- case 'h':
- help (argv[0]);
- exit (EXIT_SUCCESS);
- case 'o':
- output = optarg;
- break;
- case 'f':
- format = optarg;
- break;
- case 'k':
- kdm = optarg;
- break;
- case 'c':
- crf = atoi(optarg);
- break;
- }
- }
-
- if (optind >= argc) {
- help (argv[0]);
- exit (EXIT_FAILURE);
- }
-
- if (!output) {
- cerr << "You must specify --output-media or -o\n";
- exit (EXIT_FAILURE);
- }
-
- if (!format) {
- format = "mov";
- }
-
- if (*format != "mov" && *format != "mp4") {
- cerr << "Invalid format specified: must be mov or mp4\n";
- exit (EXIT_FAILURE);
- }
-
- dcpomatic_setup_path_encoding ();
- dcpomatic_setup ();
- signal_manager = new SignalManager ();
-
- boost::filesystem::path input = argv[optind];
- boost::filesystem::path output_file;
- if (boost::filesystem::is_directory(input)) {
- output_file = *output / (input.parent_path().filename().string() + ".ecinema");
- } else {
- output_file = *output / (input.filename().string() + ".ecinema");
- }
-
- if (!boost::filesystem::is_directory(*output)) {
- boost::filesystem::create_directory (*output);
- }
-
- av_register_all ();
-
- if (boost::filesystem::is_directory(input)) {
- /* Assume input is a DCP */
- convert_dcp (input, output_file, kdm, crf);
- } else {
- convert_ffmpeg (input, output_file, *format);
- }
-}
-
-static void
-convert_ffmpeg (boost::filesystem::path input, boost::filesystem::path output_file, string format)
-{
- AVFormatContext* input_fc = avformat_alloc_context ();
- if (avformat_open_input(&input_fc, input.string().c_str(), 0, 0) < 0) {
- cerr << "Could not open input file\n";
- exit (EXIT_FAILURE);
- }
-
- if (avformat_find_stream_info (input_fc, 0) < 0) {
- cerr << "Could not read stream information\n";
- exit (EXIT_FAILURE);
- }
-
- AVFormatContext* output_fc;
- avformat_alloc_output_context2 (&output_fc, av_guess_format(format.c_str(), 0, 0), 0, 0);
-
- for (uint32_t i = 0; i < input_fc->nb_streams; ++i) {
- AVStream* is = input_fc->streams[i];
- AVStream* os = avformat_new_stream (output_fc, is->codec->codec);
- if (avcodec_parameters_copy (os->codecpar, is->codecpar) < 0) {
- cerr << "Could not set up output stream.\n";
- exit (EXIT_FAILURE);
- }
-
- os->avg_frame_rate = is->avg_frame_rate;
-
- switch (is->codec->codec_type) {
- case AVMEDIA_TYPE_VIDEO:
- os->time_base = is->time_base;
- os->r_frame_rate = is->r_frame_rate;
- os->sample_aspect_ratio = is->sample_aspect_ratio;
- os->codec->time_base = is->codec->time_base;
- os->codec->framerate = is->codec->framerate;
- os->codec->pix_fmt = is->codec->pix_fmt;
- break;
- case AVMEDIA_TYPE_AUDIO:
- os->codec->sample_fmt = is->codec->sample_fmt;
- os->codec->bits_per_raw_sample = is->codec->bits_per_raw_sample;
- os->codec->sample_rate = is->codec->sample_rate;
- os->codec->channel_layout = is->codec->channel_layout;
- os->codec->channels = is->codec->channels;
- if (is->codecpar->codec_id == AV_CODEC_ID_PCM_S24LE) {
- /* XXX: fix incoming 24-bit files labelled lpcm, which apparently isn't allowed */
- os->codecpar->codec_tag = MKTAG('i', 'n', '2', '4');
- }
- break;
- default:
- /* XXX */
- break;
- }
- }
-
- if (avio_open2 (&output_fc->pb, output_file.string().c_str(), AVIO_FLAG_WRITE, 0, 0) < 0) {
- cerr << "Could not open output file `" << output_file.string() << "'\n";
- exit (EXIT_FAILURE);
- }
-
- dcp::Key key (AES_CTR_KEY_SIZE);
- AVDictionary* options = 0;
- av_dict_set (&options, "encryption_key", key.hex().c_str(), 0);
- /* XXX: is this OK? */
- av_dict_set (&options, "encryption_kid", "00000000000000000000000000000000", 0);
- av_dict_set (&options, "encryption_scheme", "cenc-aes-ctr", 0);
-
- string id = dcp::make_uuid ();
- if (av_dict_set(&output_fc->metadata, SWAROOP_ID_TAG, id.c_str(), 0) < 0) {
- cerr << "Could not write ID to output.\n";
- exit (EXIT_FAILURE);
- }
-
- if (avformat_write_header (output_fc, &options) < 0) {
- cerr << "Could not write header to output.\n";
- exit (EXIT_FAILURE);
- }
-
- AVPacket packet;
- while (av_read_frame(input_fc, &packet) >= 0) {
- AVStream* is = input_fc->streams[packet.stream_index];
- AVStream* os = output_fc->streams[packet.stream_index];
- packet.pts = av_rescale_q_rnd(packet.pts, is->time_base, os->time_base, (AVRounding) (AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
- packet.dts = av_rescale_q_rnd(packet.dts, is->time_base, os->time_base, (AVRounding) (AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
- packet.duration = av_rescale_q(packet.duration, is->time_base, os->time_base);
- packet.pos = -1;
- if (av_interleaved_write_frame (output_fc, &packet) < 0) {
- cerr << "Could not write frame to output.\n";
- exit (EXIT_FAILURE);
- }
- }
-
- av_write_trailer (output_fc);
-
- avformat_free_context (input_fc);
- avformat_free_context (output_fc);
-
- write_kdm (id, output_file, key);
-}
-
-static void
-write_kdm (string id, boost::filesystem::path name, dcp::Key key)
-{
- DecryptedECinemaKDM decrypted_kdm (id, name.filename().string(), key, optional<dcp::LocalTime>(), optional<dcp::LocalTime>());
- EncryptedECinemaKDM encrypted_kdm = decrypted_kdm.encrypt (Config::instance()->decryption_chain()->leaf());
-
- ofstream f(string(name.string() + ".xml").c_str());
- f << encrypted_kdm.as_xml() << "\n";
-}
-
-static void
-convert_dcp (
- boost::filesystem::path input, boost::filesystem::path output_file, optional<boost::filesystem::path> kdm, int crf
- )
-{
- shared_ptr<Film> film (new Film(boost::optional<boost::filesystem::path>()));
- shared_ptr<DCPContent> dcp (new DCPContent(input));
- film->examine_and_add_content (dcp);
- if (kdm) {
- dcp->add_kdm (dcp::EncryptedKDM(dcp::file_to_string(*kdm)));
- }
-
- JobManager* jm = JobManager::instance ();
- while (jm->work_to_do ()) {
- while (signal_manager->ui_idle ()) {}
- dcpomatic_sleep_seconds (1);
- }
- DCPOMATIC_ASSERT (!jm->errors());
-
- film->set_container (Ratio::nearest_from_ratio(dcp->video->size().ratio()));
-
- string id = dcp::make_uuid ();
- dcp::Key key (AES_CTR_KEY_SIZE);
-
- shared_ptr<TranscodeJob> job (new TranscodeJob(film));
- job->set_encoder (
- shared_ptr<FFmpegEncoder>(
- new FFmpegEncoder(film, job, output_file, EXPORT_FORMAT_H264_PCM, false, false, crf, key, id)
- )
- );
- jm->add (job);
- show_jobs_on_console (true);
-
- write_kdm (id, output_file, key);
-}
+++ /dev/null
-/*
- Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- DCP-o-matic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- 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 "../wx/wx_util.h"
-#include "../wx/wx_signal_manager.h"
-#include "../wx/content_view.h"
-#include "../wx/dcpomatic_button.h"
-#include "../lib/util.h"
-#include "../lib/config.h"
-#include "../lib/cross.h"
-#include "../lib/film.h"
-#include "../lib/dcp_content.h"
-#include "../lib/swaroop_spl_entry.h"
-#include "../lib/swaroop_spl.h"
-#include <wx/wx.h>
-#include <wx/listctrl.h>
-#include <wx/imaglist.h>
-#include <wx/spinctrl.h>
-#ifdef __WXOSX__
-#include <ApplicationServices/ApplicationServices.h>
-#endif
-
-using std::exception;
-using std::cout;
-using std::string;
-using boost::optional;
-using boost::shared_ptr;
-using boost::weak_ptr;
-using boost::bind;
-using boost::dynamic_pointer_cast;
-#if BOOST_VERSION >= 106100
-using namespace boost::placeholders;
-#endif
-
-
-class ContentDialog : public wxDialog, public ContentStore
-{
-public:
- ContentDialog (wxWindow* parent)
- : wxDialog (parent, wxID_ANY, _("Add content"), wxDefaultPosition, wxSize(800, 640))
- , _content_view (new ContentView(this))
- {
- _content_view->update ();
-
- wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL);
- SetSizer (overall_sizer);
-
- overall_sizer->Add (_content_view, 1, wxEXPAND | wxALL, DCPOMATIC_DIALOG_BORDER);
-
- wxSizer* buttons = CreateSeparatedButtonSizer (wxOK | wxCANCEL);
- if (buttons) {
- overall_sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder());
- }
-
- overall_sizer->Layout ();
- }
-
- shared_ptr<Content> selected () const
- {
- return _content_view->selected ();
- }
-
- shared_ptr<Content> get (string digest) const
- {
- return _content_view->get (digest);
- }
-
-private:
- ContentView* _content_view;
-};
-
-class DOMFrame : public wxFrame
-{
-public:
- explicit DOMFrame (wxString const & title)
- : wxFrame (0, -1, title)
- , _content_dialog (new ContentDialog(this))
- {
- /* Use a panel as the only child of the Frame so that we avoid
- the dark-grey background on Windows.
- */
- wxPanel* overall_panel = new wxPanel (this, wxID_ANY);
- wxBoxSizer* h_sizer = new wxBoxSizer (wxHORIZONTAL);
-
- _list = new wxListCtrl (
- overall_panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_SINGLE_SEL
- );
-
- _list->AppendColumn (_("Name"), wxLIST_FORMAT_LEFT, 400);
- _list->AppendColumn (_("CPL"), wxLIST_FORMAT_LEFT, 350);
- _list->AppendColumn (_("Type"), wxLIST_FORMAT_CENTRE, 100);
- _list->AppendColumn (_("Format"), wxLIST_FORMAT_CENTRE, 75);
- _list->AppendColumn (_("Encrypted"), wxLIST_FORMAT_CENTRE, 90);
- _list->AppendColumn (_("Skippable"), wxLIST_FORMAT_CENTRE, 90);
- _list->AppendColumn (_("Disable timeline"), wxLIST_FORMAT_CENTRE, 125);
- _list->AppendColumn (_("Stop after play"), wxLIST_FORMAT_CENTRE, 125);
-
- wxImageList* images = new wxImageList (16, 16);
- wxIcon tick_icon;
- wxIcon no_tick_icon;
-#ifdef DCPOMATIX_OSX
- tick_icon.LoadFile ("tick.png", wxBITMAP_TYPE_PNG_RESOURCE);
- no_tick_icon.LoadFile ("no_tick.png", wxBITMAP_TYPE_PNG_RESOURCE);
-#else
- boost::filesystem::path tick_path = resources_path() / "tick.png";
- tick_icon.LoadFile (std_to_wx(tick_path.string()));
- boost::filesystem::path no_tick_path = resources_path() / "no_tick.png";
- no_tick_icon.LoadFile (std_to_wx(no_tick_path.string()));
-#endif
- images->Add (tick_icon);
- images->Add (no_tick_icon);
-
- _list->SetImageList (images, wxIMAGE_LIST_SMALL);
-
- h_sizer->Add (_list, 1, wxEXPAND | wxALL, DCPOMATIC_SIZER_GAP);
-
- wxBoxSizer* button_sizer = new wxBoxSizer (wxVERTICAL);
- _up = new Button (overall_panel, _("Up"));
- _down = new Button (overall_panel, _("Down"));
- _add = new Button (overall_panel, _("Add"));
- _remove = new Button (overall_panel, _("Remove"));
- _save = new Button (overall_panel, _("Save playlist"));
- _load = new Button (overall_panel, _("Load playlist"));
- button_sizer->Add (_up, 0, wxEXPAND | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
- button_sizer->Add (_down, 0, wxEXPAND | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
- button_sizer->Add (_add, 0, wxEXPAND | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
- button_sizer->Add (_remove, 0, wxEXPAND | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
- button_sizer->Add (_save, 0, wxEXPAND | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
- button_sizer->Add (_load, 0, wxEXPAND | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
-
- h_sizer->Add (button_sizer, 0, wxALL, DCPOMATIC_SIZER_GAP);
-
- wxBoxSizer* v_sizer = new wxBoxSizer (wxVERTICAL);
-
- wxBoxSizer* allowed_shows_sizer = new wxBoxSizer (wxHORIZONTAL);
- _allowed_shows_enable = new wxCheckBox (overall_panel, wxID_ANY, _("Limit number of shows with this playlist to"));
- allowed_shows_sizer->Add (_allowed_shows_enable, 0, wxRIGHT, DCPOMATIC_SIZER_GAP);
- _allowed_shows = new wxSpinCtrl (overall_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 1, 65536, 100);
- allowed_shows_sizer->Add (_allowed_shows);
-
- v_sizer->Add (allowed_shows_sizer, 0, wxALL, DCPOMATIC_SIZER_GAP);
- v_sizer->Add (h_sizer);
-
- overall_panel->SetSizer (v_sizer);
-
- _list->Bind (wxEVT_LEFT_DOWN, bind(&DOMFrame::list_left_click, this, _1));
- _list->Bind (wxEVT_COMMAND_LIST_ITEM_SELECTED, boost::bind (&DOMFrame::selection_changed, this));
- _list->Bind (wxEVT_COMMAND_LIST_ITEM_DESELECTED, boost::bind (&DOMFrame::selection_changed, this));
- _up->Bind (wxEVT_BUTTON, bind(&DOMFrame::up_clicked, this));
- _down->Bind (wxEVT_BUTTON, bind(&DOMFrame::down_clicked, this));
- _add->Bind (wxEVT_BUTTON, bind(&DOMFrame::add_clicked, this));
- _remove->Bind (wxEVT_BUTTON, bind(&DOMFrame::remove_clicked, this));
- _save->Bind (wxEVT_BUTTON, bind(&DOMFrame::save_clicked, this));
- _load->Bind (wxEVT_BUTTON, bind(&DOMFrame::load_clicked, this));
- _allowed_shows_enable->Bind (wxEVT_CHECKBOX, bind(&DOMFrame::allowed_shows_changed, this));
- _allowed_shows->Bind (wxEVT_SPINCTRL, bind(&DOMFrame::allowed_shows_changed, this));
-
- setup_sensitivity ();
- }
-
-private:
-
- void allowed_shows_changed ()
- {
- if (_allowed_shows_enable->GetValue()) {
- _playlist.set_allowed_shows (_allowed_shows->GetValue());
- } else {
- _playlist.unset_allowed_shows ();
- }
- setup_sensitivity ();
- }
-
- void add (SPLEntry e)
- {
- wxListItem item;
- item.SetId (_list->GetItemCount());
- long const N = _list->InsertItem (item);
- set_item (N, e);
- }
-
- void selection_changed ()
- {
- setup_sensitivity ();
- }
-
- void set_item (long N, SPLEntry e)
- {
- _list->SetItem (N, 0, std_to_wx(e.name));
- _list->SetItem (N, 1, std_to_wx(e.id));
- _list->SetItem (N, 2, std_to_wx(dcp::content_kind_to_string(e.kind)));
- _list->SetItem (N, 3, e.type == SPLEntry::DCP ? _("DCP") : _("E-cinema"));
- _list->SetItem (N, 4, e.encrypted ? S_("Question|Y") : S_("Question|N"));
- _list->SetItem (N, COLUMN_SKIPPABLE, wxEmptyString, e.skippable ? 0 : 1);
- _list->SetItem (N, COLUMN_DISABLE_TIMELINE, wxEmptyString, e.disable_timeline ? 0 : 1);
- _list->SetItem (N, COLUMN_STOP_AFTER_PLAY, wxEmptyString, e.stop_after_play ? 0 : 1);
- }
-
- void setup_sensitivity ()
- {
- int const num_selected = _list->GetSelectedItemCount ();
- long int selected = _list->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
- _up->Enable (selected > 0);
- _down->Enable (selected != -1 && selected < (_list->GetItemCount() - 1));
- _remove->Enable (num_selected > 0);
- _allowed_shows->Enable (_allowed_shows_enable->GetValue());
- }
-
- void list_left_click (wxMouseEvent& ev)
- {
- int flags;
- long item = _list->HitTest (ev.GetPosition(), flags, 0);
- int x = ev.GetPosition().x;
- optional<int> column;
- for (int i = 0; i < _list->GetColumnCount(); ++i) {
- x -= _list->GetColumnWidth (i);
- if (x < 0) {
- column = i;
- break;
- }
- }
-
- if (item != -1 && column) {
- switch (*column) {
- case COLUMN_SKIPPABLE:
- _playlist[item].skippable = !_playlist[item].skippable;
- break;
- case COLUMN_DISABLE_TIMELINE:
- _playlist[item].disable_timeline = !_playlist[item].disable_timeline;
- break;
- case COLUMN_STOP_AFTER_PLAY:
- _playlist[item].stop_after_play = !_playlist[item].stop_after_play;
- break;
- default:
- ev.Skip ();
- }
- set_item (item, _playlist[item]);
- } else {
- ev.Skip ();
- }
- }
-
- void add_clicked ()
- {
- int const r = _content_dialog->ShowModal ();
- if (r == wxID_OK) {
- shared_ptr<Content> content = _content_dialog->selected ();
- if (content) {
- SPLEntry e (content);
- add (e);
- _playlist.add (e);
- }
- }
- }
-
- void up_clicked ()
- {
- long int s = _list->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
- if (s < 1) {
- return;
- }
-
- SPLEntry tmp = _playlist[s];
- _playlist[s] = _playlist[s-1];
- _playlist[s-1] = tmp;
-
- set_item (s - 1, _playlist[s-1]);
- set_item (s, _playlist[s]);
- }
-
- void down_clicked ()
- {
- long int s = _list->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
- if (s > (_list->GetItemCount() - 1)) {
- return;
- }
-
- SPLEntry tmp = _playlist[s];
- _playlist[s] = _playlist[s+1];
- _playlist[s+1] = tmp;
-
- set_item (s + 1, _playlist[s+1]);
- set_item (s, _playlist[s]);
- }
-
- void remove_clicked ()
- {
- long int s = _list->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
- if (s == -1) {
- return;
- }
-
- _playlist.remove (s);
- _list->DeleteItem (s);
- }
-
- void save_clicked ()
- {
- Config* c = Config::instance ();
- wxString default_dir = c->player_playlist_directory() ? std_to_wx(c->player_playlist_directory()->string()) : wxString(wxEmptyString);
- wxFileDialog* d = new wxFileDialog (this, _("Select playlist file"), default_dir, wxEmptyString, wxT("XML files (*.xml)|*.xml"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
- if (d->ShowModal() == wxID_OK) {
- boost::filesystem::path file = wx_to_std (d->GetPath());
- file.replace_extension (".xml");
- _playlist.write (file);
- }
- }
-
- void load_clicked ()
- {
- Config* c = Config::instance ();
- wxString default_dir = c->player_playlist_directory() ? std_to_wx(c->player_playlist_directory()->string()) : wxString(wxEmptyString);
- wxFileDialog* d = new wxFileDialog (this, _("Select playlist file"), default_dir, wxEmptyString, wxT("XML files (*.xml)|*.xml"));
- if (d->ShowModal() == wxID_OK) {
- _list->DeleteAllItems ();
- _playlist.read (wx_to_std(d->GetPath()), _content_dialog);
- if (!_playlist.missing()) {
- _list->DeleteAllItems ();
- BOOST_FOREACH (SPLEntry i, _playlist.get()) {
- add (i);
- }
- } else {
- error_dialog (this, _("Some content in this playlist was not found."));
- }
- optional<int> allowed_shows = _playlist.allowed_shows ();
- _allowed_shows_enable->SetValue (static_cast<bool>(allowed_shows));
- if (allowed_shows) {
- _allowed_shows->SetValue (*allowed_shows);
- } else {
- _allowed_shows->SetValue (65536);
- }
- setup_sensitivity ();
- }
- }
-
- wxListCtrl* _list;
- wxButton* _up;
- wxButton* _down;
- wxButton* _add;
- wxButton* _remove;
- wxButton* _save;
- wxButton* _load;
- wxCheckBox* _allowed_shows_enable;
- wxSpinCtrl* _allowed_shows;
- SPL _playlist;
- ContentDialog* _content_dialog;
-
- enum {
- COLUMN_SKIPPABLE = 5,
- COLUMN_DISABLE_TIMELINE = 6,
- COLUMN_STOP_AFTER_PLAY = 7
- };
-};
-
-/** @class App
- * @brief The magic App class for wxWidgets.
- */
-class App : public wxApp
-{
-public:
- App ()
- : wxApp ()
- , _frame (0)
- {}
-
-private:
-
- bool OnInit ()
- try
- {
- SetAppName (_("DCP-o-matic KDM Creator"));
-
- if (!wxApp::OnInit()) {
- return false;
- }
-
-#ifdef DCPOMATIC_LINUX
- unsetenv ("UBUNTU_MENUPROXY");
-#endif
-
-#ifdef __WXOSX__
- ProcessSerialNumber serial;
- GetCurrentProcess (&serial);
- TransformProcessType (&serial, kProcessTransformToForegroundApplication);
-#endif
-
- dcpomatic_setup_path_encoding ();
-
- /* Enable i18n; this will create a Config object
- to look for a force-configured language. This Config
- object will be wrong, however, because dcpomatic_setup
- hasn't yet been called and there aren't any filters etc.
- set up yet.
- */
- dcpomatic_setup_i18n ();
-
- /* Set things up, including filters etc.
- which will now be internationalised correctly.
- */
- dcpomatic_setup ();
-
- /* Force the configuration to be re-loaded correctly next
- time it is needed.
- */
- Config::drop ();
-
- _frame = new DOMFrame (_("DCP-o-matic Playlist Editor"));
- SetTopWindow (_frame);
- _frame->Maximize ();
- _frame->Show ();
-
- signal_manager = new wxSignalManager (this);
- Bind (wxEVT_IDLE, boost::bind (&App::idle, this));
-
- return true;
- }
- catch (exception& e)
- {
- error_dialog (0, _("DCP-o-matic could not start"), std_to_wx(e.what()));
- return true;
- }
-
- /* An unhandled exception has occurred inside the main event loop */
- bool OnExceptionInMainLoop ()
- {
- try {
- throw;
- } catch (FileError& e) {
- error_dialog (
- 0,
- wxString::Format (
- _("An exception occurred: %s (%s)\n\n") + REPORT_PROBLEM,
- std_to_wx (e.what()),
- std_to_wx (e.file().string().c_str ())
- )
- );
- } catch (exception& e) {
- error_dialog (
- 0,
- wxString::Format (
- _("An exception occurred: %s.\n\n") + " " + REPORT_PROBLEM,
- std_to_wx (e.what ())
- )
- );
- } catch (...) {
- error_dialog (0, _("An unknown exception occurred.") + " " + REPORT_PROBLEM);
- }
-
- /* This will terminate the program */
- return false;
- }
-
- void OnUnhandledException ()
- {
- error_dialog (0, _("An unknown exception occurred.") + " " + REPORT_PROBLEM);
- }
-
- void idle ()
- {
- signal_manager->ui_idle ();
- }
-
- DOMFrame* _frame;
-};
-
-IMPLEMENT_APP (App)
+++ /dev/null
-/*
- Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- DCP-o-matic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- 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 <cstdio>
-
-int main ()
-{
-#ifdef DCPOMATIC_LINUX
- FILE* f = fopen ("/sys/class/dmi/id/product_uuid", "r");
- if (!f) {
- printf ("unknown");
- return 1;
- }
- char buffer[256];
- int const N = fread (buffer, 1, 255, f);
- buffer[N] = '\0';
- printf ("%s", buffer);
- fclose (f);
- return 0;
-#endif
- printf ("unknown");
- return 1;
-}
if bld.env.TARGET_LINUX:
uselib += 'DL '
- cli_tools = []
- if bld.env.VARIANT == 'swaroop-theater':
- cli_tools = ['swaroop_dcpomatic_uuid']
- elif bld.env.VARIANT == 'swaroop-studio':
- cli_tools = ['dcpomatic_cli', 'dcpomatic_server_cli', 'server_test', 'dcpomatic_kdm_cli', 'dcpomatic_create', 'swaroop_dcpomatic_ecinema', 'swaroop_dcpomatic_uuid']
- else:
- cli_tools = ['dcpomatic_cli', 'dcpomatic_server_cli', 'server_test', 'dcpomatic_kdm_cli', 'dcpomatic_create']
- if bld.env.ENABLE_DISK:
- cli_tools.append('dcpomatic_disk_writer')
+ cli_tools = ['dcpomatic_cli', 'dcpomatic_server_cli', 'server_test', 'dcpomatic_kdm_cli', 'dcpomatic_create']
+ if bld.env.ENABLE_DISK:
+ cli_tools.append('dcpomatic_disk_writer')
for t in cli_tools:
obj = bld(features='cxx cxxprogram')
obj.source += ' ../../platform/windows/%s.rc' % t
# Prevent a console window opening when we start dcpomatic2_disk_writer
obj.env.append_value('LINKFLAGS', '-Wl,-subsystem,windows')
- obj.target = t.replace('dcpomatic', 'dcpomatic2').replace('swaroop_', '')
+ obj.target = t.replace('dcpomatic', 'dcpomatic2')
if t == 'server_test':
obj.install_path = None
gui_tools = []
if not bld.env.DISABLE_GUI:
- if bld.env.VARIANT == 'swaroop-theater':
- gui_tools = ['dcpomatic_player', 'swaroop_dcpomatic_playlist']
- elif bld.env.VARIANT == 'swaroop-studio':
- gui_tools = ['dcpomatic', 'dcpomatic_batch', 'dcpomatic_server', 'dcpomatic_kdm', 'dcpomatic_player', 'swaroop_dcpomatic_playlist']
- else:
- gui_tools = ['dcpomatic', 'dcpomatic_batch', 'dcpomatic_server', 'dcpomatic_kdm', 'dcpomatic_player', 'dcpomatic_playlist', 'dcpomatic_combiner']
- if bld.env.ENABLE_DISK:
- gui_tools.append('dcpomatic_disk')
+ gui_tools = ['dcpomatic', 'dcpomatic_batch', 'dcpomatic_server', 'dcpomatic_kdm', 'dcpomatic_player', 'dcpomatic_playlist', 'dcpomatic_combiner']
+ if bld.env.ENABLE_DISK:
+ gui_tools.append('dcpomatic_disk')
for t in gui_tools:
obj = bld(features='cxx cxxprogram')
obj.source = '%s.cc' % t
if bld.env.TARGET_WINDOWS:
obj.source += ' ../../platform/windows/%s.rc' % t
- obj.target = t.replace('dcpomatic', 'dcpomatic2').replace('swaroop_', '')
+ obj.target = t.replace('dcpomatic', 'dcpomatic2')
i18n.po_to_mo(os.path.join('src', 'tools'), 'dcpomatic2', bld)
table->Add (_kdm_directory, wxGBPosition (r, 1));
++r;
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- add_label_to_sizer (table, _panel, _("Background image"), true, wxGBPosition (r, 0));
- _background_image = new FilePickerCtrl (_panel, _("Select image file"), "*.png;*.jpg;*.jpeg;*.tif;*.tiff", true, false);
- table->Add (_background_image, wxGBPosition (r, 1));
- ++r;
-#endif
-
_content_directory->Bind (wxEVT_DIRPICKER_CHANGED, bind(&LocationsPage::content_directory_changed, this));
_playlist_directory->Bind (wxEVT_DIRPICKER_CHANGED, bind(&LocationsPage::playlist_directory_changed, this));
_kdm_directory->Bind (wxEVT_DIRPICKER_CHANGED, bind(&LocationsPage::kdm_directory_changed, this));
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- _background_image->Bind (wxEVT_FILEPICKER_CHANGED, bind(&LocationsPage::background_image_changed, this));
-#endif
}
void
if (config->player_kdm_directory()) {
checked_set (_kdm_directory, *config->player_kdm_directory());
}
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- if (config->player_background_image()) {
- checked_set (_background_image, *config->player_background_image());
- }
-#endif
}
void
{
Config::instance()->set_player_kdm_directory(wx_to_std(_kdm_directory->GetPath()));
}
-
-#ifdef DCPOMATIC_VARIANT_SWAROOP
-void
-LocationsPage::background_image_changed ()
-{
- boost::filesystem::path const f = wx_to_std(_background_image->GetPath());
- if (!boost::filesystem::is_regular_file(f) || !wxImage::CanRead(std_to_wx(f.string()))) {
- error_dialog (0, _("Could not load image file."));
- if (Config::instance()->player_background_image()) {
- checked_set (_background_image, *Config::instance()->player_background_image());
- }
- return;
- }
-
- Config::instance()->set_player_background_image(f);
-}
-#endif
void playlist_directory_changed ();
void kdm_directory_changed ();
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- void background_image_changed ();
-#endif
-
wxDirPickerCtrl* _content_directory;
wxDirPickerCtrl* _playlist_directory;
wxDirPickerCtrl* _kdm_directory;
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- FilePickerCtrl* _background_image;
-#endif
};
#endif
, _closed_captions_dialog (new ClosedCaptionsDialog(p, this))
, _outline_content (false)
, _pad_black (false)
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- , _background_image (false)
-#endif
, _idle_get (false)
{
switch (Config::instance()->video_view_type()) {
void
FilmViewer::config_changed (Config::Property p)
{
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- if (p == Config::PLAYER_BACKGROUND_IMAGE) {
- _video_view->update ();
- return;
- }
-#endif
-
if (p == Config::AUDIO_MAPPING) {
recreate_butler ();
return;
int audio_callback (void* out, unsigned int frames);
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- void set_background_image (bool b) {
- _background_image = b;
- _video_view->update ();
- }
-
- bool background_image () const {
- return _background_image;
- }
-#endif
-
StateTimer const & state_timer () const {
return _video_view->state_timer ();
}
*/
bool _pad_black;
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- bool _background_image;
-#endif
-
/** true if an get() is required next time we are idle */
bool _idle_get;
table->Add (_debug_log_file, wxGBPosition(r, 1));
++r;
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- add_label_to_sizer (table, _panel, _("KDM server URL"), true, wxGBPosition(r, 0));
- _kdm_server_url = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(400, -1));
- table->Add (_kdm_server_url, wxGBPosition (r, 1));
- ++r;
-
- add_label_to_sizer (table, _panel, _("Lock file"), true, wxGBPosition(r, 0));
- _lock_file = new FilePickerCtrl (_panel, _("Select lock file"), "*", true, true);
- table->Add (_lock_file, wxGBPosition (r, 1));
- ++r;
-#endif
-
_player_mode->Bind (wxEVT_CHOICE, bind(&PlayerGeneralPage::player_mode_changed, this));
_image_display->Bind (wxEVT_CHOICE, bind(&PlayerGeneralPage::image_display_changed, this));
_video_display_mode->Bind (wxEVT_CHOICE, bind(&PlayerGeneralPage::video_display_mode_changed, this));
_respect_kdm->Bind (wxEVT_CHECKBOX, bind(&PlayerGeneralPage::respect_kdm_changed, this));
_activity_log_file->Bind (wxEVT_FILEPICKER_CHANGED, bind(&PlayerGeneralPage::activity_log_file_changed, this));
_debug_log_file->Bind (wxEVT_FILEPICKER_CHANGED, bind(&PlayerGeneralPage::debug_log_file_changed, this));
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- _kdm_server_url->Bind (wxEVT_TEXT, bind(&PlayerGeneralPage::kdm_server_url_changed, this));
- _lock_file->Bind (wxEVT_FILEPICKER_CHANGED, bind(&PlayerGeneralPage::lock_file_changed, this));
-#endif
}
void config_changed ()
if (config->player_debug_log_file()) {
checked_set (_debug_log_file, *config->player_debug_log_file());
}
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- checked_set (_kdm_server_url, config->kdm_server_url());
- if (config->player_lock_file()) {
- checked_set (_lock_file, config->player_lock_file().get());
- }
-#endif
}
private:
Config::instance()->set_player_debug_log_file(wx_to_std(_debug_log_file->GetPath()));
}
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- void kdm_server_url_changed ()
- {
- Config::instance()->set_kdm_server_url(wx_to_std(_kdm_server_url->GetValue()));
- }
-
- void lock_file_changed ()
- {
- Config::instance()->set_player_lock_file(wx_to_std(_lock_file->GetPath()));
- }
-#endif
-
wxChoice* _player_mode;
wxChoice* _image_display;
wxChoice* _video_display_mode;
wxCheckBox* _respect_kdm;
FilePickerCtrl* _activity_log_file;
FilePickerCtrl* _debug_log_file;
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- wxTextCtrl* _kdm_server_url;
- FilePickerCtrl* _lock_file;
-#endif
};
};
-#ifdef DCPOMATIC_VARIANT_SWAROOP
-class WatermarkPage : public StandardPage
-{
-public:
- WatermarkPage (wxSize panel_size, int border)
- : StandardPage (panel_size, border)
- {}
-
- wxString GetName () const
- {
- return _("Watermark");
- }
-
-#ifdef DCPOMATIC_OSX
- wxBitmap GetLargeIcon () const
- {
- /* XXX: this icon doesn't exist; this is just to make the swaroop variant build on OS X */
- return wxBitmap ("watermark", wxBITMAP_TYPE_PNG_RESOURCE);
- }
-#endif
-
-private:
- void setup ()
- {
- wxGridBagSizer* table = new wxGridBagSizer (DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
- _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
-
- int r = 0;
-
- add_label_to_sizer (table, _panel, _("Theatre name"), true, wxGBPosition(r, 0));
- _theatre = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(300, -1));
- table->Add (_theatre, wxGBPosition(r, 1), wxGBSpan(1, 2));
- ++r;
-
- add_label_to_sizer (table, _panel, _("Period"), true, wxGBPosition(r, 0));
- _period = new wxSpinCtrl (_panel, wxID_ANY);
- _period->SetRange (1, 60);
- table->Add (_period, wxGBPosition(r, 1));
- add_label_to_sizer (table, _panel, _("minutes"), false, wxGBPosition(r, 2));
- ++r;
-
- add_label_to_sizer (table, _panel, _("Duration"), true, wxGBPosition(r, 0));
- _duration = new wxSpinCtrl (_panel, wxID_ANY);
- _duration->SetRange (100, 5000);
- table->Add (_duration, wxGBPosition(r, 1));
- add_label_to_sizer (table, _panel, _("milliseconds"), false, wxGBPosition(r, 2));
- ++r;
-
- _theatre->Bind (wxEVT_TEXT, bind(&WatermarkPage::theatre_changed, this));
- _duration->Bind (wxEVT_SPINCTRL, bind(&WatermarkPage::duration_changed, this));
- _period->Bind (wxEVT_SPINCTRL, bind(&WatermarkPage::period_changed, this));
- }
-
- void config_changed ()
- {
- Config* config = Config::instance ();
- checked_set (_theatre, config->player_watermark_theatre());
- checked_set (_duration, config->player_watermark_duration());
- checked_set (_period, config->player_watermark_period());
- }
-
- void theatre_changed ()
- {
- Config::instance()->set_player_watermark_theatre(wx_to_std(_theatre->GetValue()));
- }
-
- void period_changed ()
- {
- Config::instance()->set_player_watermark_period(_period->GetValue());
- }
-
- void duration_changed ()
- {
- Config::instance()->set_player_watermark_duration(_duration->GetValue());
- }
-
- wxTextCtrl* _theatre;
- wxSpinCtrl* _period;
- wxSpinCtrl* _duration;
-};
-
-class DevicesPage : public StandardPage
-{
-public:
- DevicesPage (wxSize panel_size, int border)
- : StandardPage (panel_size, border)
- {}
-
- wxString GetName () const
- {
- return _("Devices");
- }
-
-#ifdef DCPOMATIC_OSX
- wxBitmap GetLargeIcon () const
- {
- /* XXX: this icon doesn't exist; this is just to make the swaroop variant build on OS X */
- return wxBitmap ("devices", wxBITMAP_TYPE_PNG_RESOURCE);
- }
-#endif
-
-private:
- void setup ()
- {
- vector<EditableListColumn> columns;
- columns.push_back(EditableListColumn(_("Manufacturer ID")));
- columns.push_back(EditableListColumn(_("Product code")));
- columns.push_back(EditableListColumn(_("Serial")));
- columns.push_back(EditableListColumn(_("Manufacture week")));
- columns.push_back(EditableListColumn(_("Manufacture year")));
- _monitor_list = new EditableList<Monitor, MonitorDialog> (
- _panel,
- columns,
- boost::bind (&Config::required_monitors, Config::instance()),
- boost::bind (&Config::set_required_monitors, Config::instance(), _1),
- boost::bind (&DevicesPage::monitor_column, this, _1, _2),
- true,
- true
- );
- _panel->GetSizer()->Add(_monitor_list, 1, wxEXPAND | wxALL, _border);
-
- wxButton* get = new Button(_panel, _("Read current devices"));
- _panel->GetSizer()->Add(get, 0, wxEXPAND | wxALL, DCPOMATIC_SIZER_GAP);
- get->Bind(wxEVT_BUTTON, bind(&DevicesPage::get_clicked, this));
- }
-
- void get_clicked ()
- {
- Config::instance()->set_required_monitors(get_monitors());
- _monitor_list->refresh ();
- }
-
- string monitor_column (Monitor m, int c)
- {
- switch (c) {
- case 0:
- return m.manufacturer_id;
- case 1:
- return locale_convert<string>(m.manufacturer_product_code);
- case 2:
- return locale_convert<string>(m.serial_number);
- case 3:
- return locale_convert<string>(m.week_of_manufacture);
- case 4:
- return locale_convert<string>(m.year_of_manufacture);
- default:
- DCPOMATIC_ASSERT(false);
- }
-
- return "";
- }
-
- void config_changed ()
- {
- _monitor_list->refresh ();
- }
-
-private:
- EditableList<Monitor, MonitorDialog>* _monitor_list;
-};
-
-#endif
-
wxPreferencesEditor*
create_player_config_dialog ()
{
e->AddPage (new SoundPage(ps, border));
e->AddPage (new LocationsPage(ps, border));
e->AddPage (new KeysPage(ps, border));
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- e->AddPage (new WatermarkPage(ps, border));
- e->AddPage (new DevicesPage(ps, border));
-#endif
e->AddPage (new PlayerAdvancedPage(ps, border));
return e;
}
dcp::Size const out_size = _viewer->out_size ();
wxSize const panel_size = _panel->GetSize ();
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- if (_viewer->background_image()) {
- dc.Clear ();
- optional<boost::filesystem::path> bg = Config::instance()->player_background_image();
- if (bg) {
- wxImage image (std_to_wx(bg->string()));
- wxBitmap bitmap (image);
- dc.DrawBitmap (bitmap, max(0, (panel_size.GetWidth() - image.GetSize().GetWidth()) / 2), max(0, (panel_size.GetHeight() - image.GetSize().GetHeight()) / 2));
- }
- return;
- }
-#endif
-
if (!out_size.width || !out_size.height || !_image || out_size != _image->size()) {
dc.Clear ();
} else {
wxImage frame (out_size.width, out_size.height, _image->data()[0], true);
wxBitmap frame_bitmap (frame);
dc.DrawBitmap (frame_bitmap, 0, max(0, (panel_size.GetHeight() - out_size.height) / 2));
-
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- DCPTime const period = DCPTime::from_seconds(Config::instance()->player_watermark_period() * 60);
- int64_t n = position().get() / period.get();
- DCPTime from(n * period.get());
- DCPTime to = from + DCPTime::from_seconds(Config::instance()->player_watermark_duration() / 1000.0);
- if (from <= position() && position() <= to) {
- if (!_in_watermark) {
- _in_watermark = true;
- _watermark_x = rand() % panel_size.GetWidth();
- _watermark_y = rand() % panel_size.GetHeight();
- }
- dc.SetTextForeground(*wxWHITE);
- string wm = Config::instance()->player_watermark_theatre();
- boost::posix_time::ptime t = boost::posix_time::second_clock::local_time();
- wm += "\n" + boost::posix_time::to_iso_extended_string(t);
- dc.DrawText(std_to_wx(wm), _watermark_x, _watermark_y);
- } else {
- _in_watermark = false;
- }
-#endif
}
if (out_size.width < panel_size.GetWidth()) {
+++ /dev/null
-/*
- Copyright (C) 2018-2019 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- DCP-o-matic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- 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 "swaroop_controls.h"
-#include "film_viewer.h"
-#include "wx_util.h"
-#include "content_view.h"
-#include "dcpomatic_button.h"
-#include "static_text.h"
-#include "lib/player_video.h"
-#include "lib/dcp_content.h"
-#include "lib/cross.h"
-#include "lib/scoped_temporary.h"
-#include "lib/internet.h"
-#include "lib/ffmpeg_content.h"
-#include "lib/compose.hpp"
-#include <dcp/raw_convert.h>
-#include <dcp/exceptions.h>
-#include <wx/listctrl.h>
-#include <wx/progdlg.h>
-
-using std::string;
-using std::cout;
-using std::exception;
-using std::sort;
-using boost::shared_ptr;
-using boost::dynamic_pointer_cast;
-using boost::optional;
-using namespace dcpomatic;
-
-SwaroopControls::SwaroopControls (wxWindow* parent, shared_ptr<FilmViewer> viewer)
- : Controls (parent, viewer, false)
- , _play_button (new Button(this, _("Play")))
- , _pause_button (new Button(this, _("Pause")))
- , _stop_button (new Button(this, _("Stop")))
- , _next_button (new Button(this, "Next"))
- , _previous_button (new Button(this, "Previous"))
- , _current_disable_timeline (false)
- , _current_disable_next (false)
- , _timer (this)
-{
- _button_sizer->Add (_previous_button, 0, wxEXPAND);
- _button_sizer->Add (_play_button, 0, wxEXPAND);
- _button_sizer->Add (_pause_button, 0, wxEXPAND);
- _button_sizer->Add (_stop_button, 0, wxEXPAND);
- _button_sizer->Add (_next_button, 0, wxEXPAND);
-
- _spl_view = new wxListCtrl (this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_NO_HEADER);
- _spl_view->AppendColumn (wxT(""), wxLIST_FORMAT_LEFT, 740);
-
- wxBoxSizer* left_sizer = new wxBoxSizer (wxVERTICAL);
- wxBoxSizer* e_sizer = new wxBoxSizer (wxHORIZONTAL);
-
- wxFont subheading_font (*wxNORMAL_FONT);
- subheading_font.SetWeight (wxFONTWEIGHT_BOLD);
-
- wxBoxSizer* spl_header = new wxBoxSizer (wxHORIZONTAL);
- {
- wxStaticText* m = new StaticText (this, "Playlists");
- m->SetFont (subheading_font);
- spl_header->Add (m, 1, wxALIGN_CENTER_VERTICAL);
- }
- _refresh_spl_view = new Button (this, "Refresh");
- spl_header->Add (_refresh_spl_view, 0, wxBOTTOM, DCPOMATIC_SIZER_GAP / 2);
-
- left_sizer->Add (spl_header, 0, wxLEFT | wxRIGHT | wxEXPAND, DCPOMATIC_SIZER_GAP);
- left_sizer->Add (_spl_view, 1, wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND, DCPOMATIC_SIZER_GAP);
-
- _content_view = new ContentView (this);
-
- wxBoxSizer* content_header = new wxBoxSizer (wxHORIZONTAL);
- {
- wxStaticText* m = new StaticText (this, "Content");
- m->SetFont (subheading_font);
- content_header->Add (m, 1, wxALIGN_CENTER_VERTICAL);
- }
- _refresh_content_view = new Button (this, "Refresh");
- content_header->Add (_refresh_content_view, 0, wxBOTTOM, DCPOMATIC_SIZER_GAP / 2);
-
- left_sizer->Add (content_header, 0, wxTOP | wxLEFT | wxRIGHT | wxEXPAND, DCPOMATIC_SIZER_GAP);
- left_sizer->Add (_content_view, 1, wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND, DCPOMATIC_SIZER_GAP);
-
- _current_spl_view = new wxListCtrl (this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_NO_HEADER);
- _current_spl_view->AppendColumn (wxT(""), wxLIST_FORMAT_LEFT, 500);
- _current_spl_view->AppendColumn (wxT(""), wxLIST_FORMAT_LEFT, 80);
- e_sizer->Add (left_sizer, 1, wxALL | wxEXPAND, DCPOMATIC_SIZER_GAP);
- e_sizer->Add (_current_spl_view, 1, wxALL | wxEXPAND, DCPOMATIC_SIZER_GAP);
-
- _v_sizer->Add (e_sizer, 1, wxEXPAND);
-
- _play_button->Bind (wxEVT_BUTTON, boost::bind(&SwaroopControls::play_clicked, this));
- _pause_button->Bind (wxEVT_BUTTON, boost::bind(&SwaroopControls::pause_clicked, this));
- _stop_button->Bind (wxEVT_BUTTON, boost::bind(&SwaroopControls::stop_clicked, this));
- _next_button->Bind (wxEVT_BUTTON, boost::bind(&SwaroopControls::next_clicked, this));
- _previous_button->Bind (wxEVT_BUTTON, boost::bind(&SwaroopControls::previous_clicked, this));
- _spl_view->Bind (wxEVT_LIST_ITEM_SELECTED, boost::bind(&SwaroopControls::spl_selection_changed, this));
- _spl_view->Bind (wxEVT_LIST_ITEM_DESELECTED, boost::bind(&SwaroopControls::spl_selection_changed, this));
- _viewer->Finished.connect (boost::bind(&SwaroopControls::viewer_finished, this));
- _refresh_spl_view->Bind (wxEVT_BUTTON, boost::bind(&SwaroopControls::update_playlist_directory, this));
- _refresh_content_view->Bind (wxEVT_BUTTON, boost::bind(&ContentView::update, _content_view));
-
- /* Write position every two minutes if we're playing */
- Bind (wxEVT_TIMER, boost::bind(&SwaroopControls::write_position, this));
- _timer.Start (2 * 60 * 1000, wxTIMER_CONTINUOUS);
-
- _content_view->update ();
- update_playlist_directory ();
-
- _viewer->set_background_image (true);
-}
-
-void
-SwaroopControls::check_restart ()
-{
- cout << "check_restart called\n";
- FILE* f = fopen_boost (Config::path("position"), "r");
- if (!f) {
- cout << "could not open position file (" << errno << ")\n";
- return;
- }
-
- char id[64];
- int index;
- int64_t time;
- fscanf (f, "%63s %d %ld", id, &index, &time);
-
- cout << "Looking for playlist " << id << " to restart.\n";
-
- for (size_t i = 0; i < _playlists.size(); ++i) {
- if (_playlists[i].id() == id) {
- cout << "Found playlist " << id << "\n";
- select_playlist (i, index);
- update_current_content ();
- _viewer->seek (DCPTime(time), false);
- _viewer->start ();
- }
- }
-
- fclose (f);
-}
-
-void
-SwaroopControls::write_position ()
-{
- if (!_selected_playlist || !_viewer->playing()) {
- return;
- }
-
- FILE* f = fopen_boost (Config::path("position"), "w");
- if (f) {
- string const p = _playlists[*_selected_playlist].id()
- + " " + dcp::raw_convert<string>(_selected_playlist_position)
- + " " + dcp::raw_convert<string>(_viewer->position().get());
-
- checked_fwrite (p.c_str(), p.length(), f, Config::path("position"));
-#ifdef DCPOMATIC_LINUX
- fflush (f);
- fsync (fileno(f));
-#endif
- fclose (f);
- }
-}
-
-void
-SwaroopControls::started ()
-{
- Controls::started ();
- _play_button->Enable (false);
- _pause_button->Enable (true);
- _viewer->set_background_image (false);
-}
-
-/** Called when the viewer finishes a single piece of content, or it is explicitly stopped */
-void
-SwaroopControls::stopped ()
-{
- Controls::stopped ();
- _play_button->Enable (true);
- _pause_button->Enable (false);
-}
-
-void
-SwaroopControls::deselect_playlist ()
-{
- long int const selected = _spl_view->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
- if (selected != -1) {
- _selected_playlist = boost::none;
- _spl_view->SetItemState (selected, 0, wxLIST_STATE_SELECTED);
- }
- ResetFilm (shared_ptr<Film>(new Film(optional<boost::filesystem::path>())));
-}
-
-void
-SwaroopControls::decrement_allowed_shows ()
-{
- if (_selected_playlist) {
- SPL& spl = _playlists[*_selected_playlist];
- spl.decrement_allowed_shows();
- if (spl.path()) {
- spl.write (*spl.path());
- }
- }
-}
-
-void
-SwaroopControls::play_clicked ()
-{
- _viewer->start ();
-}
-
-void
-SwaroopControls::setup_sensitivity ()
-{
- Controls::setup_sensitivity ();
- bool const active_job = _active_job && *_active_job != "examine_content";
- bool const c = _film && !_film->content().empty() && !active_job;
- _play_button->Enable (c && !_viewer->playing());
- _pause_button->Enable (_viewer->playing());
- _slider->Enable (!_current_disable_timeline);
- _spl_view->Enable (!_viewer->playing());
- _next_button->Enable (!_current_disable_next && can_do_next());
- _previous_button->Enable (can_do_previous());
-}
-
-void
-SwaroopControls::pause_clicked ()
-{
- _viewer->stop ();
-}
-
-void
-SwaroopControls::stop_clicked ()
-{
- _viewer->stop ();
- _viewer->seek (DCPTime(), true);
- if (_selected_playlist) {
- _selected_playlist_position = 0;
- update_current_content ();
- }
- _viewer->set_background_image (true);
- decrement_allowed_shows ();
- deselect_playlist ();
-}
-
-bool
-SwaroopControls::can_do_previous ()
-{
- return _selected_playlist && (_selected_playlist_position - 1) >= 0;
-}
-
-void
-SwaroopControls::previous_clicked ()
-{
- if (!can_do_previous ()) {
- return;
- }
-
- _selected_playlist_position--;
- update_current_content ();
-}
-
-bool
-SwaroopControls::can_do_next ()
-{
- return _selected_playlist && (_selected_playlist_position + 1) < int(_playlists[*_selected_playlist].get().size());
-}
-
-void
-SwaroopControls::next_clicked ()
-{
- if (!can_do_next ()) {
- return;
- }
-
- _selected_playlist_position++;
- update_current_content ();
-}
-
-void
-SwaroopControls::log (wxString s)
-{
- optional<boost::filesystem::path> log = Config::instance()->player_activity_log_file();
- if (!log) {
- return;
- }
-
- struct timeval time;
- gettimeofday (&time, 0);
- char buffer[64];
- time_t const sec = time.tv_sec;
- struct tm* t = localtime (&sec);
- strftime (buffer, 64, "%c", t);
- wxString ts = std_to_wx(string(buffer)) + N_(": ");
- FILE* f = fopen_boost (*log, "a");
- if (!f) {
- return;
- }
- fprintf (f, "%s%s\n", wx_to_std(ts).c_str(), wx_to_std(s).c_str());
- fclose (f);
-}
-
-void
-SwaroopControls::add_playlist_to_list (SPL spl)
-{
- int const N = _spl_view->GetItemCount();
-
- wxListItem it;
- it.SetId(N);
- it.SetColumn(0);
- string t = spl.name();
- if (spl.missing()) {
- t += " (content missing)";
- }
- it.SetText (std_to_wx(t));
- _spl_view->InsertItem (it);
-}
-
-struct SPLComparator
-{
- bool operator() (SPL const & a, SPL const & b) {
- return a.name() < b.name();
- }
-};
-
-void
-SwaroopControls::update_playlist_directory ()
-{
- using namespace boost::filesystem;
-
- _spl_view->DeleteAllItems ();
- optional<path> dir = Config::instance()->player_playlist_directory();
- if (!dir) {
- return;
- }
-
- _playlists.clear ();
-
- for (directory_iterator i = directory_iterator(*dir); i != directory_iterator(); ++i) {
- try {
- if (is_regular_file(i->path()) && i->path().extension() == ".xml") {
- SPL spl;
- spl.read (i->path(), _content_view);
- _playlists.push_back (spl);
- }
- } catch (exception& e) {
- /* Never mind */
- }
- }
-
- sort (_playlists.begin(), _playlists.end(), SPLComparator());
- BOOST_FOREACH (SPL i, _playlists) {
- add_playlist_to_list (i);
- }
-
- _selected_playlist = boost::none;
-}
-
-optional<dcp::EncryptedKDM>
-SwaroopControls::get_kdm_from_url (shared_ptr<DCPContent> dcp)
-{
- ScopedTemporary temp;
- string url = Config::instance()->kdm_server_url();
- boost::algorithm::replace_all (url, "{CPL}", *dcp->cpl());
- optional<dcp::EncryptedKDM> kdm;
- if (dcp->cpl() && !get_from_url(url, false, false, temp)) {
- try {
- kdm = dcp::EncryptedKDM (dcp::file_to_string(temp.file()));
- if (kdm->cpl_id() != dcp->cpl()) {
- kdm = boost::none;
- }
- } catch (std::exception& e) {
- /* Hey well */
- }
- }
- return kdm;
-}
-
-optional<dcp::EncryptedKDM>
-SwaroopControls::get_kdm_from_directory (shared_ptr<DCPContent> dcp)
-{
- using namespace boost::filesystem;
- optional<path> kdm_dir = Config::instance()->player_kdm_directory();
- if (!kdm_dir) {
- return optional<dcp::EncryptedKDM>();
- }
- for (directory_iterator i = directory_iterator(*kdm_dir); i != directory_iterator(); ++i) {
- try {
- if (file_size(i->path()) < MAX_KDM_SIZE) {
- dcp::EncryptedKDM kdm (dcp::file_to_string(i->path()));
- if (kdm.cpl_id() == dcp->cpl()) {
- return kdm;
- }
- }
- } catch (std::exception& e) {
- /* Hey well */
- }
- }
- return optional<dcp::EncryptedKDM>();
-}
-
-optional<EncryptedECinemaKDM>
-SwaroopControls::get_kdm_from_directory (shared_ptr<FFmpegContent> ffmpeg)
-{
- using namespace boost::filesystem;
- optional<path> kdm_dir = Config::instance()->player_kdm_directory();
- if (!kdm_dir) {
- return optional<EncryptedECinemaKDM>();
- }
- for (directory_iterator i = directory_iterator(*kdm_dir); i != directory_iterator(); ++i) {
- try {
- if (file_size(i->path()) < MAX_KDM_SIZE) {
- EncryptedECinemaKDM kdm (dcp::file_to_string(i->path()));
- if (kdm.id() == ffmpeg->id().get_value_or("")) {
- return kdm;
- }
- }
- } catch (std::exception& e) {
- /* Hey well */
- }
- }
- return optional<EncryptedECinemaKDM>();
-}
-void
-SwaroopControls::spl_selection_changed ()
-{
- long int selected = _spl_view->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
- if (selected == -1) {
- _current_spl_view->DeleteAllItems ();
- _selected_playlist = boost::none;
- return;
- }
-
- if (_playlists[selected].missing()) {
- error_dialog (this, "This playlist cannot be loaded as some content is missing.");
- deselect_playlist ();
- return;
- }
-
- if (_playlists[selected].get().empty()) {
- error_dialog (this, "This playlist is empty.");
- return;
- }
-
- if (!_playlists[selected].have_allowed_shows()) {
- error_dialog (this, "There are no more allowed shows of this playlist.");
- return;
- }
-
- select_playlist (selected, 0);
-}
-
-void
-SwaroopControls::select_playlist (int selected, int position)
-{
- log (wxString::Format("load-playlist %s", std_to_wx(_playlists[selected].name()).data()));
-
- wxProgressDialog dialog (_("DCP-o-matic"), "Loading playlist and KDMs");
-
- BOOST_FOREACH (SPLEntry const & i, _playlists[selected].get()) {
- dialog.Pulse ();
- shared_ptr<DCPContent> dcp = dynamic_pointer_cast<DCPContent> (i.content);
- if (dcp && dcp->needs_kdm()) {
- optional<dcp::EncryptedKDM> kdm;
- kdm = get_kdm_from_url (dcp);
- if (!kdm) {
- kdm = get_kdm_from_directory (dcp);
- }
- if (kdm) {
- try {
- dcp->add_kdm (*kdm);
- dcp->examine (_film, shared_ptr<Job>());
- } catch (KDMError& e) {
- error_dialog (this, "Could not load KDM.");
- }
- }
- if (dcp->needs_kdm()) {
- /* We didn't get a KDM for this */
- error_dialog (this, "This playlist cannot be loaded as a KDM is missing or incorrect.");
- deselect_playlist ();
- return;
- }
- }
- shared_ptr<FFmpegContent> ffmpeg = dynamic_pointer_cast<FFmpegContent> (i.content);
- if (ffmpeg && ffmpeg->encrypted()) {
- optional<EncryptedECinemaKDM> kdm = get_kdm_from_directory (ffmpeg);
- if (kdm) {
- try {
- ffmpeg->add_kdm (*kdm);
- ffmpeg->examine (_film, shared_ptr<Job>());
- } catch (KDMError& e) {
- error_dialog (this, "This playlist cannot be loaded as a KDM is missing or incorrect.");
- deselect_playlist ();
- return;
- }
- } else {
- error_dialog (this, "This playlist cannot be loaded as a KDM is missing or incorrect.");
- deselect_playlist ();
- return;
- }
- }
- }
-
- _current_spl_view->DeleteAllItems ();
-
- int N = 0;
- BOOST_FOREACH (SPLEntry i, _playlists[selected].get()) {
- wxListItem it;
- it.SetId (N);
- it.SetColumn (0);
- it.SetText (std_to_wx(i.name));
- _current_spl_view->InsertItem (it);
- ++N;
- }
-
- _selected_playlist = selected;
- _selected_playlist_position = position;
- dialog.Pulse ();
- reset_film ();
- dialog.Pulse ();
- update_current_content ();
-}
-
-void
-SwaroopControls::reset_film ()
-{
- DCPOMATIC_ASSERT (_selected_playlist);
- shared_ptr<Film> film (new Film(optional<boost::filesystem::path>()));
- film->add_content (_playlists[*_selected_playlist].get()[_selected_playlist_position].content);
- ResetFilm (film);
-}
-
-void
-SwaroopControls::config_changed (int property)
-{
- Controls::config_changed (property);
-
- if (property == Config::PLAYER_CONTENT_DIRECTORY) {
- _content_view->update ();
- } else if (property == Config::PLAYER_PLAYLIST_DIRECTORY) {
- update_playlist_directory ();
- }
-}
-
-void
-SwaroopControls::set_film (shared_ptr<Film> film)
-{
- Controls::set_film (film);
- setup_sensitivity ();
-}
-
-void
-SwaroopControls::update_current_content ()
-{
- DCPOMATIC_ASSERT (_selected_playlist);
-
- wxProgressDialog dialog (_("DCP-o-matic"), "Loading content");
-
- SPLEntry const & e = _playlists[*_selected_playlist].get()[_selected_playlist_position];
- _current_disable_timeline = e.disable_timeline;
- _current_disable_next = !e.skippable;
-
- setup_sensitivity ();
- dialog.Pulse ();
- reset_film ();
-}
-
-/** One piece of content in our SPL has finished playing */
-void
-SwaroopControls::viewer_finished ()
-{
- if (!_selected_playlist) {
- return;
- }
-
- bool const stop = _playlists[*_selected_playlist].get()[_selected_playlist_position].stop_after_play;
-
- _selected_playlist_position++;
- if (_selected_playlist_position < int(_playlists[*_selected_playlist].get().size())) {
- /* Next piece of content on the SPL */
- update_current_content ();
- if (!stop) {
- _viewer->start ();
- }
- } else {
- /* Finished the whole SPL */
- _selected_playlist_position = 0;
- _viewer->set_background_image (true);
- ResetFilm (shared_ptr<Film>(new Film(optional<boost::filesystem::path>())));
- decrement_allowed_shows ();
- _play_button->Enable (true);
- _pause_button->Enable (false);
- }
-}
+++ /dev/null
-/*
- Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- DCP-o-matic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- 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 "controls.h"
-#include "lib/swaroop_spl.h"
-
-class DCPContent;
-class EncryptedECinemaKDM;
-
-class SwaroopControls : public Controls
-{
-public:
- SwaroopControls (wxWindow* parent, boost::shared_ptr<FilmViewer> viewer);
-
- void log (wxString s);
- void set_film (boost::shared_ptr<Film> film);
- void check_restart ();
-
- /** This is so that we can tell our parent player to reset the film
- when we have created one from a SPL. We could call a method
- in the player's DOMFrame but we don't have that in a header.
- */
- boost::signals2::signal<void (boost::weak_ptr<Film>)> ResetFilm;
-
-private:
- void play_clicked ();
- void pause_clicked ();
- void stop_clicked ();
- void next_clicked ();
- void previous_clicked ();
- void add_playlist_to_list (SPL spl);
- void update_content_directory ();
- void update_playlist_directory ();
- void spl_selection_changed ();
- void select_playlist (int selected, int position);
- void started ();
- void stopped ();
- void setup_sensitivity ();
- void config_changed (int);
- void viewer_finished ();
- void write_position ();
- void reset_film ();
- void update_current_content ();
- bool can_do_previous ();
- bool can_do_next ();
- void decrement_allowed_shows ();
- void deselect_playlist ();
-
- boost::optional<dcp::EncryptedKDM> get_kdm_from_url (boost::shared_ptr<DCPContent> dcp);
- boost::optional<dcp::EncryptedKDM> get_kdm_from_directory (boost::shared_ptr<DCPContent> dcp);
- boost::optional<EncryptedECinemaKDM> get_kdm_from_directory (boost::shared_ptr<FFmpegContent> ffmpeg);
-
- wxButton* _play_button;
- wxButton* _pause_button;
- wxButton* _stop_button;
- wxButton* _next_button;
- wxButton* _previous_button;
-
- ContentView* _content_view;
- wxButton* _refresh_content_view;
- wxListCtrl* _spl_view;
- wxButton* _refresh_spl_view;
- wxListCtrl* _current_spl_view;
-
- bool _current_disable_timeline;
- bool _current_disable_next;
-
- std::vector<SPL> _playlists;
- boost::optional<int> _selected_playlist;
- int _selected_playlist_position;
-
- wxTimer _timer;
-};
VideoView::VideoView (FilmViewer* viewer)
: _viewer (viewer)
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- , _in_watermark (false)
-#endif
, _state_timer ("viewer")
, _video_frame_rate (0)
, _eyes (EYES_LEFT)
FilmViewer* _viewer;
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- bool _in_watermark;
- int _watermark_x;
- int _watermark_y;
-#endif
-
StateTimer _state_timer;
private:
if bld.env.TARGET_OSX:
obj.framework = ['CoreAudio', 'OpenGL']
obj.use = 'libdcpomatic2'
- if not len(bld.env.VARIANT) == 0 and bld.env.VARIANT.startswith('swaroop-'):
- obj.source = sources + " swaroop_controls.cc"
- else:
- obj.source = sources
+ obj.source = sources
obj.target = 'dcpomatic2-wx'
i18n.po_to_mo(os.path.join('src', 'wx'), 'libdcpomatic2-wx', bld)
+++ /dev/null
-/*
- Copyright (C) 2019 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- DCP-o-matic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- 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 "lib/decrypted_ecinema_kdm.h"
-#include "lib/encrypted_ecinema_kdm.h"
-#include "lib/config.h"
-#include <boost/test/unit_test.hpp>
-extern "C" {
-#include <libavutil/aes_ctr.h>
-}
-#include <fstream>
-
-using std::string;
-using boost::optional;
-
-#ifdef DCPOMATIC_VARIANT_SWAROOP
-
-BOOST_AUTO_TEST_CASE (ecinema_kdm_roundtrip_test1)
-{
- dcp::Key key (AES_CTR_KEY_SIZE);
- DecryptedECinemaKDM dec ("123-456-789-0", "Hello world", key, optional<dcp::LocalTime>(), optional<dcp::LocalTime>());
- EncryptedECinemaKDM enc = dec.encrypt (Config::instance()->decryption_chain()->leaf());
- DecryptedECinemaKDM dec2 (enc, *Config::instance()->decryption_chain()->key());
- BOOST_CHECK_EQUAL (dec2.id(), "123-456-789-0");
- BOOST_CHECK_EQUAL (dec2.name(), "Hello world");
- BOOST_CHECK (dec2.key() == key);
- BOOST_CHECK (!static_cast<bool>(dec2.not_valid_before()));
- BOOST_CHECK (!static_cast<bool>(dec2.not_valid_after()));
-}
-
-BOOST_AUTO_TEST_CASE (ecinema_kdm_roundtrip_test2)
-{
- dcp::Key key (AES_CTR_KEY_SIZE);
- DecryptedECinemaKDM dec ("123-456-789-0", "Hello world", key, dcp::LocalTime("2019-06-01T15:05:23+01:00"), dcp::LocalTime("2019-07-02T19:10:12+02:00"));
- EncryptedECinemaKDM enc = dec.encrypt (Config::instance()->decryption_chain()->leaf());
- DecryptedECinemaKDM dec2 (enc, *Config::instance()->decryption_chain()->key());
- BOOST_CHECK_EQUAL (dec2.id(), "123-456-789-0");
- BOOST_CHECK_EQUAL (dec2.name(), "Hello world");
- BOOST_CHECK (dec2.key() == key);
- BOOST_REQUIRE (static_cast<bool>(dec2.not_valid_before()));
- BOOST_CHECK_EQUAL (dec2.not_valid_before()->as_string(), "2019-06-01T15:05:23+01:00");
- BOOST_REQUIRE (static_cast<bool>(dec2.not_valid_after()));
- BOOST_CHECK_EQUAL (dec2.not_valid_after()->as_string(), "2019-07-02T19:10:12+02:00");
-}
-
-BOOST_AUTO_TEST_CASE (ecinema_kdm_roundtrip_test3)
-{
- dcp::Key key (AES_CTR_KEY_SIZE);
- DecryptedECinemaKDM dec ("123-456-789-0", "Hello world", key, optional<dcp::LocalTime>(), optional<dcp::LocalTime>());
- EncryptedECinemaKDM enc = dec.encrypt (Config::instance()->decryption_chain()->leaf());
- string const enc_xml = enc.as_xml ();
- EncryptedECinemaKDM enc2 (enc_xml);
- DecryptedECinemaKDM dec2 (enc2, *Config::instance()->decryption_chain()->key());
- BOOST_CHECK_EQUAL (dec2.id(), "123-456-789-0");
- BOOST_CHECK_EQUAL (dec2.name(), "Hello world");
- BOOST_CHECK (dec2.key() == key);
- BOOST_CHECK (!static_cast<bool>(dec2.not_valid_before()));
- BOOST_CHECK (!static_cast<bool>(dec2.not_valid_after()));
-}
-
-BOOST_AUTO_TEST_CASE (ecinema_kdm_roundtrip_test4)
-{
- dcp::Key key (AES_CTR_KEY_SIZE);
- DecryptedECinemaKDM dec ("123-456-789-0", "Hello world", key, dcp::LocalTime("2019-06-01T15:05:23+01:00"), dcp::LocalTime("2019-07-02T19:10:12+02:00"));
- EncryptedECinemaKDM enc = dec.encrypt (Config::instance()->decryption_chain()->leaf());
- string const enc_xml = enc.as_xml();
- EncryptedECinemaKDM enc2 (dcp::file_to_string("build/test/shit_the_bed.xml"));
- DecryptedECinemaKDM dec2 (enc2, *Config::instance()->decryption_chain()->key());
- BOOST_CHECK_EQUAL (dec2.id(), "123-456-789-0");
- BOOST_CHECK_EQUAL (dec2.name(), "Hello world");
- BOOST_CHECK (dec2.key() == key);
- BOOST_REQUIRE (static_cast<bool>(dec2.not_valid_before()));
- BOOST_CHECK_EQUAL (dec2.not_valid_before()->as_string(), "2019-06-01T15:05:23+01:00");
- BOOST_REQUIRE (static_cast<bool>(dec2.not_valid_after()));
- BOOST_CHECK_EQUAL (dec2.not_valid_after()->as_string(), "2019-07-02T19:10:12+02:00");
-}
-
-#endif
film->write_metadata ();
shared_ptr<Job> job (new TranscodeJob (film));
- FFmpegEncoder encoder (film, job, String::compose("build/test/%1.%2", name, extension), format, false, false, false, 23
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- , optional<dcp::Key>(), optional<string>()
-#endif
- );
+ FFmpegEncoder encoder (film, job, String::compose("build/test/%1.%2", name, extension), format, false, false, false, 23);
encoder.go ();
}
film->write_metadata ();
shared_ptr<Job> job (new TranscodeJob (film));
- FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_test5.mov", EXPORT_FORMAT_PRORES, false, false, false, 23
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- , optional<dcp::Key>(), optional<string>()
-#endif
- );
+ FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_test5.mov", EXPORT_FORMAT_PRORES, false, false, false, 23);
encoder.go ();
}
film->write_metadata();
shared_ptr<Job> job (new TranscodeJob (film));
- FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_test6.mov", EXPORT_FORMAT_PRORES, false, false, false, 23
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- , optional<dcp::Key>(), optional<string>()
-#endif
- );
+ FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_test6.mov", EXPORT_FORMAT_PRORES, false, false, false, 23);
encoder.go ();
}
s->only_text()->set_effect_colour (dcp::Colour (0, 255, 255));
shared_ptr<Job> job (new TranscodeJob (film));
- FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_test7.mov", EXPORT_FORMAT_PRORES, false, false, false, 23
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- , optional<dcp::Key>(), optional<string>()
-#endif
- );
+ FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_test7.mov", EXPORT_FORMAT_PRORES, false, false, false, 23);
encoder.go ();
}
film->write_metadata();
shared_ptr<Job> job (new TranscodeJob (film));
- FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_h264_test2.mp4", EXPORT_FORMAT_H264_AAC, false, false, false, 23
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- , optional<dcp::Key>(), optional<string>()
-#endif
- );
+ FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_h264_test2.mp4", EXPORT_FORMAT_H264_AAC, false, false, false, 23);
encoder.go ();
}
film->write_metadata();
shared_ptr<Job> job (new TranscodeJob (film));
- FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_h264_test3.mp4", EXPORT_FORMAT_H264_AAC, false, false, false, 23
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- , optional<dcp::Key>(), optional<string>()
-#endif
- );
+ FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_h264_test3.mp4", EXPORT_FORMAT_H264_AAC, false, false, false, 23);
encoder.go ();
}
film->set_container(Ratio::from_id("185"));
shared_ptr<Job> job(new TranscodeJob(film));
- FFmpegEncoder encoder(film, job, "build/test/ffmpeg_encoder_h264_test4.mp4", EXPORT_FORMAT_H264_AAC, false, false, false, 23
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- , optional<dcp::Key>(), optional<string>()
-#endif
- );
+ FFmpegEncoder encoder(film, job, "build/test/ffmpeg_encoder_h264_test4.mp4", EXPORT_FORMAT_H264_AAC, false, false, false, 23);
encoder.go();
}
Rs->audio->set_mapping (map);
shared_ptr<Job> job (new TranscodeJob (film));
- FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_h264_test5.mp4", EXPORT_FORMAT_H264_AAC, true, false, false, 23
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- , optional<dcp::Key>(), optional<string>()
-#endif
- );
+ FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_h264_test5.mp4", EXPORT_FORMAT_H264_AAC, true, false, false, 23);
encoder.go ();
check_ffmpeg ("build/test/ffmpeg_encoder_h264_test5.mp4", "test/data/ffmpeg_encoder_h264_test5.mp4", 1);
}
shared_ptr<Job> job (new TranscodeJob (film2));
- FFmpegEncoder encoder (film2, job, "build/test/ffmpeg_encoder_h264_test6_vf.mp4", EXPORT_FORMAT_H264_AAC, true, false, false, 23
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- , optional<dcp::Key>(), optional<string>()
-#endif
- );
+ FFmpegEncoder encoder (film2, job, "build/test/ffmpeg_encoder_h264_test6_vf.mp4", EXPORT_FORMAT_H264_AAC, true, false, false, 23);
encoder.go ();
}
BOOST_REQUIRE (!wait_for_jobs());
shared_ptr<Job> job (new TranscodeJob (film2));
- FFmpegEncoder encoder (film2, job, "build/test/ffmpeg_encoder_h264_test7.mp4", EXPORT_FORMAT_H264_AAC, true, false, false, 23
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- , optional<dcp::Key>(), optional<string>()
-#endif
- );
+ FFmpegEncoder encoder (film2, job, "build/test/ffmpeg_encoder_h264_test7.mp4", EXPORT_FORMAT_H264_AAC, true, false, false, 23);
encoder.go ();
}
film->set_audio_channels (2);
shared_ptr<Job> job(new TranscodeJob(film));
- FFmpegEncoder encoder(film, job, "build/test/ffmpeg_encoder_h264_test8.mp4", EXPORT_FORMAT_H264_AAC, true, false, false, 23
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- , optional<dcp::Key>(), optional<string>()
-#endif
- );
+ FFmpegEncoder encoder(film, job, "build/test/ffmpeg_encoder_h264_test8.mp4", EXPORT_FORMAT_H264_AAC, true, false, false, 23);
encoder.go();
}
film->write_metadata ();
shared_ptr<Job> job (new TranscodeJob (film));
- FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_test9.mov", EXPORT_FORMAT_H264_AAC, false, false, false, 23
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- , optional<dcp::Key>(), optional<string>()
-#endif
- );
+ FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_test9.mov", EXPORT_FORMAT_H264_AAC, false, false, false, 23);
encoder.go ();
}
BOOST_CHECK_EQUAL (utf8_strlen("hëłlo wørld"), 11U);
}
-#ifdef DCPOMATIC_VARIANT_SWAROOP
-BOOST_AUTO_TEST_CASE (swaroop_chain_test)
-{
- shared_ptr<dcp::CertificateChain> cc (
- new dcp::CertificateChain (
- openssl_path(),
- "dcpomatic.com",
- "dcpomatic.com",
- ".dcpomatic.smpte-430-2.ROOT",
- ".dcpomatic.smpte-430-2.INTERMEDIATE",
- "CS.dcpomatic.smpte-430-2.LEAF"
- )
- );
-
- write_swaroop_chain (cc, "build/test/swaroop_chain");
- shared_ptr<dcp::CertificateChain> back = read_swaroop_chain ("build/test/swaroop_chain");
-
- BOOST_CHECK (cc->root_to_leaf() == back->root_to_leaf());
-}
-#endif
-
BOOST_AUTO_TEST_CASE (careful_string_filter_test)
{
BOOST_CHECK_EQUAL ("hello_world", careful_string_filter("hello_world"));
dcp_playback_test.cc
dcp_subtitle_test.cc
digest_test.cc
- ecinema_kdm_test.cc
empty_test.cc
ffmpeg_audio_only_test.cc
ffmpeg_audio_test.cc
opt.add_option('--static-curl', action='store_true', default=False, help='link statically to libcurl')
opt.add_option('--workaround-gssapi', action='store_true', default=False, help='link to gssapi_krb5')
opt.add_option('--force-cpp11', action='store_true', default=False, help='force use of C++11')
- opt.add_option('--variant', help='build variant (swaroop-studio, swaroop-theater)', choices=['swaroop-studio', 'swaroop-theater'])
opt.add_option('--use-lld', action='store_true', default=False, help='use lld linker')
opt.add_option('--enable-disk', action='store_true', default=False, help='build dcpomatic2_disk tool; requires Boost process, lwext4 and nanomsg libraries')
opt.add_option('--warnings-are-errors', action='store_true', default=False, help='build with -Werror')
else:
conf.env.append_value('CXXFLAGS', '-O2')
- if conf.options.variant is not None:
- conf.env.VARIANT = conf.options.variant
- if conf.options.variant.startswith('swaroop-'):
- conf.env.append_value('CXXFLAGS', '-DDCPOMATIC_VARIANT_SWAROOP')
-
if conf.options.enable_disk:
conf.env.append_value('CXXFLAGS', '-DDCPOMATIC_DISK')