summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2013-08-17 21:47:08 +0100
committerCarl Hetherington <cth@carlh.net>2013-08-17 21:47:08 +0100
commit2499c41097f8410cb3016e095a85d68979485a7b (patch)
tree331a23489d3be42ede2861311a797792ba663805 /src/lib
parent89af81886eeee57861bc23984a0583bec76d536d (diff)
Various bits mostly related to colour conversions.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/colour_conversion.cc96
-rw-r--r--src/lib/colour_conversion.h35
-rw-r--r--src/lib/config.cc26
-rw-r--r--src/lib/config.h15
-rw-r--r--src/lib/dcp_video_frame.cc4
-rw-r--r--src/lib/dcp_video_frame.h2
-rw-r--r--src/lib/encoder.cc12
-rw-r--r--src/lib/encoder.h2
-rw-r--r--src/lib/server.cc7
-rw-r--r--src/lib/server.h7
-rw-r--r--src/lib/video_content.cc28
-rw-r--r--src/lib/video_content.h10
12 files changed, 188 insertions, 56 deletions
diff --git a/src/lib/colour_conversion.cc b/src/lib/colour_conversion.cc
index 96dc0e2c9..cc25ccc67 100644
--- a/src/lib/colour_conversion.cc
+++ b/src/lib/colour_conversion.cc
@@ -21,18 +21,21 @@
#include <libxml++/libxml++.h>
#include <libdcp/colour_matrix.h>
#include <libcxml/cxml.h>
+#include "config.h"
#include "colour_conversion.h"
#include "i18n.h"
using std::list;
using std::string;
+using std::cout;
+using std::vector;
using boost::shared_ptr;
using boost::lexical_cast;
+using boost::optional;
ColourConversion::ColourConversion ()
- : name (_("Untitled"))
- , input_gamma (2.4)
+ : input_gamma (2.4)
, input_gamma_linearised (true)
, matrix (3, 3)
, output_gamma (2.6)
@@ -44,9 +47,8 @@ ColourConversion::ColourConversion ()
}
}
-ColourConversion::ColourConversion (string n, float i, bool il, float const m[3][3], float o)
- : name (n)
- , input_gamma (i)
+ColourConversion::ColourConversion (double i, bool il, double const m[3][3], double o)
+ : input_gamma (i)
, input_gamma_linearised (il)
, matrix (3, 3)
, output_gamma (o)
@@ -61,8 +63,7 @@ ColourConversion::ColourConversion (string n, float i, bool il, float const m[3]
ColourConversion::ColourConversion (shared_ptr<cxml::Node> node)
: matrix (3, 3)
{
- name = node->string_child ("Name");
- input_gamma = node->number_child<float> ("InputGamma");
+ input_gamma = node->number_child<double> ("InputGamma");
input_gamma_linearised = node->bool_child ("InputGammaLinearised");
for (int i = 0; i < 3; ++i) {
@@ -75,16 +76,15 @@ ColourConversion::ColourConversion (shared_ptr<cxml::Node> node)
for (list<shared_ptr<cxml::Node> >::iterator i = m.begin(); i != m.end(); ++i) {
int const ti = (*i)->number_attribute<int> ("i");
int const tj = (*i)->number_attribute<int> ("j");
- matrix(ti, tj) = lexical_cast<float> ((*i)->content ());
+ matrix(ti, tj) = lexical_cast<double> ((*i)->content ());
}
- output_gamma = node->number_child<float> ("OutputGamma");
+ output_gamma = node->number_child<double> ("OutputGamma");
}
void
ColourConversion::as_xml (xmlpp::Node* node) const
{
- node->add_child("Name")->add_child_text (name);
node->add_child("InputGamma")->add_child_text (lexical_cast<string> (input_gamma));
node->add_child("InputGammaLinearised")->add_child_text (input_gamma_linearised ? "1" : "0");
@@ -99,3 +99,79 @@ ColourConversion::as_xml (xmlpp::Node* node) const
node->add_child("OutputGamma")->add_child_text (lexical_cast<string> (output_gamma));
}
+
+optional<size_t>
+ColourConversion::preset () const
+{
+ vector<PresetColourConversion> presets = Config::instance()->colour_conversions ();
+ size_t i = 0;
+ while (i < presets.size() && (presets[i].conversion != *this)) {
+ ++i;
+ }
+
+ if (i >= presets.size ()) {
+ return optional<size_t> ();
+ }
+
+ return i;
+}
+
+PresetColourConversion::PresetColourConversion ()
+ : name (_("Untitled"))
+{
+
+}
+
+PresetColourConversion::PresetColourConversion (string n, double i, bool il, double const m[3][3], double o)
+ : name (n)
+ , conversion (i, il, m, o)
+{
+
+}
+
+PresetColourConversion::PresetColourConversion (shared_ptr<cxml::Node> node)
+ : conversion (node)
+{
+ name = node->string_child ("Name");
+}
+
+void
+PresetColourConversion::as_xml (xmlpp::Node* node) const
+{
+ conversion.as_xml (node);
+ node->add_child("Name")->add_child_text (name);
+}
+
+static bool
+about_equal (double a, double b)
+{
+ static const double eps = 1e-6;
+ return fabs (a - b) < eps;
+}
+
+bool
+operator== (ColourConversion const & a, ColourConversion const & b)
+{
+ if (
+ !about_equal (a.input_gamma, b.input_gamma) ||
+ a.input_gamma_linearised != b.input_gamma_linearised ||
+ !about_equal (a.output_gamma, b.output_gamma)) {
+ return false;
+ }
+
+ for (int i = 0; i < 3; ++i) {
+ for (int j = 0; j < 3; ++j) {
+ if (!about_equal (a.matrix (i, j), b.matrix (i, j))) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool
+operator!= (ColourConversion const & a, ColourConversion const & b)
+{
+ return !(a == b);
+}
diff --git a/src/lib/colour_conversion.h b/src/lib/colour_conversion.h
index ed89f8c63..85d951ce1 100644
--- a/src/lib/colour_conversion.h
+++ b/src/lib/colour_conversion.h
@@ -17,7 +17,11 @@
*/
+#ifndef DCPOMATIC_COLOUR_CONVERSION_H
+#define DCPOMATIC_COLOUR_CONVERSION_H
+
#include <boost/utility.hpp>
+#include <boost/optional.hpp>
#include <boost/numeric/ublas/matrix.hpp>
namespace cxml {
@@ -28,18 +32,37 @@ namespace xmlpp {
class Node;
}
-class ColourConversion : public boost::noncopyable
+class ColourConversion
{
public:
ColourConversion ();
- ColourConversion (std::string, float, bool, float const matrix[3][3], float);
+ ColourConversion (double, bool, double const matrix[3][3], double);
ColourConversion (boost::shared_ptr<cxml::Node>);
+ virtual void as_xml (xmlpp::Node *) const;
+
+ boost::optional<size_t> preset () const;
+
+ double input_gamma;
+ bool input_gamma_linearised;
+ boost::numeric::ublas::matrix<double> matrix;
+ double output_gamma;
+};
+
+class PresetColourConversion
+{
+public:
+ PresetColourConversion ();
+ PresetColourConversion (std::string, double, bool, double const matrix[3][3], double);
+ PresetColourConversion (boost::shared_ptr<cxml::Node>);
+
void as_xml (xmlpp::Node *) const;
std::string name;
- float input_gamma;
- bool input_gamma_linearised;
- boost::numeric::ublas::matrix<float> matrix;
- float output_gamma;
+ ColourConversion conversion;
};
+
+bool operator== (ColourConversion const &, ColourConversion const &);
+bool operator!= (ColourConversion const &, ColourConversion const &);
+
+#endif
diff --git a/src/lib/config.cc b/src/lib/config.cc
index 0c8413be9..10cb13ecc 100644
--- a/src/lib/config.cc
+++ b/src/lib/config.cc
@@ -65,13 +65,8 @@ Config::Config ()
_allowed_dcp_frame_rates.push_back (50);
_allowed_dcp_frame_rates.push_back (60);
- _colour_conversions.push_back (shared_ptr<ColourConversion> (
- new ColourConversion (_("sRGB"), 2.4, true, libdcp::colour_matrix::xyz_to_rgb, 2.6))
- );
-
- _colour_conversions.push_back (shared_ptr<ColourConversion> (
- new ColourConversion (_("sRGB non-linearised"), 2.4, false, libdcp::colour_matrix::xyz_to_rgb, 2.6))
- );
+ _colour_conversions.push_back (PresetColourConversion (_("sRGB"), 2.4, true, libdcp::colour_matrix::xyz_to_rgb, 2.6));
+ _colour_conversions.push_back (PresetColourConversion (_("sRGB non-linearised"), 2.4, false, libdcp::colour_matrix::xyz_to_rgb, 2.6));
}
void
@@ -91,7 +86,7 @@ Config::read ()
list<shared_ptr<cxml::Node> > servers = f.node_children ("Server");
for (list<shared_ptr<cxml::Node> >::iterator i = servers.begin(); i != servers.end(); ++i) {
- _servers.push_back (shared_ptr<ServerDescription> (new ServerDescription (*i)));
+ _servers.push_back (ServerDescription (*i));
}
_tms_ip = f.string_child ("TMSIP");
@@ -130,7 +125,7 @@ Config::read ()
}
for (list<shared_ptr<cxml::Node> >::iterator i = cc.begin(); i != cc.end(); ++i) {
- _colour_conversions.push_back (shared_ptr<ColourConversion> (new ColourConversion (*i)));
+ _colour_conversions.push_back (PresetColourConversion (*i));
}
}
@@ -163,7 +158,10 @@ Config::read_old_metadata ()
} else if (k == N_("server_port")) {
_server_port = atoi (v.c_str ());
} else if (k == N_("server")) {
- _servers.push_back (ServerDescription::create_from_metadata (v));
+ optional<ServerDescription> server = ServerDescription::create_from_metadata (v);
+ if (server) {
+ _servers.push_back (server.get ());
+ }
} else if (k == N_("tms_ip")) {
_tms_ip = v;
} else if (k == N_("tms_path")) {
@@ -237,8 +235,8 @@ Config::write () const
root->add_child("DefaultDirectory")->add_child_text (_default_directory);
root->add_child("ServerPort")->add_child_text (lexical_cast<string> (_server_port));
- for (vector<shared_ptr<ServerDescription> >::const_iterator i = _servers.begin(); i != _servers.end(); ++i) {
- (*i)->as_xml (root->add_child ("Server"));
+ for (vector<ServerDescription>::const_iterator i = _servers.begin(); i != _servers.end(); ++i) {
+ i->as_xml (root->add_child ("Server"));
}
root->add_child("TMSIP")->add_child_text (_tms_ip);
@@ -265,8 +263,8 @@ Config::write () const
root->add_child("DefaultStillLength")->add_child_text (lexical_cast<string> (_default_still_length));
root->add_child("DefaultJ2KBandwidth")->add_child_text (lexical_cast<string> (_default_j2k_bandwidth));
- for (vector<shared_ptr<ColourConversion> >::const_iterator i = _colour_conversions.begin(); i != _colour_conversions.end(); ++i) {
- (*i)->as_xml (root->add_child ("ColourConversion"));
+ for (vector<PresetColourConversion>::const_iterator i = _colour_conversions.begin(); i != _colour_conversions.end(); ++i) {
+ i->as_xml (root->add_child ("ColourConversion"));
}
doc.write_to_file_formatted (file (false));
diff --git a/src/lib/config.h b/src/lib/config.h
index 40d06a172..bce6bfd7e 100644
--- a/src/lib/config.h
+++ b/src/lib/config.h
@@ -29,6 +29,8 @@
#include <boost/signals2.hpp>
#include <libdcp/metadata.h>
#include "dci_metadata.h"
+#include "colour_conversion.h"
+#include "server.h"
class ServerDescription;
class Scaler;
@@ -36,7 +38,6 @@ class Filter;
class SoundProcessor;
class DCPContentType;
class Ratio;
-class ColourConversion;
/** @class Config
* @brief A singleton class holding configuration.
@@ -62,7 +63,7 @@ public:
}
/** @return J2K encoding servers to use */
- std::vector<boost::shared_ptr<ServerDescription> > servers () const {
+ std::vector<ServerDescription> servers () const {
return _servers;
}
@@ -123,7 +124,7 @@ public:
return _default_j2k_bandwidth;
}
- std::vector<boost::shared_ptr<ColourConversion> > colour_conversions () const {
+ std::vector<PresetColourConversion> colour_conversions () const {
return _colour_conversions;
}
@@ -142,7 +143,7 @@ public:
}
/** @param s New list of servers */
- void set_servers (std::vector<boost::shared_ptr<ServerDescription> > s) {
+ void set_servers (std::vector<ServerDescription> s) {
_servers = s;
}
@@ -210,7 +211,7 @@ public:
_default_j2k_bandwidth = b;
}
- void set_colour_conversions (std::vector<boost::shared_ptr<ColourConversion> > const & c) {
+ void set_colour_conversions (std::vector<PresetColourConversion> const & c) {
_colour_conversions = c;
}
@@ -233,7 +234,7 @@ private:
int _server_port;
/** J2K encoding servers to use */
- std::vector<boost::shared_ptr<ServerDescription> > _servers;
+ std::vector<ServerDescription> _servers;
/** Scaler to use for the "A" part of A/B comparisons */
Scaler const * _reference_scaler;
/** Filters to use for the "A" part of A/B comparisons */
@@ -257,7 +258,7 @@ private:
DCPContentType const * _default_dcp_content_type;
libdcp::XMLMetadata _dcp_metadata;
int _default_j2k_bandwidth;
- std::vector<boost::shared_ptr<ColourConversion> > _colour_conversions;
+ std::vector<PresetColourConversion> _colour_conversions;
/** Singleton instance, or 0 */
static Config* _instance;
diff --git a/src/lib/dcp_video_frame.cc b/src/lib/dcp_video_frame.cc
index 53cf1753a..1cb20b611 100644
--- a/src/lib/dcp_video_frame.cc
+++ b/src/lib/dcp_video_frame.cc
@@ -213,11 +213,11 @@ DCPVideoFrame::encode_locally ()
* @return Encoded data.
*/
shared_ptr<EncodedData>
-DCPVideoFrame::encode_remotely (boost::shared_ptr<const ServerDescription> serv)
+DCPVideoFrame::encode_remotely (ServerDescription serv)
{
boost::asio::io_service io_service;
boost::asio::ip::tcp::resolver resolver (io_service);
- boost::asio::ip::tcp::resolver::query query (serv->host_name(), boost::lexical_cast<string> (Config::instance()->server_port ()));
+ boost::asio::ip::tcp::resolver::query query (serv.host_name(), boost::lexical_cast<string> (Config::instance()->server_port ()));
boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve (query);
shared_ptr<Socket> socket (new Socket);
diff --git a/src/lib/dcp_video_frame.h b/src/lib/dcp_video_frame.h
index 18c8fe628..ce6444293 100644
--- a/src/lib/dcp_video_frame.h
+++ b/src/lib/dcp_video_frame.h
@@ -105,7 +105,7 @@ public:
DCPVideoFrame (boost::shared_ptr<const Image>, int, Eyes, int, int, boost::shared_ptr<Log>);
boost::shared_ptr<EncodedData> encode_locally ();
- boost::shared_ptr<EncodedData> encode_remotely (boost::shared_ptr<const ServerDescription>);
+ boost::shared_ptr<EncodedData> encode_remotely (ServerDescription);
Eyes eyes () const {
return _eyes;
diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc
index a1c024799..29fe64e26 100644
--- a/src/lib/encoder.cc
+++ b/src/lib/encoder.cc
@@ -71,13 +71,13 @@ void
Encoder::process_begin ()
{
for (int i = 0; i < Config::instance()->num_local_encoding_threads (); ++i) {
- _threads.push_back (new boost::thread (boost::bind (&Encoder::encoder_thread, this, shared_ptr<ServerDescription> ())));
+ _threads.push_back (new boost::thread (boost::bind (&Encoder::encoder_thread, this, optional<ServerDescription> ())));
}
- vector<shared_ptr<ServerDescription> > servers = Config::instance()->servers ();
+ vector<ServerDescription> servers = Config::instance()->servers ();
- for (vector<shared_ptr<ServerDescription> >::iterator i = servers.begin(); i != servers.end(); ++i) {
- for (int j = 0; j < (*i)->threads (); ++j) {
+ for (vector<ServerDescription>::iterator i = servers.begin(); i != servers.end(); ++i) {
+ for (int j = 0; j < i->threads (); ++j) {
_threads.push_back (new boost::thread (boost::bind (&Encoder::encoder_thread, this, *i)));
}
}
@@ -244,7 +244,7 @@ Encoder::terminate_threads ()
}
void
-Encoder::encoder_thread (shared_ptr<ServerDescription> server)
+Encoder::encoder_thread (optional<ServerDescription> server)
{
/* Number of seconds that we currently wait between attempts
to connect to the server; not relevant for localhost
@@ -275,7 +275,7 @@ Encoder::encoder_thread (shared_ptr<ServerDescription> server)
if (server) {
try {
- encoded = vf->encode_remotely (server);
+ encoded = vf->encode_remotely (server.get ());
if (remote_backoff > 0) {
_film->log()->log (String::compose (N_("%1 was lost, but now she is found; removing backoff"), server->host_name ()));
diff --git a/src/lib/encoder.h b/src/lib/encoder.h
index a4df202a2..c0ea30fcb 100644
--- a/src/lib/encoder.h
+++ b/src/lib/encoder.h
@@ -81,7 +81,7 @@ private:
void frame_done ();
- void encoder_thread (boost::shared_ptr<ServerDescription>);
+ void encoder_thread (boost::optional<ServerDescription>);
void terminate_threads ();
/** Film that we are encoding */
diff --git a/src/lib/server.cc b/src/lib/server.cc
index 54cffc077..de265dca4 100644
--- a/src/lib/server.cc
+++ b/src/lib/server.cc
@@ -49,6 +49,7 @@ using boost::algorithm::split;
using boost::thread;
using boost::bind;
using boost::scoped_array;
+using boost::optional;
using libdcp::Size;
ServerDescription::ServerDescription (shared_ptr<const cxml::Node> node)
@@ -68,17 +69,17 @@ ServerDescription::as_xml (xmlpp::Node* root) const
* @param v Metadata.
* @return ServerDescription, or 0.
*/
-shared_ptr<ServerDescription>
+optional<ServerDescription>
ServerDescription::create_from_metadata (string v)
{
vector<string> b;
split (b, v, is_any_of (N_(" ")));
if (b.size() != 2) {
- return shared_ptr<ServerDescription> ();
+ return optional<ServerDescription> ();
}
- return shared_ptr<ServerDescription> (new ServerDescription (b[0], atoi (b[1].c_str ())));
+ return ServerDescription (b[0], atoi (b[1].c_str ()));
}
Server::Server (shared_ptr<Log> log)
diff --git a/src/lib/server.h b/src/lib/server.h
index 6307c1867..56a1fdab9 100644
--- a/src/lib/server.h
+++ b/src/lib/server.h
@@ -17,6 +17,9 @@
*/
+#ifndef DCPOMATIC_SERVER_H
+#define DCPOMATIC_SERVER_H
+
/** @file src/server.h
* @brief Class to describe a server to which we can send
* encoding work, and a class to implement such a server.
@@ -78,7 +81,7 @@ public:
void as_xml (xmlpp::Node *) const;
- static boost::shared_ptr<ServerDescription> create_from_metadata (std::string v);
+ static boost::optional<ServerDescription> create_from_metadata (std::string);
private:
/** server's host name */
@@ -104,3 +107,5 @@ private:
boost::condition _worker_condition;
boost::shared_ptr<Log> _log;
};
+
+#endif
diff --git a/src/lib/video_content.cc b/src/lib/video_content.cc
index f61518ec0..8b0ec4c99 100644
--- a/src/lib/video_content.cc
+++ b/src/lib/video_content.cc
@@ -23,14 +23,17 @@
#include "video_examiner.h"
#include "ratio.h"
#include "compose.hpp"
+#include "config.h"
+#include "colour_conversion.h"
#include "i18n.h"
-int const VideoContentProperty::VIDEO_SIZE = 0;
-int const VideoContentProperty::VIDEO_FRAME_RATE = 1;
-int const VideoContentProperty::VIDEO_FRAME_TYPE = 2;
-int const VideoContentProperty::VIDEO_CROP = 3;
-int const VideoContentProperty::VIDEO_RATIO = 4;
+int const VideoContentProperty::VIDEO_SIZE = 0;
+int const VideoContentProperty::VIDEO_FRAME_RATE = 1;
+int const VideoContentProperty::VIDEO_FRAME_TYPE = 2;
+int const VideoContentProperty::VIDEO_CROP = 3;
+int const VideoContentProperty::VIDEO_RATIO = 4;
+int const VideoContentProperty::COLOUR_CONVERSION = 5;
using std::string;
using std::stringstream;
@@ -46,6 +49,7 @@ VideoContent::VideoContent (shared_ptr<const Film> f, Time s, VideoContent::Fram
, _video_frame_rate (0)
, _video_frame_type (VIDEO_FRAME_TYPE_2D)
, _ratio (Ratio::from_id ("185"))
+ , _colour_conversion (Config::instance()->colour_conversions().front().conversion)
{
}
@@ -56,6 +60,7 @@ VideoContent::VideoContent (shared_ptr<const Film> f, boost::filesystem::path p)
, _video_frame_rate (0)
, _video_frame_type (VIDEO_FRAME_TYPE_2D)
, _ratio (Ratio::from_id ("185"))
+ , _colour_conversion (Config::instance()->colour_conversions().front().conversion)
{
}
@@ -76,6 +81,7 @@ VideoContent::VideoContent (shared_ptr<const Film> f, shared_ptr<const cxml::Nod
if (r) {
_ratio = Ratio::from_id (r.get ());
}
+ _colour_conversion = ColourConversion (node->node_child ("ColourConversion"));
}
void
@@ -94,6 +100,7 @@ VideoContent::as_xml (xmlpp::Node* node) const
if (_ratio) {
node->add_child("Ratio")->add_child_text (_ratio->id ());
}
+ _colour_conversion.as_xml (node->add_child("ColourConversion"));
}
void
@@ -257,3 +264,14 @@ VideoContent::video_size_after_3d_split () const
assert (false);
}
+
+void
+VideoContent::set_colour_conversion (ColourConversion c)
+{
+ {
+ boost::mutex::scoped_lock lm (_mutex);
+ _colour_conversion = c;
+ }
+
+ signal_changed (VideoContentProperty::COLOUR_CONVERSION);
+}
diff --git a/src/lib/video_content.h b/src/lib/video_content.h
index 97ef6a9fa..72c72625b 100644
--- a/src/lib/video_content.h
+++ b/src/lib/video_content.h
@@ -21,6 +21,7 @@
#define DCPOMATIC_VIDEO_CONTENT_H
#include "content.h"
+#include "colour_conversion.h"
class VideoExaminer;
class Ratio;
@@ -33,6 +34,7 @@ public:
static int const VIDEO_FRAME_TYPE;
static int const VIDEO_CROP;
static int const VIDEO_RATIO;
+ static int const COLOUR_CONVERSION;
};
class VideoContent : public virtual Content
@@ -71,6 +73,8 @@ public:
void set_top_crop (int);
void set_bottom_crop (int);
+ void set_colour_conversion (ColourConversion);
+
VideoFrameType video_frame_type () const {
boost::mutex::scoped_lock lm (_mutex);
return _video_frame_type;
@@ -88,6 +92,11 @@ public:
return _ratio;
}
+ ColourConversion colour_conversion () const {
+ boost::mutex::scoped_lock lm (_mutex);
+ return _colour_conversion;
+ }
+
libdcp::Size video_size_after_3d_split () const;
protected:
@@ -106,6 +115,7 @@ private:
VideoFrameType _video_frame_type;
Crop _crop;
Ratio const * _ratio;
+ ColourConversion _colour_conversion;
};
#endif