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