diff options
| author | Carl Hetherington <cth@carlh.net> | 2013-08-17 21:47:08 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2013-08-17 21:47:08 +0100 |
| commit | 2499c41097f8410cb3016e095a85d68979485a7b (patch) | |
| tree | 331a23489d3be42ede2861311a797792ba663805 /src/lib | |
| parent | 89af81886eeee57861bc23984a0583bec76d536d (diff) | |
Various bits mostly related to colour conversions.
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/colour_conversion.cc | 96 | ||||
| -rw-r--r-- | src/lib/colour_conversion.h | 35 | ||||
| -rw-r--r-- | src/lib/config.cc | 26 | ||||
| -rw-r--r-- | src/lib/config.h | 15 | ||||
| -rw-r--r-- | src/lib/dcp_video_frame.cc | 4 | ||||
| -rw-r--r-- | src/lib/dcp_video_frame.h | 2 | ||||
| -rw-r--r-- | src/lib/encoder.cc | 12 | ||||
| -rw-r--r-- | src/lib/encoder.h | 2 | ||||
| -rw-r--r-- | src/lib/server.cc | 7 | ||||
| -rw-r--r-- | src/lib/server.h | 7 | ||||
| -rw-r--r-- | src/lib/video_content.cc | 28 | ||||
| -rw-r--r-- | src/lib/video_content.h | 10 |
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 |
