Add PCMParserList.h to list of extra exported headers.
[asdcplib.git] / src / AS_DCP.h
1 /*
2 Copyright (c) 2003-2008, 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 wrapper objects that offer simplified
32 access to files conforming to the file formats proposed by the SMPTE
33 D-Cinema packaging working group DC28.20.  The file format, labeled
34 AS-DCP, is described in series of separate documents which include but
35 may not be limited to:
36
37  o MXF Interop Track File Specification
38  o MXF Interop Track File Essence Encryption Specification
39  o MXF Interop Operational Constraints Specification
40  o SMPTE 429-3-2006 Track File Specification
41  o SMPTE 429-4-2006 JPEG 2000 for D-Cinema
42  o SMPTE 429-5-200X Timed Text Track File
43  o SMPTE 429-6-2006 Essence Encryption Specification
44  o SMPTE 429-10-200X Stereoscopic Image Track File
45  o SMPTE 330M - UMID
46  o SMPTE 336M - KLV
47  o SMPTE 377M - MXF
48  o SMPTE 390M - OP-Atom
49  o SMPTE 379M - Generic Container
50  o SMPTE 381M - MPEG2 picture
51  o SMPTE 422M - JPEG 2000 picture
52  o SMPTE 382M - WAV/PCM sound
53  o IETF RFC 2104 - HMAC/SHA1
54  o NIST FIPS 197 - AES (Rijndael)
55
56 The following use cases are supported by the library:
57
58  o Write a plaintext MPEG2 Video Elementary Stream to a plaintext ASDCP file
59  o Write a plaintext MPEG2 Video Elementary Stream to a ciphertext ASDCP file
60  o Read a plaintext MPEG2 Video Elementary Stream from a plaintext ASDCP file
61  o Read a plaintext MPEG2 Video Elementary Stream from a ciphertext ASDCP file
62  o Read a ciphertext MPEG2 Video Elementary Stream from a ciphertext ASDCP file
63  o Write one or more plaintext JPEG 2000 codestreams to a plaintext ASDCP file
64  o Write one or more plaintext JPEG 2000 codestreams to a ciphertext ASDCP file
65  o Read one or more plaintext JPEG 2000 codestreams from a plaintext ASDCP file
66  o Read one or more plaintext JPEG 2000 codestreams from a ciphertext ASDCP file
67  o Read one or more ciphertext JPEG 2000 codestreams from a ciphertext ASDCP file
68  o Write one or more plaintext JPEG 2000 stereoscopic codestream pairs to a plaintext ASDCP file
69  o Write one or more plaintext JPEG 2000 stereoscopic codestream pairs to a ciphertext ASDCP file
70  o Read one or more plaintext JPEG 2000 stereoscopic codestream pairs from a plaintext ASDCP file
71  o Read one or more plaintext JPEG 2000 stereoscopic codestream pairs from a ciphertext ASDCP file
72  o Read one or more ciphertext JPEG 2000 stereoscopic codestream pairs from a ciphertext ASDCP file
73  o Write one or more plaintext PCM audio streams to a plaintext ASDCP file
74  o Write one or more plaintext PCM audio streams to a ciphertext ASDCP file
75  o Read one or more plaintext PCM audio streams from a plaintext ASDCP file
76  o Read one or more plaintext PCM audio streams from a ciphertext ASDCP file
77  o Read one or more ciphertext PCM audio streams from a ciphertext ASDCP file
78  o Read header metadata from an ASDCP file
79
80 This project depends upon the following libraries:
81  - OpenSSL http://www.openssl.org/
82  - Expat http://expat.sourceforge.net/ (optional)
83
84 */
85
86 #ifndef _AS_DCP_H_
87 #define _AS_DCP_H_
88
89 #include <KM_error.h>
90 #include <stdio.h>
91 #include <stdarg.h>
92 #include <math.h>
93 #include <iostream>
94 #include <string>
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   // The version number consists of three segments: major, API minor, and
150   // implementation minor. Whenever a change is made to AS_DCP.h, the API minor
151   // version will increment. Changes made to the internal implementation will
152   // result in the incrementing of the implementation minor version.
153
154   // For example, if asdcplib version 1.0.0 were modified to accomodate changes
155   // in file format, and if no changes were made to AS_DCP.h, the new version would be
156   // 1.0.1. If changes were also required in AS_DCP.h, the new version would be 1.1.1.
157   const ui32_t VERSION_MAJOR = 1;
158   const ui32_t VERSION_APIMINOR = 3;
159   const ui32_t VERSION_IMPMINOR = 18;
160   const char* Version();
161
162   // UUIDs are passed around as strings of UUIDlen bytes
163   const ui32_t UUIDlen = 16;
164
165   // Encryption keys are passed around as strings of KeyLen bytes
166   const ui32_t KeyLen = 16;
167
168   //---------------------------------------------------------------------------------
169   // return values
170
171   using Kumu::Result_t;
172
173   using Kumu::RESULT_FALSE;
174   using Kumu::RESULT_OK;
175   using Kumu::RESULT_FAIL;
176   using Kumu::RESULT_PTR;
177   using Kumu::RESULT_NULL_STR;
178   using Kumu::RESULT_ALLOC;
179   using Kumu::RESULT_PARAM;
180   using Kumu::RESULT_SMALLBUF;
181   using Kumu::RESULT_INIT;
182   using Kumu::RESULT_NOT_FOUND;
183   using Kumu::RESULT_NO_PERM;
184   using Kumu::RESULT_FILEOPEN;
185   using Kumu::RESULT_BADSEEK;
186   using Kumu::RESULT_READFAIL;
187   using Kumu::RESULT_WRITEFAIL;
188   using Kumu::RESULT_STATE;
189   using Kumu::RESULT_ENDOFFILE;
190   using Kumu::RESULT_CONFIG;
191
192   const Kumu::Result_t RESULT_FORMAT     (-101, "The file format is not proper OP-Atom/AS-DCP.");
193   const Kumu::Result_t RESULT_RAW_ESS    (-102, "Unknown raw essence file type.");
194   const Kumu::Result_t RESULT_RAW_FORMAT (-103, "Raw essence format invalid.");
195   const Kumu::Result_t RESULT_RANGE      (-104, "Frame number out of range.");
196   const Kumu::Result_t RESULT_CRYPT_CTX  (-105, "AESEncContext required when writing to encrypted file.");
197   const Kumu::Result_t RESULT_LARGE_PTO  (-106, "Plaintext offset exceeds frame buffer size.");
198   const Kumu::Result_t RESULT_CAPEXTMEM  (-107, "Cannot resize externally allocated memory.");
199   const Kumu::Result_t RESULT_CHECKFAIL  (-108, "The check value did not decrypt correctly.");
200   const Kumu::Result_t RESULT_HMACFAIL   (-109, "HMAC authentication failure.");
201   const Kumu::Result_t RESULT_HMAC_CTX   (-110, "HMAC context required.");
202   const Kumu::Result_t RESULT_CRYPT_INIT (-111, "Error initializing block cipher context.");
203   const Kumu::Result_t RESULT_EMPTY_FB   (-112, "Empty frame buffer.");
204   const Kumu::Result_t RESULT_KLV_CODING (-113, "KLV coding error.");
205   const Kumu::Result_t RESULT_SPHASE     (-114, "Stereoscopic phase mismatch.");
206   const Kumu::Result_t RESULT_SFORMAT    (-115, "Rate mismatch, file may contain stereoscopic essence.");
207
208   //---------------------------------------------------------------------------------
209   // file identification
210
211   // The file accessors in this library implement a bounded set of essence types.
212   // This list will be expanded when support for new types is added to the library.
213   enum EssenceType_t {
214     ESS_UNKNOWN,     // the file is not a supported AS-DCP essence container
215     ESS_MPEG2_VES,   // the file contains an MPEG video elementary stream
216     ESS_JPEG_2000,   // the file contains one or more JPEG 2000 codestreams
217     ESS_PCM_24b_48k, // the file contains one or more PCM audio pairs
218     ESS_PCM_24b_96k, // the file contains one or more PCM audio pairs
219     ESS_TIMED_TEXT,  // the file contains an XML timed text document and one or more resources
220     ESS_JPEG_2000_S, // the file contains one or more JPEG 2000 codestream pairs (stereoscopic)
221   };
222
223   // Determine the type of essence contained in the given MXF file. RESULT_OK
224   // is returned if the file is successfully opened and contains a valid MXF
225   // stream. If there is an error, the result code will indicate the reason.
226   Result_t EssenceType(const char* filename, EssenceType_t& type);
227
228   // Determine the type of essence contained in the given raw file. RESULT_OK
229   // is returned if the file is successfully opened and contains a known
230   // stream type. If there is an error, the result code will indicate the reason.
231   Result_t RawEssenceType(const char* filename, EssenceType_t& type);
232
233
234   //---------------------------------------------------------------------------------
235   // base types
236
237   // A simple container for rational numbers.
238   class Rational
239   {
240   public:
241     i32_t Numerator;
242     i32_t Denominator;
243
244     Rational() : Numerator(0), Denominator(0) {}
245     Rational(i32_t n, i32_t d) : Numerator(n), Denominator(d) {}
246
247     inline double Quotient() const {
248       return (double)Numerator / (double)Denominator;
249     }
250
251     inline bool operator==(const Rational& rhs) const {
252       return ( rhs.Numerator == Numerator && rhs.Denominator == Denominator );
253     }
254
255     inline bool operator!=(const Rational& rhs) const {
256       return ( rhs.Numerator != Numerator || rhs.Denominator != Denominator );
257     }
258   };
259
260   // common edit rates, use these instead of hard coded constants
261   const Rational EditRate_24(24,1);
262   const Rational EditRate_23_98(24000,1001); // Not a DCI-compliant value!
263   const Rational EditRate_48(48,1);
264   const Rational SampleRate_48k(48000,1);
265   const Rational SampleRate_96k(96000,1);
266
267   // Non-reference counting container for internal member objects.
268   // Please do not use this class for any other purpose.
269   template <class T>
270     class mem_ptr
271     {
272       T* m_p; // the thing we point to
273       mem_ptr(T&);
274
275     public:
276       mem_ptr() : m_p(0) {}
277       mem_ptr(T* p) : m_p(p) {}
278       ~mem_ptr() { delete m_p; }
279
280       inline T&   operator*()  const { return *m_p; }
281       inline T*   operator->() const { return m_p; }
282       inline      operator T*()const { return m_p; }
283       inline const mem_ptr<T>& operator=(T* p) { set(p); return *this; }
284       inline T*   set(T* p)          { delete m_p; m_p = p; return m_p; }
285       inline T*   get()        const { return m_p; }
286       inline void release()          { m_p = 0; }
287       inline bool empty()      const { return m_p == 0; }
288     };
289
290
291   //---------------------------------------------------------------------------------
292   // WriterInfo class - encapsulates writer identification details used for
293   // OpenWrite() calls.  Replace these values at runtime to identify your product.
294   //
295   // MXF files use SMPTE Universal Labels to identify data items. The set of Labels
296   // in a file is determined by the MXF Operational Pattern and any constraining
297   // documentation. There are currently two flavors of AS-DCP file in use: MXF Interop
298   // and SMPTE. The two differ only in the values of two labels:
299   //
300   //   OP Atom     / Interop : 06 0e 2b 34 04 01 01 01  0d 01 02 01 10 00 00 00
301   //   OP Atom     / SMPTE   : 06 0e 2b 34 04 01 01 02  0d 01 02 01 10 00 00 00
302   // and 
303   //   EKLV Packet / Interop : 06 0e 2b 34 02 04 01 07  0d 01 03 01 02 7e 01 00
304   //   EKLV Packet / SMPTE   : 06 0e 2b 34 02 04 01 01  0d 01 03 01 02 7e 01 00
305   //
306   // asdcplib will read any (otherwise valid) file which has any combination of the
307   // above values. When writing files, MXF Interop labels are used by default. To
308   // write a file containing SMPTE labels, replace the default label set value in
309   // the WriterInfo before calling OpenWrite()
310   //
311   enum LabelSet_t
312   {
313     LS_MXF_UNKNOWN,
314     LS_MXF_INTEROP,
315     LS_MXF_SMPTE
316   };
317
318   //
319   struct WriterInfo
320   {
321     byte_t      ProductUUID[UUIDlen];
322     byte_t      AssetUUID[UUIDlen];
323     byte_t      ContextID[UUIDlen];
324     byte_t      CryptographicKeyID[UUIDlen];
325     bool        EncryptedEssence; // true if essence data is (or is going to be) encrypted
326     bool        UsesHMAC;         // true if HMAC exists or is to be calculated
327     std::string ProductVersion;
328     std::string CompanyName;
329     std::string ProductName;
330     LabelSet_t  LabelSetType;
331
332     WriterInfo() : EncryptedEssence(false), UsesHMAC(false), LabelSetType(LS_MXF_INTEROP)
333     {
334       static byte_t default_ProductUUID_Data[UUIDlen] = {
335         0x43, 0x05, 0x9a, 0x1d, 0x04, 0x32, 0x41, 0x01,
336         0xb8, 0x3f, 0x73, 0x68, 0x15, 0xac, 0xf3, 0x1d };
337       
338       memcpy(ProductUUID, default_ProductUUID_Data, UUIDlen);
339       memset(AssetUUID, 0, UUIDlen);
340       memset(ContextID, 0, UUIDlen);
341       memset(CryptographicKeyID, 0, UUIDlen);
342
343       ProductVersion = "Unreleased ";
344       ProductVersion += Version();
345       CompanyName = "DCI";
346       ProductName = "asdcplib";
347     }
348   };
349
350   // Print WriterInfo to stream, stderr by default.
351   void WriterInfoDump(const WriterInfo&, FILE* = 0);
352
353   //---------------------------------------------------------------------------------
354   // cryptographic support
355
356   // The following classes define interfaces to Rijndael contexts having the following properties:
357   //  o 16 byte key
358   //  o CBC mode with 16 byte block size
359   const ui32_t CBC_KEY_SIZE = 16;
360   const ui32_t CBC_BLOCK_SIZE = 16;
361   const ui32_t HMAC_SIZE = 20;
362
363   //
364   class AESEncContext
365     {
366       class h__AESContext;
367       mem_ptr<h__AESContext> m_Context;
368       ASDCP_NO_COPY_CONSTRUCT(AESEncContext);
369
370     public:
371       AESEncContext();
372       ~AESEncContext();
373
374       // Initializes Rijndael CBC encryption context.
375       // Returns error if the key argument is NULL.
376       Result_t InitKey(const byte_t* key);
377       
378       // Initializes 16 byte CBC Initialization Vector. This operation may be performed
379       // any number of times for a given key.
380       // Returns error if the i_vec argument is NULL.
381       Result_t SetIVec(const byte_t* i_vec);
382       Result_t GetIVec(byte_t* i_vec) const;
383
384       // Encrypt a block of data. The block size must be a multiple of CBC_BLOCK_SIZE.
385       // Returns error if either argument is NULL.
386       Result_t EncryptBlock(const byte_t* pt_buf, byte_t* ct_buf, ui32_t block_size);
387     };
388
389   //
390   class AESDecContext
391     {
392       class h__AESContext;
393       mem_ptr<h__AESContext> m_Context;
394       ASDCP_NO_COPY_CONSTRUCT(AESDecContext);
395
396     public:
397       AESDecContext();
398       ~AESDecContext();
399
400       // Initializes Rijndael CBC decryption context.
401       // Returns error if the key argument is NULL.
402       Result_t InitKey(const byte_t* key);
403
404       // Initializes 16 byte CBC Initialization Vector. This operation may be performed
405       // any number of times for a given key.
406       // Returns error if the i_vec argument is NULL.
407       Result_t SetIVec(const byte_t* i_vec);
408
409       // Decrypt a block of data. The block size must be a multiple of CBC_BLOCK_SIZE.
410       // Returns error if either argument is NULL.
411       Result_t DecryptBlock(const byte_t* ct_buf, byte_t* pt_buf, ui32_t block_size);
412     };
413
414   //
415   class HMACContext
416     {
417       class h__HMACContext;
418       mem_ptr<h__HMACContext> m_Context;
419       ASDCP_NO_COPY_CONSTRUCT(HMACContext);
420
421     public:
422       HMACContext();
423       ~HMACContext();
424
425       // Initializes HMAC context. The key argument must point to a binary
426       // key that is CBC_KEY_SIZE bytes in length. Returns error if the key
427       // argument is NULL.
428       Result_t InitKey(const byte_t* key, LabelSet_t);
429
430       // Reset internal state, allows repeated cycles of Update -> Finalize
431       void Reset();
432
433       // Add data to the digest. Returns error if the key argument is NULL or
434       // if the digest has been finalized.
435       Result_t Update(const byte_t* buf, ui32_t buf_len);
436
437       // Finalize digest.  Returns error if the digest has already been finalized.
438       Result_t Finalize();
439
440       // Writes HMAC value to given buffer. buf must point to a writable area of
441       // memory that is at least HMAC_SIZE bytes in length. Returns error if the
442       // buf argument is NULL or if the digest has not been finalized.
443       Result_t GetHMACValue(byte_t* buf) const;
444
445       // Tests the given value against the finalized value in the object. buf must
446       // point to a readable area of memory that is at least HMAC_SIZE bytes in length.
447       // Returns error if the buf argument is NULL or if the values do ot match.
448       Result_t TestHMACValue(const byte_t* buf) const;
449     };
450
451   //---------------------------------------------------------------------------------
452   // frame buffer base class
453   //
454   // The supported essence types are stored using per-frame KLV packetization. The
455   // following class implements essence-neutral functionality for managing a buffer
456   // containing a frame of essence.
457
458   class FrameBuffer
459     {
460       ASDCP_NO_COPY_CONSTRUCT(FrameBuffer);
461
462     protected:
463       byte_t* m_Data;          // pointer to memory area containing frame data
464       ui32_t  m_Capacity;      // size of memory area pointed to by m_Data
465       bool    m_OwnMem;        // if false, m_Data points to externally allocated memory
466       ui32_t  m_Size;          // size of frame data in memory area pointed to by m_Data
467       ui32_t  m_FrameNumber;   // delivery-order frame number
468
469       // It is possible to read raw ciphertext from an encrypted AS-DCP file.
470       // After reading an encrypted AS-DCP file in raw mode, the frame buffer will
471       // contain the encrypted source value portion of the Encrypted Triplet, followed
472       // by the integrity pack, if it exists.
473       // The buffer will begin with the IV and CheckValue, followed by encrypted essence
474       // and optional integrity pack
475       // The SourceLength and PlaintextOffset values from the packet will be held in the
476       // following variables:
477       ui32_t  m_SourceLength;       // plaintext length (delivered plaintext+decrypted ciphertext)
478       ui32_t  m_PlaintextOffset;    // offset to first byte of ciphertext
479
480      public:
481       FrameBuffer();
482       virtual ~FrameBuffer();
483
484       // Instructs the object to use an externally allocated buffer. The external
485       // buffer will not be cleaned up by the frame buffer when it exits.
486       // Call with (0,0) to revert to internally allocated buffer.
487       // Returns error if the buf_addr argument is NULL and buf_size is non-zero.
488       Result_t SetData(byte_t* buf_addr, ui32_t buf_size);
489
490       // Sets the size of the internally allocate buffer. Returns RESULT_CAPEXTMEM
491       // if the object is using an externally allocated buffer via SetData();
492       // Resets content size to zero.
493       Result_t Capacity(ui32_t cap);
494
495       // returns the size of the buffer
496       inline ui32_t  Capacity() const { return m_Capacity; }
497
498       // returns a const pointer to the essence data
499       inline const byte_t* RoData() const { return m_Data; }
500
501       // returns a non-const pointer to the essence data
502       inline byte_t* Data() { return m_Data; }
503
504       // set the size of the buffer's contents
505       inline ui32_t  Size(ui32_t size) { return m_Size = size; }
506
507       // returns the size of the buffer's contents
508       inline ui32_t  Size() const { return m_Size; }
509
510       // Sets the absolute frame number of this frame in the file in delivery order.
511       inline void    FrameNumber(ui32_t num) { m_FrameNumber = num; }
512
513       // Returns the absolute frame number of this frame in the file in delivery order.
514       inline ui32_t  FrameNumber() const { return m_FrameNumber; }
515
516       // Sets the length of the plaintext essence data
517       inline void    SourceLength(ui32_t len) { m_SourceLength = len; }
518
519       // When this value is 0 (zero), the buffer contains only plaintext. When it is
520       // non-zero, the buffer contains raw ciphertext and the return value is the length
521       // of the original plaintext.
522       inline ui32_t  SourceLength() const { return m_SourceLength; }
523
524       // Sets the offset into the buffer at which encrypted data begins
525       inline void    PlaintextOffset(ui32_t ofst) { m_PlaintextOffset = ofst; }
526
527       // Returns offset into buffer of first byte of ciphertext.
528       inline ui32_t  PlaintextOffset() const { return m_PlaintextOffset; }
529     };
530
531
532   //---------------------------------------------------------------------------------
533   // MPEG2 video elementary stream support
534
535   //
536   namespace MPEG2
537     {
538       // MPEG picture coding type
539       enum FrameType_t {
540         FRAME_U = 0x00, // Unknown
541         FRAME_I = 0x01, // I-Frame
542         FRAME_P = 0x02, // P-Frame
543         FRAME_B = 0x03  // B-Frame
544       };
545
546       // convert FrameType_t to char
547       inline char FrameTypeChar(FrameType_t type)
548         {
549           switch ( type )
550             {
551             case FRAME_I: return 'I';
552             case FRAME_B: return 'B';
553             case FRAME_P: return 'P';
554             default: return 'U';
555             }
556         }
557
558       // Structure represents the metadata elements in the file header's
559       // MPEG2VideoDescriptor object.
560       struct VideoDescriptor
561         {
562           Rational EditRate;                // 
563           ui32_t   FrameRate;               // 
564           Rational SampleRate;              // 
565           ui8_t    FrameLayout;             // 
566           ui32_t   StoredWidth;             // 
567           ui32_t   StoredHeight;            // 
568           Rational AspectRatio;             // 
569           ui32_t   ComponentDepth;          // 
570           ui32_t   HorizontalSubsampling;   // 
571           ui32_t   VerticalSubsampling;     // 
572           ui8_t    ColorSiting;             // 
573           ui8_t    CodedContentType;        // 
574           bool     LowDelay;                // 
575           ui32_t   BitRate;                 // 
576           ui8_t    ProfileAndLevel;         // 
577           ui32_t   ContainerDuration;       // 
578       };
579
580       // Print VideoDescriptor to stream, stderr by default.
581       void VideoDescriptorDump(const VideoDescriptor&, FILE* = 0);
582
583       // A container for MPEG frame data.
584       class FrameBuffer : public ASDCP::FrameBuffer
585         {
586           ASDCP_NO_COPY_CONSTRUCT(FrameBuffer); // TODO: should have copy construct
587
588         protected:
589           FrameType_t m_FrameType;
590           ui8_t       m_TemporalOffset;
591           bool        m_ClosedGOP;
592           bool        m_GOPStart;
593
594         public:
595           FrameBuffer() :
596             m_FrameType(FRAME_U), m_TemporalOffset(0),
597             m_ClosedGOP(false), m_GOPStart(false) {}
598
599           FrameBuffer(ui32_t size) :
600             m_FrameType(FRAME_U), m_TemporalOffset(0),
601             m_ClosedGOP(false), m_GOPStart(false)
602             {
603               Capacity(size);
604             }
605             
606           virtual ~FrameBuffer() {}
607
608           // Sets the MPEG frame type of the picture data in the frame buffer.
609           inline void FrameType(FrameType_t type) { m_FrameType = type; }
610
611           // Returns the MPEG frame type of the picture data in the frame buffer.
612           inline FrameType_t FrameType() const { return m_FrameType; }
613
614           // Sets the MPEG temporal offset of the picture data in the frame buffer.
615           inline void TemporalOffset(ui8_t offset) { m_TemporalOffset = offset; }
616
617           // Returns the MPEG temporal offset of the picture data in the frame buffer.
618           inline ui8_t TemporalOffset() const { return m_TemporalOffset; }
619
620           // Sets the MPEG GOP 'start' attribute for the frame buffer.
621           inline void GOPStart(bool start) { m_GOPStart = start; }
622
623           // True if the frame in the buffer is the first in the GOP (in transport order)
624           inline bool GOPStart() const { return m_GOPStart; }
625
626           // Sets the MPEG GOP 'closed' attribute for the frame buffer.
627           inline void ClosedGOP(bool closed) { m_ClosedGOP = closed; }
628
629           // Returns true if the frame in the buffer is from a closed GOP, false if
630           // the frame is from an open GOP.  Always returns false unless GOPStart()
631           // returns true.
632           inline bool ClosedGOP() const { return m_ClosedGOP; }
633
634           // Print object state to stream, include n bytes of frame data if indicated.
635           // Default stream is stderr.
636           void    Dump(FILE* = 0, ui32_t dump_len = 0) const;
637         };
638
639
640       // An object which opens and reads an MPEG2 Video Elementary Stream file.  The call to
641       // OpenRead() reads metadata from the file and populates an internal VideoDescriptor object.
642       // Each subsequent call to ReadFrame() reads exactly one frame from the stream into the
643       // given FrameBuffer object.
644       class Parser
645         {
646           class h__Parser;
647           mem_ptr<h__Parser> m_Parser;
648           ASDCP_NO_COPY_CONSTRUCT(Parser);
649
650         public:
651           Parser();
652           virtual ~Parser();
653
654           // Opens the stream for reading, parses enough data to provide a complete
655           // set of stream metadata for the MXFWriter below.
656           Result_t OpenRead(const char* filename) const;
657
658           // Fill a VideoDescriptor struct with the values from the file's header.
659           // Returns RESULT_INIT if the file is not open.
660           Result_t FillVideoDescriptor(VideoDescriptor&) const;
661
662           // Rewind the stream to the beginning.
663           Result_t Reset() const;
664
665           // Reads the next sequential frame in the input file and places it in the
666           // frame buffer. Fails if the buffer is too small or the stream is empty.
667           // The frame buffer's PlaintextOffset parameter will be set to the first
668           // data byte of the first slice. Set this value to zero if you want
669           // encrypted headers.
670           Result_t ReadFrame(FrameBuffer&) const;
671         };
672
673       // A class which creates and writes MPEG frame data to an AS-DCP format MXF file.
674       // Not yet implemented
675       class MXFWriter
676         {
677           class h__Writer;
678           mem_ptr<h__Writer> m_Writer;
679           ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
680
681         public:
682           MXFWriter();
683           virtual ~MXFWriter();
684
685           // Open the file for writing. The file must not exist. Returns error if
686           // the operation cannot be completed or if nonsensical data is discovered
687           // in the essence descriptor.
688           Result_t OpenWrite(const char* filename, const WriterInfo&,
689                              const VideoDescriptor&, ui32_t HeaderSize = 16384);
690
691           // Writes a frame of essence to the MXF file. If the optional AESEncContext
692           // argument is present, the essence is encrypted prior to writing.
693           // Fails if the file is not open, is finalized, or an operating system
694           // error occurs.
695           Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
696
697           // Closes the MXF file, writing the index and revised header.
698           Result_t Finalize();
699         };
700
701       // A class which reads MPEG frame data from an AS-DCP format MXF file.
702       class MXFReader
703         {
704           class h__Reader;
705           mem_ptr<h__Reader> m_Reader;
706           ASDCP_NO_COPY_CONSTRUCT(MXFReader);
707
708         public:
709           MXFReader();
710           virtual ~MXFReader();
711
712           // Open the file for reading. The file must exist. Returns error if the
713           // operation cannot be completed.
714           Result_t OpenRead(const char* filename) const;
715
716           // Returns RESULT_INIT if the file is not open.
717           Result_t Close() const;
718
719           // Fill a VideoDescriptor struct with the values from the file's header.
720           // Returns RESULT_INIT if the file is not open.
721           Result_t FillVideoDescriptor(VideoDescriptor&) const;
722
723           // Fill a WriterInfo struct with the values from the file's header.
724           // Returns RESULT_INIT if the file is not open.
725           Result_t FillWriterInfo(WriterInfo&) const;
726
727           // Reads a frame of essence from the MXF file. If the optional AESEncContext
728           // argument is present, the essence is decrypted after reading. If the MXF
729           // file is encrypted and the AESDecContext argument is NULL, the frame buffer
730           // will contain the ciphertext frame data. If the HMACContext argument is
731           // not NULL, the HMAC will be calculated (if the file supports it).
732           // Returns RESULT_INIT if the file is not open, failure if the frame number is
733           // out of range, or if optional decrypt or HAMC operations fail.
734           Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
735
736           // Calculates the first frame in transport order of the GOP in which the requested
737           // frame is located.  Calls ReadFrame() to fetch the frame at the calculated position.
738           // Returns RESULT_INIT if the file is not open.
739           Result_t ReadFrameGOPStart(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
740
741           // Calculates the first frame in transport order of the GOP in which the requested
742           // frame is located.  Sets key_frame_number to the number of the frame at the calculated position.
743           // Returns RESULT_INIT if the file is not open.
744           Result_t FindFrameGOPStart(ui32_t frame_number, ui32_t& key_frame_number) const;
745
746           // Returns the type of the frame at the given position.
747           // Returns RESULT_INIT if the file is not open or RESULT_RANGE if the index is out of range.
748           Result_t FrameType(ui32_t frame_number, FrameType_t&) const;
749
750           // Print debugging information to stream
751           void     DumpHeaderMetadata(FILE* = 0) const;
752           void     DumpIndex(FILE* = 0) const;
753         };
754     } // namespace MPEG2
755
756   //
757   namespace PCM
758     {
759       struct AudioDescriptor
760         {
761           Rational SampleRate;         // rate of frame wrapping
762           Rational AudioSamplingRate;  // rate of audio sample
763           ui32_t   Locked;             // 
764           ui32_t   ChannelCount;       // number of channels
765           ui32_t   QuantizationBits;   // number of bits per single-channel sample
766           ui32_t   BlockAlign;         // number of bytes ber sample, all channels
767           ui32_t   AvgBps;             // 
768           ui32_t   LinkedTrackID;      // 
769           ui32_t   ContainerDuration;  // number of frames
770       };
771
772       // Print debugging information to stream (stderr default)
773       void   AudioDescriptorDump(const AudioDescriptor&, FILE* = 0);
774
775       // Returns size in bytes of a single sample of data described by ADesc
776       inline ui32_t CalcSampleSize(const AudioDescriptor& ADesc)
777         {
778           return (ADesc.QuantizationBits / 8) * ADesc.ChannelCount;
779         }
780
781       // Returns number of samples per frame of data described by ADesc
782       inline ui32_t CalcSamplesPerFrame(const AudioDescriptor& ADesc)
783         {
784           double tmpd = ADesc.AudioSamplingRate.Quotient() / ADesc.SampleRate.Quotient();
785           return (ui32_t)ceil(tmpd);
786         }
787
788       // Returns the size in bytes of a frame of data described by ADesc
789       inline ui32_t CalcFrameBufferSize(const AudioDescriptor& ADesc)
790         {
791           return CalcSampleSize(ADesc) * CalcSamplesPerFrame(ADesc);
792         }
793
794       //
795       class FrameBuffer : public ASDCP::FrameBuffer
796         {
797         public:
798           FrameBuffer() {}
799           FrameBuffer(ui32_t size) { Capacity(size); }
800           virtual ~FrameBuffer() {}
801         
802           // Print debugging information to stream (stderr default)
803           void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
804         };
805
806       // An object which opens and reads a WAV file.  The call to OpenRead() reads metadata from
807       // the file and populates an internal AudioDescriptor object. Each subsequent call to
808       // ReadFrame() reads exactly one frame from the stream into the given FrameBuffer object.
809       // A "frame" is either 2000 or 2002 samples, depending upon the value of PictureRate.
810       class WAVParser
811         {
812           class h__WAVParser;
813           mem_ptr<h__WAVParser> m_Parser;
814           ASDCP_NO_COPY_CONSTRUCT(WAVParser);
815
816         public:
817           WAVParser();
818           virtual ~WAVParser();
819
820           // Opens the stream for reading, parses enough data to provide a complete
821           // set of stream metadata for the MXFWriter below. PictureRate controls
822           // ther frame rate for the MXF frame wrapping option.
823           Result_t OpenRead(const char* filename, const Rational& PictureRate) const;
824
825           // Fill an AudioDescriptor struct with the values from the file's header.
826           // Returns RESULT_INIT if the file is not open.
827           Result_t FillAudioDescriptor(AudioDescriptor&) const;
828
829           // Rewind the stream to the beginning.
830           Result_t Reset() const;
831
832           // Reads the next sequential frame in the input file and places it in the
833           // frame buffer. Fails if the buffer is too small or the stream is empty.
834           Result_t ReadFrame(FrameBuffer&) const;
835         };
836
837
838       //
839       class MXFWriter
840         {
841           class h__Writer;
842           mem_ptr<h__Writer> m_Writer;
843           ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
844
845         public:
846           MXFWriter();
847           virtual ~MXFWriter();
848
849           // Open the file for writing. The file must not exist. Returns error if
850           // the operation cannot be completed or if nonsensical data is discovered
851           // in the essence descriptor.
852           Result_t OpenWrite(const char* filename, const WriterInfo&,
853                              const AudioDescriptor&, ui32_t HeaderSize = 16384);
854
855           // Writes a frame of essence to the MXF file. If the optional AESEncContext
856           // argument is present, the essence is encrypted prior to writing.
857           // Fails if the file is not open, is finalized, or an operating system
858           // error occurs.
859           Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
860
861           // Closes the MXF file, writing the index and revised header.
862           Result_t Finalize();
863         };
864
865       //
866       class MXFReader
867         {
868           class h__Reader;
869           mem_ptr<h__Reader> m_Reader;
870           ASDCP_NO_COPY_CONSTRUCT(MXFReader);
871
872         public:
873           MXFReader();
874           virtual ~MXFReader();
875
876           // Open the file for reading. The file must exist. Returns error if the
877           // operation cannot be completed.
878           Result_t OpenRead(const char* filename) const;
879
880           // Returns RESULT_INIT if the file is not open.
881           Result_t Close() const;
882
883           // Fill an AudioDescriptor struct with the values from the file's header.
884           // Returns RESULT_INIT if the file is not open.
885           Result_t FillAudioDescriptor(AudioDescriptor&) const;
886
887           // Fill a WriterInfo struct with the values from the file's header.
888           // Returns RESULT_INIT if the file is not open.
889           Result_t FillWriterInfo(WriterInfo&) const;
890
891           // Reads a frame of essence from the MXF file. If the optional AESEncContext
892           // argument is present, the essence is decrypted after reading. If the MXF
893           // file is encrypted and the AESDecContext argument is NULL, the frame buffer
894           // will contain the ciphertext frame data. If the HMACContext argument is
895           // not NULL, the HMAC will be calculated (if the file supports it).
896           // Returns RESULT_INIT if the file is not open, failure if the frame number is
897           // out of range, or if optional decrypt or HAMC operations fail.
898           Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
899
900           // Print debugging information to stream
901           void     DumpHeaderMetadata(FILE* = 0) const;
902           void     DumpIndex(FILE* = 0) const;
903         };
904     } // namespace PCM
905
906   //
907   namespace JP2K
908     {
909       const ui32_t MaxComponents = 3;
910       const ui32_t MaxPrecincts = 32; // ISO 15444-1 Annex A.6.1
911       const ui32_t MaxDefaults = 256; // made up
912
913 #pragma pack(1)
914       struct ImageComponent_t  // ISO 15444-1 Annex A.5.1
915       {
916         ui8_t Ssize;
917         ui8_t XRsize;
918         ui8_t YRsize;
919       };
920
921       struct CodingStyleDefault_t // ISO 15444-1 Annex A.6.1
922       {
923         ui8_t   Scod;
924
925         struct
926         {
927           ui8_t  ProgressionOrder;
928           ui8_t  NumberOfLayers[sizeof(ui16_t)];
929           ui8_t  MultiCompTransform;
930         } SGcod;
931         
932         struct
933         {
934           ui8_t  DecompositionLevels;
935           ui8_t  CodeblockWidth;
936           ui8_t  CodeblockHeight;
937           ui8_t  CodeblockStyle;
938           ui8_t  Transformation;
939           ui8_t  PrecinctSize[MaxPrecincts];
940         } SPcod;
941       };
942
943       struct QuantizationDefault_t // ISO 15444-1 Annex A.6.4
944       {
945         ui8_t  Sqcd;
946         ui8_t  SPqcd[MaxDefaults];
947         ui8_t  SPqcdLength;
948       };
949 #pragma pack()
950
951       struct PictureDescriptor
952       {
953         Rational       EditRate;
954         ui32_t         ContainerDuration;
955         Rational       SampleRate;
956         ui32_t         StoredWidth;
957         ui32_t         StoredHeight;
958         Rational       AspectRatio;
959         ui16_t         Rsize;
960         ui32_t         Xsize;
961         ui32_t         Ysize;
962         ui32_t         XOsize;
963         ui32_t         YOsize;
964         ui32_t         XTsize;
965         ui32_t         YTsize;
966         ui32_t         XTOsize;
967         ui32_t         YTOsize;
968         ui16_t         Csize;
969         ImageComponent_t      ImageComponents[MaxComponents];
970         CodingStyleDefault_t  CodingStyleDefault;
971         QuantizationDefault_t QuantizationDefault;
972       };
973
974       // Print debugging information to stream (stderr default)
975       void   PictureDescriptorDump(const PictureDescriptor&, FILE* = 0);
976
977       //
978       class FrameBuffer : public ASDCP::FrameBuffer
979         {
980         public:
981           FrameBuffer() {}
982           FrameBuffer(ui32_t size) { Capacity(size); }
983           virtual ~FrameBuffer() {}
984         
985           // Print debugging information to stream (stderr default)
986           void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
987         };
988
989
990       // An object which opens and reads a JPEG 2000 codestream file.  The file is expected
991       // to contain exactly one complete frame of picture essence as an unwrapped (raw)
992       // ISO/IEC 15444 codestream.
993       class CodestreamParser
994         {
995           class h__CodestreamParser;
996           mem_ptr<h__CodestreamParser> m_Parser;
997           ASDCP_NO_COPY_CONSTRUCT(CodestreamParser);
998
999         public:
1000           CodestreamParser();
1001           virtual ~CodestreamParser();
1002
1003           // Opens a file for reading, parses enough data to provide a complete
1004           // set of stream metadata for the MXFWriter below.
1005           // The frame buffer's PlaintextOffset parameter will be set to the first
1006           // byte of the data segment. Set this value to zero if you want
1007           // encrypted headers.
1008           Result_t OpenReadFrame(const char* filename, FrameBuffer&) const;
1009
1010           // Fill a PictureDescriptor struct with the values from the file's codestream.
1011           // Returns RESULT_INIT if the file is not open.
1012           Result_t FillPictureDescriptor(PictureDescriptor&) const;
1013         };
1014
1015       // Parses the data in the frame buffer to fill in the picture descriptor. Copies
1016       // the offset of the image data into start_of_data. Returns error if the parser fails.
1017       Result_t ParseMetadataIntoDesc(const FrameBuffer&, PictureDescriptor&, byte_t* start_of_data = 0);
1018
1019       // An object which reads a sequence of files containing JPEG 2000 pictures.
1020       class SequenceParser
1021         {
1022           class h__SequenceParser;
1023           mem_ptr<h__SequenceParser> m_Parser;
1024           ASDCP_NO_COPY_CONSTRUCT(SequenceParser);
1025
1026         public:
1027           SequenceParser();
1028           virtual ~SequenceParser();
1029
1030           // Opens a directory for reading.  The directory is expected to contain one or
1031           // more files, each containing the codestream for exactly one picture. The
1032           // files must be named such that the frames are in temporal order when sorted
1033           // alphabetically by filename. The parser will automatically parse enough data
1034           // from the first file to provide a complete set of stream metadata for the
1035           // MXFWriter below.  If the "pedantic" parameter is given and is true, the
1036           // parser will check the metadata for each codestream and fail if a 
1037           // mismatch is detected.
1038           Result_t OpenRead(const char* filename, bool pedantic = false) const;
1039
1040           // Fill a PictureDescriptor struct with the values from the first file's codestream.
1041           // Returns RESULT_INIT if the directory is not open.
1042           Result_t FillPictureDescriptor(PictureDescriptor&) const;
1043
1044           // Rewind the directory to the beginning.
1045           Result_t Reset() const;
1046
1047           // Reads the next sequential frame in the directory and places it in the
1048           // frame buffer. Fails if the buffer is too small or the direcdtory
1049           // contains no more files.
1050           // The frame buffer's PlaintextOffset parameter will be set to the first
1051           // byte of the data segment. Set this value to zero if you want
1052           // encrypted headers.
1053           Result_t ReadFrame(FrameBuffer&) const;
1054         };
1055
1056
1057       //
1058       class MXFWriter
1059         {
1060           class h__Writer;
1061           mem_ptr<h__Writer> m_Writer;
1062           ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
1063
1064         public:
1065           MXFWriter();
1066           virtual ~MXFWriter();
1067
1068           // Open the file for writing. The file must not exist. Returns error if
1069           // the operation cannot be completed or if nonsensical data is discovered
1070           // in the essence descriptor.
1071           Result_t OpenWrite(const char* filename, const WriterInfo&,
1072                              const PictureDescriptor&, ui32_t HeaderSize = 16384);
1073
1074           // Writes a frame of essence to the MXF file. If the optional AESEncContext
1075           // argument is present, the essence is encrypted prior to writing.
1076           // Fails if the file is not open, is finalized, or an operating system
1077           // error occurs.
1078           Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
1079
1080           // Closes the MXF file, writing the index and revised header.
1081           Result_t Finalize();
1082         };
1083
1084       //
1085       class MXFReader
1086         {
1087           class h__Reader;
1088           mem_ptr<h__Reader> m_Reader;
1089           ASDCP_NO_COPY_CONSTRUCT(MXFReader);
1090
1091         public:
1092           MXFReader();
1093           virtual ~MXFReader();
1094
1095           // Open the file for reading. The file must exist. Returns error if the
1096           // operation cannot be completed.
1097           Result_t OpenRead(const char* filename) const;
1098
1099           // Returns RESULT_INIT if the file is not open.
1100           Result_t Close() const;
1101
1102           // Fill an AudioDescriptor struct with the values from the file's header.
1103           // Returns RESULT_INIT if the file is not open.
1104           Result_t FillPictureDescriptor(PictureDescriptor&) const;
1105
1106           // Fill a WriterInfo struct with the values from the file's header.
1107           // Returns RESULT_INIT if the file is not open.
1108           Result_t FillWriterInfo(WriterInfo&) const;
1109
1110           // Reads a frame of essence from the MXF file. If the optional AESEncContext
1111           // argument is present, the essence is decrypted after reading. If the MXF
1112           // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1113           // will contain the ciphertext frame data. If the HMACContext argument is
1114           // not NULL, the HMAC will be calculated (if the file supports it).
1115           // Returns RESULT_INIT if the file is not open, failure if the frame number is
1116           // out of range, or if optional decrypt or HAMC operations fail.
1117           Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1118
1119           // Print debugging information to stream
1120           void     DumpHeaderMetadata(FILE* = 0) const;
1121           void     DumpIndex(FILE* = 0) const;
1122         };
1123
1124
1125       // Stereoscopic Image support
1126       //
1127
1128       enum StereoscopicPhase_t
1129       {
1130         SP_LEFT,
1131         SP_RIGHT
1132       };
1133       
1134       struct SFrameBuffer
1135       {
1136         JP2K::FrameBuffer Left;
1137         JP2K::FrameBuffer Right;
1138
1139         SFrameBuffer(ui32_t size) {
1140           Left.Capacity(size);
1141           Right.Capacity(size);
1142         }
1143       };
1144
1145       class MXFSWriter
1146       {
1147           class h__SWriter;
1148           mem_ptr<h__SWriter> m_Writer;
1149           ASDCP_NO_COPY_CONSTRUCT(MXFSWriter);
1150
1151         public:
1152           MXFSWriter();
1153           virtual ~MXFSWriter();
1154
1155           // Open the file for writing. The file must not exist. Returns error if
1156           // the operation cannot be completed or if nonsensical data is discovered
1157           // in the essence descriptor.
1158           Result_t OpenWrite(const char* filename, const WriterInfo&,
1159                              const PictureDescriptor&, ui32_t HeaderSize = 16384);
1160
1161           // Writes a pair of frames of essence to the MXF file. If the optional AESEncContext
1162           // argument is present, the essence is encrypted prior to writing.
1163           // Fails if the file is not open, is finalized, or an operating system
1164           // error occurs.
1165           Result_t WriteFrame(const SFrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
1166
1167           // Writes a frame of essence to the MXF file. If the optional AESEncContext
1168           // argument is present, the essence is encrypted prior to writing.
1169           // Fails if the file is not open, is finalized, or an operating system
1170           // error occurs. Frames must be written in the proper phase (L-R-L-R),
1171           // RESULT_SPHASE will be returned if phase is reversed. The first frame
1172           // written must be left eye.
1173           Result_t WriteFrame(const FrameBuffer&, StereoscopicPhase_t phase,
1174                               AESEncContext* = 0, HMACContext* = 0);
1175
1176           // Closes the MXF file, writing the index and revised header.  Returns
1177           // RESULT_SPHASE if WriteFrame was called an odd number of times.
1178           Result_t Finalize();
1179         };
1180
1181       //
1182       class MXFSReader
1183         {
1184           class h__SReader;
1185           mem_ptr<h__SReader> m_Reader;
1186           ASDCP_NO_COPY_CONSTRUCT(MXFSReader);
1187
1188         public:
1189           MXFSReader();
1190           virtual ~MXFSReader();
1191
1192           // Open the file for reading. The file must exist. Returns error if the
1193           // operation cannot be completed.
1194           Result_t OpenRead(const char* filename) const;
1195
1196           // Returns RESULT_INIT if the file is not open.
1197           Result_t Close() const;
1198
1199           // Fill an AudioDescriptor struct with the values from the file's header.
1200           // Returns RESULT_INIT if the file is not open.
1201           Result_t FillPictureDescriptor(PictureDescriptor&) const;
1202
1203           // Fill a WriterInfo struct with the values from the file's header.
1204           // Returns RESULT_INIT if the file is not open.
1205           Result_t FillWriterInfo(WriterInfo&) const;
1206
1207           // Reads a pair of frames of essence from the MXF file. If the optional AESEncContext
1208           // argument is present, the essence is decrypted after reading. If the MXF
1209           // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1210           // will contain the ciphertext frame data. If the HMACContext argument is
1211           // not NULL, the HMAC will be calculated (if the file supports it).
1212           // Returns RESULT_INIT if the file is not open, failure if the frame number is
1213           // out of range, or if optional decrypt or HAMC operations fail.
1214           Result_t ReadFrame(ui32_t frame_number, SFrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1215
1216           // Reads a frame of essence from the MXF file. If the optional AESEncContext
1217           // argument is present, the essence is decrypted after reading. If the MXF
1218           // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1219           // will contain the ciphertext frame data. If the HMACContext argument is
1220           // not NULL, the HMAC will be calculated (if the file supports it).
1221           // Returns RESULT_INIT if the file is not open, failure if the frame number is
1222           // out of range, or if optional decrypt or HAMC operations fail.
1223           Result_t ReadFrame(ui32_t frame_number, StereoscopicPhase_t phase,
1224                              FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1225
1226           // Print debugging information to stream
1227           void     DumpHeaderMetadata(FILE* = 0) const;
1228           void     DumpIndex(FILE* = 0) const;
1229         };
1230     } // namespace JP2K
1231
1232   //
1233   namespace TimedText
1234     {
1235       enum MIMEType_t { MT_BIN, MT_PNG, MT_OPENTYPE };
1236
1237       struct TimedTextResourceDescriptor
1238       {
1239         byte_t      ResourceID[UUIDlen];
1240         MIMEType_t  Type;
1241
1242         TimedTextResourceDescriptor() : Type(MT_BIN) {}
1243       };
1244
1245       typedef std::list<TimedTextResourceDescriptor> ResourceList_t;
1246
1247       struct TimedTextDescriptor
1248       {
1249         Rational       EditRate;                // 
1250         ui32_t         ContainerDuration;
1251         byte_t         AssetID[UUIDlen];
1252         std::string    NamespaceName;
1253         std::string    EncodingName;
1254         ResourceList_t ResourceList;
1255
1256       TimedTextDescriptor() : ContainerDuration(0), EncodingName("UTF-8") {} // D-Cinema format is always UTF-8
1257       };
1258
1259       // Print debugging information to stream (stderr default)
1260       void   DescriptorDump(const TimedTextDescriptor&, FILE* = 0);
1261
1262       //
1263       class FrameBuffer : public ASDCP::FrameBuffer
1264       {
1265         ASDCP_NO_COPY_CONSTRUCT(FrameBuffer); // TODO: should have copy construct
1266
1267       protected:
1268         byte_t      m_AssetID[UUIDlen];
1269         std::string m_MIMEType;
1270
1271       public:
1272         FrameBuffer() { memset(m_AssetID, 0, UUIDlen); }
1273         FrameBuffer(ui32_t size) { Capacity(size); memset(m_AssetID, 0, UUIDlen); }
1274         virtual ~FrameBuffer() {}
1275         
1276         inline const byte_t* AssetID() const { return m_AssetID; }
1277         inline void          AssetID(const byte_t* buf) { memcpy(m_AssetID, buf, UUIDlen); }
1278         inline const char*   MIMEType() const { return m_MIMEType.c_str(); }
1279         inline void          MIMEType(const std::string& s) { m_MIMEType = s; }
1280
1281         // Print debugging information to stream (stderr default)
1282         void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
1283       };
1284
1285       //
1286       class IResourceResolver
1287       {
1288       public:
1289         virtual ~IResourceResolver() {}
1290         virtual Result_t ResolveRID(const byte_t* uuid, FrameBuffer&) const = 0; // return data for RID
1291       };
1292
1293       //
1294       class DCSubtitleParser
1295         {
1296           class h__SubtitleParser;
1297           mem_ptr<h__SubtitleParser> m_Parser;
1298           ASDCP_NO_COPY_CONSTRUCT(DCSubtitleParser);
1299
1300         public:
1301           DCSubtitleParser();
1302           virtual ~DCSubtitleParser();
1303
1304           // Opens the XML file for reading, parse data to provide a complete
1305           // set of stream metadata for the MXFWriter below.
1306           Result_t OpenRead(const char* filename) const;
1307
1308           // Fill a TimedTextDescriptor struct with the values from the file's contents.
1309           // Returns RESULT_INIT if the file is not open.
1310           Result_t FillDescriptor(TimedTextDescriptor&) const;
1311
1312           // Reads the complete Timed Text Resource into the given string.
1313           Result_t ReadTimedTextResource(std::string&) const;
1314
1315           // Reads the Ancillary Resource having the given ID. Fails if the buffer
1316           // is too small or the resource does not exist. The optional Resolver
1317           // argument can be provided which will be used to retrieve the resource
1318           // having a particulat UUID. If a Resolver is not supplied, the default
1319           // internal resolver will return the contents of the file having the UUID
1320           // as the filename. The filename must exist in the same directory as the
1321           // XML file opened with OpenRead().
1322           Result_t ReadAncillaryResource(const byte_t* uuid, FrameBuffer&,
1323                                          const IResourceResolver* Resolver = 0) const;
1324         };
1325
1326       //
1327       class MXFWriter
1328         {
1329           class h__Writer;
1330           mem_ptr<h__Writer> m_Writer;
1331           ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
1332
1333         public:
1334           MXFWriter();
1335           virtual ~MXFWriter();
1336
1337           // Open the file for writing. The file must not exist. Returns error if
1338           // the operation cannot be completed or if nonsensical data is discovered
1339           // in the essence descriptor.
1340           Result_t OpenWrite(const char* filename, const WriterInfo&,
1341                              const TimedTextDescriptor&, ui32_t HeaderSize = 16384);
1342
1343           // Writes the Timed-Text Resource to the MXF file. The file must be UTF-8
1344           // encoded. If the optional AESEncContext argument is present, the essence
1345           // is encrypted prior to writing. Fails if the file is not open, is finalized,
1346           // or an operating system error occurs.
1347           // This method may only be called once, and it must be called before any
1348           // call to WriteAncillaryResource(). RESULT_STATE will be returned if these
1349           // conditions are not met.
1350           Result_t WriteTimedTextResource(const std::string& XMLDoc, AESEncContext* = 0, HMACContext* = 0);
1351
1352           // Writes an Ancillary Resource to the MXF file. If the optional AESEncContext
1353           // argument is present, the essence is encrypted prior to writing.
1354           // Fails if the file is not open, is finalized, or an operating system
1355           // error occurs. RESULT_STATE will be returned if the method is called before
1356           // WriteTimedTextResource()
1357           Result_t WriteAncillaryResource(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
1358
1359           // Closes the MXF file, writing the index and revised header.
1360           Result_t Finalize();
1361         };
1362
1363       //
1364       class MXFReader
1365         {
1366           class h__Reader;
1367           mem_ptr<h__Reader> m_Reader;
1368           ASDCP_NO_COPY_CONSTRUCT(MXFReader);
1369
1370         public:
1371           MXFReader();
1372           virtual ~MXFReader();
1373
1374           // Open the file for reading. The file must exist. Returns error if the
1375           // operation cannot be completed.
1376           Result_t OpenRead(const char* filename) const;
1377
1378           // Returns RESULT_INIT if the file is not open.
1379           Result_t Close() const;
1380
1381           // Fill a TimedTextDescriptor struct with the values from the file's header.
1382           // Returns RESULT_INIT if the file is not open.
1383           Result_t FillDescriptor(TimedTextDescriptor&) const;
1384
1385           // Fill a WriterInfo struct with the values from the file's header.
1386           // Returns RESULT_INIT if the file is not open.
1387           Result_t FillWriterInfo(WriterInfo&) const;
1388
1389           // Reads the complete Timed Text Resource into the given string. Fails if the resource
1390           // is encrypted and AESDecContext is NULL (use the following method to retrieve the
1391           // raw ciphertet block).
1392           Result_t ReadTimedTextResource(std::string&, AESDecContext* = 0, HMACContext* = 0) const;
1393
1394           // Reads the complete Timed Text Resource from the MXF file. If the optional AESEncContext
1395           // argument is present, the resource 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 ReadTimedTextResource(FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1402
1403           // Reads the timed-text resource having the given UUID from the MXF file. If the
1404           // optional AESEncContext argument is present, the resource is decrypted after
1405           // reading. If the MXF file is encrypted and the AESDecContext argument is NULL,
1406           // the frame buffer will contain the ciphertext frame data. If the HMACContext
1407           // argument is 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 ReadAncillaryResource(const byte_t* uuid, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1411
1412           // Print debugging information to stream
1413           void     DumpHeaderMetadata(FILE* = 0) const;
1414           void     DumpIndex(FILE* = 0) const;
1415         };
1416     } // namespace TimedText
1417
1418
1419 } // namespace ASDCP
1420
1421
1422 #endif // _AS_DCP_H_
1423
1424 //
1425 // end AS_DCP.h
1426 //