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