Move ScopeGuard into libdcp.
[dcpomatic.git] / src / lib / video_content.cc
index 51d6ba418f8848e9d32862fc91da113bec60788a..6c3f23a5702ebd2735936c914b204bc8c366bfc4 100644 (file)
@@ -86,28 +86,25 @@ VideoContent::VideoContent (Content* parent)
 }
 
 
+/** @param video_range_hint Video range to use if none is given in the XML */
 shared_ptr<VideoContent>
-VideoContent::from_xml (Content* parent, cxml::ConstNodePtr node, int version)
+VideoContent::from_xml (Content* parent, cxml::ConstNodePtr node, int version, VideoRange video_range_hint)
 {
        if (!node->optional_number_child<int> ("VideoWidth")) {
                return {};
        }
 
-       return make_shared<VideoContent>(parent, node, version);
+       return make_shared<VideoContent>(parent, node, version, video_range_hint);
 }
 
-VideoContent::VideoContent (Content* parent, cxml::ConstNodePtr node, int version)
+
+/** @param video_range_hint Video range to use if none is given in the XML */
+VideoContent::VideoContent (Content* parent, cxml::ConstNodePtr node, int version, VideoRange video_range_hint)
        : ContentPart (parent)
 {
        _size.width = node->number_child<int> ("VideoWidth");
        _size.height = node->number_child<int> ("VideoHeight");
 
-       /* Backwards compatibility */
-       auto r = node->optional_number_child<double>("VideoFrameRate");
-       if (r) {
-               _parent->set_video_frame_rate (r.get ());
-       }
-
        _use = node->optional_bool_child("Use").get_value_or(true);
        _length = node->number_child<Frame> ("VideoLength");
 
@@ -185,8 +182,12 @@ VideoContent::VideoContent (Content* parent, cxml::ConstNodePtr node, int versio
                _fade_in = _fade_out = 0;
        }
 
-       _range = VideoRange::FULL;
-       if (node->optional_string_child("Range").get_value_or("full") == "video") {
+       auto video_range = node->optional_string_child("Range");
+       if (!video_range) {
+               _range = video_range_hint;
+       } else if (*video_range == "full") {
+               _range = VideoRange::FULL;
+       } else {
                _range = VideoRange::VIDEO;
        }
 
@@ -304,7 +305,7 @@ VideoContent::as_xml (xmlpp::Node* node) const
 }
 
 void
-VideoContent::take_from_examiner (shared_ptr<VideoExaminer> d)
+VideoContent::take_from_examiner(shared_ptr<const Film> film, shared_ptr<VideoExaminer> d)
 {
        /* These examiner calls could call other content methods which take a lock on the mutex */
        auto const vs = d->video_size ();
@@ -331,7 +332,7 @@ VideoContent::take_from_examiner (shared_ptr<VideoExaminer> d)
        LOG_GENERAL ("Video length obtained from header as %1 frames", _length);
 
        if (d->video_frame_rate()) {
-               _parent->set_video_frame_rate (d->video_frame_rate().get());
+               _parent->set_video_frame_rate(film, d->video_frame_rate().get());
        }
 }
 
@@ -522,6 +523,12 @@ VideoContent::set_length (Frame len)
        maybe_set (_length, len, ContentProperty::LENGTH);
 }
 
+void
+VideoContent::set_crop (Crop c)
+{
+       maybe_set (_crop, c, VideoContentProperty::CROP);
+}
+
 void
 VideoContent::set_left_crop (int c)
 {
@@ -616,6 +623,7 @@ VideoContent::take_settings_from (shared_ptr<const VideoContent> c)
        set_fade_in (c->_fade_in);
        set_fade_out (c->_fade_out);
        set_burnt_subtitle_language (c->_burnt_subtitle_language);
+       set_range(c->_range);
 }
 
 
@@ -643,11 +651,14 @@ VideoContent::scaled_size (dcp::Size film_container)
        }
 
        if (_custom_size) {
-               return *_custom_size;
+               if (_custom_size->width <= film_container.width && _custom_size->height <= film_container.height) {
+                       return *_custom_size;
+               }
+               return fit_ratio_within(_custom_size->ratio(), film_container);
        }
 
        auto size = size_after_crop ();
-       size.width *= _sample_aspect_ratio.get_value_or(1);
+       size.width = std::lrint(size.width * _sample_aspect_ratio.get_value_or(1));
 
        /* This is what we will return unless there is any legacy stuff to take into account */
        auto auto_size = fit_ratio_within (size.ratio(), film_container);