/*
-Copyright (c) 2003-2012, John Hurst
+Copyright (c) 2003-2018, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*! \file AS_DCP.h
- \version $Id$
+ \version $Id$
\brief AS-DCP library, public interface
The asdcplib library is a set of file access objects that offer simplified
access to files conforming to the standards published by the SMPTE
D-Cinema Technology Committee 21DC. The file format, labeled AS-DCP,
-is described in series of separate documents which include but may not
+is described in a series of documents which includes but may not
be be limited to:
o SMPTE ST 429-2:2011 DCP Operational Constraints
o SMPTE ST 429-5:2009 Timed Text Track File
o SMPTE ST 429-6:2006 MXF Track File Essence Encryption
o SMPTE ST 429-10:2008 Stereoscopic Picture Track File
+ o SMPTE ST 429-14:2008 Aux Data Track File
o SMPTE ST 330:2004 - UMID
o SMPTE ST 336:2001 - KLV
+ o SMPTE ST 377:2004 - MXF (old version, required)
o SMPTE ST 377-1:2011 - MXF
o SMPTE ST 377-4:2012 - MXF Multichannel Audio Labeling Framework
o SMPTE ST 390:2011 - MXF OP-Atom
The following use cases are supported by the library:
o Write essence to a plaintext or ciphertext AS-DCP file:
- MPEG2 Video Elementary Stream
- JPEG 2000 codestreams
- JPEG 2000 stereoscopic codestream pairs
- PCM audio streams
- SMPTE 429-7 Timed Text XML with font and image resources
-
o Read essence from a plaintext or ciphertext AS-DCP file:
MPEG2 Video Elementary Stream
JPEG 2000 codestreams
JPEG 2000 stereoscopic codestream pairs
PCM audio streams
SMPTE 429-7 Timed Text XML with font and image resources
+ Aux Data (frame-wrapped synchronous blob)
+ Proposed Dolby (TM) Atmos track file
o Read header metadata from an AS-DCP file
#define _AS_DCP_H_
#include <KM_error.h>
+#include <KM_fileio.h>
#include <stdio.h>
#include <stdarg.h>
#include <math.h>
// The file accessors in this library implement a bounded set of essence types.
// This list will be expanded when support for new types is added to the library.
enum EssenceType_t {
- ESS_UNKNOWN, // the file is not a supported AS-DCP essence container
- ESS_MPEG2_VES, // the file contains an MPEG video elementary stream
- ESS_JPEG_2000, // the file contains one or more JPEG 2000 codestreams
- ESS_PCM_24b_48k, // the file contains one or more PCM audio pairs
- ESS_PCM_24b_96k, // the file contains one or more PCM audio pairs
- ESS_TIMED_TEXT, // the file contains an XML timed text document and one or more resources
- ESS_JPEG_2000_S, // the file contains one or more JPEG 2000 codestream pairs (stereoscopic)
+ ESS_UNKNOWN, // the file is not a supported AS-DCP of AS-02 essence container
+
+ //
+ ESS_MPEG2_VES, // the file contains an MPEG-2 video elementary stream
+
+ // d-cinema essence types
+ ESS_JPEG_2000, // the file contains one or more JPEG 2000 codestreams
+ ESS_PCM_24b_48k, // the file contains one or more PCM audio pairs
+ ESS_PCM_24b_96k, // the file contains one or more PCM audio pairs
+ ESS_TIMED_TEXT, // the file contains an XML timed text document and one or more resources
+ ESS_JPEG_2000_S, // the file contains one or more JPEG 2000 codestream pairs (stereoscopic)
+ ESS_DCDATA_UNKNOWN, // the file contains one or more D-Cinema Data bytestreams
+ ESS_DCDATA_DOLBY_ATMOS, // the file contains one or more DolbyATMOS bytestreams
+
+ // IMF essence types
+ ESS_AS02_JPEG_2000, // the file contains one or more JPEG 2000 codestreams
+ ESS_AS02_PCM_24b_48k, // the file contains one or more PCM audio pairs, clip wrapped
+ ESS_AS02_PCM_24b_96k, // the file contains one or more PCM audio pairs, clip wrapped
+ ESS_AS02_TIMED_TEXT, // the file contains a TTML document and zero or more resources
+ ESS_AS02_ISXD, // the file contains an ISXD document stream (per SMPTE RDD 47)
+ ESS_AS02_ACES, // the file contains two or more ACES codestreams (per SMPTE ST 2067-50)
+ ESS_MAX
};
// Determine the type of essence contained in the given MXF file. RESULT_OK
// is returned if the file is successfully opened and contains a valid MXF
// stream. If there is an error, the result code will indicate the reason.
- Result_t EssenceType(const char* filename, EssenceType_t& type);
+ Result_t EssenceType(const std::string& filename, EssenceType_t& type);
// Determine the type of essence contained in the given raw file. RESULT_OK
// is returned if the file is successfully opened and contains a known
// stream type. If there is an error, the result code will indicate the reason.
- Result_t RawEssenceType(const char* filename, EssenceType_t& type);
+ Result_t RawEssenceType(const std::string& filename, EssenceType_t& type);
//---------------------------------------------------------------------------------
if ( Numerator == rhs.Numerator && Denominator < rhs.Denominator ) return true;
return false;
}
-
+
inline bool operator>(const Rational& rhs) {
if ( Numerator > rhs.Numerator ) return true;
if ( Numerator == rhs.Numerator && Denominator > rhs.Denominator ) return true;
}
};
+ // Encodes a rational number as a string having a single delimiter character between
+ // numerator and denominator. Retuns the buffer pointer to allow convenient in-line use.
+ const char* EncodeRational(const Rational&, char* str_buf, ui32_t buf_len, char delimiter = ' ');
+
+ // Decodes a rational number havng a single non-digit delimiter character between
+ // the numerator and denominator. Returns false if the string does not contain
+ // the expected syntax.
+ bool DecodeRational(const char* str_rat, Rational&);
+
+
// common edit rates, use these instead of hard coded constants
const Rational EditRate_24 = Rational(24,1);
const Rational EditRate_23_98 = Rational(24000,1001); // Not a DCI-compliant value!
const Rational EditRate_96 = Rational(96,1);
const Rational EditRate_100 = Rational(100,1);
const Rational EditRate_120 = Rational(120,1);
+ const Rational EditRate_192 = Rational(192,1);
+ const Rational EditRate_200 = Rational(200,1);
+ const Rational EditRate_240 = Rational(240,1);
+
+ // Archival frame rates, see ST 428-21
+ // These rates are new and not supported by all systems. Do not assume that
+ // a package made using one of these rates will work just anywhere!
+ const Rational EditRate_16 = Rational(16,1);
+ const Rational EditRate_18 = Rational(200,11); // 18.182
+ const Rational EditRate_20 = Rational(20,1);
+ const Rational EditRate_22 = Rational(240,11); // 21.818
+
// Non-reference counting container for internal member objects.
// Please do not use this class for any other purpose.
{
LS_MXF_UNKNOWN,
LS_MXF_INTEROP,
- LS_MXF_SMPTE
+ LS_MXF_SMPTE,
+ LS_MAX
};
//
static byte_t default_ProductUUID_Data[UUIDlen] = {
0x43, 0x05, 0x9a, 0x1d, 0x04, 0x32, 0x41, 0x01,
0xb8, 0x3f, 0x73, 0x68, 0x15, 0xac, 0xf3, 0x1d };
-
+
memcpy(ProductUUID, default_ProductUUID_Data, UUIDlen);
memset(AssetUUID, 0, UUIDlen);
memset(ContextID, 0, UUIDlen);
// Initializes Rijndael CBC encryption context.
// Returns error if the key argument is NULL.
Result_t InitKey(const byte_t* key);
-
+
// Initializes 16 byte CBC Initialization Vector. This operation may be performed
// any number of times for a given key.
// Returns error if the i_vec argument is NULL.
namespace MXF {
// #include<Metadata.h> to use these
- class OPAtomHeader;
+ class OP1aHeader;
class OPAtomIndexFooter;
+ class RIP;
};
//---------------------------------------------------------------------------------
// MPEG2VideoDescriptor object.
struct VideoDescriptor
{
- Rational EditRate; //
- ui32_t FrameRate; //
- Rational SampleRate; //
- ui8_t FrameLayout; //
- ui32_t StoredWidth; //
- ui32_t StoredHeight; //
- Rational AspectRatio; //
- ui32_t ComponentDepth; //
- ui32_t HorizontalSubsampling; //
- ui32_t VerticalSubsampling; //
- ui8_t ColorSiting; //
- ui8_t CodedContentType; //
- bool LowDelay; //
- ui32_t BitRate; //
- ui8_t ProfileAndLevel; //
- ui32_t ContainerDuration; //
+ Rational EditRate; //
+ ui32_t FrameRate; //
+ Rational SampleRate; //
+ ui8_t FrameLayout; //
+ ui32_t StoredWidth; //
+ ui32_t StoredHeight; //
+ Rational AspectRatio; //
+ ui32_t ComponentDepth; //
+ ui32_t HorizontalSubsampling; //
+ ui32_t VerticalSubsampling; //
+ ui8_t ColorSiting; //
+ ui8_t CodedContentType; //
+ bool LowDelay; //
+ ui32_t BitRate; //
+ ui8_t ProfileAndLevel; //
+ ui32_t ContainerDuration; //
};
// Print VideoDescriptor to std::ostream
{
Capacity(size);
}
-
+
virtual ~FrameBuffer() {}
// Sets the MPEG frame type of the picture data in the frame buffer.
// Opens the stream for reading, parses enough data to provide a complete
// set of stream metadata for the MXFWriter below.
- Result_t OpenRead(const char* filename) const;
+ Result_t OpenRead(const std::string& filename) const;
// Fill a VideoDescriptor struct with the values from the file's header.
// Returns RESULT_INIT if the file is not open.
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
- virtual MXF::OPAtomHeader& OPAtomHeader();
+ virtual MXF::OP1aHeader& OP1aHeader();
virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+ virtual MXF::RIP& RIP();
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed or if nonsensical data is discovered
// in the essence descriptor.
- Result_t OpenWrite(const char* filename, const WriterInfo&,
+ Result_t OpenWrite(const std::string& filename, const WriterInfo&,
const VideoDescriptor&, ui32_t HeaderSize = 16384);
// Writes a frame of essence to the MXF file. If the optional AESEncContext
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
- virtual MXF::OPAtomHeader& OPAtomHeader();
+ virtual MXF::OP1aHeader& OP1aHeader();
virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+ virtual MXF::RIP& RIP();
// Open the file for reading. The file must exist. Returns error if the
// operation cannot be completed.
- Result_t OpenRead(const char* filename) const;
+ Result_t OpenRead(const std::string& filename) const;
// Returns RESULT_INIT if the file is not open.
Result_t Close() const;
// out of range, or if optional decrypt or HAMC operations fail.
Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
+ // Using the index table read from the footer partition, lookup the frame number
+ // and return the offset into the file at which to read that frame of essence.
+ // Returns RESULT_INIT if the file is not open, and RESULT_RANGE if the frame number is
+ // out of range.
+ Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
+
// Calculates the first frame in transport order of the GOP in which the requested
// frame is located. Calls ReadFrame() to fetch the frame at the calculated position.
// Returns RESULT_INIT if the file is not open.
CF_CFG_3, // 7.1 (SDDS) with optional HI/VI
CF_CFG_4, // Wild Track Format
CF_CFG_5, // 7.1 DS with optional HI/VI
+ CF_CFG_6, // ST 377-4 (MCA) labels (see also ASDCP::MXF::decode_mca_string)
+ CF_MAXIMUM
};
struct AudioDescriptor
{
Rational EditRate; // rate of frame wrapping
Rational AudioSamplingRate; // rate of audio sample
- ui32_t Locked; //
+ ui32_t Locked; //
ui32_t ChannelCount; // number of channels
ui32_t QuantizationBits; // number of bits per single-channel sample
ui32_t BlockAlign; // number of bytes ber sample, all channels
- ui32_t AvgBps; //
- ui32_t LinkedTrackID; //
+ ui32_t AvgBps; //
+ ui32_t LinkedTrackID; //
ui32_t ContainerDuration; // number of frames
ChannelFormat_t ChannelFormat; // audio channel arrangement
};
FrameBuffer() {}
FrameBuffer(ui32_t size) { Capacity(size); }
virtual ~FrameBuffer() {}
-
+
// Print debugging information to stream (stderr default)
void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
};
// Opens the stream for reading, parses enough data to provide a complete
// set of stream metadata for the MXFWriter below. PictureRate controls
// ther frame rate for the MXF frame wrapping option.
- Result_t OpenRead(const char* filename, const Rational& PictureRate) const;
+ Result_t OpenRead(const std::string& filename, const Rational& PictureRate) const;
// Fill an AudioDescriptor struct with the values from the file's header.
// Returns RESULT_INIT if the file is not open.
// Reads the next sequential frame in the input file and places it in the
// frame buffer. Fails if the buffer is too small or the stream is empty.
Result_t ReadFrame(FrameBuffer&) const;
+
+ Result_t Seek(ui32_t frame_number) const;
};
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
- virtual MXF::OPAtomHeader& OPAtomHeader();
+ virtual MXF::OP1aHeader& OP1aHeader();
virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+ virtual MXF::RIP& RIP();
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed or if nonsensical data is discovered
// in the essence descriptor.
- Result_t OpenWrite(const char* filename, const WriterInfo&,
+ Result_t OpenWrite(const std::string& filename, const WriterInfo&,
const AudioDescriptor&, ui32_t HeaderSize = 16384);
// Writes a frame of essence to the MXF file. If the optional AESEncContext
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
- virtual MXF::OPAtomHeader& OPAtomHeader();
+ virtual MXF::OP1aHeader& OP1aHeader();
virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+ virtual MXF::RIP& RIP();
// Open the file for reading. The file must exist. Returns error if the
// operation cannot be completed.
- Result_t OpenRead(const char* filename) const;
+ Result_t OpenRead(const std::string& filename) const;
// Returns RESULT_INIT if the file is not open.
Result_t Close() const;
// out of range, or if optional decrypt or HAMC operations fail.
Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
+ // Using the index table read from the footer partition, lookup the frame number
+ // and return the offset into the file at which to read that frame of essence.
+ // Returns RESULT_INIT if the file is not open, and RESULT_RANGE if the frame number is
+ // out of range.
+ Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
+
// Print debugging information to stream
void DumpHeaderMetadata(FILE* = 0) const;
void DumpIndex(FILE* = 0) const;
ui8_t NumberOfLayers[sizeof(ui16_t)];
ui8_t MultiCompTransform;
} SGcod;
-
+
struct
{
ui8_t DecompositionLevels;
FrameBuffer() {}
FrameBuffer(ui32_t size) { Capacity(size); }
virtual ~FrameBuffer() {}
-
+
// Print debugging information to stream (stderr default)
void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
};
// The frame buffer's PlaintextOffset parameter will be set to the first
// byte of the data segment. Set this value to zero if you want
// encrypted headers.
- Result_t OpenReadFrame(const char* filename, FrameBuffer&) const;
+ Result_t OpenReadFrame(const std::string& filename, FrameBuffer&) const;
// Fill a PictureDescriptor struct with the values from the file's codestream.
// Returns RESULT_INIT if the file is not open.
// alphabetically by filename. The parser will automatically parse enough data
// from the first file to provide a complete set of stream metadata for the
// MXFWriter below. If the "pedantic" parameter is given and is true, the
- // parser will check the metadata for each codestream and fail if a
+ // parser will check the metadata for each codestream and fail if a
// mismatch is detected.
- Result_t OpenRead(const char* filename, bool pedantic = false) const;
+ Result_t OpenRead(const std::string& filename, bool pedantic = false) const;
// Opens a file sequence for reading. The sequence is expected to contain one or
// more filenames, each naming a file containing the codestream for exactly one
// picture. The parser will automatically parse enough data
// from the first file to provide a complete set of stream metadata for the
// MXFWriter below. If the "pedantic" parameter is given and is true, the
- // parser will check the metadata for each codestream and fail if a
+ // parser will check the metadata for each codestream and fail if a
// mismatch is detected.
Result_t OpenRead(const std::list<std::string>& file_list, bool pedantic = false) const;
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
- virtual MXF::OPAtomHeader& OPAtomHeader();
+ virtual MXF::OP1aHeader& OP1aHeader();
virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+ virtual MXF::RIP& RIP();
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed or if nonsensical data is discovered
// in the essence descriptor.
- Result_t OpenWrite(const char* filename, const WriterInfo&,
+ Result_t OpenWrite(const std::string& filename, const WriterInfo&,
const PictureDescriptor&, ui32_t HeaderSize = 16384);
// Writes a frame of essence to the MXF file. If the optional AESEncContext
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
- virtual MXF::OPAtomHeader& OPAtomHeader();
+ virtual MXF::OP1aHeader& OP1aHeader();
virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+ virtual MXF::RIP& RIP();
// Open the file for reading. The file must exist. Returns error if the
// operation cannot be completed.
- Result_t OpenRead(const char* filename) const;
+ Result_t OpenRead(const std::string& filename) const;
// Returns RESULT_INIT if the file is not open.
Result_t Close() const;
// out of range, or if optional decrypt or HAMC operations fail.
Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
+ // Using the index table read from the footer partition, lookup the frame number
+ // and return the offset into the file at which to read that frame of essence.
+ // Returns RESULT_INIT if the file is not open, and RESULT_FRAME if the frame number is
+ // out of range.
+ Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
+
// Print debugging information to stream
void DumpHeaderMetadata(FILE* = 0) const;
void DumpIndex(FILE* = 0) const;
SP_LEFT,
SP_RIGHT
};
-
+
struct SFrameBuffer
{
JP2K::FrameBuffer Left;
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
- virtual MXF::OPAtomHeader& OPAtomHeader();
+ virtual MXF::OP1aHeader& OP1aHeader();
virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+ virtual MXF::RIP& RIP();
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed or if nonsensical data is discovered
// in the essence descriptor.
- Result_t OpenWrite(const char* filename, const WriterInfo&,
+ Result_t OpenWrite(const std::string& filename, const WriterInfo&,
const PictureDescriptor&, ui32_t HeaderSize = 16384);
// Writes a pair of frames of essence to the MXF file. If the optional AESEncContext
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
- virtual MXF::OPAtomHeader& OPAtomHeader();
+ virtual MXF::OP1aHeader& OP1aHeader();
virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+ virtual MXF::RIP& RIP();
// Open the file for reading. The file must exist. Returns error if the
// operation cannot be completed.
- Result_t OpenRead(const char* filename) const;
+ Result_t OpenRead(const std::string& filename) const;
// Returns RESULT_INIT if the file is not open.
Result_t Close() const;
Result_t ReadFrame(ui32_t frame_number, StereoscopicPhase_t phase,
FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
+ // Using the index table read from the footer partition, lookup the frame number
+ // and return the offset into the file at which to read that frame of essence.
+ // Returns RESULT_INIT if the file is not open, and RESULT_FRAME if the frame number is
+ // out of range.
+ Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
+
// Print debugging information to stream
void DumpHeaderMetadata(FILE* = 0) const;
void DumpIndex(FILE* = 0) const;
struct TimedTextResourceDescriptor
{
byte_t ResourceID[UUIDlen];
- MIMEType_t Type;
+ MIMEType_t Type;
TimedTextResourceDescriptor() : Type(MT_BIN) {}
};
struct TimedTextDescriptor
{
- Rational EditRate; //
+ Rational EditRate; //
ui32_t ContainerDuration;
byte_t AssetID[UUIDlen];
std::string NamespaceName;
FrameBuffer() { memset(m_AssetID, 0, UUIDlen); }
FrameBuffer(ui32_t size) { Capacity(size); memset(m_AssetID, 0, UUIDlen); }
virtual ~FrameBuffer() {}
-
+
inline const byte_t* AssetID() const { return m_AssetID; }
inline void AssetID(const byte_t* buf) { memcpy(m_AssetID, buf, UUIDlen); }
inline const char* MIMEType() const { return m_MIMEType.c_str(); }
void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
};
+ // An abstract base for a lookup service that returns the resource data
+ // identified by the given ancillary resource id.
//
class IResourceResolver
{
virtual Result_t ResolveRID(const byte_t* uuid, FrameBuffer&) const = 0; // return data for RID
};
+ // Resolves resource references by testing the named directory for file names containing
+ // the respective UUID.
+ //
+ class LocalFilenameResolver : public ASDCP::TimedText::IResourceResolver
+ {
+ std::string m_Dirname;
+ ASDCP_NO_COPY_CONSTRUCT(LocalFilenameResolver);
+
+ public:
+ LocalFilenameResolver();
+ virtual ~LocalFilenameResolver();
+ Result_t OpenRead(const std::string& dirname);
+ Result_t ResolveRID(const byte_t* uuid, FrameBuffer& FrameBuf) const;
+ };
+
//
class DCSubtitleParser
{
// Opens an XML file for reading, parses data to provide a complete
// set of stream metadata for the MXFWriter below.
- Result_t OpenRead(const char* filename) const;
+ Result_t OpenRead(const std::string& filename) const;
// Parses an XML document to provide a complete set of stream metadata
// for the MXFWriter below. The optional filename argument is used to
// initialize the default resource resolver (see ReadAncillaryResource).
- Result_t OpenRead(const std::string& xml_doc, const char* filename = 0) const;
+ Result_t OpenRead(const std::string& xml_doc, const std::string& filename) const;
// Fill a TimedTextDescriptor struct with the values from the file's contents.
// Returns RESULT_INIT if the file is not open.
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
- virtual MXF::OPAtomHeader& OPAtomHeader();
+ virtual MXF::OP1aHeader& OP1aHeader();
virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+ virtual MXF::RIP& RIP();
// Open the file for writing. The file must not exist. Returns error if
// the operation cannot be completed or if nonsensical data is discovered
// in the essence descriptor.
- Result_t OpenWrite(const char* filename, const WriterInfo&,
+ Result_t OpenWrite(const std::string& filename, const WriterInfo&,
const TimedTextDescriptor&, ui32_t HeaderSize = 16384);
// Writes the Timed-Text Resource to the MXF file. The file must be UTF-8
// Warning: direct manipulation of MXF structures can interfere
// with the normal operation of the wrapper. Caveat emptor!
- virtual MXF::OPAtomHeader& OPAtomHeader();
+ virtual MXF::OP1aHeader& OP1aHeader();
virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+ virtual MXF::RIP& RIP();
// Open the file for reading. The file must exist. Returns error if the
// operation cannot be completed.
- Result_t OpenRead(const char* filename) const;
+ Result_t OpenRead(const std::string& filename) const;
// Returns RESULT_INIT if the file is not open.
Result_t Close() const;
};
} // namespace TimedText
+ //---------------------------------------------------------------------------------
+ //
+ namespace DCData
+ {
+ struct DCDataDescriptor
+ {
+ Rational EditRate; // Sample rate
+ ui32_t ContainerDuration; // number of frames
+ byte_t AssetID[UUIDlen]; // The UUID for the DCData track
+ byte_t DataEssenceCoding[UUIDlen]; // The coding for the data carried
+ };
+
+ // Print DCDataDescriptor to std::ostream
+ std::ostream& operator << (std::ostream& strm, const DCDataDescriptor& ddesc);
+ // Print debugging information to stream (stderr default)
+ void DCDataDescriptorDump(const DCDataDescriptor&, FILE* = 0);
+
+ //
+ class FrameBuffer : public ASDCP::FrameBuffer
+ {
+ public:
+ FrameBuffer() {}
+ FrameBuffer(ui32_t size) { Capacity(size); }
+ virtual ~FrameBuffer() {}
+
+ // Print debugging information to stream (stderr default)
+ void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
+ };
+
+ // An object which opens and reads a DC Data file. The file is expected
+ // to contain exactly one complete frame of DC data essence as an unwrapped (raw)
+ // byte stream.
+ class BytestreamParser
+ {
+ class h__BytestreamParser;
+ mem_ptr<h__BytestreamParser> m_Parser;
+ ASDCP_NO_COPY_CONSTRUCT(BytestreamParser);
+
+ public:
+ BytestreamParser();
+ virtual ~BytestreamParser();
+
+ // Opens a file for reading, parses enough data to provide a complete
+ // set of stream metadata for the MXFWriter below.
+ // The frame buffer's PlaintextOffset parameter will be set to the first
+ // byte of the data segment. Set this value to zero if you want
+ // encrypted headers.
+ Result_t OpenReadFrame(const std::string& filename, FrameBuffer&) const;
+
+ // Fill a DCDataDescriptor struct with the values from the file's bytestream.
+ // Returns RESULT_INIT if the file is not open.
+ Result_t FillDCDataDescriptor(DCDataDescriptor&) const;
+ };
+
+ // An object which reads a sequence of files containing DC Data.
+ class SequenceParser
+ {
+ class h__SequenceParser;
+ mem_ptr<h__SequenceParser> m_Parser;
+ ASDCP_NO_COPY_CONSTRUCT(SequenceParser);
+
+ public:
+ SequenceParser();
+ virtual ~SequenceParser();
+
+ // Opens a directory for reading. The directory is expected to contain one or
+ // more files, each containing the bytestream for exactly one frame. The files
+ // must be named such that the frames are in temporal order when sorted
+ // alphabetically by filename.
+ Result_t OpenRead(const std::string& filename) const;
+
+ // Opens a file sequence for reading. The sequence is expected to contain one or
+ // more filenames, each naming a file containing the bytestream for exactly one
+ // frame.
+ Result_t OpenRead(const std::list<std::string>& file_list) const;
+
+ // Fill a DCDataDescriptor struct with default values.
+ // Returns RESULT_INIT if the directory is not open.
+ Result_t FillDCDataDescriptor(DCDataDescriptor&) const;
+
+ // Rewind the directory to the beginning.
+ Result_t Reset() const;
+
+ // Reads the next sequential frame in the directory and places it in the
+ // frame buffer. Fails if the buffer is too small or the direcdtory
+ // contains no more files.
+ // The frame buffer's PlaintextOffset parameter will be set to the first
+ // byte of the data segment. Set this value to zero if you want
+ // encrypted headers.
+ Result_t ReadFrame(FrameBuffer&) const;
+ };
+
+ //
+ class MXFWriter
+ {
+ class h__Writer;
+ mem_ptr<h__Writer> m_Writer;
+ ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
+
+ public:
+ MXFWriter();
+ virtual ~MXFWriter();
+
+ // Warning: direct manipulation of MXF structures can interfere
+ // with the normal operation of the wrapper. Caveat emptor!
+ virtual MXF::OP1aHeader& OP1aHeader();
+ virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+ virtual MXF::RIP& RIP();
+
+ // Open the file for writing. The file must not exist. Returns error if
+ // the operation cannot be completed or if nonsensical data is discovered
+ // in the essence descriptor.
+ Result_t OpenWrite(const std::string& filename, const WriterInfo&,
+ const DCDataDescriptor&, ui32_t HeaderSize = 16384);
+
+ // Writes a frame of essence to the MXF file. If the optional AESEncContext
+ // argument is present, the essence is encrypted prior to writing.
+ // Fails if the file is not open, is finalized, or an operating system
+ // error occurs.
+ Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
+
+ // Closes the MXF file, writing the index and revised header.
+ Result_t Finalize();
+ };
+
+ //
+ class MXFReader
+ {
+ class h__Reader;
+ mem_ptr<h__Reader> m_Reader;
+ ASDCP_NO_COPY_CONSTRUCT(MXFReader);
+
+ public:
+ MXFReader();
+ virtual ~MXFReader();
+
+ // Warning: direct manipulation of MXF structures can interfere
+ // with the normal operation of the wrapper. Caveat emptor!
+ virtual MXF::OP1aHeader& OP1aHeader();
+ virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+ virtual MXF::RIP& RIP();
+
+ // Open the file for reading. The file must exist. Returns error if the
+ // operation cannot be completed.
+ Result_t OpenRead(const std::string& filename) const;
+
+ // Returns RESULT_INIT if the file is not open.
+ Result_t Close() const;
+
+ // Fill a DCDataDescriptor struct with the values from the file's header.
+ // Returns RESULT_INIT if the file is not open.
+ Result_t FillDCDataDescriptor(DCDataDescriptor&) const;
+
+ // Fill a WriterInfo struct with the values from the file's header.
+ // Returns RESULT_INIT if the file is not open.
+ Result_t FillWriterInfo(WriterInfo&) const;
+
+ // Reads a frame of essence from the MXF file. If the optional AESEncContext
+ // argument is present, the essence is decrypted after reading. If the MXF
+ // file is encrypted and the AESDecContext argument is NULL, the frame buffer
+ // will contain the ciphertext frame data. If the HMACContext argument is
+ // not NULL, the HMAC will be calculated (if the file supports it).
+ // Returns RESULT_INIT if the file is not open, failure if the frame number is
+ // out of range, or if optional decrypt or HAMC operations fail.
+ Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
+
+ // Using the index table read from the footer partition, lookup the frame number
+ // and return the offset into the file at which to read that frame of essence.
+ // Returns RESULT_INIT if the file is not open, and RESULT_RANGE if the frame number is
+ // out of range.
+ Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
+
+ // Print debugging information to stream
+ void DumpHeaderMetadata(FILE* = 0) const;
+ void DumpIndex(FILE* = 0) const;
+ };
+
+ } // namespace DCData
+
+ //---------------------------------------------------------------------------------
+ //
+ namespace ATMOS
+ {
+ struct AtmosDescriptor : public DCData::DCDataDescriptor
+ {
+ ui32_t FirstFrame; // Frame number of the frame to align with the FFOA of the picture track
+ ui16_t MaxChannelCount; // Max number of channels in bitstream
+ ui16_t MaxObjectCount; // Max number of objects in bitstream
+ byte_t AtmosID[UUIDlen]; // UUID of Atmos Project
+ ui8_t AtmosVersion; // ATMOS Coder Version used to create bitstream
+ };
+
+ // Print AtmosDescriptor to std::ostream
+ std::ostream& operator << (std::ostream& strm, const AtmosDescriptor& adesc);
+ // Print debugging information to stream (stderr default)
+ void AtmosDescriptorDump(const AtmosDescriptor&, FILE* = 0);
+ // Determine if a file is a raw atmos file
+ bool IsDolbyAtmos(const std::string& filename);
+
+ //
+ class MXFWriter
+ {
+
+ class h__Writer;
+ mem_ptr<h__Writer> m_Writer;
+ ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
+
+ public:
+ MXFWriter();
+ virtual ~MXFWriter();
+
+ // Warning: direct manipulation of MXF structures can interfere
+ // with the normal operation of the wrapper. Caveat emptor!
+ virtual MXF::OP1aHeader& OP1aHeader();
+ virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+ virtual MXF::RIP& RIP();
+
+ // Open the file for writing. The file must not exist. Returns error if
+ // the operation cannot be completed or if nonsensical data is discovered
+ // in the essence descriptor.
+ Result_t OpenWrite(const std::string& filename, const WriterInfo&,
+ const AtmosDescriptor&, ui32_t HeaderSize = 16384);
+
+ // Writes a frame of essence to the MXF file. If the optional AESEncContext
+ // argument is present, the essence is encrypted prior to writing.
+ // Fails if the file is not open, is finalized, or an operating system
+ // error occurs.
+ Result_t WriteFrame(const DCData::FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
+
+ // Closes the MXF file, writing the index and revised header.
+ Result_t Finalize();
+ };
+
+ //
+ class MXFReader
+ {
+ class h__Reader;
+ mem_ptr<h__Reader> m_Reader;
+ ASDCP_NO_COPY_CONSTRUCT(MXFReader);
+
+ public:
+ MXFReader();
+ virtual ~MXFReader();
+
+ // Warning: direct manipulation of MXF structures can interfere
+ // with the normal operation of the wrapper. Caveat emptor!
+ virtual MXF::OP1aHeader& OP1aHeader();
+ virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+ virtual MXF::RIP& RIP();
+
+ // Open the file for reading. The file must exist. Returns error if the
+ // operation cannot be completed.
+ Result_t OpenRead(const std::string& filename) const;
+
+ // Returns RESULT_INIT if the file is not open.
+ Result_t Close() const;
+
+ // Fill an AtmosDescriptor struct with the values from the file's header.
+ // Returns RESULT_INIT if the file is not open.
+ Result_t FillAtmosDescriptor(AtmosDescriptor&) const;
+
+ // Fill a WriterInfo struct with the values from the file's header.
+ // Returns RESULT_INIT if the file is not open.
+ Result_t FillWriterInfo(WriterInfo&) const;
+
+ // Reads a frame of essence from the MXF file. If the optional AESEncContext
+ // argument is present, the essence is decrypted after reading. If the MXF
+ // file is encrypted and the AESDecContext argument is NULL, the frame buffer
+ // will contain the ciphertext frame data. If the HMACContext argument is
+ // not NULL, the HMAC will be calculated (if the file supports it).
+ // Returns RESULT_INIT if the file is not open, failure if the frame number is
+ // out of range, or if optional decrypt or HAMC operations fail.
+ Result_t ReadFrame(ui32_t frame_number, DCData::FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
+
+ // Using the index table read from the footer partition, lookup the frame number
+ // and return the offset into the file at which to read that frame of essence.
+ // Returns RESULT_INIT if the file is not open, and RESULT_RANGE if the frame number is
+ // out of range.
+ Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
+
+ // Print debugging information to stream
+ void DumpHeaderMetadata(FILE* = 0) const;
+ void DumpIndex(FILE* = 0) const;
+ };
+
+ } // namespace ATMOS
+
+
} // namespace ASDCP