/*
- Copyright (C) 2015-2020 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2015-2021 Carl Hetherington <cth@carlh.net>
This file is part of libdcp.
files in the program, then also delete it here.
*/
+
#include "array_data.h"
#include "util.h"
#include "exceptions.h"
#include <cstdio>
#include <cerrno>
+
using boost::shared_array;
using namespace dcp;
+
ArrayData::ArrayData ()
: _size (0)
{
}
+
ArrayData::ArrayData (int size)
: _data (new uint8_t[size])
, _size (size)
}
+
ArrayData::ArrayData (uint8_t const * data, int size)
: _data (new uint8_t[size])
, _size (size)
memcpy (_data.get(), data, size);
}
+
ArrayData::ArrayData (shared_array<uint8_t> data, int size)
: _data (data)
, _size (size)
}
+
ArrayData::ArrayData (boost::filesystem::path file)
{
_size = boost::filesystem::file_size (file);
_data.reset (new uint8_t[_size]);
- FILE* f = fopen_boost (file, "rb");
+ auto f = fopen_boost (file, "rb");
if (!f) {
throw FileError ("could not open file for reading", file, errno);
}
- size_t const r = fread (_data.get(), 1, _size, f);
- if (r != size_t (_size)) {
- fclose (f);
+ auto const r = fread (_data.get(), 1, _size, f);
+ fclose (f);
+ if (r != static_cast<size_t>(_size)) {
throw FileError ("could not read from file", file, errno);
}
-
- fclose (f);
}
/*
- Copyright (C) 2015-2020 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2015-2021 Carl Hetherington <cth@carlh.net>
This file is part of libdcp.
files in the program, then also delete it here.
*/
+
+/** @file src/array_data.h
+ * @brief ArrayData class.
+ */
+
+
#ifndef LIBDCP_ARRAY_DATA_H
#define LIBDCP_ARRAY_DATA_H
#include <boost/filesystem.hpp>
#include <stdint.h>
+
namespace dcp {
+/** @brief Class to hold an arbitrary block of data */
class ArrayData : public Data
{
public:
ArrayData ();
explicit ArrayData (int size);
ArrayData (uint8_t const * data, int size);
+
+ /** Create an ArrayData by copying a shared_array<>
+ * @param data shared_array<> to copy (the shared_array<> is copied, not the data)
+ * @param size Size of data in bytes
+ */
ArrayData (boost::shared_array<uint8_t> data, int size);
+
+ /** Create an ArrayData by reading the contents of a file
+ * @param file Filename to read
+ */
explicit ArrayData (boost::filesystem::path file);
virtual ~ArrayData () {}
return _data.get();
}
+ /** @return size of the data in _data, or whatever was last
+ * passed to a set_size() call
+ */
int size () const {
return _size;
}
+ /** Set the size that will be returned from size() */
void set_size (int s) {
_size = s;
}
int _size;
};
+
}
+
#endif
/*
- Copyright (C) 2014-2018 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2014-2021 Carl Hetherington <cth@carlh.net>
This file is part of libdcp.
files in the program, then also delete it here.
*/
+
/** @file src/asset.cc
* @brief Asset class.
*/
+
#include "raw_convert.h"
#include "asset.h"
#include "util.h"
#include <libxml++/libxml++.h>
#include <boost/algorithm/string.hpp>
+
using std::string;
using boost::function;
using std::shared_ptr;
using boost::optional;
+using namespace boost::filesystem;
using namespace dcp;
-/** Create an Asset with a randomly-generated ID */
+
Asset::Asset ()
{
}
-/** Create an Asset from a given file.
- * @param file File name.
- */
-Asset::Asset (boost::filesystem::path file)
+
+Asset::Asset (path file)
: _file (file)
{
}
-/** Create an Asset from a given file with a known ID.
- * @param file File name.
- * @param id ID.
- */
-Asset::Asset (string id, boost::filesystem::path file)
+
+Asset::Asset (string id, path file)
: Object (id)
, _file (file)
{
}
+
void
-Asset::add_to_pkl (shared_ptr<PKL> pkl, boost::filesystem::path root) const
+Asset::add_to_pkl (shared_ptr<PKL> pkl, path root) const
{
DCP_ASSERT (_file);
- optional<boost::filesystem::path> path = relative_to_root (
- boost::filesystem::canonical (root),
- boost::filesystem::canonical (_file.get())
+ auto path = relative_to_root (
+ canonical(root),
+ canonical(_file.get())
);
if (!path) {
return;
}
- pkl->add_asset (_id, _id, hash(), boost::filesystem::file_size (_file.get()), pkl_type (pkl->standard()));
+ pkl->add_asset (_id, _id, hash(), file_size(_file.get()), pkl_type(pkl->standard()));
}
+
void
-Asset::write_to_assetmap (xmlpp::Node* node, boost::filesystem::path root) const
+Asset::write_to_assetmap (xmlpp::Node* node, path root) const
{
DCP_ASSERT (_file);
write_file_to_assetmap (node, root, _file.get(), _id);
}
+
void
-Asset::write_file_to_assetmap (xmlpp::Node* node, boost::filesystem::path root, boost::filesystem::path file, string id)
+Asset::write_file_to_assetmap (xmlpp::Node* node, path root, path file, string id)
{
- optional<boost::filesystem::path> path = relative_to_root (
- boost::filesystem::canonical (root),
- boost::filesystem::canonical (file)
+ auto path = relative_to_root (
+ canonical(root),
+ canonical(file)
);
if (!path) {
return;
}
- xmlpp::Node* asset = node->add_child ("Asset");
- 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");
+ auto asset = node->add_child ("Asset");
+ asset->add_child("Id")->add_child_text("urn:uuid:" + id);
+ auto chunk_list = asset->add_child ("ChunkList");
+ auto chunk = chunk_list->add_child ("Chunk");
- chunk->add_child("Path")->add_child_text (path.get().generic_string());
- chunk->add_child("VolumeIndex")->add_child_text ("1");
- chunk->add_child("Offset")->add_child_text ("0");
- chunk->add_child("Length")->add_child_text (raw_convert<string> (boost::filesystem::file_size (file)));
+ chunk->add_child("Path")->add_child_text(path.get().generic_string());
+ chunk->add_child("VolumeIndex")->add_child_text("1");
+ chunk->add_child("Offset")->add_child_text("0");
+ chunk->add_child("Length")->add_child_text(raw_convert<string>(file_size(file)));
}
+
string
Asset::hash (function<void (float)> progress) const
{
return _hash.get();
}
+
bool
Asset::equals (std::shared_ptr<const Asset> other, EqualityOptions, NoteHandler note) const
{
return true;
}
-/** Set the file that holds this asset on disk. Calling this function
- * clears this object's store of its hash, so you should call ::hash
- * after this.
- *
- * @param file New file's path.
- */
+
void
-Asset::set_file (boost::filesystem::path file) const
+Asset::set_file (path file) const
{
- _file = boost::filesystem::absolute (file);
- _hash = optional<string> ();
+ _file = absolute (file);
+ _hash = {};
}
+
void
Asset::set_hash (string hash)
{
/*
- Copyright (C) 2014 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2014-2021 Carl Hetherington <cth@carlh.net>
This file is part of libdcp.
files in the program, then also delete it here.
*/
+
/** @file src/asset.h
- * @brief Asset class.
+ * @brief Asset class
*/
+
#ifndef LIBDCP_ASSET_H
#define LIBDCP_ASSET_H
+
#include "object.h"
#include "types.h"
#include "pkl.h"
#include <boost/function.hpp>
#include <boost/optional.hpp>
+
namespace xmlpp {
class Node;
}
+
struct asset_test;
+
namespace dcp {
+
/** @class Asset
- * @brief Parent class for DCP assets, i.e. picture, sound, subtitles, CPLs, fonts.
+ * @brief Parent class for DCP assets, i.e. picture, sound, subtitles, closed captions, CPLs, fonts
*
* Note that this class is not used for ReelAssets; those are just for the metadata
* that gets put into <Reel>s.
class Asset : public Object
{
public:
+ /** Create an Asset with a randomly-generated ID */
Asset ();
+
+ /** Create an Asset from a given file with a randomly-generated ID
+ * @param file File name
+ */
explicit Asset (boost::filesystem::path file);
+
+ /** Create an Asset from a given file with a given ID
+ * @param id ID
+ * @param file File name
+ */
Asset (std::string id, boost::filesystem::path file);
virtual bool equals (
NoteHandler note
) const;
- /** Write details of the asset to a ASSETMAP.
- * @param node Parent node.
- */
virtual void write_to_assetmap (xmlpp::Node* node, boost::filesystem::path root) const;
virtual void add_to_pkl (std::shared_ptr<PKL> pkl, boost::filesystem::path root) const;
return _file;
}
+ /** Set the file that holds this asset on disk. Calling this function
+ * clears this object's store of its hash, so you should call ::hash
+ * after this.
+ *
+ * @param file New file's path.
+ */
void set_file (boost::filesystem::path file) const;
- /** @return the hash of this asset's file */
- std::string hash (boost::function<void (float)> progress = 0) const;
+ /** Calculate the hash of this asset's file, if it has not already been calculated,
+ * then return it
+ * @param progress Function that will be called with a parameter between 0 and 1 to indicate
+ * progress in the calculation
+ * @return the hash
+ */
+ std::string hash (boost::function<void (float)> progress = {}) const;
void set_hash (std::string hash);
mutable boost::optional<std::string> _hash;
};
+
}
+
#endif
/*
- Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2018-2021 Carl Hetherington <cth@carlh.net>
This file is part of libdcp.
#include <memory>
using std::shared_ptr;
+using std::make_shared;
using namespace dcp;
shared_ptr<Asset>
throw ReadError ("MPEG2 video essences are not supported");
case ASDCP::ESS_JPEG_2000:
try {
- return shared_ptr<MonoPictureAsset> (new MonoPictureAsset (path));
+ return make_shared<MonoPictureAsset>(path);
} catch (dcp::MXFFileError& e) {
if (ignore_incorrect_picture_mxf_type && e.number() == ASDCP::RESULT_SFORMAT) {
/* Tried to load it as mono but the error says it's stereo; try that instead */
- return shared_ptr<StereoPictureAsset> (new StereoPictureAsset (path));
+ return make_shared<StereoPictureAsset>(path);
} else {
throw;
}
}
case ASDCP::ESS_PCM_24b_48k:
case ASDCP::ESS_PCM_24b_96k:
- return shared_ptr<SoundAsset> (new SoundAsset (path));
+ return make_shared<SoundAsset>(path);
case ASDCP::ESS_JPEG_2000_S:
- return shared_ptr<StereoPictureAsset> (new StereoPictureAsset (path));
+ return make_shared<StereoPictureAsset>(path);
case ASDCP::ESS_TIMED_TEXT:
- return shared_ptr<SMPTESubtitleAsset> (new SMPTESubtitleAsset (path));
+ return make_shared<SMPTESubtitleAsset>(path);
case ASDCP::ESS_DCDATA_DOLBY_ATMOS:
- return shared_ptr<AtmosAsset> (new AtmosAsset (path));
+ return make_shared<AtmosAsset>(path);
default:
- throw ReadError (String::compose ("Unknown MXF essence type %1 in %2", int(type), path.string()));
+ throw ReadError (String::compose("Unknown MXF essence type %1 in %2", static_cast<int>(type), path.string()));
}
- return shared_ptr<Asset>();
+ return {};
}
/*
- Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2018-2021 Carl Hetherington <cth@carlh.net>
This file is part of libdcp.
/*
- Copyright (C) 2016 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2016-2021 Carl Hetherington <cth@carlh.net>
This file is part of libdcp.
files in the program, then also delete it here.
*/
+
#include "atmos_asset.h"
#include "atmos_asset_reader.h"
#include "atmos_asset_writer.h"
#include "exceptions.h"
#include <asdcp/AS_DCP.h>
+
using std::string;
using std::shared_ptr;
using std::make_shared;
using namespace dcp;
+
AtmosAsset::AtmosAsset (Fraction edit_rate, int first_frame, int max_channel_count, int max_object_count, int atmos_version)
: MXF (Standard::SMPTE)
, _edit_rate (edit_rate)
}
+
AtmosAsset::AtmosAsset (boost::filesystem::path file)
: Asset (file)
, MXF (Standard::SMPTE)
{
ASDCP::ATMOS::MXFReader reader;
- Kumu::Result_t r = reader.OpenRead (file.string().c_str());
+ auto r = reader.OpenRead (file.string().c_str());
if (ASDCP_FAILURE (r)) {
- boost::throw_exception (MXFFileError ("could not open MXF file for reading", file.string(), r));
+ boost::throw_exception (MXFFileError("could not open MXF file for reading", file.string(), r));
}
ASDCP::ATMOS::AtmosDescriptor desc;
if (ASDCP_FAILURE (reader.FillAtmosDescriptor (desc))) {
- boost::throw_exception (ReadError ("could not read Atmos MXF information"));
+ boost::throw_exception (ReadError("could not read Atmos MXF information"));
}
_edit_rate = Fraction (desc.EditRate.Numerator, desc.EditRate.Denominator);
_max_object_count = desc.MaxObjectCount;
char id[64];
- Kumu::bin2UUIDhex (desc.AtmosID, ASDCP::UUIDlen, id, sizeof (id));
+ Kumu::bin2UUIDhex (desc.AtmosID, ASDCP::UUIDlen, id, sizeof(id));
_atmos_id = id;
_atmos_version = desc.AtmosVersion;
ASDCP::WriterInfo info;
- if (ASDCP_FAILURE (reader.FillWriterInfo (info))) {
+ if (ASDCP_FAILURE (reader.FillWriterInfo(info))) {
boost::throw_exception (ReadError ("could not read audio MXF information"));
}
_id = read_writer_info (info);
}
+
string
AtmosAsset::static_pkl_type (Standard)
{
return "application/mxf";
}
+
shared_ptr<AtmosAssetReader>
AtmosAsset::start_read () const
{
return make_shared<AtmosAssetReader>(this, key(), Standard::SMPTE);
}
+
shared_ptr<AtmosAssetWriter>
AtmosAsset::start_write (boost::filesystem::path file)
{
- return shared_ptr<AtmosAssetWriter> (new AtmosAssetWriter (this, file));
+ /* Can't use make_shared here since the constructor is protected */
+ return shared_ptr<AtmosAssetWriter>(new AtmosAssetWriter(this, file));
}
/*
- Copyright (C) 2016 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2016-2021 Carl Hetherington <cth@carlh.net>
This file is part of libdcp.
files in the program, then also delete it here.
*/
+
+/** @file src/atmos_asset.h
+ * @brief AtmosAsset class
+ */
+
+
#ifndef LIBDCP_ATMOS_ASSET_H
#define LIBDCP_ATMOS_ASSET_H
+
#include "asset.h"
#include "mxf.h"
#include "atmos_asset_reader.h"
+
namespace dcp {
+
class AtmosAssetWriter;
+
+/** @class AtmosAsset
+ * @brief An asset of Dolby ATMOS sound data
+ */
class AtmosAsset : public Asset, public MXF
{
public:
int _atmos_version;
};
+
}
+
#endif
/*
- Copyright (C) 2016-2020 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2016-2021 Carl Hetherington <cth@carlh.net>
This file is part of libdcp.
files in the program, then also delete it here.
*/
+
#include "atmos_asset_writer.h"
#include "atmos_asset.h"
#include "exceptions.h"
#include "crypto_context.h"
#include <asdcp/AS_DCP.h>
+
using std::min;
using std::max;
using std::shared_ptr;
using namespace dcp;
+
struct AtmosAssetWriter::ASDCPState
{
ASDCP::ATMOS::MXFWriter mxf_writer;
ASDCP::ATMOS::AtmosDescriptor desc;
};
+
AtmosAssetWriter::AtmosAssetWriter (AtmosAsset* asset, boost::filesystem::path file)
: AssetWriter (asset, file)
, _state (new AtmosAssetWriter::ASDCPState)
DCP_ASSERT (!_finalized);
if (!_started) {
- Kumu::Result_t r = _state->mxf_writer.OpenWrite (_file.string().c_str(), _state->writer_info, _state->desc);
- if (ASDCP_FAILURE (r)) {
+ auto r = _state->mxf_writer.OpenWrite (_file.string().c_str(), _state->writer_info, _state->desc);
+ if (ASDCP_FAILURE(r)) {
boost::throw_exception (FileError ("could not open atmos MXF for writing", _file.string(), r));
}
_state->frame_buffer.Size (size);
memcpy (_state->frame_buffer.Data(), data, size);
- ASDCP::Result_t const r = _state->mxf_writer.WriteFrame (_state->frame_buffer, _crypto_context->context(), _crypto_context->hmac());
- if (ASDCP_FAILURE (r)) {
- boost::throw_exception (MiscError (String::compose ("could not write atmos MXF frame (%1)", int (r))));
+ auto const r = _state->mxf_writer.WriteFrame (_state->frame_buffer, _crypto_context->context(), _crypto_context->hmac());
+ if (ASDCP_FAILURE(r)) {
+ boost::throw_exception (MiscError(String::compose("could not write atmos MXF frame (%1)", static_cast<int>(r))));
}
++_frames_written;
bool
AtmosAssetWriter::finalize ()
{
- if (_started && ASDCP_FAILURE (_state->mxf_writer.Finalize())) {
- boost::throw_exception (MiscError ("could not finalise atmos MXF"));
+ if (_started && ASDCP_FAILURE(_state->mxf_writer.Finalize())) {
+ boost::throw_exception (MiscError("could not finalise atmos MXF"));
}
_asset->_intrinsic_duration = _frames_written;
/*
- Copyright (C) 2016 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2016-2021 Carl Hetherington <cth@carlh.net>
This file is part of libdcp.
files in the program, then also delete it here.
*/
-#ifndef LIBDCP_ATMOS_ASSET_WRITER_H
-#define LIBDCP_ATMOS_ASSET_WRITER_H
/** @file src/atmos_asset_writer.h
- * @brief AtmosAssetWriter class.
+ * @brief AtmosAssetWriter class
*/
+
+#ifndef LIBDCP_ATMOS_ASSET_WRITER_H
+#define LIBDCP_ATMOS_ASSET_WRITER_H
+
+
#include "asset_writer.h"
#include "types.h"
#include "atmos_frame.h"
#include <memory>
#include <boost/filesystem.hpp>
+
namespace dcp {
+
class AtmosAsset;
+
/** @class AtmosAssetWriter
* @brief A helper class for writing to AtmosAssets.
*
AtmosAsset* _asset;
};
+
}
+
#endif