diff options
| author | Carl Hetherington <cth@carlh.net> | 2013-05-21 23:19:31 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2013-05-21 23:19:31 +0100 |
| commit | b9f6e9512017dc1ecd3a42aa1ef3c6058608cef5 (patch) | |
| tree | 0c5ccae6f26d46c270e9287a722b63e397900c57 /src/lib | |
| parent | 02e4022f540915f8a38f9ab9576ac896fe39a1ab (diff) | |
Give Film a container; move crop into video content; other bits.
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/config.cc | 16 | ||||
| -rw-r--r-- | src/lib/config.h | 12 | ||||
| -rw-r--r-- | src/lib/container.cc | 83 | ||||
| -rw-r--r-- | src/lib/container.h | 78 | ||||
| -rw-r--r-- | src/lib/encoder.cc | 4 | ||||
| -rw-r--r-- | src/lib/ffmpeg_decoder.cc | 3 | ||||
| -rw-r--r-- | src/lib/ffmpeg_decoder.h | 4 | ||||
| -rw-r--r-- | src/lib/film.cc | 122 | ||||
| -rw-r--r-- | src/lib/film.h | 28 | ||||
| -rw-r--r-- | src/lib/filter_graph.cc | 6 | ||||
| -rw-r--r-- | src/lib/imagemagick_decoder.cc | 4 | ||||
| -rw-r--r-- | src/lib/util.cc | 2 | ||||
| -rw-r--r-- | src/lib/video_content.cc | 81 | ||||
| -rw-r--r-- | src/lib/video_content.h | 13 | ||||
| -rw-r--r-- | src/lib/video_decoder.cc | 5 | ||||
| -rw-r--r-- | src/lib/video_decoder.h | 4 | ||||
| -rw-r--r-- | src/lib/writer.cc | 4 | ||||
| -rw-r--r-- | src/lib/wscript | 1 |
18 files changed, 318 insertions, 152 deletions
diff --git a/src/lib/config.cc b/src/lib/config.cc index 3beb0aea6..c5245bfb4 100644 --- a/src/lib/config.cc +++ b/src/lib/config.cc @@ -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 ()); diff --git a/src/lib/config.h b/src/lib/config.h index 96aa4e449..c43a4f079 100644 --- a/src/lib/config.h +++ b/src/lib/config.h @@ -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 index 000000000..6eaea7300 --- /dev/null +++ b/src/lib/container.cc @@ -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 index 000000000..fc3c72792 --- /dev/null +++ b/src/lib/container.h @@ -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; +}; diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 95e98ab76..52927c5d3 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -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(), diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index a637160ae..fcb2e82ba 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -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); diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h index f3f6b126b..7aadef105 100644 --- a/src/lib/ffmpeg_decoder.h +++ b/src/lib/ffmpeg_decoder.h @@ -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 */ diff --git a/src/lib/film.cc b/src/lib/film.cc index ef67a2704..f05362d56 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -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 diff --git a/src/lib/film.h b/src/lib/film.h index 6dd2b446d..9b01dc604 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -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 */ diff --git a/src/lib/filter_graph.cc b/src/lib/filter_graph.cc index a52c030fe..09bbf5dcd 100644 --- a/src/lib/filter_graph.cc +++ b/src/lib/filter_graph.cc @@ -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) { diff --git a/src/lib/imagemagick_decoder.cc b/src/lib/imagemagick_decoder.cc index dd18ad64e..c6b19b742 100644 --- a/src/lib/imagemagick_decoder.cc +++ b/src/lib/imagemagick_decoder.cc @@ -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; diff --git a/src/lib/util.cc b/src/lib/util.cc index de5fbf8d1..e1bc560c6 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -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 (); diff --git a/src/lib/video_content.cc b/src/lib/video_content.cc index 9fb2b9bce..cb31b6476 100644 --- a/src/lib/video_content.cc +++ b/src/lib/video_content.cc @@ -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); +} + diff --git a/src/lib/video_content.h b/src/lib/video_content.h index 75e507d4d..67217e10c 100644 --- a/src/lib/video_content.h +++ b/src/lib/video_content.h @@ -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 diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc index 533fdcf1a..0c8cda294 100644 --- a/src/lib/video_decoder.cc +++ b/src/lib/video_decoder.cc @@ -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)); } } diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h index a73c7d11e..286a0d6e4 100644 --- a/src/lib/video_decoder.h +++ b/src/lib/video_decoder.h @@ -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; }; diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 96c797c5a..aef7230dd 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -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 () ) ); diff --git a/src/lib/wscript b/src/lib/wscript index d8cc8261d..1da245484 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -13,6 +13,7 @@ sources = """ audio_source.cc config.cc combiner.cc + container.cc content.cc cross.cc dci_metadata.cc |
