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