Make DCPExaminer::size() optional and deal with the consequences. v2.16.78
authorCarl Hetherington <cth@carlh.net>
Wed, 21 Feb 2024 09:47:38 +0000 (10:47 +0100)
committerCarl Hetherington <cth@carlh.net>
Wed, 21 Feb 2024 17:48:53 +0000 (18:48 +0100)
This means we can fix the case of a VF having no known size in a nice way,
in turn fixing problems caused by the fix to #2775.

26 files changed:
src/lib/copy_dcp_details_to_film.cc
src/lib/dcp_content.cc
src/lib/dcp_examiner.h
src/lib/ffmpeg_content.cc
src/lib/ffmpeg_decoder.cc
src/lib/ffmpeg_examiner.cc
src/lib/ffmpeg_examiner.h
src/lib/film.cc
src/lib/hints.cc
src/lib/image_decoder.cc
src/lib/image_examiner.cc
src/lib/image_examiner.h
src/lib/player.cc
src/lib/player_video.cc
src/lib/video_content.cc
src/lib/video_content.h
src/lib/video_examiner.h
src/lib/video_mxf_examiner.cc
src/lib/video_mxf_examiner.h
src/tools/dcpomatic_cli.cc
src/tools/dcpomatic_player.cc
src/wx/content_menu.cc
src/wx/player_information.cc
src/wx/video_panel.cc
test/dcp_examiner_test.cc
test/video_content_scale_test.cc

