kumu merge
[asdcplib.git] / src / AS_DCP.h
1 /*
2 Copyright (c) 2003-2006, John Hurst
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8 1. Redistributions of source code must retain the above copyright
9    notice, this list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright
11    notice, this list of conditions and the following disclaimer in the
12    documentation and/or other materials provided with the distribution.
13 3. The name of the author may not be used to endorse or promote products
14    derived from this software without specific prior written permission.
15
16 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 /*! \file    AS_DCP.h
28     \version $Id$       
29     \brief   AS-DCP library, public interface
30
31 The asdcplib library is a set of wrapper objects that offer simplified
32 access to files conforming to the file formats proposed by the SMPTE
33 D-Cinema packaging working group DC28.20.  The file format, labeled
34 AS-DCP, is described in series of separate documents which include but
35 may not be limited to:
36
37  o AS-DCP Track File Specification
38  o AS-DCP Track File Essence Encryption Specification
39  o AS-DCP Operational Constraints Specification
40  o SMPTE 330M - UMID
41  o SMPTE 336M - KLV
42  o SMPTE 377M - MXF
43  o SMPTE 390M - OP-Atom
44  o SMPTE 379M - Generic Container
45  o SMPTE 381M - MPEG2 picture
46  o SMPTE XXXM - JPEG 2000 picture
47  o SMPTE 382M - WAV/PCM sound
48  o IETF RFC 2104 - HMAC/SHA1
49  o NIST FIPS 197 - AES (Rijndael)
50
51 The following use cases are supported by the library:
52
53  o Write a plaintext MPEG2 Video Elementary Stream to a plaintext ASDCP file
54  o Write a plaintext MPEG2 Video Elementary Stream to a ciphertext ASDCP file
55  o Read a plaintext MPEG2 Video Elementary Stream from a plaintext ASDCP file
56  o Read a plaintext MPEG2 Video Elementary Stream from a ciphertext ASDCP file
57  o Read a ciphertext MPEG2 Video Elementary Stream from a ciphertext ASDCP file
58  o Write one or more plaintext JPEG 2000 codestreams to a plaintext ASDCP file
59  o Write one or more plaintext JPEG 2000 codestreams to a ciphertext ASDCP file
60  o Read one or more plaintext JPEG 2000 codestreams from a plaintext ASDCP file
61  o Read one or more plaintext JPEG 2000 codestreams from a ciphertext ASDCP file
62  o Read one or more ciphertext JPEG 2000 codestreams from a ciphertext ASDCP file
63  o Write one or more plaintext PCM audio streams to a plaintext ASDCP file
64  o Write one or more plaintext PCM audio streams to a ciphertext ASDCP file
65  o Read one or more plaintext PCM audio streams from a plaintext ASDCP file
66  o Read one or more plaintext PCM audio streams from a ciphertext ASDCP file
67  o Read one or more ciphertext PCM audio streams from a ciphertext ASDCP file
68  o Read header metadata from an ASDCP file
69
70 This project depends upon the following library:
71  - OpenSSL http://www.openssl.org/
72
73 */
74
75 #ifndef _AS_DCP_H_
76 #define _AS_DCP_H_
77
78 #include <KM_error.h>
79 #include <stdio.h>
80 #include <stdarg.h>
81 #include <iostream>
82 #include <math.h>
83
84 //--------------------------------------------------------------------------------
85 // common integer types
86 // supply your own by defining ASDCP_NO_BASE_TYPES
87
88 #ifndef ASDCP_NO_BASE_TYPES
89 typedef unsigned char  byte_t;
90 typedef char           i8_t;
91 typedef unsigned char  ui8_t;
92 typedef short          i16_t;
93 typedef unsigned short ui16_t;
94 typedef int            i32_t;
95 typedef unsigned int   ui32_t;
96 #endif
97
98
99 //--------------------------------------------------------------------------------
100 // convenience macros
101
102 // Convenience macros for managing return values in predicates
103 #define ASDCP_SUCCESS(v) (((v) < 0) ? 0 : 1)
104 #define ASDCP_FAILURE(v) (((v) < 0) ? 1 : 0)
105
106
107 // Returns RESULT_PTR if the given argument is NULL.
108 // See Result_t below for an explanation of RESULT_* symbols.
109 #define ASDCP_TEST_NULL(p) \
110   if ( (p) == 0  ) { \
111     return ASDCP::RESULT_PTR; \
112   }
113
114 // Returns RESULT_PTR if the given argument is NULL. See Result_t
115 // below for an explanation of RESULT_* symbols. It then assumes
116 // that the argument is a pointer to a string and returns
117 // RESULT_NULL_STR if the first character is '\0'.
118 //
119 #define ASDCP_TEST_NULL_STR(p) \
120   ASDCP_TEST_NULL(p); \
121   if ( (p)[0] == '\0' ) { \
122     return ASDCP::RESULT_NULL_STR; \
123   }
124
125 // Produces copy constructor boilerplate. Allows convenient private
126 // declatarion of copy constructors to prevent the compiler from
127 // silently manufacturing default methods.
128 #define ASDCP_NO_COPY_CONSTRUCT(T)   \
129           T(const T&); \
130           T& operator=(const T&)
131
132 //--------------------------------------------------------------------------------
133 // All library components are defined in the namespace ASDCP
134 //
135 namespace ASDCP {
136   // The version number consists of three segments: major, API minor, and
137   // implementation minor. Whenever a change is made to AS_DCP.h, the API minor
138   // version will increment. Changes made to the internal implementation will
139   // result in the incrementing of the implementation minor version.
140
141   // For example, if asdcplib version 1.0.0 were modified to accomodate changes
142   // in file format, and if no changes were made to AS_DCP.h, the new version would be
143   // 1.0.1. If changes were also required in AS_DCP.h, the new version would be 1.1.1.
144   const ui32_t VERSION_MAJOR = 1;
145   const ui32_t VERSION_APIMINOR = 1;
146   const ui32_t VERSION_IMPMINOR = 8;
147   const char* Version();
148
149   // UUIDs are passed around as strings of UUIDlen bytes
150   const ui32_t UUIDlen = 16;
151
152   // Encryption keys are passed around as strings of KeyLen bytes
153   const ui32_t KeyLen = 16;
154
155   //---------------------------------------------------------------------------------
156   // return values
157
158   using Kumu::Result_t;
159
160   using Kumu::RESULT_FALSE;
161   using Kumu::RESULT_OK;
162   using Kumu::RESULT_FAIL;
163   using Kumu::RESULT_PTR;
164   using Kumu::RESULT_NULL_STR;
165   using Kumu::RESULT_ALLOC;
166   using Kumu::RESULT_PARAM;
167   using Kumu::RESULT_SMALLBUF;
168   using Kumu::RESULT_INIT;
169   using Kumu::RESULT_NOT_FOUND;
170   using Kumu::RESULT_NO_PERM;
171   using Kumu::RESULT_FILEOPEN;
172   using Kumu::RESULT_BADSEEK;
173   using Kumu::RESULT_READFAIL;
174   using Kumu::RESULT_WRITEFAIL;
175   using Kumu::RESULT_STATE;
176   using Kumu::RESULT_ENDOFFILE;
177   using Kumu::RESULT_CONFIG;
178
179   const Kumu::Result_t RESULT_FORMAT     (-101, "The file format is not proper OP-Atom/AS-DCP.");
180   const Kumu::Result_t RESULT_RAW_ESS    (-102, "Unknown raw essence file type.");
181   const Kumu::Result_t RESULT_RAW_FORMAT (-103, "Raw essence format invalid.");
182   const Kumu::Result_t RESULT_RANGE      (-104, "Frame number out of range.");
183   const Kumu::Result_t RESULT_CRYPT_CTX  (-105, "AESEncContext required when writing to encrypted file.");
184   const Kumu::Result_t RESULT_LARGE_PTO  (-106, "Plaintext offset exceeds frame buffer size.");
185   const Kumu::Result_t RESULT_CAPEXTMEM  (-107, "Cannot resize externally allocated memory.");
186   const Kumu::Result_t RESULT_CHECKFAIL  (-108, "The check value did not decrypt correctly.");
187   const Kumu::Result_t RESULT_HMACFAIL   (-109, "HMAC authentication failure.");
188   const Kumu::Result_t RESULT_HMAC_CTX   (-110, "HMAC context required.");
189   const Kumu::Result_t RESULT_CRYPT_INIT (-111, "Error initializing block cipher context.");
190   const Kumu::Result_t RESULT_EMPTY_FB   (-112, "Empty frame buffer.");
191   const Kumu::Result_t RESULT_KLV_CODING (-113, "KLV coding error.");
192
193   //---------------------------------------------------------------------------------
194   // file identification
195
196   // The file accessors in this library implement a bounded set of essence types.
197   // This list will be expanded when support for new types is added to the library.
198   enum EssenceType_t {
199     ESS_UNKNOWN,     // the file is not a supported AS-DCP essence container
200     ESS_MPEG2_VES,   // the file contains an MPEG video elementary stream
201     ESS_JPEG_2000,   // the file contains one or more JPEG 2000 codestreams
202     ESS_PCM_24b_48k, // the file contains one or more PCM audio pairs
203     ESS_PCM_24b_96k, // the file contains one or more PCM audio pairs
204     ESS_UTF8_XML,    // the file contains UTF-8 encoded XML data
205     ESS_PNG          // the file contains a Portable Network Graphics image
206   };
207
208   // Determine the type of essence contained in the given MXF file. RESULT_OK
209   // is returned if the file is successfully opened and contains a valid MXF
210   // stream. If there is an error, the result code will indicate the reason.
211   Result_t EssenceType(const char* filename, EssenceType_t& type);
212
213   // Determine the type of essence contained in the given raw file. RESULT_OK
214   // is returned if the file is successfully opened and contains a known
215   // stream type. If there is an error, the result code will indicate the reason.
216   Result_t RawEssenceType(const char* filename, EssenceType_t& type);
217
218
219   //---------------------------------------------------------------------------------
220   // base types
221
222   // A simple container for rational numbers.
223   class Rational
224   {
225   public:
226     i32_t Numerator;
227     i32_t Denominator;
228
229     Rational() : Numerator(0), Denominator(0) {}
230     Rational(i32_t n, i32_t d) : Numerator(n), Denominator(d) {}
231
232     inline double Quotient() const {
233       return (double)Numerator / (double)Denominator;
234     }
235
236     inline bool operator==(const Rational& rhs) const {
237       return ( rhs.Numerator == Numerator && rhs.Denominator == Denominator );
238     }
239
240     inline bool operator!=(const Rational& rhs) const {
241       return ( rhs.Numerator != Numerator || rhs.Denominator != Denominator );
242     }
243   };
244
245   // common edit rates, use these instead of hard coded constants
246   const Rational EditRate_24(24,1);
247   const Rational EditRate_23_98(24000,1001);
248   const Rational EditRate_48(48,1);
249   const Rational SampleRate_48k(48000,1);
250
251   // Non-reference counting container for internal member objects.
252   // Please do not use this class for any other purpose.
253   template <class T>
254     class mem_ptr
255     {
256       T* m_p; // the thing we point to
257       mem_ptr(T&);
258
259     public:
260       mem_ptr() : m_p(0) {}
261       mem_ptr(T* p) : m_p(p) {}
262       ~mem_ptr() { delete m_p; }
263
264       inline T&   operator*()  const { return *m_p; }
265       inline T*   operator->() const { return m_p; }
266       inline      operator T*()const { return m_p; }
267       inline const mem_ptr<T>& operator=(T* p) { set(p); return *this; }
268       inline T*   set(T* p)          { delete m_p; m_p = p; return m_p; }
269       inline T*   get()        const { return m_p; }
270       inline void release()          { m_p = 0; }
271       inline bool empty()      const { return m_p == 0; }
272     };
273
274
275   //---------------------------------------------------------------------------------
276   // WriterInfo class - encapsulates writer identification details used for
277   // OpenWrite() calls.  Replace these values at runtime to identify your product.
278   //
279   // MXF files use SMPTE Universal Labels to identify data items. The set of Labels
280   // in a file is determined by the MXF Operational Pattern and any constraining
281   // documentation. There are currently two flavors of AS-DCP file in use: MXF Interop
282   // and SMPTE. The two differ only in the values of two labels:
283   //
284   //   OP Atom     / Interop : 06 0e 2b 34 04 01 01 01  0d 01 02 01 10 00 00 00
285   //   OP Atom     / SMPTE   : 06 0e 2b 34 04 01 01 02  0d 01 02 01 10 00 00 00
286   // and 
287   //   EKLV Packet / Interop : 06 0e 2b 34 02 04 01 07  0d 01 03 01 02 7e 01 00
288   //   EKLV Packet / SMPTE   : 06 0e 2b 34 02 04 01 01  0d 01 03 01 02 7e 01 00
289   //
290   // asdcplib will read any (otherwise valid) file which has any combination of the
291   // above values. When writing files, MXF Interop labels are used by default. To
292   // write a file containing SMPTE labels, replace the default label set value in
293   // the WriterInfo before calling OpenWrite()
294   //
295   enum LabelSet_t
296   {
297     LS_MXF_UNKNOWN,
298     LS_MXF_INTEROP,
299     LS_MXF_SMPTE
300   };
301
302   //
303   struct WriterInfo
304   {
305     byte_t      ProductUUID[UUIDlen];
306     byte_t      AssetUUID[UUIDlen];
307     byte_t      ContextID[UUIDlen];
308     byte_t      CryptographicKeyID[UUIDlen];
309     bool        EncryptedEssence; // true if essence data is (or is going to be) encrypted
310     bool        UsesHMAC;         // true if HMAC exists or is to be calculated
311     std::string ProductVersion;
312     std::string CompanyName;
313     std::string ProductName;
314     LabelSet_t  LabelSetType;
315
316     WriterInfo() : EncryptedEssence(false), UsesHMAC(false), LabelSetType(LS_MXF_INTEROP)
317     {
318       static byte_t default_ProductUUID_Data[UUIDlen] = {
319         0x43, 0x05, 0x9a, 0x1d, 0x04, 0x32, 0x41, 0x01,
320         0xb8, 0x3f, 0x73, 0x68, 0x15, 0xac, 0xf3, 0x1d };
321       
322       memcpy(ProductUUID, default_ProductUUID_Data, UUIDlen);
323       memset(AssetUUID, 0, UUIDlen);
324       memset(ContextID, 0, UUIDlen);
325       memset(CryptographicKeyID, 0, UUIDlen);
326
327       ProductVersion = "Unreleased ";
328       ProductVersion += Version();
329       CompanyName = "DCI";
330       ProductName = "asdcplib";
331     }
332   };
333
334   // Print WriterInfo to stream, stderr by default.
335   void WriterInfoDump(const WriterInfo&, FILE* = 0);
336
337   //---------------------------------------------------------------------------------
338   // cryptographic support
339
340   // The following classes define interfaces to Rijndael contexts having the following properties:
341   //  o 16 byte key
342   //  o CBC mode with 16 byte block size
343   const ui32_t CBC_KEY_SIZE = 16;
344   const ui32_t CBC_BLOCK_SIZE = 16;
345   const ui32_t HMAC_SIZE = 20;
346
347   //
348   class AESEncContext
349     {
350       class h__AESContext;
351       mem_ptr<h__AESContext> m_Context;
352       ASDCP_NO_COPY_CONSTRUCT(AESEncContext);
353
354     public:
355       AESEncContext();
356       ~AESEncContext();
357
358       // Initializes Rijndael CBC encryption context.
359       // Returns error if the key argument is NULL.
360       Result_t InitKey(const byte_t* key);
361       
362       // Initializes 16 byte CBC Initialization Vector. This operation may be performed
363       // any number of times for a given key.
364       // Returns error if the i_vec argument is NULL.
365       Result_t SetIVec(const byte_t* i_vec);
366       Result_t GetIVec(byte_t* i_vec) const;
367
368       // Encrypt a block of data. The block size must be a multiple of CBC_BLOCK_SIZE.
369       // Returns error if either argument is NULL.
370       Result_t EncryptBlock(const byte_t* pt_buf, byte_t* ct_buf, ui32_t block_size);
371     };
372
373   //
374   class AESDecContext
375     {
376       class h__AESContext;
377       mem_ptr<h__AESContext> m_Context;
378       ASDCP_NO_COPY_CONSTRUCT(AESDecContext);
379
380     public:
381       AESDecContext();
382       ~AESDecContext();
383
384       // Initializes Rijndael CBC decryption context.
385       // Returns error if the key argument is NULL.
386       Result_t InitKey(const byte_t* key);
387
388       // Initializes 16 byte CBC Initialization Vector. This operation may be performed
389       // any number of times for a given key.
390       // Returns error if the i_vec argument is NULL.
391       Result_t SetIVec(const byte_t* i_vec);
392
393       // Decrypt a block of data. The block size must be a multiple of CBC_BLOCK_SIZE.
394       // Returns error if either argument is NULL.
395       Result_t DecryptBlock(const byte_t* ct_buf, byte_t* pt_buf, ui32_t block_size);
396     };
397
398   //
399   class HMACContext
400     {
401       class h__HMACContext;
402       mem_ptr<h__HMACContext> m_Context;
403       ASDCP_NO_COPY_CONSTRUCT(HMACContext);
404
405     public:
406       HMACContext();
407       ~HMACContext();
408
409       // Initializes HMAC context. The key argument must point to a binary
410       // key that is CBC_KEY_SIZE bytes in length. Returns error if the key
411       // argument is NULL.
412       Result_t InitKey(const byte_t* key, LabelSet_t = LS_MXF_INTEROP);
413
414       // Reset internal state, allows repeated cycles of Update -> Finalize
415       void Reset();
416
417       // Add data to the digest. Returns error if the key argument is NULL or
418       // if the digest has been finalized.
419       Result_t Update(const byte_t* buf, ui32_t buf_len);
420
421       // Finalize digest.  Returns error if the digest has already been finalized.
422       Result_t Finalize();
423
424       // Writes HMAC value to given buffer. buf must point to a writable area of
425       // memory that is at least HMAC_SIZE bytes in length. Returns error if the
426       // buf argument is NULL or if the digest has not been finalized.
427       Result_t GetHMACValue(byte_t* buf) const;
428
429       // Tests the given value against the finalized value in the object. buf must
430       // point to a readable area of memory that is at least HMAC_SIZE bytes in length.
431       // Returns error if the buf argument is NULL or if the values do ot match.
432       Result_t TestHMACValue(const byte_t* buf) const;
433     };
434
435   //---------------------------------------------------------------------------------
436   // frame buffer base class
437   //
438   // The supported essence types are stored using per-frame KLV packetization. The
439   // following class implements essence-neutral functionality for managing a buffer
440   // containing a frame of essence.
441
442   class FrameBuffer
443     {
444       ASDCP_NO_COPY_CONSTRUCT(FrameBuffer);
445
446     protected:
447       byte_t* m_Data;          // pointer to memory area containing frame data
448       ui32_t  m_Capacity;      // size of memory area pointed to by m_Data
449       bool    m_OwnMem;        // if false, m_Data points to externally allocated memory
450       ui32_t  m_Size;          // size of frame data in memory area pointed to by m_Data
451       ui32_t  m_FrameNumber;   // delivery-order frame number
452
453       // It is possible to read raw ciphertext from an encrypted AS-DCP file.
454       // After reading an encrypted AS-DCP file in raw mode, the frame buffer will
455       // contain the encrypted source value portion of the Encrypted Triplet, followed
456       // by the integrity pack, if it exists.
457       // The buffer will begin with the IV and CheckValue, followed by encrypted essence
458       // and optional integrity pack
459       // The SourceLength and PlaintextOffset values from the packet will be held in the
460       // following variables:
461       ui32_t  m_SourceLength;       // plaintext length (delivered plaintext+decrypted ciphertext)
462       ui32_t  m_PlaintextOffset;    // offset to first byte of ciphertext
463
464      public:
465       FrameBuffer();
466       virtual ~FrameBuffer();
467
468       // Instructs the object to use an externally allocated buffer. The external
469       // buffer will not be cleaned up by the frame buffer when it exits.
470       // Call with (0,0) to revert to internally allocated buffer.
471       // Returns error if the buf_addr argument is NULL and buf_size is non-zero.
472       Result_t SetData(byte_t* buf_addr, ui32_t buf_size);
473
474       // Sets the size of the internally allocate buffer. Returns RESULT_CAPEXTMEM
475       // if the object is using an externally allocated buffer via SetData();
476       // Resets content size to zero.
477       Result_t Capacity(ui32_t cap);
478
479       // returns the size of the buffer
480       inline ui32_t  Capacity() const { return m_Capacity; }
481
482       // returns a const pointer to the essence data
483       inline const byte_t* RoData() const { return m_Data; }
484
485       // returns a non-const pointer to the essence data
486       inline byte_t* Data() { return m_Data; }
487
488       // set the size of the buffer's contents
489       inline ui32_t  Size(ui32_t size) { return m_Size = size; }
490
491       // returns the size of the buffer's contents
492       inline ui32_t  Size() const { return m_Size; }
493
494       // Sets the absolute frame number of this frame in the file in delivery order.
495       inline void    FrameNumber(ui32_t num) { m_FrameNumber = num; }
496
497       // Returns the absolute frame number of this frame in the file in delivery order.
498       inline ui32_t  FrameNumber() const { return m_FrameNumber; }
499
500       // Sets the length of the plaintext essence data
501       inline void    SourceLength(ui32_t len) { m_SourceLength = len; }
502
503       // When this value is 0 (zero), the buffer contains only plaintext. When it is
504       // non-zero, the buffer contains raw ciphertext and the return value is the length
505       // of the original plaintext.
506       inline ui32_t  SourceLength() const { return m_SourceLength; }
507
508       // Sets the offset into the buffer at which encrypted data begins
509       inline void    PlaintextOffset(ui32_t ofst) { m_PlaintextOffset = ofst; }
510
511       // Returns offset into buffer of first byte of ciphertext.
512       inline ui32_t  PlaintextOffset() const { return m_PlaintextOffset; }
513     };
514
515
516   //---------------------------------------------------------------------------------
517   // MPEG2 video elementary stream support
518
519   //
520   namespace MPEG2
521     {
522       // MPEG picture coding type
523       enum FrameType_t {
524         FRAME_U = 0x00, // Unknown
525         FRAME_I = 0x01, // I-Frame
526         FRAME_P = 0x02, // P-Frame
527         FRAME_B = 0x03  // B-Frame
528       };
529
530       // convert FrameType_t to char
531       inline char FrameTypeChar(FrameType_t type)
532         {
533           switch ( type )
534             {
535             case FRAME_I: return 'I';
536             case FRAME_B: return 'B';
537             case FRAME_P: return 'P';
538             default: return 'U';
539             }
540         }
541
542       // Structure represents the metadata elements in the file header's
543       // MPEG2VideoDescriptor object.
544       struct VideoDescriptor
545         {
546           Rational EditRate;                // 
547           ui32_t   FrameRate;               // 
548           Rational SampleRate;              // 
549           ui8_t    FrameLayout;             // 
550           ui32_t   StoredWidth;             // 
551           ui32_t   StoredHeight;            // 
552           Rational AspectRatio;             // 
553           ui32_t   ComponentDepth;          // 
554           ui32_t   HorizontalSubsampling;   // 
555           ui32_t   VerticalSubsampling;     // 
556           ui8_t    ColorSiting;             // 
557           ui8_t    CodedContentType;        // 
558           bool     LowDelay;                // 
559           ui32_t   BitRate;                 // 
560           ui8_t    ProfileAndLevel;         // 
561           ui32_t   ContainerDuration;       // 
562       };
563
564       // Print VideoDescriptor to stream, stderr by default.
565       void VideoDescriptorDump(const VideoDescriptor&, FILE* = 0);
566
567       // A container for MPEG frame data.
568       class FrameBuffer : public ASDCP::FrameBuffer
569         {
570           ASDCP_NO_COPY_CONSTRUCT(FrameBuffer); // TODO: should have copy construct
571
572         protected:
573           FrameType_t m_FrameType;
574           ui8_t       m_TemporalOffset;
575           bool        m_ClosedGOP;
576           bool        m_GOPStart;
577
578         public:
579           FrameBuffer() :
580             m_FrameType(FRAME_U), m_TemporalOffset(0),
581             m_ClosedGOP(false), m_GOPStart(false) {}
582
583           FrameBuffer(ui32_t size) :
584             m_FrameType(FRAME_U), m_TemporalOffset(0),
585             m_ClosedGOP(false), m_GOPStart(false)
586             {
587               Capacity(size);
588             }
589             
590           virtual ~FrameBuffer() {}
591
592           // Sets the MPEG frame type of the picture data in the frame buffer.
593           inline void FrameType(FrameType_t type) { m_FrameType = type; }
594
595           // Returns the MPEG frame type of the picture data in the frame buffer.
596           inline FrameType_t FrameType() const { return m_FrameType; }
597
598           // Sets the MPEG temporal offset of the picture data in the frame buffer.
599           inline void TemporalOffset(ui8_t offset) { m_TemporalOffset = offset; }
600
601           // Returns the MPEG temporal offset of the picture data in the frame buffer.
602           inline ui8_t TemporalOffset() const { return m_TemporalOffset; }
603
604           // Sets the MPEG GOP 'start' attribute for the frame buffer.
605           inline void GOPStart(bool start) { m_GOPStart = start; }
606
607           // True if the frame in the buffer is the first in the GOP (in transport order)
608           inline bool GOPStart() const { return m_GOPStart; }
609
610           // Sets the MPEG GOP 'closed' attribute for the frame buffer.
611           inline void ClosedGOP(bool closed) { m_ClosedGOP = closed; }
612
613           // Returns true if the frame in the buffer is from a closed GOP, false if
614           // the frame is from an open GOP.  Always returns false unless GOPStart()
615           // returns true.
616           inline bool ClosedGOP() const { return m_ClosedGOP; }
617
618           // Print object state to stream, include n bytes of frame data if indicated.
619           // Default stream is stderr.
620           void    Dump(FILE* = 0, ui32_t dump_len = 0) const;
621         };
622
623
624       // An object which opens and reads an MPEG2 Video Elementary Stream file.  The call to
625       // OpenRead() reads metadata from the file and populates an internal VideoDescriptor object.
626       // Each subsequent call to ReadFrame() reads exactly one frame from the stream into the
627       // given FrameBuffer object.
628       class Parser
629         {
630           class h__Parser;
631           mem_ptr<h__Parser> m_Parser;
632           ASDCP_NO_COPY_CONSTRUCT(Parser);
633
634         public:
635           Parser();
636           virtual ~Parser();
637
638           // Opens the stream for reading, parses enough data to provide a complete
639           // set of stream metadata for the MXFWriter below.
640           Result_t OpenRead(const char* filename) const;
641
642           // Fill a VideoDescriptor struct with the values from the file's header.
643           // Returns RESULT_INIT if the file is not open.
644           Result_t FillVideoDescriptor(VideoDescriptor&) const;
645
646           // Rewind the stream to the beginning.
647           Result_t Reset() const;
648
649           // Reads the next sequential frame in the input file and places it in the
650           // frame buffer. Fails if the buffer is too small or the stream is empty.
651           // The frame buffer's PlaintextOffset parameter will be set to the first
652           // data byte of the first slice. Set this value to zero if you want
653           // encrypted headers.
654           Result_t ReadFrame(FrameBuffer&) const;
655         };
656
657       // A class which creates and writes MPEG frame data to an AS-DCP format MXF file.
658       // Not yet implemented
659       class MXFWriter
660         {
661           class h__Writer;
662           mem_ptr<h__Writer> m_Writer;
663           ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
664
665         public:
666           MXFWriter();
667           virtual ~MXFWriter();
668
669           // Open the file for writing. The file must not exist. Returns error if
670           // the operation cannot be completed or if nonsensical data is discovered
671           // in the essence descriptor.
672           Result_t OpenWrite(const char* filename, const WriterInfo&,
673                              const VideoDescriptor&, ui32_t HeaderSize = 16384);
674
675           // Writes a frame of essence to the MXF file. If the optional AESEncContext
676           // argument is present, the essence is encrypted prior to writing.
677           // Fails if the file is not open, is finalized, or an operating system
678           // error occurs.
679           Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
680
681           // Closes the MXF file, writing the index and revised header.
682           Result_t Finalize();
683         };
684
685       // A class which reads MPEG frame data from an AS-DCP format MXF file.
686       class MXFReader
687         {
688           class h__Reader;
689           mem_ptr<h__Reader> m_Reader;
690           ASDCP_NO_COPY_CONSTRUCT(MXFReader);
691
692         public:
693           MXFReader();
694           virtual ~MXFReader();
695
696           // Open the file for reading. The file must exist. Returns error if the
697           // operation cannot be completed.
698           Result_t OpenRead(const char* filename) const;
699
700           // Returns RESULT_INIT if the file is not open.
701           Result_t Close() const;
702
703           // Fill a VideoDescriptor struct with the values from the file's header.
704           // Returns RESULT_INIT if the file is not open.
705           Result_t FillVideoDescriptor(VideoDescriptor&) const;
706
707           // Fill a WriterInfo struct with the values from the file's header.
708           // Returns RESULT_INIT if the file is not open.
709           Result_t FillWriterInfo(WriterInfo&) const;
710
711           // Reads a frame of essence from the MXF file. If the optional AESEncContext
712           // argument is present, the essence is decrypted after reading. If the MXF
713           // file is encrypted and the AESDecContext argument is NULL, the frame buffer
714           // will contain the ciphertext frame data. If the HMACContext argument is
715           // not NULL, the HMAC will be calculated (if the file supports it).
716           // Returns RESULT_INIT if the file is not open, failure if the frame number is
717           // out of range, or if optional decrypt or HAMC operations fail.
718           Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
719
720           // Calculates the first frame in transport order of the GOP in which the requested
721           // frame is located.  Calls ReadFrame() to fetch the frame at the calculated position.
722           // Returns RESULT_INIT if the file is not open.
723           Result_t ReadFrameGOPStart(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
724
725           // Calculates the first frame in transport order of the GOP in which the requested
726           // frame is located.  Sets key_frame_number to the number of the frame at the calculated position.
727           // Returns RESULT_INIT if the file is not open.
728           Result_t FindFrameGOPStart(ui32_t frame_number, ui32_t& key_frame_number) const;
729
730           // Returns the type of the frame at the given position.
731           // Returns RESULT_INIT if the file is not open or RESULT_RANGE if the index is out of range.
732           Result_t FrameType(ui32_t frame_number, FrameType_t&) const;
733
734           // Print debugging information to stream
735           void     DumpHeaderMetadata(FILE* = 0) const;
736           void     DumpIndex(FILE* = 0) const;
737         };
738     } // namespace MPEG2
739
740   //
741   namespace PCM
742     {
743       struct AudioDescriptor
744         {
745           Rational SampleRate;         // rate of frame wrapping
746           Rational AudioSamplingRate;  // rate of audio sample
747           ui32_t   Locked;             // 
748           ui32_t   ChannelCount;       // number of channels
749           ui32_t   QuantizationBits;   // number of bits per single-channel sample
750           ui32_t   BlockAlign;         // number of bytes ber sample, all channels
751           ui32_t   AvgBps;             // 
752           ui32_t   LinkedTrackID;      // 
753           ui32_t   ContainerDuration;  // number of frames
754       };
755
756       // Print debugging information to stream (stderr default)
757       void   AudioDescriptorDump(const AudioDescriptor&, FILE* = 0);
758
759       // Returns size in bytes of a single sample of data described by ADesc
760       inline ui32_t CalcSampleSize(const AudioDescriptor& ADesc)
761         {
762           return (ADesc.QuantizationBits / 8) * ADesc.ChannelCount;
763         }
764
765       // Returns number of samples per frame of data described by ADesc
766       inline ui32_t CalcSamplesPerFrame(const AudioDescriptor& ADesc)
767         {
768           double tmpd = ADesc.AudioSamplingRate.Quotient() / ADesc.SampleRate.Quotient();
769           return (ui32_t)ceil(tmpd);
770         }
771
772       // Returns the size in bytes of a frame of data described by ADesc
773       inline ui32_t CalcFrameBufferSize(const AudioDescriptor& ADesc)
774         {
775           return CalcSampleSize(ADesc) * CalcSamplesPerFrame(ADesc);
776         }
777
778       //
779       class FrameBuffer : public ASDCP::FrameBuffer
780         {
781         public:
782           FrameBuffer() {}
783           FrameBuffer(ui32_t size) { Capacity(size); }
784           virtual ~FrameBuffer() {}
785         
786           // Print debugging information to stream (stderr default)
787           void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
788         };
789
790       // An object which opens and reads a WAV file.  The call to OpenRead() reads metadata from
791       // the file and populates an internal AudioDescriptor object. Each subsequent call to
792       // ReadFrame() reads exactly one frame from the stream into the given FrameBuffer object.
793       // A "frame" is either 2000 or 2002 samples, depending upon the value of PictureRate.
794       class WAVParser
795         {
796           class h__WAVParser;
797           mem_ptr<h__WAVParser> m_Parser;
798           ASDCP_NO_COPY_CONSTRUCT(WAVParser);
799
800         public:
801           WAVParser();
802           virtual ~WAVParser();
803
804           // Opens the stream for reading, parses enough data to provide a complete
805           // set of stream metadata for the MXFWriter below. PictureRate controls
806           // ther frame rate for the MXF frame wrapping option.
807           Result_t OpenRead(const char* filename, const Rational& PictureRate) const;
808
809           // Fill an AudioDescriptor struct with the values from the file's header.
810           // Returns RESULT_INIT if the file is not open.
811           Result_t FillAudioDescriptor(AudioDescriptor&) const;
812
813           // Rewind the stream to the beginning.
814           Result_t Reset() const;
815
816           // Reads the next sequential frame in the input file and places it in the
817           // frame buffer. Fails if the buffer is too small or the stream is empty.
818           Result_t ReadFrame(FrameBuffer&) const;
819         };
820
821
822       //
823       class MXFWriter
824         {
825           class h__Writer;
826           mem_ptr<h__Writer> m_Writer;
827           ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
828
829         public:
830           MXFWriter();
831           virtual ~MXFWriter();
832
833           // Open the file for writing. The file must not exist. Returns error if
834           // the operation cannot be completed or if nonsensical data is discovered
835           // in the essence descriptor.
836           Result_t OpenWrite(const char* filename, const WriterInfo&,
837                              const AudioDescriptor&, ui32_t HeaderSize = 16384);
838
839           // Writes a frame of essence to the MXF file. If the optional AESEncContext
840           // argument is present, the essence is encrypted prior to writing.
841           // Fails if the file is not open, is finalized, or an operating system
842           // error occurs.
843           Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
844
845           // Closes the MXF file, writing the index and revised header.
846           Result_t Finalize();
847         };
848
849       //
850       class MXFReader
851         {
852           class h__Reader;
853           mem_ptr<h__Reader> m_Reader;
854           ASDCP_NO_COPY_CONSTRUCT(MXFReader);
855
856         public:
857           MXFReader();
858           virtual ~MXFReader();
859
860           // Open the file for reading. The file must exist. Returns error if the
861           // operation cannot be completed.
862           Result_t OpenRead(const char* filename) const;
863
864           // Returns RESULT_INIT if the file is not open.
865           Result_t Close() const;
866
867           // Fill an AudioDescriptor struct with the values from the file's header.
868           // Returns RESULT_INIT if the file is not open.
869           Result_t FillAudioDescriptor(AudioDescriptor&) const;
870
871           // Fill a WriterInfo struct with the values from the file's header.
872           // Returns RESULT_INIT if the file is not open.
873           Result_t FillWriterInfo(WriterInfo&) const;
874
875           // Reads a frame of essence from the MXF file. If the optional AESEncContext
876           // argument is present, the essence is decrypted after reading. If the MXF
877           // file is encrypted and the AESDecContext argument is NULL, the frame buffer
878           // will contain the ciphertext frame data. If the HMACContext argument is
879           // not NULL, the HMAC will be calculated (if the file supports it).
880           // Returns RESULT_INIT if the file is not open, failure if the frame number is
881           // out of range, or if optional decrypt or HAMC operations fail.
882           Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
883
884           // Print debugging information to stream
885           void     DumpHeaderMetadata(FILE* = 0) const;
886           void     DumpIndex(FILE* = 0) const;
887         };
888     } // namespace PCM
889
890   //
891   namespace JP2K
892     {
893       const ui32_t MaxComponents = 3;
894       const ui32_t DefaultCodingDataLength = 64;
895
896       struct ImageComponent
897       {
898         byte_t Ssize;
899         byte_t XRsize;
900         byte_t YRsize;
901       };
902
903       struct PictureDescriptor
904       {
905         Rational       EditRate;
906         ui32_t         ContainerDuration;
907         Rational       SampleRate;
908         ui32_t         StoredWidth;
909         ui32_t         StoredHeight;
910         Rational       AspectRatio;
911         ui16_t         Rsize;
912         ui32_t         Xsize;
913         ui32_t         Ysize;
914         ui32_t         XOsize;
915         ui32_t         YOsize;
916         ui32_t         XTsize;
917         ui32_t         YTsize;
918         ui32_t         XTOsize;
919         ui32_t         YTOsize;
920         ui16_t         Csize;
921         ImageComponent ImageComponents[MaxComponents];
922         byte_t         CodingStyle[DefaultCodingDataLength];
923         ui32_t         CodingStyleLength;
924         byte_t         QuantDefault[DefaultCodingDataLength];
925         ui32_t         QuantDefaultLength;
926       };
927
928       // Print debugging information to stream (stderr default)
929       void   PictureDescriptorDump(const PictureDescriptor&, FILE* = 0);
930
931       //
932       class FrameBuffer : public ASDCP::FrameBuffer
933         {
934         public:
935           FrameBuffer() {}
936           FrameBuffer(ui32_t size) { Capacity(size); }
937           virtual ~FrameBuffer() {}
938         
939           // Print debugging information to stream (stderr default)
940           void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
941         };
942
943
944       // An object which opens and reads a JPEG 2000 codestream file.  The file is expected
945       // to contain exactly one complete frame of picture essence as an unwrapped (raw)
946       // ISO/IEC 15444 codestream.
947       class CodestreamParser
948         {
949           class h__CodestreamParser;
950           mem_ptr<h__CodestreamParser> m_Parser;
951           ASDCP_NO_COPY_CONSTRUCT(CodestreamParser);
952
953         public:
954           CodestreamParser();
955           virtual ~CodestreamParser();
956
957           // Opens a file for reading, parses enough data to provide a complete
958           // set of stream metadata for the MXFWriter below.
959           // The frame buffer's PlaintextOffset parameter will be set to the first
960           // byte of the data segment. Set this value to zero if you want
961           // encrypted headers.
962           Result_t OpenReadFrame(const char* filename, FrameBuffer&) const;
963
964           // Fill a PictureDescriptor struct with the values from the file's codestream.
965           // Returns RESULT_INIT if the file is not open.
966           Result_t FillPictureDescriptor(PictureDescriptor&) const;
967         };
968
969       // An object which reads a sequence of files containing JPEG 2000 pictures.
970       class SequenceParser
971         {
972           class h__SequenceParser;
973           mem_ptr<h__SequenceParser> m_Parser;
974           ASDCP_NO_COPY_CONSTRUCT(SequenceParser);
975
976         public:
977           SequenceParser();
978           virtual ~SequenceParser();
979
980           // Opens a directory for reading.  The directory is expected to contain one or
981           // more files, each containing the codestream for exactly one picture. The
982           // files must be named such that the frames are in temporal order when sorted
983           // alphabetically by filename. The parser will automatically parse enough data
984           // from the first file to provide a complete set of stream metadata for the
985           // MXFWriter below.  If the "pedantic" parameter is given and is true, the
986           // parser will check the metadata for each codestream and fail if a 
987           // mismatch is detected.
988           Result_t OpenRead(const char* filename, bool pedantic = false) const;
989
990           // Fill a PictureDescriptor struct with the values from the first file's codestream.
991           // Returns RESULT_INIT if the directory is not open.
992           Result_t FillPictureDescriptor(PictureDescriptor&) const;
993
994           // Rewind the directory to the beginning.
995           Result_t Reset() const;
996
997           // Reads the next sequential frame in the directory and places it in the
998           // frame buffer. Fails if the buffer is too small or the direcdtory
999           // contains no more files.
1000           // The frame buffer's PlaintextOffset parameter will be set to the first
1001           // byte of the data segment. Set this value to zero if you want
1002           // encrypted headers.
1003           Result_t ReadFrame(FrameBuffer&) const;
1004         };
1005
1006
1007       //
1008       class MXFWriter
1009         {
1010           class h__Writer;
1011           mem_ptr<h__Writer> m_Writer;
1012           ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
1013
1014         public:
1015           MXFWriter();
1016           virtual ~MXFWriter();
1017
1018           // Open the file for writing. The file must not exist. Returns error if
1019           // the operation cannot be completed or if nonsensical data is discovered
1020           // in the essence descriptor.
1021           Result_t OpenWrite(const char* filename, const WriterInfo&,
1022                              const PictureDescriptor&, ui32_t HeaderSize = 16384);
1023
1024           // Writes a frame of essence to the MXF file. If the optional AESEncContext
1025           // argument is present, the essence is encrypted prior to writing.
1026           // Fails if the file is not open, is finalized, or an operating system
1027           // error occurs.
1028           Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
1029
1030           // Closes the MXF file, writing the index and revised header.
1031           Result_t Finalize();
1032         };
1033
1034       //
1035       class MXFReader
1036         {
1037           class h__Reader;
1038           mem_ptr<h__Reader> m_Reader;
1039           ASDCP_NO_COPY_CONSTRUCT(MXFReader);
1040
1041         public:
1042           MXFReader();
1043           virtual ~MXFReader();
1044
1045           // Open the file for reading. The file must exist. Returns error if the
1046           // operation cannot be completed.
1047           Result_t OpenRead(const char* filename) const;
1048
1049           // Returns RESULT_INIT if the file is not open.
1050           Result_t Close() const;
1051
1052           // Fill an AudioDescriptor struct with the values from the file's header.
1053           // Returns RESULT_INIT if the file is not open.
1054           Result_t FillPictureDescriptor(PictureDescriptor&) const;
1055
1056           // Fill a WriterInfo struct with the values from the file's header.
1057           // Returns RESULT_INIT if the file is not open.
1058           Result_t FillWriterInfo(WriterInfo&) const;
1059
1060           // Reads a frame of essence from the MXF file. If the optional AESEncContext
1061           // argument is present, the essence is decrypted after reading. If the MXF
1062           // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1063           // will contain the ciphertext frame data. If the HMACContext argument is
1064           // not NULL, the HMAC will be calculated (if the file supports it).
1065           // Returns RESULT_INIT if the file is not open, failure if the frame number is
1066           // out of range, or if optional decrypt or HAMC operations fail.
1067           Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1068
1069           // Print debugging information to stream
1070           void     DumpHeaderMetadata(FILE* = 0) const;
1071           void     DumpIndex(FILE* = 0) const;
1072         };
1073     } // namespace JP2K
1074 } // namespace ASDCP
1075
1076
1077 #endif // _AS_DCP_H_
1078
1079 //
1080 // end AS_DCP.h
1081 //