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