b28f1143f7588567025e3fb1b4c1004d7177d110
[asdcplib.git] / src / AS_DCP.h
1 /*
2 Copyright (c) 2003-2018, John Hurst
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8 1. Redistributions of source code must retain the above copyright
9    notice, this list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright
11    notice, this list of conditions and the following disclaimer in the
12    documentation and/or other materials provided with the distribution.
13 3. The name of the author may not be used to endorse or promote products
14    derived from this software without specific prior written permission.
15
16 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 /*! \file    AS_DCP.h
28     \version $Id$
29     \brief   AS-DCP library, public interface
30
31 The asdcplib library is a set of file access objects that offer simplified
32 access to files conforming to the standards published by the SMPTE
33 D-Cinema Technology Committee 21DC. The file format, labeled AS-DCP,
34 is described in a series of documents which includes but may not
35 be be limited to:
36
37  o SMPTE ST 429-2:2011 DCP Operational Constraints
38  o SMPTE ST 429-3:2006 Sound and Picture Track File
39  o SMPTE ST 429-4:2006 MXF JPEG 2000 Application
40  o SMPTE ST 429-5:2009 Timed Text Track File
41  o SMPTE ST 429-6:2006 MXF Track File Essence Encryption
42  o SMPTE ST 429-10:2008 Stereoscopic Picture Track File
43  o SMPTE ST 429-14:2008 Aux Data Track File
44  o SMPTE ST 330:2004 - UMID
45  o SMPTE ST 336:2001 - KLV
46  o SMPTE ST 377:2004 - MXF (old version, required)
47  o SMPTE ST 377-1:2011 - MXF
48  o SMPTE ST 377-4:2012 - MXF Multichannel Audio Labeling Framework
49  o SMPTE ST 390:2011 - MXF OP-Atom
50  o SMPTE ST 379-1:2009 - MXF Generic Container (GC)
51  o SMPTE ST 381-1:2005 - MPEG2 picture in GC
52  o SMPTE ST 422:2006 - JPEG 2000 picture in GC
53  o SMPTE ST 382:2007 - WAV/PCM sound in GC
54  o IETF RFC 2104 - HMAC/SHA1
55  o NIST FIPS 197 - AES (Rijndael) (via OpenSSL)
56
57  o MXF Interop Track File Specification
58  o MXF Interop Track File Essence Encryption Specification
59  o MXF Interop Operational Constraints Specification
60  - Note: the MXF Interop documents are not formally published.
61    Contact the asdcplib support address to get copies.
62
63 The following use cases are supported by the library:
64
65  o Write essence to a plaintext or ciphertext AS-DCP file:
66  o Read essence from a plaintext or ciphertext AS-DCP file:
67      MPEG2 Video Elementary Stream
68      JPEG 2000 codestreams
69      JPEG 2000 stereoscopic codestream pairs
70      PCM audio streams
71      SMPTE 429-7 Timed Text XML with font and image resources
72      Aux Data (frame-wrapped synchronous blob)
73      Proposed Dolby (TM) Atmos track file
74
75  o Read header metadata from an AS-DCP file
76
77 This project depends upon the following libraries:
78  - OpenSSL http://www.openssl.org/
79  - Expat http://expat.sourceforge.net/  or
80      Xerces-C http://xerces.apache.org/xerces-c/
81    An XML library is not needed if you don't need support for SMPTE ST 429-5:2009.
82 */
83
84 #ifndef _AS_DCP_H_
85 #define _AS_DCP_H_
86
87 #include <KM_error.h>
88 #include <KM_fileio.h>
89 #include <stdio.h>
90 #include <stdarg.h>
91 #include <math.h>
92 #include <iosfwd>
93 #include <string>
94 #include <cstring>
95 #include <list>
96
97 //--------------------------------------------------------------------------------
98 // common integer types
99 // supply your own by defining ASDCP_NO_BASE_TYPES
100
101 #ifndef ASDCP_NO_BASE_TYPES
102 typedef unsigned char  byte_t;
103 typedef char           i8_t;
104 typedef unsigned char  ui8_t;
105 typedef short          i16_t;
106 typedef unsigned short ui16_t;
107 typedef int            i32_t;
108 typedef unsigned int   ui32_t;
109 #endif
110
111
112 //--------------------------------------------------------------------------------
113 // convenience macros
114
115 // Convenience macros for managing return values in predicates
116 #define ASDCP_SUCCESS(v) (((v) < 0) ? 0 : 1)
117 #define ASDCP_FAILURE(v) (((v) < 0) ? 1 : 0)
118
119
120 // Returns RESULT_PTR if the given argument is NULL.
121 // See Result_t below for an explanation of RESULT_* symbols.
122 #define ASDCP_TEST_NULL(p) \
123   if ( (p) == 0  ) { \
124     return ASDCP::RESULT_PTR; \
125   }
126
127 // Returns RESULT_PTR if the given argument is NULL. See Result_t
128 // below for an explanation of RESULT_* symbols. It then assumes
129 // that the argument is a pointer to a string and returns
130 // RESULT_NULL_STR if the first character is '\0'.
131 //
132 #define ASDCP_TEST_NULL_STR(p) \
133   ASDCP_TEST_NULL(p); \
134   if ( (p)[0] == '\0' ) { \
135     return ASDCP::RESULT_NULL_STR; \
136   }
137
138 // Produces copy constructor boilerplate. Allows convenient private
139 // declatarion of copy constructors to prevent the compiler from
140 // silently manufacturing default methods.
141 #define ASDCP_NO_COPY_CONSTRUCT(T)   \
142           T(const T&); \
143           T& operator=(const T&)
144
145 //--------------------------------------------------------------------------------
146 // All library components are defined in the namespace ASDCP
147 //
148 namespace ASDCP {
149   //
150   // The version number declaration and explanation have moved to ../configure.ac
151   const char* Version();
152
153   // UUIDs are passed around as strings of UUIDlen bytes
154   const ui32_t UUIDlen = 16;
155
156   // Encryption keys are passed around as strings of KeyLen bytes
157   const ui32_t KeyLen = 16;
158
159   //---------------------------------------------------------------------------------
160   // return values
161
162   using Kumu::Result_t;
163
164   using Kumu::RESULT_FALSE;
165   using Kumu::RESULT_OK;
166   using Kumu::RESULT_FAIL;
167   using Kumu::RESULT_PTR;
168   using Kumu::RESULT_NULL_STR;
169   using Kumu::RESULT_ALLOC;
170   using Kumu::RESULT_PARAM;
171   using Kumu::RESULT_SMALLBUF;
172   using Kumu::RESULT_INIT;
173   using Kumu::RESULT_NOT_FOUND;
174   using Kumu::RESULT_NO_PERM;
175   using Kumu::RESULT_FILEOPEN;
176   using Kumu::RESULT_BADSEEK;
177   using Kumu::RESULT_READFAIL;
178   using Kumu::RESULT_WRITEFAIL;
179   using Kumu::RESULT_STATE;
180   using Kumu::RESULT_ENDOFFILE;
181   using Kumu::RESULT_CONFIG;
182
183   KM_DECLARE_RESULT(FORMAT,     -101, "The file format is not proper OP-Atom/AS-DCP.");
184   KM_DECLARE_RESULT(RAW_ESS,    -102, "Unknown raw essence file type.");
185   KM_DECLARE_RESULT(RAW_FORMAT, -103, "Raw essence format invalid.");
186   KM_DECLARE_RESULT(RANGE,      -104, "Frame number out of range.");
187   KM_DECLARE_RESULT(CRYPT_CTX,  -105, "AESEncContext required when writing to encrypted file.");
188   KM_DECLARE_RESULT(LARGE_PTO,  -106, "Plaintext offset exceeds frame buffer size.");
189   KM_DECLARE_RESULT(CAPEXTMEM,  -107, "Cannot resize externally allocated memory.");
190   KM_DECLARE_RESULT(CHECKFAIL,  -108, "The check value did not decrypt correctly.");
191   KM_DECLARE_RESULT(HMACFAIL,   -109, "HMAC authentication failure.");
192   KM_DECLARE_RESULT(HMAC_CTX,   -110, "HMAC context required.");
193   KM_DECLARE_RESULT(CRYPT_INIT, -111, "Error initializing block cipher context.");
194   KM_DECLARE_RESULT(EMPTY_FB,   -112, "Empty frame buffer.");
195   KM_DECLARE_RESULT(KLV_CODING, -113, "KLV coding error.");
196   KM_DECLARE_RESULT(SPHASE,     -114, "Stereoscopic phase mismatch.");
197   KM_DECLARE_RESULT(SFORMAT,    -115, "Rate mismatch, file may contain stereoscopic essence.");
198
199   //---------------------------------------------------------------------------------
200   // file identification
201
202   // The file accessors in this library implement a bounded set of essence types.
203   // This list will be expanded when support for new types is added to the library.
204   enum EssenceType_t {
205     ESS_UNKNOWN,              // the file is not a supported AS-DCP of AS-02 essence container
206
207     // 
208     ESS_MPEG2_VES,            // the file contains an MPEG-2 video elementary stream
209
210     // d-cinema essence types
211     ESS_JPEG_2000,            // the file contains one or more JPEG 2000 codestreams
212     ESS_PCM_24b_48k,          // the file contains one or more PCM audio pairs
213     ESS_PCM_24b_96k,          // the file contains one or more PCM audio pairs
214     ESS_TIMED_TEXT,           // the file contains an XML timed text document and one or more resources
215     ESS_JPEG_2000_S,          // the file contains one or more JPEG 2000 codestream pairs (stereoscopic)
216     ESS_DCDATA_UNKNOWN,       // the file contains one or more D-Cinema Data bytestreams
217     ESS_DCDATA_DOLBY_ATMOS,   // the file contains one or more DolbyATMOS bytestreams
218
219     // IMF essence types
220     ESS_AS02_JPEG_2000,       // the file contains one or more JPEG 2000 codestreams
221     ESS_AS02_PCM_24b_48k,     // the file contains one or more PCM audio pairs, clip wrapped
222     ESS_AS02_PCM_24b_96k,     // the file contains one or more PCM audio pairs, clip wrapped
223     ESS_AS02_TIMED_TEXT,      // the file contains a TTML document and zero or more resources
224     ESS_AS02_ISXD,            // the file contains an ISXD document stream (per SMPTE RDD 47)
225     ESS_AS02_ACES,            // the file contains two or more ACES codestreams (per SMPTE ST 2067-50)
226     ESS_MAX
227   };
228
229   // Determine the type of essence contained in the given MXF file. RESULT_OK
230   // is returned if the file is successfully opened and contains a valid MXF
231   // stream. If there is an error, the result code will indicate the reason.
232   Result_t EssenceType(const std::string& filename, EssenceType_t& type);
233
234   // Determine the type of essence contained in the given raw file. RESULT_OK
235   // is returned if the file is successfully opened and contains a known
236   // stream type. If there is an error, the result code will indicate the reason.
237   Result_t RawEssenceType(const std::string& filename, EssenceType_t& type);
238
239
240   //---------------------------------------------------------------------------------
241   // base types
242
243   // A simple container for rational numbers.
244   class Rational
245   {
246   public:
247     i32_t Numerator;
248     i32_t Denominator;
249
250     Rational() : Numerator(0), Denominator(0) {}
251     Rational(i32_t n, i32_t d) : Numerator(n), Denominator(d) {}
252
253     inline double Quotient() const {
254       return (double)Numerator / (double)Denominator;
255     }
256
257     inline bool operator==(const Rational& rhs) const {
258       return ( rhs.Numerator == Numerator && rhs.Denominator == Denominator );
259     }
260
261     inline bool operator!=(const Rational& rhs) const {
262       return ( rhs.Numerator != Numerator || rhs.Denominator != Denominator );
263     }
264
265     inline bool operator<(const Rational& rhs) {
266       if ( Numerator < rhs.Numerator )     return true;
267       if ( Numerator == rhs.Numerator && Denominator < rhs.Denominator )    return true;
268       return false;
269     }
270
271     inline bool operator>(const Rational& rhs) {
272       if ( Numerator > rhs.Numerator )     return true;
273       if ( Numerator == rhs.Numerator && Denominator > rhs.Denominator )     return true;
274       return false;
275     }
276   };
277
278   // Encodes a rational number as a string having a single delimiter character between
279   // numerator and denominator.  Retuns the buffer pointer to allow convenient in-line use.
280   const char* EncodeRational(const Rational&, char* str_buf, ui32_t buf_len, char delimiter = ' ');
281
282   // Decodes a rational number havng a single non-digit delimiter character between
283   // the numerator and denominator.  Returns false if the string does not contain
284   // the expected syntax.
285   bool DecodeRational(const char* str_rat, Rational&);
286
287
288   // common edit rates, use these instead of hard coded constants
289   const Rational EditRate_24 = Rational(24,1);
290   const Rational EditRate_23_98 = Rational(24000,1001); // Not a DCI-compliant value!
291   const Rational EditRate_48 = Rational(48,1);
292   const Rational SampleRate_48k = Rational(48000,1);
293   const Rational SampleRate_96k = Rational(96000,1);
294
295   // Additional frame rates, see ST 428-11, ST 429-13
296   // These rates are new and not supported by all systems. Do not assume that
297   // a package made using one of these rates will work just anywhere!
298   const Rational EditRate_25 = Rational(25,1);
299   const Rational EditRate_30 = Rational(30,1);
300   const Rational EditRate_50 = Rational(50,1);
301   const Rational EditRate_60 = Rational(60,1);
302   const Rational EditRate_96 = Rational(96,1);
303   const Rational EditRate_100 = Rational(100,1);
304   const Rational EditRate_120 = Rational(120,1);
305   const Rational EditRate_192 = Rational(192,1);
306   const Rational EditRate_200 = Rational(200,1);
307   const Rational EditRate_240 = Rational(240,1);
308
309   // Archival frame rates, see ST 428-21
310   // These rates are new and not supported by all systems. Do not assume that
311   // a package made using one of these rates will work just anywhere!
312   const Rational EditRate_16 = Rational(16,1);
313   const Rational EditRate_18 = Rational(200,11); // 18.182
314   const Rational EditRate_20 = Rational(20,1);
315   const Rational EditRate_22 = Rational(240,11); // 21.818
316
317
318   // Non-reference counting container for internal member objects.
319   // Please do not use this class for any other purpose.
320   template <class T>
321     class mem_ptr
322     {
323       T* m_p; // the thing we point to
324       mem_ptr(T&);
325
326     public:
327       mem_ptr() : m_p(0) {}
328       mem_ptr(T* p) : m_p(p) {}
329       ~mem_ptr() { delete m_p; }
330
331       inline T&   operator*()  const { return *m_p; }
332       inline T*   operator->() const { return m_p; }
333       inline      operator T*()const { return m_p; }
334       inline const mem_ptr<T>& operator=(T* p) { set(p); return *this; }
335       inline T*   set(T* p)          { delete m_p; m_p = p; return m_p; }
336       inline T*   get()        const { return m_p; }
337       inline void release()          { m_p = 0; }
338       inline bool empty()      const { return m_p == 0; }
339     };
340
341
342   //---------------------------------------------------------------------------------
343   // WriterInfo class - encapsulates writer identification details used for
344   // OpenWrite() calls.  Replace these values at runtime to identify your product.
345   //
346   // MXF files use SMPTE Universal Labels to identify data items. The set of Labels
347   // in a file is determined by the MXF Operational Pattern and any constraining
348   // documentation. There are currently two flavors of AS-DCP file in use: MXF Interop
349   // (AKA JPEG Interop) and SMPTE. The two differ in the values of three labels:
350   //
351   //   OPAtom
352   //      Interop : 06 0e 2b 34 04 01 01 01  0d 01 02 01 10 00 00 00
353   //      SMPTE   : 06 0e 2b 34 04 01 01 02  0d 01 02 01 10 00 00 00
354   //
355   //   EKLV Packet:
356   //      Interop : 06 0e 2b 34 02 04 01 07  0d 01 03 01 02 7e 01 00
357   //      SMPTE   : 06 0e 2b 34 02 04 01 01  0d 01 03 01 02 7e 01 00
358   //
359   //   GenericDescriptor/SubDescriptors:
360   //      Interop : 06 0e 2b 34 01 01 01 02  06 01 01 04 06 10 00 00
361   //      SMPTE   : 06 0e 2b 34 01 01 01 09  06 01 01 04 06 10 00 00
362   //
363   // asdcplib will read any (otherwise valid) file which has any combination of the
364   // above values. When writing files, MXF Interop labels are used by default. To
365   // write a file containing SMPTE labels, replace the default label set value in
366   // the WriterInfo before calling OpenWrite()
367   //
368   //
369   enum LabelSet_t
370   {
371     LS_MXF_UNKNOWN,
372     LS_MXF_INTEROP,
373     LS_MXF_SMPTE,
374     LS_MAX
375   };
376
377   //
378   struct WriterInfo
379   {
380     byte_t      ProductUUID[UUIDlen];
381     byte_t      AssetUUID[UUIDlen];
382     byte_t      ContextID[UUIDlen];
383     byte_t      CryptographicKeyID[UUIDlen];
384     bool        EncryptedEssence; // true if essence data is (or is going to be) encrypted
385     bool        UsesHMAC;         // true if HMAC exists or is to be calculated
386     std::string ProductVersion;
387     std::string CompanyName;
388     std::string ProductName;
389     LabelSet_t  LabelSetType;
390
391     WriterInfo() : EncryptedEssence(false), UsesHMAC(false), LabelSetType(LS_MXF_INTEROP)
392     {
393       static byte_t default_ProductUUID_Data[UUIDlen] = {
394         0x43, 0x05, 0x9a, 0x1d, 0x04, 0x32, 0x41, 0x01,
395         0xb8, 0x3f, 0x73, 0x68, 0x15, 0xac, 0xf3, 0x1d };
396
397       memcpy(ProductUUID, default_ProductUUID_Data, UUIDlen);
398       memset(AssetUUID, 0, UUIDlen);
399       memset(ContextID, 0, UUIDlen);
400       memset(CryptographicKeyID, 0, UUIDlen);
401
402       ProductVersion = "Unreleased ";
403       ProductVersion += Version();
404       CompanyName = "DCI";
405       ProductName = "asdcplib";
406     }
407   };
408
409   // Print WriterInfo to std::ostream
410   std::ostream& operator << (std::ostream& strm, const WriterInfo& winfo);
411   // Print WriterInfo to stream, stderr by default.
412   void WriterInfoDump(const WriterInfo&, FILE* = 0);
413
414   //---------------------------------------------------------------------------------
415   // cryptographic support
416
417   // The following classes define interfaces to Rijndael contexts having the following properties:
418   //  o 16 byte key
419   //  o CBC mode with 16 byte block size
420   const ui32_t CBC_KEY_SIZE = 16;
421   const ui32_t CBC_BLOCK_SIZE = 16;
422   const ui32_t HMAC_SIZE = 20;
423
424   //
425   class AESEncContext
426     {
427       class h__AESContext;
428       mem_ptr<h__AESContext> m_Context;
429       ASDCP_NO_COPY_CONSTRUCT(AESEncContext);
430
431     public:
432       AESEncContext();
433       ~AESEncContext();
434
435       // Initializes Rijndael CBC encryption context.
436       // Returns error if the key argument is NULL.
437       Result_t InitKey(const byte_t* key);
438
439       // Initializes 16 byte CBC Initialization Vector. This operation may be performed
440       // any number of times for a given key.
441       // Returns error if the i_vec argument is NULL.
442       Result_t SetIVec(const byte_t* i_vec);
443       Result_t GetIVec(byte_t* i_vec) const;
444
445       // Encrypt a block of data. The block size must be a multiple of CBC_BLOCK_SIZE.
446       // Returns error if either argument is NULL.
447       Result_t EncryptBlock(const byte_t* pt_buf, byte_t* ct_buf, ui32_t block_size);
448     };
449
450   //
451   class AESDecContext
452     {
453       class h__AESContext;
454       mem_ptr<h__AESContext> m_Context;
455       ASDCP_NO_COPY_CONSTRUCT(AESDecContext);
456
457     public:
458       AESDecContext();
459       ~AESDecContext();
460
461       // Initializes Rijndael CBC decryption context.
462       // Returns error if the key argument is NULL.
463       Result_t InitKey(const byte_t* key);
464
465       // Initializes 16 byte CBC Initialization Vector. This operation may be performed
466       // any number of times for a given key.
467       // Returns error if the i_vec argument is NULL.
468       Result_t SetIVec(const byte_t* i_vec);
469
470       // Decrypt a block of data. The block size must be a multiple of CBC_BLOCK_SIZE.
471       // Returns error if either argument is NULL.
472       Result_t DecryptBlock(const byte_t* ct_buf, byte_t* pt_buf, ui32_t block_size);
473     };
474
475   //
476   class HMACContext
477     {
478       class h__HMACContext;
479       mem_ptr<h__HMACContext> m_Context;
480       ASDCP_NO_COPY_CONSTRUCT(HMACContext);
481
482     public:
483       HMACContext();
484       ~HMACContext();
485
486       // Initializes HMAC context. The key argument must point to a binary
487       // key that is CBC_KEY_SIZE bytes in length. Returns error if the key
488       // argument is NULL.
489       Result_t InitKey(const byte_t* key, LabelSet_t);
490
491       // Reset internal state, allows repeated cycles of Update -> Finalize
492       void Reset();
493
494       // Add data to the digest. Returns error if the key argument is NULL or
495       // if the digest has been finalized.
496       Result_t Update(const byte_t* buf, ui32_t buf_len);
497
498       // Finalize digest.  Returns error if the digest has already been finalized.
499       Result_t Finalize();
500
501       // Writes HMAC value to given buffer. buf must point to a writable area of
502       // memory that is at least HMAC_SIZE bytes in length. Returns error if the
503       // buf argument is NULL or if the digest has not been finalized.
504       Result_t GetHMACValue(byte_t* buf) const;
505
506       // Tests the given value against the finalized value in the object. buf must
507       // point to a readable area of memory that is at least HMAC_SIZE bytes in length.
508       // Returns error if the buf argument is NULL or if the values do ot match.
509       Result_t TestHMACValue(const byte_t* buf) const;
510     };
511
512   //---------------------------------------------------------------------------------
513   // frame buffer base class
514   //
515   // The supported essence types are stored using per-frame KLV packetization. The
516   // following class implements essence-neutral functionality for managing a buffer
517   // containing a frame of essence.
518
519   class FrameBuffer
520     {
521       ASDCP_NO_COPY_CONSTRUCT(FrameBuffer);
522
523     protected:
524       byte_t* m_Data;          // pointer to memory area containing frame data
525       ui32_t  m_Capacity;      // size of memory area pointed to by m_Data
526       bool    m_OwnMem;        // if false, m_Data points to externally allocated memory
527       ui32_t  m_Size;          // size of frame data in memory area pointed to by m_Data
528       ui32_t  m_FrameNumber;   // delivery-order frame number
529
530       // It is possible to read raw ciphertext from an encrypted AS-DCP file.
531       // After reading an encrypted AS-DCP file in raw mode, the frame buffer will
532       // contain the encrypted source value portion of the Encrypted Triplet, followed
533       // by the integrity pack, if it exists.
534       // The buffer will begin with the IV and CheckValue, followed by encrypted essence
535       // and optional integrity pack
536       // The SourceLength and PlaintextOffset values from the packet will be held in the
537       // following variables:
538       ui32_t  m_SourceLength;       // plaintext length (delivered plaintext+decrypted ciphertext)
539       ui32_t  m_PlaintextOffset;    // offset to first byte of ciphertext
540
541      public:
542       FrameBuffer();
543       virtual ~FrameBuffer();
544
545       // Instructs the object to use an externally allocated buffer. The external
546       // buffer will not be cleaned up by the frame buffer when it exits.
547       // Call with (0,0) to revert to internally allocated buffer.
548       // Returns error if the buf_addr argument is NULL and buf_size is non-zero.
549       Result_t SetData(byte_t* buf_addr, ui32_t buf_size);
550
551       // Sets the size of the internally allocate buffer. Returns RESULT_CAPEXTMEM
552       // if the object is using an externally allocated buffer via SetData();
553       // Resets content size to zero.
554       Result_t Capacity(ui32_t cap);
555
556       // returns the size of the buffer
557       inline ui32_t  Capacity() const { return m_Capacity; }
558
559       // returns a const pointer to the essence data
560       inline const byte_t* RoData() const { return m_Data; }
561
562       // returns a non-const pointer to the essence data
563       inline byte_t* Data() { return m_Data; }
564
565       // set the size of the buffer's contents
566       inline ui32_t  Size(ui32_t size) { return m_Size = size; }
567
568       // returns the size of the buffer's contents
569       inline ui32_t  Size() const { return m_Size; }
570
571       // Sets the absolute frame number of this frame in the file in delivery order.
572       inline void    FrameNumber(ui32_t num) { m_FrameNumber = num; }
573
574       // Returns the absolute frame number of this frame in the file in delivery order.
575       inline ui32_t  FrameNumber() const { return m_FrameNumber; }
576
577       // Sets the length of the plaintext essence data
578       inline void    SourceLength(ui32_t len) { m_SourceLength = len; }
579
580       // When this value is 0 (zero), the buffer contains only plaintext. When it is
581       // non-zero, the buffer contains raw ciphertext and the return value is the length
582       // of the original plaintext.
583       inline ui32_t  SourceLength() const { return m_SourceLength; }
584
585       // Sets the offset into the buffer at which encrypted data begins
586       inline void    PlaintextOffset(ui32_t ofst) { m_PlaintextOffset = ofst; }
587
588       // Returns offset into buffer of first byte of ciphertext.
589       inline ui32_t  PlaintextOffset() const { return m_PlaintextOffset; }
590     };
591
592   //---------------------------------------------------------------------------------
593   // Accessors in the MXFReader and MXFWriter classes below return these types to
594   // provide direct access to MXF metadata structures declared in MXF.h and Metadata.h
595
596   namespace MXF {
597     // #include<Metadata.h> to use these
598     class OP1aHeader;
599     class OPAtomIndexFooter;
600     class RIP;
601   };
602
603   //---------------------------------------------------------------------------------
604   // MPEG2 video elementary stream support
605
606   //
607   namespace MPEG2
608     {
609       // MPEG picture coding type
610       enum FrameType_t {
611         FRAME_U = 0x00, // Unknown
612         FRAME_I = 0x01, // I-Frame
613         FRAME_P = 0x02, // P-Frame
614         FRAME_B = 0x03  // B-Frame
615       };
616
617       // convert FrameType_t to char
618       inline char FrameTypeChar(FrameType_t type)
619         {
620           switch ( type )
621             {
622             case FRAME_I: return 'I';
623             case FRAME_B: return 'B';
624             case FRAME_P: return 'P';
625             default: return 'U';
626             }
627         }
628
629       // Structure represents the metadata elements in the file header's
630       // MPEG2VideoDescriptor object.
631       struct VideoDescriptor
632         {
633           Rational EditRate;                //
634           ui32_t   FrameRate;               //
635           Rational SampleRate;              //
636           ui8_t    FrameLayout;             //
637           ui32_t   StoredWidth;             //
638           ui32_t   StoredHeight;            //
639           Rational AspectRatio;             //
640           ui32_t   ComponentDepth;          //
641           ui32_t   HorizontalSubsampling;   //
642           ui32_t   VerticalSubsampling;     //
643           ui8_t    ColorSiting;             //
644           ui8_t    CodedContentType;        //
645           bool     LowDelay;                //
646           ui32_t   BitRate;                 //
647           ui8_t    ProfileAndLevel;         //
648           ui32_t   ContainerDuration;       //
649       };
650
651       // Print VideoDescriptor to std::ostream
652       std::ostream& operator << (std::ostream& strm, const VideoDescriptor& vdesc);
653       // Print VideoDescriptor to stream, stderr by default.
654       void VideoDescriptorDump(const VideoDescriptor&, FILE* = 0);
655
656       // A container for MPEG frame data.
657       class FrameBuffer : public ASDCP::FrameBuffer
658         {
659           ASDCP_NO_COPY_CONSTRUCT(FrameBuffer); // TODO: should have copy construct
660
661         protected:
662           FrameType_t m_FrameType;
663           ui8_t       m_TemporalOffset;
664           bool        m_ClosedGOP;
665           bool        m_GOPStart;
666
667         public:
668           FrameBuffer() :
669             m_FrameType(FRAME_U), m_TemporalOffset(0),
670             m_ClosedGOP(false), m_GOPStart(false) {}
671
672           FrameBuffer(ui32_t size) :
673             m_FrameType(FRAME_U), m_TemporalOffset(0),
674             m_ClosedGOP(false), m_GOPStart(false)
675             {
676               Capacity(size);
677             }
678
679           virtual ~FrameBuffer() {}
680
681           // Sets the MPEG frame type of the picture data in the frame buffer.
682           inline void FrameType(FrameType_t type) { m_FrameType = type; }
683
684           // Returns the MPEG frame type of the picture data in the frame buffer.
685           inline FrameType_t FrameType() const { return m_FrameType; }
686
687           // Sets the MPEG temporal offset of the picture data in the frame buffer.
688           inline void TemporalOffset(ui8_t offset) { m_TemporalOffset = offset; }
689
690           // Returns the MPEG temporal offset of the picture data in the frame buffer.
691           inline ui8_t TemporalOffset() const { return m_TemporalOffset; }
692
693           // Sets the MPEG GOP 'start' attribute for the frame buffer.
694           inline void GOPStart(bool start) { m_GOPStart = start; }
695
696           // True if the frame in the buffer is the first in the GOP (in transport order)
697           inline bool GOPStart() const { return m_GOPStart; }
698
699           // Sets the MPEG GOP 'closed' attribute for the frame buffer.
700           inline void ClosedGOP(bool closed) { m_ClosedGOP = closed; }
701
702           // Returns true if the frame in the buffer is from a closed GOP, false if
703           // the frame is from an open GOP.  Always returns false unless GOPStart()
704           // returns true.
705           inline bool ClosedGOP() const { return m_ClosedGOP; }
706
707           // Print object state to stream, include n bytes of frame data if indicated.
708           // Default stream is stderr.
709           void    Dump(FILE* = 0, ui32_t dump_len = 0) const;
710         };
711
712
713       // An object which opens and reads an MPEG2 Video Elementary Stream file.  The call to
714       // OpenRead() reads metadata from the file and populates an internal VideoDescriptor object.
715       // Each subsequent call to ReadFrame() reads exactly one frame from the stream into the
716       // given FrameBuffer object.
717       class Parser
718         {
719           class h__Parser;
720           mem_ptr<h__Parser> m_Parser;
721           ASDCP_NO_COPY_CONSTRUCT(Parser);
722
723         public:
724           Parser();
725           virtual ~Parser();
726
727           // Opens the stream for reading, parses enough data to provide a complete
728           // set of stream metadata for the MXFWriter below.
729           Result_t OpenRead(const std::string& filename) const;
730
731           // Fill a VideoDescriptor struct with the values from the file's header.
732           // Returns RESULT_INIT if the file is not open.
733           Result_t FillVideoDescriptor(VideoDescriptor&) const;
734
735           // Rewind the stream to the beginning.
736           Result_t Reset() const;
737
738           // Reads the next sequential frame in the input file and places it in the
739           // frame buffer. Fails if the buffer is too small or the stream is empty.
740           // The frame buffer's PlaintextOffset parameter will be set to the first
741           // data byte of the first slice. Set this value to zero if you want
742           // encrypted headers.
743           Result_t ReadFrame(FrameBuffer&) const;
744         };
745
746       // A class which creates and writes MPEG frame data to an AS-DCP format MXF file.
747       // Not yet implemented
748       class MXFWriter
749         {
750           class h__Writer;
751           mem_ptr<h__Writer> m_Writer;
752           ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
753
754         public:
755           MXFWriter();
756           virtual ~MXFWriter();
757
758           // Warning: direct manipulation of MXF structures can interfere
759           // with the normal operation of the wrapper.  Caveat emptor!
760           virtual MXF::OP1aHeader& OP1aHeader();
761           virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
762           virtual MXF::RIP& RIP();
763
764           // Open the file for writing. The file must not exist. Returns error if
765           // the operation cannot be completed or if nonsensical data is discovered
766           // in the essence descriptor.
767           Result_t OpenWrite(const std::string& filename, const WriterInfo&,
768                              const VideoDescriptor&, ui32_t HeaderSize = 16384);
769
770           // Writes a frame of essence to the MXF file. If the optional AESEncContext
771           // argument is present, the essence is encrypted prior to writing.
772           // Fails if the file is not open, is finalized, or an operating system
773           // error occurs.
774           Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
775
776           // Closes the MXF file, writing the index and revised header.
777           Result_t Finalize();
778         };
779
780       // A class which reads MPEG frame data from an AS-DCP format MXF file.
781       class MXFReader
782         {
783           class h__Reader;
784           mem_ptr<h__Reader> m_Reader;
785           ASDCP_NO_COPY_CONSTRUCT(MXFReader);
786
787         public:
788           MXFReader();
789           virtual ~MXFReader();
790
791           // Warning: direct manipulation of MXF structures can interfere
792           // with the normal operation of the wrapper.  Caveat emptor!
793           virtual MXF::OP1aHeader& OP1aHeader();
794           virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
795           virtual MXF::RIP& RIP();
796
797           // Open the file for reading. The file must exist. Returns error if the
798           // operation cannot be completed.
799           Result_t OpenRead(const std::string& filename) const;
800
801           // Returns RESULT_INIT if the file is not open.
802           Result_t Close() const;
803
804           // Fill a VideoDescriptor struct with the values from the file's header.
805           // Returns RESULT_INIT if the file is not open.
806           Result_t FillVideoDescriptor(VideoDescriptor&) const;
807
808           // Fill a WriterInfo struct with the values from the file's header.
809           // Returns RESULT_INIT if the file is not open.
810           Result_t FillWriterInfo(WriterInfo&) const;
811
812           // Reads a frame of essence from the MXF file. If the optional AESEncContext
813           // argument is present, the essence is decrypted after reading. If the MXF
814           // file is encrypted and the AESDecContext argument is NULL, the frame buffer
815           // will contain the ciphertext frame data. If the HMACContext argument is
816           // not NULL, the HMAC will be calculated (if the file supports it).
817           // Returns RESULT_INIT if the file is not open, failure if the frame number is
818           // out of range, or if optional decrypt or HAMC operations fail.
819           Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
820
821           // Using the index table read from the footer partition, lookup the frame number
822           // and return the offset into the file at which to read that frame of essence.
823           // Returns RESULT_INIT if the file is not open, and RESULT_RANGE if the frame number is
824           // out of range.
825           Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
826
827           // Calculates the first frame in transport order of the GOP in which the requested
828           // frame is located.  Calls ReadFrame() to fetch the frame at the calculated position.
829           // Returns RESULT_INIT if the file is not open.
830           Result_t ReadFrameGOPStart(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
831
832           // Calculates the first frame in transport order of the GOP in which the requested
833           // frame is located.  Sets key_frame_number to the number of the frame at the calculated position.
834           // Returns RESULT_INIT if the file is not open.
835           Result_t FindFrameGOPStart(ui32_t frame_number, ui32_t& key_frame_number) const;
836
837           // Returns the type of the frame at the given position.
838           // Returns RESULT_INIT if the file is not open or RESULT_RANGE if the index is out of range.
839           Result_t FrameType(ui32_t frame_number, FrameType_t&) const;
840
841           // Print debugging information to stream
842           void     DumpHeaderMetadata(FILE* = 0) const;
843           void     DumpIndex(FILE* = 0) const;
844         };
845     } // namespace MPEG2
846
847   //---------------------------------------------------------------------------------
848   //
849
850
851
852   namespace PCM
853     {
854       // The default value of the ChannelFormat element of the AudioDescriptor struct
855       // is CF_NONE. If the value is set to one of the other ChannelFormat_t enum
856       // values, the file's Wave Audio Descriptor will contain a Channel Assignment
857       // element.
858       //
859       // The channel format should be one of (CF_CFG_1, CF_CFG_2, or CF_CFG_3) for
860       // SMPTE 429-2 files. It should normally be CF_NONE for JPEG Interop files, but
861       // the 429-2 may also be used.
862       //
863       enum ChannelFormat_t {
864         CF_NONE,
865         CF_CFG_1, // 5.1 with optional HI/VI
866         CF_CFG_2, // 6.1 (5.1 + center surround) with optional HI/VI
867         CF_CFG_3, // 7.1 (SDDS) with optional HI/VI
868         CF_CFG_4, // Wild Track Format
869         CF_CFG_5, // 7.1 DS with optional HI/VI
870         CF_CFG_6, // ST 377-4 (MCA) labels (see also ASDCP::MXF::decode_mca_string)
871         CF_MAXIMUM
872       };
873
874       struct AudioDescriptor
875         {
876           Rational EditRate;         // rate of frame wrapping
877           Rational AudioSamplingRate;  // rate of audio sample
878           ui32_t   Locked;             //
879           ui32_t   ChannelCount;       // number of channels
880           ui32_t   QuantizationBits;   // number of bits per single-channel sample
881           ui32_t   BlockAlign;         // number of bytes ber sample, all channels
882           ui32_t   AvgBps;             //
883           ui32_t   LinkedTrackID;      //
884           ui32_t   ContainerDuration;  // number of frames
885           ChannelFormat_t ChannelFormat; // audio channel arrangement
886       };
887
888       // Print AudioDescriptor to std::ostream
889       std::ostream& operator << (std::ostream& strm, const AudioDescriptor& adesc);
890       // Print debugging information to stream (stderr default)
891       void   AudioDescriptorDump(const AudioDescriptor&, FILE* = 0);
892
893       // Returns size in bytes of a single sample of data described by ADesc
894       inline ui32_t CalcSampleSize(const AudioDescriptor& ADesc)
895         {
896           return (ADesc.QuantizationBits / 8) * ADesc.ChannelCount;
897         }
898
899       // Returns number of samples per frame of data described by ADesc
900       inline ui32_t CalcSamplesPerFrame(const AudioDescriptor& ADesc)
901         {
902           double tmpd = ADesc.AudioSamplingRate.Quotient() / ADesc.EditRate.Quotient();
903           return (ui32_t)ceil(tmpd);
904         }
905
906       // Returns the size in bytes of a frame of data described by ADesc
907       inline ui32_t CalcFrameBufferSize(const AudioDescriptor& ADesc)
908         {
909           return CalcSampleSize(ADesc) * CalcSamplesPerFrame(ADesc);
910         }
911
912       //
913       class FrameBuffer : public ASDCP::FrameBuffer
914         {
915         public:
916           FrameBuffer() {}
917           FrameBuffer(ui32_t size) { Capacity(size); }
918           virtual ~FrameBuffer() {}
919
920           // Print debugging information to stream (stderr default)
921           void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
922         };
923
924       // An object which opens and reads a WAV file.  The call to OpenRead() reads metadata from
925       // the file and populates an internal AudioDescriptor object. Each subsequent call to
926       // ReadFrame() reads exactly one frame from the stream into the given FrameBuffer object.
927       // A "frame" is either 2000 or 2002 samples, depending upon the value of PictureRate.
928       class WAVParser
929         {
930           class h__WAVParser;
931           mem_ptr<h__WAVParser> m_Parser;
932           ASDCP_NO_COPY_CONSTRUCT(WAVParser);
933
934         public:
935           WAVParser();
936           virtual ~WAVParser();
937
938           // Opens the stream for reading, parses enough data to provide a complete
939           // set of stream metadata for the MXFWriter below. PictureRate controls
940           // ther frame rate for the MXF frame wrapping option.
941           Result_t OpenRead(const std::string& filename, const Rational& PictureRate) const;
942
943           // Fill an AudioDescriptor struct with the values from the file's header.
944           // Returns RESULT_INIT if the file is not open.
945           Result_t FillAudioDescriptor(AudioDescriptor&) const;
946
947           // Rewind the stream to the beginning.
948           Result_t Reset() const;
949
950           // Reads the next sequential frame in the input file and places it in the
951           // frame buffer. Fails if the buffer is too small or the stream is empty.
952           Result_t ReadFrame(FrameBuffer&) const;
953
954           Result_t Seek(ui32_t frame_number) const;
955         };
956
957
958       //
959       class MXFWriter
960         {
961           class h__Writer;
962           mem_ptr<h__Writer> m_Writer;
963           ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
964
965         public:
966           MXFWriter();
967           virtual ~MXFWriter();
968
969           // Warning: direct manipulation of MXF structures can interfere
970           // with the normal operation of the wrapper.  Caveat emptor!
971           virtual MXF::OP1aHeader& OP1aHeader();
972           virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
973           virtual MXF::RIP& RIP();
974
975           // Open the file for writing. The file must not exist. Returns error if
976           // the operation cannot be completed or if nonsensical data is discovered
977           // in the essence descriptor.
978           Result_t OpenWrite(const std::string& filename, const WriterInfo&,
979                              const AudioDescriptor&, ui32_t HeaderSize = 16384);
980
981           // Writes a frame of essence to the MXF file. If the optional AESEncContext
982           // argument is present, the essence is encrypted prior to writing.
983           // Fails if the file is not open, is finalized, or an operating system
984           // error occurs.
985           Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
986
987           // Closes the MXF file, writing the index and revised header.
988           Result_t Finalize();
989         };
990
991       //
992       class MXFReader
993         {
994           class h__Reader;
995           mem_ptr<h__Reader> m_Reader;
996           ASDCP_NO_COPY_CONSTRUCT(MXFReader);
997
998         public:
999           MXFReader();
1000           virtual ~MXFReader();
1001
1002           // Warning: direct manipulation of MXF structures can interfere
1003           // with the normal operation of the wrapper.  Caveat emptor!
1004           virtual MXF::OP1aHeader& OP1aHeader();
1005           virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1006           virtual MXF::RIP& RIP();
1007
1008           // Open the file for reading. The file must exist. Returns error if the
1009           // operation cannot be completed.
1010           Result_t OpenRead(const std::string& filename) const;
1011
1012           // Returns RESULT_INIT if the file is not open.
1013           Result_t Close() const;
1014
1015           // Fill an AudioDescriptor struct with the values from the file's header.
1016           // Returns RESULT_INIT if the file is not open.
1017           Result_t FillAudioDescriptor(AudioDescriptor&) const;
1018
1019           // Fill a WriterInfo struct with the values from the file's header.
1020           // Returns RESULT_INIT if the file is not open.
1021           Result_t FillWriterInfo(WriterInfo&) const;
1022
1023           // Reads a frame of essence from the MXF file. If the optional AESEncContext
1024           // argument is present, the essence is decrypted after reading. If the MXF
1025           // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1026           // will contain the ciphertext frame data. If the HMACContext argument is
1027           // not NULL, the HMAC will be calculated (if the file supports it).
1028           // Returns RESULT_INIT if the file is not open, failure if the frame number is
1029           // out of range, or if optional decrypt or HAMC operations fail.
1030           Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1031
1032           // Using the index table read from the footer partition, lookup the frame number
1033           // and return the offset into the file at which to read that frame of essence.
1034           // Returns RESULT_INIT if the file is not open, and RESULT_RANGE if the frame number is
1035           // out of range.
1036           Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
1037
1038           // Print debugging information to stream
1039           void     DumpHeaderMetadata(FILE* = 0) const;
1040           void     DumpIndex(FILE* = 0) const;
1041         };
1042     } // namespace PCM
1043
1044   //---------------------------------------------------------------------------------
1045   //
1046   namespace JP2K
1047     {
1048       const ui32_t MaxComponents = 3;
1049       const ui32_t MaxPrecincts = 32; // ISO 15444-1 Annex A.6.1
1050       const ui32_t MaxDefaults = 256; // made up
1051       const ui8_t  MaxCapabilities = 32;
1052                         const ui16_t MaxPRFN = 4;
1053                         const ui16_t MaxCPFN = 4;
1054
1055 #pragma pack(1)
1056       struct ImageComponent_t  // ISO 15444-1 Annex A.5.1
1057       {
1058         ui8_t Ssize;
1059         ui8_t XRsize;
1060         ui8_t YRsize;
1061       };
1062
1063       struct CodingStyleDefault_t // ISO 15444-1 Annex A.6.1
1064       {
1065         ui8_t   Scod;
1066
1067         struct
1068         {
1069           ui8_t  ProgressionOrder;
1070           ui8_t  NumberOfLayers[sizeof(ui16_t)];
1071           ui8_t  MultiCompTransform;
1072         } SGcod;
1073
1074         struct
1075         {
1076           ui8_t  DecompositionLevels;
1077           ui8_t  CodeblockWidth;
1078           ui8_t  CodeblockHeight;
1079           ui8_t  CodeblockStyle;
1080           ui8_t  Transformation;
1081           ui8_t  PrecinctSize[MaxPrecincts];
1082         } SPcod;
1083       };
1084
1085       struct QuantizationDefault_t // ISO 15444-1 Annex A.6.4
1086       {
1087         ui8_t  Sqcd;
1088         ui8_t  SPqcd[MaxDefaults];
1089         ui8_t  SPqcdLength;
1090       };
1091
1092       struct ExtendedCapabilities_t // ISO 15444-1 Annex A.5.2
1093       {
1094         ui32_t  Pcap; // Pcap = 0 means that no extended capabilities are required
1095         ui16_t  Ccap[MaxCapabilities]; // Ccap^i in ISO/IEC 15444-1 corresponds to Ccap[i -1]
1096       };
1097
1098                         struct Profile_t // ISO 15444-1
1099       {
1100         ui16_t  N; // N = 0 means that the profile is signaled through Rsiz exclusively
1101         ui16_t  Pprf[MaxPRFN]; // Pprf^i in ISO/IEC 15444-1 corresponds to Pprf[i -1]
1102       };
1103
1104                         struct CorrespondingProfile_t // ISO 15444-1
1105       {
1106         ui16_t  N; // N = 0 means that no corresponding profile is signaled
1107         ui16_t  Pcpf[MaxCPFN]; // Pcpf^i in ISO/IEC 15444-1 corresponds to Pcpf[i -1]
1108       };
1109
1110 #pragma pack()
1111
1112       struct PictureDescriptor
1113       {
1114         Rational       EditRate;
1115         ui32_t         ContainerDuration;
1116         Rational       SampleRate;
1117         ui32_t         StoredWidth;
1118         ui32_t         StoredHeight;
1119         Rational       AspectRatio;
1120         ui16_t         Rsize;
1121         ui32_t         Xsize;
1122         ui32_t         Ysize;
1123         ui32_t         XOsize;
1124         ui32_t         YOsize;
1125         ui32_t         XTsize;
1126         ui32_t         YTsize;
1127         ui32_t         XTOsize;
1128         ui32_t         YTOsize;
1129         ui16_t         Csize;
1130         ImageComponent_t      ImageComponents[MaxComponents];
1131         CodingStyleDefault_t  CodingStyleDefault;
1132         QuantizationDefault_t QuantizationDefault;
1133   ExtendedCapabilities_t ExtendedCapabilities;
1134   Profile_t   Profile;
1135         CorrespondingProfile_t   CorrespondingProfile;    
1136       };
1137
1138       // Print debugging information to std::ostream
1139       std::ostream& operator << (std::ostream& strm, const PictureDescriptor& pdesc);
1140       // Print debugging information to stream (stderr default)
1141       void   PictureDescriptorDump(const PictureDescriptor&, FILE* = 0);
1142
1143       //
1144       class FrameBuffer : public ASDCP::FrameBuffer
1145         {
1146         public:
1147           FrameBuffer() {}
1148           FrameBuffer(ui32_t size) { Capacity(size); }
1149           virtual ~FrameBuffer() {}
1150
1151           // Print debugging information to stream (stderr default)
1152           void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
1153         };
1154
1155
1156       // An object which opens and reads a JPEG 2000 codestream file.  The file is expected
1157       // to contain exactly one complete frame of picture essence as an unwrapped (raw)
1158       // ISO/IEC 15444 codestream.
1159       class CodestreamParser
1160         {
1161           class h__CodestreamParser;
1162           mem_ptr<h__CodestreamParser> m_Parser;
1163           ASDCP_NO_COPY_CONSTRUCT(CodestreamParser);
1164
1165         public:
1166           CodestreamParser();
1167           virtual ~CodestreamParser();
1168
1169           // Opens a file for reading, parses enough data to provide a complete
1170           // set of stream metadata for the MXFWriter below.
1171           // The frame buffer's PlaintextOffset parameter will be set to the first
1172           // byte of the data segment. Set this value to zero if you want
1173           // encrypted headers.
1174           Result_t OpenReadFrame(const std::string& filename, FrameBuffer&) const;
1175
1176           // Fill a PictureDescriptor struct with the values from the file's codestream.
1177           // Returns RESULT_INIT if the file is not open.
1178           Result_t FillPictureDescriptor(PictureDescriptor&) const;
1179         };
1180
1181       // Parses the data in the frame buffer to fill in the picture descriptor. Copies
1182       // the offset of the image data into start_of_data. Returns error if the parser fails.
1183       Result_t ParseMetadataIntoDesc(const FrameBuffer&, PictureDescriptor&, byte_t* start_of_data = 0);
1184
1185       // An object which reads a sequence of files containing JPEG 2000 pictures.
1186       class SequenceParser
1187         {
1188           class h__SequenceParser;
1189           mem_ptr<h__SequenceParser> m_Parser;
1190           ASDCP_NO_COPY_CONSTRUCT(SequenceParser);
1191
1192         public:
1193           SequenceParser();
1194           virtual ~SequenceParser();
1195
1196           // Opens a directory for reading.  The directory is expected to contain one or
1197           // more files, each containing the codestream for exactly one picture. The
1198           // files must be named such that the frames are in temporal order when sorted
1199           // alphabetically by filename. The parser will automatically parse enough data
1200           // from the first file to provide a complete set of stream metadata for the
1201           // MXFWriter below.  If the "pedantic" parameter is given and is true, the
1202           // parser will check the metadata for each codestream and fail if a
1203           // mismatch is detected.
1204           Result_t OpenRead(const std::string& filename, bool pedantic = false) const;
1205
1206           // Opens a file sequence for reading.  The sequence is expected to contain one or
1207           // more filenames, each naming a file containing the codestream for exactly one
1208           // picture. The parser will automatically parse enough data
1209           // from the first file to provide a complete set of stream metadata for the
1210           // MXFWriter below.  If the "pedantic" parameter is given and is true, the
1211           // parser will check the metadata for each codestream and fail if a
1212           // mismatch is detected.
1213           Result_t OpenRead(const std::list<std::string>& file_list, bool pedantic = false) const;
1214
1215           // Fill a PictureDescriptor struct with the values from the first file's codestream.
1216           // Returns RESULT_INIT if the directory is not open.
1217           Result_t FillPictureDescriptor(PictureDescriptor&) const;
1218
1219           // Rewind the directory to the beginning.
1220           Result_t Reset() const;
1221
1222           // Reads the next sequential frame in the directory and places it in the
1223           // frame buffer. Fails if the buffer is too small or the direcdtory
1224           // contains no more files.
1225           // The frame buffer's PlaintextOffset parameter will be set to the first
1226           // byte of the data segment. Set this value to zero if you want
1227           // encrypted headers.
1228           Result_t ReadFrame(FrameBuffer&) const;
1229         };
1230
1231
1232       //
1233       class MXFWriter
1234         {
1235           class h__Writer;
1236           mem_ptr<h__Writer> m_Writer;
1237           ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
1238
1239         public:
1240           MXFWriter();
1241           virtual ~MXFWriter();
1242
1243           // Warning: direct manipulation of MXF structures can interfere
1244           // with the normal operation of the wrapper.  Caveat emptor!
1245           virtual MXF::OP1aHeader& OP1aHeader();
1246           virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1247           virtual MXF::RIP& RIP();
1248
1249           // Open the file for writing. The file must not exist. Returns error if
1250           // the operation cannot be completed or if nonsensical data is discovered
1251           // in the essence descriptor.
1252           Result_t OpenWrite(const std::string& filename, const WriterInfo&,
1253                              const PictureDescriptor&, ui32_t HeaderSize = 16384);
1254
1255           // Writes a frame of essence to the MXF file. If the optional AESEncContext
1256           // argument is present, the essence is encrypted prior to writing.
1257           // Fails if the file is not open, is finalized, or an operating system
1258           // error occurs.
1259           Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
1260
1261           // Closes the MXF file, writing the index and revised header.
1262           Result_t Finalize();
1263         };
1264
1265       //
1266       class MXFReader
1267         {
1268           class h__Reader;
1269           mem_ptr<h__Reader> m_Reader;
1270           ASDCP_NO_COPY_CONSTRUCT(MXFReader);
1271
1272         public:
1273           MXFReader();
1274           virtual ~MXFReader();
1275
1276           // Warning: direct manipulation of MXF structures can interfere
1277           // with the normal operation of the wrapper.  Caveat emptor!
1278           virtual MXF::OP1aHeader& OP1aHeader();
1279           virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1280           virtual MXF::RIP& RIP();
1281
1282           // Open the file for reading. The file must exist. Returns error if the
1283           // operation cannot be completed.
1284           Result_t OpenRead(const std::string& filename) const;
1285
1286           // Returns RESULT_INIT if the file is not open.
1287           Result_t Close() const;
1288
1289           // Fill an AudioDescriptor struct with the values from the file's header.
1290           // Returns RESULT_INIT if the file is not open.
1291           Result_t FillPictureDescriptor(PictureDescriptor&) const;
1292
1293           // Fill a WriterInfo struct with the values from the file's header.
1294           // Returns RESULT_INIT if the file is not open.
1295           Result_t FillWriterInfo(WriterInfo&) const;
1296
1297           // Reads a frame of essence from the MXF file. If the optional AESEncContext
1298           // argument is present, the essence is decrypted after reading. If the MXF
1299           // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1300           // will contain the ciphertext frame data. If the HMACContext argument is
1301           // not NULL, the HMAC will be calculated (if the file supports it).
1302           // Returns RESULT_INIT if the file is not open, failure if the frame number is
1303           // out of range, or if optional decrypt or HAMC operations fail.
1304           Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1305
1306           // Using the index table read from the footer partition, lookup the frame number
1307           // and return the offset into the file at which to read that frame of essence.
1308           // Returns RESULT_INIT if the file is not open, and RESULT_FRAME if the frame number is
1309           // out of range.
1310           Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
1311
1312           // Print debugging information to stream
1313           void     DumpHeaderMetadata(FILE* = 0) const;
1314           void     DumpIndex(FILE* = 0) const;
1315         };
1316
1317
1318       // Stereoscopic Image support
1319       //
1320
1321       enum StereoscopicPhase_t
1322       {
1323         SP_LEFT,
1324         SP_RIGHT
1325       };
1326
1327       struct SFrameBuffer
1328       {
1329         JP2K::FrameBuffer Left;
1330         JP2K::FrameBuffer Right;
1331
1332         SFrameBuffer(ui32_t size) {
1333           Left.Capacity(size);
1334           Right.Capacity(size);
1335         }
1336       };
1337
1338       class MXFSWriter
1339       {
1340           class h__SWriter;
1341           mem_ptr<h__SWriter> m_Writer;
1342           ASDCP_NO_COPY_CONSTRUCT(MXFSWriter);
1343
1344         public:
1345           MXFSWriter();
1346           virtual ~MXFSWriter();
1347
1348           // Warning: direct manipulation of MXF structures can interfere
1349           // with the normal operation of the wrapper.  Caveat emptor!
1350           virtual MXF::OP1aHeader& OP1aHeader();
1351           virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1352           virtual MXF::RIP& RIP();
1353
1354           // Open the file for writing. The file must not exist. Returns error if
1355           // the operation cannot be completed or if nonsensical data is discovered
1356           // in the essence descriptor.
1357           Result_t OpenWrite(const std::string& filename, const WriterInfo&,
1358                              const PictureDescriptor&, ui32_t HeaderSize = 16384);
1359
1360           // Writes a pair of frames of essence to the MXF file. If the optional AESEncContext
1361           // argument is present, the essence is encrypted prior to writing.
1362           // Fails if the file is not open, is finalized, or an operating system
1363           // error occurs.
1364           Result_t WriteFrame(const SFrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
1365
1366           // Writes a frame of essence to the MXF file. If the optional AESEncContext
1367           // argument is present, the essence is encrypted prior to writing.
1368           // Fails if the file is not open, is finalized, or an operating system
1369           // error occurs. Frames must be written in the proper phase (L-R-L-R),
1370           // RESULT_SPHASE will be returned if phase is reversed. The first frame
1371           // written must be left eye.
1372           Result_t WriteFrame(const FrameBuffer&, StereoscopicPhase_t phase,
1373                               AESEncContext* = 0, HMACContext* = 0);
1374
1375           // Closes the MXF file, writing the index and revised header.  Returns
1376           // RESULT_SPHASE if WriteFrame was called an odd number of times.
1377           Result_t Finalize();
1378         };
1379
1380       //
1381       class MXFSReader
1382         {
1383           class h__SReader;
1384           mem_ptr<h__SReader> m_Reader;
1385           ASDCP_NO_COPY_CONSTRUCT(MXFSReader);
1386
1387         public:
1388           MXFSReader();
1389           virtual ~MXFSReader();
1390
1391           // Warning: direct manipulation of MXF structures can interfere
1392           // with the normal operation of the wrapper.  Caveat emptor!
1393           virtual MXF::OP1aHeader& OP1aHeader();
1394           virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1395           virtual MXF::RIP& RIP();
1396
1397           // Open the file for reading. The file must exist. Returns error if the
1398           // operation cannot be completed.
1399           Result_t OpenRead(const std::string& filename) const;
1400
1401           // Returns RESULT_INIT if the file is not open.
1402           Result_t Close() const;
1403
1404           // Fill an AudioDescriptor struct with the values from the file's header.
1405           // Returns RESULT_INIT if the file is not open.
1406           Result_t FillPictureDescriptor(PictureDescriptor&) const;
1407
1408           // Fill a WriterInfo struct with the values from the file's header.
1409           // Returns RESULT_INIT if the file is not open.
1410           Result_t FillWriterInfo(WriterInfo&) const;
1411
1412           // Reads a pair of frames of essence from the MXF file. If the optional AESEncContext
1413           // argument is present, the essence is decrypted after reading. If the MXF
1414           // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1415           // will contain the ciphertext frame data. If the HMACContext argument is
1416           // not NULL, the HMAC will be calculated (if the file supports it).
1417           // Returns RESULT_INIT if the file is not open, failure if the frame number is
1418           // out of range, or if optional decrypt or HAMC operations fail.
1419           Result_t ReadFrame(ui32_t frame_number, SFrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1420
1421           // Reads a frame of essence from the MXF file. If the optional AESEncContext
1422           // argument is present, the essence is decrypted after reading. If the MXF
1423           // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1424           // will contain the ciphertext frame data. If the HMACContext argument is
1425           // not NULL, the HMAC will be calculated (if the file supports it).
1426           // Returns RESULT_INIT if the file is not open, failure if the frame number is
1427           // out of range, or if optional decrypt or HAMC operations fail.
1428           Result_t ReadFrame(ui32_t frame_number, StereoscopicPhase_t phase,
1429                              FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1430
1431           // Using the index table read from the footer partition, lookup the frame number
1432           // and return the offset into the file at which to read that frame of essence.
1433           // Returns RESULT_INIT if the file is not open, and RESULT_FRAME if the frame number is
1434           // out of range.
1435           Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
1436
1437           // Print debugging information to stream
1438           void     DumpHeaderMetadata(FILE* = 0) const;
1439           void     DumpIndex(FILE* = 0) const;
1440         };
1441     } // namespace JP2K
1442
1443   //---------------------------------------------------------------------------------
1444   //
1445   namespace TimedText
1446     {
1447       enum MIMEType_t { MT_BIN, MT_PNG, MT_OPENTYPE };
1448
1449       struct TimedTextResourceDescriptor
1450       {
1451         byte_t      ResourceID[UUIDlen];
1452           MIMEType_t  Type;
1453
1454         TimedTextResourceDescriptor() : Type(MT_BIN) {}
1455       };
1456
1457       typedef std::list<TimedTextResourceDescriptor> ResourceList_t;
1458
1459       struct TimedTextDescriptor
1460       {
1461         Rational       EditRate;                //
1462         ui32_t         ContainerDuration;
1463         byte_t         AssetID[UUIDlen];
1464         std::string    NamespaceName;
1465         std::string    EncodingName;
1466         ResourceList_t ResourceList;
1467
1468       TimedTextDescriptor() : ContainerDuration(0), EncodingName("UTF-8") {} // D-Cinema format is always UTF-8
1469       };
1470
1471       // Print debugging information to std::ostream
1472       std::ostream& operator << (std::ostream& strm, const TimedTextDescriptor& tinfo);
1473       // Print debugging information to stream (stderr default)
1474       void   DescriptorDump(const TimedTextDescriptor&, FILE* = 0);
1475
1476       //
1477       class FrameBuffer : public ASDCP::FrameBuffer
1478       {
1479         ASDCP_NO_COPY_CONSTRUCT(FrameBuffer); // TODO: should have copy construct
1480
1481       protected:
1482         byte_t      m_AssetID[UUIDlen];
1483         std::string m_MIMEType;
1484
1485       public:
1486         FrameBuffer() { memset(m_AssetID, 0, UUIDlen); }
1487         FrameBuffer(ui32_t size) { Capacity(size); memset(m_AssetID, 0, UUIDlen); }
1488         virtual ~FrameBuffer() {}
1489
1490         inline const byte_t* AssetID() const { return m_AssetID; }
1491         inline void          AssetID(const byte_t* buf) { memcpy(m_AssetID, buf, UUIDlen); }
1492         inline const char*   MIMEType() const { return m_MIMEType.c_str(); }
1493         inline void          MIMEType(const std::string& s) { m_MIMEType = s; }
1494
1495         // Print debugging information to stream (stderr default)
1496         void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
1497       };
1498
1499       // An abstract base for a lookup service that returns the resource data
1500       // identified by the given ancillary resource id.
1501       //
1502       class IResourceResolver
1503       {
1504       public:
1505         virtual ~IResourceResolver() {}
1506         virtual Result_t ResolveRID(const byte_t* uuid, FrameBuffer&) const = 0; // return data for RID
1507       };
1508
1509       // Resolves resource references by testing the named directory for file names containing
1510       // the respective UUID.
1511       //
1512       class LocalFilenameResolver : public ASDCP::TimedText::IResourceResolver
1513         {
1514           std::string m_Dirname;
1515           ASDCP_NO_COPY_CONSTRUCT(LocalFilenameResolver);
1516
1517         public:
1518           LocalFilenameResolver();
1519           virtual ~LocalFilenameResolver();
1520           Result_t OpenRead(const std::string& dirname);
1521           Result_t ResolveRID(const byte_t* uuid, FrameBuffer& FrameBuf) const;
1522         };
1523
1524       //
1525       class DCSubtitleParser
1526         {
1527           class h__SubtitleParser;
1528           mem_ptr<h__SubtitleParser> m_Parser;
1529           ASDCP_NO_COPY_CONSTRUCT(DCSubtitleParser);
1530
1531         public:
1532           DCSubtitleParser();
1533           virtual ~DCSubtitleParser();
1534
1535           // Opens an XML file for reading, parses data to provide a complete
1536           // set of stream metadata for the MXFWriter below.
1537           Result_t OpenRead(const std::string& filename) const;
1538
1539           // Parses an XML document to provide a complete set of stream metadata
1540           // for the MXFWriter below. The optional filename argument is used to
1541           // initialize the default resource resolver (see ReadAncillaryResource).
1542           Result_t OpenRead(const std::string& xml_doc, const std::string& filename) const;
1543
1544           // Fill a TimedTextDescriptor struct with the values from the file's contents.
1545           // Returns RESULT_INIT if the file is not open.
1546           Result_t FillTimedTextDescriptor(TimedTextDescriptor&) const;
1547
1548           // Reads the complete Timed Text Resource into the given string.
1549           Result_t ReadTimedTextResource(std::string&) const;
1550
1551           // Reads the Ancillary Resource having the given ID. Fails if the buffer
1552           // is too small or the resource does not exist. The optional Resolver
1553           // argument can be provided which will be used to retrieve the resource
1554           // having a particulat UUID. If a Resolver is not supplied, the default
1555           // internal resolver will return the contents of the file having the UUID
1556           // as the filename. The filename must exist in the same directory as the
1557           // XML file opened with OpenRead().
1558           Result_t ReadAncillaryResource(const byte_t* uuid, FrameBuffer&,
1559                                          const IResourceResolver* Resolver = 0) const;
1560         };
1561
1562       //
1563       class MXFWriter
1564         {
1565           class h__Writer;
1566           mem_ptr<h__Writer> m_Writer;
1567           ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
1568
1569         public:
1570           MXFWriter();
1571           virtual ~MXFWriter();
1572
1573           // Warning: direct manipulation of MXF structures can interfere
1574           // with the normal operation of the wrapper.  Caveat emptor!
1575           virtual MXF::OP1aHeader& OP1aHeader();
1576           virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1577           virtual MXF::RIP& RIP();
1578
1579           // Open the file for writing. The file must not exist. Returns error if
1580           // the operation cannot be completed or if nonsensical data is discovered
1581           // in the essence descriptor.
1582           Result_t OpenWrite(const std::string& filename, const WriterInfo&,
1583                              const TimedTextDescriptor&, ui32_t HeaderSize = 16384);
1584
1585           // Writes the Timed-Text Resource to the MXF file. The file must be UTF-8
1586           // encoded. If the optional AESEncContext argument is present, the essence
1587           // is encrypted prior to writing. Fails if the file is not open, is finalized,
1588           // or an operating system error occurs.
1589           // This method may only be called once, and it must be called before any
1590           // call to WriteAncillaryResource(). RESULT_STATE will be returned if these
1591           // conditions are not met.
1592           Result_t WriteTimedTextResource(const std::string& XMLDoc, AESEncContext* = 0, HMACContext* = 0);
1593
1594           // Writes an Ancillary Resource to the MXF file. If the optional AESEncContext
1595           // argument is present, the essence is encrypted prior to writing.
1596           // Fails if the file is not open, is finalized, or an operating system
1597           // error occurs. RESULT_STATE will be returned if the method is called before
1598           // WriteTimedTextResource()
1599           Result_t WriteAncillaryResource(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
1600
1601           // Closes the MXF file, writing the index and revised header.
1602           Result_t Finalize();
1603         };
1604
1605       //
1606       class MXFReader
1607         {
1608           class h__Reader;
1609           mem_ptr<h__Reader> m_Reader;
1610           ASDCP_NO_COPY_CONSTRUCT(MXFReader);
1611
1612         public:
1613           MXFReader();
1614           virtual ~MXFReader();
1615
1616           // Warning: direct manipulation of MXF structures can interfere
1617           // with the normal operation of the wrapper.  Caveat emptor!
1618           virtual MXF::OP1aHeader& OP1aHeader();
1619           virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1620           virtual MXF::RIP& RIP();
1621
1622           // Open the file for reading. The file must exist. Returns error if the
1623           // operation cannot be completed.
1624           Result_t OpenRead(const std::string& filename) const;
1625
1626           // Returns RESULT_INIT if the file is not open.
1627           Result_t Close() const;
1628
1629           // Fill a TimedTextDescriptor struct with the values from the file's header.
1630           // Returns RESULT_INIT if the file is not open.
1631           Result_t FillTimedTextDescriptor(TimedTextDescriptor&) const;
1632
1633           // Fill a WriterInfo struct with the values from the file's header.
1634           // Returns RESULT_INIT if the file is not open.
1635           Result_t FillWriterInfo(WriterInfo&) const;
1636
1637           // Reads the complete Timed Text Resource into the given string. Fails if the resource
1638           // is encrypted and AESDecContext is NULL (use the following method to retrieve the
1639           // raw ciphertet block).
1640           Result_t ReadTimedTextResource(std::string&, AESDecContext* = 0, HMACContext* = 0) const;
1641
1642           // Reads the complete Timed Text Resource from the MXF file. If the optional AESEncContext
1643           // argument is present, the resource is decrypted after reading. If the MXF
1644           // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1645           // will contain the ciphertext frame data. If the HMACContext argument is
1646           // not NULL, the HMAC will be calculated (if the file supports it).
1647           // Returns RESULT_INIT if the file is not open, failure if the frame number is
1648           // out of range, or if optional decrypt or HAMC operations fail.
1649           Result_t ReadTimedTextResource(FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1650
1651           // Reads the timed-text resource having the given UUID from the MXF file. If the
1652           // optional AESEncContext argument is present, the resource is decrypted after
1653           // reading. If the MXF file is encrypted and the AESDecContext argument is NULL,
1654           // the frame buffer will contain the ciphertext frame data. If the HMACContext
1655           // argument is not NULL, the HMAC will be calculated (if the file supports it).
1656           // Returns RESULT_INIT if the file is not open, failure if the frame number is
1657           // out of range, or if optional decrypt or HAMC operations fail.
1658           Result_t ReadAncillaryResource(const byte_t* uuid, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1659
1660           // Print debugging information to stream
1661           void     DumpHeaderMetadata(FILE* = 0) const;
1662           void     DumpIndex(FILE* = 0) const;
1663         };
1664     } // namespace TimedText
1665
1666   //---------------------------------------------------------------------------------
1667   //
1668   namespace DCData
1669   {
1670     struct DCDataDescriptor
1671     {
1672       Rational EditRate;                 // Sample rate
1673       ui32_t   ContainerDuration;          // number of frames
1674       byte_t   AssetID[UUIDlen];           // The UUID for the DCData track
1675       byte_t   DataEssenceCoding[UUIDlen]; // The coding for the data carried
1676     };
1677
1678     // Print DCDataDescriptor to std::ostream
1679     std::ostream& operator << (std::ostream& strm, const DCDataDescriptor& ddesc);
1680     // Print debugging information to stream (stderr default)
1681     void DCDataDescriptorDump(const DCDataDescriptor&, FILE* = 0);
1682
1683     //
1684     class FrameBuffer : public ASDCP::FrameBuffer
1685         {
1686      public:
1687           FrameBuffer() {}
1688           FrameBuffer(ui32_t size) { Capacity(size); }
1689           virtual ~FrameBuffer() {}
1690
1691           // Print debugging information to stream (stderr default)
1692           void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
1693         };
1694
1695     // An object which opens and reads a DC Data file.  The file is expected
1696     // to contain exactly one complete frame of DC data essence as an unwrapped (raw)
1697     // byte stream.
1698     class BytestreamParser
1699         {
1700           class h__BytestreamParser;
1701           mem_ptr<h__BytestreamParser> m_Parser;
1702           ASDCP_NO_COPY_CONSTRUCT(BytestreamParser);
1703
1704      public:
1705           BytestreamParser();
1706           virtual ~BytestreamParser();
1707
1708           // Opens a file for reading, parses enough data to provide a complete
1709       // set of stream metadata for the MXFWriter below.
1710           // The frame buffer's PlaintextOffset parameter will be set to the first
1711           // byte of the data segment. Set this value to zero if you want
1712           // encrypted headers.
1713           Result_t OpenReadFrame(const std::string& filename, FrameBuffer&) const;
1714
1715           // Fill a DCDataDescriptor struct with the values from the file's bytestream.
1716           // Returns RESULT_INIT if the file is not open.
1717           Result_t FillDCDataDescriptor(DCDataDescriptor&) const;
1718         };
1719
1720     // An object which reads a sequence of files containing DC Data.
1721     class SequenceParser
1722         {
1723           class h__SequenceParser;
1724           mem_ptr<h__SequenceParser> m_Parser;
1725           ASDCP_NO_COPY_CONSTRUCT(SequenceParser);
1726
1727      public:
1728           SequenceParser();
1729           virtual ~SequenceParser();
1730
1731           // Opens a directory for reading.  The directory is expected to contain one or
1732           // more files, each containing the bytestream for exactly one frame. The files
1733       // must be named such that the frames are in temporal order when sorted
1734           // alphabetically by filename.
1735           Result_t OpenRead(const std::string& filename) const;
1736
1737           // Opens a file sequence for reading.  The sequence is expected to contain one or
1738           // more filenames, each naming a file containing the bytestream for exactly one
1739           // frame.
1740           Result_t OpenRead(const std::list<std::string>& file_list) const;
1741
1742           // Fill a DCDataDescriptor struct with default values.
1743           // Returns RESULT_INIT if the directory is not open.
1744           Result_t FillDCDataDescriptor(DCDataDescriptor&) const;
1745
1746           // Rewind the directory to the beginning.
1747           Result_t Reset() const;
1748
1749           // Reads the next sequential frame in the directory and places it in the
1750           // frame buffer. Fails if the buffer is too small or the direcdtory
1751           // contains no more files.
1752           // The frame buffer's PlaintextOffset parameter will be set to the first
1753           // byte of the data segment. Set this value to zero if you want
1754           // encrypted headers.
1755           Result_t ReadFrame(FrameBuffer&) const;
1756         };
1757
1758     //
1759     class MXFWriter
1760         {
1761           class h__Writer;
1762           mem_ptr<h__Writer> m_Writer;
1763           ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
1764
1765      public:
1766           MXFWriter();
1767           virtual ~MXFWriter();
1768
1769           // Warning: direct manipulation of MXF structures can interfere
1770           // with the normal operation of the wrapper.  Caveat emptor!
1771           virtual MXF::OP1aHeader& OP1aHeader();
1772           virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1773           virtual MXF::RIP& RIP();
1774
1775           // Open the file for writing. The file must not exist. Returns error if
1776           // the operation cannot be completed or if nonsensical data is discovered
1777           // in the essence descriptor.
1778           Result_t OpenWrite(const std::string& filename, const WriterInfo&,
1779                              const DCDataDescriptor&, ui32_t HeaderSize = 16384);
1780
1781           // Writes a frame of essence to the MXF file. If the optional AESEncContext
1782           // argument is present, the essence is encrypted prior to writing.
1783           // Fails if the file is not open, is finalized, or an operating system
1784           // error occurs.
1785           Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
1786
1787           // Closes the MXF file, writing the index and revised header.
1788           Result_t Finalize();
1789         };
1790
1791     //
1792     class MXFReader
1793         {
1794           class h__Reader;
1795           mem_ptr<h__Reader> m_Reader;
1796           ASDCP_NO_COPY_CONSTRUCT(MXFReader);
1797
1798      public:
1799           MXFReader();
1800           virtual ~MXFReader();
1801
1802           // Warning: direct manipulation of MXF structures can interfere
1803           // with the normal operation of the wrapper.  Caveat emptor!
1804           virtual MXF::OP1aHeader& OP1aHeader();
1805           virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1806           virtual MXF::RIP& RIP();
1807
1808           // Open the file for reading. The file must exist. Returns error if the
1809           // operation cannot be completed.
1810           Result_t OpenRead(const std::string& filename) const;
1811
1812           // Returns RESULT_INIT if the file is not open.
1813           Result_t Close() const;
1814
1815           // Fill a DCDataDescriptor struct with the values from the file's header.
1816           // Returns RESULT_INIT if the file is not open.
1817           Result_t FillDCDataDescriptor(DCDataDescriptor&) const;
1818
1819           // Fill a WriterInfo struct with the values from the file's header.
1820           // Returns RESULT_INIT if the file is not open.
1821           Result_t FillWriterInfo(WriterInfo&) const;
1822
1823           // Reads a frame of essence from the MXF file. If the optional AESEncContext
1824           // argument is present, the essence is decrypted after reading. If the MXF
1825           // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1826           // will contain the ciphertext frame data. If the HMACContext argument is
1827           // not NULL, the HMAC will be calculated (if the file supports it).
1828           // Returns RESULT_INIT if the file is not open, failure if the frame number is
1829           // out of range, or if optional decrypt or HAMC operations fail.
1830           Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1831
1832           // Using the index table read from the footer partition, lookup the frame number
1833           // and return the offset into the file at which to read that frame of essence.
1834           // Returns RESULT_INIT if the file is not open, and RESULT_RANGE if the frame number is
1835           // out of range.
1836           Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
1837
1838           // Print debugging information to stream
1839           void     DumpHeaderMetadata(FILE* = 0) const;
1840           void     DumpIndex(FILE* = 0) const;
1841         };
1842
1843   } // namespace DCData
1844
1845   //---------------------------------------------------------------------------------
1846   //
1847   namespace ATMOS
1848   {
1849     struct AtmosDescriptor : public DCData::DCDataDescriptor
1850     {
1851       ui32_t FirstFrame;       // Frame number of the frame to align with the FFOA of the picture track
1852       ui16_t MaxChannelCount;  // Max number of channels in bitstream
1853       ui16_t MaxObjectCount;   // Max number of objects in bitstream
1854       byte_t AtmosID[UUIDlen]; // UUID of Atmos Project
1855       ui8_t  AtmosVersion;     // ATMOS Coder Version used to create bitstream
1856     };
1857
1858     // Print AtmosDescriptor to std::ostream
1859     std::ostream& operator << (std::ostream& strm, const AtmosDescriptor& adesc);
1860     // Print debugging information to stream (stderr default)
1861     void AtmosDescriptorDump(const AtmosDescriptor&, FILE* = 0);
1862     // Determine if a file is a raw atmos file
1863     bool IsDolbyAtmos(const std::string& filename);
1864
1865     //
1866     class MXFWriter
1867         {
1868
1869       class h__Writer;
1870           mem_ptr<h__Writer> m_Writer;
1871           ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
1872
1873      public:
1874           MXFWriter();
1875           virtual ~MXFWriter();
1876
1877           // Warning: direct manipulation of MXF structures can interfere
1878           // with the normal operation of the wrapper.  Caveat emptor!
1879           virtual MXF::OP1aHeader& OP1aHeader();
1880           virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1881           virtual MXF::RIP& RIP();
1882
1883           // Open the file for writing. The file must not exist. Returns error if
1884           // the operation cannot be completed or if nonsensical data is discovered
1885           // in the essence descriptor.
1886           Result_t OpenWrite(const std::string& filename, const WriterInfo&,
1887                              const AtmosDescriptor&, ui32_t HeaderSize = 16384);
1888
1889           // Writes a frame of essence to the MXF file. If the optional AESEncContext
1890           // argument is present, the essence is encrypted prior to writing.
1891           // Fails if the file is not open, is finalized, or an operating system
1892           // error occurs.
1893       Result_t WriteFrame(const DCData::FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
1894
1895           // Closes the MXF file, writing the index and revised header.
1896           Result_t Finalize();
1897         };
1898
1899     //
1900     class MXFReader
1901         {
1902       class h__Reader;
1903           mem_ptr<h__Reader> m_Reader;
1904           ASDCP_NO_COPY_CONSTRUCT(MXFReader);
1905
1906      public:
1907           MXFReader();
1908           virtual ~MXFReader();
1909
1910           // Warning: direct manipulation of MXF structures can interfere
1911           // with the normal operation of the wrapper.  Caveat emptor!
1912           virtual MXF::OP1aHeader& OP1aHeader();
1913           virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1914           virtual MXF::RIP& RIP();
1915
1916           // Open the file for reading. The file must exist. Returns error if the
1917           // operation cannot be completed.
1918           Result_t OpenRead(const std::string& filename) const;
1919
1920           // Returns RESULT_INIT if the file is not open.
1921           Result_t Close() const;
1922
1923           // Fill an AtmosDescriptor struct with the values from the file's header.
1924           // Returns RESULT_INIT if the file is not open.
1925           Result_t FillAtmosDescriptor(AtmosDescriptor&) const;
1926
1927           // Fill a WriterInfo struct with the values from the file's header.
1928           // Returns RESULT_INIT if the file is not open.
1929           Result_t FillWriterInfo(WriterInfo&) const;
1930
1931           // Reads a frame of essence from the MXF file. If the optional AESEncContext
1932           // argument is present, the essence is decrypted after reading. If the MXF
1933           // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1934           // will contain the ciphertext frame data. If the HMACContext argument is
1935           // not NULL, the HMAC will be calculated (if the file supports it).
1936           // Returns RESULT_INIT if the file is not open, failure if the frame number is
1937           // out of range, or if optional decrypt or HAMC operations fail.
1938           Result_t ReadFrame(ui32_t frame_number, DCData::FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1939
1940           // Using the index table read from the footer partition, lookup the frame number
1941           // and return the offset into the file at which to read that frame of essence.
1942           // Returns RESULT_INIT if the file is not open, and RESULT_RANGE if the frame number is
1943           // out of range.
1944           Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
1945
1946           // Print debugging information to stream
1947           void     DumpHeaderMetadata(FILE* = 0) const;
1948           void     DumpIndex(FILE* = 0) const;
1949         };
1950
1951   } // namespace ATMOS
1952
1953
1954
1955 } // namespace ASDCP
1956
1957
1958 #endif // _AS_DCP_H_
1959
1960 //
1961 // end AS_DCP.h
1962 //