diff options
| author | Carl Hetherington <cth@carlh.net> | 2012-07-18 00:23:28 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2012-07-18 00:23:28 +0100 |
| commit | ca45f479876579c91b9d438c47c5166b1a178704 (patch) | |
| tree | 2757a90d01307b66a39ecbca5544c47ffdf324fc /src | |
| parent | 2194158985f9c1300ffe24c7c6fb786cb39bbdb5 (diff) | |
Allow functor to obtain content paths.
Diffstat (limited to 'src')
| -rw-r--r-- | src/dcp.cc | 24 | ||||
| -rw-r--r-- | src/dcp.h | 25 | ||||
| -rw-r--r-- | src/picture_asset.cc | 46 | ||||
| -rw-r--r-- | src/picture_asset.h | 25 | ||||
| -rw-r--r-- | src/sound_asset.cc | 69 | ||||
| -rw-r--r-- | src/sound_asset.h | 40 | ||||
| -rw-r--r-- | src/types.h | 38 | ||||
| -rw-r--r-- | src/wscript | 1 |
8 files changed, 232 insertions, 36 deletions
@@ -44,7 +44,7 @@ DCP::DCP (string directory, string name, ContentType content_type, int fps, int } void -DCP::add_sound_asset (list<string> const & files) +DCP::add_sound_asset (vector<string> const & files) { filesystem::path p; p /= _directory; @@ -53,12 +53,30 @@ DCP::add_sound_asset (list<string> const & files) } void -DCP::add_picture_asset (list<string> const & files, int w, int h) +DCP::add_sound_asset (sigc::slot<string, Channel> get_path, int channels) +{ + filesystem::path p; + p /= _directory; + p /= "audio.mxf"; + _assets.push_back (shared_ptr<SoundAsset> (new SoundAsset (get_path, p.string(), &Progress, _fps, _length, channels))); +} + +void +DCP::add_picture_asset (vector<string> const & files, int width, int height) +{ + filesystem::path p; + p /= _directory; + p /= "video.mxf"; + _assets.push_back (shared_ptr<PictureAsset> (new PictureAsset (files, p.string(), &Progress, _fps, _length, width, height))); +} + +void +DCP::add_picture_asset (sigc::slot<string, int> get_path, int width, int height) { filesystem::path p; p /= _directory; p /= "video.mxf"; - _assets.push_back (shared_ptr<PictureAsset> (new PictureAsset (files, p.string(), &Progress, _fps, _length, w, h))); + _assets.push_back (shared_ptr<PictureAsset> (new PictureAsset (get_path, p.string(), &Progress, _fps, _length, width, height))); } void @@ -24,6 +24,7 @@ #include <list> #include <boost/shared_ptr.hpp> #include <sigc++/sigc++.h> +#include "types.h" /** @brief Namespace for everything in libdcp */ namespace libdcp @@ -41,7 +42,7 @@ class Asset; * * libdcp::DCP dcp ("My Film DCP", "My Film", libdcp::DCP::FEATURE, 24, 50000); * - * list<string> j2k_files; + * vector<string> j2k_files; * j2k_files.push_back ("1.j2c"); * ... * j2k_files.push_back ("50000.j2c"); @@ -49,7 +50,7 @@ class Asset; * // These images are 1998x1080 pixels (DCI Flat) * dcp.add_picture_asset (j2k_files, 1998, 1080); * - * list<string> wav_files; + * vector<string> wav_files; * wav_files.push_back ("L.wav"); * wav_files.push_back ("R.wav"); * wav_files.push_back ("C.wav"); @@ -101,16 +102,30 @@ public: /** Add a sound asset. * @param files Pathnames of WAV files to use in the order Left, Right, - * Centre, Lfe (sub), Left surround, Right surround. + * Centre, Lfe (sub), Left surround, Right surround; not all files need + * to be present. */ - void add_sound_asset (std::list<std::string> const & files); + 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::list<std::string> const & files, int width, int height); + 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); /** Write the required XML files to the directory that was * passed into the constructor. diff --git a/src/picture_asset.cc b/src/picture_asset.cc index 3888ca72..383d218a 100644 --- a/src/picture_asset.cc +++ b/src/picture_asset.cc @@ -36,7 +36,7 @@ using namespace boost; using namespace libdcp; PictureAsset::PictureAsset ( - list<string> const & files, + sigc::slot<string, int> get_path, string mxf_path, sigc::signal1<void, float>* progress, int fps, @@ -47,11 +47,38 @@ PictureAsset::PictureAsset ( , _width (width) , _height (height) { + construct (get_path); +} + +PictureAsset::PictureAsset ( + vector<string> const & files, + string mxf_path, + sigc::signal1<void, float>* progress, + int fps, + int length, + int width, + int height) + : Asset (mxf_path, progress, fps, length) + , _width (width) + , _height (height) +{ + construct (sigc::bind (sigc::mem_fun (*this, &PictureAsset::path_from_list), files)); +} + +string +PictureAsset::path_from_list (int f, vector<string> const & files) const +{ + return files[f]; +} + +void +PictureAsset::construct (sigc::slot<string, int> get_path) +{ ASDCP::JP2K::CodestreamParser j2k_parser; ASDCP::JP2K::FrameBuffer frame_buffer (4 * Kumu::Megabyte); - if (ASDCP_FAILURE (j2k_parser.OpenReadFrame (files.front().c_str(), frame_buffer))) { + if (ASDCP_FAILURE (j2k_parser.OpenReadFrame (get_path(0).c_str(), frame_buffer))) { stringstream s; - s << "could not open " << files.front() << " for reading"; + s << "could not open " << get_path(0) << " for reading"; throw runtime_error (s.str()); } @@ -67,11 +94,13 @@ PictureAsset::PictureAsset ( throw runtime_error ("could not open MXF for writing"); } - int j = 0; - for (list<string>::const_iterator i = files.begin(); i != files.end(); ++i) { - if (ASDCP_FAILURE (j2k_parser.OpenReadFrame (i->c_str(), frame_buffer))) { + for (int i = 0; i < _length; ++i) { + + string const path = get_path (i); + + if (ASDCP_FAILURE (j2k_parser.OpenReadFrame (path.c_str(), frame_buffer))) { stringstream s; - s << "could not open " << *i << " for reading"; + s << "could not open " << path << " for reading"; throw runtime_error (s.str()); } @@ -80,8 +109,7 @@ PictureAsset::PictureAsset ( throw runtime_error ("error in writing video MXF"); } - ++j; - (*_progress) (0.5 * float (j) / files.size ()); + (*_progress) (0.5 * float (i) / _length); } if (ASDCP_FAILURE (mxf_writer.Finalize())) { diff --git a/src/picture_asset.h b/src/picture_asset.h index 2f3c7cdf..58dd1dfd 100644 --- a/src/picture_asset.h +++ b/src/picture_asset.h @@ -41,7 +41,7 @@ public: * @param height Height of images in pixels. */ PictureAsset ( - std::list<std::string> const & files, + std::vector<std::string> const & files, std::string mxf_path, sigc::signal1<void, float>* progress, int fps, @@ -50,12 +50,35 @@ public: int height ); + /** Construct a PictureAsset, generating the MXF from the JPEG2000 files. + * This may take some time; progress is indicated by emission of the Progress signal. + * @param files Pathnames of JPEG2000 files, in frame order. + * @param mxf_path Pathname of MXF file to create. + * @param progress Signal to inform of progress. + * @param fps Frames per second. + * @param length Length in frames. + * @param width Width of images in pixels. + * @param height Height of images in pixels. + */ + PictureAsset ( + sigc::slot<std::string, int> get_path, + std::string mxf_path, + sigc::signal1<void, float>* progress, + int fps, + int length, + int width, + int height + ); + /** Write details of this asset to a CPL stream. * @param s Stream. */ void write_to_cpl (std::ostream& s) const; private: + std::string path_from_list (int f, std::vector<std::string> const & files) const; + void construct (sigc::slot<std::string, int>); + /** picture width in pixels */ int _width; /** picture height in pixels */ diff --git a/src/sound_asset.cc b/src/sound_asset.cc index 8c85f9df..0d32db2a 100644 --- a/src/sound_asset.cc +++ b/src/sound_asset.cc @@ -32,13 +32,39 @@ using namespace std; using namespace boost; using namespace libdcp; -SoundAsset::SoundAsset (list<string> const & files, string mxf_path, sigc::signal1<void, float>* progress, int fps, int length) +SoundAsset::SoundAsset ( + vector<string> const & files, string mxf_path, sigc::signal1<void, float>* progress, int fps, int length + ) : Asset (mxf_path, progress, fps, length) + , _channels (files.size ()) +{ + construct (sigc::bind (sigc::mem_fun (*this, &SoundAsset::path_from_channel), files)); +} + +SoundAsset::SoundAsset ( + sigc::slot<string, Channel> get_path, string mxf_path, sigc::signal1<void, float>* progress, int fps, int length, int channels + ) + : Asset (mxf_path, progress, fps, length) + , _channels (channels) +{ + construct (get_path); +} + +string +SoundAsset::path_from_channel (Channel channel, vector<string> const & files) +{ + unsigned int const c = int (channel); + assert (c < files.size ()); + return files[c]; +} + +void +SoundAsset::construct (sigc::slot<string, Channel> get_path) { ASDCP::Rational asdcp_fps (_fps, 1); - ASDCP::PCM::WAVParser pcm_parser_channel[files.size()]; - if (pcm_parser_channel[0].OpenRead (files.front().c_str(), asdcp_fps)) { + ASDCP::PCM::WAVParser pcm_parser_channel[_channels]; + if (pcm_parser_channel[0].OpenRead (get_path(LEFT).c_str(), asdcp_fps)) { throw runtime_error ("could not open WAV file for reading"); } @@ -47,24 +73,33 @@ SoundAsset::SoundAsset (list<string> const & files, string mxf_path, sigc::signa audio_desc.ChannelCount = 0; audio_desc.BlockAlign = 0; audio_desc.EditRate = asdcp_fps; - audio_desc.AvgBps = audio_desc.AvgBps * files.size (); + audio_desc.AvgBps = audio_desc.AvgBps * _channels; - ASDCP::PCM::FrameBuffer frame_buffer_channel[files.size()]; - ASDCP::PCM::AudioDescriptor audio_desc_channel[files.size()]; - - int j = 0; - for (list<string>::const_iterator i = files.begin(); i != files.end(); ++i) { + Channel channels[] = { + LEFT, + RIGHT, + CENTRE, + LFE, + LS, + RS + }; + + ASDCP::PCM::FrameBuffer frame_buffer_channel[_channels]; + ASDCP::PCM::AudioDescriptor audio_desc_channel[_channels]; + + for (int i = 0; i < _channels; ++i) { + + string const path = get_path (channels[i]); - if (ASDCP_FAILURE (pcm_parser_channel[j].OpenRead (i->c_str(), asdcp_fps))) { + if (ASDCP_FAILURE (pcm_parser_channel[i].OpenRead (path.c_str(), asdcp_fps))) { throw runtime_error ("could not open WAV file for reading"); } - pcm_parser_channel[j].FillAudioDescriptor (audio_desc_channel[j]); - frame_buffer_channel[j].Capacity (ASDCP::PCM::CalcFrameBufferSize (audio_desc_channel[j])); + pcm_parser_channel[i].FillAudioDescriptor (audio_desc_channel[i]); + frame_buffer_channel[i].Capacity (ASDCP::PCM::CalcFrameBufferSize (audio_desc_channel[i])); - audio_desc.ChannelCount += audio_desc_channel[j].ChannelCount; - audio_desc.BlockAlign += audio_desc_channel[j].BlockAlign; - ++j; + audio_desc.ChannelCount += audio_desc_channel[i].ChannelCount; + audio_desc.BlockAlign += audio_desc_channel[i].BlockAlign; } ASDCP::PCM::FrameBuffer frame_buffer; @@ -86,7 +121,7 @@ SoundAsset::SoundAsset (list<string> const & files, string mxf_path, sigc::signa byte_t sample_size = ASDCP::PCM::CalcSampleSize (audio_desc_channel[0]); int offset = 0; - for (list<string>::size_type j = 0; j < files.size(); ++j) { + for (int j = 0; j < _channels; ++j) { memset (frame_buffer_channel[j].Data(), 0, frame_buffer_channel[j].Capacity()); if (ASDCP_FAILURE (pcm_parser_channel[j].ReadFrame (frame_buffer_channel[j]))) { throw runtime_error ("could not read audio frame"); @@ -98,7 +133,7 @@ SoundAsset::SoundAsset (list<string> const & files, string mxf_path, sigc::signa } while (data_s < data_e) { - for (list<string>::size_type j = 0; j < files.size(); ++j) { + for (int j = 0; j < _channels; ++j) { byte_t* frame = frame_buffer_channel[j].Data() + offset; memcpy (data_s, frame, sample_size); data_s += sample_size; diff --git a/src/sound_asset.h b/src/sound_asset.h index c63bab90..591b0a47 100644 --- a/src/sound_asset.h +++ b/src/sound_asset.h @@ -17,11 +17,15 @@ */ +#ifndef LIBDCP_SOUND_ASSET_H +#define LIBDCP_SOUND_ASSET_H + /** @file src/sound_asset.h * @brief An asset made up of WAV files */ #include "asset.h" +#include "types.h" namespace libdcp { @@ -37,13 +41,47 @@ public: * @param progress Signal to inform of progress. * @param fps Frames per second. * @param length Length in frames. + * @param channels Number of audio channels. */ - SoundAsset (std::list<std::string> const & files, std::string mxf_path, sigc::signal1<void, float>* progress, int fps, int length); + SoundAsset ( + std::vector<std::string> const & files, + std::string mxf_path, + sigc::signal1<void, float>* progress, + int fps, + int length + ); + /** Construct a SoundAsset, generating the MXF from the WAV files. + * This may take some time; progress is indicated by emission of the Progress signal. + * @param files Pathnames of sound files, in the order Left, Right, Centre, Lfe (sub), Left surround, Right surround. + * @param mxf_path Pathname of MXF file to create. + * @param progress Signal to inform of progress. + * @param fps Frames per second. + * @param length Length in frames. + * @param channels Number of audio channels. + */ + SoundAsset ( + sigc::slot<std::string, Channel>, + std::string mxf_path, + sigc::signal1<void, float>* progress, + int fps, + int length, + int channels + ); + /** Write details of this asset to a CPL stream. * @param s Stream. */ void write_to_cpl (std::ostream& s) const; + +private: + void construct (sigc::slot<std::string, Channel> get_path); + std::string path_from_channel (Channel channel, std::vector<std::string> const & files); + + /** Number of channels in the asset */ + int _channels; }; } + +#endif diff --git a/src/types.h b/src/types.h new file mode 100644 index 00000000..286c3623 --- /dev/null +++ b/src/types.h @@ -0,0 +1,38 @@ +/* + 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. + +*/ + +#ifndef LIBDCP_CHANNEL_H +#define LIBDCP_CHANNEL_H + +namespace libdcp +{ + +/** Identifier for a sound channel */ +enum Channel { + LEFT = 0, ///< left + RIGHT = 1, ///< right + CENTRE = 2, ///< centre + LFE = 3, ///< low-frequency effects (sub) + LS = 4, ///< left surround + RS = 5 ///< right surround +}; + +} + +#endif diff --git a/src/wscript b/src/wscript index 7417dee5..db6906c8 100644 --- a/src/wscript +++ b/src/wscript @@ -17,6 +17,7 @@ def build(bld): headers = """ dcp.h metadata.h + types.h """ bld.install_files('${PREFIX}/include/libdcp', headers) |
