From e64a1a9aae0200d14feed49a4c6cf537bf5708a4 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 8 Nov 2020 22:34:18 +0100 Subject: Obey requests to change the video range of RGB content. Video that comes in with RGB pixels will not have its video level ranges changed by libswscale (it only does this for YUV and greyscale). Here we add code to do it ourselves for RGB content coming in via image files (e.g. PNG/DPX etc). Part of #1851. --- src/lib/ffmpeg_image_proxy.cc | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'src/lib/ffmpeg_image_proxy.cc') diff --git a/src/lib/ffmpeg_image_proxy.cc b/src/lib/ffmpeg_image_proxy.cc index 602185bb8..c978fc383 100644 --- a/src/lib/ffmpeg_image_proxy.cc +++ b/src/lib/ffmpeg_image_proxy.cc @@ -30,6 +30,7 @@ extern "C" { #include #include +#include } DCPOMATIC_DISABLE_WARNINGS #include @@ -48,23 +49,26 @@ using boost::optional; using boost::dynamic_pointer_cast; using dcp::raw_convert; -FFmpegImageProxy::FFmpegImageProxy (boost::filesystem::path path) +FFmpegImageProxy::FFmpegImageProxy (boost::filesystem::path path, VideoRange video_range) : _data (path) + , _video_range (video_range) , _pos (0) , _path (path) { } -FFmpegImageProxy::FFmpegImageProxy (dcp::ArrayData data) +FFmpegImageProxy::FFmpegImageProxy (dcp::ArrayData data, VideoRange video_range) : _data (data) + , _video_range (video_range) , _pos (0) { } -FFmpegImageProxy::FFmpegImageProxy (shared_ptr, shared_ptr socket) - : _pos (0) +FFmpegImageProxy::FFmpegImageProxy (shared_ptr node, shared_ptr socket) + : _video_range (string_to_video_range(node->string_child("VideoRange"))) + , _pos (0) { uint32_t const size = socket->read_uint32 (); _data = dcp::ArrayData (size); @@ -188,7 +192,16 @@ FFmpegImageProxy::image (optional) const throw DecodeError (N_("could not decode video")); } - _image.reset (new Image (frame)); + AVPixelFormat const pix_fmt = static_cast(frame->format); + + _image.reset (new Image(frame)); + if (_video_range == VIDEO_RANGE_VIDEO && av_pix_fmt_desc_get(pix_fmt)->flags & AV_PIX_FMT_FLAG_RGB) { + /* Asking for the video range to be converted by libswscale (in Image) will not work for + * RGB sources since that method only processes video range in YUV and greyscale. So we have + * to do it ourselves here. + */ + _image->video_range_to_full_range(); + } av_packet_unref (&packet); av_frame_free (&frame); @@ -206,6 +219,7 @@ void FFmpegImageProxy::add_metadata (xmlpp::Node* node) const { node->add_child("Type")->add_child_text (N_("FFmpeg")); + node->add_child("VideoRange")->add_child_text(video_range_to_string(_video_range)); } void -- cgit v1.2.3