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