exit 1
fi
+# Check the DCP written by dcp_test5
+diff -ur test/ref/DCP/dcp_test5 $work/DCP/dcp_test5
+if [ "$?" != "0" ]; then
+ echo "FAIL: files differ"
+ exit 1
+fi
+
# Check the DCP written by encryption_test
diff -ur test/ref/DCP/encryption_test $work/DCP/encryption_test
if [ "$?" != "0" ]; then
boost::throw_exception (DCPReadError ("could not read Atmos MXF information"));
}
+ _edit_rate = Fraction (desc.EditRate.Numerator, desc.EditRate.Denominator);
+ _intrinsic_duration = desc.ContainerDuration;
_first_frame = desc.FirstFrame;
_max_channel_count = desc.MaxChannelCount;
_max_object_count = desc.MaxObjectCount;
std::string pkl_type (Standard) const;
+ Fraction edit_rate () const {
+ return _edit_rate;
+ }
+
+ int64_t intrinsic_duration () const {
+ return _intrinsic_duration;
+ }
+
/** @return frame number of the frame to align with the FFOA of the picture track */
int first_frame () const {
return _first_frame;
}
private:
+ Fraction _edit_rate;
+ int64_t _intrinsic_duration;
int _first_frame;
int _max_channel_count;
int _max_object_count;
/*
- Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2016 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
#include "reel_picture_asset.h"
#include "reel_sound_asset.h"
#include "reel_subtitle_asset.h"
+#include "reel_atmos_asset.h"
#include "local_time.h"
#include "dcp_assert.h"
#include "compose.hpp"
if (i->main_subtitle ()) {
c.push_back (i->main_subtitle());
}
+ if (i->atmos ()) {
+ c.push_back (i->atmos());
+ }
}
return c;
#include "decrypted_kdm_key.h"
#include "decrypted_kdm.h"
#include "interop_subtitle_asset.h"
+#include "reel_atmos_asset.h"
#include <libxml++/nodes/element.h>
using std::string;
_main_subtitle.reset (new ReelSubtitleAsset (main_subtitle));
}
+ shared_ptr<cxml::Node> atmos = asset_list->optional_node_child ("axd:AuxData");
+ if (atmos) {
+ _atmos.reset (new ReelAtmosAsset (atmos));
+ }
+
node->ignore_child ("AnnotationText");
node->done ();
}
/* ... but stereo pictures must come after */
_main_picture->write_to_cpl (asset_list, standard);
}
+
+ if (_atmos) {
+ _atmos->write_to_cpl (asset_list, standard);
+ }
}
bool
return false;
}
+ if ((_atmos && !other->_atmos) || (!_atmos && other->_atmos)) {
+ note (DCP_ERROR, "Reel: assets differ");
+ return false;
+ }
+
+ if (_atmos && !_atmos->equals (other->_atmos, opt, note)) {
+ return false;
+ }
+
return true;
}
bool
Reel::encrypted () const
{
- return ((_main_picture && _main_picture->encrypted ()) || (_main_sound && _main_sound->encrypted ()));
+ return (
+ (_main_picture && _main_picture->encrypted ()) ||
+ (_main_sound && _main_sound->encrypted ()) ||
+ (_atmos && _atmos->encrypted ())
+ );
}
void
if (i->id() == _main_sound->key_id()) {
_main_sound->asset()->set_key (i->key ());
}
+ if (i->id() == _atmos->key_id()) {
+ _atmos->asset()->set_key (i->key ());
+ }
}
}
shared_ptr<ReelPictureAsset> p = dynamic_pointer_cast<ReelPictureAsset> (asset);
shared_ptr<ReelSoundAsset> so = dynamic_pointer_cast<ReelSoundAsset> (asset);
shared_ptr<ReelSubtitleAsset> su = dynamic_pointer_cast<ReelSubtitleAsset> (asset);
+ shared_ptr<ReelAtmosAsset> a = dynamic_pointer_cast<ReelAtmosAsset> (asset);
if (p) {
_main_picture = p;
} else if (so) {
_main_sound = so;
} else if (su) {
_main_subtitle = su;
+ } else if (a) {
+ _atmos = a;
}
}
iop->resolve_fonts (assets);
}
}
+
+ if (_atmos) {
+ _atmos->asset_ref().resolve (assets);
+ }
}
int64_t
if (_main_subtitle) {
d = max (d, _main_subtitle->duration ());
}
+ if (_atmos) {
+ d = max (d, _atmos->duration ());
+ }
return d;
}
class ReelPictureAsset;
class ReelSoundAsset;
class ReelSubtitleAsset;
+class ReelAtmosAsset;
class Content;
/** @brief A reel within a DCP; the part which actually refers to picture, sound and subtitle data */
Reel (
boost::shared_ptr<ReelPictureAsset> picture,
- boost::shared_ptr<ReelSoundAsset> sound,
- boost::shared_ptr<ReelSubtitleAsset> subtitle
+ boost::shared_ptr<ReelSoundAsset> sound = boost::shared_ptr<ReelSoundAsset> (),
+ boost::shared_ptr<ReelSubtitleAsset> subtitle = boost::shared_ptr<ReelSubtitleAsset> (),
+ boost::shared_ptr<ReelAtmosAsset> atmos = boost::shared_ptr<ReelAtmosAsset> ()
)
: _main_picture (picture)
, _main_sound (sound)
, _main_subtitle (subtitle)
+ , _atmos (atmos)
{}
Reel (boost::shared_ptr<const cxml::Node>);
return _main_subtitle;
}
+ boost::shared_ptr<ReelAtmosAsset> atmos () const {
+ return _atmos;
+ }
+
int64_t duration () const;
void add (boost::shared_ptr<ReelAsset> asset);
boost::shared_ptr<ReelPictureAsset> _main_picture;
boost::shared_ptr<ReelSoundAsset> _main_sound;
boost::shared_ptr<ReelSubtitleAsset> _main_subtitle;
+ boost::shared_ptr<ReelAtmosAsset> _atmos;
};
}
--- /dev/null
+/*
+ Copyright (C) 2016 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.
+
+*/
+
+/** @file src/reel_atmos_asset.cc
+ * @brief ReelAtmosAsset class.
+ */
+
+#include "atmos_asset.h"
+#include "reel_atmos_asset.h"
+#include <libcxml/cxml.h>
+#include <libxml++/libxml++.h>
+
+using std::string;
+using boost::shared_ptr;
+using namespace dcp;
+
+ReelAtmosAsset::ReelAtmosAsset (boost::shared_ptr<AtmosAsset> asset, int64_t entry_point)
+ : ReelAsset (asset, asset->edit_rate(), asset->intrinsic_duration(), entry_point)
+{
+
+}
+
+ReelAtmosAsset::ReelAtmosAsset (boost::shared_ptr<const cxml::Node> node)
+ : ReelAsset (node)
+{
+ node->done ();
+}
+
+string
+ReelAtmosAsset::cpl_node_name () const
+{
+ return "axd:AuxData";
+}
+
+string
+ReelAtmosAsset::key_type () const
+{
+ return "MDEK";
+}
+
+void
+ReelAtmosAsset::write_to_cpl (xmlpp::Node* node, Standard standard) const
+{
+ ReelAsset::write_to_cpl (node, standard);
+
+ /* Find <axd:AuxData> */
+ xmlpp::Node* mp = find_child (node, cpl_node_name ());
+ mp->add_child("axd:DataType")->add_child_text ("urn:smpte:ul:060e2b34.04010105.0e090604.00000000");
+}
--- /dev/null
+/*
+ Copyright (C) 2016 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.
+
+*/
+
+/** @file src/reel_atmos_asset.h
+ * @brief ReelAtmosAsset class.
+ */
+
+#ifndef LIBDCP_REEL_ATMOS_ASSET_H
+#define LIBDCP_REEL_ATMOS_ASSET_H
+
+#include "reel_asset.h"
+#include "atmos_asset.h"
+#include "reel_mxf.h"
+
+namespace dcp {
+
+class AtmosAsset;
+
+/** @class ReelAtmosAsset
+ * @brief Part of a Reel's description which refers to a Atmos MXF.
+ */
+class ReelAtmosAsset : public ReelAsset, public ReelMXF
+{
+public:
+ ReelAtmosAsset (boost::shared_ptr<AtmosAsset> asset, int64_t entry_point);
+ ReelAtmosAsset (boost::shared_ptr<const cxml::Node>);
+
+ boost::shared_ptr<AtmosAsset> asset () const {
+ return asset_of_type<AtmosAsset> ();
+ }
+
+ void write_to_cpl (xmlpp::Node* node, Standard standard) const;
+
+private:
+ std::string key_type () const;
+ std::string cpl_node_name () const;
+};
+
+}
+
+#endif
picture_asset_writer.cc
reel.cc
reel_asset.cc
+ reel_atmos_asset.cc
reel_mono_picture_asset.cc
reel_mxf.cc
reel_picture_asset.cc
rgb_xyz.h
reel.h
reel_asset.h
+ reel_atmos_asset.h
reel_mono_picture_asset.h
reel_mxf.h
reel_picture_asset.h
#include <boost/test/unit_test.hpp>
#include <iostream>
-BOOST_AUTO_TEST_CASE (atmos_test)
+/** Check basic read of an Atmos asset */
+BOOST_AUTO_TEST_CASE (atmos_read_test)
{
dcp::AtmosAsset a (private_test / "20160218_NameOfFilm_FTR_OV_EN_A_dcs_r01.mxf");
BOOST_CHECK_EQUAL (a.first_frame(), 192);
#include "picture_asset_writer.h"
#include "sound_asset_writer.h"
#include "sound_asset.h"
+#include "atmos_asset.h"
#include "reel.h"
#include "test.h"
#include "file.h"
#include "reel_mono_picture_asset.h"
#include "reel_stereo_picture_asset.h"
#include "reel_sound_asset.h"
+#include "reel_atmos_asset.h"
#include "KM_util.h"
#include <sndfile.h>
#include <boost/test/unit_test.hpp>
cpl->add (shared_ptr<dcp::Reel> (
new dcp::Reel (
shared_ptr<dcp::ReelMonoPictureAsset> (new dcp::ReelMonoPictureAsset (mp, 0)),
- shared_ptr<dcp::ReelSoundAsset> (new dcp::ReelSoundAsset (ms, 0)),
- shared_ptr<dcp::ReelSubtitleAsset> ()
+ shared_ptr<dcp::ReelSoundAsset> (new dcp::ReelSoundAsset (ms, 0))
)
));
d.write_xml (dcp::SMPTE, xml_meta);
- /* build/test/DCP/dcp_test1 is checked against test/ref/DCP/dcp_test1 by run-tests.sh */
+ /* build/test/DCP/dcp_test1 is checked against test/ref/DCP/dcp_test1 by run/tests */
}
/** Test creation of a 3D DCP from very simple inputs */
cpl->add (shared_ptr<dcp::Reel> (
new dcp::Reel (
shared_ptr<dcp::ReelStereoPictureAsset> (new dcp::ReelStereoPictureAsset (mp, 0)),
- shared_ptr<dcp::ReelSoundAsset> (new dcp::ReelSoundAsset (ms, 0)),
- shared_ptr<dcp::ReelSubtitleAsset> ()
+ shared_ptr<dcp::ReelSoundAsset> (new dcp::ReelSoundAsset (ms, 0))
)
));
d.write_xml (dcp::SMPTE, xml_meta);
- /* build/test/DCP/dcp_test2 is checked against test/ref/DCP/dcp_test2 by run-tests.sh */
+ /* build/test/DCP/dcp_test2 is checked against test/ref/DCP/dcp_test2 by run/tests */
}
static void
BOOST_CHECK (!A.equals (B, dcp::EqualityOptions(), boost::bind (¬e, _1, _2)));
}
+
+/** Test creation of a 2D DCP with an Atmos track */
+BOOST_AUTO_TEST_CASE (dcp_test5)
+{
+ Kumu::cth_test = true;
+
+ /* Some known metadata */
+ dcp::XMLMetadata xml_meta;
+ xml_meta.issuer = "OpenDCP 0.0.25";
+ xml_meta.creator = "OpenDCP 0.0.25";
+ xml_meta.issue_date = "2012-07-17T04:45:18+00:00";
+ dcp::MXFMetadata mxf_meta;
+ mxf_meta.company_name = "OpenDCP";
+ mxf_meta.product_name = "OpenDCP";
+ mxf_meta.product_version = "0.0.25";
+
+ /* We're making build/test/DCP/dcp_test5 */
+ boost::filesystem::remove_all ("build/test/DCP/dcp_test5");
+ boost::filesystem::create_directories ("build/test/DCP/dcp_test5");
+ dcp::DCP d ("build/test/DCP/dcp_test5");
+ shared_ptr<dcp::CPL> cpl (new dcp::CPL ("A Test DCP", dcp::FEATURE));
+ cpl->set_content_version_id ("urn:uri:81fb54df-e1bf-4647-8788-ea7ba154375b_2012-07-17T04:45:18+00:00");
+ cpl->set_content_version_label_text ("81fb54df-e1bf-4647-8788-ea7ba154375b_2012-07-17T04:45:18+00:00");
+ cpl->set_metadata (xml_meta);
+
+ shared_ptr<dcp::MonoPictureAsset> mp (new dcp::MonoPictureAsset (dcp::Fraction (24, 1)));
+ mp->set_metadata (mxf_meta);
+ shared_ptr<dcp::PictureAssetWriter> picture_writer = mp->start_write ("build/test/DCP/dcp_test5/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 ());
+ }
+ picture_writer->finalize ();
+
+ shared_ptr<dcp::SoundAsset> ms (new dcp::SoundAsset (dcp::Fraction (24, 1), 48000, 1));
+ ms->set_metadata (mxf_meta);
+ shared_ptr<dcp::SoundAssetWriter> sound_writer = ms->start_write ("build/test/DCP/dcp_test5/audio.mxf", dcp::SMPTE);
+
+ SF_INFO info;
+ info.format = 0;
+ SNDFILE* sndfile = sf_open ("test/data/1s_24-bit_48k_silence.wav", SFM_READ, &info);
+ BOOST_CHECK (sndfile);
+ float buffer[4096*6];
+ float* channels[1];
+ channels[0] = buffer;
+ while (1) {
+ sf_count_t N = sf_readf_float (sndfile, buffer, 4096);
+ sound_writer->write (channels, N);
+ if (N < 4096) {
+ break;
+ }
+ }
+
+ sound_writer->finalize ();
+
+ shared_ptr<dcp::AtmosAsset> am (new dcp::AtmosAsset (private_test / "20160218_NameOfFilm_FTR_OV_EN_A_dcs_r01.mxf"));
+
+ cpl->add (shared_ptr<dcp::Reel> (
+ new dcp::Reel (
+ shared_ptr<dcp::ReelMonoPictureAsset> (new dcp::ReelMonoPictureAsset (mp, 0)),
+ shared_ptr<dcp::ReelSoundAsset> (new dcp::ReelSoundAsset (ms, 0)),
+ shared_ptr<dcp::ReelSubtitleAsset> (),
+ shared_ptr<dcp::ReelAtmosAsset> (new dcp::ReelAtmosAsset (am, 0))
+ )
+ ));
+
+ d.add (cpl);
+
+ d.write_xml (dcp::SMPTE, xml_meta);
+
+ /* build/test/DCP/dcp_test5 is checked against test/ref/DCP/dcp_test5 by run/tests */
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<AssetMap xmlns="http://www.smpte-ra.org/schemas/429-9/2007/AM"><Id>urn:uuid:74e205d0-d145-42d2-8c49-7b55d058ca55</Id><AnnotationText>Created by OpenDCP 0.0.25</AnnotationText><Creator>OpenDCP 0.0.25</Creator><VolumeCount>1</VolumeCount><IssueDate>2012-07-17T04:45:18+00:00</IssueDate><Issuer>OpenDCP 0.0.25</Issuer><AssetList><Asset><Id>urn:uuid:ae8a9818-872a-4f86-8493-11dfdea03e09</Id><PackingList>true</PackingList><ChunkList><Chunk><Path>pkl_ae8a9818-872a-4f86-8493-11dfdea03e09.xml</Path><VolumeIndex>1</VolumeIndex><Offset>0</Offset><Length>1022</Length></Chunk></ChunkList></Asset><Asset><Id>urn:uuid:81fb54df-e1bf-4647-8788-ea7ba154375b</Id><ChunkList><Chunk><Path>cpl_81fb54df-e1bf-4647-8788-ea7ba154375b.xml</Path><VolumeIndex>1</VolumeIndex><Offset>0</Offset><Length>1768</Length></Chunk></ChunkList></Asset><Asset><Id>urn:uuid:46c3eb45-15e5-47d6-8684-d8641e4dc516</Id><ChunkList><Chunk><Path>video.mxf</Path><VolumeIndex>1</VolumeIndex><Offset>0</Offset><Length>26080</Length></Chunk></ChunkList></Asset><Asset><Id>urn:uuid:9482e87d-292d-4e0e-a98d-c61822b60fe9</Id><ChunkList><Chunk><Path>audio.mxf</Path><VolumeIndex>1</VolumeIndex><Offset>0</Offset><Length>161326</Length></Chunk></ChunkList></Asset></AssetList></AssetMap>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<VolumeIndex xmlns="http://www.smpte-ra.org/schemas/429-9/2007/AM"><Index>1</Index></VolumeIndex>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<CompositionPlaylist xmlns="http://www.smpte-ra.org/schemas/429-7/2006/CPL"><Id>urn:uuid:81fb54df-e1bf-4647-8788-ea7ba154375b</Id><AnnotationText>A Test DCP</AnnotationText><IssueDate>2012-07-17T04:45:18+00:00</IssueDate><Issuer>OpenDCP 0.0.25</Issuer><Creator>OpenDCP 0.0.25</Creator><ContentTitleText>A Test DCP</ContentTitleText><ContentKind>feature</ContentKind><ContentVersion><Id>urn:uri:81fb54df-e1bf-4647-8788-ea7ba154375b_2012-07-17T04:45:18+00:00</Id><LabelText>81fb54df-e1bf-4647-8788-ea7ba154375b_2012-07-17T04:45:18+00:00</LabelText></ContentVersion><RatingList/><ReelList><Reel><Id>urn:uuid:18be072e-5a0f-44e1-b2eb-c8a52ae12789</Id><AssetList><MainPicture><Id>urn:uuid:46c3eb45-15e5-47d6-8684-d8641e4dc516</Id><AnnotationText>video.mxf</AnnotationText><EditRate>24 1</EditRate><IntrinsicDuration>24</IntrinsicDuration><EntryPoint>0</EntryPoint><Duration>24</Duration><Hash>KdrrbczelKFhmvqbhvzFX7Mxiro=</Hash><FrameRate>24 1</FrameRate><ScreenAspectRatio>32 32</ScreenAspectRatio></MainPicture><MainSound><Id>urn:uuid:9482e87d-292d-4e0e-a98d-c61822b60fe9</Id><AnnotationText>audio.mxf</AnnotationText><EditRate>24 1</EditRate><IntrinsicDuration>24</IntrinsicDuration><EntryPoint>0</EntryPoint><Duration>24</Duration><Hash>+dJynGEtjP7cApJ17SNz171iI4A=</Hash></MainSound><axd:AuxData><Id>urn:uuid:b135d5cf-d180-43d8-b0b3-7373737b73bf</Id><AnnotationText>20160218_NameOfFilm_FTR_OV_EN_A_dcs_r01.mxf</AnnotationText><EditRate>24 1</EditRate><IntrinsicDuration>1489</IntrinsicDuration><EntryPoint>0</EntryPoint><Duration>1489</Duration><Hash>jo8pQSebhScPN4EVvvpIUWRrDeM=</Hash><axd:DataType>urn:smpte:ul:060e2b34.04010105.0e090604.00000000</axd:DataType></axd:AuxData></AssetList></Reel></ReelList></CompositionPlaylist>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<PackingList xmlns="http://www.smpte-ra.org/schemas/429-8/2007/PKL"><Id>urn:uuid:ae8a9818-872a-4f86-8493-11dfdea03e09</Id><AnnotationText>A Test DCP</AnnotationText><IssueDate>2012-07-17T04:45:18+00:00</IssueDate><Issuer>OpenDCP 0.0.25</Issuer><Creator>OpenDCP 0.0.25</Creator><AssetList><Asset><Id>urn:uuid:81fb54df-e1bf-4647-8788-ea7ba154375b</Id><AnnotationText>81fb54df-e1bf-4647-8788-ea7ba154375b</AnnotationText><Hash>dVhGU/gRwjhAp0yGxCqaHuGy2tI=</Hash><Size>1768</Size><Type>text/xml</Type></Asset><Asset><Id>urn:uuid:46c3eb45-15e5-47d6-8684-d8641e4dc516</Id><AnnotationText>46c3eb45-15e5-47d6-8684-d8641e4dc516</AnnotationText><Hash>KdrrbczelKFhmvqbhvzFX7Mxiro=</Hash><Size>26080</Size><Type>application/mxf</Type></Asset><Asset><Id>urn:uuid:9482e87d-292d-4e0e-a98d-c61822b60fe9</Id><AnnotationText>9482e87d-292d-4e0e-a98d-c61822b60fe9</AnnotationText><Hash>+dJynGEtjP7cApJ17SNz171iI4A=</Hash><Size>161326</Size><Type>application/mxf</Type></Asset></AssetList></PackingList>