index 669fc8ac9df9313b814be9fd710626f8f415b864..f6ca08638ee32aca807e6e80be8f1e9cb4db9834 100644 (file)
@@ -51,7 +51,9 @@ copy_dcp_settings_to_film(shared_ptr<const DCPContent> dcp, shared_ptr<Film> fil
        film->set_three_d (dcp->three_d());
 
        if (dcp->video) {
-               film->set_container (Ratio::nearest_from_ratio(dcp->video->size().ratio()));
+               if (auto size = dcp->video->size()) {
+                       film->set_container(Ratio::nearest_from_ratio(size->ratio()));
+               }
                film->set_resolution (dcp->resolution());
                DCPOMATIC_ASSERT (dcp->video_frame_rate());
                film->set_video_frame_rate (*dcp->video_frame_rate());
index e22f69f56c62b8373b58e60dc04fb8d81d311a12..6185b3a19db2cfbd4e49474794b3b3057154022a 100644 (file)
@@ -830,7 +830,7 @@ DCPContent::kdm_timing_window_valid () const
 Resolution
 DCPContent::resolution () const
 {
-       if (video->size().width > 2048 || video->size().height > 1080) {
+       if (video->size() && (video->size()->width > 2048 || video->size()->height > 1080)) {
                return Resolution::FOUR_K;
        }
 
index 444fb7567f6947098645591802da349f54aaacac..04fa31ea4281c611e16ed237616aff749d76e328 100644 (file)
@@ -48,10 +48,8 @@ public:
                return _video_frame_rate;
        }
 
-       dcp::Size video_size () const override {
-               DCPOMATIC_ASSERT (_has_video);
-               DCPOMATIC_ASSERT (_video_size);
-               return *_video_size;
+       boost::optional<dcp::Size> video_size() const override {
+               return _video_size;
        }
 
        Frame video_length () const override {
index 20fe7776bd9aafb80ca12c0fbd035875c0551aaf..c788e7cb1d271296fd201477f9e0e6631de0c32b 100644 (file)
@@ -521,7 +521,7 @@ FFmpegContent::set_default_colour_conversion ()
                video->set_colour_conversion (PresetColourConversion::from_id ("rec2020").conversion);
                break;
        default:
-               if (s.width < 1080) {
+               if (s && s->width < 1080) {
                        video->set_colour_conversion (PresetColourConversion::from_id ("rec601").conversion);
                } else {
                        video->set_colour_conversion (PresetColourConversion::from_id ("rec709").conversion);
index 0d43156c0cdefd3fcd83842c47a0b8ef27bf916b..7f7a078638b540ba81bbbe38c5ad260970232fa0 100644 (file)
@@ -828,11 +828,14 @@ FFmpegDecoder::process_ass_subtitle (string ass, ContentTime from)
        }
 
        sub::RawSubtitle base;
+       auto video_size = _ffmpeg_content->video->size();
+       DCPOMATIC_ASSERT(video_size);
+
        auto raw = sub::SSAReader::parse_line (
                base,
                text,
-               _ffmpeg_content->video->size().width,
-               _ffmpeg_content->video->size().height,
+               video_size->width,
+               video_size->height,
                sub::Colour(1, 1, 1)
                );
 
index ed6f210945960503ac303effc8d731af4554e4d2..15cb14ad53301605df3e96ec4398f7ffdce55b8c 100644 (file)
@@ -305,7 +305,7 @@ FFmpegExaminer::video_frame_rate () const
 }
 
 
-dcp::Size
+optional<dcp::Size>
 FFmpegExaminer::video_size () const
 {
        return dcp::Size (video_codec_context()->width, video_codec_context()->height);
index 4747929b594571caf08775d5baea04c2a2261639..45313ec18cc22f501bf626c74f6bb5459d4a18e4 100644 (file)
@@ -38,7 +38,7 @@ public:
        bool has_video () const override;
 
        boost::optional<double> video_frame_rate () const override;
-       dcp::Size video_size () const override;
+       boost::optional<dcp::Size> video_size() const override;
        Frame video_length () const override;
        boost::optional<double> sample_aspect_ratio () const override;
        bool yuv () const override;
index 0bba13e2802c369504e973262b7140f0b306c8d4..d9ab6e2a3f8a2e4df368a6eece61ae2b37187b44 100644 (file)
@@ -943,10 +943,12 @@ Film::isdcf_name (bool if_created_now) const
        if (dcp_content_type() && dcp_content_type()->libdcp_kind() != dcp::ContentKind::TRAILER) {
                auto first_video = std::find_if(content_list.begin(), content_list.end(), [](shared_ptr<Content> c) { return static_cast<bool>(c->video); });
                if (first_video != content_list.end()) {
-                       auto first_ratio = lrintf((*first_video)->video->scaled_size(frame_size()).ratio() * 100);
-                       auto container_ratio = lrintf(container()->ratio() * 100);
-                       if (first_ratio != container_ratio) {
-                               isdcf_name += "-" + dcp::raw_convert<string>(first_ratio);
+                       if (auto scaled_size = (*first_video)->video->scaled_size(frame_size())) {
+                               auto first_ratio = lrintf(scaled_size->ratio() * 100);
+                               auto container_ratio = lrintf(container()->ratio() * 100);
+                               if (first_ratio != container_ratio) {
+                                       isdcf_name += "-" + dcp::raw_convert<string>(first_ratio);
+                               }
                        }
                }
        }
@@ -1435,13 +1437,13 @@ Film::maybe_set_container_and_resolution ()
                }
        }
 
-       if (video) {
+       if (video && video->size()) {
                /* This is the only piece of video content in this Film.  Use it to make a guess for
                 * DCP container size and resolution, unless the user has already explicitly set these
                 * things.
                 */
                if (!_user_explicit_container) {
-                       if (video->size().ratio() > 2.3) {
+                       if (video->size()->ratio() > 2.3) {
                                set_container (Ratio::from_id("239"), false);
                        } else {
                                set_container (Ratio::from_id("185"), false);
@@ -1449,7 +1451,7 @@ Film::maybe_set_container_and_resolution ()
                }
 
                if (!_user_explicit_resolution) {
-                       if (video->size_after_crop().width > 2048 || video->size_after_crop().height > 1080) {
+                       if (video->size_after_crop()->width > 2048 || video->size_after_crop()->height > 1080) {
                                set_resolution (Resolution::FOUR_K, false);
                        } else {
                                set_resolution (Resolution::TWO_K, false);
@@ -1647,9 +1649,10 @@ Film::active_area () const
 
        for (auto i: content()) {
                if (i->video) {
-                       dcp::Size s = i->video->scaled_size (frame);
-                       active.width = max(active.width, s.width);
-                       active.height = max(active.height, s.height);
+                       if (auto s = i->video->scaled_size(frame)) {
+                               active.width = max(active.width, s->width);
+                               active.height = max(active.height, s->height);
+                       }
                }
        }
 
index 7537317d40b77d89b80876699cadb48230621622..bbd5ae5d594e5a3b1b81ac4f3ad1ab7bb4ba10ae 100644 (file)
@@ -128,8 +128,8 @@ Hints::check_incorrect_container ()
        int narrower_than_scope = 0;
        int scope = 0;
        for (auto i: film()->content()) {
-               if (i->video) {
-                       auto const r = Ratio::nearest_from_ratio(i->video->scaled_size(film()->frame_size()).ratio());
+               if (i->video && i->video->size()) {
+                       auto const r = Ratio::nearest_from_ratio(i->video->scaled_size(film()->frame_size())->ratio());
                        if (r && r->id() == "239") {
                                ++scope;
                        } else if (r && r->id() != "239" && r->id() != "235" && r->id() != "190") {
index 26a9ad624b31fb168633c7aa3f721f44edf403db..ce5c8757f7f636adc40cdf9f5dd23e5daf3d10dc 100644 (file)
@@ -73,7 +73,9 @@ ImageDecoder::pass ()
                        /* We can't extract image size from a JPEG2000 codestream without decoding it,
                           so pass in the image content's size here.
                        */
-                       _image = make_shared<J2KImageProxy>(path, _image_content->video->size(), pf);
+                       auto size = _image_content->video->size();
+                       DCPOMATIC_ASSERT(size);
+                       _image = make_shared<J2KImageProxy>(path, *size, pf);
                } else {
                        _image = make_shared<FFmpegImageProxy>(path);
                }
index ac2c95a08a1d71f12d0333fb56db2c9901721bd0..15a0b043d56543c8451cfd243c27204afc336f16 100644 (file)
@@ -77,10 +77,10 @@ ImageExaminer::ImageExaminer (shared_ptr<const Film> film, shared_ptr<const Imag
 }
 
 
-dcp::Size
+optional<dcp::Size>
 ImageExaminer::video_size () const
 {
-       return _video_size.get ();
+       return _video_size;
 }
 
 
index 53fab327e495dac5a34ef37040cabf0603773a71..54fca7ed1c2e6ce10efe02d04877bec6e0424f4e 100644 (file)
@@ -31,7 +31,7 @@ public:
                return true;
        }
        boost::optional<double> video_frame_rate () const override;
-       dcp::Size video_size () const override;
+       boost::optional<dcp::Size> video_size() const override;
        Frame video_length () const override {
                return _video_length;
        }
index 0796fbceb118323890583014fbbbb104e412dab1..c03cb97a59f50ad8549f8142279e48a236a801dc 100644 (file)
@@ -1094,13 +1094,16 @@ Player::video (weak_ptr<Piece> weak_piece, ContentVideo video)
 
        auto const content_video = piece->content->video;
 
+       auto scaled_size = content_video->scaled_size(film->frame_size());
+       DCPOMATIC_ASSERT(scaled_size);
+
        for (auto eyes: eyes_to_emit) {
                _last_video[weak_piece] = std::make_shared<PlayerVideo>(
                        video.image,
                        content_video->actual_crop(),
                        content_video->fade(film, video.frame),
                        scale_for_display(
-                               content_video->scaled_size(film->frame_size()),
+                               *scaled_size,
                                _video_container_size,
                                film->frame_size(),
                                content_video->pixel_quanta()
index d45bf9f432b90c996feb870baf1580fc3a5796a4..35c5d3daa484f997d141417bf56efa10208753e8 100644 (file)
@@ -362,8 +362,13 @@ PlayerVideo::reset_metadata (shared_ptr<const Film> film, dcp::Size player_video
 
        _crop = content->video->actual_crop();
        _fade = content->video->fade(film, _video_frame.get());
+       auto const size = content->video->scaled_size(film->frame_size());
+       if (!size) {
+               return false;
+       }
+
        _inter_size = scale_for_display(
-               content->video->scaled_size(film->frame_size()),
+               *size,
                player_video_container_size,
                film->frame_size(),
                content->video->pixel_quanta()
index 6c3f23a5702ebd2735936c914b204bc8c366bfc4..91ed1185588d181056d76a8fd78ea11ffaefa8c5 100644 (file)
@@ -102,8 +102,7 @@ VideoContent::from_xml (Content* parent, cxml::ConstNodePtr node, int version, V
 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");
+       _size = dcp::Size(node->number_child<int>("VideoWidth"), node->number_child<int>("VideoHeight"));
 
        _use = node->optional_bool_child("Use").get_value_or(true);
        _length = node->number_child<Frame> ("VideoLength");
@@ -154,10 +153,12 @@ VideoContent::VideoContent (Content* parent, cxml::ConstNodePtr node, int versio
                if (scale) {
                        if (*scale) {
                                /* This is what we used to call "no stretch" */
-                               _legacy_ratio = _size.ratio();
+                               DCPOMATIC_ASSERT(_size);
+                               _legacy_ratio = _size->ratio();
                        } else {
                                /* This is what we used to call "no scale" */
-                               _custom_size = _size;
+                               DCPOMATIC_ASSERT(_size);
+                               _custom_size = *_size;
                        }
                }
 
@@ -277,8 +278,10 @@ VideoContent::as_xml (xmlpp::Node* node) const
        boost::mutex::scoped_lock lm (_mutex);
        node->add_child("Use")->add_child_text (_use ? "1" : "0");
        node->add_child("VideoLength")->add_child_text (raw_convert<string> (_length));
-       node->add_child("VideoWidth")->add_child_text (raw_convert<string> (_size.width));
-       node->add_child("VideoHeight")->add_child_text (raw_convert<string> (_size.height));
+       if (_size) {
+               node->add_child("VideoWidth")->add_child_text(raw_convert<string>(_size->width));
+               node->add_child("VideoHeight")->add_child_text(raw_convert<string>(_size->height));
+       }
        node->add_child("VideoFrameType")->add_child_text (video_frame_type_to_string (_frame_type));
        if (_sample_aspect_ratio) {
                node->add_child("SampleAspectRatio")->add_child_text (raw_convert<string> (_sample_aspect_ratio.get ()));
@@ -369,11 +372,12 @@ VideoContent::identifier () const
 string
 VideoContent::technical_summary () const
 {
+       string const size_string = size() ? String::compose("%1x%2", size()->width, size()->height) : _("unknown");
+
        string s = String::compose (
-               N_("video: length %1 frames, size %2x%3"),
+               N_("video: length %1 frames, size %2"),
                length_after_3d_combine(),
-               size().width,
-               size().height
+               size_string
                );
 
        if (sample_aspect_ratio ()) {
@@ -383,31 +387,40 @@ VideoContent::technical_summary () const
        return s;
 }
 
-dcp::Size
+optional<dcp::Size>
 VideoContent::size_after_3d_split () const
 {
        auto const s = size ();
+       if (!s) {
+               return {};
+       }
+
        switch (frame_type ()) {
        case VideoFrameType::TWO_D:
        case VideoFrameType::THREE_D:
        case VideoFrameType::THREE_D_ALTERNATE:
        case VideoFrameType::THREE_D_LEFT:
        case VideoFrameType::THREE_D_RIGHT:
-               return s;
+               return *s;
        case VideoFrameType::THREE_D_LEFT_RIGHT:
-               return dcp::Size (s.width / 2, s.height);
+               return dcp::Size(s->width / 2, s->height);
        case VideoFrameType::THREE_D_TOP_BOTTOM:
-               return dcp::Size (s.width, s.height / 2);
+               return dcp::Size(s->width, s->height / 2);
        }
 
        DCPOMATIC_ASSERT (false);
 }
 
 /** @return Video size after 3D split and crop */
-dcp::Size
+optional<dcp::Size>
 VideoContent::size_after_crop () const
 {
-       return actual_crop().apply(size_after_3d_split());
+       auto const after_3d = size_after_3d_split();
+       if (!after_3d) {
+               return {};
+       }
+
+       return actual_crop().apply(*after_3d);
 }
 
 
@@ -440,15 +453,15 @@ VideoContent::processing_description (shared_ptr<const Film> film)
        string d;
        char buffer[256];
 
-       if (size().width && size().height) {
+       if (size() && size()->width && size()->height) {
                d += String::compose (
                        _("Content video is %1x%2"),
-                       size_after_3d_split().width,
-                       size_after_3d_split().height
+                       size_after_3d_split()->width,
+                       size_after_3d_split()->height
                        );
 
 
-               double ratio = size_after_3d_split().ratio ();
+               auto ratio = size_after_3d_split()->ratio();
 
                if (sample_aspect_ratio ()) {
                        snprintf (buffer, sizeof(buffer), _(", pixel aspect ratio %.2f:1"), sample_aspect_ratio().get());
@@ -464,29 +477,31 @@ VideoContent::processing_description (shared_ptr<const Film> film)
 
        if ((crop.left || crop.right || crop.top || crop.bottom) && size() != dcp::Size(0, 0)) {
                auto const cropped = size_after_crop ();
-               d += String::compose (
-                       _("\nCropped to %1x%2"),
-                       cropped.width, cropped.height
-                       );
+               if (cropped) {
+                       d += String::compose (
+                               _("\nCropped to %1x%2"),
+                               cropped->width, cropped->height
+                               );
 
-               snprintf (buffer, sizeof(buffer), " (%.2f:1)", cropped.ratio());
-               d += buffer;
+                       snprintf(buffer, sizeof(buffer), " (%.2f:1)", cropped->ratio());
+                       d += buffer;
+               }
        }
 
        auto const container_size = film->frame_size ();
        auto const scaled = scaled_size (container_size);
 
-       if (scaled != size_after_crop ()) {
+       if (scaled && *scaled != size_after_crop()) {
                d += String::compose (
                        _("\nScaled to %1x%2"),
-                       scaled.width, scaled.height
+                       scaled->width, scaled->height
                        );
 
-               snprintf (buffer, sizeof(buffer), _(" (%.2f:1)"), scaled.ratio());
+               snprintf (buffer, sizeof(buffer), _(" (%.2f:1)"), scaled->ratio());
                d += buffer;
        }
 
-       if (scaled != container_size) {
+       if (scaled && *scaled != container_size) {
                d += String::compose (
                        _("\nPadded with black to fit container %1 (%2x%3)"),
                        film->container()->container_nickname (),
@@ -514,7 +529,9 @@ void
 VideoContent::add_properties (list<UserProperty>& p) const
 {
        p.push_back (UserProperty (UserProperty::VIDEO, _("Length"), length (), _("video frames")));
-       p.push_back (UserProperty (UserProperty::VIDEO, _("Size"), String::compose ("%1x%2", size().width, size().height)));
+       if (auto s = size()) {
+               p.push_back(UserProperty(UserProperty::VIDEO, _("Size"), String::compose("%1x%2", s->width, s->height)));
+       }
 }
 
 void
@@ -643,7 +660,7 @@ VideoContent::modify_trim_start (ContentTime& trim) const
 
 
 /** @param film_container The size of the container for the DCP that we are working on */
-dcp::Size
+optional<dcp::Size>
 VideoContent::scaled_size (dcp::Size film_container)
 {
        if (_custom_ratio) {
@@ -658,18 +675,22 @@ VideoContent::scaled_size (dcp::Size film_container)
        }
 
        auto size = size_after_crop ();
-       size.width = std::lrint(size.width * _sample_aspect_ratio.get_value_or(1));
+       if (!size) {
+               return {};
+       }
+
+       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);
+       auto auto_size = fit_ratio_within(size->ratio(), film_container);
 
        if (_legacy_ratio) {
                if (fit_ratio_within(*_legacy_ratio, film_container) != auto_size) {
                        _custom_ratio = *_legacy_ratio;
-                       _legacy_ratio = optional<float>();
+                       _legacy_ratio = {};
                        return fit_ratio_within(*_custom_ratio, film_container);
                }
-               _legacy_ratio = boost::optional<float>();
+               _legacy_ratio = {};
        }
 
        return _pixel_quanta.round (auto_size);
index 9f6cc105ea42155fec19d9776ff016a368e96280..e7e8eb1b3d3d6f35c68169bc71677ffddf0632e7 100644 (file)
@@ -85,7 +85,7 @@ public:
                return _length;
        }
 
-       dcp::Size size () const {
+       boost::optional<dcp::Size> size () const {
                boost::mutex::scoped_lock lm (_mutex);
                return _size;
        }
@@ -204,9 +204,9 @@ public:
 
 
        /* XXX: names for these? */
-       dcp::Size size_after_3d_split () const;
-       dcp::Size size_after_crop () const;
-       dcp::Size scaled_size (dcp::Size container_size);
+       boost::optional<dcp::Size> size_after_3d_split() const;
+       boost::optional<dcp::Size> size_after_crop() const;
+       boost::optional<dcp::Size> scaled_size(dcp::Size container_size);
 
        boost::optional<double> fade (std::shared_ptr<const Film> film, Frame) const;
 
@@ -237,7 +237,7 @@ private:
        bool _use;
        Frame _length;
        boost::optional<ColourConversion> _colour_conversion;
-       dcp::Size _size;
+       boost::optional<dcp::Size> _size;
        VideoFrameType _frame_type;
        Crop _crop;
        /** ratio to scale cropped image to (or none to guess); i.e. if set, scale to _custom_ratio:1 */
index 44a1186bb5fa4ff0c0cbbf660aa6f5eeebf50036..b670dafc54a8191165a9fbfd0e4205f87126ca34 100644 (file)
@@ -41,8 +41,8 @@ public:
 
        /** @return video frame rate (if known); must not be called if has_video() == false */
        virtual boost::optional<double> video_frame_rate () const = 0;
-       /** @return video size; must not be called if has_video() == false */
-       virtual dcp::Size video_size () const = 0;
+       /** @return video size (if known) */
+       virtual boost::optional<dcp::Size> video_size() const = 0;
        /** @return video length in frames; must not be called if has_video() == false */
        virtual Frame video_length () const = 0;
        /** @return video sample aspect ratio (if known); must not be called if has_video() == false */
index 8c7029ea817f3ff255efcd7c6ae621db4d991d14..7a05f33691a756499f93b7f07ca06ee0696c22b9 100644 (file)
@@ -48,7 +48,7 @@ VideoMXFExaminer::video_frame_rate () const
        return _asset->frame_rate().as_float ();
 }
 
-dcp::Size
+optional<dcp::Size>
 VideoMXFExaminer::video_size () const
 {
        return _asset->size ();
index f5c9bf1fd8ac8c2b83625118d140d1227aa12d12..e4cd98f0730681c7df7a60065e3985d4af80eea8 100644 (file)
@@ -35,7 +35,7 @@ public:
                return true;
        }
        boost::optional<double> video_frame_rate () const override;
-       dcp::Size video_size () const override;
+       boost::optional<dcp::Size> video_size() const override;
        Frame video_length () const override;
        boost::optional<double> sample_aspect_ratio () const override;
        bool yuv () const override;
index c07f39add91f6503be0df9ce6c39e46fac86678f..65252ff29dfd1efb6d8804d8a336840446f9a122 100644 (file)
@@ -103,8 +103,8 @@ print_dump (shared_ptr<Film> film)
                     << " start trim " << c->trim_start().seconds ()
                     << " end trim " << c->trim_end().seconds () << "\n";
 
-               if (c->video) {
-                       cout << "\t" << c->video->size().width << "x" << c->video->size().height << "\n"
+               if (c->video && c->video->size()) {
+                       cout << "\t" << c->video->size()->width << "x" << c->video->size()->height << "\n"
                             << "\t" << c->active_video_frame_rate(film) << "fps\n"
                             << "\tcrop left " << c->video->requested_left_crop()
                             << " right " << c->video->requested_right_crop()
index 9c7522bc589af6f11d846a78fd38071c7063a9c6..e658395211c5b040cce4b191518b641ea477ab9d 100644 (file)
@@ -477,8 +477,8 @@ public:
                                j->set_use (true);
                        }
 
-                       if (i->video) {
-                               auto const r = Ratio::nearest_from_ratio(i->video->size().ratio());
+                       if (i->video && i->video->size()) {
+                               auto const r = Ratio::nearest_from_ratio(i->video->size()->ratio());
                                if (r->id() == "239") {
                                        /* Any scope content means we use scope */
                                        _film->set_container(r);
@@ -687,8 +687,8 @@ private:
                        for (auto i: dcp->text) {
                                i->set_use (true);
                        }
-                       if (dcp->video) {
-                               auto const r = Ratio::nearest_from_ratio(dcp->video->size().ratio());
+                       if (dcp->video && dcp->video->size()) {
+                               auto const r = Ratio::nearest_from_ratio(dcp->video->size()->ratio());
                                if (r) {
                                        _film->set_container(r);
                                }
index 700683bd2b8e177f2d1417816e865c11acd15b42..4af5a71b708d66f118d336e1412445274883e4a2 100644 (file)
@@ -548,12 +548,13 @@ ContentMenu::auto_crop ()
                DCPOMATIC_ASSERT (film);
                auto const content = _content.front();
                auto const current_crop = content->video->actual_crop();
+               auto const video_size_guess = content->video->size().get_value_or(dcp::Size(1998, 1080));
                _viewer.set_crop_guess(
                        dcpomatic::Rect<float>(
-                               static_cast<float>(std::max(0, crop.left - current_crop.left)) / content->video->size().width,
-                               static_cast<float>(std::max(0, crop.top - current_crop.top)) / content->video->size().height,
-                               1.0f - (static_cast<float>(std::max(0, crop.left - current_crop.left + crop.right - current_crop.right)) / content->video->size().width),
-                               1.0f - (static_cast<float>(std::max(0, crop.top - current_crop.top + crop.bottom - current_crop.bottom)) / content->video->size().height)
+                               static_cast<float>(std::max(0, crop.left - current_crop.left)) / video_size_guess.width,
+                               static_cast<float>(std::max(0, crop.top - current_crop.top)) / video_size_guess.height,
+                               1.0f - (static_cast<float>(std::max(0, crop.left - current_crop.left + crop.right - current_crop.right)) / video_size_guess.width),
+                               1.0f - (static_cast<float>(std::max(0, crop.top - current_crop.top + crop.bottom - current_crop.bottom)) / video_size_guess.height)
                                ));
        };
 
index 806611140f2a028d4de5bde16e69fc8c7f31ce36..057d26740498becf89fa3b4fcc814648a8bd9f19 100644 (file)
@@ -161,7 +161,13 @@ PlayerInformation::triggered_update ()
 
        DCPOMATIC_ASSERT (dcp->video);
 
-       checked_set (_dcp[r++], wxString::Format(_("Size: %dx%d"), dcp->video->size().width, dcp->video->size().height));
+       auto const size = dcp->video->size();
+
+       if (size) {
+               checked_set(_dcp[r++], wxString::Format(_("Size: %dx%d"), size->width, size->height));
+       } else {
+               checked_set(_dcp[r++], _("Size: unknown"));
+       }
        if (dcp->video_frame_rate()) {
                checked_set (_dcp[r++], wxString::Format(_("Frame rate: %d"), (int) lrint(*dcp->video_frame_rate())));
        }
@@ -186,14 +192,18 @@ PlayerInformation::triggered_update ()
 
        checked_set (_dcp[r++], std_to_wx(len));
 
-       auto decode = dcp->video->size();
+       auto decode = size;
        auto reduction = _viewer.dcp_decode_reduction();
-       if (reduction) {
-               decode.width /= pow(2, *reduction);
-               decode.height /= pow(2, *reduction);
+       if (reduction && decode) {
+               decode->width /= pow(2, *reduction);
+               decode->height /= pow(2, *reduction);
        }
 
-       checked_set (_decode_resolution, wxString::Format(_("Decode resolution: %dx%d"), decode.width, decode.height));
+       if (decode) {
+               checked_set(_decode_resolution, wxString::Format(_("Decode resolution: %dx%d"), decode->width, decode->height));
+       } else {
+               checked_set(_decode_resolution, _("Decode resolution: unknown"));
+       }
 
        DCPOMATIC_ASSERT(r <= dcp_lines);
 
index 8a02dff25b01acc08e958f05717124dce8f96ad0..b27db2547baa72e5e2d1f7b9720184dd1997685d 100644 (file)
@@ -725,7 +725,10 @@ bool
 VideoPanel::scale_custom_edit_clicked ()
 {
        auto vc = _parent->selected_video().front()->video;
-       CustomScaleDialog dialog(this, vc->size(), _parent->film()->frame_size(), vc->custom_ratio(), vc->custom_size());
+       auto size = vc->size();
+       DCPOMATIC_ASSERT(size);
+
+       CustomScaleDialog dialog(this, *size, _parent->film()->frame_size(), vc->custom_ratio(), vc->custom_size());
        if (dialog.ShowModal() != wxID_OK) {
                return false;
        }
index cdd6b20f1fa367df57b2e8fa05ecf3fa7d9a9de9..7275a33c725de54dfd36fe119c1a44aab4ef60d3 100644 (file)
@@ -40,11 +40,11 @@ BOOST_AUTO_TEST_CASE(check_examine_vfs)
 
        auto ov_dcp = make_shared<DCPContent>(ov->dir(ov->dcp_name()));
        auto second_reel = content_factory("test/data/scope_red.png")[0];
-       auto vf = new_test_film2("check_examine_vf_vf", { ov_dcp, second_reel });
+       auto vf = new_test_film2("check_examine_vfs_vf", { ov_dcp, second_reel });
        vf->set_container(Ratio::from_id("239"));
        vf->set_reel_type(ReelType::BY_VIDEO_CONTENT);
        ov_dcp->set_reference_video(true);
-       make_and_verify_dcp(vf, { dcp::VerificationNote::Code::EXTERNAL_ASSET });
+       make_and_verify_dcp(vf, { dcp::VerificationNote::Code::EXTERNAL_ASSET }, false);
 
        auto vf_dcp = make_shared<DCPContent>(vf->dir(vf->dcp_name()));
        DCPExaminer examiner(vf_dcp, false);
index 73feb7dc66460dbaebd87e1158f687aaeb8f7acf..c82392f8115bfb95cbdcace363d52b2d433c14bd 100644 (file)
@@ -38,37 +38,37 @@ BOOST_AUTO_TEST_CASE (scaled_size_test1)
        /* Images at full size and in DCP-approved sizes that will not be scaled */
        // Flat/scope content into flat/scope container
        vc._size = FLAT;
-       BOOST_CHECK_EQUAL (vc.scaled_size(FLAT), FLAT);
+       BOOST_CHECK_EQUAL(*vc.scaled_size(FLAT), FLAT);
        vc._size = SCOPE;
-       BOOST_CHECK_EQUAL (vc.scaled_size(SCOPE), SCOPE);
+       BOOST_CHECK_EQUAL(*vc.scaled_size(SCOPE), SCOPE);
        // 1.33:1 into flat container
        vc._size = FOUR_TO_THREE;
-       BOOST_CHECK_EQUAL (vc.scaled_size(FLAT), dcp::Size(FOUR_TO_THREE));
+       BOOST_CHECK_EQUAL(*vc.scaled_size(FLAT), dcp::Size(FOUR_TO_THREE));
        // Scope into flat container
        vc._size = SCOPE;
-       BOOST_CHECK_EQUAL (vc.scaled_size(FLAT), dcp::Size(1998, 837));
+       BOOST_CHECK_EQUAL(*vc.scaled_size(FLAT), dcp::Size(1998, 837));
 
        /* Smaller images but in the same ratios */
        vc._size = dcp::Size(185, 100);
-       BOOST_CHECK_EQUAL (vc.scaled_size(FLAT), FLAT);
+       BOOST_CHECK_EQUAL(*vc.scaled_size(FLAT), FLAT);
        vc._size = dcp::Size(955, 400);
-       BOOST_CHECK_EQUAL (vc.scaled_size(SCOPE), SCOPE);
+       BOOST_CHECK_EQUAL(*vc.scaled_size(SCOPE), SCOPE);
        // 1.33:1 into flat container
        vc._size = dcp::Size(133, 100);
-       BOOST_CHECK_EQUAL (vc.scaled_size(FLAT), dcp::Size(FOUR_TO_THREE));
+       BOOST_CHECK_EQUAL(*vc.scaled_size(FLAT), dcp::Size(FOUR_TO_THREE));
        // Scope into flat container
        vc._size = dcp::Size(239, 100);
-       BOOST_CHECK_EQUAL (vc.scaled_size(FLAT), dcp::Size(1998, 836));
+       BOOST_CHECK_EQUAL(*vc.scaled_size(FLAT), dcp::Size(1998, 836));
 
        /* Images at full size that are not DCP-approved but will still remain unscaled */
        vc._size = dcp::Size(600, 1080);
-       BOOST_CHECK_EQUAL (vc.scaled_size(FLAT), dcp::Size(600, 1080));
+       BOOST_CHECK_EQUAL(*vc.scaled_size(FLAT), dcp::Size(600, 1080));
        vc._size = dcp::Size(1700, 1080);
-       BOOST_CHECK_EQUAL (vc.scaled_size(FLAT), dcp::Size(1700, 1080));
+       BOOST_CHECK_EQUAL(*vc.scaled_size(FLAT), dcp::Size(1700, 1080));
 
        /* Image at full size that is too big for the container and will be shrunk */
        vc._size = dcp::Size(3000, 1080);
-       BOOST_CHECK_EQUAL (vc.scaled_size(FLAT), dcp::Size(1998, 719));
+       BOOST_CHECK_EQUAL(*vc.scaled_size(FLAT), dcp::Size(1998, 719));
 }
 
 
@@ -82,37 +82,37 @@ BOOST_AUTO_TEST_CASE (scaled_size_test2)
        /* Images at full size and in DCP-approved sizes that will not be scaled */
        // Flat/scope content into flat/scope container
        vc._size = dcp::Size (1998 / 2, 1080);
-       BOOST_CHECK_EQUAL (vc.scaled_size(FLAT), FLAT);
+       BOOST_CHECK_EQUAL(*vc.scaled_size(FLAT), FLAT);
        vc._size = dcp::Size (2048 / 2, 858);
-       BOOST_CHECK_EQUAL (vc.scaled_size(SCOPE), SCOPE);
+       BOOST_CHECK_EQUAL(*vc.scaled_size(SCOPE), SCOPE);
        // 1.33:1 into flat container
        vc._size = dcp::Size (1436 / 2, 1080);
-       BOOST_CHECK_EQUAL (vc.scaled_size(FLAT), dcp::Size(FOUR_TO_THREE));
+       BOOST_CHECK_EQUAL(*vc.scaled_size(FLAT), dcp::Size(FOUR_TO_THREE));
        // Scope into flat container
        vc._size = dcp::Size (2048 / 2, 858);
-       BOOST_CHECK_EQUAL (vc.scaled_size(FLAT), dcp::Size(1998, 837));
+       BOOST_CHECK_EQUAL(*vc.scaled_size(FLAT), dcp::Size(1998, 837));
 
        /* Smaller images but in the same ratios */
        vc._size = dcp::Size(185, 200);
-       BOOST_CHECK_EQUAL (vc.scaled_size(FLAT), FLAT);
+       BOOST_CHECK_EQUAL(*vc.scaled_size(FLAT), FLAT);
        vc._size = dcp::Size(955, 800);
-       BOOST_CHECK_EQUAL (vc.scaled_size(SCOPE), SCOPE);
+       BOOST_CHECK_EQUAL(*vc.scaled_size(SCOPE), SCOPE);
        // 4:3 into flat container
        vc._size = dcp::Size(133, 200);
-       BOOST_CHECK_EQUAL (vc.scaled_size(FLAT), dcp::Size(FOUR_TO_THREE));
+       BOOST_CHECK_EQUAL(*vc.scaled_size(FLAT), dcp::Size(FOUR_TO_THREE));
        // Scope into flat container
        vc._size = dcp::Size(239, 200);
-       BOOST_CHECK_EQUAL (vc.scaled_size(FLAT), dcp::Size(1998, 836));
+       BOOST_CHECK_EQUAL(*vc.scaled_size(FLAT), dcp::Size(1998, 836));
 
        /* Images at full size that are not DCP-approved but will still remain unscaled */
        vc._size = dcp::Size(600 / 2, 1080);
-       BOOST_CHECK_EQUAL (vc.scaled_size(FLAT), dcp::Size(600, 1080));
+       BOOST_CHECK_EQUAL(*vc.scaled_size(FLAT), dcp::Size(600, 1080));
        vc._size = dcp::Size(1700 / 2, 1080);
-       BOOST_CHECK_EQUAL (vc.scaled_size(FLAT), dcp::Size(1700, 1080));
+       BOOST_CHECK_EQUAL(*vc.scaled_size(FLAT), dcp::Size(1700, 1080));
 
        /* Image at full size that is too big for the container and will be shrunk */
        vc._size = dcp::Size(3000 / 2, 1080);
-       BOOST_CHECK_EQUAL (vc.scaled_size(FLAT), dcp::Size(1998, 719));
+       BOOST_CHECK_EQUAL(*vc.scaled_size(FLAT), dcp::Size(1998, 719));
 }
 
 
@@ -124,7 +124,7 @@ BOOST_AUTO_TEST_CASE (scaled_size_legacy_test)
                VideoContent vc (0);
                vc._size = dcp::Size(640, 480);
                vc._legacy_ratio = Ratio::from_id("185")->ratio();
-               BOOST_CHECK_EQUAL (vc.scaled_size(FLAT), FLAT);
+               BOOST_CHECK_EQUAL(*vc.scaled_size(FLAT), FLAT);
        }
 
        {
@@ -132,7 +132,7 @@ BOOST_AUTO_TEST_CASE (scaled_size_legacy_test)
                VideoContent vc (0);
                vc._size = dcp::Size(640, 480);
                vc._legacy_ratio = 1.33;
-               BOOST_CHECK_EQUAL (vc.scaled_size(FLAT), FOUR_TO_THREE);
+               BOOST_CHECK_EQUAL(*vc.scaled_size(FLAT), FOUR_TO_THREE);
        }
 
        {
@@ -140,7 +140,7 @@ BOOST_AUTO_TEST_CASE (scaled_size_legacy_test)
                VideoContent vc (0);
                vc._size = dcp::Size(640, 480);
                vc._custom_size = dcp::Size(640, 480);
-               BOOST_CHECK_EQUAL (vc.scaled_size(FLAT), dcp::Size(640, 480));
+               BOOST_CHECK_EQUAL(*vc.scaled_size(FLAT), dcp::Size(640, 480));
        }
 }