diff options
| author | Carl Hetherington <cth@carlh.net> | 2012-08-20 00:54:40 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2012-08-20 00:54:40 +0100 |
| commit | 4d91615b49a3246654baaf7a08f10f303b79b85a (patch) | |
| tree | 8f19add6844bbc9680c455bc3f513395f933663f /src | |
| parent | b6488655b833ecffa6b7934cd83cced49571868c (diff) | |
Proper-ish support for multi-reel DCPs.
Diffstat (limited to 'src')
| -rw-r--r-- | src/cpl.cc | 4 | ||||
| -rw-r--r-- | src/cpl.h | 8 | ||||
| -rw-r--r-- | src/dcp.cc | 158 | ||||
| -rw-r--r-- | src/dcp.h | 41 | ||||
| -rw-r--r-- | src/reel.cc | 115 | ||||
| -rw-r--r-- | src/reel.h | 67 | ||||
| -rw-r--r-- | src/wscript | 2 |
7 files changed, 250 insertions, 145 deletions
@@ -38,7 +38,7 @@ CPL::CPL (string file) content_kind = kind_node ("ContentKind"); content_version = optional_sub_node<ContentVersion> ("ContentVersion"); ignore_node ("RatingList"); - reels = sub_nodes<Reel> ("ReelList", "Reel"); + reels = sub_nodes<CPLReel> ("ReelList", "Reel"); ignore_node ("Issuer"); ignore_node ("Signer"); @@ -55,7 +55,7 @@ ContentVersion::ContentVersion (xmlpp::Node const * node) done (); } -Reel::Reel (xmlpp::Node const * node) +CPLReel::CPLReel (xmlpp::Node const * node) : XMLNode (node) { id = string_node ("Id"); @@ -87,11 +87,11 @@ public: }; /** CPL Reel node */ -class Reel : public XMLNode +class CPLReel : public XMLNode { public: - Reel () {} - Reel (xmlpp::Node const * node); + CPLReel () {} + CPLReel (xmlpp::Node const * node); std::string id; boost::shared_ptr<CPLAssetList> asset_list; @@ -122,7 +122,7 @@ public: std::string content_title_text; ContentKind content_kind; boost::shared_ptr<ContentVersion> content_version; - std::list<boost::shared_ptr<Reel> > reels; + std::list<boost::shared_ptr<CPLReel> > reels; }; } @@ -39,6 +39,7 @@ #include "cpl.h" #include "pkl.h" #include "asset_map.h" +#include "reel.h" using namespace std; using namespace boost; @@ -55,27 +56,9 @@ DCP::DCP (string directory, string name, ContentKind content_kind, int fps, int } void -DCP::add_sound_asset (vector<string> const & files) +DCP::add_reel (shared_ptr<const Reel> reel) { - _assets.push_back (shared_ptr<SoundAsset> (new SoundAsset (files, _directory, "audio.mxf", &Progress, _fps, _length))); -} - -void -DCP::add_sound_asset (sigc::slot<string, Channel> get_path, int channels) -{ - _assets.push_back (shared_ptr<SoundAsset> (new SoundAsset (get_path, _directory, "audio.mxf", &Progress, _fps, _length, channels))); -} - -void -DCP::add_picture_asset (vector<string> const & files, int width, int height) -{ - _assets.push_back (shared_ptr<PictureAsset> (new PictureAsset (files, _directory, "video.mxf", &Progress, _fps, _length, width, height))); -} - -void -DCP::add_picture_asset (sigc::slot<string, int> get_path, int width, int height) -{ - _assets.push_back (shared_ptr<PictureAsset> (new PictureAsset (get_path, _directory, "video.mxf", &Progress, _fps, _length, width, height))); + _reels.push_back (reel); } void @@ -118,11 +101,7 @@ DCP::write_cpl (string cpl_uuid) const << " <RatingList/>\n" << " <ReelList>\n"; - cpl << " <Reel>\n" - << " <Id>urn:uuid:" << make_uuid() << "</Id>\n" - << " <AssetList>\n"; - - for (list<shared_ptr<Asset> >::const_iterator i = _assets.begin(); i != _assets.end(); ++i) { + for (list<shared_ptr<const Reel> >::const_iterator i = _reels.begin(); i != _reels.end(); ++i) { (*i)->write_to_cpl (cpl); } @@ -153,7 +132,7 @@ DCP::write_pkl (string pkl_uuid, string cpl_uuid, string cpl_digest, int cpl_len << " <Creator>" << Metadata::instance()->creator << "</Creator>\n" << " <AssetList>\n"; - for (list<shared_ptr<Asset> >::const_iterator i = _assets.begin(); i != _assets.end(); ++i) { + for (list<shared_ptr<const Reel> >::const_iterator i = _reels.begin(); i != _reels.end(); ++i) { (*i)->write_to_pkl (pkl); } @@ -226,7 +205,7 @@ DCP::write_assetmap (string cpl_uuid, int cpl_length, string pkl_uuid, int pkl_l << " </ChunkList>\n" << " </Asset>\n"; - for (list<shared_ptr<Asset> >::const_iterator i = _assets.begin(); i != _assets.end(); ++i) { + for (list<shared_ptr<const Reel> >::const_iterator i = _reels.begin(); i != _reels.end(); ++i) { (*i)->write_to_assetmap (am); } @@ -282,47 +261,54 @@ DCP::DCP (string directory) _name = cpl->annotation_text; _content_kind = cpl->content_kind; + _length = 0; + _fps = 0; - shared_ptr<CPLAssetList> cpl_assets = cpl->reels.front()->asset_list; - - /* XXX */ - _fps = cpl_assets->main_picture->frame_rate.numerator; - _length = cpl_assets->main_picture->duration; - - string n = pkl->asset_from_id(cpl_assets->main_picture->id)->original_file_name; - if (n.empty ()) { - n = cpl_assets->main_picture->annotation_text; - } + for (list<shared_ptr<CPLReel> >::iterator i = cpl->reels.begin(); i != cpl->reels.end(); ++i) { + assert (_fps == 0 || _fps == (*i)->asset_list->main_picture->frame_rate.numerator); + _fps = (*i)->asset_list->main_picture->frame_rate.numerator; + _length += (*i)->asset_list->main_picture->duration; - _assets.push_back (shared_ptr<PictureAsset> ( - new PictureAsset ( - _directory, - n, - _fps, - _length - ) - )); + string n = pkl->asset_from_id ((*i)->asset_list->main_picture->id)->original_file_name; + if (n.empty ()) { + n = (*i)->asset_list->main_picture->annotation_text; + } + + shared_ptr<PictureAsset> picture (new PictureAsset ( + _directory, + n, + _fps, + (*i)->asset_list->main_picture->duration + ) + ); + + shared_ptr<SoundAsset> sound; + + if ((*i)->asset_list->main_sound) { + + n = pkl->asset_from_id ((*i)->asset_list->main_sound->id)->original_file_name; + if (n.empty ()) { + n = (*i)->asset_list->main_sound->annotation_text; + } + + sound.reset (new SoundAsset ( + _directory, + n, + _fps, + (*i)->asset_list->main_sound->duration + ) + ); + } - if (cpl_assets->main_sound) { + assert (files.subtitles.size() < 2); - n = pkl->asset_from_id(cpl_assets->main_sound->id)->original_file_name; - if (n.empty ()) { - n = cpl_assets->main_sound->annotation_text; + shared_ptr<SubtitleAsset> subtitle; + if (!files.subtitles.empty ()) { + string const l = files.subtitles.front().substr (_directory.length ()); + subtitle.reset (new SubtitleAsset (_directory, l)); } - - _assets.push_back (shared_ptr<SoundAsset> ( - new SoundAsset ( - _directory, - n, - _fps, - _length - ) - )); - } - for (list<string>::iterator i = files.subtitles.begin(); i != files.subtitles.end(); ++i) { - string const l = i->substr (_directory.length ()); - _assets.push_back (shared_ptr<SubtitleAsset> (new SubtitleAsset (_directory, l))); + _reels.push_back (shared_ptr<Reel> (new Reel (picture, sound, subtitle))); } } @@ -406,14 +392,14 @@ DCP::equals (DCP const & other, EqualityOptions opt) const } } - if (_assets.size() != other._assets.size()) { - notes.push_back ("asset counts differ"); + if (_reels.size() != other._reels.size()) { + notes.push_back ("reel counts differ"); } - list<shared_ptr<Asset> >::const_iterator a = _assets.begin (); - list<shared_ptr<Asset> >::const_iterator b = other._assets.begin (); + list<shared_ptr<const Reel> >::const_iterator a = _reels.begin (); + list<shared_ptr<const Reel> >::const_iterator b = other._reels.begin (); - while (a != _assets.end ()) { + while (a != _reels.end ()) { list<string> n = (*a)->equals (*b, opt); notes.merge (n); ++a; @@ -423,41 +409,3 @@ DCP::equals (DCP const & other, EqualityOptions opt) const return notes; } -shared_ptr<const PictureAsset> -DCP::picture_asset () const -{ - for (list<shared_ptr<Asset> >::const_iterator i = _assets.begin(); i != _assets.end(); ++i) { - shared_ptr<PictureAsset> p = dynamic_pointer_cast<PictureAsset> (*i); - if (p) { - return p; - } - } - - return shared_ptr<const PictureAsset> (); -} - -shared_ptr<const SoundAsset> -DCP::sound_asset () const -{ - for (list<shared_ptr<Asset> >::const_iterator i = _assets.begin(); i != _assets.end(); ++i) { - shared_ptr<SoundAsset> s = dynamic_pointer_cast<SoundAsset> (*i); - if (s) { - return s; - } - } - - return shared_ptr<const SoundAsset> (); -} - -shared_ptr<const SubtitleAsset> -DCP::subtitle_asset () const -{ - for (list<shared_ptr<Asset> >::const_iterator i = _assets.begin(); i != _assets.end(); ++i) { - shared_ptr<SubtitleAsset> s = dynamic_pointer_cast<SubtitleAsset> (*i); - if (s) { - return s; - } - } - - return shared_ptr<const SubtitleAsset> (); -} @@ -42,6 +42,7 @@ class Asset; class PictureAsset; class SoundAsset; class SubtitleAsset; +class Reel; /** @class DCP dcp.h libdcp/dcp.h * @brief A class to create or read a DCP. @@ -71,32 +72,7 @@ public: */ DCP (std::string directory); - /** Add a sound asset. - * @param files Pathnames of WAV files to use in the order Left, Right, - * Centre, Lfe (sub), Left surround, Right surround; not all files need - * to be present. - */ - void add_sound_asset (std::vector<std::string> const & files); - - /** Add a sound asset. - * @param get_path Functor to get the path to the WAV for a given channel. - * @param channels Number of channels. - */ - void add_sound_asset (sigc::slot<std::string, Channel> get_path, int channels); - - /** Add a picture asset. - * @param files Pathnames of JPEG2000 files, in frame order. - * @param width Width of images in pixels. - * @param height Height of images in pixels. - */ - void add_picture_asset (std::vector<std::string> const & files, int width, int height); - - /** Add a picture asset. - * @param get_path Functor to get path to the JPEG2000 for a given frame. - * @param width Width of images in pixels. - * @param height Height of images in pixels. - */ - void add_picture_asset (sigc::slot<std::string, int> get_path, int width, int height); + void add_reel (boost::shared_ptr<const Reel> reel); /** Write the required XML files to the directory that was * passed into the constructor. @@ -127,12 +103,9 @@ public: return _length; } - /** @return the main picture asset, if one exists, otherwise 0 */ - boost::shared_ptr<const PictureAsset> picture_asset () const; - /** @return the main sound asset, if one exists, otherwise 0 */ - boost::shared_ptr<const SoundAsset> sound_asset () const; - /** @return the main subtitle asset, if one exists, otherwise 0 */ - boost::shared_ptr<const SubtitleAsset> subtitle_asset () const; + std::list<boost::shared_ptr<const Reel> > reels () const { + return _reels; + } /** Compare this DCP with another, according to various options. * @param other DCP to compare this one to. @@ -193,8 +166,8 @@ private: int _fps; /** length in frames */ int _length; - /** assets */ - std::list<boost::shared_ptr<Asset> > _assets; + /** reels */ + std::list<boost::shared_ptr<const Reel> > _reels; }; } diff --git a/src/reel.cc b/src/reel.cc new file mode 100644 index 00000000..431af69a --- /dev/null +++ b/src/reel.cc @@ -0,0 +1,115 @@ +/* + Copyright (C) 2012 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 "reel.h" +#include "util.h" +#include "picture_asset.h" +#include "sound_asset.h" +#include "subtitle_asset.h" + +using namespace std; +using namespace libdcp; + +void +Reel::write_to_cpl (ostream& s) const +{ + s << " <Reel>\n" + << " <Id>urn:uuid:" << make_uuid() << "</Id>\n" + << " <AssetList>\n"; + + if (_main_picture) { + _main_picture->write_to_cpl (s); + } + + if (_main_sound) { + _main_sound->write_to_cpl (s); + } + + if (_main_subtitle) { + _main_subtitle->write_to_cpl (s); + } +} + +void +Reel::write_to_pkl (ostream& s) const +{ + if (_main_picture) { + _main_picture->write_to_pkl (s); + } + + if (_main_sound) { + _main_sound->write_to_pkl (s); + } + + if (_main_subtitle) { + _main_subtitle->write_to_pkl (s); + } +} + +void +Reel::write_to_assetmap (ostream& s) const +{ + if (_main_picture) { + _main_picture->write_to_assetmap (s); + } + + if (_main_sound) { + _main_sound->write_to_assetmap (s); + } + + if (_main_subtitle) { + _main_subtitle->write_to_assetmap (s); + } +} + +list<string> +Reel::equals (boost::shared_ptr<const Reel> other, EqualityOptions opt) const +{ + list<string> o; + + if ((_main_picture && !other->_main_picture) || (!_main_picture && other->_main_picture)) { + o.push_back ("reel has different assets"); + } + + if (_main_picture) { + list<string> m = _main_picture->equals (other->_main_picture, opt); + o.merge (m); + } + + if ((_main_sound && !other->_main_sound) || (!_main_sound && other->_main_sound)) { + o.push_back ("reel has different assets"); + } + + if (_main_sound) { + list<string> m = _main_sound->equals (other->_main_sound, opt); + o.merge (m); + } + + if ((_main_subtitle && !other->_main_subtitle) || (!_main_subtitle && other->_main_subtitle)) { + o.push_back ("reel has different assets"); + } + + if (_main_subtitle) { + list<string> m = _main_subtitle->equals (other->_main_subtitle, opt); + o.merge (m); + } + + return o; +} + diff --git a/src/reel.h b/src/reel.h new file mode 100644 index 00000000..28d827f8 --- /dev/null +++ b/src/reel.h @@ -0,0 +1,67 @@ +/* + Copyright (C) 2012 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 <list> +#include <boost/shared_ptr.hpp> +#include "types.h" + +namespace libdcp { + +class PictureAsset; +class SoundAsset; +class SubtitleAsset; + +class Reel +{ +public: + Reel ( + boost::shared_ptr<const PictureAsset> picture, + boost::shared_ptr<const SoundAsset> sound, + boost::shared_ptr<const SubtitleAsset> subtitle + ) + : _main_picture (picture) + , _main_sound (sound) + , _main_subtitle (subtitle) + {} + + boost::shared_ptr<const PictureAsset> main_picture () const { + return _main_picture; + } + + boost::shared_ptr<const SoundAsset> main_sound () const { + return _main_sound; + } + + boost::shared_ptr<const SubtitleAsset> main_subtitle () const { + return _main_subtitle; + } + + void write_to_cpl (std::ostream & s) const; + void write_to_pkl (std::ostream & s) const; + void write_to_assetmap (std::ostream & s) const; + + std::list<std::string> equals (boost::shared_ptr<const Reel> other, EqualityOptions opt) const; + +private: + boost::shared_ptr<const PictureAsset> _main_picture; + boost::shared_ptr<const SoundAsset> _main_sound; + boost::shared_ptr<const SubtitleAsset> _main_subtitle; +}; + +} diff --git a/src/wscript b/src/wscript index fb62970a..bef62a93 100644 --- a/src/wscript +++ b/src/wscript @@ -17,6 +17,7 @@ def build(bld): picture_asset.cc picture_frame.cc pkl.cc + reel.cc rgba_frame.cc sound_asset.cc sound_frame.cc @@ -37,6 +38,7 @@ def build(bld): mxf_asset.h picture_asset.h picture_frame.h + reel.h rgba_frame.h sound_asset.h sound_frame.h |
