diff options
| author | Carl Hetherington <cth@carlh.net> | 2019-05-24 23:29:39 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2019-05-24 23:29:39 +0100 |
| commit | 92784c9c28c48859578cd6e75aa01d5657d0c341 (patch) | |
| tree | 595a34ecd2c59bf9d3dbcfa0c6f0a91b17ecfa5b /src/lib | |
| parent | 6c78f6d31a457ad34fb14b7c926fb418b4d6790d (diff) | |
Basic ability to set video range (JPEG/MPEG) at least for YUV content. May not work for RGB. See #1509.
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/dcp_examiner.h | 4 | ||||
| -rw-r--r-- | src/lib/ffmpeg_examiner.cc | 13 | ||||
| -rw-r--r-- | src/lib/ffmpeg_examiner.h | 2 | ||||
| -rw-r--r-- | src/lib/image.cc | 6 | ||||
| -rw-r--r-- | src/lib/image.h | 2 | ||||
| -rw-r--r-- | src/lib/image_examiner.h | 3 | ||||
| -rw-r--r-- | src/lib/player.cc | 2 | ||||
| -rw-r--r-- | src/lib/player_video.cc | 13 | ||||
| -rw-r--r-- | src/lib/player_video.h | 4 | ||||
| -rw-r--r-- | src/lib/types.h | 6 | ||||
| -rw-r--r-- | src/lib/video_content.cc | 25 | ||||
| -rw-r--r-- | src/lib/video_content.h | 11 | ||||
| -rw-r--r-- | src/lib/video_examiner.h | 1 | ||||
| -rw-r--r-- | src/lib/video_mxf_examiner.h | 3 |
14 files changed, 83 insertions, 12 deletions
diff --git a/src/lib/dcp_examiner.h b/src/lib/dcp_examiner.h index 199ac3985..da9092411 100644 --- a/src/lib/dcp_examiner.h +++ b/src/lib/dcp_examiner.h @@ -55,6 +55,10 @@ public: return false; } + VideoRange range () const { + return VIDEO_RANGE_FULL; + } + std::string name () const { return _name; } diff --git a/src/lib/ffmpeg_examiner.cc b/src/lib/ffmpeg_examiner.cc index a4c5eb128..3fb9a53e4 100644 --- a/src/lib/ffmpeg_examiner.cc +++ b/src/lib/ffmpeg_examiner.cc @@ -388,3 +388,16 @@ FFmpegExaminer::has_video () const { return static_cast<bool> (_video_stream); } + +VideoRange +FFmpegExaminer::range () const +{ + switch (color_range()) { + case AVCOL_RANGE_MPEG: + case AVCOL_RANGE_UNSPECIFIED: + return VIDEO_RANGE_VIDEO; + case AVCOL_RANGE_JPEG: + default: + return VIDEO_RANGE_FULL; + } +} diff --git a/src/lib/ffmpeg_examiner.h b/src/lib/ffmpeg_examiner.h index 1c0dad3dc..9ffb8421b 100644 --- a/src/lib/ffmpeg_examiner.h +++ b/src/lib/ffmpeg_examiner.h @@ -53,6 +53,8 @@ public: return _first_video; } + VideoRange range () const; + AVColorRange color_range () const { return video_codec_context()->color_range; } diff --git a/src/lib/image.cc b/src/lib/image.cc index c176c2d65..b473403e4 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -129,7 +129,7 @@ Image::planes () const */ shared_ptr<Image> Image::crop_scale_window ( - Crop crop, dcp::Size inter_size, dcp::Size out_size, dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast + Crop crop, dcp::Size inter_size, dcp::Size out_size, dcp::YUVToRGB yuv_to_rgb, VideoRange video_range, AVPixelFormat out_format, bool out_aligned, bool fast ) const { /* Empirical testing suggests that sws_scale() will crash if @@ -198,8 +198,8 @@ Image::crop_scale_window ( */ sws_setColorspaceDetails ( scale_context, - sws_getCoefficients (lut[yuv_to_rgb]), 0, - sws_getCoefficients (lut[yuv_to_rgb]), 0, + sws_getCoefficients (lut[yuv_to_rgb]), video_range == VIDEO_RANGE_VIDEO ? 0 : 1, + sws_getCoefficients (lut[yuv_to_rgb]), 1, 0, 1 << 16, 1 << 16 ); diff --git a/src/lib/image.h b/src/lib/image.h index dbcb38cc7..4b059ff36 100644 --- a/src/lib/image.h +++ b/src/lib/image.h @@ -63,7 +63,7 @@ public: boost::shared_ptr<Image> convert_pixel_format (dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool aligned, bool fast) const; boost::shared_ptr<Image> scale (dcp::Size out_size, dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool aligned, bool fast) const; boost::shared_ptr<Image> crop_scale_window ( - Crop crop, dcp::Size inter_size, dcp::Size out_size, dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool aligned, bool fast + Crop crop, dcp::Size inter_size, dcp::Size out_size, dcp::YUVToRGB yuv_to_rgb, VideoRange video_range, AVPixelFormat out_format, bool aligned, bool fast ) const; void make_black (); diff --git a/src/lib/image_examiner.h b/src/lib/image_examiner.h index 2e743a82e..ca8ecf9c8 100644 --- a/src/lib/image_examiner.h +++ b/src/lib/image_examiner.h @@ -36,6 +36,9 @@ public: return _video_length; } bool yuv () const; + VideoRange range () const { + return VIDEO_RANGE_FULL; + } private: boost::weak_ptr<const Film> _film; diff --git a/src/lib/player.cc b/src/lib/player.cc index e44edd8dc..f79e379d2 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -332,6 +332,7 @@ Player::black_player_video_frame (Eyes eyes) const eyes, PART_WHOLE, PresetColourConversion::all().front().conversion, + VIDEO_RANGE_FULL, boost::weak_ptr<Content>(), boost::optional<Frame>() ) @@ -826,6 +827,7 @@ Player::video (weak_ptr<Piece> wp, ContentVideo video) video.eyes, video.part, piece->content->video->colour_conversion(), + piece->content->video->range(), piece->content, video.frame ) diff --git a/src/lib/player_video.cc b/src/lib/player_video.cc index e36eb1984..75479136f 100644 --- a/src/lib/player_video.cc +++ b/src/lib/player_video.cc @@ -52,6 +52,7 @@ PlayerVideo::PlayerVideo ( Eyes eyes, Part part, optional<ColourConversion> colour_conversion, + VideoRange video_range, weak_ptr<Content> content, optional<Frame> video_frame ) @@ -63,6 +64,7 @@ PlayerVideo::PlayerVideo ( , _eyes (eyes) , _part (part) , _colour_conversion (colour_conversion) + , _video_range (video_range) , _content (content) , _video_frame (video_frame) { @@ -78,6 +80,7 @@ PlayerVideo::PlayerVideo (shared_ptr<cxml::Node> node, shared_ptr<Socket> socket _out_size = dcp::Size (node->number_child<int> ("OutWidth"), node->number_child<int> ("OutHeight")); _eyes = (Eyes) node->number_child<int> ("Eyes"); _part = (Part) node->number_child<int> ("Part"); + _video_range = (VideoRange) node->number_child<int>("VideoRange"); /* Assume that the ColourConversion uses the current state version */ _colour_conversion = ColourConversion::from_xml (node, Film::current_state_version); @@ -166,7 +169,7 @@ PlayerVideo::make_image (function<AVPixelFormat (AVPixelFormat)> pixel_format, b } _image = im->crop_scale_window ( - total_crop, _inter_size, _out_size, yuv_to_rgb, pixel_format (im->pixel_format()), aligned, fast + total_crop, _inter_size, _out_size, yuv_to_rgb, _video_range, pixel_format (im->pixel_format()), aligned, fast ); if (_text) { @@ -192,6 +195,7 @@ PlayerVideo::add_metadata (xmlpp::Node* node) const node->add_child("OutHeight")->add_child_text (raw_convert<string> (_out_size.height)); node->add_child("Eyes")->add_child_text (raw_convert<string> (static_cast<int> (_eyes))); node->add_child("Part")->add_child_text (raw_convert<string> (static_cast<int> (_part))); + node->add_child("VideoRange")->add_child_text(raw_convert<string>(static_cast<int>(_video_range))); if (_colour_conversion) { _colour_conversion.get().as_xml (node); } @@ -249,7 +253,8 @@ PlayerVideo::same (shared_ptr<const PlayerVideo> other) const _out_size != other->_out_size || _eyes != other->_eyes || _part != other->_part || - _colour_conversion != other->_colour_conversion) { + _colour_conversion != other->_colour_conversion || + _video_range != other->_video_range) { return false; } @@ -310,13 +315,14 @@ PlayerVideo::shallow_copy () const _eyes, _part, _colour_conversion, + _video_range, _content, _video_frame ) ); } -/** Re-read crop, fade, inter/out size and colour conversion from our content. +/** Re-read crop, fade, inter/out size, colour conversion and video range from our content. * @return true if this was possible, false if not. */ bool @@ -332,6 +338,7 @@ PlayerVideo::reset_metadata (shared_ptr<const Film> film, dcp::Size video_contai _inter_size = content->video->scale().size(content->video, video_container_size, film_frame_size); _out_size = video_container_size; _colour_conversion = content->video->colour_conversion(); + _video_range = content->video->range(); return true; } diff --git a/src/lib/player_video.h b/src/lib/player_video.h index c38d60641..3cd559409 100644 --- a/src/lib/player_video.h +++ b/src/lib/player_video.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2015 Carl Hetherington <cth@carlh.net> + Copyright (C) 2013-2019 Carl Hetherington <cth@carlh.net> This file is part of DCP-o-matic. @@ -54,6 +54,7 @@ public: Eyes, Part, boost::optional<ColourConversion>, + VideoRange video_range, boost::weak_ptr<Content>, boost::optional<Frame> ); @@ -117,6 +118,7 @@ private: Eyes _eyes; Part _part; boost::optional<ColourConversion> _colour_conversion; + VideoRange _video_range; boost::optional<PositionImage> _text; /** Content that we came from. This is so that reset_metadata() can work, and also * for variant:swaroop's non-skippable ads. diff --git a/src/lib/types.h b/src/lib/types.h index 94e101a3d..c9f68a21c 100644 --- a/src/lib/types.h +++ b/src/lib/types.h @@ -136,6 +136,12 @@ enum ChangeType CHANGE_TYPE_CANCELLED }; +enum VideoRange +{ + VIDEO_RANGE_FULL, ///< full, or "JPEG" (0-255 for 8-bit) + VIDEO_RANGE_VIDEO ///< video, or "MPEG" (16-235 for 8-bit) +}; + /** Type of captions. * * The generally accepted definitions seem to be: diff --git a/src/lib/video_content.cc b/src/lib/video_content.cc index d8d8adbf8..4eda7d967 100644 --- a/src/lib/video_content.cc +++ b/src/lib/video_content.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2016 Carl Hetherington <cth@carlh.net> + Copyright (C) 2013-2019 Carl Hetherington <cth@carlh.net> This file is part of DCP-o-matic. @@ -46,6 +46,7 @@ int const VideoContentProperty::SCALE = 3; int const VideoContentProperty::COLOUR_CONVERSION = 4; int const VideoContentProperty::FADE_IN = 5; int const VideoContentProperty::FADE_OUT = 6; +int const VideoContentProperty::RANGE = 7; using std::string; using std::setprecision; @@ -71,6 +72,7 @@ VideoContent::VideoContent (Content* parent) , _yuv (true) , _fade_in (0) , _fade_out (0) + , _range (VIDEO_RANGE_FULL) { } @@ -152,6 +154,11 @@ VideoContent::VideoContent (Content* parent, cxml::ConstNodePtr node, int versio } else { _fade_in = _fade_out = 0; } + + _range = VIDEO_RANGE_FULL; + if (node->optional_string_child("Range").get_value_or("full") == "video") { + _range = VIDEO_RANGE_VIDEO; + } } VideoContent::VideoContent (Content* parent, vector<shared_ptr<Content> > c) @@ -202,6 +209,7 @@ VideoContent::VideoContent (Content* parent, vector<shared_ptr<Content> > c) _colour_conversion = ref->colour_conversion (); _fade_in = ref->fade_in (); _fade_out = ref->fade_out (); + _range = ref->range (); } void @@ -223,6 +231,7 @@ VideoContent::as_xml (xmlpp::Node* node) const node->add_child("YUV")->add_child_text (_yuv ? "1" : "0"); node->add_child("FadeIn")->add_child_text (raw_convert<string> (_fade_in)); node->add_child("FadeOut")->add_child_text (raw_convert<string> (_fade_out)); + node->add_child("Range")->add_child_text(_range == VIDEO_RANGE_FULL ? "full" : "video"); } void @@ -233,10 +242,12 @@ VideoContent::take_from_examiner (shared_ptr<VideoExaminer> d) Frame vl = d->video_length (); optional<double> const ar = d->sample_aspect_ratio (); bool const yuv = d->yuv (); + VideoRange const range = d->range (); ChangeSignaller<Content> cc1 (_parent, VideoContentProperty::SIZE); ChangeSignaller<Content> cc2 (_parent, VideoContentProperty::SCALE); ChangeSignaller<Content> cc3 (_parent, ContentProperty::LENGTH); + ChangeSignaller<Content> cc4 (_parent, VideoContentProperty::RANGE); { boost::mutex::scoped_lock lm (_mutex); @@ -244,6 +255,7 @@ VideoContent::take_from_examiner (shared_ptr<VideoExaminer> d) _length = vl; _sample_aspect_ratio = ar; _yuv = yuv; + _range = range; if (Config::instance()->default_scale_to ()) { _scale = VideoContentScale (Config::instance()->default_scale_to ()); @@ -268,14 +280,15 @@ VideoContent::identifier () const { char buffer[256]; snprintf ( - buffer, sizeof(buffer), "%d_%d_%d_%d_%s_%" PRId64 "_%" PRId64, + buffer, sizeof(buffer), "%d_%d_%d_%d_%s_%" PRId64 "_%" PRId64 "_%d", crop().left, crop().right, crop().top, crop().bottom, scale().id().c_str(), _fade_in, - _fade_out + _fade_out, + _range == VIDEO_RANGE_FULL ? 0 : 1 ); string s (buffer); @@ -526,6 +539,12 @@ VideoContent::set_fade_out (Frame t) } void +VideoContent::set_range (VideoRange r) +{ + maybe_set (_range, r, VideoContentProperty::RANGE); +} + +void VideoContent::take_settings_from (shared_ptr<const VideoContent> c) { if (c->_colour_conversion) { diff --git a/src/lib/video_content.h b/src/lib/video_content.h index 3d07a0947..f5fb6c9ac 100644 --- a/src/lib/video_content.h +++ b/src/lib/video_content.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2016 Carl Hetherington <cth@carlh.net> + Copyright (C) 2013-2019 Carl Hetherington <cth@carlh.net> This file is part of DCP-o-matic. @@ -46,6 +46,7 @@ public: static int const COLOUR_CONVERSION; static int const FADE_IN; static int const FADE_OUT; + static int const RANGE; }; class VideoContent : public ContentPart, public boost::enable_shared_from_this<VideoContent> @@ -92,6 +93,8 @@ public: void set_fade_in (Frame); void set_fade_out (Frame); + void set_range (VideoRange); + VideoFrameType frame_type () const { boost::mutex::scoped_lock lm (_mutex); return _frame_type; @@ -153,6 +156,11 @@ public: return _fade_out; } + VideoRange range () const { + boost::mutex::scoped_lock lm (_mutex); + return _range; + } + dcp::Size size_after_3d_split () const; dcp::Size size_after_crop () const; @@ -194,6 +202,7 @@ private: bool _yuv; Frame _fade_in; Frame _fade_out; + VideoRange _range; }; #endif diff --git a/src/lib/video_examiner.h b/src/lib/video_examiner.h index dd5d08c9e..4e5c6dc0a 100644 --- a/src/lib/video_examiner.h +++ b/src/lib/video_examiner.h @@ -48,4 +48,5 @@ public: } /** @return true if this video is in YUV; must not be called if has_video() == false */ virtual bool yuv () const = 0; + virtual VideoRange range () const = 0; }; diff --git a/src/lib/video_mxf_examiner.h b/src/lib/video_mxf_examiner.h index 205daa361..ec2933c27 100644 --- a/src/lib/video_mxf_examiner.h +++ b/src/lib/video_mxf_examiner.h @@ -39,6 +39,9 @@ public: Frame video_length () const; boost::optional<double> sample_aspect_ratio () const; bool yuv () const; + VideoRange range () const { + return VIDEO_RANGE_FULL; + } private: boost::shared_ptr<dcp::PictureAsset> _asset; |
