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