Give Film a container; move crop into video content; other bits.
authorCarl Hetherington <cth@carlh.net>
Tue, 21 May 2013 22:19:31 +0000 (23:19 +0100)
committerCarl Hetherington <cth@carlh.net>
Tue, 21 May 2013 22:19:31 +0000 (23:19 +0100)
25 files changed:
branch-notes
src/lib/config.cc
src/lib/config.h
src/lib/container.cc [new file with mode: 0644]
src/lib/container.h [new file with mode: 0644]
src/lib/encoder.cc
src/lib/ffmpeg_decoder.cc
src/lib/ffmpeg_decoder.h
src/lib/film.cc
src/lib/film.h
src/lib/filter_graph.cc
src/lib/imagemagick_decoder.cc
src/lib/util.cc
src/lib/video_content.cc
src/lib/video_content.h
src/lib/video_decoder.cc
src/lib/video_decoder.h
src/lib/writer.cc
src/lib/wscript
src/wx/config_dialog.cc
src/wx/config_dialog.h
src/wx/film_editor.cc
src/wx/film_editor.h
src/wx/film_viewer.cc
test/test.cc

index 1348831350cb3bdacf6408818c88d906054f451f..3695ecfd5764aca8b07450301caa5c6ebd4591cc 100644 (file)
@@ -6,3 +6,4 @@ things to put back
        overall length?
        trim method (trim in general)
        A/B
+
index 3beb0aea62327c14bae36e4132344fa61550f0cd..c5245bfb47135eaf61b01e949caabf8a1f964de2 100644 (file)
@@ -27,7 +27,7 @@
 #include "server.h"
 #include "scaler.h"
 #include "filter.h"
-#include "format.h"
+#include "container.h"
 #include "dcp_content_type.h"
 #include "sound_processor.h"
 
@@ -52,7 +52,7 @@ Config::Config ()
        , _tms_path (N_("."))
        , _sound_processor (SoundProcessor::from_id (N_("dolby_cp750")))
        , _default_still_length (10)
