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