Added support for CAP, PRF and CPF markers
[asdcplib.git] / src / AS_DCP.h
index 6f9969805b37d017241aa33873931af49ec41b03..b28f1143f7588567025e3fb1b4c1004d7177d110 100755 (executable)
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2003-2013, John Hurst
+Copyright (c) 2003-2018, John Hurst
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 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
@@ -40,8 +40,10 @@ be be limited to:
  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
@@ -61,21 +63,13 @@ be be limited to:
 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
-     Proposed SMPTE Aux Data track file
-     Proposed Dolby (TM) Atmos track file
-
  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
-     Proposed SMPTE Aux Data track file
+     Aux Data (frame-wrapped synchronous blob)
      Proposed Dolby (TM) Atmos track file
 
  o Read header metadata from an AS-DCP file
@@ -208,8 +202,12 @@ namespace ASDCP {
   // 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_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
@@ -217,18 +215,26 @@ namespace ASDCP {
     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);
 
 
   //---------------------------------------------------------------------------------
@@ -269,6 +275,16 @@ namespace ASDCP {
     }
   };
 
+  // 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!
@@ -286,6 +302,9 @@ namespace ASDCP {
   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
@@ -707,7 +726,7 @@ namespace ASDCP {
 
          // 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.
@@ -745,7 +764,7 @@ namespace ASDCP {
          // 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
@@ -777,7 +796,7 @@ namespace ASDCP {
 
          // 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;
@@ -848,6 +867,7 @@ namespace ASDCP {
        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
       };
 
@@ -918,7 +938,7 @@ namespace ASDCP {
          // 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.
@@ -930,6 +950,8 @@ namespace ASDCP {
          // 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;
        };
 
 
@@ -953,7 +975,7 @@ namespace ASDCP {
          // 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
@@ -985,7 +1007,7 @@ namespace ASDCP {
 
          // 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;
@@ -1026,6 +1048,9 @@ namespace ASDCP {
       const ui32_t MaxComponents = 3;
       const ui32_t MaxPrecincts = 32; // ISO 15444-1 Annex A.6.1
       const ui32_t MaxDefaults = 256; // made up
+      const ui8_t  MaxCapabilities = 32;
+                       const ui16_t MaxPRFN = 4;
+                       const ui16_t MaxCPFN = 4;
 
 #pragma pack(1)
       struct ImageComponent_t  // ISO 15444-1 Annex A.5.1
@@ -1063,6 +1088,25 @@ namespace ASDCP {
        ui8_t  SPqcd[MaxDefaults];
        ui8_t  SPqcdLength;
       };
+
+      struct ExtendedCapabilities_t // ISO 15444-1 Annex A.5.2
+      {
+       ui32_t  Pcap; // Pcap = 0 means that no extended capabilities are required
+       ui16_t  Ccap[MaxCapabilities]; // Ccap^i in ISO/IEC 15444-1 corresponds to Ccap[i -1]
+      };
+
+                       struct Profile_t // ISO 15444-1
+      {
+       ui16_t  N; // N = 0 means that the profile is signaled through Rsiz exclusively
+       ui16_t  Pprf[MaxPRFN]; // Pprf^i in ISO/IEC 15444-1 corresponds to Pprf[i -1]
+      };
+
+                       struct CorrespondingProfile_t // ISO 15444-1
+      {
+       ui16_t  N; // N = 0 means that no corresponding profile is signaled
+       ui16_t  Pcpf[MaxCPFN]; // Pcpf^i in ISO/IEC 15444-1 corresponds to Pcpf[i -1]
+      };
+
 #pragma pack()
 
       struct PictureDescriptor
@@ -1086,6 +1130,9 @@ namespace ASDCP {
        ImageComponent_t      ImageComponents[MaxComponents];
        CodingStyleDefault_t  CodingStyleDefault;
        QuantizationDefault_t QuantizationDefault;
+  ExtendedCapabilities_t ExtendedCapabilities;
+  Profile_t   Profile;
+       CorrespondingProfile_t   CorrespondingProfile;    
       };
 
       // Print debugging information to std::ostream
@@ -1124,7 +1171,7 @@ namespace ASDCP {
          // 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.
@@ -1154,7 +1201,7 @@ namespace ASDCP {
          // MXFWriter below.  If the "pedantic" parameter is given and is true, the
          // 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
@@ -1202,7 +1249,7 @@ namespace ASDCP {
          // 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
@@ -1234,7 +1281,7 @@ namespace ASDCP {
 
          // 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;
@@ -1307,7 +1354,7 @@ namespace ASDCP {
          // 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
@@ -1349,7 +1396,7 @@ namespace ASDCP {
 
          // 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;
@@ -1469,6 +1516,7 @@ namespace ASDCP {
 
        public:
          LocalFilenameResolver();
+         virtual ~LocalFilenameResolver();
          Result_t OpenRead(const std::string& dirname);
          Result_t ResolveRID(const byte_t* uuid, FrameBuffer& FrameBuf) const;
        };
@@ -1486,12 +1534,12 @@ namespace ASDCP {
 
          // 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.
@@ -1531,7 +1579,7 @@ namespace ASDCP {
          // 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
@@ -1573,7 +1621,7 @@ namespace ASDCP {
 
          // 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;
@@ -1662,7 +1710,7 @@ namespace ASDCP {
          // 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 DCDataDescriptor struct with the values from the file's bytestream.
          // Returns RESULT_INIT if the file is not open.
@@ -1684,7 +1732,7 @@ namespace ASDCP {
          // 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 char* filename) const;
+         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
@@ -1727,7 +1775,7 @@ namespace ASDCP {
          // 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 DCDataDescriptor&, ui32_t HeaderSize = 16384);
 
          // Writes a frame of essence to the MXF file. If the optional AESEncContext
@@ -1759,7 +1807,7 @@ namespace ASDCP {
 
          // 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;
@@ -1812,7 +1860,7 @@ namespace ASDCP {
     // 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 char* filename);
+    bool IsDolbyAtmos(const std::string& filename);
 
     //
     class MXFWriter
@@ -1835,7 +1883,7 @@ namespace ASDCP {
          // 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 AtmosDescriptor&, ui32_t HeaderSize = 16384);
 
          // Writes a frame of essence to the MXF file. If the optional AESEncContext
@@ -1867,7 +1915,7 @@ namespace ASDCP {
 
          // 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;