summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2012-07-18 00:23:28 +0100
committerCarl Hetherington <cth@carlh.net>2012-07-18 00:23:28 +0100
commitca45f479876579c91b9d438c47c5166b1a178704 (patch)
tree2757a90d01307b66a39ecbca5544c47ffdf324fc /src
parent2194158985f9c1300ffe24c7c6fb786cb39bbdb5 (diff)
Allow functor to obtain content paths.
Diffstat (limited to 'src')
-rw-r--r--src/dcp.cc24
-rw-r--r--src/dcp.h25
-rw-r--r--src/picture_asset.cc46
-rw-r--r--src/picture_asset.h25
-rw-r--r--src/sound_asset.cc69
-rw-r--r--src/sound_asset.h40
-rw-r--r--src/types.h38
-rw-r--r--src/wscript1
8 files changed, 232 insertions, 36 deletions
diff --git a/src/dcp.cc b/src/dcp.cc
index ca2a2d14..c466396c 100644
--- a/src/dcp.cc
+++ b/src/dcp.cc
@@ -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
diff --git a/src/dcp.h b/src/dcp.h
index b2d20c69..f683c419 100644
--- a/src/dcp.h
+++ b/src/dcp.h
@@ -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)