#include "asset.h"
#include "util.h"
+#include "exceptions.h"
+#include "compose.hpp"
#include <libxml++/libxml++.h>
#include <boost/lexical_cast.hpp>
}
void
-Asset::write_to_assetmap (xmlpp::Node* node) const
+Asset::write_to_assetmap (xmlpp::Node* node, boost::filesystem::path root) const
{
assert (!_file.empty ());
asset->add_child("Id")->add_child_text ("urn:uuid:" + _id);
xmlpp::Node* chunk_list = asset->add_child ("ChunkList");
xmlpp::Node* chunk = chunk_list->add_child ("Chunk");
- chunk->add_child("Path")->add_child_text (_file.string ());
+ boost::optional<boost::filesystem::path> path = relative_to_root (root, _file);
+ if (!path) {
+ throw MiscError (String::compose ("Asset %1 is not within the directory %2", _file, root));
+ }
+ chunk->add_child("Path")->add_child_text (path.get().string ());
chunk->add_child("VolumeIndex")->add_child_text ("1");
chunk->add_child("Offset")->add_child_text ("0");
chunk->add_child("Length")->add_child_text (lexical_cast<string> (boost::filesystem::file_size (_file)));
{
assert (!_file.empty ());
- if (!_hash.empty ()) {
+ if (_hash.empty ()) {
_hash = make_digest (_file, 0);
}
return true;
}
+
+void
+Asset::set_file (boost::filesystem::path file) const
+{
+ _file = boost::filesystem::absolute (file);
+ _hash.clear ();
+}
+
/** Write details of the asset to a ASSETMAP.
* @param node Parent node.
*/
- void write_to_assetmap (xmlpp::Node* node) const;
+ void write_to_assetmap (xmlpp::Node* node, boost::filesystem::path root) const;
/** Write details of the asset to a PKL AssetList node.
* @param node Parent node.
return _file;
}
- void set_file (boost::filesystem::path file) const {
- _file = file;
- _hash.clear ();
- }
+ void set_file (boost::filesystem::path file) const;
/** @return the hash of this asset's file. It will be
* computed by this call if necessary.
: _directory (directory)
{
boost::filesystem::create_directories (directory);
+ _directory = boost::filesystem::canonical (_directory);
}
void
chunk->add_child("Length")->add_child_text (lexical_cast<string> (pkl_length));
for (list<shared_ptr<Asset> >::const_iterator i = _assets.begin(); i != _assets.end(); ++i) {
- (*i)->write_to_assetmap (asset_list);
+ (*i)->write_to_assetmap (asset_list, _directory);
}
/* This must not be the _formatted version otherwise signature digests will be wrong */
MonoPictureMXFWriter::start (uint8_t* data, int size)
{
dcp::start (this, _state, _standard, _picture_mxf, data, size);
+ _picture_mxf->set_frame_rate (_picture_mxf->edit_rate());
}
FrameInfo
return _size;
}
+ void set_size (Size s) {
+ _size = s;
+ }
+
Fraction frame_rate () const {
return _frame_rate;
}
+ void set_frame_rate (Fraction r) {
+ _frame_rate = r;
+ }
+
Fraction screen_aspect_ratio () const {
return _screen_aspect_ratio;
}
-protected:
+ void set_screen_aspect_ratio (Fraction r) {
+ _screen_aspect_ratio = r;
+ }
+
+protected:
bool frame_buffer_equals (
int frame, EqualityOptions opt, boost::function<void (NoteType, std::string)> note,
state->j2k_parser.FillPictureDescriptor (state->picture_descriptor);
state->picture_descriptor.EditRate = ASDCP::Rational (mxf->edit_rate().numerator, mxf->edit_rate().denominator);
+
+ mxf->set_size (Size (state->picture_descriptor.StoredWidth, state->picture_descriptor.StoredHeight));
+ mxf->set_screen_aspect_ratio (Fraction (state->picture_descriptor.AspectRatio.Numerator, state->picture_descriptor.AspectRatio.Denominator));
mxf->fill_writer_info (&state->writer_info, standard);
StereoPictureMXFWriter::start (uint8_t* data, int size)
{
dcp::start (this, _state, _standard, _picture_mxf, data, size);
+ _picture_mxf->set_frame_rate (Fraction (_picture_mxf->edit_rate().numerator * 2, _picture_mxf->edit_rate().denominator));
}
/** Write a frame for one eye. Frames must be written left, then right, then left etc.
return fopen (p.c_str(), t.c_str ());
#endif
}
+
+boost::optional<boost::filesystem::path>
+dcp::relative_to_root (boost::filesystem::path root, boost::filesystem::path file)
+{
+ boost::filesystem::path::const_iterator i = root.begin ();
+ boost::filesystem::path::const_iterator j = file.begin ();
+
+ while (i != root.end() && j != file.end() && *i == *j) {
+ ++i;
+ ++j;
+ }
+
+ if (i != root.end ()) {
+ return boost::optional<boost::filesystem::path> ();
+ }
+
+ boost::filesystem::path rel;
+ while (j != file.end ()) {
+ rel /= *j++;
+ }
+
+ return rel;
+}
#include <boost/function.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/filesystem.hpp>
+#include <boost/optional.hpp>
#include <openjpeg.h>
#include <string>
#include <stdint.h>
extern void add_signer (xmlpp::Element* parent, CertificateChain const & certificates, std::string const & ns);
extern int base64_decode (std::string const & in, unsigned char* out, int out_length);
-
+extern boost::optional<boost::filesystem::path> relative_to_root (boost::filesystem::path root, boost::filesystem::path file);
extern std::string tm_to_string (struct tm *);
extern std::string utc_offset_to_string (int);
extern std::string ptime_to_string (boost::posix_time::ptime);
shared_ptr<dcp::MonoPictureMXF> mp (new dcp::MonoPictureMXF (dcp::Fraction (24, 1)));
mp->set_progress (&d.Progress);
mp->set_metadata (mxf_meta);
- shared_ptr<dcp::PictureMXFWriter> picture_writer = mp->start_write ("build/test/DCP/bar/video.mxf", dcp::SMPTE, false);
+ shared_ptr<dcp::PictureMXFWriter> picture_writer = mp->start_write ("build/test/foo/video.mxf", dcp::SMPTE, false);
dcp::File j2c ("test/data/32x32_red_square.j2c");
for (int i = 0; i < 24; ++i) {
picture_writer->write (j2c.data (), j2c.size ());
shared_ptr<dcp::SoundMXF> ms (new dcp::SoundMXF (dcp::Fraction (24, 1), 48000, 1));
ms->set_progress (&d.Progress);
ms->set_metadata (mxf_meta);
- shared_ptr<dcp::SoundMXFWriter> sound_writer = ms->start_write ("build/test/DCP/bar/audio.mxf", dcp::SMPTE);
+ shared_ptr<dcp::SoundMXFWriter> sound_writer = ms->start_write ("build/test/foo/audio.mxf", dcp::SMPTE);
SF_INFO info;
info.format = 0;
));
d.add (cpl);
+ d.add (mp);
+ d.add (ms);
d.write_xml (dcp::SMPTE, xml_meta);
BOOST_CHECK_EQUAL (dcp::content_kind_from_string ("psa"), dcp::PUBLIC_SERVICE_ANNOUNCEMENT);
BOOST_CHECK_EQUAL (dcp::content_kind_from_string ("advertisement"), dcp::ADVERTISEMENT);
}
+
+BOOST_AUTO_TEST_CASE (relative_to_root_test)
+{
+ {
+ boost::filesystem::path root = "a";
+ root /= "b";
+
+ boost::filesystem::path file = "a";
+ file /= "b";
+ file /= "c";
+
+ boost::optional<boost::filesystem::path> rel = dcp::relative_to_root (root, file);
+ BOOST_CHECK (rel);
+ BOOST_CHECK_EQUAL (rel.get(), boost::filesystem::path ("c"));
+ }
+
+ {
+ boost::filesystem::path root = "a";
+ root /= "b";
+ root /= "c";
+
+ boost::filesystem::path file = "a";
+ file /= "b";
+
+ boost::optional<boost::filesystem::path> rel = dcp::relative_to_root (root, file);
+ BOOST_CHECK (!rel);
+ }
+
+ {
+ boost::filesystem::path root = "a";
+
+ boost::filesystem::path file = "a";
+ file /= "b";
+ file /= "c";
+
+ boost::optional<boost::filesystem::path> rel = dcp::relative_to_root (root, file);
+ BOOST_CHECK (rel);
+
+ boost::filesystem::path check = "b";
+ check /= "c";
+ BOOST_CHECK_EQUAL (rel.get(), check);
+ }
+}