using namespace boost;
using namespace libdcp;
-Asset::Asset (string directory, string mxf_name, sigc::signal1<void, float>* progress, int fps, int length)
+Asset::Asset (string directory, string file_name)
: _directory (directory)
- , _mxf_name (mxf_name)
- , _progress (progress)
- , _fps (fps)
- , _length (length)
+ , _file_name (file_name)
, _uuid (make_uuid ())
{
{
s << " <Asset>\n"
<< " <Id>urn:uuid:" << _uuid << "</Id>\n"
- << " <AnnotationText>" << _mxf_name << "</AnnotationText>\n"
+ << " <AnnotationText>" << _file_name << "</AnnotationText>\n"
<< " <Hash>" << digest() << "</Hash>\n"
- << " <Size>" << filesystem::file_size(mxf_path()) << "</Size>\n"
+ << " <Size>" << filesystem::file_size(path()) << "</Size>\n"
<< " <Type>application/mxf</Type>\n"
<< " </Asset>\n";
}
<< " <Id>urn:uuid:" << _uuid << "</Id>\n"
<< " <ChunkList>\n"
<< " <Chunk>\n"
- << " <Path>" << _mxf_name << "</Path>\n"
+ << " <Path>" << _file_name << "</Path>\n"
<< " <VolumeIndex>1</VolumeIndex>\n"
<< " <Offset>0</Offset>\n"
- << " <Length>" << filesystem::file_size(mxf_path()) << "</Length>\n"
+ << " <Length>" << filesystem::file_size(path()) << "</Length>\n"
<< " </Chunk>\n"
<< " </ChunkList>\n"
<< " </Asset>\n";
}
-void
-Asset::fill_writer_info (ASDCP::WriterInfo* writer_info) const
-{
- writer_info->ProductVersion = Metadata::instance()->product_version;
- writer_info->CompanyName = Metadata::instance()->company_name;
- writer_info->ProductName = Metadata::instance()->product_name.c_str();
-
- writer_info->LabelSetType = ASDCP::LS_MXF_SMPTE;
- unsigned int c;
- Kumu::hex2bin (_uuid.c_str(), writer_info->AssetUUID, Kumu::UUID_Length, &c);
- assert (c == Kumu::UUID_Length);
-}
-
filesystem::path
-Asset::mxf_path () const
+Asset::path () const
{
filesystem::path p;
p /= _directory;
- p /= _mxf_name;
+ p /= _file_name;
return p;
}
-list<string>
-Asset::equals (shared_ptr<const Asset> other, EqualityOptions opt) const
-{
- list<string> notes;
-
- if (opt.flags & LIBDCP_METADATA) {
- if (_mxf_name != other->_mxf_name) {
- notes.push_back ("MXF names differ");
- }
- if (_fps != other->_fps) {
- notes.push_back ("MXF frames per second differ");
- }
- if (_length != other->_length) {
- notes.push_back ("MXF lengths differ");
- }
- }
-
- if (opt.flags & MXF_BITWISE) {
-
- if (digest() != other->digest()) {
- notes.push_back ("MXF digests differ");
- }
-
- if (filesystem::file_size (mxf_path()) != filesystem::file_size (other->mxf_path())) {
- notes.push_back (mxf_path().string() + " and " + other->mxf_path().string() + " sizes differ");
- return notes;
- }
-
- ifstream a (mxf_path().string().c_str(), ios::binary);
- ifstream b (other->mxf_path().string().c_str(), ios::binary);
-
- int buffer_size = 65536;
- char abuffer[buffer_size];
- char bbuffer[buffer_size];
-
- int n = filesystem::file_size (mxf_path ());
-
- while (n) {
- int const t = min (n, buffer_size);
- a.read (abuffer, t);
- b.read (bbuffer, t);
-
- if (memcmp (abuffer, bbuffer, t) != 0) {
- notes.push_back (mxf_path().string() + " and " + other->mxf_path().string() + " content differs");
- return notes;
- }
-
- n -= t;
- }
- }
-
- return notes;
-}
-
string
Asset::digest () const
{
if (_digest.empty ()) {
- _digest = make_digest (mxf_path().string(), 0);
+ _digest = make_digest (path().string(), 0);
}
return _digest;
}
-
-int
-Asset::length () const
-{
- return _length;
-}
-
-
{
public:
/** Construct an Asset.
- * @param directory Directory where MXF file is.
- * @param mxf_name Name of MXF file.
- * @param progress Signal to inform of progress.
- * @param fps Frames per second.
- * @param length Length in frames.
+ * @param directory Directory where our XML or MXF file is.
+ * @param file_name Name of our file within directory.
*/
- Asset (std::string directory, std::string mxf_path, sigc::signal1<void, float>* progress, int fps, int length);
+ Asset (std::string directory, std::string file_name);
/** Write details of the asset to a CPL stream.
* @param s Stream.
*/
void write_to_assetmap (std::ostream& s) const;
- virtual std::list<std::string> equals (boost::shared_ptr<const Asset> other, EqualityOptions opt) const;
-
- int length () const;
+ virtual std::list<std::string> equals (boost::shared_ptr<const Asset> other, EqualityOptions opt) const = 0;
protected:
friend class PictureAsset;
friend class SoundAsset;
- /** Fill in a ADSCP::WriteInfo struct.
- * @param w struct to fill in.
- */
- void fill_writer_info (ASDCP::WriterInfo* w) const;
-
- boost::filesystem::path mxf_path () const;
std::string digest () const;
+ boost::filesystem::path path () const;
- /** Directory that our MXF file is in */
+ /** Directory that our MXF or XML file is in */
std::string _directory;
- /** Name of our MXF file */
- std::string _mxf_name;
- /** Signal to emit to report progress */
- sigc::signal1<void, float>* _progress;
- /** Frames per second */
- int _fps;
- /** Length in frames */
- int _length;
+ /** Name of our MXF or XML file */
+ std::string _file_name;
/** Our UUID */
std::string _uuid;
private:
- /** Digest of our MXF */
+ /** Digest of our MXF or XML file */
mutable std::string _digest;
};
int length,
int width,
int height)
- : Asset (directory, mxf_name, progress, fps, length)
+ : MXFAsset (directory, mxf_name, progress, fps, length)
, _width (width)
, _height (height)
{
int length,
int width,
int height)
- : Asset (directory, mxf_name, progress, fps, length)
+ : MXFAsset (directory, mxf_name, progress, fps, length)
, _width (width)
, _height (height)
{
}
PictureAsset::PictureAsset (string directory, string mxf_name, int fps, int length)
- : Asset (directory, mxf_name, 0, fps, length)
+ : MXFAsset (directory, mxf_name, 0, fps, length)
{
ASDCP::JP2K::MXFReader reader;
- if (ASDCP_FAILURE (reader.OpenRead (mxf_path().string().c_str()))) {
- throw FileError ("could not open MXF file for reading", mxf_path().string());
+ if (ASDCP_FAILURE (reader.OpenRead (path().string().c_str()))) {
+ throw FileError ("could not open MXF file for reading", path().string());
}
ASDCP::JP2K::PictureDescriptor desc;
fill_writer_info (&writer_info);
ASDCP::JP2K::MXFWriter mxf_writer;
- if (ASDCP_FAILURE (mxf_writer.OpenWrite (mxf_path().string().c_str(), writer_info, picture_desc))) {
- throw FileError ("could not open MXF file for writing", mxf_path().string());
+ if (ASDCP_FAILURE (mxf_writer.OpenWrite (path().string().c_str(), writer_info, picture_desc))) {
+ throw FileError ("could not open MXF file for writing", path().string());
}
for (int i = 0; i < _length; ++i) {
{
s << " <MainPicture>\n"
<< " <Id>urn:uuid:" << _uuid << "</Id>\n"
- << " <AnnotationText>" << _mxf_name << "</AnnotationText>\n"
+ << " <AnnotationText>" << _file_name << "</AnnotationText>\n"
<< " <EditRate>" << _fps << " 1</EditRate>\n"
<< " <IntrinsicDuration>" << _length << "</IntrinsicDuration>\n"
<< " <EntryPoint>0</EntryPoint>\n"
list<string>
PictureAsset::equals (shared_ptr<const Asset> other, EqualityOptions opt) const
{
- list<string> notes = Asset::equals (other, opt);
+ list<string> notes = MXFAsset::equals (other, opt);
if (opt.flags & MXF_INSPECT) {
ASDCP::JP2K::MXFReader reader_A;
- if (ASDCP_FAILURE (reader_A.OpenRead (mxf_path().string().c_str()))) {
- throw FileError ("could not open MXF file for reading", mxf_path().string());
+ if (ASDCP_FAILURE (reader_A.OpenRead (path().string().c_str()))) {
+ throw FileError ("could not open MXF file for reading", path().string());
}
ASDCP::JP2K::MXFReader reader_B;
- if (ASDCP_FAILURE (reader_B.OpenRead (other->mxf_path().string().c_str()))) {
- throw FileError ("could not open MXF file for reading", mxf_path().string());
+ if (ASDCP_FAILURE (reader_B.OpenRead (other->path().string().c_str()))) {
+ throw FileError ("could not open MXF file for reading", path().string());
}
ASDCP::JP2K::PictureDescriptor desc_A;
shared_ptr<const PictureFrame>
PictureAsset::get_frame (int n) const
{
- return shared_ptr<const PictureFrame> (new PictureFrame (mxf_path().string(), n));
+ return shared_ptr<const PictureFrame> (new PictureFrame (path().string(), n));
}
*/
#include <openjpeg.h>
-#include "asset.h"
+#include "mxf_asset.h"
namespace libdcp
{
class PictureFrame;
/** @brief An asset made up of JPEG2000 files */
-class PictureAsset : public Asset
+class PictureAsset : public MXFAsset
{
public:
/** Construct a PictureAsset, generating the MXF from the JPEG2000 files.
SoundAsset::SoundAsset (
vector<string> const & files, string directory, string mxf_name, sigc::signal1<void, float>* progress, int fps, int length
)
- : Asset (directory, mxf_name, progress, fps, length)
+ : MXFAsset (directory, mxf_name, progress, fps, length)
, _channels (files.size ())
, _sampling_rate (0)
{
SoundAsset::SoundAsset (
sigc::slot<string, Channel> get_path, string directory, string mxf_name, sigc::signal1<void, float>* progress, int fps, int length, int channels
)
- : Asset (directory, mxf_name, progress, fps, length)
+ : MXFAsset (directory, mxf_name, progress, fps, length)
, _channels (channels)
, _sampling_rate (0)
{
}
SoundAsset::SoundAsset (string directory, string mxf_name, int fps, int length)
- : Asset (directory, mxf_name, 0, fps, length)
+ : MXFAsset (directory, mxf_name, 0, fps, length)
, _channels (0)
{
ASDCP::PCM::MXFReader reader;
- if (ASDCP_FAILURE (reader.OpenRead (mxf_path().string().c_str()))) {
- throw FileError ("could not open MXF file for reading", mxf_path().string());
+ if (ASDCP_FAILURE (reader.OpenRead (path().string().c_str()))) {
+ throw FileError ("could not open MXF file for reading", path().string());
}
fill_writer_info (&writer_info);
ASDCP::PCM::MXFWriter mxf_writer;
- if (ASDCP_FAILURE (mxf_writer.OpenWrite (mxf_path().string().c_str(), writer_info, audio_desc))) {
- throw FileError ("could not open audio MXF for writing", mxf_path().string());
+ if (ASDCP_FAILURE (mxf_writer.OpenWrite (path().string().c_str(), writer_info, audio_desc))) {
+ throw FileError ("could not open audio MXF for writing", path().string());
}
for (int i = 0; i < _length; ++i) {
{
s << " <MainSound>\n"
<< " <Id>urn:uuid:" << _uuid << "</Id>\n"
- << " <AnnotationText>" << _mxf_name << "</AnnotationText>\n"
+ << " <AnnotationText>" << _file_name << "</AnnotationText>\n"
<< " <EditRate>" << _fps << " 1</EditRate>\n"
<< " <IntrinsicDuration>" << _length << "</IntrinsicDuration>\n"
<< " <EntryPoint>0</EntryPoint>\n"
list<string>
SoundAsset::equals (shared_ptr<const Asset> other, EqualityOptions opt) const
{
- list<string> notes = Asset::equals (other, opt);
+ list<string> notes = MXFAsset::equals (other, opt);
if (opt.flags & MXF_INSPECT) {
ASDCP::PCM::MXFReader reader_A;
- if (ASDCP_FAILURE (reader_A.OpenRead (mxf_path().string().c_str()))) {
- cout << "failed " << mxf_path() << "\n";
- throw FileError ("could not open MXF file for reading", mxf_path().string());
+ if (ASDCP_FAILURE (reader_A.OpenRead (path().string().c_str()))) {
+ cout << "failed " << path() << "\n";
+ throw FileError ("could not open MXF file for reading", path().string());
}
ASDCP::PCM::MXFReader reader_B;
- if (ASDCP_FAILURE (reader_B.OpenRead (other->mxf_path().string().c_str()))) {
- cout << "failed " << other->mxf_path() << "\n";
- throw FileError ("could not open MXF file for reading", mxf_path().string());
+ if (ASDCP_FAILURE (reader_B.OpenRead (other->path().string().c_str()))) {
+ cout << "failed " << other->path() << "\n";
+ throw FileError ("could not open MXF file for reading", path().string());
}
ASDCP::PCM::AudioDescriptor desc_A;
shared_ptr<const SoundFrame>
SoundAsset::get_frame (int n) const
{
- return shared_ptr<const SoundFrame> (new SoundFrame (mxf_path().string(), n));
+ return shared_ptr<const SoundFrame> (new SoundFrame (path().string(), n));
}
* @brief An asset made up of WAV files
*/
-#include "asset.h"
+#include "mxf_asset.h"
#include "types.h"
namespace libdcp
class SoundFrame;
/** @brief An asset made up of WAV files */
-class SoundAsset : public Asset
+class SoundAsset : public MXFAsset
{
public:
/** Construct a SoundAsset, generating the MXF from the WAV files.
extern std::string content_kind_to_string (ContentKind kind);
extern ContentKind content_kind_from_string (std::string kind);
extern bool ends_with (std::string big, std::string little);
-
+
}
asset_map.cc
cpl.cc
dcp.cc
+ dcp_time.cc
+ mxf_asset.cc
sound_asset.cc
+ subtitle_asset.cc
picture_asset.cc
picture_frame.cc
pkl.cc
_taken.push_back (name);
}
+Time
+XMLNode::time_attribute (string name)
+{
+
+}
+
void
XMLNode::done ()
{
void ignore_node (std::string);
void done ();
+ Time time_attribute (std::string);
+ float float_attribute (std::string);
+
template <class T>
boost::shared_ptr<T> sub_node (std::string name) {
return boost::shared_ptr<T> (new T (xml_node (name)));
}
template <class T>
- std::list<boost::shared_ptr<T> > sub_nodes (std::string name, std::string sub) {
- XMLNode p (xml_node (name));
- std::list<xmlpp::Node*> n = p.xml_nodes (sub);
+ std::list<boost::shared_ptr<T> > sub_nodes (std::string name) {
+ std::list<xmlpp::Node*> n = xml_nodes (name);
std::list<boost::shared_ptr<T> > r;
for (typename std::list<xmlpp::Node*>::iterator i = n.begin(); i != n.end(); ++i) {
r.push_back (boost::shared_ptr<T> (new T (*i)));
return r;
}
+ template <class T>
+ std::list<boost::shared_ptr<T> > sub_nodes (std::string name, std::string sub) {
+ XMLNode p (xml_node (name));
+ return p.sub_nodes<T> (sub);
+ }
+
xmlpp::Node const * _node;
private:
#include "metadata.h"
#include "types.h"
#include "exceptions.h"
+#include "subtitle_asset.h"
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE libdcp_test
BOOST_CHECK_EQUAL (d.length(), 24);
}
+BOOST_AUTO_TEST_CASE (subtitles)
+{
+ libdcp::SubtitleAsset subs ("test/ref", "subs.xml");
+
+ BOOST_CHECK_EQUAL (subs.language(), "French");
+ BOOST_CHECK_EQUAL (subs.fonts().size(), 1);
+ BOOST_CHECK_EQUAL (subs.fonts().front()->subtitles().size(), 4);
+
+ list<shared_ptr<libdcp::Subtitle> >::const_iterator i = subs.fonts().front()->subtitles().begin ();
+
+ BOOST_CHECK_EQUAL ((*i)->in(), libdcp::Time (0, 0, 5, 198));
+ BOOST_CHECK_EQUAL ((*i)->out(), libdcp::Time (0, 0, 7, 115));
+ BOOST_CHECK_EQUAL ((*i)->texts().size(), 1);
+ BOOST_CHECK_EQUAL ((*i)->texts().front()->v_position(), 15);
+ BOOST_CHECK_EQUAL ((*i)->texts().front()->text(), "My jacket was Idi Amin's");
+}
+