Add support for no-scale of the input video.
authorCarl Hetherington <cth@carlh.net>
Tue, 4 Mar 2014 16:44:20 +0000 (16:44 +0000)
committerCarl Hetherington <cth@carlh.net>
Tue, 4 Mar 2014 16:44:20 +0000 (16:44 +0000)
Requested-by: GĂ©rald Maruccia
19 files changed:
ChangeLog
src/lib/ffmpeg_content.cc
src/lib/film.cc
src/lib/image.cc
src/lib/image_content.cc
src/lib/image_content.h
src/lib/player.cc
src/lib/util.cc
src/lib/video_content.cc
src/lib/video_content.h
src/tools/dcpomatic_create.cc
src/wx/video_panel.cc
src/wx/video_panel.h
test/4k_test.cc
test/black_fill_test.cc
test/ffmpeg_audio_test.cc
test/ffmpeg_dcp_test.cc
test/scaling_test.cc
test/threed_test.cc

index 00df090c70e45ef03eef8204e797cc06c872d073..c7d7f758fc12c9dca9f4885a91ab08a7cb913831 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2014-03-04  Carl Hetherington  <cth@carlh.net>
+
+       * Add option to disable all scaling of the input video.
+
 2014-03-03  Carl Hetherington  <cth@carlh.net>
 
        * Fix rounding of timecodes in at least some cases (#323).
index 5524efc65fc45cc6e24b5aa5e920da5f4d3739ea..4ae5546c2c2daa38a76a07c770eba837f572047a 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2013-2014 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -60,7 +60,7 @@ FFmpegContent::FFmpegContent (shared_ptr<const Film> f, boost::filesystem::path
 
 FFmpegContent::FFmpegContent (shared_ptr<const Film> f, shared_ptr<const cxml::Node> node, int version)
        : Content (f, node)
-       , VideoContent (f, node)
+       , VideoContent (f, node, version)
        , AudioContent (f, node)
        , SubtitleContent (f, node, version)
 {
index 13481045200ac26be456979fa5fab70e8d8b40f0..00beb870f6e0ead188a1c013cc4f32b23e8594bb 100644 (file)
@@ -85,8 +85,10 @@ using libdcp::Signer;
  * AudioMapping XML changed.
  * 6 -> 7
  * Subtitle offset changed to subtitle y offset, and subtitle x offset added.
+ * 7 -> 8
+ * Use <Scale> tag in <VideoContent> rather than <Ratio>.
  */
-int const Film::current_state_version = 7;
+int const Film::current_state_version = 8;
 
 /** Construct a Film object in a given directory.
  *
index 4722563c45d532f397bb5231adf3ffdc548c4835..c7dfc91cb374eb9c765b0009e22a00a407f1aff2 100644 (file)
@@ -32,9 +32,12 @@ extern "C" {
 #include "exceptions.h"
 #include "scaler.h"
 
+#include "i18n.h"
+
 using std::string;
 using std::min;
 using std::cout;
+using std::cerr;
 using boost::shared_ptr;
 using libdcp::Size;
 
@@ -88,26 +91,38 @@ Image::crop_scale_window (Crop crop, libdcp::Size inter_size, libdcp::Size out_s
        */
        assert (aligned ());
 
+       assert (out_size.width >= inter_size.width);
+       assert (out_size.height >= inter_size.height);
+
+       /* Here's an image of out_size */
        shared_ptr<Image> out (new Image (out_format, out_size, out_aligned));
        out->make_black ();
-       
-       libdcp::Size cropped_size = crop.apply (size ());
 
+       /* Size of the image after any crop */
+       libdcp::Size const cropped_size = crop.apply (size ());
+
+       /* Scale context for a scale from cropped_size to inter_size */
        struct SwsContext* scale_context = sws_getContext (
                cropped_size.width, cropped_size.height, pixel_format(),
                inter_size.width, inter_size.height, out_format,
                scaler->ffmpeg_id (), 0, 0, 0
                );
 
+       if (!scale_context) {
+               throw StringError (N_("Could not allocate SwsContext"));
+       }
+
+       /* Prepare input data pointers with crop */
        uint8_t* scale_in_data[components()];
        for (int c = 0; c < components(); ++c) {
                scale_in_data[c] = data()[c] + int (rint (bytes_per_pixel(c) * crop.left)) + stride()[c] * (crop.top / line_factor(c));
        }
 
+       /* Corner of the image within out_size */
        Position<int> const corner ((out_size.width - inter_size.width) / 2, (out_size.height - inter_size.height) / 2);
 
-       uint8_t* scale_out_data[components()];
-       for (int c = 0; c < components(); ++c) {
+       uint8_t* scale_out_data[out->components()];
+       for (int c = 0; c < out->components(); ++c) {
                scale_out_data[c] = out->data()[c] + int (rint (out->bytes_per_pixel(c) * corner.x)) + out->stride()[c] * corner.y;
        }
 
index 2d29df0c4bf2fa5a25b32e7e3aa7d200c6c3ca4c..fd0b578943639a0871b529f2df2cd90947e110a6 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2013-2014 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -50,9 +50,9 @@ ImageContent::ImageContent (shared_ptr<const Film> f, boost::filesystem::path p)
 }
 
 
-ImageContent::ImageContent (shared_ptr<const Film> f, shared_ptr<const cxml::Node> node, int)
+ImageContent::ImageContent (shared_ptr<const Film> f, shared_ptr<const cxml::Node> node, int version)
        : Content (f, node)
-       , VideoContent (f, node)
+       , VideoContent (f, node, version)
 {
        
 }
index e5a0311d97947f816f62dbfc5aefd67a8a9ef282..e56abce4a07a8218ab0ad4a7a1b26280d131adce 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2013-2014 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
index 59db923be79503d4425122f24c320690e3d961ed..99aece8d660d5c67c1140410868b6bdd32d3b9f5 100644 (file)
@@ -273,8 +273,7 @@ Player::process_video (weak_ptr<Piece> weak_piece, shared_ptr<const Image> image
        }
 
        Time const time = content->position() + relative_time + extra - content->trim_start ();
-       float const ratio = content->ratio() ? content->ratio()->ratio() : content->video_size_after_crop().ratio();
-       libdcp::Size const image_size = fit_ratio_within (ratio, _video_container_size);
+       libdcp::Size const image_size = content->scale().size (content, _video_container_size);
 
        shared_ptr<PlayerImage> pi (
                new PlayerImage (
@@ -537,7 +536,7 @@ Player::content_changed (weak_ptr<Content> w, int property, bool frequent)
                Changed (frequent);
 
        } else if (
-               property == VideoContentProperty::VIDEO_CROP || property == VideoContentProperty::VIDEO_RATIO ||
+               property == VideoContentProperty::VIDEO_CROP || property == VideoContentProperty::VIDEO_SCALE ||
                property == VideoContentProperty::VIDEO_FRAME_RATE
                ) {
                
index f604cd10a7830c0e9b0ff69540530233bf2ea926..48b418d37634fe6ecdd41bb507ae6d54830485d5 100644 (file)
@@ -70,6 +70,7 @@ extern "C" {
 #include "ratio.h"
 #include "job.h"
 #include "cross.h"
+#include "video_content.h"
 #ifdef DCPOMATIC_WINDOWS
 #include "stack.hpp"
 #endif
@@ -345,6 +346,7 @@ dcpomatic_setup ()
        libdcp::init ();
        
        Ratio::setup_ratios ();
+       VideoContentScale::setup_scales ();
        DCPContentType::setup_dcp_content_types ();
        Scaler::setup_scalers ();
        Filter::setup_filters ();
index cc075a34ced0534d0e3298affe5ce840d0a8926a..7bf2a6b621284a5c6ea3e3cc31538d2263df0f27 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2013-2014 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -22,8 +22,8 @@
 #include <libdcp/colour_matrix.h>
 #include "video_content.h"
 #include "video_examiner.h"
-#include "ratio.h"
 #include "compose.hpp"
+#include "ratio.h"
 #include "config.h"
 #include "colour_conversion.h"
 #include "util.h"
@@ -36,7 +36,7 @@ int const VideoContentProperty::VIDEO_SIZE      = 0;
 int const VideoContentProperty::VIDEO_FRAME_RATE  = 1;
 int const VideoContentProperty::VIDEO_FRAME_TYPE  = 2;
 int const VideoContentProperty::VIDEO_CROP       = 3;
-int const VideoContentProperty::VIDEO_RATIO      = 4;
+int const VideoContentProperty::VIDEO_SCALE      = 4;
 int const VideoContentProperty::COLOUR_CONVERSION = 5;
 
 using std::string;
@@ -49,12 +49,14 @@ using boost::lexical_cast;
 using boost::optional;
 using boost::dynamic_pointer_cast;
 
+vector<VideoContentScale> VideoContentScale::_scales;
+
 VideoContent::VideoContent (shared_ptr<const Film> f)
        : Content (f)
        , _video_length (0)
        , _video_frame_rate (0)
        , _video_frame_type (VIDEO_FRAME_TYPE_2D)
-       , _ratio (Ratio::from_id ("185"))
+       , _scale (Ratio::from_id ("185"))
 {
        setup_default_colour_conversion ();
 }
@@ -64,7 +66,7 @@ VideoContent::VideoContent (shared_ptr<const Film> f, Time s, VideoContent::Fram
        , _video_length (len)
        , _video_frame_rate (0)
        , _video_frame_type (VIDEO_FRAME_TYPE_2D)
-       , _ratio (Ratio::from_id ("185"))
+       , _scale (Ratio::from_id ("185"))
 {
        setup_default_colour_conversion ();
 }
@@ -74,14 +76,13 @@ VideoContent::VideoContent (shared_ptr<const Film> f, boost::filesystem::path p)
        , _video_length (0)
        , _video_frame_rate (0)
        , _video_frame_type (VIDEO_FRAME_TYPE_2D)
-       , _ratio (Ratio::from_id ("185"))
+       , _scale (Ratio::from_id ("185"))
 {
        setup_default_colour_conversion ();
 }
 
-VideoContent::VideoContent (shared_ptr<const Film> f, shared_ptr<const cxml::Node> node)
+VideoContent::VideoContent (shared_ptr<const Film> f, shared_ptr<const cxml::Node> node, int version)
        : Content (f, node)
-       , _ratio (0)
 {
        _video_length = node->number_child<VideoContent::Frame> ("VideoLength");
        _video_size.width = node->number_child<int> ("VideoWidth");
@@ -92,10 +93,16 @@ VideoContent::VideoContent (shared_ptr<const Film> f, shared_ptr<const cxml::Nod
        _crop.right = node->number_child<int> ("RightCrop");
        _crop.top = node->number_child<int> ("TopCrop");
        _crop.bottom = node->number_child<int> ("BottomCrop");
-       optional<string> r = node->optional_string_child ("Ratio");
-       if (r) {
-               _ratio = Ratio::from_id (r.get ());
+
+       if (version <= 7) {
+               optional<string> r = node->optional_string_child ("Ratio");
+               if (r) {
+                       _scale = VideoContentScale (Ratio::from_id (r.get ()));
+               }
+       } else {
+               _scale = VideoContentScale (node->node_child ("Scale"));
        }
+       
        _colour_conversion = ColourConversion (node->node_child ("ColourConversion"));
 }
 
@@ -125,8 +132,8 @@ VideoContent::VideoContent (shared_ptr<const Film> f, vector<shared_ptr<Content>
                        throw JoinError (_("Content to be joined must have the same crop."));
                }
 
-               if (vc->ratio() != ref->ratio()) {
-                       throw JoinError (_("Content to be joined must have the same ratio."));
+               if (vc->scale() != ref->scale()) {
+                       throw JoinError (_("Content to be joined must have the same scale setting."));
                }
 
                if (vc->colour_conversion() != ref->colour_conversion()) {
@@ -140,7 +147,7 @@ VideoContent::VideoContent (shared_ptr<const Film> f, vector<shared_ptr<Content>
        _video_frame_rate = ref->video_frame_rate ();
        _video_frame_type = ref->video_frame_type ();
        _crop = ref->crop ();
-       _ratio = ref->ratio ();
+       _scale = ref->scale ();
        _colour_conversion = ref->colour_conversion ();
 }
 
@@ -157,9 +164,7 @@ VideoContent::as_xml (xmlpp::Node* node) const
        node->add_child("RightCrop")->add_child_text (boost::lexical_cast<string> (_crop.right));
        node->add_child("TopCrop")->add_child_text (boost::lexical_cast<string> (_crop.top));
        node->add_child("BottomCrop")->add_child_text (boost::lexical_cast<string> (_crop.bottom));
-       if (_ratio) {
-               node->add_child("Ratio")->add_child_text (_ratio->id ());
-       }
+       _scale.as_xml (node->add_child("Scale"));
        _colour_conversion.as_xml (node->add_child("ColourConversion"));
 }
 
@@ -268,18 +273,18 @@ VideoContent::set_bottom_crop (int c)
 }
 
 void
-VideoContent::set_ratio (Ratio const * r)
+VideoContent::set_scale (VideoContentScale s)
 {
        {
                boost::mutex::scoped_lock lm (_mutex);
-               if (_ratio == r) {
+               if (_scale == s) {
                        return;
                }
 
-               _ratio = r;
+               _scale = s;
        }
 
-       signal_changed (VideoContentProperty::VIDEO_RATIO);
+       signal_changed (VideoContentProperty::VIDEO_SCALE);
 }
 
 /** @return string which includes everything about how this content looks */
@@ -292,12 +297,9 @@ VideoContent::identifier () const
          << "_" << crop().right
          << "_" << crop().top
          << "_" << crop().bottom
+         << "_" << scale().id()
          << "_" << colour_conversion().identifier ();
 
-       if (ratio()) {
-               s << "_" << ratio()->id ();
-       }
-
        return s.str ();
 }
 
@@ -369,3 +371,113 @@ VideoContent::time_to_content_video_frames (Time t) const
        */
        return t * film->video_frame_rate() / (frc.factor() * TIME_HZ);
 }
+
+VideoContentScale::VideoContentScale (Ratio const * r)
+       : _ratio (r)
+       , _scale (true)
+{
+
+}
+
+VideoContentScale::VideoContentScale ()
+       : _ratio (0)
+       , _scale (false)
+{
+
+}
+
+VideoContentScale::VideoContentScale (bool scale)
+       : _ratio (0)
+       , _scale (scale)
+{
+
+}
+
+VideoContentScale::VideoContentScale (shared_ptr<cxml::Node> node)
+       : _ratio (0)
+       , _scale (true)
+{
+       optional<string> r = node->optional_string_child ("Ratio");
+       if (r) {
+               _ratio = Ratio::from_id (r.get ());
+       } else {
+               _scale = node->bool_child ("Scale");
+       }
+}
+
+void
+VideoContentScale::as_xml (xmlpp::Node* node) const
+{
+       if (_ratio) {
+               node->add_child("Ratio")->add_child_text (_ratio->id ());
+       } else {
+               node->add_child("Scale")->add_child_text (_scale ? "1" : "0");
+       }
+}
+
+string
+VideoContentScale::id () const
+{
+       stringstream s;
+       
+       if (_ratio) {
+               s << _ratio->id () << "_";
+       } else {
+               s << (_scale ? "S1" : "S0");
+       }
+       
+       return s.str ();
+}
+
+string
+VideoContentScale::name () const
+{
+       if (_ratio) {
+               return _ratio->nickname ();
+       }
+
+       if (_scale) {
+               return _("No stretch");
+       }
+
+       return _("No scale");
+}
+
+libdcp::Size
+VideoContentScale::size (shared_ptr<const VideoContent> c, libdcp::Size container) const
+{
+       if (_ratio) {
+               return fit_ratio_within (_ratio->ratio (), container);
+       }
+
+       /* Force scale if the container is smaller than the content's image */
+       if (_scale || container.width < c->video_size().width || container.height < c->video_size().height) {
+               return fit_ratio_within (c->video_size().ratio (), container);
+       }
+
+       return c->video_size ();
+}
+
+void
+VideoContentScale::setup_scales ()
+{
+       vector<Ratio const *> ratios = Ratio::all ();
+       for (vector<Ratio const *>::const_iterator i = ratios.begin(); i != ratios.end(); ++i) {
+               _scales.push_back (VideoContentScale (*i));
+       }
+
+       _scales.push_back (VideoContentScale (true));
+       _scales.push_back (VideoContentScale (false));
+}
+
+bool
+operator== (VideoContentScale const & a, VideoContentScale const & b)
+{
+       return (a.ratio() == b.ratio() && a.scale() == b.scale());
+}
+
+bool
+operator!= (VideoContentScale const & a, VideoContentScale const & b)
+{
+       return (a.ratio() != b.ratio() || a.scale() != b.scale());
+}
index 141525e01b20b237184c32cf21bc49d7a21791d9..c98a52d3a7cc17c842ddcde6634cf7951d362541 100644 (file)
@@ -33,10 +33,46 @@ public:
        static int const VIDEO_FRAME_RATE;
        static int const VIDEO_FRAME_TYPE;
        static int const VIDEO_CROP;
-       static int const VIDEO_RATIO;
+       static int const VIDEO_SCALE;
        static int const COLOUR_CONVERSION;
 };
 
+class VideoContentScale
+{
+public:
+       VideoContentScale ();
+       VideoContentScale (Ratio const *);
+       VideoContentScale (bool);
+       VideoContentScale (boost::shared_ptr<cxml::Node>);
+
+       libdcp::Size size (boost::shared_ptr<const VideoContent>, libdcp::Size) const;
+       std::string id () const;
+       std::string name () const;
+       void as_xml (xmlpp::Node *) const;
+
+       Ratio const * ratio () const {
+               return _ratio;
+       }
+
+       bool scale () const {
+               return _scale;
+       }
+
+       static void setup_scales ();
+       static std::vector<VideoContentScale> all () {
+               return _scales;
+       }
+
+private:
+       Ratio const * _ratio;
+       bool _scale;
+
+       static std::vector<VideoContentScale> _scales;
+};
+
+bool operator== (VideoContentScale const & a, VideoContentScale const & b);
+bool operator!= (VideoContentScale const & a, VideoContentScale const & b);
+
 class VideoContent : public virtual Content
 {
 public:
@@ -45,7 +81,7 @@ public:
        VideoContent (boost::shared_ptr<const Film>);
        VideoContent (boost::shared_ptr<const Film>, Time, VideoContent::Frame);
        VideoContent (boost::shared_ptr<const Film>, boost::filesystem::path);
-       VideoContent (boost::shared_ptr<const Film>, boost::shared_ptr<const cxml::Node>);
+       VideoContent (boost::shared_ptr<const Film>, boost::shared_ptr<const cxml::Node>, int);
        VideoContent (boost::shared_ptr<const Film>, std::vector<boost::shared_ptr<Content> >);
 
        void as_xml (xmlpp::Node *) const;
@@ -75,8 +111,9 @@ public:
        void set_top_crop (int);
        void set_bottom_crop (int);
 
+       void set_scale (VideoContentScale);
        void set_colour_conversion (ColourConversion);
-
+       
        VideoFrameType video_frame_type () const {
                boost::mutex::scoped_lock lm (_mutex);
                return _video_frame_type;
@@ -106,13 +143,11 @@ public:
                boost::mutex::scoped_lock lm (_mutex);
                return _crop.bottom;
        }
-       
-       void set_ratio (Ratio const *);
 
-       /** @return ratio to scale to, or 0 if the content's own ratio should be preserved. */
-       Ratio const * ratio () const {
+       /** @return Description of how to scale this content (if indeed it should be scaled) */
+       VideoContentScale scale () const {
                boost::mutex::scoped_lock lm (_mutex);
-               return _ratio;
+               return _scale;
        }
 
        ColourConversion colour_conversion () const {
@@ -142,7 +177,7 @@ private:
        libdcp::Size _video_size;
        VideoFrameType _video_frame_type;
        Crop _crop;
-       Ratio const * _ratio;
+       VideoContentScale _scale;
        ColourConversion _colour_conversion;
 };
 
index 05121652aa7148312affcf820a189d978d9cf08c..3dfbd63b57a1c9db685f6eb48415e18b66078889 100644 (file)
@@ -155,7 +155,7 @@ main (int argc, char* argv[])
                        shared_ptr<Content> c = content_factory (film, argv[i]);
                        shared_ptr<VideoContent> vc = dynamic_pointer_cast<VideoContent> (c);
                        if (vc) {
-                               vc->set_ratio (content_ratio);
+                               vc->set_scale (VideoContentScale (content_ratio));
                        }
                        film->examine_and_add_content (c);
                }
index 8854f7e7b54441c5c2689b7b157d4f71c4089384..492968f1bea567e35e383a6a3ff55d2b03f5ec7c 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
 */
 
 #include <wx/spinctrl.h>
-#include "lib/ratio.h"
 #include "lib/filter.h"
 #include "lib/ffmpeg_content.h"
 #include "lib/colour_conversion.h"
 #include "lib/config.h"
 #include "lib/util.h"
+#include "lib/ratio.h"
 #include "filter_dialog.h"
 #include "video_panel.h"
 #include "wx_util.h"
@@ -41,29 +41,26 @@ using boost::dynamic_pointer_cast;
 using boost::bind;
 using boost::optional;
 
-static Ratio const *
-index_to_ratio (int n)
+static VideoContentScale
+index_to_scale (int n)
 {
+       vector<VideoContentScale> scales = VideoContentScale::all ();
        assert (n >= 0);
-       
-       vector<Ratio const *> ratios = Ratio::all ();
-       if (n >= int (ratios.size ())) {
-               return 0;
-       }
-
-       return ratios[n];
+       assert (n < int (scales.size ()));
+       return scales[n];
 }
 
 static int
-ratio_to_index (Ratio const * r)
+scale_to_index (VideoContentScale scale)
 {
-       vector<Ratio const *> ratios = Ratio::all ();
-       size_t i = 0;
-       while (i < ratios.size() && ratios[i] != r) {
-               ++i;
+       vector<VideoContentScale> scales = VideoContentScale::all ();
+       for (size_t i = 0; i < scales.size(); ++i) {
+               if (scales[i] == scale) {
+                       return i;
+               }
        }
 
-       return i;
+       assert (false);
 }
 
 VideoPanel::VideoPanel (FilmEditor* e)
@@ -132,16 +129,16 @@ VideoPanel::VideoPanel (FilmEditor* e)
        ++r;
 
        add_label_to_grid_bag_sizer (grid, this, _("Scale to"), true, wxGBPosition (r, 0));
-       _ratio = new ContentChoice<VideoContent, Ratio const *> (
+       _scale = new ContentChoice<VideoContent, VideoContentScale> (
                this,
                new wxChoice (this, wxID_ANY),
-               VideoContentProperty::VIDEO_RATIO,
-               boost::mem_fn (&VideoContent::ratio),
-               boost::mem_fn (&VideoContent::set_ratio),
-               &index_to_ratio,
-               &ratio_to_index
+               VideoContentProperty::VIDEO_SCALE,
+               boost::mem_fn (&VideoContent::scale),
+               boost::mem_fn (&VideoContent::set_scale),
+               &index_to_scale,
+               &scale_to_index
                );
-       _ratio->add (grid, wxGBPosition (r, 1));
+       _scale->add (grid, wxGBPosition (r, 1));
        ++r;
 
        {
@@ -190,12 +187,11 @@ VideoPanel::VideoPanel (FilmEditor* e)
        _right_crop->wrapped()->SetRange (0, 1024);
        _bottom_crop->wrapped()->SetRange (0, 1024);
 
-       vector<Ratio const *> ratios = Ratio::all ();
-       _ratio->wrapped()->Clear ();
-       for (vector<Ratio const *>::iterator i = ratios.begin(); i != ratios.end(); ++i) {
-               _ratio->wrapped()->Append (std_to_wx ((*i)->nickname ()));
+       vector<VideoContentScale> scales = VideoContentScale::all ();
+       _scale->wrapped()->Clear ();
+       for (vector<VideoContentScale>::iterator i = scales.begin(); i != scales.end(); ++i) {
+               _scale->wrapped()->Append (std_to_wx (i->name ()));
        }
-       _ratio->wrapped()->Append (_("No stretch"));
 
        _frame_type->wrapped()->Append (_("2D"));
        _frame_type->wrapped()->Append (_("3D left/right"));
@@ -234,7 +230,7 @@ VideoPanel::film_content_changed (int property)
                setup_description ();
        } else if (property == VideoContentProperty::VIDEO_CROP) {
                setup_description ();
-       } else if (property == VideoContentProperty::VIDEO_RATIO) {
+       } else if (property == VideoContentProperty::VIDEO_SCALE) {
                setup_description ();
        } else if (property == VideoContentProperty::VIDEO_FRAME_RATE) {
                setup_description ();
@@ -309,19 +305,17 @@ VideoPanel::setup_description ()
                ++lines;
        }
 
-       Ratio const * ratio = vcs->ratio ();
-       libdcp::Size container_size = fit_ratio_within (_editor->film()->container()->ratio (), _editor->film()->full_frame ());
-       float const ratio_value = ratio ? ratio->ratio() : vcs->video_size_after_crop().ratio ();
+       libdcp::Size const container_size = fit_ratio_within (_editor->film()->container()->ratio (), _editor->film()->full_frame ());
+       libdcp::Size const scaled = vcs->scale().size (vcs, container_size);
 
-       /* We have a specified ratio to scale to */
-       libdcp::Size const scaled = fit_ratio_within (ratio_value, container_size);
-       
-       d << wxString::Format (
-               _("Scaled to %dx%d (%.2f:1)\n"),
-               scaled.width, scaled.height,
-               scaled.ratio ()
-               );
-       ++lines;
+       if (scaled != vcs->video_size_after_crop ()) {
+               d << wxString::Format (
+                       _("Scaled to %dx%d (%.2f:1)\n"),
+                       scaled.width, scaled.height,
+                       scaled.ratio ()
+                       );
+               ++lines;
+       }
        
        if (scaled != container_size) {
                d << wxString::Format (
@@ -374,7 +368,7 @@ VideoPanel::content_selection_changed ()
        _top_crop->set_content (sel);
        _bottom_crop->set_content (sel);
        _frame_type->set_content (sel);
-       _ratio->set_content (sel);
+       _scale->set_content (sel);
 
        /* Things that are only allowed with single selections */
        _filters_button->Enable (single);
index 2f0c97cb7643f399fbfbd4635972ae39d41b990a..99633491d835ea9948538ad696459035e5f16876 100644 (file)
@@ -41,12 +41,12 @@ private:
 
        void setup_description ();
 
-       ContentChoice<VideoContent, VideoFrameType>* _frame_type;
-       ContentSpinCtrl<VideoContent>*               _left_crop;
-       ContentSpinCtrl<VideoContent>*               _right_crop;
-       ContentSpinCtrl<VideoContent>*               _top_crop;
-       ContentSpinCtrl<VideoContent>*               _bottom_crop;
-       ContentChoice<VideoContent, Ratio const *>*  _ratio;
+       ContentChoice<VideoContent, VideoFrameType>*    _frame_type;
+       ContentSpinCtrl<VideoContent>*                  _left_crop;
+       ContentSpinCtrl<VideoContent>*                  _right_crop;
+       ContentSpinCtrl<VideoContent>*                  _top_crop;
+       ContentSpinCtrl<VideoContent>*                  _bottom_crop;
+       ContentChoice<VideoContent, VideoContentScale>* _scale;
        wxStaticText* _description;
        wxStaticText* _filters;
        wxButton* _filters_button;
index ee9ac0d9817c6f2fd7e19fca65d3bccf9f92c0b0..5224fae833baaa9c274762eb41535096b1380355 100644 (file)
@@ -31,7 +31,7 @@ BOOST_AUTO_TEST_CASE (fourk_test)
        shared_ptr<Film> film = new_test_film ("4k_test");
        film->set_name ("4k_test");
        shared_ptr<FFmpegContent> c (new FFmpegContent (film, "test/data/test.mp4"));
-       c->set_ratio (Ratio::from_id ("185"));
+       c->set_scale (VideoContentScale (Ratio::from_id ("185")));
        film->set_resolution (RESOLUTION_4K);
        film->set_dcp_content_type (DCPContentType::from_dci_name ("FTR"));
        film->set_container (Ratio::from_id ("185"));
index 9e8aa381bbd0cb0832006fe2a7d6108b71699bac..c2170d891744f3ce14848a9a372acdd0cdd5eb2a 100644 (file)
@@ -38,9 +38,9 @@ BOOST_AUTO_TEST_CASE (black_fill_test)
        film->set_container (Ratio::from_id ("185"));
        film->set_sequence_video (false);
        shared_ptr<ImageContent> contentA (new ImageContent (film, "test/data/simple_testcard_640x480.png"));
-       contentA->set_ratio (Ratio::from_id ("185"));
+       contentA->set_scale (VideoContentScale (Ratio::from_id ("185")));
        shared_ptr<ImageContent> contentB (new ImageContent (film, "test/data/simple_testcard_640x480.png"));
-       contentB->set_ratio (Ratio::from_id ("185"));
+       contentB->set_scale (VideoContentScale (Ratio::from_id ("185")));
 
        film->examine_and_add_content (contentA);
        film->examine_and_add_content (contentB);
index 65c29325c348178b2fd4febc13fa8ac7f01044ff..2e83d45c9101dbef0c064e3c0e26ef5446bcab85 100644 (file)
@@ -39,7 +39,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_audio_test)
        shared_ptr<Film> film = new_test_film ("ffmpeg_audio_test");
        film->set_name ("ffmpeg_audio_test");
        shared_ptr<FFmpegContent> c (new FFmpegContent (film, "test/data/staircase.mov"));
-       c->set_ratio (Ratio::from_id ("185"));
+       c->set_scale (VideoContentScale (Ratio::from_id ("185")));
        film->examine_and_add_content (c);
 
        wait_for_jobs ();
index c79acd3dfb30deda09577736875a2d1d23c6cb67..88b1e94af063de1ef394bd85afcebc39c69ee918 100644 (file)
@@ -36,7 +36,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_dcp_test)
        shared_ptr<Film> film = new_test_film ("ffmpeg_dcp_test");
        film->set_name ("test_film2");
        shared_ptr<FFmpegContent> c (new FFmpegContent (film, "test/data/test.mp4"));
-       c->set_ratio (Ratio::from_id ("185"));
+       c->set_scale (VideoContentScale (Ratio::from_id ("185")));
        film->examine_and_add_content (c);
 
        wait_for_jobs ();
index c936fe8d45fa4175e8c774d1782238e35a28b6bf..f0cf3fe4a5bf89a3b473abac7af75d9071b89076 100644 (file)
@@ -33,7 +33,7 @@ using boost::shared_ptr;
 
 static void scaling_test_for (shared_ptr<Film> film, shared_ptr<VideoContent> content, string image, string container)
 {
-       content->set_ratio (Ratio::from_id (image));
+       content->set_scale (VideoContentScale (Ratio::from_id (image)));
        film->set_container (Ratio::from_id (container));
        film->make_dcp ();
 
index 31a95e38278d36c8d79c58a9a372147cbe2f4dda..8da9b46a891fa8daeed4cd406eb784d23b8c7cc6 100644 (file)
@@ -32,7 +32,7 @@ BOOST_AUTO_TEST_CASE (threed_test)
        shared_ptr<Film> film = new_test_film ("threed_test");
        film->set_name ("test_film2");
        shared_ptr<FFmpegContent> c (new FFmpegContent (film, "test/data/test.mp4"));
-       c->set_ratio (Ratio::from_id ("185"));
+       c->set_scale (VideoContentScale (Ratio::from_id ("185")));
        c->set_video_frame_type (VIDEO_FRAME_TYPE_3D_LEFT_RIGHT);
        film->examine_and_add_content (c);