2014-10-24 Carl Hetherington <cth@carlh.net>
+ * Experimental support for bypassing colourspace conversion (#266).
+
* Version 1.76.6 released.
2014-10-23 Carl Hetherington <cth@carlh.net>
def dependencies(target):
return (('ffmpeg-cdist', '2dffa11'),
- ('libdcp', 'd5accd6'))
+ ('libdcp', '0073935'))
def build(target, options):
cmd = './waf configure --prefix=%s' % target.directory
output_gamma = node->number_child<double> ("OutputGamma");
}
+boost::optional<ColourConversion>
+ColourConversion::from_xml (cxml::NodePtr node)
+{
+ if (!node->optional_node_child ("InputGamma")) {
+ return boost::optional<ColourConversion> ();
+ }
+
+ return ColourConversion (node);
+}
+
void
ColourConversion::as_xml (xmlpp::Node* node) const
{
boost::optional<size_t> preset () const;
+ static boost::optional<ColourConversion> from_xml (cxml::NodePtr);
+
double input_gamma;
bool input_gamma_linearised;
boost::numeric::ublas::matrix<double> matrix;
shared_ptr<EncodedData>
DCPVideoFrame::encode_locally ()
{
- shared_ptr<libdcp::LUT> in_lut;
- if (_frame->colour_conversion().input_gamma_linearised) {
- in_lut = libdcp::SRGBLinearisedGammaLUT::cache.get (12, _frame->colour_conversion().input_gamma);
- } else {
- in_lut = libdcp::GammaLUT::cache.get (12, _frame->colour_conversion().input_gamma);
- }
-
- /* XXX: libdcp should probably use boost */
-
- double matrix[3][3];
- for (int i = 0; i < 3; ++i) {
- for (int j = 0; j < 3; ++j) {
- matrix[i][j] = _frame->colour_conversion().matrix (i, j);
+ shared_ptr<libdcp::XYZFrame> xyz;
+
+ if (_frame->colour_conversion()) {
+ ColourConversion conversion = _frame->colour_conversion().get ();
+ shared_ptr<libdcp::LUT> in_lut;
+ if (conversion.input_gamma_linearised) {
+ in_lut = libdcp::SRGBLinearisedGammaLUT::cache.get (12, conversion.input_gamma);
+ } else {
+ in_lut = libdcp::GammaLUT::cache.get (12, conversion.input_gamma);
+ }
+
+ /* XXX: libdcp should probably use boost */
+
+ double matrix[3][3];
+ for (int i = 0; i < 3; ++i) {
+ for (int j = 0; j < 3; ++j) {
+ matrix[i][j] = conversion.matrix (i, j);
+ }
}
+
+ xyz = libdcp::rgb_to_xyz (
+ _frame->image(AV_PIX_FMT_RGB48LE),
+ in_lut,
+ libdcp::GammaLUT::cache.get (16, 1 / conversion.output_gamma),
+ matrix
+ );
+ } else {
+ xyz = libdcp::xyz_to_xyz (_frame->image (AV_PIX_FMT_RGB48LE));
}
- shared_ptr<libdcp::XYZFrame> xyz = libdcp::rgb_to_xyz (
- _frame->image(AV_PIX_FMT_RGB48LE),
- in_lut,
- libdcp::GammaLUT::cache.get (16, 1 / _frame->colour_conversion().output_gamma),
- matrix
- );
-
/* Set the max image and component sizes based on frame_rate */
int max_cs_len = ((float) _j2k_bandwidth) / 8 / _frames_per_second;
if (_frame->eyes() == EYES_LEFT || _frame->eyes() == EYES_RIGHT) {
Scaler const * scaler,
Eyes eyes,
Part part,
- ColourConversion colour_conversion
+ boost::optional<ColourConversion> colour_conversion
)
: _in (in)
, _crop (crop)
_scaler = Scaler::from_id (node->string_child ("Scaler"));
_eyes = (Eyes) node->number_child<int> ("Eyes");
_part = (Part) node->number_child<int> ("Part");
- _colour_conversion = ColourConversion (node);
+ _colour_conversion = ColourConversion::from_xml (node);
_in = image_proxy_factory (node->node_child ("In"), socket, log);
node->add_child("Scaler")->add_child_text (_scaler->id ());
node->add_child("Eyes")->add_child_text (raw_convert<string> (_eyes));
node->add_child("Part")->add_child_text (raw_convert<string> (_part));
- _colour_conversion.as_xml (node);
+ if (_colour_conversion) {
+ _colour_conversion.get().as_xml (node);
+ }
if (_subtitle_image) {
node->add_child ("SubtitleWidth")->add_child_text (raw_convert<string> (_subtitle_image->size().width));
node->add_child ("SubtitleHeight")->add_child_text (raw_convert<string> (_subtitle_image->size().height));
class PlayerVideoFrame
{
public:
- PlayerVideoFrame (boost::shared_ptr<const ImageProxy>, Crop, libdcp::Size, libdcp::Size, Scaler const *, Eyes, Part, ColourConversion);
+ PlayerVideoFrame (boost::shared_ptr<const ImageProxy>, Crop, libdcp::Size, libdcp::Size, Scaler const *, Eyes, Part, boost::optional<ColourConversion>);
PlayerVideoFrame (boost::shared_ptr<cxml::Node>, boost::shared_ptr<Socket>, boost::shared_ptr<Log>);
void set_subtitle (boost::shared_ptr<const Image>, Position<int>);
return _eyes;
}
- ColourConversion colour_conversion () const {
+ boost::optional<ColourConversion> colour_conversion () const {
return _colour_conversion;
}
Scaler const * _scaler;
Eyes _eyes;
Part _part;
- ColourConversion _colour_conversion;
+ boost::optional<ColourConversion> _colour_conversion;
boost::shared_ptr<const Image> _subtitle_image;
Position<int> _subtitle_position;
};
, _video_frame_type (VIDEO_FRAME_TYPE_2D)
, _scale (Config::instance()->default_scale ())
{
- setup_default_colour_conversion ();
+ set_default_colour_conversion ();
}
VideoContent::VideoContent (shared_ptr<const Film> f, Time s, VideoContent::Frame len)
, _video_frame_type (VIDEO_FRAME_TYPE_2D)
, _scale (Config::instance()->default_scale ())
{
- setup_default_colour_conversion ();
+ set_default_colour_conversion ();
}
VideoContent::VideoContent (shared_ptr<const Film> f, boost::filesystem::path p)
, _video_frame_type (VIDEO_FRAME_TYPE_2D)
, _scale (Config::instance()->default_scale ())
{
- setup_default_colour_conversion ();
+ set_default_colour_conversion ();
}
VideoContent::VideoContent (shared_ptr<const Film> f, shared_ptr<const cxml::Node> node, int version)
} else {
_scale = VideoContentScale (node->node_child ("Scale"));
}
-
- _colour_conversion = ColourConversion (node->node_child ("ColourConversion"));
+
+ if (node->optional_node_child ("ColourConversion")) {
+ _colour_conversion = ColourConversion (node->node_child ("ColourConversion"));
+ }
}
VideoContent::VideoContent (shared_ptr<const Film> f, vector<shared_ptr<Content> > c)
node->add_child("VideoFrameType")->add_child_text (raw_convert<string> (static_cast<int> (_video_frame_type)));
_crop.as_xml (node);
_scale.as_xml (node->add_child("Scale"));
- _colour_conversion.as_xml (node->add_child("ColourConversion"));
+ if (_colour_conversion) {
+ _colour_conversion.get().as_xml (node->add_child("ColourConversion"));
+ }
}
void
-VideoContent::setup_default_colour_conversion ()
+VideoContent::set_default_colour_conversion ()
{
- _colour_conversion = PresetColourConversion (_("sRGB"), 2.4, true, libdcp::colour_matrix::srgb_to_xyz, 2.6).conversion;
+ set_colour_conversion (PresetColourConversion (_("sRGB"), 2.4, true, libdcp::colour_matrix::srgb_to_xyz, 2.6).conversion);
}
void
<< "_" << crop().right
<< "_" << crop().top
<< "_" << crop().bottom
- << "_" << scale().id()
- << "_" << colour_conversion().identifier ();
+ << "_" << scale().id();
+
+ if (colour_conversion()) {
+ s << "_" << colour_conversion().get().identifier ();
+ }
return s.str ();
}
assert (false);
}
+void
+VideoContent::unset_colour_conversion ()
+{
+ {
+ boost::mutex::scoped_lock lm (_mutex);
+ _colour_conversion = boost::optional<ColourConversion> ();
+ }
+
+ signal_changed (VideoContentProperty::COLOUR_CONVERSION);
+}
+
void
VideoContent::set_colour_conversion (ColourConversion c)
{
void set_bottom_crop (int);
void set_scale (VideoContentScale);
+ void unset_colour_conversion ();
void set_colour_conversion (ColourConversion);
+ void set_default_colour_conversion ();
VideoFrameType video_frame_type () const {
boost::mutex::scoped_lock lm (_mutex);
return _scale;
}
- ColourConversion colour_conversion () const {
+ boost::optional<ColourConversion> colour_conversion () const {
boost::mutex::scoped_lock lm (_mutex);
return _colour_conversion;
}
friend class best_dcp_frame_rate_test_double;
friend class audio_sampling_rate_test;
- void setup_default_colour_conversion ();
-
libdcp::Size _video_size;
VideoFrameType _video_frame_type;
Crop _crop;
VideoContentScale _scale;
- ColourConversion _colour_conversion;
+ boost::optional<ColourConversion> _colour_conversion;
};
#endif
wxSizer* s = new wxBoxSizer (wxHORIZONTAL);
wxClientDC dc (this);
- wxSize size = dc.GetTextExtent (wxT ("A quite long name"));
+ wxSize size = dc.GetTextExtent (wxT ("A quite long-ish name"));
size.SetHeight (-1);
_filters = new wxStaticText (this, wxID_ANY, _("None"), wxDefaultPosition, size);
++r;
{
- add_label_to_grid_bag_sizer (grid, this, _("Colour conversion"), true, wxGBPosition (r, 0));
+ _enable_colour_conversion = new wxCheckBox (this, wxID_ANY, _("Colour conversion"));
+ grid->Add (_enable_colour_conversion, wxGBPosition (r, 0), wxDefaultSpan, wxALIGN_CENTER_VERTICAL);
+
wxSizer* s = new wxBoxSizer (wxHORIZONTAL);
wxClientDC dc (this);
- wxSize size = dc.GetTextExtent (wxT ("A quite long name"));
+ wxSize size = dc.GetTextExtent (wxT ("A quite long-ish name"));
size.SetHeight (-1);
_colour_conversion = new wxStaticText (this, wxID_ANY, wxT (""), wxDefaultPosition, size);
_frame_type->wrapped()->Append (_("3D right only"));
_filters_button->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&VideoPanel::edit_filters_clicked, this));
+ _enable_colour_conversion->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&VideoPanel::enable_colour_conversion_clicked, this));
_colour_conversion_button->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&VideoPanel::edit_colour_conversion_clicked, this));
}
} else if (property == VideoContentProperty::VIDEO_FRAME_RATE) {
setup_description ();
} else if (property == VideoContentProperty::COLOUR_CONVERSION) {
- optional<size_t> preset = vcs ? vcs->colour_conversion().preset () : optional<size_t> ();
- vector<PresetColourConversion> cc = Config::instance()->colour_conversions ();
- _colour_conversion->SetLabel (preset ? std_to_wx (cc[preset.get()].name) : _("Custom"));
+ if (!vcs) {
+ _colour_conversion->SetLabel (wxT (""));
+ } else if (vcs->colour_conversion ()) {
+ optional<size_t> preset = vcs->colour_conversion().get().preset ();
+ vector<PresetColourConversion> cc = Config::instance()->colour_conversions ();
+ _colour_conversion->SetLabel (preset ? std_to_wx (cc[preset.get()].name) : _("Custom"));
+ _enable_colour_conversion->SetValue (true);
+ _colour_conversion->Enable (true);
+ _colour_conversion_button->Enable (true);
+ } else {
+ _colour_conversion->SetLabel (_("None"));
+ _enable_colour_conversion->SetValue (false);
+ _colour_conversion->Enable (false);
+ _colour_conversion_button->Enable (false);
+ }
} else if (property == FFmpegContentProperty::FILTERS) {
if (fcs) {
string const p = Filter::ffmpeg_string (fcs->filters ());
return;
}
- ColourConversion conversion = vc.front()->colour_conversion ();
+ if (!vc.front()->colour_conversion ()) {
+ return;
+ }
+
+ ColourConversion conversion = vc.front()->colour_conversion().get ();
ContentColourConversionDialog* d = new ContentColourConversionDialog (this);
d->set (conversion);
d->ShowModal ();
film_content_changed (VideoContentProperty::COLOUR_CONVERSION);
film_content_changed (FFmpegContentProperty::FILTERS);
}
+
+void
+VideoPanel::enable_colour_conversion_clicked ()
+{
+ VideoContentList vc = _editor->selected_video_content ();
+ if (vc.size() != 1) {
+ return;
+ }
+
+ if (_enable_colour_conversion->GetValue()) {
+ vc.front()->set_default_colour_conversion ();
+ } else {
+ vc.front()->unset_colour_conversion ();
+ }
+}
private:
void edit_filters_clicked ();
+ void enable_colour_conversion_clicked ();
void edit_colour_conversion_clicked ();
void setup_description ();
wxStaticText* _description;
wxStaticText* _filters;
wxButton* _filters_button;
+ wxCheckBox* _enable_colour_conversion;
wxStaticText* _colour_conversion;
wxButton* _colour_conversion_button;
};