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