-       , _default_format (0)
+       , _default_container (0)
        , _default_dcp_content_type (0)
 {
        _allowed_dcp_frame_rates.push_back (24);
@@ -104,9 +104,9 @@ Config::read ()
 
        _language = f.optional_string_child ("Language");
 
-       c = f.optional_string_child ("DefaultFormat");
+       c = f.optional_string_child ("DefaultContainer");
        if (c) {
-               _default_format = Format::from_id (c.get ());
+               _default_container = Container::from_id (c.get ());
        }
 
        c = f.optional_string_child ("DefaultDCPContentType");
@@ -167,8 +167,8 @@ Config::read_old_metadata ()
                        _sound_processor = SoundProcessor::from_id (v);
                } else if (k == "language") {
                        _language = v;
-               } else if (k == "default_format") {
-                       _default_format = Format::from_id (v);
+               } else if (k == "default_container") {
+                       _default_container = Container::from_id (v);
                } else if (k == "default_dcp_content_type") {
                        _default_dcp_content_type = DCPContentType::from_dci_name (v);
                } else if (k == "dcp_metadata_issuer") {
@@ -247,8 +247,8 @@ Config::write () const
        if (_language) {
                root->add_child("Language")->add_child_text (_language.get());
        }
-       if (_default_format) {
-               root->add_child("DefaultFormat")->add_child_text (_default_format->id ());
+       if (_default_container) {
+               root->add_child("DefaultContainer")->add_child_text (_default_container->id ());
        }
        if (_default_dcp_content_type) {
                root->add_child("DefaultDCPContentType")->add_child_text (_default_dcp_content_type->dci_name ());
index 96aa4e44969d730d1490263b8c094b32d8370dbc..c43a4f079ef4b9753ebb02ea50ec2a2633f4758e 100644 (file)
@@ -34,7 +34,7 @@ class ServerDescription;
 class Scaler;
 class Filter;
 class SoundProcessor;
-class Format;
+class Container;
 class DCPContentType;
 
 /** @class Config
@@ -114,8 +114,8 @@ public:
                return _default_still_length;
        }
 
-       Format const * default_format () const {
-               return _default_format;
+       Container const * default_container () const {
+               return _default_container;
        }
 
        DCPContentType const * default_dcp_content_type () const {
@@ -193,8 +193,8 @@ public:
                _default_still_length = s;
        }
 
-       void set_default_format (Format const * f) {
-               _default_format = f;
+       void set_default_container (Container const * f) {
+               _default_container = f;
        }
 
        void set_default_dcp_content_type (DCPContentType const * t) {
@@ -244,7 +244,7 @@ private:
        DCIMetadata _default_dci_metadata;
        boost::optional<std::string> _language;
        int _default_still_length;
-       Format const * _default_format;
+       Container const * _default_container;
        DCPContentType const * _default_dcp_content_type;
        libdcp::XMLMetadata _dcp_metadata;
 
diff --git a/src/lib/container.cc b/src/lib/container.cc
new file mode 100644 (file)
index 0000000..6eaea73
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+    Copyright (C) 2013 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
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <sstream>
+#include <libdcp/types.h>
+#include "container.h"
+
+#include "i18n.h"
+
+using std::string;
+using std::stringstream;
+using std::vector;
+
+vector<Container const *> Container::_containers;
+
+void
+Container::setup_containers ()
+{
+       _containers.push_back (new Container (libdcp::Size (1285, 1080), "119", _("1.19"), "F"));
+       _containers.push_back (new Container (libdcp::Size (1436, 1080), "133", _("4:3"), "F"));
+       _containers.push_back (new Container (libdcp::Size (1480, 1080), "137", _("Academy"), "F"));
+       _containers.push_back (new Container (libdcp::Size (1485, 1080), "138", _("1.375"), "F"));
+       _containers.push_back (new Container (libdcp::Size (1793, 1080), "166", _("1.66"), "F"));
+       _containers.push_back (new Container (libdcp::Size (1920, 1080), "178", _("16:9"), "F"));
+       _containers.push_back (new Container (libdcp::Size (1998, 1080), "185", _("Flat"), "F"));
+       _containers.push_back (new Container (libdcp::Size (2048, 858), "239", _("Scope"), "S"));
+       _containers.push_back (new Container (libdcp::Size (2048, 1080), "full-frame", _("Full frame"), "C"));
+}
+
+/** @return A name to be presented to the user */
+string
+Container::name () const
+{
+       stringstream s;
+       if (!_nickname.empty ()) {
+               s << _nickname << " (";
+       }
+
+       s << _dcp_size.width << "x" << _dcp_size.height;
+
+       if (!_nickname.empty ()) {
+               s << ")";
+       }
+
+       return s.str ();
+}
+
+Container const *
+Container::from_id (string i)
+{
+       vector<Container const *>::iterator j = _containers.begin ();
+       while (j != _containers.end() && (*j)->id() != i) {
+               ++j;
+       }
+
+       if (j == _containers.end ()) {
+               return 0;
+       }
+
+       return *j;
+}
+
+float
+Container::ratio () const
+{
+       return static_cast<float> (_dcp_size.width) / _dcp_size.height;
+}
diff --git a/src/lib/container.h b/src/lib/container.h
new file mode 100644 (file)
index 0000000..fc3c727
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+    Copyright (C) 2013 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
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <vector>
+#include <libdcp/util.h>
+
+class Container
+{
+public:
+       Container (libdcp::Size dcp, std::string id, std::string n, std::string d)
+               : _dcp_size (dcp)
+               , _id (id)
+               , _nickname (n)
+               , _dci_name (d)
+       {}
+
+       /** @return size in pixels of the images that we should
+        *  put in a DCP for this ratio.  This size will not correspond
+        *  to the ratio when we are doing things like 16:9 in a Flat frame.
+        */
+       libdcp::Size dcp_size () const {
+               return _dcp_size;
+       }
+
+       std::string id () const {
+               return _id;
+       }
+
+       /** @return Full name to present to the user */
+       std::string name () const;
+
+       /** @return Nickname (e.g. Flat, Scope) */
+       std::string nickname () const {
+               return _nickname;
+       }
+
+       std::string dci_name () const {
+               return _dci_name;
+       }
+
+       float ratio () const;
+       
+       static void setup_containers ();
+       static Container const * from_id (std::string i);
+       static std::vector<Container const *> all () {
+               return _containers;
+       }
+
+private:
+       /** libdcp::Size in pixels of the images that we should
+        *  put in a DCP for this container.
+        */
+       libdcp::Size _dcp_size;
+       /** id for use in metadata */
+       std::string _id;
+       /** nickname (e.g. Flat, Scope) */
+       std::string _nickname;
+       std::string _dci_name;
+
+       /** all available containers */
+       static std::vector<Container const *> _containers;
+};
index 95e98ab760cecb9abbd681840a69b946d2bacbfb..52927c5d324f054250e939f96d9e4b841153e2a1 100644 (file)
@@ -39,6 +39,7 @@
 #include "writer.h"
 #include "player.h"
 #include "audio_mapping.h"
+#include "container.h"
 
 #include "i18n.h"
 
@@ -208,9 +209,10 @@ Encoder::process_video (shared_ptr<const Image> image, bool same, shared_ptr<Sub
                /* Queue this new frame for encoding */
                pair<string, string> const s = Filter::ffmpeg_strings (_film->filters());
                TIMING ("adding to queue of %1", _queue.size ());
+               /* XXX: padding */
                _queue.push_back (shared_ptr<DCPVideoFrame> (
                                          new DCPVideoFrame (
-                                                 image, sub, _film->format()->dcp_size(), _film->format()->dcp_padding (_film),
+                                                 image, sub, _film->container()->dcp_size(), 0,
                                                  _film->subtitle_offset(), _film->subtitle_scale(),
                                                  _film->scaler(), _video_frames_out, _film->dcp_video_frame_rate(), s.second,
                                                  _film->colour_lut(), _film->j2k_bandwidth(),
index a637160ae918228ad73c7e9aba46ce49dbdc1e7d..fcb2e82baabd84de4b0f6d53169a92831b920809 100644 (file)
@@ -68,7 +68,7 @@ boost::mutex FFmpegDecoder::_mutex;
 
 FFmpegDecoder::FFmpegDecoder (shared_ptr<const Film> f, shared_ptr<const FFmpegContent> c, bool video, bool audio, bool subtitles)
        : Decoder (f)
-       , VideoDecoder (f)
+       , VideoDecoder (f, c)
        , AudioDecoder (f, c)
        , _ffmpeg_content (c)
        , _format_context (0)
@@ -540,7 +540,6 @@ void
 FFmpegDecoder::film_changed (Film::Property p)
 {
        switch (p) {
-       case Film::CROP:
        case Film::FILTERS:
        {
                boost::mutex::scoped_lock lm (_filter_graphs_mutex);
index f3f6b126b3a183cdb9a2c1b931699f9b0ac0b24e..7aadef10583902af29d22b4563c5047c91b175c2 100644 (file)
@@ -83,6 +83,10 @@ public:
        bool seek_back ();
        bool pass ();
 
+       boost::shared_ptr<const FFmpegContent> ffmpeg_content () const {
+               return _ffmpeg_content;
+       }
+
 private:
 
        /* No copy construction */
index ef67a270420ab3b9e62c5c5a5d59e6bcc9cd400c..f05362d56234abf830620118dbcd2049d81bc57c 100644 (file)
@@ -34,7 +34,7 @@
 #include <libxml++/libxml++.h>
 #include <libcxml/cxml.h>
 #include "film.h"
-#include "format.h"
+#include "container.h"
 #include "job.h"
 #include "filter.h"
 #include "util.h"
@@ -95,7 +95,7 @@ Film::Film (string d, bool must_exist)
        : _playlist (new Playlist)
        , _use_dci_name (true)
        , _dcp_content_type (Config::instance()->default_dcp_content_type ())
-       , _format (Config::instance()->default_format ())
+       , _container (Config::instance()->default_container ())
        , _scaler (Scaler::from_id ("bicubic"))
        , _ab (false)
        , _audio_gain (0)
@@ -160,8 +160,7 @@ Film::Film (Film const & o)
        , _name              (o._name)
        , _use_dci_name      (o._use_dci_name)
        , _dcp_content_type  (o._dcp_content_type)
-       , _format            (o._format)
-       , _crop              (o._crop)
+       , _container         (o._container)
        , _filters           (o._filters)
        , _scaler            (o._scaler)
        , _ab                (o._ab)
@@ -183,15 +182,14 @@ Film::Film (Film const & o)
 string
 Film::video_state_identifier () const
 {
-       assert (format ());
+       assert (container ());
        LocaleGuard lg;
 
        pair<string, string> f = Filter::ffmpeg_strings (filters());
 
        stringstream s;
-       s << format()->id()
+       s << container()->id()
          << "_" << _playlist->video_digest()
-         << "_" << crop().left << "_" << crop().right << "_" << crop().top << "_" << crop().bottom
          << "_" << _dcp_video_frame_rate
          << "_" << f.first << "_" << f.second
          << "_" << scaler()->id()
@@ -305,8 +303,8 @@ Film::make_dcp ()
        pair<string, int> const c = cpu_info ();
        log()->log (String::compose ("CPU: %1, %2 processors", c.first, c.second));
        
-       if (format() == 0) {
-               throw MissingSettingError (_("format"));
+       if (container() == 0) {
+               throw MissingSettingError (_("container"));
        }
 
        if (_playlist->content().empty ()) {
@@ -377,7 +375,7 @@ Film::send_dcp_to_tms ()
 int
 Film::encoded_frames () const
 {
-       if (format() == 0) {
+       if (container() == 0) {
                return 0;
        }
 
@@ -410,15 +408,10 @@ Film::write_metadata () const
                root->add_child("DCPContentType")->add_child_text (_dcp_content_type->dci_name ());
        }
 
-       if (_format) {
-               root->add_child("Format")->add_child_text (_format->id ());
+       if (_container) {
+               root->add_child("Container")->add_child_text (_container->id ());
        }
 
-       root->add_child("LeftCrop")->add_child_text (boost::lexical_cast<string> (_crop.left));
-       root->add_child("RightCrop")->add_child_text (boost::lexical_cast<string> (_crop.right));
-       root->add_child("TopCrop")->add_child_text (boost::lexical_cast<string> (_crop.top));
-       root->add_child("BottomCrop")->add_child_text (boost::lexical_cast<string> (_crop.bottom));
-
        for (vector<Filter const *>::const_iterator i = _filters.begin(); i != _filters.end(); ++i) {
                root->add_child("Filter")->add_child_text ((*i)->id ());
        }
@@ -466,17 +459,12 @@ Film::read_metadata ()
        }
 
        {
-               optional<string> c = f.optional_string_child ("Format");
+               optional<string> c = f.optional_string_child ("Container");
                if (c) {
-                       _format = Format::from_id (c.get ());
+                       _container = Container::from_id (c.get ());
                }
        }
 
-       _crop.left = f.number_child<int> ("LeftCrop");
-       _crop.right = f.number_child<int> ("RightCrop");
-       _crop.top = f.number_child<int> ("TopCrop");
-       _crop.bottom = f.number_child<int> ("BottomCrop");
-
        {
                list<shared_ptr<cxml::Node> > c = f.node_children ("Filter");
                for (list<shared_ptr<cxml::Node> >::iterator i = c.begin(); i != c.end(); ++i) {
@@ -502,15 +490,6 @@ Film::read_metadata ()
        _dirty = false;
 }
 
-libdcp::Size
-Film::cropped_size (libdcp::Size s) const
-{
-       boost::mutex::scoped_lock lm (_state_mutex);
-       s.width -= _crop.left + _crop.right;
-       s.height -= _crop.top + _crop.bottom;
-       return s;
-}
-
 /** Given a directory name, return its full path within the Film's directory.
  *  The directory (and its parents) will be created if they do not exist.
  */
@@ -570,8 +549,8 @@ Film::dci_name (bool if_created_now) const
                d << "_" << dcp_content_type()->dci_name();
        }
 
-       if (format()) {
-               d << "_" << format()->dci_name();
+       if (container()) {
+               d << "_" << container()->dci_name();
        }
 
        DCIMetadata const dm = dci_metadata ();
@@ -666,80 +645,13 @@ Film::set_dcp_content_type (DCPContentType const * t)
 }
 
 void
-Film::set_format (Format const * f)
+Film::set_container (Container const * c)
 {
        {
                boost::mutex::scoped_lock lm (_state_mutex);
-               _format = f;
-       }
-       signal_changed (FORMAT);
-}
-
-void
-Film::set_crop (Crop c)
-{
-       {
-               boost::mutex::scoped_lock lm (_state_mutex);
-               _crop = c;
-       }
-       signal_changed (CROP);
-}
-
-void
-Film::set_left_crop (int c)
-{
-       {
-               boost::mutex::scoped_lock lm (_state_mutex);
-               
-               if (_crop.left == c) {
-                       return;
-               }
-               
-               _crop.left = c;
-       }
-       signal_changed (CROP);
-}
-
-void
-Film::set_right_crop (int c)
-{
-       {
-               boost::mutex::scoped_lock lm (_state_mutex);
-               if (_crop.right == c) {
-                       return;
-               }
-               
-               _crop.right = c;
-       }
-       signal_changed (CROP);
-}
-
-void
-Film::set_top_crop (int c)
-{
-       {
-               boost::mutex::scoped_lock lm (_state_mutex);
-               if (_crop.top == c) {
-                       return;
-               }
-               
-               _crop.top = c;
-       }
-       signal_changed (CROP);
-}
-
-void
-Film::set_bottom_crop (int c)
-{
-       {
-               boost::mutex::scoped_lock lm (_state_mutex);
-               if (_crop.bottom == c) {
-                       return;
-               }
-               
-               _crop.bottom = c;
+               _container = c;
        }
-       signal_changed (CROP);
+       signal_changed (CONTAINER);
 }
 
 void
index 6dd2b446dc499be4898538d7d4bf25697e00866d..9b01dc6047adfe89a8ff21637c417b11192b5428 100644 (file)
@@ -39,7 +39,7 @@
 #include "playlist.h"
 
 class DCPContentType;
-class Format;
+class Container;
 class Job;
 class Filter;
 class Log;
@@ -88,7 +88,6 @@ public:
 
        void write_metadata () const;
 
-       libdcp::Size cropped_size (libdcp::Size) const;
        std::string dci_name (bool if_created_now) const;
        std::string dcp_name (bool if_created_now = false) const;
 
@@ -131,8 +130,7 @@ public:
                CONTENT,
                LOOP,
                DCP_CONTENT_TYPE,
-               FORMAT,
-               CROP,
+               CONTAINER,
                FILTERS,
                SCALER,
                AB,
@@ -170,14 +168,9 @@ public:
                return _dcp_content_type;
        }
 
-       Format const * format () const {
+       Container const * container () const {
                boost::mutex::scoped_lock lm (_state_mutex);
-               return _format;
-       }
-
-       Crop crop () const {
-               boost::mutex::scoped_lock lm (_state_mutex);
-               return _crop;
+               return _container;
        }
 
        std::vector<Filter const *> filters () const {
@@ -249,12 +242,7 @@ public:
        void add_content (boost::shared_ptr<Content>);
        void remove_content (boost::shared_ptr<Content>);
        void set_dcp_content_type (DCPContentType const *);
-       void set_format (Format const *);
-       void set_crop (Crop);
-       void set_left_crop (int);
-       void set_right_crop (int);
-       void set_top_crop (int);
-       void set_bottom_crop (int);
+       void set_container (Container const *);
        void set_filters (std::vector<Filter const *>);
        void set_scaler (Scaler const *);
        void set_ab (bool);
@@ -309,10 +297,8 @@ private:
        bool _use_dci_name;
        /** The type of content that this Film represents (feature, trailer etc.) */
        DCPContentType const * _dcp_content_type;
-       /** The format to present this Film in (flat, scope, etc.) */
-       Format const * _format;
-       /** The crop to apply to the source */
-       Crop _crop;
+       /** The container to put this Film in (flat, scope, etc.) */
+       Container const * _container;
        /** Video filters that should be used when generating DCPs */
        std::vector<Filter const *> _filters;
        /** Scaler algorithm to use */
index a52c030fe549d475be012dbbf7788b2764f5d25d..09bbf5dcd327d2e00116c3229da97721b70f92b1 100644 (file)
@@ -68,7 +68,11 @@ FilterGraph::FilterGraph (shared_ptr<const Film> film, FFmpegDecoder* decoder, l
                filters += N_(",");
        }
 
-       filters += crop_string (Position (film->crop().left, film->crop().top), film->cropped_size (decoder->native_size()));
+       Crop crop = decoder->ffmpeg_content()->crop ();
+       libdcp::Size cropped_size = decoder->native_size ();
+       cropped_size.width -= crop.left + crop.right;
+       cropped_size.height -= crop.top + crop.bottom;
+       filters += crop_string (Position (crop.left, crop.top), cropped_size);
 
        AVFilterGraph* graph = avfilter_graph_alloc();
        if (graph == 0) {
index dd18ad64ed03e94957343f8105ca34eb0353a658..c6b19b742bf72a9037842d2ff02b6b9891eece43 100644 (file)
@@ -34,7 +34,7 @@ using libdcp::Size;
 
 ImageMagickDecoder::ImageMagickDecoder (shared_ptr<const Film> f, shared_ptr<const ImageMagickContent> c)
        : Decoder (f)
-       , VideoDecoder (f)
+       , VideoDecoder (f, c)
        , _imagemagick_content (c)
        , _position (0)
 {
@@ -92,7 +92,7 @@ ImageMagickDecoder::pass ()
 
        delete magick_image;
 
-       _image = _image->crop (_film->crop(), true);
+       _image = _image->crop (_imagemagick_content->crop(), true);
        emit_video (_image, false, double (_position) / 24);
 
        ++_position;
index de5fbf8d18ecb56182a799d6a58f23532b39bc30..e1bc560c613e9fc21267435255d5b93e7edb89ef 100644 (file)
@@ -61,6 +61,7 @@ extern "C" {
 #include "filter.h"
 #include "sound_processor.h"
 #include "config.h"
+#include "container.h"
 #ifdef DVDOMATIC_WINDOWS
 #include "stack.hpp"
 #endif
@@ -285,6 +286,7 @@ dcpomatic_setup ()
        avfilter_register_all ();
        
        Format::setup_formats ();
+       Container::setup_containers ();
        DCPContentType::setup_dcp_content_types ();
        Scaler::setup_scalers ();
        Filter::setup_filters ();
index 9fb2b9bce8f3a4c12860ee6bae4ab00e8b2ef59f..cb31b6476863cf506ecb84c006c7e5f32e955684 100644 (file)
@@ -26,6 +26,7 @@
 int const VideoContentProperty::VIDEO_LENGTH = 0;
 int const VideoContentProperty::VIDEO_SIZE = 1;
 int const VideoContentProperty::VIDEO_FRAME_RATE = 2;
+int const VideoContentProperty::VIDEO_CROP = 3;
 
 using std::string;
 using std::stringstream;
@@ -47,6 +48,10 @@ VideoContent::VideoContent (shared_ptr<const cxml::Node> node)
        _video_size.width = node->number_child<int> ("VideoWidth");
        _video_size.height = node->number_child<int> ("VideoHeight");
        _video_frame_rate = node->number_child<float> ("VideoFrameRate");
+       _crop.left = node->number_child<int> ("LeftCrop");
+       _crop.right = node->number_child<int> ("RightCrop");
+       _crop.top = node->number_child<int> ("TopCrop");
+       _crop.bottom = node->number_child<int> ("BottomCrop");
 }
 
 VideoContent::VideoContent (VideoContent const & o)
@@ -66,6 +71,10 @@ VideoContent::as_xml (xmlpp::Node* node) const
        node->add_child("VideoWidth")->add_child_text (lexical_cast<string> (_video_size.width));
        node->add_child("VideoHeight")->add_child_text (lexical_cast<string> (_video_size.height));
        node->add_child("VideoFrameRate")->add_child_text (lexical_cast<string> (_video_frame_rate));
+       node->add_child("LeftCrop")->add_child_text (boost::lexical_cast<string> (_crop.left));
+       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));
 }
 
 void
@@ -104,3 +113,75 @@ VideoContent::information () const
        
        return s.str ();
 }
+
+void
+VideoContent::set_crop (Crop c)
+{
+       {
+               boost::mutex::scoped_lock lm (_mutex);
+               _crop = c;
+       }
+       signal_changed (VideoContentProperty::VIDEO_CROP);
+}
+
+void
+VideoContent::set_left_crop (int c)
+{
+       {
+               boost::mutex::scoped_lock lm (_mutex);
+               
+               if (_crop.left == c) {
+                       return;
+               }
+               
+               _crop.left = c;
+       }
+       
+       signal_changed (VideoContentProperty::VIDEO_CROP);
+}
+
+void
+VideoContent::set_right_crop (int c)
+{
+       {
+               boost::mutex::scoped_lock lm (_mutex);
+               if (_crop.right == c) {
+                       return;
+               }
+               
+               _crop.right = c;
+       }
+       
+       signal_changed (VideoContentProperty::VIDEO_CROP);
+}
+
+void
+VideoContent::set_top_crop (int c)
+{
+       {
+               boost::mutex::scoped_lock lm (_mutex);
+               if (_crop.top == c) {
+                       return;
+               }
+               
+               _crop.top = c;
+       }
+       
+       signal_changed (VideoContentProperty::VIDEO_CROP);
+}
+
+void
+VideoContent::set_bottom_crop (int c)
+{
+       {
+               boost::mutex::scoped_lock lm (_mutex);
+               if (_crop.bottom == c) {
+                       return;
+               }
+               
+               _crop.bottom = c;
+       }
+
+       signal_changed (VideoContentProperty::VIDEO_CROP);
+}
+
index 75e507d4d799a7cfc24be6224bdaca26099c7eed..67217e10c3838cf020136a118a72772bd93255ac 100644 (file)
@@ -31,6 +31,7 @@ public:
        static int const VIDEO_LENGTH;
        static int const VIDEO_SIZE;
        static int const VIDEO_FRAME_RATE;
+       static int const VIDEO_CROP;
 };
 
 class VideoContent : public virtual Content
@@ -58,6 +59,17 @@ public:
                return _video_frame_rate;
        }
 
+       void set_crop (Crop);
+       void set_left_crop (int);
+       void set_right_crop (int);
+       void set_top_crop (int);
+       void set_bottom_crop (int);
+
+       Crop crop () const {
+               boost::mutex::scoped_lock lm (_mutex);
+               return _crop;
+       }
+
 protected:
        void take_from_video_decoder (boost::shared_ptr<VideoDecoder>);
 
@@ -66,6 +78,7 @@ protected:
 private:
        libdcp::Size _video_size;
        float _video_frame_rate;
+       Crop _crop;
 };
 
 #endif
index 533fdcf1a435d6aeb88eb298285ef6843c40bec4..0c8cda2944c47b7b7bdb97815e9978a69af069d5 100644 (file)
@@ -32,8 +32,9 @@ using std::cout;
 using boost::shared_ptr;
 using boost::optional;
 
-VideoDecoder::VideoDecoder (shared_ptr<const Film> f)
+VideoDecoder::VideoDecoder (shared_ptr<const Film> f, shared_ptr<const VideoContent> c)
        : Decoder (f)
+       , _video_content (c)
        , _video_frame (0)
        , _last_content_time (0)
 {
@@ -72,7 +73,7 @@ VideoDecoder::emit_subtitle (shared_ptr<TimedSubtitle> s)
        
        if (_timed_subtitle) {
                Position const p = _timed_subtitle->subtitle()->position ();
-               _timed_subtitle->subtitle()->set_position (Position (p.x - _film->crop().left, p.y - _film->crop().top));
+               _timed_subtitle->subtitle()->set_position (Position (p.x - _video_content->crop().left, p.y - _video_content->crop().top));
        }
 }
 
index a73c7d11e0e67ff8a9a01b2440f47410cc26ee6f..286a0d6e4770c7ce467a21f1edf4469d9f1dbf92 100644 (file)
@@ -28,7 +28,7 @@ class VideoContent;
 class VideoDecoder : public VideoSource, public virtual Decoder
 {
 public:
-       VideoDecoder (boost::shared_ptr<const Film>);
+       VideoDecoder (boost::shared_ptr<const Film>, boost::shared_ptr<const VideoContent>);
 
        /** @return video frame rate second, or 0 if unknown */
        virtual float video_frame_rate () const = 0;
@@ -60,9 +60,9 @@ protected:
        void emit_subtitle (boost::shared_ptr<TimedSubtitle>);
 
 private:
+       boost::shared_ptr<const VideoContent> _video_content;
        int _video_frame;
        double _last_content_time;
-       
        boost::shared_ptr<TimedSubtitle> _timed_subtitle;
 };
 
index 96c797c5a91e69e5ae9eedfaeb46bdd03c823c45..aef7230dd0834ae735e55c7cc314acdc21ed95fb 100644 (file)
@@ -27,7 +27,7 @@
 #include "writer.h"
 #include "compose.hpp"
 #include "film.h"
-#include "format.h"
+#include "container.h"
 #include "log.h"
 #include "dcp_video_frame.h"
 #include "dcp_content_type.h"
@@ -76,7 +76,7 @@ Writer::Writer (shared_ptr<Film> f, shared_ptr<Job> j)
                        _film->internal_video_mxf_dir (),
                        _film->internal_video_mxf_filename (),
                        _film->dcp_video_frame_rate (),
-                       _film->format()->dcp_size ()
+                       _film->container()->dcp_size ()
                        )
                );
 
index d8cc8261d386bf0f06482b0bd71082312f22762b..1da2454841bc8c047ba0df18ee29b25c1312cca6 100644 (file)
@@ -13,6 +13,7 @@ sources = """
           audio_source.cc
           config.cc
           combiner.cc
+          container.cc
           content.cc
           cross.cc
           dci_metadata.cc
index 50b8990b13a2afcd1c25319512cfc391e9a1275e..ae5bed723253e86aed4c666d1c924a0ec60694d1 100644 (file)
@@ -28,7 +28,7 @@
 #include <wx/notebook.h>
 #include "lib/config.h"
 #include "lib/server.h"
-#include "lib/format.h"
+#include "lib/container.h"
 #include "lib/scaler.h"
 #include "lib/filter.h"
 #include "lib/dcp_content_type.h"
@@ -127,9 +127,9 @@ ConfigDialog::make_misc_panel ()
        table->Add (_default_dci_metadata_button);
        table->AddSpacer (1);
 
-       add_label_to_sizer (table, _misc_panel, _("Default format"));
-       _default_format = new wxChoice (_misc_panel, wxID_ANY);
-       table->Add (_default_format);
+       add_label_to_sizer (table, _misc_panel, _("Default container"));
+       _default_container = new wxChoice (_misc_panel, wxID_ANY);
+       table->Add (_default_container);
        table->AddSpacer (1);
 
        add_label_to_sizer (table, _misc_panel, _("Default content type"));
@@ -171,17 +171,17 @@ ConfigDialog::make_misc_panel ()
 
        _default_dci_metadata_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (ConfigDialog::edit_default_dci_metadata_clicked), 0, this);
 
-       vector<Format const *> fmt = Format::all ();
+       vector<Container const *> fmt = Container::all ();
        int n = 0;
-       for (vector<Format const *>::iterator i = fmt.begin(); i != fmt.end(); ++i) {
-               _default_format->Append (std_to_wx ((*i)->name ()));
-               if (*i == config->default_format ()) {
-                       _default_format->SetSelection (n);
+       for (vector<Container const *>::iterator i = fmt.begin(); i != fmt.end(); ++i) {
+               _default_container->Append (std_to_wx ((*i)->name ()));
+               if (*i == config->default_container ()) {
+                       _default_container->SetSelection (n);
                }
                ++n;
        }
 
-       _default_format->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (ConfigDialog::default_format_changed), 0, this);
+       _default_container->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (ConfigDialog::default_container_changed), 0, this);
        
        vector<DCPContentType const *> const ct = DCPContentType::all ();
        n = 0;
@@ -533,10 +533,10 @@ ConfigDialog::default_still_length_changed (wxCommandEvent &)
 }
 
 void
-ConfigDialog::default_format_changed (wxCommandEvent &)
+ConfigDialog::default_container_changed (wxCommandEvent &)
 {
-       vector<Format const *> fmt = Format::all ();
-       Config::instance()->set_default_format (fmt[_default_format->GetSelection()]);
+       vector<Container const *> fmt = Container::all ();
+       Config::instance()->set_default_container (fmt[_default_container->GetSelection()]);
 }
 
 void
index 5df1a634fd25041eb202404b28e23d7a9981c102..dda846b7db2cea232a4a840aef2be3a26cb199b6 100644 (file)
@@ -57,7 +57,7 @@ private:
        void edit_server_clicked (wxCommandEvent &);
        void remove_server_clicked (wxCommandEvent &);
        void server_selection_changed (wxListEvent &);
-       void default_format_changed (wxCommandEvent &);
+       void default_container_changed (wxCommandEvent &);
        void default_dcp_content_type_changed (wxCommandEvent &);
        void issuer_changed (wxCommandEvent &);
        void creator_changed (wxCommandEvent &);
@@ -79,7 +79,7 @@ private:
        wxPanel* _metadata_panel;
        wxCheckBox* _set_language;
        wxChoice* _language;
-       wxChoice* _default_format;
+       wxChoice* _default_container;
        wxChoice* _default_dcp_content_type;
        wxTextCtrl* _tms_ip;
        wxTextCtrl* _tms_path;
index 4955d9f3d25b084a1525e485e4502374c33081ba..3c5e1e0a7e722984fff4e1c8a42e47e1d2eb978a 100644 (file)
@@ -54,6 +54,7 @@
 #include "imagemagick_content_dialog.h"
 #include "timeline_dialog.h"
 #include "audio_mapping_view.h"
+#include "container.h"
 
 using std::string;
 using std::cout;
@@ -126,6 +127,11 @@ FilmEditor::make_dcp_panel ()
        grid->Add (_edit_dci_button, wxGBPosition (r, 1), wxDefaultSpan);
        ++r;
 
+       add_label_to_grid_bag_sizer (grid, _dcp_panel, _("Container"), wxGBPosition (r, 0));
+       _container = new wxChoice (_dcp_panel, wxID_ANY);
+       grid->Add (_container, wxGBPosition (r, 1));
+       ++r;
+
        add_label_to_grid_bag_sizer (grid, _dcp_panel, _("Content Type"), wxGBPosition (r, 0));
        _dcp_content_type = new wxChoice (_dcp_panel, wxID_ANY);
        grid->Add (_dcp_content_type, wxGBPosition (r, 1));
@@ -137,11 +143,16 @@ FilmEditor::make_dcp_panel ()
                _dcp_frame_rate = new wxChoice (_dcp_panel, wxID_ANY);
                s->Add (_dcp_frame_rate, 1, wxALIGN_CENTER_VERTICAL);
                _best_dcp_frame_rate = new wxButton (_dcp_panel, wxID_ANY, _("Use best"));
-               s->Add (_best_dcp_frame_rate, 1, wxALIGN_CENTER_VERTICAL | wxALL | wxEXPAND, 6);
+               s->Add (_best_dcp_frame_rate, 1, wxALIGN_CENTER_VERTICAL | wxEXPAND);
                grid->Add (s, wxGBPosition (r, 1));
        }
        ++r;
 
+       vector<Container const *> const co = Container::all ();
+       for (vector<Container const *>::const_iterator i = co.begin(); i != co.end(); ++i) {
+               _container->Append (std_to_wx ((*i)->name ()));
+       }
+
        vector<DCPContentType const *> const ct = DCPContentType::all ();
        for (vector<DCPContentType const *>::const_iterator i = ct.begin(); i != ct.end(); ++i) {
                _dcp_content_type->Append (std_to_wx ((*i)->pretty_name ()));
@@ -159,7 +170,8 @@ FilmEditor::connect_to_widgets ()
        _name->Connect                   (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED,         wxCommandEventHandler (FilmEditor::name_changed), 0, this);
        _use_dci_name->Connect           (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED,     wxCommandEventHandler (FilmEditor::use_dci_name_toggled), 0, this);
        _edit_dci_button->Connect        (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED,       wxCommandEventHandler (FilmEditor::edit_dci_button_clicked), 0, this);
-       _format->Connect                 (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED,      wxCommandEventHandler (FilmEditor::format_changed), 0, this);
+       _container->Connect              (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED,      wxCommandEventHandler (FilmEditor::container_changed), 0, this);
+//     _format->Connect                 (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED,      wxCommandEventHandler (FilmEditor::format_changed), 0, this);
        _content->Connect                (wxID_ANY, wxEVT_COMMAND_LIST_ITEM_SELECTED,   wxListEventHandler    (FilmEditor::content_selection_changed), 0, this);
        _content->Connect                (wxID_ANY, wxEVT_COMMAND_LIST_ITEM_DESELECTED, wxListEventHandler    (FilmEditor::content_selection_changed), 0, this);
        _content_add->Connect            (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED,       wxCommandEventHandler (FilmEditor::content_add_clicked), 0, this);
@@ -434,44 +446,48 @@ FilmEditor::make_subtitle_panel ()
 void
 FilmEditor::left_crop_changed (wxCommandEvent &)
 {
-       if (!_film) {
+       shared_ptr<VideoContent> c = selected_video_content ();
+       if (!c) {
                return;
        }
 
-       _film->set_left_crop (_left_crop->GetValue ());
+       c->set_left_crop (_left_crop->GetValue ());
 }
 
 /** Called when the right crop widget has been changed */
 void
 FilmEditor::right_crop_changed (wxCommandEvent &)
 {
-       if (!_film) {
+       shared_ptr<VideoContent> c = selected_video_content ();
+       if (!c) {
                return;
        }
 
-       _film->set_right_crop (_right_crop->GetValue ());
+       c->set_right_crop (_right_crop->GetValue ());
 }
 
 /** Called when the top crop widget has been changed */
 void
 FilmEditor::top_crop_changed (wxCommandEvent &)
 {
-       if (!_film) {
+       shared_ptr<VideoContent> c = selected_video_content ();
+       if (!c) {
                return;
        }
 
-       _film->set_top_crop (_top_crop->GetValue ());
+       c->set_top_crop (_top_crop->GetValue ());
 }
 
 /** Called when the bottom crop value has been changed */
 void
 FilmEditor::bottom_crop_changed (wxCommandEvent &)
 {
-       if (!_film) {
+       shared_ptr<VideoContent> c = selected_video_content ();
+       if (!c) {
                return;
        }
 
-       _film->set_bottom_crop (_bottom_crop->GetValue ());
+       c->set_bottom_crop (_bottom_crop->GetValue ());
 }
 
 /** Called when the name widget has been changed */
@@ -561,7 +577,7 @@ FilmEditor::film_changed (Film::Property p)
        case Film::CONTENT:
                setup_content ();
                setup_formats ();
-               setup_format ();
+//             setup_format ();
                setup_subtitle_control_sensitivity ();
                setup_show_audio_sensitivity ();
                break;
@@ -570,15 +586,8 @@ FilmEditor::film_changed (Film::Property p)
                checked_set (_loop_count, _film->loop());
                setup_loop_sensitivity ();
                break;
-       case Film::FORMAT:
-               setup_format ();
-               break;
-       case Film::CROP:
-               checked_set (_left_crop, _film->crop().left);
-               checked_set (_right_crop, _film->crop().right);
-               checked_set (_top_crop, _film->crop().top);
-               checked_set (_bottom_crop, _film->crop().bottom);
-               setup_scaling_description ();
+       case Film::CONTAINER:
+               setup_container ();
                break;
        case Film::FILTERS:
        {
@@ -655,7 +664,7 @@ FilmEditor::film_changed (Film::Property p)
 }
 
 void
-FilmEditor::film_content_changed (weak_ptr<Content> content, int property)
+FilmEditor::film_content_changed (weak_ptr<Content> weak_content, int property)
 {
        if (!_film) {
                /* We call this method ourselves (as well as using it as a signal handler)
@@ -663,8 +672,20 @@ FilmEditor::film_content_changed (weak_ptr<Content> content, int property)
                */
                return;
        }
-               
-       if (property == FFmpegContentProperty::SUBTITLE_STREAMS) {
+
+       shared_ptr<Content> content = weak_content.lock ();
+       shared_ptr<VideoContent> video_content;
+       if (content) {
+               video_content = dynamic_pointer_cast<VideoContent> (content);
+       }
+
+       if (property == VideoContentProperty::VIDEO_CROP) {
+               checked_set (_left_crop,   video_content ? video_content->crop().left :   0);
+               checked_set (_right_crop,  video_content ? video_content->crop().right :  0);
+               checked_set (_top_crop,    video_content ? video_content->crop().top :    0);
+               checked_set (_bottom_crop, video_content ? video_content->crop().bottom : 0);
+               setup_scaling_description ();
+       } else if (property == FFmpegContentProperty::SUBTITLE_STREAMS) {
                setup_subtitle_control_sensitivity ();
        } else if (property == FFmpegContentProperty::AUDIO_STREAMS) {
                setup_show_audio_sensitivity ();
@@ -675,37 +696,39 @@ FilmEditor::film_content_changed (weak_ptr<Content> content, int property)
 }
 
 void
-FilmEditor::setup_format ()
+FilmEditor::setup_container ()
 {
        int n = 0;
-       vector<Format const *>::iterator i = _formats.begin ();
-       while (i != _formats.end() && *i != _film->format ()) {
+       vector<Container const *> containers = Container::all ();
+       vector<Container const *>::iterator i = containers.begin ();
+       while (i != containers.end() && *i != _film->container ()) {
                ++i;
                ++n;
        }
        
-       if (i == _formats.end()) {
-               checked_set (_format, -1);
+       if (i == containers.end()) {
+               checked_set (_container, -1);
        } else {
-               checked_set (_format, n);
+               checked_set (_container, n);
        }
        
        setup_dcp_name ();
        setup_scaling_description ();
 }      
 
-/** Called when the format widget has been changed */
+/** Called when the container widget has been changed */
 void
-FilmEditor::format_changed (wxCommandEvent &)
+FilmEditor::container_changed (wxCommandEvent &)
 {
        if (!_film) {
                return;
        }
 
-       int const n = _format->GetSelection ();
+       int const n = _container->GetSelection ();
        if (n >= 0) {
-               assert (n < int (_formats.size()));
-               _film->set_format (_formats[n]);
+               vector<Container const *> containers = Container::all ();
+               assert (n < int (containers.size()));
+               _film->set_container (containers[n]);
        }
 }
 
@@ -755,8 +778,7 @@ FilmEditor::set_film (shared_ptr<Film> f)
        film_changed (Film::CONTENT);
        film_changed (Film::LOOP);
        film_changed (Film::DCP_CONTENT_TYPE);
-       film_changed (Film::FORMAT);
-       film_changed (Film::CROP);
+       film_changed (Film::CONTAINER);
        film_changed (Film::FILTERS);
        film_changed (Film::SCALER);
        film_changed (Film::AUDIO_GAIN);
@@ -769,6 +791,7 @@ FilmEditor::set_film (shared_ptr<Film> f)
        film_changed (Film::DCI_METADATA);
        film_changed (Film::DCP_VIDEO_FRAME_RATE);
 
+       film_content_changed (boost::shared_ptr<Content> (), VideoContentProperty::VIDEO_CROP);
        film_content_changed (boost::shared_ptr<Content> (), FFmpegContentProperty::SUBTITLE_STREAMS);
        film_content_changed (boost::shared_ptr<Content> (), FFmpegContentProperty::SUBTITLE_STREAM);
        film_content_changed (boost::shared_ptr<Content> (), FFmpegContentProperty::AUDIO_STREAMS);
@@ -1102,6 +1125,17 @@ FilmEditor::selected_content ()
        return c[s];
 }
 
+shared_ptr<VideoContent>
+FilmEditor::selected_video_content ()
+{
+       shared_ptr<Content> c = selected_content ();
+       if (!c) {
+               return shared_ptr<VideoContent> ();
+       }
+
+       return dynamic_pointer_cast<VideoContent> (c);
+}
+
 void
 FilmEditor::setup_scaling_description ()
 {
index 9123dfdb400e5483ccea64c81a216ee607f97302..3f72642964415324093f8770f1ccfb1b97bbf774 100644 (file)
@@ -35,6 +35,7 @@ class Film;
 class AudioDialog;
 class TimelineDialog;
 class AudioMappingView;
+class Format;
 
 /** @class FilmEditor
  *  @brief A wx widget to edit a film's metadata, and perform various functions.
@@ -69,7 +70,7 @@ private:
        void content_add_clicked (wxCommandEvent &);
        void content_remove_clicked (wxCommandEvent &);
        void imagemagick_video_length_changed (wxCommandEvent &);
-       void format_changed (wxCommandEvent &);
+       void container_changed (wxCommandEvent &);
        void dcp_content_type_changed (wxCommandEvent &);
        void scaler_changed (wxCommandEvent &);
        void audio_gain_changed (wxCommandEvent &);
@@ -103,13 +104,14 @@ private:
        void setup_scaling_description ();
        void setup_main_notebook_size ();
        void setup_content ();
-       void setup_format ();
+       void setup_container ();
        void setup_content_button_sensitivity ();
        void setup_loop_sensitivity ();
        void setup_content_properties ();
        
        void active_jobs_changed (bool);
        boost::shared_ptr<Content> selected_content ();
+       boost::shared_ptr<VideoContent> selected_video_content ();
 
        wxNotebook* _main_notebook;
        wxNotebook* _content_notebook;
@@ -129,6 +131,7 @@ private:
        wxTextCtrl* _name;
        wxStaticText* _dcp_name;
        wxCheckBox* _use_dci_name;
+       wxChoice* _container;
        wxListCtrl* _content;
        wxButton* _content_add;
        wxButton* _content_remove;
index 2f69235c150d953f6d924060ba71de2f484b9804..6a40e88f7ee141d3b878f63968462c34210d7a03 100644 (file)
@@ -27,6 +27,7 @@
 #include <iomanip>
 #include <wx/tglbtn.h>
 #include "lib/film.h"
+#include "lib/container.h"
 #include "lib/format.h"
 #include "lib/util.h"
 #include "lib/job_manager.h"
@@ -115,7 +116,7 @@ void
 FilmViewer::film_changed (Film::Property p)
 {
        switch (p) {
-       case Film::FORMAT:
+       case Film::CONTAINER:
                calculate_sizes ();
                update_from_raw ();
                break;
@@ -135,7 +136,6 @@ FilmViewer::film_changed (Film::Property p)
                break;
        case Film::SCALER:
        case Film::FILTERS:
-       case Film::CROP:
                update_from_decoder ();
                break;
        default:
@@ -173,7 +173,7 @@ FilmViewer::set_film (shared_ptr<Film> f)
        _film->ContentChanged.connect (boost::bind (&FilmViewer::film_content_changed, this, _1, _2));
 
        film_changed (Film::CONTENT);
-       film_changed (Film::FORMAT);
+       film_changed (Film::CONTAINER);
        film_changed (Film::WITH_SUBTITLES);
        film_changed (Film::SUBTITLE_OFFSET);
        film_changed (Film::SUBTITLE_SCALE);
@@ -314,7 +314,8 @@ FilmViewer::raw_to_display ()
                   when working out the scale that we are applying.
                */
 
-               Size const cropped_size = _film->cropped_size (_raw_frame->size ());
+               /* XXX */
+               Size const cropped_size = _raw_frame->size ();//_film->cropped_size (_raw_frame->size ());
 
                Rect tx = subtitle_transformed_area (
                        float (_film_size.width) / cropped_size.width,
@@ -337,10 +338,10 @@ FilmViewer::calculate_sizes ()
                return;
        }
 
-       Format const * format = _film->format ();
+       Container const * container = _film->container ();
        
        float const panel_ratio = static_cast<float> (_panel_size.width) / _panel_size.height;
-       float const film_ratio = format ? format->container_ratio () : 1.78;
+       float const film_ratio = container ? container->ratio () : 1.78;
                        
        if (panel_ratio < film_ratio) {
                /* panel is less widscreen than the film; clamp width */
@@ -356,9 +357,9 @@ FilmViewer::calculate_sizes ()
           of our _display_frame.
        */
        _display_frame_x = 0;
-       if (format) {
-               _display_frame_x = static_cast<float> (format->dcp_padding (_film)) * _out_size.width / format->dcp_size().width;
-       }
+//     if (format) {
+//             _display_frame_x = static_cast<float> (format->dcp_padding (_film)) * _out_size.width / format->dcp_size().width;
+//     }
 
        _film_size = _out_size;
        _film_size.width -= _display_frame_x * 2;
@@ -472,7 +473,9 @@ FilmViewer::film_content_changed (weak_ptr<Content>, int p)
                /* Force an update to our frame */
                wxScrollEvent ev;
                slider_moved (ev);
-       }
+       } else if (p == VideoContentProperty::VIDEO_CROP) {
+               update_from_decoder ();
+       }               
 }
 
 void
index eaf210370e58358fbf42be6803b42746e2fe5c68..68d8611c11a8670a683449d9fca6917606d17129 100644 (file)
@@ -40,6 +40,7 @@
 #include "ffmpeg_decoder.h"
 #include "sndfile_decoder.h"
 #include "dcp_content_type.h"
+#include "container.h"
 #define BOOST_TEST_DYN_LINK
 #define BOOST_TEST_MODULE dcpomatic_test
 #include <boost/test/unit_test.hpp>
@@ -137,18 +138,14 @@ BOOST_AUTO_TEST_CASE (film_metadata_test)
        
        shared_ptr<Film> f (new Film (test_film, false));
        f->_dci_date = boost::gregorian::from_undelimited_string ("20130211");
-       BOOST_CHECK (f->format() == 0);
+       BOOST_CHECK (f->container() == 0);
        BOOST_CHECK (f->dcp_content_type() == 0);
        BOOST_CHECK (f->filters ().empty());
 
        f->set_name ("fred");
 //     BOOST_CHECK_THROW (f->set_content ("jim"), OpenFileError);
        f->set_dcp_content_type (DCPContentType::from_pretty_name ("Short"));
-       f->set_format (Format::from_nickname ("Flat"));
-       f->set_left_crop (1);
-       f->set_right_crop (2);
-       f->set_top_crop (3);
-       f->set_bottom_crop (4);
+       f->set_container (Container::from_id ("185"));
        vector<Filter const *> f_filters;
        f_filters.push_back (Filter::from_id ("pphb"));
        f_filters.push_back (Filter::from_id ("unsharp"));
@@ -164,11 +161,7 @@ BOOST_AUTO_TEST_CASE (film_metadata_test)
 
        BOOST_CHECK_EQUAL (g->name(), "fred");
        BOOST_CHECK_EQUAL (g->dcp_content_type(), DCPContentType::from_pretty_name ("Short"));
-       BOOST_CHECK_EQUAL (g->format(), Format::from_nickname ("Flat"));
-       BOOST_CHECK_EQUAL (g->crop().left, 1);
-       BOOST_CHECK_EQUAL (g->crop().right, 2);
-       BOOST_CHECK_EQUAL (g->crop().top, 3);
-       BOOST_CHECK_EQUAL (g->crop().bottom, 4);
+       BOOST_CHECK_EQUAL (g->container(), Container::from_id ("185"));
        vector<Filter const *> g_filters = g->filters ();
        BOOST_CHECK_EQUAL (g_filters.size(), 2);
        BOOST_CHECK_EQUAL (g_filters.front(), Filter::from_id ("pphb"));
@@ -317,7 +310,7 @@ BOOST_AUTO_TEST_CASE (make_dcp_test)
        shared_ptr<Film> film = new_test_film ("make_dcp_test");
        film->set_name ("test_film2");
 //     film->set_content ("../../../test/test.mp4");
-       film->set_format (Format::from_nickname ("Flat"));
+       film->set_container (Container::from_id ("185"));
        film->set_dcp_content_type (DCPContentType::from_pretty_name ("Test"));
        film->make_dcp ();
        film->write_metadata ();
@@ -348,7 +341,7 @@ BOOST_AUTO_TEST_CASE (make_dcp_with_range_test)
        film->set_name ("test_film3");
 //     film->set_content ("../../../test/test.mp4");
 //     film->examine_content ();
-       film->set_format (Format::from_nickname ("Flat"));
+       film->set_container (Container::from_id ("185"));
        film->set_dcp_content_type (DCPContentType::from_pretty_name ("Test"));
        film->make_dcp ();