2 Copyright (c) 2003-2013, John Hurst
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
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.
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.
29 \brief AS-DCP library, public interface
31 The asdcplib library is a set of file access objects that offer simplified
32 access to files conforming to the standards published by the SMPTE
33 D-Cinema Technology Committee 21DC. The file format, labeled AS-DCP,
34 is described in series of separate documents which include but may not
37 o SMPTE ST 429-2:2011 DCP Operational Constraints
38 o SMPTE ST 429-3:2006 Sound and Picture Track File
39 o SMPTE ST 429-4:2006 MXF JPEG 2000 Application
40 o SMPTE ST 429-5:2009 Timed Text Track File
41 o SMPTE ST 429-6:2006 MXF Track File Essence Encryption
42 o SMPTE ST 429-10:2008 Stereoscopic Picture Track File
43 o SMPTE ST 330:2004 - UMID
44 o SMPTE ST 336:2001 - KLV
45 o SMPTE ST 377-1:2011 - MXF
46 o SMPTE ST 377-4:2012 - MXF Multichannel Audio Labeling Framework
47 o SMPTE ST 390:2011 - MXF OP-Atom
48 o SMPTE ST 379-1:2009 - MXF Generic Container (GC)
49 o SMPTE ST 381-1:2005 - MPEG2 picture in GC
50 o SMPTE ST 422:2006 - JPEG 2000 picture in GC
51 o SMPTE ST 382:2007 - WAV/PCM sound in GC
52 o IETF RFC 2104 - HMAC/SHA1
53 o NIST FIPS 197 - AES (Rijndael) (via OpenSSL)
55 o MXF Interop Track File Specification
56 o MXF Interop Track File Essence Encryption Specification
57 o MXF Interop Operational Constraints Specification
58 - Note: the MXF Interop documents are not formally published.
59 Contact the asdcplib support address to get copies.
61 The following use cases are supported by the library:
63 o Write essence to a plaintext or ciphertext AS-DCP file:
64 MPEG2 Video Elementary Stream
66 JPEG 2000 stereoscopic codestream pairs
68 SMPTE 429-7 Timed Text XML with font and image resources
70 o Read essence from a plaintext or ciphertext AS-DCP file:
71 MPEG2 Video Elementary Stream
73 JPEG 2000 stereoscopic codestream pairs
75 SMPTE 429-7 Timed Text XML with font and image resources
77 o Read header metadata from an AS-DCP file
79 This project depends upon the following libraries:
80 - OpenSSL http://www.openssl.org/
81 - Expat http://expat.sourceforge.net/ or
82 Xerces-C http://xerces.apache.org/xerces-c/
83 An XML library is not needed if you don't need support for SMPTE ST 429-5:2009.
90 #include <KM_fileio.h>
99 //--------------------------------------------------------------------------------
100 // common integer types
101 // supply your own by defining ASDCP_NO_BASE_TYPES
103 #ifndef ASDCP_NO_BASE_TYPES
104 typedef unsigned char byte_t;
106 typedef unsigned char ui8_t;
108 typedef unsigned short ui16_t;
110 typedef unsigned int ui32_t;
114 //--------------------------------------------------------------------------------
115 // convenience macros
117 // Convenience macros for managing return values in predicates
118 #define ASDCP_SUCCESS(v) (((v) < 0) ? 0 : 1)
119 #define ASDCP_FAILURE(v) (((v) < 0) ? 1 : 0)
122 // Returns RESULT_PTR if the given argument is NULL.
123 // See Result_t below for an explanation of RESULT_* symbols.
124 #define ASDCP_TEST_NULL(p) \
126 return ASDCP::RESULT_PTR; \
129 // Returns RESULT_PTR if the given argument is NULL. See Result_t
130 // below for an explanation of RESULT_* symbols. It then assumes
131 // that the argument is a pointer to a string and returns
132 // RESULT_NULL_STR if the first character is '\0'.
134 #define ASDCP_TEST_NULL_STR(p) \
135 ASDCP_TEST_NULL(p); \
136 if ( (p)[0] == '\0' ) { \
137 return ASDCP::RESULT_NULL_STR; \
140 // Produces copy constructor boilerplate. Allows convenient private
141 // declatarion of copy constructors to prevent the compiler from
142 // silently manufacturing default methods.
143 #define ASDCP_NO_COPY_CONSTRUCT(T) \
145 T& operator=(const T&)
147 //--------------------------------------------------------------------------------
148 // All library components are defined in the namespace ASDCP
152 // The version number declaration and explanation have moved to ../configure.ac
153 const char* Version();
155 // UUIDs are passed around as strings of UUIDlen bytes
156 const ui32_t UUIDlen = 16;
158 // Encryption keys are passed around as strings of KeyLen bytes
159 const ui32_t KeyLen = 16;
161 //---------------------------------------------------------------------------------
164 using Kumu::Result_t;
166 using Kumu::RESULT_FALSE;
167 using Kumu::RESULT_OK;
168 using Kumu::RESULT_FAIL;
169 using Kumu::RESULT_PTR;
170 using Kumu::RESULT_NULL_STR;
171 using Kumu::RESULT_ALLOC;
172 using Kumu::RESULT_PARAM;
173 using Kumu::RESULT_SMALLBUF;
174 using Kumu::RESULT_INIT;
175 using Kumu::RESULT_NOT_FOUND;
176 using Kumu::RESULT_NO_PERM;
177 using Kumu::RESULT_FILEOPEN;
178 using Kumu::RESULT_BADSEEK;
179 using Kumu::RESULT_READFAIL;
180 using Kumu::RESULT_WRITEFAIL;
181 using Kumu::RESULT_STATE;
182 using Kumu::RESULT_ENDOFFILE;
183 using Kumu::RESULT_CONFIG;
185 KM_DECLARE_RESULT(FORMAT, -101, "The file format is not proper OP-Atom/AS-DCP.");
186 KM_DECLARE_RESULT(RAW_ESS, -102, "Unknown raw essence file type.");
187 KM_DECLARE_RESULT(RAW_FORMAT, -103, "Raw essence format invalid.");
188 KM_DECLARE_RESULT(RANGE, -104, "Frame number out of range.");
189 KM_DECLARE_RESULT(CRYPT_CTX, -105, "AESEncContext required when writing to encrypted file.");
190 KM_DECLARE_RESULT(LARGE_PTO, -106, "Plaintext offset exceeds frame buffer size.");
191 KM_DECLARE_RESULT(CAPEXTMEM, -107, "Cannot resize externally allocated memory.");
192 KM_DECLARE_RESULT(CHECKFAIL, -108, "The check value did not decrypt correctly.");
193 KM_DECLARE_RESULT(HMACFAIL, -109, "HMAC authentication failure.");
194 KM_DECLARE_RESULT(HMAC_CTX, -110, "HMAC context required.");
195 KM_DECLARE_RESULT(CRYPT_INIT, -111, "Error initializing block cipher context.");
196 KM_DECLARE_RESULT(EMPTY_FB, -112, "Empty frame buffer.");
197 KM_DECLARE_RESULT(KLV_CODING, -113, "KLV coding error.");
198 KM_DECLARE_RESULT(SPHASE, -114, "Stereoscopic phase mismatch.");
199 KM_DECLARE_RESULT(SFORMAT, -115, "Rate mismatch, file may contain stereoscopic essence.");
201 //---------------------------------------------------------------------------------
202 // file identification
204 // The file accessors in this library implement a bounded set of essence types.
205 // This list will be expanded when support for new types is added to the library.
207 ESS_UNKNOWN, // the file is not a supported AS-DCP essence container
208 ESS_MPEG2_VES, // the file contains an MPEG video elementary stream
209 ESS_JPEG_2000, // the file contains one or more JPEG 2000 codestreams
210 ESS_PCM_24b_48k, // the file contains one or more PCM audio pairs
211 ESS_PCM_24b_96k, // the file contains one or more PCM audio pairs
212 ESS_TIMED_TEXT, // the file contains an XML timed text document and one or more resources
213 ESS_JPEG_2000_S, // the file contains one or more JPEG 2000 codestream pairs (stereoscopic)
214 ESS_DCDATA_UNKNOWN, // the file contains one or more D-Cinema Data bytestreams
215 ESS_DCDATA_DOLBY_ATMOS, // the file contains one or more DolbyATMOS bytestreams
218 // Determine the type of essence contained in the given MXF file. RESULT_OK
219 // is returned if the file is successfully opened and contains a valid MXF
220 // stream. If there is an error, the result code will indicate the reason.
221 Result_t EssenceType(const char* filename, EssenceType_t& type);
223 // Determine the type of essence contained in the given raw file. RESULT_OK
224 // is returned if the file is successfully opened and contains a known
225 // stream type. If there is an error, the result code will indicate the reason.
226 Result_t RawEssenceType(const char* filename, EssenceType_t& type);
229 //---------------------------------------------------------------------------------
232 // A simple container for rational numbers.
239 Rational() : Numerator(0), Denominator(0) {}
240 Rational(i32_t n, i32_t d) : Numerator(n), Denominator(d) {}
242 inline double Quotient() const {
243 return (double)Numerator / (double)Denominator;
246 inline bool operator==(const Rational& rhs) const {
247 return ( rhs.Numerator == Numerator && rhs.Denominator == Denominator );
250 inline bool operator!=(const Rational& rhs) const {
251 return ( rhs.Numerator != Numerator || rhs.Denominator != Denominator );
254 inline bool operator<(const Rational& rhs) {
255 if ( Numerator < rhs.Numerator ) return true;
256 if ( Numerator == rhs.Numerator && Denominator < rhs.Denominator ) return true;
260 inline bool operator>(const Rational& rhs) {
261 if ( Numerator > rhs.Numerator ) return true;
262 if ( Numerator == rhs.Numerator && Denominator > rhs.Denominator ) return true;
267 // common edit rates, use these instead of hard coded constants
268 const Rational EditRate_24 = Rational(24,1);
269 const Rational EditRate_23_98 = Rational(24000,1001); // Not a DCI-compliant value!
270 const Rational EditRate_48 = Rational(48,1);
271 const Rational SampleRate_48k = Rational(48000,1);
272 const Rational SampleRate_96k = Rational(96000,1);
274 // Additional frame rates, see ST 428-11, ST 429-13
275 // These rates are new and not supported by all systems. Do not assume that
276 // a package made using one of these rates will work just anywhere!
277 const Rational EditRate_25 = Rational(25,1);
278 const Rational EditRate_30 = Rational(30,1);
279 const Rational EditRate_50 = Rational(50,1);
280 const Rational EditRate_60 = Rational(60,1);
281 const Rational EditRate_96 = Rational(96,1);
282 const Rational EditRate_100 = Rational(100,1);
283 const Rational EditRate_120 = Rational(120,1);
285 // Archival frame rates, see ST 428-21
286 // These rates are new and not supported by all systems. Do not assume that
287 // a package made using one of these rates will work just anywhere!
288 const Rational EditRate_16 = Rational(16,1);
289 const Rational EditRate_18 = Rational(200,11); // 18.182
290 const Rational EditRate_20 = Rational(20,1);
291 const Rational EditRate_22 = Rational(240,11); // 21.818
294 // Non-reference counting container for internal member objects.
295 // Please do not use this class for any other purpose.
299 T* m_p; // the thing we point to
303 mem_ptr() : m_p(0) {}
304 mem_ptr(T* p) : m_p(p) {}
305 ~mem_ptr() { delete m_p; }
307 inline T& operator*() const { return *m_p; }
308 inline T* operator->() const { return m_p; }
309 inline operator T*()const { return m_p; }
310 inline const mem_ptr<T>& operator=(T* p) { set(p); return *this; }
311 inline T* set(T* p) { delete m_p; m_p = p; return m_p; }
312 inline T* get() const { return m_p; }
313 inline void release() { m_p = 0; }
314 inline bool empty() const { return m_p == 0; }
318 //---------------------------------------------------------------------------------
319 // WriterInfo class - encapsulates writer identification details used for
320 // OpenWrite() calls. Replace these values at runtime to identify your product.
322 // MXF files use SMPTE Universal Labels to identify data items. The set of Labels
323 // in a file is determined by the MXF Operational Pattern and any constraining
324 // documentation. There are currently two flavors of AS-DCP file in use: MXF Interop
325 // (AKA JPEG Interop) and SMPTE. The two differ in the values of three labels:
328 // Interop : 06 0e 2b 34 04 01 01 01 0d 01 02 01 10 00 00 00
329 // SMPTE : 06 0e 2b 34 04 01 01 02 0d 01 02 01 10 00 00 00
332 // Interop : 06 0e 2b 34 02 04 01 07 0d 01 03 01 02 7e 01 00
333 // SMPTE : 06 0e 2b 34 02 04 01 01 0d 01 03 01 02 7e 01 00
335 // GenericDescriptor/SubDescriptors:
336 // Interop : 06 0e 2b 34 01 01 01 02 06 01 01 04 06 10 00 00
337 // SMPTE : 06 0e 2b 34 01 01 01 09 06 01 01 04 06 10 00 00
339 // asdcplib will read any (otherwise valid) file which has any combination of the
340 // above values. When writing files, MXF Interop labels are used by default. To
341 // write a file containing SMPTE labels, replace the default label set value in
342 // the WriterInfo before calling OpenWrite()
355 byte_t ProductUUID[UUIDlen];
356 byte_t AssetUUID[UUIDlen];
357 byte_t ContextID[UUIDlen];
358 byte_t CryptographicKeyID[UUIDlen];
359 bool EncryptedEssence; // true if essence data is (or is going to be) encrypted
360 bool UsesHMAC; // true if HMAC exists or is to be calculated
361 std::string ProductVersion;
362 std::string CompanyName;
363 std::string ProductName;
364 LabelSet_t LabelSetType;
366 WriterInfo() : EncryptedEssence(false), UsesHMAC(false), LabelSetType(LS_MXF_INTEROP)
368 static byte_t default_ProductUUID_Data[UUIDlen] = {
369 0x43, 0x05, 0x9a, 0x1d, 0x04, 0x32, 0x41, 0x01,
370 0xb8, 0x3f, 0x73, 0x68, 0x15, 0xac, 0xf3, 0x1d };
372 memcpy(ProductUUID, default_ProductUUID_Data, UUIDlen);
373 memset(AssetUUID, 0, UUIDlen);
374 memset(ContextID, 0, UUIDlen);
375 memset(CryptographicKeyID, 0, UUIDlen);
377 ProductVersion = "Unreleased ";
378 ProductVersion += Version();
380 ProductName = "asdcplib";
384 // Print WriterInfo to std::ostream
385 std::ostream& operator << (std::ostream& strm, const WriterInfo& winfo);
386 // Print WriterInfo to stream, stderr by default.
387 void WriterInfoDump(const WriterInfo&, FILE* = 0);
389 //---------------------------------------------------------------------------------
390 // cryptographic support
392 // The following classes define interfaces to Rijndael contexts having the following properties:
394 // o CBC mode with 16 byte block size
395 const ui32_t CBC_KEY_SIZE = 16;
396 const ui32_t CBC_BLOCK_SIZE = 16;
397 const ui32_t HMAC_SIZE = 20;
403 mem_ptr<h__AESContext> m_Context;
404 ASDCP_NO_COPY_CONSTRUCT(AESEncContext);
410 // Initializes Rijndael CBC encryption context.
411 // Returns error if the key argument is NULL.
412 Result_t InitKey(const byte_t* key);
414 // Initializes 16 byte CBC Initialization Vector. This operation may be performed
415 // any number of times for a given key.
416 // Returns error if the i_vec argument is NULL.
417 Result_t SetIVec(const byte_t* i_vec);
418 Result_t GetIVec(byte_t* i_vec) const;
420 // Encrypt a block of data. The block size must be a multiple of CBC_BLOCK_SIZE.
421 // Returns error if either argument is NULL.
422 Result_t EncryptBlock(const byte_t* pt_buf, byte_t* ct_buf, ui32_t block_size);
429 mem_ptr<h__AESContext> m_Context;
430 ASDCP_NO_COPY_CONSTRUCT(AESDecContext);
436 // Initializes Rijndael CBC decryption context.
437 // Returns error if the key argument is NULL.
438 Result_t InitKey(const byte_t* key);
440 // Initializes 16 byte CBC Initialization Vector. This operation may be performed
441 // any number of times for a given key.
442 // Returns error if the i_vec argument is NULL.
443 Result_t SetIVec(const byte_t* i_vec);
445 // Decrypt a block of data. The block size must be a multiple of CBC_BLOCK_SIZE.
446 // Returns error if either argument is NULL.
447 Result_t DecryptBlock(const byte_t* ct_buf, byte_t* pt_buf, ui32_t block_size);
453 class h__HMACContext;
454 mem_ptr<h__HMACContext> m_Context;
455 ASDCP_NO_COPY_CONSTRUCT(HMACContext);
461 // Initializes HMAC context. The key argument must point to a binary
462 // key that is CBC_KEY_SIZE bytes in length. Returns error if the key
464 Result_t InitKey(const byte_t* key, LabelSet_t);
466 // Reset internal state, allows repeated cycles of Update -> Finalize
469 // Add data to the digest. Returns error if the key argument is NULL or
470 // if the digest has been finalized.
471 Result_t Update(const byte_t* buf, ui32_t buf_len);
473 // Finalize digest. Returns error if the digest has already been finalized.
476 // Writes HMAC value to given buffer. buf must point to a writable area of
477 // memory that is at least HMAC_SIZE bytes in length. Returns error if the
478 // buf argument is NULL or if the digest has not been finalized.
479 Result_t GetHMACValue(byte_t* buf) const;
481 // Tests the given value against the finalized value in the object. buf must
482 // point to a readable area of memory that is at least HMAC_SIZE bytes in length.
483 // Returns error if the buf argument is NULL or if the values do ot match.
484 Result_t TestHMACValue(const byte_t* buf) const;
487 //---------------------------------------------------------------------------------
488 // frame buffer base class
490 // The supported essence types are stored using per-frame KLV packetization. The
491 // following class implements essence-neutral functionality for managing a buffer
492 // containing a frame of essence.
496 ASDCP_NO_COPY_CONSTRUCT(FrameBuffer);
499 byte_t* m_Data; // pointer to memory area containing frame data
500 ui32_t m_Capacity; // size of memory area pointed to by m_Data
501 bool m_OwnMem; // if false, m_Data points to externally allocated memory
502 ui32_t m_Size; // size of frame data in memory area pointed to by m_Data
503 ui32_t m_FrameNumber; // delivery-order frame number
505 // It is possible to read raw ciphertext from an encrypted AS-DCP file.
506 // After reading an encrypted AS-DCP file in raw mode, the frame buffer will
507 // contain the encrypted source value portion of the Encrypted Triplet, followed
508 // by the integrity pack, if it exists.
509 // The buffer will begin with the IV and CheckValue, followed by encrypted essence
510 // and optional integrity pack
511 // The SourceLength and PlaintextOffset values from the packet will be held in the
512 // following variables:
513 ui32_t m_SourceLength; // plaintext length (delivered plaintext+decrypted ciphertext)
514 ui32_t m_PlaintextOffset; // offset to first byte of ciphertext
518 virtual ~FrameBuffer();
520 // Instructs the object to use an externally allocated buffer. The external
521 // buffer will not be cleaned up by the frame buffer when it exits.
522 // Call with (0,0) to revert to internally allocated buffer.
523 // Returns error if the buf_addr argument is NULL and buf_size is non-zero.
524 Result_t SetData(byte_t* buf_addr, ui32_t buf_size);
526 // Sets the size of the internally allocate buffer. Returns RESULT_CAPEXTMEM
527 // if the object is using an externally allocated buffer via SetData();
528 // Resets content size to zero.
529 Result_t Capacity(ui32_t cap);
531 // returns the size of the buffer
532 inline ui32_t Capacity() const { return m_Capacity; }
534 // returns a const pointer to the essence data
535 inline const byte_t* RoData() const { return m_Data; }
537 // returns a non-const pointer to the essence data
538 inline byte_t* Data() { return m_Data; }
540 // set the size of the buffer's contents
541 inline ui32_t Size(ui32_t size) { return m_Size = size; }
543 // returns the size of the buffer's contents
544 inline ui32_t Size() const { return m_Size; }
546 // Sets the absolute frame number of this frame in the file in delivery order.
547 inline void FrameNumber(ui32_t num) { m_FrameNumber = num; }
549 // Returns the absolute frame number of this frame in the file in delivery order.
550 inline ui32_t FrameNumber() const { return m_FrameNumber; }
552 // Sets the length of the plaintext essence data
553 inline void SourceLength(ui32_t len) { m_SourceLength = len; }
555 // When this value is 0 (zero), the buffer contains only plaintext. When it is
556 // non-zero, the buffer contains raw ciphertext and the return value is the length
557 // of the original plaintext.
558 inline ui32_t SourceLength() const { return m_SourceLength; }
560 // Sets the offset into the buffer at which encrypted data begins
561 inline void PlaintextOffset(ui32_t ofst) { m_PlaintextOffset = ofst; }
563 // Returns offset into buffer of first byte of ciphertext.
564 inline ui32_t PlaintextOffset() const { return m_PlaintextOffset; }
567 //---------------------------------------------------------------------------------
568 // Accessors in the MXFReader and MXFWriter classes below return these types to
569 // provide direct access to MXF metadata structures declared in MXF.h and Metadata.h
572 // #include<Metadata.h> to use these
574 class OPAtomIndexFooter;
578 //---------------------------------------------------------------------------------
579 // MPEG2 video elementary stream support
584 // MPEG picture coding type
586 FRAME_U = 0x00, // Unknown
587 FRAME_I = 0x01, // I-Frame
588 FRAME_P = 0x02, // P-Frame
589 FRAME_B = 0x03 // B-Frame
592 // convert FrameType_t to char
593 inline char FrameTypeChar(FrameType_t type)
597 case FRAME_I: return 'I';
598 case FRAME_B: return 'B';
599 case FRAME_P: return 'P';
604 // Structure represents the metadata elements in the file header's
605 // MPEG2VideoDescriptor object.
606 struct VideoDescriptor
608 Rational EditRate; //
610 Rational SampleRate; //
611 ui8_t FrameLayout; //
612 ui32_t StoredWidth; //
613 ui32_t StoredHeight; //
614 Rational AspectRatio; //
615 ui32_t ComponentDepth; //
616 ui32_t HorizontalSubsampling; //
617 ui32_t VerticalSubsampling; //
618 ui8_t ColorSiting; //
619 ui8_t CodedContentType; //
622 ui8_t ProfileAndLevel; //
623 ui32_t ContainerDuration; //
626 // Print VideoDescriptor to std::ostream
627 std::ostream& operator << (std::ostream& strm, const VideoDescriptor& vdesc);
628 // Print VideoDescriptor to stream, stderr by default.
629 void VideoDescriptorDump(const VideoDescriptor&, FILE* = 0);
631 // A container for MPEG frame data.
632 class FrameBuffer : public ASDCP::FrameBuffer
634 ASDCP_NO_COPY_CONSTRUCT(FrameBuffer); // TODO: should have copy construct
637 FrameType_t m_FrameType;
638 ui8_t m_TemporalOffset;
644 m_FrameType(FRAME_U), m_TemporalOffset(0),
645 m_ClosedGOP(false), m_GOPStart(false) {}
647 FrameBuffer(ui32_t size) :
648 m_FrameType(FRAME_U), m_TemporalOffset(0),
649 m_ClosedGOP(false), m_GOPStart(false)
654 virtual ~FrameBuffer() {}
656 // Sets the MPEG frame type of the picture data in the frame buffer.
657 inline void FrameType(FrameType_t type) { m_FrameType = type; }
659 // Returns the MPEG frame type of the picture data in the frame buffer.
660 inline FrameType_t FrameType() const { return m_FrameType; }
662 // Sets the MPEG temporal offset of the picture data in the frame buffer.
663 inline void TemporalOffset(ui8_t offset) { m_TemporalOffset = offset; }
665 // Returns the MPEG temporal offset of the picture data in the frame buffer.
666 inline ui8_t TemporalOffset() const { return m_TemporalOffset; }
668 // Sets the MPEG GOP 'start' attribute for the frame buffer.
669 inline void GOPStart(bool start) { m_GOPStart = start; }
671 // True if the frame in the buffer is the first in the GOP (in transport order)
672 inline bool GOPStart() const { return m_GOPStart; }
674 // Sets the MPEG GOP 'closed' attribute for the frame buffer.
675 inline void ClosedGOP(bool closed) { m_ClosedGOP = closed; }
677 // Returns true if the frame in the buffer is from a closed GOP, false if
678 // the frame is from an open GOP. Always returns false unless GOPStart()
680 inline bool ClosedGOP() const { return m_ClosedGOP; }
682 // Print object state to stream, include n bytes of frame data if indicated.
683 // Default stream is stderr.
684 void Dump(FILE* = 0, ui32_t dump_len = 0) const;
688 // An object which opens and reads an MPEG2 Video Elementary Stream file. The call to
689 // OpenRead() reads metadata from the file and populates an internal VideoDescriptor object.
690 // Each subsequent call to ReadFrame() reads exactly one frame from the stream into the
691 // given FrameBuffer object.
695 mem_ptr<h__Parser> m_Parser;
696 ASDCP_NO_COPY_CONSTRUCT(Parser);
702 // Opens the stream for reading, parses enough data to provide a complete
703 // set of stream metadata for the MXFWriter below.
704 Result_t OpenRead(const char* filename) const;
706 // Fill a VideoDescriptor struct with the values from the file's header.
707 // Returns RESULT_INIT if the file is not open.
708 Result_t FillVideoDescriptor(VideoDescriptor&) const;
710 // Rewind the stream to the beginning.
711 Result_t Reset() const;
713 // Reads the next sequential frame in the input file and places it in the
714 // frame buffer. Fails if the buffer is too small or the stream is empty.
715 // The frame buffer's PlaintextOffset parameter will be set to the first
716 // data byte of the first slice. Set this value to zero if you want
717 // encrypted headers.
718 Result_t ReadFrame(FrameBuffer&) const;
721 // A class which creates and writes MPEG frame data to an AS-DCP format MXF file.
722 // Not yet implemented
726 mem_ptr<h__Writer> m_Writer;
727 ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
731 virtual ~MXFWriter();
733 // Warning: direct manipulation of MXF structures can interfere
734 // with the normal operation of the wrapper. Caveat emptor!
735 virtual MXF::OP1aHeader& OP1aHeader();
736 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
737 virtual MXF::RIP& RIP();
739 // Open the file for writing. The file must not exist. Returns error if
740 // the operation cannot be completed or if nonsensical data is discovered
741 // in the essence descriptor.
742 Result_t OpenWrite(const char* filename, const WriterInfo&,
743 const VideoDescriptor&, ui32_t HeaderSize = 16384);
745 // Writes a frame of essence to the MXF file. If the optional AESEncContext
746 // argument is present, the essence is encrypted prior to writing.
747 // Fails if the file is not open, is finalized, or an operating system
749 Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
751 // Closes the MXF file, writing the index and revised header.
755 // A class which reads MPEG frame data from an AS-DCP format MXF file.
759 mem_ptr<h__Reader> m_Reader;
760 ASDCP_NO_COPY_CONSTRUCT(MXFReader);
764 virtual ~MXFReader();
766 // Warning: direct manipulation of MXF structures can interfere
767 // with the normal operation of the wrapper. Caveat emptor!
768 virtual MXF::OP1aHeader& OP1aHeader();
769 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
770 virtual MXF::RIP& RIP();
772 // Open the file for reading. The file must exist. Returns error if the
773 // operation cannot be completed.
774 Result_t OpenRead(const char* filename) const;
776 // Returns RESULT_INIT if the file is not open.
777 Result_t Close() const;
779 // Fill a VideoDescriptor struct with the values from the file's header.
780 // Returns RESULT_INIT if the file is not open.
781 Result_t FillVideoDescriptor(VideoDescriptor&) const;
783 // Fill a WriterInfo struct with the values from the file's header.
784 // Returns RESULT_INIT if the file is not open.
785 Result_t FillWriterInfo(WriterInfo&) const;
787 // Reads a frame of essence from the MXF file. If the optional AESEncContext
788 // argument is present, the essence is decrypted after reading. If the MXF
789 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
790 // will contain the ciphertext frame data. If the HMACContext argument is
791 // not NULL, the HMAC will be calculated (if the file supports it).
792 // Returns RESULT_INIT if the file is not open, failure if the frame number is
793 // out of range, or if optional decrypt or HAMC operations fail.
794 Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
796 // Using the index table read from the footer partition, lookup the frame number
797 // and return the offset into the file at which to read that frame of essence.
798 // Returns RESULT_INIT if the file is not open, and RESULT_RANGE if the frame number is
800 Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
802 // Calculates the first frame in transport order of the GOP in which the requested
803 // frame is located. Calls ReadFrame() to fetch the frame at the calculated position.
804 // Returns RESULT_INIT if the file is not open.
805 Result_t ReadFrameGOPStart(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
807 // Calculates the first frame in transport order of the GOP in which the requested
808 // frame is located. Sets key_frame_number to the number of the frame at the calculated position.
809 // Returns RESULT_INIT if the file is not open.
810 Result_t FindFrameGOPStart(ui32_t frame_number, ui32_t& key_frame_number) const;
812 // Returns the type of the frame at the given position.
813 // Returns RESULT_INIT if the file is not open or RESULT_RANGE if the index is out of range.
814 Result_t FrameType(ui32_t frame_number, FrameType_t&) const;
816 // Print debugging information to stream
817 void DumpHeaderMetadata(FILE* = 0) const;
818 void DumpIndex(FILE* = 0) const;
822 //---------------------------------------------------------------------------------
829 // The default value of the ChannelFormat element of the AudioDescriptor struct
830 // is CF_NONE. If the value is set to one of the other ChannelFormat_t enum
831 // values, the file's Wave Audio Descriptor will contain a Channel Assignment
834 // The channel format should be one of (CF_CFG_1, CF_CFG_2, or CF_CFG_3) for
835 // SMPTE 429-2 files. It should normally be CF_NONE for JPEG Interop files, but
836 // the 429-2 may also be used.
838 enum ChannelFormat_t {
840 CF_CFG_1, // 5.1 with optional HI/VI
841 CF_CFG_2, // 6.1 (5.1 + center surround) with optional HI/VI
842 CF_CFG_3, // 7.1 (SDDS) with optional HI/VI
843 CF_CFG_4, // Wild Track Format
844 CF_CFG_5, // 7.1 DS with optional HI/VI
847 struct AudioDescriptor
849 Rational EditRate; // rate of frame wrapping
850 Rational AudioSamplingRate; // rate of audio sample
852 ui32_t ChannelCount; // number of channels
853 ui32_t QuantizationBits; // number of bits per single-channel sample
854 ui32_t BlockAlign; // number of bytes ber sample, all channels
856 ui32_t LinkedTrackID; //
857 ui32_t ContainerDuration; // number of frames
858 ChannelFormat_t ChannelFormat; // audio channel arrangement
861 // Print AudioDescriptor to std::ostream
862 std::ostream& operator << (std::ostream& strm, const AudioDescriptor& adesc);
863 // Print debugging information to stream (stderr default)
864 void AudioDescriptorDump(const AudioDescriptor&, FILE* = 0);
866 // Returns size in bytes of a single sample of data described by ADesc
867 inline ui32_t CalcSampleSize(const AudioDescriptor& ADesc)
869 return (ADesc.QuantizationBits / 8) * ADesc.ChannelCount;
872 // Returns number of samples per frame of data described by ADesc
873 inline ui32_t CalcSamplesPerFrame(const AudioDescriptor& ADesc)
875 double tmpd = ADesc.AudioSamplingRate.Quotient() / ADesc.EditRate.Quotient();
876 return (ui32_t)ceil(tmpd);
879 // Returns the size in bytes of a frame of data described by ADesc
880 inline ui32_t CalcFrameBufferSize(const AudioDescriptor& ADesc)
882 return CalcSampleSize(ADesc) * CalcSamplesPerFrame(ADesc);
886 class FrameBuffer : public ASDCP::FrameBuffer
890 FrameBuffer(ui32_t size) { Capacity(size); }
891 virtual ~FrameBuffer() {}
893 // Print debugging information to stream (stderr default)
894 void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
897 // An object which opens and reads a WAV file. The call to OpenRead() reads metadata from
898 // the file and populates an internal AudioDescriptor object. Each subsequent call to
899 // ReadFrame() reads exactly one frame from the stream into the given FrameBuffer object.
900 // A "frame" is either 2000 or 2002 samples, depending upon the value of PictureRate.
904 mem_ptr<h__WAVParser> m_Parser;
905 ASDCP_NO_COPY_CONSTRUCT(WAVParser);
909 virtual ~WAVParser();
911 // Opens the stream for reading, parses enough data to provide a complete
912 // set of stream metadata for the MXFWriter below. PictureRate controls
913 // ther frame rate for the MXF frame wrapping option.
914 Result_t OpenRead(const char* filename, const Rational& PictureRate) const;
916 // Fill an AudioDescriptor struct with the values from the file's header.
917 // Returns RESULT_INIT if the file is not open.
918 Result_t FillAudioDescriptor(AudioDescriptor&) const;
920 // Rewind the stream to the beginning.
921 Result_t Reset() const;
923 // Reads the next sequential frame in the input file and places it in the
924 // frame buffer. Fails if the buffer is too small or the stream is empty.
925 Result_t ReadFrame(FrameBuffer&) const;
933 mem_ptr<h__Writer> m_Writer;
934 ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
938 virtual ~MXFWriter();
940 // Warning: direct manipulation of MXF structures can interfere
941 // with the normal operation of the wrapper. Caveat emptor!
942 virtual MXF::OP1aHeader& OP1aHeader();
943 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
944 virtual MXF::RIP& RIP();
946 // Open the file for writing. The file must not exist. Returns error if
947 // the operation cannot be completed or if nonsensical data is discovered
948 // in the essence descriptor.
949 Result_t OpenWrite(const char* filename, const WriterInfo&,
950 const AudioDescriptor&, ui32_t HeaderSize = 16384);
952 // Writes a frame of essence to the MXF file. If the optional AESEncContext
953 // argument is present, the essence is encrypted prior to writing.
954 // Fails if the file is not open, is finalized, or an operating system
956 Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
958 // Closes the MXF file, writing the index and revised header.
966 mem_ptr<h__Reader> m_Reader;
967 ASDCP_NO_COPY_CONSTRUCT(MXFReader);
971 virtual ~MXFReader();
973 // Warning: direct manipulation of MXF structures can interfere
974 // with the normal operation of the wrapper. Caveat emptor!
975 virtual MXF::OP1aHeader& OP1aHeader();
976 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
977 virtual MXF::RIP& RIP();
979 // Open the file for reading. The file must exist. Returns error if the
980 // operation cannot be completed.
981 Result_t OpenRead(const char* filename) const;
983 // Returns RESULT_INIT if the file is not open.
984 Result_t Close() const;
986 // Fill an AudioDescriptor struct with the values from the file's header.
987 // Returns RESULT_INIT if the file is not open.
988 Result_t FillAudioDescriptor(AudioDescriptor&) const;
990 // Fill a WriterInfo struct with the values from the file's header.
991 // Returns RESULT_INIT if the file is not open.
992 Result_t FillWriterInfo(WriterInfo&) const;
994 // Reads a frame of essence from the MXF file. If the optional AESEncContext
995 // argument is present, the essence is decrypted after reading. If the MXF
996 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
997 // will contain the ciphertext frame data. If the HMACContext argument is
998 // not NULL, the HMAC will be calculated (if the file supports it).
999 // Returns RESULT_INIT if the file is not open, failure if the frame number is
1000 // out of range, or if optional decrypt or HAMC operations fail.
1001 Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1003 // Using the index table read from the footer partition, lookup the frame number
1004 // and return the offset into the file at which to read that frame of essence.
1005 // Returns RESULT_INIT if the file is not open, and RESULT_RANGE if the frame number is
1007 Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
1009 // Print debugging information to stream
1010 void DumpHeaderMetadata(FILE* = 0) const;
1011 void DumpIndex(FILE* = 0) const;
1015 //---------------------------------------------------------------------------------
1019 const ui32_t MaxComponents = 3;
1020 const ui32_t MaxPrecincts = 32; // ISO 15444-1 Annex A.6.1
1021 const ui32_t MaxDefaults = 256; // made up
1024 struct ImageComponent_t // ISO 15444-1 Annex A.5.1
1031 struct CodingStyleDefault_t // ISO 15444-1 Annex A.6.1
1037 ui8_t ProgressionOrder;
1038 ui8_t NumberOfLayers[sizeof(ui16_t)];
1039 ui8_t MultiCompTransform;
1044 ui8_t DecompositionLevels;
1045 ui8_t CodeblockWidth;
1046 ui8_t CodeblockHeight;
1047 ui8_t CodeblockStyle;
1048 ui8_t Transformation;
1049 ui8_t PrecinctSize[MaxPrecincts];
1053 struct QuantizationDefault_t // ISO 15444-1 Annex A.6.4
1056 ui8_t SPqcd[MaxDefaults];
1061 struct PictureDescriptor
1064 ui32_t ContainerDuration;
1065 Rational SampleRate;
1067 ui32_t StoredHeight;
1068 Rational AspectRatio;
1079 ImageComponent_t ImageComponents[MaxComponents];
1080 CodingStyleDefault_t CodingStyleDefault;
1081 QuantizationDefault_t QuantizationDefault;
1084 // Print debugging information to std::ostream
1085 std::ostream& operator << (std::ostream& strm, const PictureDescriptor& pdesc);
1086 // Print debugging information to stream (stderr default)
1087 void PictureDescriptorDump(const PictureDescriptor&, FILE* = 0);
1090 class FrameBuffer : public ASDCP::FrameBuffer
1094 FrameBuffer(ui32_t size) { Capacity(size); }
1095 virtual ~FrameBuffer() {}
1097 // Print debugging information to stream (stderr default)
1098 void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
1102 // An object which opens and reads a JPEG 2000 codestream file. The file is expected
1103 // to contain exactly one complete frame of picture essence as an unwrapped (raw)
1104 // ISO/IEC 15444 codestream.
1105 class CodestreamParser
1107 class h__CodestreamParser;
1108 mem_ptr<h__CodestreamParser> m_Parser;
1109 ASDCP_NO_COPY_CONSTRUCT(CodestreamParser);
1113 virtual ~CodestreamParser();
1115 // Opens a file for reading, parses enough data to provide a complete
1116 // set of stream metadata for the MXFWriter below.
1117 // The frame buffer's PlaintextOffset parameter will be set to the first
1118 // byte of the data segment. Set this value to zero if you want
1119 // encrypted headers.
1120 Result_t OpenReadFrame(const char* filename, FrameBuffer&) const;
1122 // Fill a PictureDescriptor struct with the values from the file's codestream.
1123 // Returns RESULT_INIT if the file is not open.
1124 Result_t FillPictureDescriptor(PictureDescriptor&) const;
1127 // Parses the data in the frame buffer to fill in the picture descriptor. Copies
1128 // the offset of the image data into start_of_data. Returns error if the parser fails.
1129 Result_t ParseMetadataIntoDesc(const FrameBuffer&, PictureDescriptor&, byte_t* start_of_data = 0);
1131 // An object which reads a sequence of files containing JPEG 2000 pictures.
1132 class SequenceParser
1134 class h__SequenceParser;
1135 mem_ptr<h__SequenceParser> m_Parser;
1136 ASDCP_NO_COPY_CONSTRUCT(SequenceParser);
1140 virtual ~SequenceParser();
1142 // Opens a directory for reading. The directory is expected to contain one or
1143 // more files, each containing the codestream for exactly one picture. The
1144 // files must be named such that the frames are in temporal order when sorted
1145 // alphabetically by filename. The parser will automatically parse enough data
1146 // from the first file to provide a complete set of stream metadata for the
1147 // MXFWriter below. If the "pedantic" parameter is given and is true, the
1148 // parser will check the metadata for each codestream and fail if a
1149 // mismatch is detected.
1150 Result_t OpenRead(const char* filename, bool pedantic = false) const;
1152 // Opens a file sequence for reading. The sequence is expected to contain one or
1153 // more filenames, each naming a file containing the codestream for exactly one
1154 // picture. The parser will automatically parse enough data
1155 // from the first file to provide a complete set of stream metadata for the
1156 // MXFWriter below. If the "pedantic" parameter is given and is true, the
1157 // parser will check the metadata for each codestream and fail if a
1158 // mismatch is detected.
1159 Result_t OpenRead(const std::list<std::string>& file_list, bool pedantic = false) const;
1161 // Fill a PictureDescriptor struct with the values from the first file's codestream.
1162 // Returns RESULT_INIT if the directory is not open.
1163 Result_t FillPictureDescriptor(PictureDescriptor&) const;
1165 // Rewind the directory to the beginning.
1166 Result_t Reset() const;
1168 // Reads the next sequential frame in the directory and places it in the
1169 // frame buffer. Fails if the buffer is too small or the direcdtory
1170 // contains no more files.
1171 // The frame buffer's PlaintextOffset parameter will be set to the first
1172 // byte of the data segment. Set this value to zero if you want
1173 // encrypted headers.
1174 Result_t ReadFrame(FrameBuffer&) const;
1182 mem_ptr<h__Writer> m_Writer;
1183 ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
1187 virtual ~MXFWriter();
1189 // Warning: direct manipulation of MXF structures can interfere
1190 // with the normal operation of the wrapper. Caveat emptor!
1191 virtual MXF::OP1aHeader& OP1aHeader();
1192 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1193 virtual MXF::RIP& RIP();
1195 // Open the file for writing. The file must not exist. Returns error if
1196 // the operation cannot be completed or if nonsensical data is discovered
1197 // in the essence descriptor.
1198 Result_t OpenWrite(const char* filename, const WriterInfo&,
1199 const PictureDescriptor&, ui32_t HeaderSize = 16384);
1201 // Writes a frame of essence to the MXF file. If the optional AESEncContext
1202 // argument is present, the essence is encrypted prior to writing.
1203 // Fails if the file is not open, is finalized, or an operating system
1205 Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
1207 // Closes the MXF file, writing the index and revised header.
1208 Result_t Finalize();
1215 mem_ptr<h__Reader> m_Reader;
1216 ASDCP_NO_COPY_CONSTRUCT(MXFReader);
1220 virtual ~MXFReader();
1222 // Warning: direct manipulation of MXF structures can interfere
1223 // with the normal operation of the wrapper. Caveat emptor!
1224 virtual MXF::OP1aHeader& OP1aHeader();
1225 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1226 virtual MXF::RIP& RIP();
1228 // Open the file for reading. The file must exist. Returns error if the
1229 // operation cannot be completed.
1230 Result_t OpenRead(const char* filename) const;
1232 // Returns RESULT_INIT if the file is not open.
1233 Result_t Close() const;
1235 // Fill an AudioDescriptor struct with the values from the file's header.
1236 // Returns RESULT_INIT if the file is not open.
1237 Result_t FillPictureDescriptor(PictureDescriptor&) const;
1239 // Fill a WriterInfo struct with the values from the file's header.
1240 // Returns RESULT_INIT if the file is not open.
1241 Result_t FillWriterInfo(WriterInfo&) const;
1243 // Reads a frame of essence from the MXF file. If the optional AESEncContext
1244 // argument is present, the essence is decrypted after reading. If the MXF
1245 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1246 // will contain the ciphertext frame data. If the HMACContext argument is
1247 // not NULL, the HMAC will be calculated (if the file supports it).
1248 // Returns RESULT_INIT if the file is not open, failure if the frame number is
1249 // out of range, or if optional decrypt or HAMC operations fail.
1250 Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1252 // Using the index table read from the footer partition, lookup the frame number
1253 // and return the offset into the file at which to read that frame of essence.
1254 // Returns RESULT_INIT if the file is not open, and RESULT_FRAME if the frame number is
1256 Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
1258 // Print debugging information to stream
1259 void DumpHeaderMetadata(FILE* = 0) const;
1260 void DumpIndex(FILE* = 0) const;
1264 // Stereoscopic Image support
1267 enum StereoscopicPhase_t
1275 JP2K::FrameBuffer Left;
1276 JP2K::FrameBuffer Right;
1278 SFrameBuffer(ui32_t size) {
1279 Left.Capacity(size);
1280 Right.Capacity(size);
1287 mem_ptr<h__SWriter> m_Writer;
1288 ASDCP_NO_COPY_CONSTRUCT(MXFSWriter);
1292 virtual ~MXFSWriter();
1294 // Warning: direct manipulation of MXF structures can interfere
1295 // with the normal operation of the wrapper. Caveat emptor!
1296 virtual MXF::OP1aHeader& OP1aHeader();
1297 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1298 virtual MXF::RIP& RIP();
1300 // Open the file for writing. The file must not exist. Returns error if
1301 // the operation cannot be completed or if nonsensical data is discovered
1302 // in the essence descriptor.
1303 Result_t OpenWrite(const char* filename, const WriterInfo&,
1304 const PictureDescriptor&, ui32_t HeaderSize = 16384);
1306 // Writes a pair of frames of essence to the MXF file. If the optional AESEncContext
1307 // argument is present, the essence is encrypted prior to writing.
1308 // Fails if the file is not open, is finalized, or an operating system
1310 Result_t WriteFrame(const SFrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
1312 // Writes a frame of essence to the MXF file. If the optional AESEncContext
1313 // argument is present, the essence is encrypted prior to writing.
1314 // Fails if the file is not open, is finalized, or an operating system
1315 // error occurs. Frames must be written in the proper phase (L-R-L-R),
1316 // RESULT_SPHASE will be returned if phase is reversed. The first frame
1317 // written must be left eye.
1318 Result_t WriteFrame(const FrameBuffer&, StereoscopicPhase_t phase,
1319 AESEncContext* = 0, HMACContext* = 0);
1321 // Closes the MXF file, writing the index and revised header. Returns
1322 // RESULT_SPHASE if WriteFrame was called an odd number of times.
1323 Result_t Finalize();
1330 mem_ptr<h__SReader> m_Reader;
1331 ASDCP_NO_COPY_CONSTRUCT(MXFSReader);
1335 virtual ~MXFSReader();
1337 // Warning: direct manipulation of MXF structures can interfere
1338 // with the normal operation of the wrapper. Caveat emptor!
1339 virtual MXF::OP1aHeader& OP1aHeader();
1340 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1341 virtual MXF::RIP& RIP();
1343 // Open the file for reading. The file must exist. Returns error if the
1344 // operation cannot be completed.
1345 Result_t OpenRead(const char* filename) const;
1347 // Returns RESULT_INIT if the file is not open.
1348 Result_t Close() const;
1350 // Fill an AudioDescriptor struct with the values from the file's header.
1351 // Returns RESULT_INIT if the file is not open.
1352 Result_t FillPictureDescriptor(PictureDescriptor&) const;
1354 // Fill a WriterInfo struct with the values from the file's header.
1355 // Returns RESULT_INIT if the file is not open.
1356 Result_t FillWriterInfo(WriterInfo&) const;
1358 // Reads a pair of frames of essence from the MXF file. If the optional AESEncContext
1359 // argument is present, the essence is decrypted after reading. If the MXF
1360 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1361 // will contain the ciphertext frame data. If the HMACContext argument is
1362 // not NULL, the HMAC will be calculated (if the file supports it).
1363 // Returns RESULT_INIT if the file is not open, failure if the frame number is
1364 // out of range, or if optional decrypt or HAMC operations fail.
1365 Result_t ReadFrame(ui32_t frame_number, SFrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1367 // Reads a frame of essence from the MXF file. If the optional AESEncContext
1368 // argument is present, the essence is decrypted after reading. If the MXF
1369 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1370 // will contain the ciphertext frame data. If the HMACContext argument is
1371 // not NULL, the HMAC will be calculated (if the file supports it).
1372 // Returns RESULT_INIT if the file is not open, failure if the frame number is
1373 // out of range, or if optional decrypt or HAMC operations fail.
1374 Result_t ReadFrame(ui32_t frame_number, StereoscopicPhase_t phase,
1375 FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1377 // Using the index table read from the footer partition, lookup the frame number
1378 // and return the offset into the file at which to read that frame of essence.
1379 // Returns RESULT_INIT if the file is not open, and RESULT_FRAME if the frame number is
1381 Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
1383 // Print debugging information to stream
1384 void DumpHeaderMetadata(FILE* = 0) const;
1385 void DumpIndex(FILE* = 0) const;
1389 //---------------------------------------------------------------------------------
1393 enum MIMEType_t { MT_BIN, MT_PNG, MT_OPENTYPE };
1395 struct TimedTextResourceDescriptor
1397 byte_t ResourceID[UUIDlen];
1400 TimedTextResourceDescriptor() : Type(MT_BIN) {}
1403 typedef std::list<TimedTextResourceDescriptor> ResourceList_t;
1405 struct TimedTextDescriptor
1407 Rational EditRate; //
1408 ui32_t ContainerDuration;
1409 byte_t AssetID[UUIDlen];
1410 std::string NamespaceName;
1411 std::string EncodingName;
1412 ResourceList_t ResourceList;
1414 TimedTextDescriptor() : ContainerDuration(0), EncodingName("UTF-8") {} // D-Cinema format is always UTF-8
1417 // Print debugging information to std::ostream
1418 std::ostream& operator << (std::ostream& strm, const TimedTextDescriptor& tinfo);
1419 // Print debugging information to stream (stderr default)
1420 void DescriptorDump(const TimedTextDescriptor&, FILE* = 0);
1423 class FrameBuffer : public ASDCP::FrameBuffer
1425 ASDCP_NO_COPY_CONSTRUCT(FrameBuffer); // TODO: should have copy construct
1428 byte_t m_AssetID[UUIDlen];
1429 std::string m_MIMEType;
1432 FrameBuffer() { memset(m_AssetID, 0, UUIDlen); }
1433 FrameBuffer(ui32_t size) { Capacity(size); memset(m_AssetID, 0, UUIDlen); }
1434 virtual ~FrameBuffer() {}
1436 inline const byte_t* AssetID() const { return m_AssetID; }
1437 inline void AssetID(const byte_t* buf) { memcpy(m_AssetID, buf, UUIDlen); }
1438 inline const char* MIMEType() const { return m_MIMEType.c_str(); }
1439 inline void MIMEType(const std::string& s) { m_MIMEType = s; }
1441 // Print debugging information to stream (stderr default)
1442 void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
1446 class IResourceResolver
1449 virtual ~IResourceResolver() {}
1450 virtual Result_t ResolveRID(const byte_t* uuid, FrameBuffer&) const = 0; // return data for RID
1454 class DCSubtitleParser
1456 class h__SubtitleParser;
1457 mem_ptr<h__SubtitleParser> m_Parser;
1458 ASDCP_NO_COPY_CONSTRUCT(DCSubtitleParser);
1462 virtual ~DCSubtitleParser();
1464 // Opens an XML file for reading, parses data to provide a complete
1465 // set of stream metadata for the MXFWriter below.
1466 Result_t OpenRead(const char* filename) const;
1468 // Parses an XML document to provide a complete set of stream metadata
1469 // for the MXFWriter below. The optional filename argument is used to
1470 // initialize the default resource resolver (see ReadAncillaryResource).
1471 Result_t OpenRead(const std::string& xml_doc, const char* filename = 0) const;
1473 // Fill a TimedTextDescriptor struct with the values from the file's contents.
1474 // Returns RESULT_INIT if the file is not open.
1475 Result_t FillTimedTextDescriptor(TimedTextDescriptor&) const;
1477 // Reads the complete Timed Text Resource into the given string.
1478 Result_t ReadTimedTextResource(std::string&) const;
1480 // Reads the Ancillary Resource having the given ID. Fails if the buffer
1481 // is too small or the resource does not exist. The optional Resolver
1482 // argument can be provided which will be used to retrieve the resource
1483 // having a particulat UUID. If a Resolver is not supplied, the default
1484 // internal resolver will return the contents of the file having the UUID
1485 // as the filename. The filename must exist in the same directory as the
1486 // XML file opened with OpenRead().
1487 Result_t ReadAncillaryResource(const byte_t* uuid, FrameBuffer&,
1488 const IResourceResolver* Resolver = 0) const;
1495 mem_ptr<h__Writer> m_Writer;
1496 ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
1500 virtual ~MXFWriter();
1502 // Warning: direct manipulation of MXF structures can interfere
1503 // with the normal operation of the wrapper. Caveat emptor!
1504 virtual MXF::OP1aHeader& OP1aHeader();
1505 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1506 virtual MXF::RIP& RIP();
1508 // Open the file for writing. The file must not exist. Returns error if
1509 // the operation cannot be completed or if nonsensical data is discovered
1510 // in the essence descriptor.
1511 Result_t OpenWrite(const char* filename, const WriterInfo&,
1512 const TimedTextDescriptor&, ui32_t HeaderSize = 16384);
1514 // Writes the Timed-Text Resource to the MXF file. The file must be UTF-8
1515 // encoded. If the optional AESEncContext argument is present, the essence
1516 // is encrypted prior to writing. Fails if the file is not open, is finalized,
1517 // or an operating system error occurs.
1518 // This method may only be called once, and it must be called before any
1519 // call to WriteAncillaryResource(). RESULT_STATE will be returned if these
1520 // conditions are not met.
1521 Result_t WriteTimedTextResource(const std::string& XMLDoc, AESEncContext* = 0, HMACContext* = 0);
1523 // Writes an Ancillary Resource to the MXF file. If the optional AESEncContext
1524 // argument is present, the essence is encrypted prior to writing.
1525 // Fails if the file is not open, is finalized, or an operating system
1526 // error occurs. RESULT_STATE will be returned if the method is called before
1527 // WriteTimedTextResource()
1528 Result_t WriteAncillaryResource(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
1530 // Closes the MXF file, writing the index and revised header.
1531 Result_t Finalize();
1538 mem_ptr<h__Reader> m_Reader;
1539 ASDCP_NO_COPY_CONSTRUCT(MXFReader);
1543 virtual ~MXFReader();
1545 // Warning: direct manipulation of MXF structures can interfere
1546 // with the normal operation of the wrapper. Caveat emptor!
1547 virtual MXF::OP1aHeader& OP1aHeader();
1548 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1549 virtual MXF::RIP& RIP();
1551 // Open the file for reading. The file must exist. Returns error if the
1552 // operation cannot be completed.
1553 Result_t OpenRead(const char* filename) const;
1555 // Returns RESULT_INIT if the file is not open.
1556 Result_t Close() const;
1558 // Fill a TimedTextDescriptor struct with the values from the file's header.
1559 // Returns RESULT_INIT if the file is not open.
1560 Result_t FillTimedTextDescriptor(TimedTextDescriptor&) const;
1562 // Fill a WriterInfo struct with the values from the file's header.
1563 // Returns RESULT_INIT if the file is not open.
1564 Result_t FillWriterInfo(WriterInfo&) const;
1566 // Reads the complete Timed Text Resource into the given string. Fails if the resource
1567 // is encrypted and AESDecContext is NULL (use the following method to retrieve the
1568 // raw ciphertet block).
1569 Result_t ReadTimedTextResource(std::string&, AESDecContext* = 0, HMACContext* = 0) const;
1571 // Reads the complete Timed Text Resource from the MXF file. If the optional AESEncContext
1572 // argument is present, the resource is decrypted after reading. If the MXF
1573 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1574 // will contain the ciphertext frame data. If the HMACContext argument is
1575 // not NULL, the HMAC will be calculated (if the file supports it).
1576 // Returns RESULT_INIT if the file is not open, failure if the frame number is
1577 // out of range, or if optional decrypt or HAMC operations fail.
1578 Result_t ReadTimedTextResource(FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1580 // Reads the timed-text resource having the given UUID from the MXF file. If the
1581 // optional AESEncContext argument is present, the resource is decrypted after
1582 // reading. If the MXF file is encrypted and the AESDecContext argument is NULL,
1583 // the frame buffer will contain the ciphertext frame data. If the HMACContext
1584 // argument is not NULL, the HMAC will be calculated (if the file supports it).
1585 // Returns RESULT_INIT if the file is not open, failure if the frame number is
1586 // out of range, or if optional decrypt or HAMC operations fail.
1587 Result_t ReadAncillaryResource(const byte_t* uuid, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1589 // Print debugging information to stream
1590 void DumpHeaderMetadata(FILE* = 0) const;
1591 void DumpIndex(FILE* = 0) const;
1593 } // namespace TimedText
1595 //---------------------------------------------------------------------------------
1599 struct DCDataDescriptor
1601 Rational EditRate; // Sample rate
1602 ui32_t ContainerDuration; // number of frames
1603 byte_t AssetID[UUIDlen]; // The UUID for the DCData track
1604 byte_t DataEssenceCoding[UUIDlen]; // The coding for the data carried
1607 // Print DCDataDescriptor to std::ostream
1608 std::ostream& operator << (std::ostream& strm, const DCDataDescriptor& ddesc);
1609 // Print debugging information to stream (stderr default)
1610 void DCDataDescriptorDump(const DCDataDescriptor&, FILE* = 0);
1613 class FrameBuffer : public ASDCP::FrameBuffer
1617 FrameBuffer(ui32_t size) { Capacity(size); }
1618 virtual ~FrameBuffer() {}
1620 // Print debugging information to stream (stderr default)
1621 void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
1624 // An object which opens and reads a DC Data file. The file is expected
1625 // to contain exactly one complete frame of DC data essence as an unwrapped (raw)
1627 class BytestreamParser
1629 class h__BytestreamParser;
1630 mem_ptr<h__BytestreamParser> m_Parser;
1631 ASDCP_NO_COPY_CONSTRUCT(BytestreamParser);
1635 virtual ~BytestreamParser();
1637 // Opens a file for reading, parses enough data to provide a complete
1638 // set of stream metadata for the MXFWriter below.
1639 // The frame buffer's PlaintextOffset parameter will be set to the first
1640 // byte of the data segment. Set this value to zero if you want
1641 // encrypted headers.
1642 Result_t OpenReadFrame(const char* filename, FrameBuffer&) const;
1644 // Fill a DCDataDescriptor struct with the values from the file's bytestream.
1645 // Returns RESULT_INIT if the file is not open.
1646 Result_t FillDCDataDescriptor(DCDataDescriptor&) const;
1649 // An object which reads a sequence of files containing DC Data.
1650 class SequenceParser
1652 class h__SequenceParser;
1653 mem_ptr<h__SequenceParser> m_Parser;
1654 ASDCP_NO_COPY_CONSTRUCT(SequenceParser);
1658 virtual ~SequenceParser();
1660 // Opens a directory for reading. The directory is expected to contain one or
1661 // more files, each containing the bytestream for exactly one frame. The files
1662 // must be named such that the frames are in temporal order when sorted
1663 // alphabetically by filename.
1664 Result_t OpenRead(const char* filename) const;
1666 // Opens a file sequence for reading. The sequence is expected to contain one or
1667 // more filenames, each naming a file containing the bytestream for exactly one
1669 Result_t OpenRead(const std::list<std::string>& file_list) const;
1671 // Fill a DCDataDescriptor struct with default values.
1672 // Returns RESULT_INIT if the directory is not open.
1673 Result_t FillDCDataDescriptor(DCDataDescriptor&) const;
1675 // Rewind the directory to the beginning.
1676 Result_t Reset() const;
1678 // Reads the next sequential frame in the directory and places it in the
1679 // frame buffer. Fails if the buffer is too small or the direcdtory
1680 // contains no more files.
1681 // The frame buffer's PlaintextOffset parameter will be set to the first
1682 // byte of the data segment. Set this value to zero if you want
1683 // encrypted headers.
1684 Result_t ReadFrame(FrameBuffer&) const;
1691 mem_ptr<h__Writer> m_Writer;
1692 ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
1696 virtual ~MXFWriter();
1698 // Warning: direct manipulation of MXF structures can interfere
1699 // with the normal operation of the wrapper. Caveat emptor!
1700 virtual MXF::OP1aHeader& OP1aHeader();
1701 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1702 virtual MXF::RIP& RIP();
1704 // Open the file for writing. The file must not exist. Returns error if
1705 // the operation cannot be completed or if nonsensical data is discovered
1706 // in the essence descriptor.
1707 Result_t OpenWrite(const char* filename, const WriterInfo&,
1708 const DCDataDescriptor&, ui32_t HeaderSize = 16384);
1710 // Writes a frame of essence to the MXF file. If the optional AESEncContext
1711 // argument is present, the essence is encrypted prior to writing.
1712 // Fails if the file is not open, is finalized, or an operating system
1714 Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
1716 // Closes the MXF file, writing the index and revised header.
1717 Result_t Finalize();
1724 mem_ptr<h__Reader> m_Reader;
1725 ASDCP_NO_COPY_CONSTRUCT(MXFReader);
1729 virtual ~MXFReader();
1731 // Warning: direct manipulation of MXF structures can interfere
1732 // with the normal operation of the wrapper. Caveat emptor!
1733 virtual MXF::OP1aHeader& OP1aHeader();
1734 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1735 virtual MXF::RIP& RIP();
1737 // Open the file for reading. The file must exist. Returns error if the
1738 // operation cannot be completed.
1739 Result_t OpenRead(const char* filename) const;
1741 // Returns RESULT_INIT if the file is not open.
1742 Result_t Close() const;
1744 // Fill a DCDataDescriptor struct with the values from the file's header.
1745 // Returns RESULT_INIT if the file is not open.
1746 Result_t FillDCDataDescriptor(DCDataDescriptor&) const;
1748 // Fill a WriterInfo struct with the values from the file's header.
1749 // Returns RESULT_INIT if the file is not open.
1750 Result_t FillWriterInfo(WriterInfo&) const;
1752 // Reads a frame of essence from the MXF file. If the optional AESEncContext
1753 // argument is present, the essence is decrypted after reading. If the MXF
1754 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1755 // will contain the ciphertext frame data. If the HMACContext argument is
1756 // not NULL, the HMAC will be calculated (if the file supports it).
1757 // Returns RESULT_INIT if the file is not open, failure if the frame number is
1758 // out of range, or if optional decrypt or HAMC operations fail.
1759 Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1761 // Using the index table read from the footer partition, lookup the frame number
1762 // and return the offset into the file at which to read that frame of essence.
1763 // Returns RESULT_INIT if the file is not open, and RESULT_RANGE if the frame number is
1765 Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
1767 // Print debugging information to stream
1768 void DumpHeaderMetadata(FILE* = 0) const;
1769 void DumpIndex(FILE* = 0) const;
1772 } // namespace DCData
1774 //---------------------------------------------------------------------------------
1778 struct AtmosDescriptor : public DCData::DCDataDescriptor
1780 ui32_t FirstFrame; // Frame number of the frame to align with the FFOA of the picture track
1781 ui16_t MaxChannelCount; // Max number of channels in bitstream
1782 ui16_t MaxObjectCount; // Max number of objects in bitstream
1783 byte_t AtmosID[UUIDlen]; // UUID of Atmos Project
1784 ui8_t AtmosVersion; // ATMOS Coder Version used to create bitstream
1787 // Print AtmosDescriptor to std::ostream
1788 std::ostream& operator << (std::ostream& strm, const AtmosDescriptor& adesc);
1789 // Print debugging information to stream (stderr default)
1790 void AtmosDescriptorDump(const AtmosDescriptor&, FILE* = 0);
1791 // Determine if a file is a raw atmos file
1792 bool IsDolbyAtmos(const char* filename);
1799 mem_ptr<h__Writer> m_Writer;
1800 ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
1804 virtual ~MXFWriter();
1806 // Warning: direct manipulation of MXF structures can interfere
1807 // with the normal operation of the wrapper. Caveat emptor!
1808 virtual MXF::OP1aHeader& OP1aHeader();
1809 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1810 virtual MXF::RIP& RIP();
1812 // Open the file for writing. The file must not exist. Returns error if
1813 // the operation cannot be completed or if nonsensical data is discovered
1814 // in the essence descriptor.
1815 Result_t OpenWrite(const char* filename, const WriterInfo&,
1816 const AtmosDescriptor&, ui32_t HeaderSize = 16384);
1818 // Writes a frame of essence to the MXF file. If the optional AESEncContext
1819 // argument is present, the essence is encrypted prior to writing.
1820 // Fails if the file is not open, is finalized, or an operating system
1822 Result_t WriteFrame(const DCData::FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
1824 // Closes the MXF file, writing the index and revised header.
1825 Result_t Finalize();
1832 mem_ptr<h__Reader> m_Reader;
1833 ASDCP_NO_COPY_CONSTRUCT(MXFReader);
1837 virtual ~MXFReader();
1839 // Warning: direct manipulation of MXF structures can interfere
1840 // with the normal operation of the wrapper. Caveat emptor!
1841 virtual MXF::OP1aHeader& OP1aHeader();
1842 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1843 virtual MXF::RIP& RIP();
1845 // Open the file for reading. The file must exist. Returns error if the
1846 // operation cannot be completed.
1847 Result_t OpenRead(const char* filename) const;
1849 // Returns RESULT_INIT if the file is not open.
1850 Result_t Close() const;
1852 // Fill an AtmosDescriptor struct with the values from the file's header.
1853 // Returns RESULT_INIT if the file is not open.
1854 Result_t FillAtmosDescriptor(AtmosDescriptor&) const;
1856 // Fill a WriterInfo struct with the values from the file's header.
1857 // Returns RESULT_INIT if the file is not open.
1858 Result_t FillWriterInfo(WriterInfo&) const;
1860 // Reads a frame of essence from the MXF file. If the optional AESEncContext
1861 // argument is present, the essence is decrypted after reading. If the MXF
1862 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1863 // will contain the ciphertext frame data. If the HMACContext argument is
1864 // not NULL, the HMAC will be calculated (if the file supports it).
1865 // Returns RESULT_INIT if the file is not open, failure if the frame number is
1866 // out of range, or if optional decrypt or HAMC operations fail.
1867 Result_t ReadFrame(ui32_t frame_number, DCData::FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1869 // Using the index table read from the footer partition, lookup the frame number
1870 // and return the offset into the file at which to read that frame of essence.
1871 // Returns RESULT_INIT if the file is not open, and RESULT_RANGE if the frame number is
1873 Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
1875 // Print debugging information to stream
1876 void DumpHeaderMetadata(FILE* = 0) const;
1877 void DumpIndex(FILE* = 0) const;
1880 } // namespace ATMOS
1884 } // namespace ASDCP
1887 #endif // _AS_DCP_H_