summaryrefslogtreecommitdiff
path: root/src/lib/ffmpeg_image_proxy.cc
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2020-11-08 22:34:18 +0100
committerCarl Hetherington <cth@carlh.net>2020-11-16 01:40:36 +0100
commite64a1a9aae0200d14feed49a4c6cf537bf5708a4 (patch)
treeb1b01bb8e6f1872309eb246434120de3b769e9e5 /src/lib/ffmpeg_image_proxy.cc
parentf5608308b17c72b3ee459c805663e0103de1d2a4 (diff)
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.
Diffstat (limited to 'src/lib/ffmpeg_image_proxy.cc')
-rw-r--r--src/lib/ffmpeg_image_proxy.cc24
1 files changed, 19 insertions, 5 deletions
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 <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
+#include <libavutil/pixdesc.h>
}
DCPOMATIC_DISABLE_WARNINGS
#include <libxml++/libxml++.h>
@@ -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<cxml::Node>, shared_ptr<Socket> socket)
- : _pos (0)
+FFmpegImageProxy::FFmpegImageProxy (shared_ptr<cxml::Node> node, shared_ptr<Socket> 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<dcp::Size>) const
throw DecodeError (N_("could not decode video"));
}
- _image.reset (new Image (frame));
+ AVPixelFormat const pix_fmt = static_cast<AVPixelFormat>(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