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