diff options
| -rw-r--r-- | src/lib/colour_conversion.cc | 14 | ||||
| -rw-r--r-- | src/lib/mpeg2_encoder.cc | 20 | ||||
| -rw-r--r-- | src/wx/colour_conversion_editor.cc | 12 | ||||
| -rw-r--r-- | src/wx/colour_conversion_editor.h | 1 | ||||
| -rw-r--r-- | test/colour_conversion_test.cc | 2 |
5 files changed, 48 insertions, 1 deletions
diff --git a/src/lib/colour_conversion.cc b/src/lib/colour_conversion.cc index b5d6cd4c5..5dc633f60 100644 --- a/src/lib/colour_conversion.cc +++ b/src/lib/colour_conversion.cc @@ -138,6 +138,12 @@ ColourConversion::ColourConversion(cxml::NodePtr node, int version) } else { _out_j2k = make_shared<dcp::IdentityTransferFunction>(); } + + if (auto mpeg2_gamma = node->optional_number_child<double>("OutputMPEG2Gamma")) { + _out_mpeg2 = make_shared<dcp::GammaTransferFunction>(*mpeg2_gamma); + } else { + _out_mpeg2 = make_shared<dcp::IdentityTransferFunction>(); + } } boost::optional<ColourConversion> @@ -186,6 +192,10 @@ ColourConversion::as_xml(xmlpp::Element* element) const if (auto gf = dynamic_pointer_cast<const dcp::GammaTransferFunction>(_out_j2k)) { cxml::add_text_child(element, "OutputGamma", fmt::to_string(gf->gamma())); } + + if (auto gf = dynamic_pointer_cast<const dcp::GammaTransferFunction>(_out_mpeg2)) { + cxml::add_text_child(element, "OutputMPEG2Gamma", fmt::to_string(gf->gamma())); + } } optional<size_t> @@ -240,6 +250,10 @@ ColourConversion::identifier() const digester.add(gf->gamma()); } + if (auto gf = dynamic_pointer_cast<const dcp::GammaTransferFunction>(_out_mpeg2)) { + digester.add(gf->gamma()); + } + return digester.get(); } diff --git a/src/lib/mpeg2_encoder.cc b/src/lib/mpeg2_encoder.cc index 38388431d..c9ee6c491 100644 --- a/src/lib/mpeg2_encoder.cc +++ b/src/lib/mpeg2_encoder.cc @@ -22,6 +22,7 @@ #include "mpeg2_encoder.h" #include "writer.h" #include <dcp/ffmpeg_image.h> +#include <dcp/transfer_function.h> extern "C" { #include <libavutil/pixfmt.h> } @@ -43,7 +44,24 @@ MPEG2Encoder::encode(shared_ptr<PlayerVideo> pv, dcpomatic::DCPTime time) { VideoEncoder::encode(pv, time); - auto image = pv->image(force(AV_PIX_FMT_YUV420P), VideoRange::VIDEO, false); + shared_ptr<Image> image; + + if (auto conversion = pv->colour_conversion()) { + if (!conversion->in()->about_equal(conversion->out_mpeg2(), 0.05)) { + image = pv->image([](AVPixelFormat) { return AV_PIX_FMT_RGB24; }, VideoRange::VIDEO, Image::Alignment::PADDED, false); + dcp::convert_rgb_gamma(image->data()[0], image->size(), image->stride()[0], *conversion); + image = image->convert_pixel_format(conversion->yuv_to_rgb(), AV_PIX_FMT_YUV420P, Image::Alignment::COMPACT, false); + } + } + + if (!image) { + image = pv->image( + [](AVPixelFormat) { return AV_PIX_FMT_YUV420P; }, + VideoRange::VIDEO, + Image::Alignment::COMPACT, + false + ); + } dcp::FFmpegImage ffmpeg_image(time.get() * _film->video_frame_rate() / dcpomatic::DCPTime::HZ); diff --git a/src/wx/colour_conversion_editor.cc b/src/wx/colour_conversion_editor.cc index a16b7066f..83dbf67b7 100644 --- a/src/wx/colour_conversion_editor.cc +++ b/src/wx/colour_conversion_editor.cc @@ -216,6 +216,10 @@ ColourConversionEditor::ColourConversionEditor (wxWindow* parent, bool yuv) table->Add(_output_j2k, wxGBPosition(r, 0), wxGBSpan(1, 2)); ++r; + _output_mpeg2 = new CheckBox(this, _("Inverse 2.4 gamma correction on output to MPEG2")); + table->Add(_output_mpeg2, wxGBPosition(r, 0), wxGBSpan(1, 2)); + ++r; + _input_gamma->SetRange (0.1, 4.0); _input_gamma->SetDigits (2); _input_gamma->SetIncrement (0.1); @@ -242,6 +246,7 @@ ColourConversionEditor::ColourConversionEditor (wxWindow* parent, bool yuv) _adjusted_white_y->Bind (wxEVT_TEXT, bind (&ColourConversionEditor::adjusted_white_changed, this)); _yuv_to_rgb->Bind (wxEVT_CHOICE, bind (&ColourConversionEditor::changed, this)); _output_j2k->bind(&ColourConversionEditor::changed, this); + _output_mpeg2->bind(&ColourConversionEditor::changed, this); } @@ -313,6 +318,7 @@ ColourConversionEditor::set (ColourConversion conversion) } _output_j2k->SetValue(static_cast<bool>(dynamic_pointer_cast<const dcp::GammaTransferFunction>(conversion.out_j2k()))); + _output_mpeg2->SetValue(static_cast<bool>(dynamic_pointer_cast<const dcp::GammaTransferFunction>(conversion.out_mpeg2()))); update_rgb_to_xyz (); update_bradford (); @@ -380,6 +386,12 @@ ColourConversionEditor::get () const conversion.set_out_j2k(make_shared<dcp::IdentityTransferFunction>()); } + if (_output_mpeg2->GetValue()) { + conversion.set_out_mpeg2(make_shared<dcp::GammaTransferFunction>(2.4)); + } else { + conversion.set_out_mpeg2(make_shared<dcp::IdentityTransferFunction>()); + } + return conversion; } diff --git a/src/wx/colour_conversion_editor.h b/src/wx/colour_conversion_editor.h index ac2273540..6ec524992 100644 --- a/src/wx/colour_conversion_editor.h +++ b/src/wx/colour_conversion_editor.h @@ -83,6 +83,7 @@ private: wxTextCtrl* _adjusted_white_x; wxTextCtrl* _adjusted_white_y; CheckBox* _output_j2k; + CheckBox* _output_mpeg2; wxStaticText* _rgb_to_xyz[3][3]; wxStaticText* _bradford[3][3]; }; diff --git a/test/colour_conversion_test.cc b/test/colour_conversion_test.cc index db33a2b37..765ad491a 100644 --- a/test/colour_conversion_test.cc +++ b/test/colour_conversion_test.cc @@ -74,6 +74,7 @@ BOOST_AUTO_TEST_CASE (colour_conversion_test2) " <WhiteX>0.3127</WhiteX>\n" " <WhiteY>0.329</WhiteY>\n" " <OutputGamma>2.6</OutputGamma>\n" + " <OutputMPEG2Gamma>2.4</OutputMPEG2Gamma>\n" "</Test>\n" ); } @@ -103,6 +104,7 @@ BOOST_AUTO_TEST_CASE (colour_conversion_test3) " <WhiteX>0.3127</WhiteX>\n" " <WhiteY>0.329</WhiteY>\n" " <OutputGamma>2.6</OutputGamma>\n" + " <OutputMPEG2Gamma>2.4</OutputMPEG2Gamma>\n" "</Test>\n" ); } |
