2 Copyright (c) 2003-2018, 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 a series of documents which includes 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 429-14:2008 Aux Data Track File
44 o SMPTE ST 330:2004 - UMID
45 o SMPTE ST 336:2001 - KLV
46 o SMPTE ST 377:2004 - MXF (old version, required)
47 o SMPTE ST 377-1:2011 - MXF
48 o SMPTE ST 377-4:2012 - MXF Multichannel Audio Labeling Framework
49 o SMPTE ST 390:2011 - MXF OP-Atom
50 o SMPTE ST 379-1:2009 - MXF Generic Container (GC)
51 o SMPTE ST 381-1:2005 - MPEG2 picture in GC
52 o SMPTE ST 422:2006 - JPEG 2000 picture in GC
53 o SMPTE ST 382:2007 - WAV/PCM sound in GC
54 o IETF RFC 2104 - HMAC/SHA1
55 o NIST FIPS 197 - AES (Rijndael) (via OpenSSL)
57 o MXF Interop Track File Specification
58 o MXF Interop Track File Essence Encryption Specification
59 o MXF Interop Operational Constraints Specification
60 - Note: the MXF Interop documents are not formally published.
61 Contact the asdcplib support address to get copies.
63 The following use cases are supported by the library:
65 o Write essence to a plaintext or ciphertext AS-DCP file:
66 o Read essence from a plaintext or ciphertext AS-DCP file:
67 MPEG2 Video Elementary Stream
69 JPEG 2000 stereoscopic codestream pairs
71 SMPTE 429-7 Timed Text XML with font and image resources
72 Aux Data (frame-wrapped synchronous blob)
73 Proposed Dolby (TM) Atmos track file
75 o Read header metadata from an AS-DCP file
77 This project depends upon the following libraries:
78 - OpenSSL http://www.openssl.org/
79 - Expat http://expat.sourceforge.net/ or
80 Xerces-C http://xerces.apache.org/xerces-c/
81 An XML library is not needed if you don't need support for SMPTE ST 429-5:2009.
88 #include <KM_fileio.h>
97 //--------------------------------------------------------------------------------
98 // common integer types
99 // supply your own by defining ASDCP_NO_BASE_TYPES
101 #ifndef ASDCP_NO_BASE_TYPES
102 typedef unsigned char byte_t;
104 typedef unsigned char ui8_t;
106 typedef unsigned short ui16_t;
108 typedef unsigned int ui32_t;
112 //--------------------------------------------------------------------------------
113 // convenience macros
115 // Convenience macros for managing return values in predicates
116 #define ASDCP_SUCCESS(v) (((v) < 0) ? 0 : 1)
117 #define ASDCP_FAILURE(v) (((v) < 0) ? 1 : 0)
120 // Returns RESULT_PTR if the given argument is NULL.
121 // See Result_t below for an explanation of RESULT_* symbols.
122 #define ASDCP_TEST_NULL(p) \
124 return ASDCP::RESULT_PTR; \
127 // Returns RESULT_PTR if the given argument is NULL. See Result_t
128 // below for an explanation of RESULT_* symbols. It then assumes
129 // that the argument is a pointer to a string and returns
130 // RESULT_NULL_STR if the first character is '\0'.
132 #define ASDCP_TEST_NULL_STR(p) \
133 ASDCP_TEST_NULL(p); \
134 if ( (p)[0] == '\0' ) { \
135 return ASDCP::RESULT_NULL_STR; \
138 // Produces copy constructor boilerplate. Allows convenient private
139 // declatarion of copy constructors to prevent the compiler from
140 // silently manufacturing default methods.
141 #define ASDCP_NO_COPY_CONSTRUCT(T) \
143 T& operator=(const T&)
145 //--------------------------------------------------------------------------------
146 // All library components are defined in the namespace ASDCP
150 // The version number declaration and explanation have moved to ../configure.ac
151 const char* Version();
153 // UUIDs are passed around as strings of UUIDlen bytes
154 const ui32_t UUIDlen = 16;
156 // Encryption keys are passed around as strings of KeyLen bytes
157 const ui32_t KeyLen = 16;
159 //---------------------------------------------------------------------------------
162 using Kumu::Result_t;
164 using Kumu::RESULT_FALSE;
165 using Kumu::RESULT_OK;
166 using Kumu::RESULT_FAIL;
167 using Kumu::RESULT_PTR;
168 using Kumu::RESULT_NULL_STR;
169 using Kumu::RESULT_ALLOC;
170 using Kumu::RESULT_PARAM;
171 using Kumu::RESULT_SMALLBUF;
172 using Kumu::RESULT_INIT;
173 using Kumu::RESULT_NOT_FOUND;
174 using Kumu::RESULT_NO_PERM;
175 using Kumu::RESULT_FILEOPEN;
176 using Kumu::RESULT_BADSEEK;
177 using Kumu::RESULT_READFAIL;
178 using Kumu::RESULT_WRITEFAIL;
179 using Kumu::RESULT_STATE;
180 using Kumu::RESULT_ENDOFFILE;
181 using Kumu::RESULT_CONFIG;
183 KM_DECLARE_RESULT(FORMAT, -101, "The file format is not proper OP-Atom/AS-DCP.");
184 KM_DECLARE_RESULT(RAW_ESS, -102, "Unknown raw essence file type.");
185 KM_DECLARE_RESULT(RAW_FORMAT, -103, "Raw essence format invalid.");
186 KM_DECLARE_RESULT(RANGE, -104, "Frame number out of range.");
187 KM_DECLARE_RESULT(CRYPT_CTX, -105, "AESEncContext required when writing to encrypted file.");
188 KM_DECLARE_RESULT(LARGE_PTO, -106, "Plaintext offset exceeds frame buffer size.");
189 KM_DECLARE_RESULT(CAPEXTMEM, -107, "Cannot resize externally allocated memory.");
190 KM_DECLARE_RESULT(CHECKFAIL, -108, "The check value did not decrypt correctly.");
191 KM_DECLARE_RESULT(HMACFAIL, -109, "HMAC authentication failure.");
192 KM_DECLARE_RESULT(HMAC_CTX, -110, "HMAC context required.");
193 KM_DECLARE_RESULT(CRYPT_INIT, -111, "Error initializing block cipher context.");
194 KM_DECLARE_RESULT(EMPTY_FB, -112, "Empty frame buffer.");
195 KM_DECLARE_RESULT(KLV_CODING, -113, "KLV coding error.");
196 KM_DECLARE_RESULT(SPHASE, -114, "Stereoscopic phase mismatch.");
197 KM_DECLARE_RESULT(SFORMAT, -115, "Rate mismatch, file may contain stereoscopic essence.");
199 //---------------------------------------------------------------------------------
200 // file identification
202 // The file accessors in this library implement a bounded set of essence types.
203 // This list will be expanded when support for new types is added to the library.
205 ESS_UNKNOWN, // the file is not a supported AS-DCP of AS-02 essence container
208 ESS_MPEG2_VES, // the file contains an MPEG-2 video elementary stream
210 // d-cinema essence types
211 ESS_JPEG_2000, // the file contains one or more JPEG 2000 codestreams
212 ESS_PCM_24b_48k, // the file contains one or more PCM audio pairs
213 ESS_PCM_24b_96k, // the file contains one or more PCM audio pairs
214 ESS_TIMED_TEXT, // the file contains an XML timed text document and one or more resources
215 ESS_JPEG_2000_S, // the file contains one or more JPEG 2000 codestream pairs (stereoscopic)
216 ESS_DCDATA_UNKNOWN, // the file contains one or more D-Cinema Data bytestreams
217 ESS_DCDATA_DOLBY_ATMOS, // the file contains one or more DolbyATMOS bytestreams
220 ESS_AS02_JPEG_2000, // the file contains one or more JPEG 2000 codestreams
221 ESS_AS02_PCM_24b_48k, // the file contains one or more PCM audio pairs, clip wrapped
222 ESS_AS02_PCM_24b_96k, // the file contains one or more PCM audio pairs, clip wrapped
223 ESS_AS02_TIMED_TEXT, // the file contains a TTML document and zero or more resources
224 ESS_AS02_ISXD, // the file contains an ISXD document stream (per SMPTE RDD 47)
225 ESS_AS02_ACES, // the file contains two or more ACES codestreams (per SMPTE ST 2067-50)
229 // Determine the type of essence contained in the given MXF file. RESULT_OK
230 // is returned if the file is successfully opened and contains a valid MXF
231 // stream. If there is an error, the result code will indicate the reason.
232 Result_t EssenceType(const std::string& filename, EssenceType_t& type);
234 // Determine the type of essence contained in the given raw file. RESULT_OK
235 // is returned if the file is successfully opened and contains a known
236 // stream type. If there is an error, the result code will indicate the reason.
237 Result_t RawEssenceType(const std::string& filename, EssenceType_t& type);
240 //---------------------------------------------------------------------------------
243 // A simple container for rational numbers.
250 Rational() : Numerator(0), Denominator(0) {}
251 Rational(i32_t n, i32_t d) : Numerator(n), Denominator(d) {}
253 inline double Quotient() const {
254 return (double)Numerator / (double)Denominator;
257 inline bool operator==(const Rational& rhs) const {
258 return ( rhs.Numerator == Numerator && rhs.Denominator == Denominator );
261 inline bool operator!=(const Rational& rhs) const {
262 return ( rhs.Numerator != Numerator || rhs.Denominator != Denominator );
265 inline bool operator<(const Rational& rhs) {
266 if ( Numerator < rhs.Numerator ) return true;
267 if ( Numerator == rhs.Numerator && Denominator < rhs.Denominator ) return true;
271 inline bool operator>(const Rational& rhs) {
272 if ( Numerator > rhs.Numerator ) return true;
273 if ( Numerator == rhs.Numerator && Denominator > rhs.Denominator ) return true;
278 // Encodes a rational number as a string having a single delimiter character between
279 // numerator and denominator. Retuns the buffer pointer to allow convenient in-line use.
280 const char* EncodeRational(const Rational&, char* str_buf, ui32_t buf_len, char delimiter = ' ');
282 // Decodes a rational number havng a single non-digit delimiter character between
283 // the numerator and denominator. Returns false if the string does not contain
284 // the expected syntax.
285 bool DecodeRational(const char* str_rat, Rational&);
288 // common edit rates, use these instead of hard coded constants
289 const Rational EditRate_24 = Rational(24,1);
290 const Rational EditRate_23_98 = Rational(24000,1001); // Not a DCI-compliant value!
291 const Rational EditRate_48 = Rational(48,1);
292 const Rational SampleRate_48k = Rational(48000,1);
293 const Rational SampleRate_96k = Rational(96000,1);
295 // Additional frame rates, see ST 428-11, ST 429-13
296 // These rates are new and not supported by all systems. Do not assume that
297 // a package made using one of these rates will work just anywhere!
298 const Rational EditRate_25 = Rational(25,1);
299 const Rational EditRate_30 = Rational(30,1);
300 const Rational EditRate_50 = Rational(50,1);
301 const Rational EditRate_60 = Rational(60,1);
302 const Rational EditRate_96 = Rational(96,1);
303 const Rational EditRate_100 = Rational(100,1);
304 const Rational EditRate_120 = Rational(120,1);
305 const Rational EditRate_192 = Rational(192,1);
306 const Rational EditRate_200 = Rational(200,1);
307 const Rational EditRate_240 = Rational(240,1);
309 // Archival frame rates, see ST 428-21
310 // These rates are new and not supported by all systems. Do not assume that
311 // a package made using one of these rates will work just anywhere!
312 const Rational EditRate_16 = Rational(16,1);
313 const Rational EditRate_18 = Rational(200,11); // 18.182
314 const Rational EditRate_20 = Rational(20,1);
315 const Rational EditRate_22 = Rational(240,11); // 21.818
318 // Non-reference counting container for internal member objects.
319 // Please do not use this class for any other purpose.
323 T* m_p; // the thing we point to
327 mem_ptr() : m_p(0) {}
328 mem_ptr(T* p) : m_p(p) {}
329 ~mem_ptr() { delete m_p; }
331 inline T& operator*() const { return *m_p; }
332 inline T* operator->() const { return m_p; }
333 inline operator T*()const { return m_p; }
334 inline const mem_ptr<T>& operator=(T* p) { set(p); return *this; }
335 inline T* set(T* p) { delete m_p; m_p = p; return m_p; }
336 inline T* get() const { return m_p; }
337 inline void release() { m_p = 0; }
338 inline bool empty() const { return m_p == 0; }
342 //---------------------------------------------------------------------------------
343 // WriterInfo class - encapsulates writer identification details used for
344 // OpenWrite() calls. Replace these values at runtime to identify your product.
346 // MXF files use SMPTE Universal Labels to identify data items. The set of Labels
347 // in a file is determined by the MXF Operational Pattern and any constraining
348 // documentation. There are currently two flavors of AS-DCP file in use: MXF Interop
349 // (AKA JPEG Interop) and SMPTE. The two differ in the values of three labels:
352 // Interop : 06 0e 2b 34 04 01 01 01 0d 01 02 01 10 00 00 00
353 // SMPTE : 06 0e 2b 34 04 01 01 02 0d 01 02 01 10 00 00 00
356 // Interop : 06 0e 2b 34 02 04 01 07 0d 01 03 01 02 7e 01 00
357 // SMPTE : 06 0e 2b 34 02 04 01 01 0d 01 03 01 02 7e 01 00
359 // GenericDescriptor/SubDescriptors:
360 // Interop : 06 0e 2b 34 01 01 01 02 06 01 01 04 06 10 00 00
361 // SMPTE : 06 0e 2b 34 01 01 01 09 06 01 01 04 06 10 00 00
363 // asdcplib will read any (otherwise valid) file which has any combination of the
364 // above values. When writing files, MXF Interop labels are used by default. To
365 // write a file containing SMPTE labels, replace the default label set value in
366 // the WriterInfo before calling OpenWrite()
380 byte_t ProductUUID[UUIDlen];
381 byte_t AssetUUID[UUIDlen];
382 byte_t ContextID[UUIDlen];
383 byte_t CryptographicKeyID[UUIDlen];
384 bool EncryptedEssence; // true if essence data is (or is going to be) encrypted
385 bool UsesHMAC; // true if HMAC exists or is to be calculated
386 std::string ProductVersion;
387 std::string CompanyName;
388 std::string ProductName;
389 LabelSet_t LabelSetType;
391 WriterInfo() : EncryptedEssence(false), UsesHMAC(false), LabelSetType(LS_MXF_INTEROP)
393 static byte_t default_ProductUUID_Data[UUIDlen] = {
394 0x43, 0x05, 0x9a, 0x1d, 0x04, 0x32, 0x41, 0x01,
395 0xb8, 0x3f, 0x73, 0x68, 0x15, 0xac, 0xf3, 0x1d };
397 memcpy(ProductUUID, default_ProductUUID_Data, UUIDlen);
398 memset(AssetUUID, 0, UUIDlen);
399 memset(ContextID, 0, UUIDlen);
400 memset(CryptographicKeyID, 0, UUIDlen);
402 ProductVersion = "Unreleased ";
403 ProductVersion += Version();
405 ProductName = "asdcplib";
409 // Print WriterInfo to std::ostream
410 std::ostream& operator << (std::ostream& strm, const WriterInfo& winfo);
411 // Print WriterInfo to stream, stderr by default.
412 void WriterInfoDump(const WriterInfo&, FILE* = 0);
414 //---------------------------------------------------------------------------------
415 // cryptographic support
417 // The following classes define interfaces to Rijndael contexts having the following properties:
419 // o CBC mode with 16 byte block size
420 const ui32_t CBC_KEY_SIZE = 16;
421 const ui32_t CBC_BLOCK_SIZE = 16;
422 const ui32_t HMAC_SIZE = 20;
428 mem_ptr<h__AESContext> m_Context;
429 ASDCP_NO_COPY_CONSTRUCT(AESEncContext);
435 // Initializes Rijndael CBC encryption context.
436 // Returns error if the key argument is NULL.
437 Result_t InitKey(const byte_t* key);
439 // Initializes 16 byte CBC Initialization Vector. This operation may be performed
440 // any number of times for a given key.
441 // Returns error if the i_vec argument is NULL.
442 Result_t SetIVec(const byte_t* i_vec);
443 Result_t GetIVec(byte_t* i_vec) const;
445 // Encrypt 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 EncryptBlock(const byte_t* pt_buf, byte_t* ct_buf, ui32_t block_size);
454 mem_ptr<h__AESContext> m_Context;
455 ASDCP_NO_COPY_CONSTRUCT(AESDecContext);
461 // Initializes Rijndael CBC decryption context.
462 // Returns error if the key argument is NULL.
463 Result_t InitKey(const byte_t* key);
465 // Initializes 16 byte CBC Initialization Vector. This operation may be performed
466 // any number of times for a given key.
467 // Returns error if the i_vec argument is NULL.
468 Result_t SetIVec(const byte_t* i_vec);
470 // Decrypt a block of data. The block size must be a multiple of CBC_BLOCK_SIZE.
471 // Returns error if either argument is NULL.
472 Result_t DecryptBlock(const byte_t* ct_buf, byte_t* pt_buf, ui32_t block_size);
478 class h__HMACContext;
479 mem_ptr<h__HMACContext> m_Context;
480 ASDCP_NO_COPY_CONSTRUCT(HMACContext);
486 // Initializes HMAC context. The key argument must point to a binary
487 // key that is CBC_KEY_SIZE bytes in length. Returns error if the key
489 Result_t InitKey(const byte_t* key, LabelSet_t);
491 // Reset internal state, allows repeated cycles of Update -> Finalize
494 // Add data to the digest. Returns error if the key argument is NULL or
495 // if the digest has been finalized.
496 Result_t Update(const byte_t* buf, ui32_t buf_len);
498 // Finalize digest. Returns error if the digest has already been finalized.
501 // Writes HMAC value to given buffer. buf must point to a writable area of
502 // memory that is at least HMAC_SIZE bytes in length. Returns error if the
503 // buf argument is NULL or if the digest has not been finalized.
504 Result_t GetHMACValue(byte_t* buf) const;
506 // Tests the given value against the finalized value in the object. buf must
507 // point to a readable area of memory that is at least HMAC_SIZE bytes in length.
508 // Returns error if the buf argument is NULL or if the values do ot match.
509 Result_t TestHMACValue(const byte_t* buf) const;
512 //---------------------------------------------------------------------------------
513 // frame buffer base class
515 // The supported essence types are stored using per-frame KLV packetization. The
516 // following class implements essence-neutral functionality for managing a buffer
517 // containing a frame of essence.
521 ASDCP_NO_COPY_CONSTRUCT(FrameBuffer);
524 byte_t* m_Data; // pointer to memory area containing frame data
525 ui32_t m_Capacity; // size of memory area pointed to by m_Data
526 bool m_OwnMem; // if false, m_Data points to externally allocated memory
527 ui32_t m_Size; // size of frame data in memory area pointed to by m_Data
528 ui32_t m_FrameNumber; // delivery-order frame number
530 // It is possible to read raw ciphertext from an encrypted AS-DCP file.
531 // After reading an encrypted AS-DCP file in raw mode, the frame buffer will
532 // contain the encrypted source value portion of the Encrypted Triplet, followed
533 // by the integrity pack, if it exists.
534 // The buffer will begin with the IV and CheckValue, followed by encrypted essence
535 // and optional integrity pack
536 // The SourceLength and PlaintextOffset values from the packet will be held in the
537 // following variables:
538 ui32_t m_SourceLength; // plaintext length (delivered plaintext+decrypted ciphertext)
539 ui32_t m_PlaintextOffset; // offset to first byte of ciphertext
543 virtual ~FrameBuffer();
545 // Instructs the object to use an externally allocated buffer. The external
546 // buffer will not be cleaned up by the frame buffer when it exits.
547 // Call with (0,0) to revert to internally allocated buffer.
548 // Returns error if the buf_addr argument is NULL and buf_size is non-zero.
549 Result_t SetData(byte_t* buf_addr, ui32_t buf_size);
551 // Sets the size of the internally allocate buffer. Returns RESULT_CAPEXTMEM
552 // if the object is using an externally allocated buffer via SetData();
553 // Resets content size to zero.
554 Result_t Capacity(ui32_t cap);
556 // returns the size of the buffer
557 inline ui32_t Capacity() const { return m_Capacity; }
559 // returns a const pointer to the essence data
560 inline const byte_t* RoData() const { return m_Data; }
562 // returns a non-const pointer to the essence data
563 inline byte_t* Data() { return m_Data; }
565 // set the size of the buffer's contents
566 inline ui32_t Size(ui32_t size) { return m_Size = size; }
568 // returns the size of the buffer's contents
569 inline ui32_t Size() const { return m_Size; }
571 // Sets the absolute frame number of this frame in the file in delivery order.
572 inline void FrameNumber(ui32_t num) { m_FrameNumber = num; }
574 // Returns the absolute frame number of this frame in the file in delivery order.
575 inline ui32_t FrameNumber() const { return m_FrameNumber; }
577 // Sets the length of the plaintext essence data
578 inline void SourceLength(ui32_t len) { m_SourceLength = len; }
580 // When this value is 0 (zero), the buffer contains only plaintext. When it is
581 // non-zero, the buffer contains raw ciphertext and the return value is the length
582 // of the original plaintext.
583 inline ui32_t SourceLength() const { return m_SourceLength; }
585 // Sets the offset into the buffer at which encrypted data begins
586 inline void PlaintextOffset(ui32_t ofst) { m_PlaintextOffset = ofst; }
588 // Returns offset into buffer of first byte of ciphertext.
589 inline ui32_t PlaintextOffset() const { return m_PlaintextOffset; }
592 //---------------------------------------------------------------------------------
593 // Accessors in the MXFReader and MXFWriter classes below return these types to
594 // provide direct access to MXF metadata structures declared in MXF.h and Metadata.h
597 // #include<Metadata.h> to use these
599 class OPAtomIndexFooter;
603 //---------------------------------------------------------------------------------
604 // MPEG2 video elementary stream support
609 // MPEG picture coding type
611 FRAME_U = 0x00, // Unknown
612 FRAME_I = 0x01, // I-Frame
613 FRAME_P = 0x02, // P-Frame
614 FRAME_B = 0x03 // B-Frame
617 // convert FrameType_t to char
618 inline char FrameTypeChar(FrameType_t type)
622 case FRAME_I: return 'I';
623 case FRAME_B: return 'B';
624 case FRAME_P: return 'P';
629 // Structure represents the metadata elements in the file header's
630 // MPEG2VideoDescriptor object.
631 struct VideoDescriptor
633 Rational EditRate; //
635 Rational SampleRate; //
636 ui8_t FrameLayout; //
637 ui32_t StoredWidth; //
638 ui32_t StoredHeight; //
639 Rational AspectRatio; //
640 ui32_t ComponentDepth; //
641 ui32_t HorizontalSubsampling; //
642 ui32_t VerticalSubsampling; //
643 ui8_t ColorSiting; //
644 ui8_t CodedContentType; //
647 ui8_t ProfileAndLevel; //
648 ui32_t ContainerDuration; //
651 // Print VideoDescriptor to std::ostream
652 std::ostream& operator << (std::ostream& strm, const VideoDescriptor& vdesc);
653 // Print VideoDescriptor to stream, stderr by default.
654 void VideoDescriptorDump(const VideoDescriptor&, FILE* = 0);
656 // A container for MPEG frame data.
657 class FrameBuffer : public ASDCP::FrameBuffer
659 ASDCP_NO_COPY_CONSTRUCT(FrameBuffer); // TODO: should have copy construct
662 FrameType_t m_FrameType;
663 ui8_t m_TemporalOffset;
669 m_FrameType(FRAME_U), m_TemporalOffset(0),
670 m_ClosedGOP(false), m_GOPStart(false) {}
672 FrameBuffer(ui32_t size) :
673 m_FrameType(FRAME_U), m_TemporalOffset(0),
674 m_ClosedGOP(false), m_GOPStart(false)
679 virtual ~FrameBuffer() {}
681 // Sets the MPEG frame type of the picture data in the frame buffer.
682 inline void FrameType(FrameType_t type) { m_FrameType = type; }
684 // Returns the MPEG frame type of the picture data in the frame buffer.
685 inline FrameType_t FrameType() const { return m_FrameType; }
687 // Sets the MPEG temporal offset of the picture data in the frame buffer.
688 inline void TemporalOffset(ui8_t offset) { m_TemporalOffset = offset; }
690 // Returns the MPEG temporal offset of the picture data in the frame buffer.
691 inline ui8_t TemporalOffset() const { return m_TemporalOffset; }
693 // Sets the MPEG GOP 'start' attribute for the frame buffer.
694 inline void GOPStart(bool start) { m_GOPStart = start; }
696 // True if the frame in the buffer is the first in the GOP (in transport order)
697 inline bool GOPStart() const { return m_GOPStart; }
699 // Sets the MPEG GOP 'closed' attribute for the frame buffer.
700 inline void ClosedGOP(bool closed) { m_ClosedGOP = closed; }
702 // Returns true if the frame in the buffer is from a closed GOP, false if
703 // the frame is from an open GOP. Always returns false unless GOPStart()
705 inline bool ClosedGOP() const { return m_ClosedGOP; }
707 // Print object state to stream, include n bytes of frame data if indicated.
708 // Default stream is stderr.
709 void Dump(FILE* = 0, ui32_t dump_len = 0) const;
713 // An object which opens and reads an MPEG2 Video Elementary Stream file. The call to
714 // OpenRead() reads metadata from the file and populates an internal VideoDescriptor object.
715 // Each subsequent call to ReadFrame() reads exactly one frame from the stream into the
716 // given FrameBuffer object.
720 mem_ptr<h__Parser> m_Parser;
721 ASDCP_NO_COPY_CONSTRUCT(Parser);
727 // Opens the stream for reading, parses enough data to provide a complete
728 // set of stream metadata for the MXFWriter below.
729 Result_t OpenRead(const std::string& filename) const;
731 // Fill a VideoDescriptor struct with the values from the file's header.
732 // Returns RESULT_INIT if the file is not open.
733 Result_t FillVideoDescriptor(VideoDescriptor&) const;
735 // Rewind the stream to the beginning.
736 Result_t Reset() const;
738 // Reads the next sequential frame in the input file and places it in the
739 // frame buffer. Fails if the buffer is too small or the stream is empty.
740 // The frame buffer's PlaintextOffset parameter will be set to the first
741 // data byte of the first slice. Set this value to zero if you want
742 // encrypted headers.
743 Result_t ReadFrame(FrameBuffer&) const;
746 // A class which creates and writes MPEG frame data to an AS-DCP format MXF file.
747 // Not yet implemented
751 mem_ptr<h__Writer> m_Writer;
752 ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
756 virtual ~MXFWriter();
758 // Warning: direct manipulation of MXF structures can interfere
759 // with the normal operation of the wrapper. Caveat emptor!
760 virtual MXF::OP1aHeader& OP1aHeader();
761 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
762 virtual MXF::RIP& RIP();
764 // Open the file for writing. The file must not exist. Returns error if
765 // the operation cannot be completed or if nonsensical data is discovered
766 // in the essence descriptor.
767 Result_t OpenWrite(const std::string& filename, const WriterInfo&,
768 const VideoDescriptor&, ui32_t HeaderSize = 16384);
770 // Writes a frame of essence to the MXF file. If the optional AESEncContext
771 // argument is present, the essence is encrypted prior to writing.
772 // Fails if the file is not open, is finalized, or an operating system
774 Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
776 // Closes the MXF file, writing the index and revised header.
780 // A class which reads MPEG frame data from an AS-DCP format MXF file.
784 mem_ptr<h__Reader> m_Reader;
785 ASDCP_NO_COPY_CONSTRUCT(MXFReader);
789 virtual ~MXFReader();
791 // Warning: direct manipulation of MXF structures can interfere
792 // with the normal operation of the wrapper. Caveat emptor!
793 virtual MXF::OP1aHeader& OP1aHeader();
794 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
795 virtual MXF::RIP& RIP();
797 // Open the file for reading. The file must exist. Returns error if the
798 // operation cannot be completed.
799 Result_t OpenRead(const std::string& filename) const;
801 // Returns RESULT_INIT if the file is not open.
802 Result_t Close() const;
804 // Fill a VideoDescriptor struct with the values from the file's header.
805 // Returns RESULT_INIT if the file is not open.
806 Result_t FillVideoDescriptor(VideoDescriptor&) const;
808 // Fill a WriterInfo struct with the values from the file's header.
809 // Returns RESULT_INIT if the file is not open.
810 Result_t FillWriterInfo(WriterInfo&) const;
812 // Reads a frame of essence from the MXF file. If the optional AESEncContext
813 // argument is present, the essence is decrypted after reading. If the MXF
814 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
815 // will contain the ciphertext frame data. If the HMACContext argument is
816 // not NULL, the HMAC will be calculated (if the file supports it).
817 // Returns RESULT_INIT if the file is not open, failure if the frame number is
818 // out of range, or if optional decrypt or HAMC operations fail.
819 Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
821 // Using the index table read from the footer partition, lookup the frame number
822 // and return the offset into the file at which to read that frame of essence.
823 // Returns RESULT_INIT if the file is not open, and RESULT_RANGE if the frame number is
825 Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
827 // Calculates the first frame in transport order of the GOP in which the requested
828 // frame is located. Calls ReadFrame() to fetch the frame at the calculated position.
829 // Returns RESULT_INIT if the file is not open.
830 Result_t ReadFrameGOPStart(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
832 // Calculates the first frame in transport order of the GOP in which the requested
833 // frame is located. Sets key_frame_number to the number of the frame at the calculated position.
834 // Returns RESULT_INIT if the file is not open.
835 Result_t FindFrameGOPStart(ui32_t frame_number, ui32_t& key_frame_number) const;
837 // Returns the type of the frame at the given position.
838 // Returns RESULT_INIT if the file is not open or RESULT_RANGE if the index is out of range.
839 Result_t FrameType(ui32_t frame_number, FrameType_t&) const;
841 // Print debugging information to stream
842 void DumpHeaderMetadata(FILE* = 0) const;
843 void DumpIndex(FILE* = 0) const;
847 //---------------------------------------------------------------------------------
854 // The default value of the ChannelFormat element of the AudioDescriptor struct
855 // is CF_NONE. If the value is set to one of the other ChannelFormat_t enum
856 // values, the file's Wave Audio Descriptor will contain a Channel Assignment
859 // The channel format should be one of (CF_CFG_1, CF_CFG_2, or CF_CFG_3) for
860 // SMPTE 429-2 files. It should normally be CF_NONE for JPEG Interop files, but
861 // the 429-2 may also be used.
863 enum ChannelFormat_t {
865 CF_CFG_1, // 5.1 with optional HI/VI
866 CF_CFG_2, // 6.1 (5.1 + center surround) with optional HI/VI
867 CF_CFG_3, // 7.1 (SDDS) with optional HI/VI
868 CF_CFG_4, // Wild Track Format
869 CF_CFG_5, // 7.1 DS with optional HI/VI
870 CF_CFG_6, // ST 377-4 (MCA) labels (see also ASDCP::MXF::decode_mca_string)
874 struct AudioDescriptor
876 Rational EditRate; // rate of frame wrapping
877 Rational AudioSamplingRate; // rate of audio sample
879 ui32_t ChannelCount; // number of channels
880 ui32_t QuantizationBits; // number of bits per single-channel sample
881 ui32_t BlockAlign; // number of bytes ber sample, all channels
883 ui32_t LinkedTrackID; //
884 ui32_t ContainerDuration; // number of frames
885 ChannelFormat_t ChannelFormat; // audio channel arrangement
888 // Print AudioDescriptor to std::ostream
889 std::ostream& operator << (std::ostream& strm, const AudioDescriptor& adesc);
890 // Print debugging information to stream (stderr default)
891 void AudioDescriptorDump(const AudioDescriptor&, FILE* = 0);
893 // Returns size in bytes of a single sample of data described by ADesc
894 inline ui32_t CalcSampleSize(const AudioDescriptor& ADesc)
896 return (ADesc.QuantizationBits / 8) * ADesc.ChannelCount;
899 // Returns number of samples per frame of data described by ADesc
900 inline ui32_t CalcSamplesPerFrame(const AudioDescriptor& ADesc)
902 double tmpd = ADesc.AudioSamplingRate.Quotient() / ADesc.EditRate.Quotient();
903 return (ui32_t)ceil(tmpd);
906 // Returns the size in bytes of a frame of data described by ADesc
907 inline ui32_t CalcFrameBufferSize(const AudioDescriptor& ADesc)
909 return CalcSampleSize(ADesc) * CalcSamplesPerFrame(ADesc);
913 class FrameBuffer : public ASDCP::FrameBuffer
917 FrameBuffer(ui32_t size) { Capacity(size); }
918 virtual ~FrameBuffer() {}
920 // Print debugging information to stream (stderr default)
921 void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
924 // An object which opens and reads a WAV file. The call to OpenRead() reads metadata from
925 // the file and populates an internal AudioDescriptor object. Each subsequent call to
926 // ReadFrame() reads exactly one frame from the stream into the given FrameBuffer object.
927 // A "frame" is either 2000 or 2002 samples, depending upon the value of PictureRate.
931 mem_ptr<h__WAVParser> m_Parser;
932 ASDCP_NO_COPY_CONSTRUCT(WAVParser);
936 virtual ~WAVParser();
938 // Opens the stream for reading, parses enough data to provide a complete
939 // set of stream metadata for the MXFWriter below. PictureRate controls
940 // ther frame rate for the MXF frame wrapping option.
941 Result_t OpenRead(const std::string& filename, const Rational& PictureRate) const;
943 // Fill an AudioDescriptor struct with the values from the file's header.
944 // Returns RESULT_INIT if the file is not open.
945 Result_t FillAudioDescriptor(AudioDescriptor&) const;
947 // Rewind the stream to the beginning.
948 Result_t Reset() const;
950 // Reads the next sequential frame in the input file and places it in the
951 // frame buffer. Fails if the buffer is too small or the stream is empty.
952 Result_t ReadFrame(FrameBuffer&) const;
954 Result_t Seek(ui32_t frame_number) const;
962 mem_ptr<h__Writer> m_Writer;
963 ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
967 virtual ~MXFWriter();
969 // Warning: direct manipulation of MXF structures can interfere
970 // with the normal operation of the wrapper. Caveat emptor!
971 virtual MXF::OP1aHeader& OP1aHeader();
972 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
973 virtual MXF::RIP& RIP();
975 // Open the file for writing. The file must not exist. Returns error if
976 // the operation cannot be completed or if nonsensical data is discovered
977 // in the essence descriptor.
978 Result_t OpenWrite(const std::string& filename, const WriterInfo&,
979 const AudioDescriptor&, ui32_t HeaderSize = 16384);
981 // Writes a frame of essence to the MXF file. If the optional AESEncContext
982 // argument is present, the essence is encrypted prior to writing.
983 // Fails if the file is not open, is finalized, or an operating system
985 Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
987 // Closes the MXF file, writing the index and revised header.
995 mem_ptr<h__Reader> m_Reader;
996 ASDCP_NO_COPY_CONSTRUCT(MXFReader);
1000 virtual ~MXFReader();
1002 // Warning: direct manipulation of MXF structures can interfere
1003 // with the normal operation of the wrapper. Caveat emptor!
1004 virtual MXF::OP1aHeader& OP1aHeader();
1005 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1006 virtual MXF::RIP& RIP();
1008 // Open the file for reading. The file must exist. Returns error if the
1009 // operation cannot be completed.
1010 Result_t OpenRead(const std::string& filename) const;
1012 // Returns RESULT_INIT if the file is not open.
1013 Result_t Close() const;
1015 // Fill an AudioDescriptor struct with the values from the file's header.
1016 // Returns RESULT_INIT if the file is not open.
1017 Result_t FillAudioDescriptor(AudioDescriptor&) const;
1019 // Fill a WriterInfo struct with the values from the file's header.
1020 // Returns RESULT_INIT if the file is not open.
1021 Result_t FillWriterInfo(WriterInfo&) const;
1023 // Reads a frame of essence from the MXF file. If the optional AESEncContext
1024 // argument is present, the essence is decrypted after reading. If the MXF
1025 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1026 // will contain the ciphertext frame data. If the HMACContext argument is
1027 // not NULL, the HMAC will be calculated (if the file supports it).
1028 // Returns RESULT_INIT if the file is not open, failure if the frame number is
1029 // out of range, or if optional decrypt or HAMC operations fail.
1030 Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1032 // Using the index table read from the footer partition, lookup the frame number
1033 // and return the offset into the file at which to read that frame of essence.
1034 // Returns RESULT_INIT if the file is not open, and RESULT_RANGE if the frame number is
1036 Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
1038 // Print debugging information to stream
1039 void DumpHeaderMetadata(FILE* = 0) const;
1040 void DumpIndex(FILE* = 0) const;
1044 //---------------------------------------------------------------------------------
1048 const ui32_t MaxComponents = 3;
1049 const ui32_t MaxPrecincts = 32; // ISO 15444-1 Annex A.6.1
1050 const ui32_t MaxDefaults = 256; // made up
1051 const ui8_t MaxCapabilities = 32;
1052 const ui16_t MaxPRFN = 4;
1053 const ui16_t MaxCPFN = 4;
1056 struct ImageComponent_t // ISO 15444-1 Annex A.5.1
1063 struct CodingStyleDefault_t // ISO 15444-1 Annex A.6.1
1069 ui8_t ProgressionOrder;
1070 ui8_t NumberOfLayers[sizeof(ui16_t)];
1071 ui8_t MultiCompTransform;
1076 ui8_t DecompositionLevels;
1077 ui8_t CodeblockWidth;
1078 ui8_t CodeblockHeight;
1079 ui8_t CodeblockStyle;
1080 ui8_t Transformation;
1081 ui8_t PrecinctSize[MaxPrecincts];
1085 struct QuantizationDefault_t // ISO 15444-1 Annex A.6.4
1088 ui8_t SPqcd[MaxDefaults];
1092 struct ExtendedCapabilities_t // ISO 15444-1 Annex A.5.2
1094 ui32_t Pcap; // Pcap = 0 means that no extended capabilities are required
1095 ui16_t Ccap[MaxCapabilities]; // Ccap^i in ISO/IEC 15444-1 corresponds to Ccap[i -1]
1098 struct Profile_t // ISO 15444-1
1100 ui16_t N; // N = 0 means that the profile is signaled through Rsiz exclusively
1101 ui16_t Pprf[MaxPRFN]; // Pprf^i in ISO/IEC 15444-1 corresponds to Pprf[i -1]
1104 struct CorrespondingProfile_t // ISO 15444-1
1106 ui16_t N; // N = 0 means that no corresponding profile is signaled
1107 ui16_t Pcpf[MaxCPFN]; // Pcpf^i in ISO/IEC 15444-1 corresponds to Pcpf[i -1]
1112 struct PictureDescriptor
1115 ui32_t ContainerDuration;
1116 Rational SampleRate;
1118 ui32_t StoredHeight;
1119 Rational AspectRatio;
1130 ImageComponent_t ImageComponents[MaxComponents];
1131 CodingStyleDefault_t CodingStyleDefault;
1132 QuantizationDefault_t QuantizationDefault;
1133 ExtendedCapabilities_t ExtendedCapabilities;
1135 CorrespondingProfile_t CorrespondingProfile;
1138 // Print debugging information to std::ostream
1139 std::ostream& operator << (std::ostream& strm, const PictureDescriptor& pdesc);
1140 // Print debugging information to stream (stderr default)
1141 void PictureDescriptorDump(const PictureDescriptor&, FILE* = 0);
1144 class FrameBuffer : public ASDCP::FrameBuffer
1148 FrameBuffer(ui32_t size) { Capacity(size); }
1149 virtual ~FrameBuffer() {}
1151 // Print debugging information to stream (stderr default)
1152 void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
1156 // An object which opens and reads a JPEG 2000 codestream file. The file is expected
1157 // to contain exactly one complete frame of picture essence as an unwrapped (raw)
1158 // ISO/IEC 15444 codestream.
1159 class CodestreamParser
1161 class h__CodestreamParser;
1162 mem_ptr<h__CodestreamParser> m_Parser;
1163 ASDCP_NO_COPY_CONSTRUCT(CodestreamParser);
1167 virtual ~CodestreamParser();
1169 // Opens a file for reading, parses enough data to provide a complete
1170 // set of stream metadata for the MXFWriter below.
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 OpenReadFrame(const std::string& filename, FrameBuffer&) const;
1176 // Fill a PictureDescriptor struct with the values from the file's codestream.
1177 // Returns RESULT_INIT if the file is not open.
1178 Result_t FillPictureDescriptor(PictureDescriptor&) const;
1181 // Parses the data in the frame buffer to fill in the picture descriptor. Copies
1182 // the offset of the image data into start_of_data. Returns error if the parser fails.
1183 Result_t ParseMetadataIntoDesc(const FrameBuffer&, PictureDescriptor&, byte_t* start_of_data = 0);
1185 // An object which reads a sequence of files containing JPEG 2000 pictures.
1186 class SequenceParser
1188 class h__SequenceParser;
1189 mem_ptr<h__SequenceParser> m_Parser;
1190 ASDCP_NO_COPY_CONSTRUCT(SequenceParser);
1194 virtual ~SequenceParser();
1196 // Opens a directory for reading. The directory is expected to contain one or
1197 // more files, each containing the codestream for exactly one picture. The
1198 // files must be named such that the frames are in temporal order when sorted
1199 // alphabetically by filename. The parser will automatically parse enough data
1200 // from the first file to provide a complete set of stream metadata for the
1201 // MXFWriter below. If the "pedantic" parameter is given and is true, the
1202 // parser will check the metadata for each codestream and fail if a
1203 // mismatch is detected.
1204 Result_t OpenRead(const std::string& filename, bool pedantic = false) const;
1206 // Opens a file sequence for reading. The sequence is expected to contain one or
1207 // more filenames, each naming a file containing the codestream for exactly one
1208 // picture. The parser will automatically parse enough data
1209 // from the first file to provide a complete set of stream metadata for the
1210 // MXFWriter below. If the "pedantic" parameter is given and is true, the
1211 // parser will check the metadata for each codestream and fail if a
1212 // mismatch is detected.
1213 Result_t OpenRead(const std::list<std::string>& file_list, bool pedantic = false) const;
1215 // Fill a PictureDescriptor struct with the values from the first file's codestream.
1216 // Returns RESULT_INIT if the directory is not open.
1217 Result_t FillPictureDescriptor(PictureDescriptor&) const;
1219 // Rewind the directory to the beginning.
1220 Result_t Reset() const;
1222 // Reads the next sequential frame in the directory and places it in the
1223 // frame buffer. Fails if the buffer is too small or the direcdtory
1224 // contains no more files.
1225 // The frame buffer's PlaintextOffset parameter will be set to the first
1226 // byte of the data segment. Set this value to zero if you want
1227 // encrypted headers.
1228 Result_t ReadFrame(FrameBuffer&) const;
1236 mem_ptr<h__Writer> m_Writer;
1237 ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
1241 virtual ~MXFWriter();
1243 // Warning: direct manipulation of MXF structures can interfere
1244 // with the normal operation of the wrapper. Caveat emptor!
1245 virtual MXF::OP1aHeader& OP1aHeader();
1246 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1247 virtual MXF::RIP& RIP();
1249 // Open the file for writing. The file must not exist. Returns error if
1250 // the operation cannot be completed or if nonsensical data is discovered
1251 // in the essence descriptor.
1252 Result_t OpenWrite(const std::string& filename, const WriterInfo&,
1253 const PictureDescriptor&, ui32_t HeaderSize = 16384);
1255 // Writes a frame of essence to the MXF file. If the optional AESEncContext
1256 // argument is present, the essence is encrypted prior to writing.
1257 // Fails if the file is not open, is finalized, or an operating system
1259 Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
1261 // Closes the MXF file, writing the index and revised header.
1262 Result_t Finalize();
1269 mem_ptr<h__Reader> m_Reader;
1270 ASDCP_NO_COPY_CONSTRUCT(MXFReader);
1274 virtual ~MXFReader();
1276 // Warning: direct manipulation of MXF structures can interfere
1277 // with the normal operation of the wrapper. Caveat emptor!
1278 virtual MXF::OP1aHeader& OP1aHeader();
1279 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1280 virtual MXF::RIP& RIP();
1282 // Open the file for reading. The file must exist. Returns error if the
1283 // operation cannot be completed.
1284 Result_t OpenRead(const std::string& filename) const;
1286 // Returns RESULT_INIT if the file is not open.
1287 Result_t Close() const;
1289 // Fill an AudioDescriptor struct with the values from the file's header.
1290 // Returns RESULT_INIT if the file is not open.
1291 Result_t FillPictureDescriptor(PictureDescriptor&) const;
1293 // Fill a WriterInfo struct with the values from the file's header.
1294 // Returns RESULT_INIT if the file is not open.
1295 Result_t FillWriterInfo(WriterInfo&) const;
1297 // Reads a frame of essence from the MXF file. If the optional AESEncContext
1298 // argument is present, the essence is decrypted after reading. If the MXF
1299 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1300 // will contain the ciphertext frame data. If the HMACContext argument is
1301 // not NULL, the HMAC will be calculated (if the file supports it).
1302 // Returns RESULT_INIT if the file is not open, failure if the frame number is
1303 // out of range, or if optional decrypt or HAMC operations fail.
1304 Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1306 // Using the index table read from the footer partition, lookup the frame number
1307 // and return the offset into the file at which to read that frame of essence.
1308 // Returns RESULT_INIT if the file is not open, and RESULT_FRAME if the frame number is
1310 Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
1312 // Print debugging information to stream
1313 void DumpHeaderMetadata(FILE* = 0) const;
1314 void DumpIndex(FILE* = 0) const;
1318 // Stereoscopic Image support
1321 enum StereoscopicPhase_t
1329 JP2K::FrameBuffer Left;
1330 JP2K::FrameBuffer Right;
1332 SFrameBuffer(ui32_t size) {
1333 Left.Capacity(size);
1334 Right.Capacity(size);
1341 mem_ptr<h__SWriter> m_Writer;
1342 ASDCP_NO_COPY_CONSTRUCT(MXFSWriter);
1346 virtual ~MXFSWriter();
1348 // Warning: direct manipulation of MXF structures can interfere
1349 // with the normal operation of the wrapper. Caveat emptor!
1350 virtual MXF::OP1aHeader& OP1aHeader();
1351 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1352 virtual MXF::RIP& RIP();
1354 // Open the file for writing. The file must not exist. Returns error if
1355 // the operation cannot be completed or if nonsensical data is discovered
1356 // in the essence descriptor.
1357 Result_t OpenWrite(const std::string& filename, const WriterInfo&,
1358 const PictureDescriptor&, ui32_t HeaderSize = 16384);
1360 // Writes a pair of frames of essence to the MXF file. If the optional AESEncContext
1361 // argument is present, the essence is encrypted prior to writing.
1362 // Fails if the file is not open, is finalized, or an operating system
1364 Result_t WriteFrame(const SFrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
1366 // Writes a frame of essence to the MXF file. If the optional AESEncContext
1367 // argument is present, the essence is encrypted prior to writing.
1368 // Fails if the file is not open, is finalized, or an operating system
1369 // error occurs. Frames must be written in the proper phase (L-R-L-R),
1370 // RESULT_SPHASE will be returned if phase is reversed. The first frame
1371 // written must be left eye.
1372 Result_t WriteFrame(const FrameBuffer&, StereoscopicPhase_t phase,
1373 AESEncContext* = 0, HMACContext* = 0);
1375 // Closes the MXF file, writing the index and revised header. Returns
1376 // RESULT_SPHASE if WriteFrame was called an odd number of times.
1377 Result_t Finalize();
1384 mem_ptr<h__SReader> m_Reader;
1385 ASDCP_NO_COPY_CONSTRUCT(MXFSReader);
1389 virtual ~MXFSReader();
1391 // Warning: direct manipulation of MXF structures can interfere
1392 // with the normal operation of the wrapper. Caveat emptor!
1393 virtual MXF::OP1aHeader& OP1aHeader();
1394 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1395 virtual MXF::RIP& RIP();
1397 // Open the file for reading. The file must exist. Returns error if the
1398 // operation cannot be completed.
1399 Result_t OpenRead(const std::string& filename) const;
1401 // Returns RESULT_INIT if the file is not open.
1402 Result_t Close() const;
1404 // Fill an AudioDescriptor struct with the values from the file's header.
1405 // Returns RESULT_INIT if the file is not open.
1406 Result_t FillPictureDescriptor(PictureDescriptor&) const;
1408 // Fill a WriterInfo struct with the values from the file's header.
1409 // Returns RESULT_INIT if the file is not open.
1410 Result_t FillWriterInfo(WriterInfo&) const;
1412 // Reads a pair of frames of essence from the MXF file. If the optional AESEncContext
1413 // argument is present, the essence is decrypted after reading. If the MXF
1414 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1415 // will contain the ciphertext frame data. If the HMACContext argument is
1416 // not NULL, the HMAC will be calculated (if the file supports it).
1417 // Returns RESULT_INIT if the file is not open, failure if the frame number is
1418 // out of range, or if optional decrypt or HAMC operations fail.
1419 Result_t ReadFrame(ui32_t frame_number, SFrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1421 // Reads a frame of essence from the MXF file. If the optional AESEncContext
1422 // argument is present, the essence is decrypted after reading. If the MXF
1423 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1424 // will contain the ciphertext frame data. If the HMACContext argument is
1425 // not NULL, the HMAC will be calculated (if the file supports it).
1426 // Returns RESULT_INIT if the file is not open, failure if the frame number is
1427 // out of range, or if optional decrypt or HAMC operations fail.
1428 Result_t ReadFrame(ui32_t frame_number, StereoscopicPhase_t phase,
1429 FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1431 // Using the index table read from the footer partition, lookup the frame number
1432 // and return the offset into the file at which to read that frame of essence.
1433 // Returns RESULT_INIT if the file is not open, and RESULT_FRAME if the frame number is
1435 Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
1437 // Print debugging information to stream
1438 void DumpHeaderMetadata(FILE* = 0) const;
1439 void DumpIndex(FILE* = 0) const;
1443 //---------------------------------------------------------------------------------
1447 enum MIMEType_t { MT_BIN, MT_PNG, MT_OPENTYPE };
1449 struct TimedTextResourceDescriptor
1451 byte_t ResourceID[UUIDlen];
1454 TimedTextResourceDescriptor() : Type(MT_BIN) {}
1457 typedef std::list<TimedTextResourceDescriptor> ResourceList_t;
1459 struct TimedTextDescriptor
1461 Rational EditRate; //
1462 ui32_t ContainerDuration;
1463 byte_t AssetID[UUIDlen];
1464 std::string NamespaceName;
1465 std::string EncodingName;
1466 ResourceList_t ResourceList;
1468 TimedTextDescriptor() : ContainerDuration(0), EncodingName("UTF-8") {} // D-Cinema format is always UTF-8
1471 // Print debugging information to std::ostream
1472 std::ostream& operator << (std::ostream& strm, const TimedTextDescriptor& tinfo);
1473 // Print debugging information to stream (stderr default)
1474 void DescriptorDump(const TimedTextDescriptor&, FILE* = 0);
1477 class FrameBuffer : public ASDCP::FrameBuffer
1479 ASDCP_NO_COPY_CONSTRUCT(FrameBuffer); // TODO: should have copy construct
1482 byte_t m_AssetID[UUIDlen];
1483 std::string m_MIMEType;
1486 FrameBuffer() { memset(m_AssetID, 0, UUIDlen); }
1487 FrameBuffer(ui32_t size) { Capacity(size); memset(m_AssetID, 0, UUIDlen); }
1488 virtual ~FrameBuffer() {}
1490 inline const byte_t* AssetID() const { return m_AssetID; }
1491 inline void AssetID(const byte_t* buf) { memcpy(m_AssetID, buf, UUIDlen); }
1492 inline const char* MIMEType() const { return m_MIMEType.c_str(); }
1493 inline void MIMEType(const std::string& s) { m_MIMEType = s; }
1495 // Print debugging information to stream (stderr default)
1496 void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
1499 // An abstract base for a lookup service that returns the resource data
1500 // identified by the given ancillary resource id.
1502 class IResourceResolver
1505 virtual ~IResourceResolver() {}
1506 virtual Result_t ResolveRID(const byte_t* uuid, FrameBuffer&) const = 0; // return data for RID
1509 // Resolves resource references by testing the named directory for file names containing
1510 // the respective UUID.
1512 class LocalFilenameResolver : public ASDCP::TimedText::IResourceResolver
1514 std::string m_Dirname;
1515 ASDCP_NO_COPY_CONSTRUCT(LocalFilenameResolver);
1518 LocalFilenameResolver();
1519 virtual ~LocalFilenameResolver();
1520 Result_t OpenRead(const std::string& dirname);
1521 Result_t ResolveRID(const byte_t* uuid, FrameBuffer& FrameBuf) const;
1525 class DCSubtitleParser
1527 class h__SubtitleParser;
1528 mem_ptr<h__SubtitleParser> m_Parser;
1529 ASDCP_NO_COPY_CONSTRUCT(DCSubtitleParser);
1533 virtual ~DCSubtitleParser();
1535 // Opens an XML file for reading, parses data to provide a complete
1536 // set of stream metadata for the MXFWriter below.
1537 Result_t OpenRead(const std::string& filename) const;
1539 // Parses an XML document to provide a complete set of stream metadata
1540 // for the MXFWriter below. The optional filename argument is used to
1541 // initialize the default resource resolver (see ReadAncillaryResource).
1542 Result_t OpenRead(const std::string& xml_doc, const std::string& filename) const;
1544 // Fill a TimedTextDescriptor struct with the values from the file's contents.
1545 // Returns RESULT_INIT if the file is not open.
1546 Result_t FillTimedTextDescriptor(TimedTextDescriptor&) const;
1548 // Reads the complete Timed Text Resource into the given string.
1549 Result_t ReadTimedTextResource(std::string&) const;
1551 // Reads the Ancillary Resource having the given ID. Fails if the buffer
1552 // is too small or the resource does not exist. The optional Resolver
1553 // argument can be provided which will be used to retrieve the resource
1554 // having a particulat UUID. If a Resolver is not supplied, the default
1555 // internal resolver will return the contents of the file having the UUID
1556 // as the filename. The filename must exist in the same directory as the
1557 // XML file opened with OpenRead().
1558 Result_t ReadAncillaryResource(const byte_t* uuid, FrameBuffer&,
1559 const IResourceResolver* Resolver = 0) const;
1566 mem_ptr<h__Writer> m_Writer;
1567 ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
1571 virtual ~MXFWriter();
1573 // Warning: direct manipulation of MXF structures can interfere
1574 // with the normal operation of the wrapper. Caveat emptor!
1575 virtual MXF::OP1aHeader& OP1aHeader();
1576 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1577 virtual MXF::RIP& RIP();
1579 // Open the file for writing. The file must not exist. Returns error if
1580 // the operation cannot be completed or if nonsensical data is discovered
1581 // in the essence descriptor.
1582 Result_t OpenWrite(const std::string& filename, const WriterInfo&,
1583 const TimedTextDescriptor&, ui32_t HeaderSize = 16384);
1585 // Writes the Timed-Text Resource to the MXF file. The file must be UTF-8
1586 // encoded. If the optional AESEncContext argument is present, the essence
1587 // is encrypted prior to writing. Fails if the file is not open, is finalized,
1588 // or an operating system error occurs.
1589 // This method may only be called once, and it must be called before any
1590 // call to WriteAncillaryResource(). RESULT_STATE will be returned if these
1591 // conditions are not met.
1592 Result_t WriteTimedTextResource(const std::string& XMLDoc, AESEncContext* = 0, HMACContext* = 0);
1594 // Writes an Ancillary Resource to the MXF file. If the optional AESEncContext
1595 // argument is present, the essence is encrypted prior to writing.
1596 // Fails if the file is not open, is finalized, or an operating system
1597 // error occurs. RESULT_STATE will be returned if the method is called before
1598 // WriteTimedTextResource()
1599 Result_t WriteAncillaryResource(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
1601 // Closes the MXF file, writing the index and revised header.
1602 Result_t Finalize();
1609 mem_ptr<h__Reader> m_Reader;
1610 ASDCP_NO_COPY_CONSTRUCT(MXFReader);
1614 virtual ~MXFReader();
1616 // Warning: direct manipulation of MXF structures can interfere
1617 // with the normal operation of the wrapper. Caveat emptor!
1618 virtual MXF::OP1aHeader& OP1aHeader();
1619 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1620 virtual MXF::RIP& RIP();
1622 // Open the file for reading. The file must exist. Returns error if the
1623 // operation cannot be completed.
1624 Result_t OpenRead(const std::string& filename) const;
1626 // Returns RESULT_INIT if the file is not open.
1627 Result_t Close() const;
1629 // Fill a TimedTextDescriptor struct with the values from the file's header.
1630 // Returns RESULT_INIT if the file is not open.
1631 Result_t FillTimedTextDescriptor(TimedTextDescriptor&) const;
1633 // Fill a WriterInfo struct with the values from the file's header.
1634 // Returns RESULT_INIT if the file is not open.
1635 Result_t FillWriterInfo(WriterInfo&) const;
1637 // Reads the complete Timed Text Resource into the given string. Fails if the resource
1638 // is encrypted and AESDecContext is NULL (use the following method to retrieve the
1639 // raw ciphertet block).
1640 Result_t ReadTimedTextResource(std::string&, AESDecContext* = 0, HMACContext* = 0) const;
1642 // Reads the complete Timed Text Resource from the MXF file. If the optional AESEncContext
1643 // argument is present, the resource is decrypted after reading. If the MXF
1644 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1645 // will contain the ciphertext frame data. If the HMACContext argument is
1646 // not NULL, the HMAC will be calculated (if the file supports it).
1647 // Returns RESULT_INIT if the file is not open, failure if the frame number is
1648 // out of range, or if optional decrypt or HAMC operations fail.
1649 Result_t ReadTimedTextResource(FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1651 // Reads the timed-text resource having the given UUID from the MXF file. If the
1652 // optional AESEncContext argument is present, the resource is decrypted after
1653 // reading. If the MXF file is encrypted and the AESDecContext argument is NULL,
1654 // the frame buffer will contain the ciphertext frame data. If the HMACContext
1655 // argument is not NULL, the HMAC will be calculated (if the file supports it).
1656 // Returns RESULT_INIT if the file is not open, failure if the frame number is
1657 // out of range, or if optional decrypt or HAMC operations fail.
1658 Result_t ReadAncillaryResource(const byte_t* uuid, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1660 // Print debugging information to stream
1661 void DumpHeaderMetadata(FILE* = 0) const;
1662 void DumpIndex(FILE* = 0) const;
1664 } // namespace TimedText
1666 //---------------------------------------------------------------------------------
1670 struct DCDataDescriptor
1672 Rational EditRate; // Sample rate
1673 ui32_t ContainerDuration; // number of frames
1674 byte_t AssetID[UUIDlen]; // The UUID for the DCData track
1675 byte_t DataEssenceCoding[UUIDlen]; // The coding for the data carried
1678 // Print DCDataDescriptor to std::ostream
1679 std::ostream& operator << (std::ostream& strm, const DCDataDescriptor& ddesc);
1680 // Print debugging information to stream (stderr default)
1681 void DCDataDescriptorDump(const DCDataDescriptor&, FILE* = 0);
1684 class FrameBuffer : public ASDCP::FrameBuffer
1688 FrameBuffer(ui32_t size) { Capacity(size); }
1689 virtual ~FrameBuffer() {}
1691 // Print debugging information to stream (stderr default)
1692 void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
1695 // An object which opens and reads a DC Data file. The file is expected
1696 // to contain exactly one complete frame of DC data essence as an unwrapped (raw)
1698 class BytestreamParser
1700 class h__BytestreamParser;
1701 mem_ptr<h__BytestreamParser> m_Parser;
1702 ASDCP_NO_COPY_CONSTRUCT(BytestreamParser);
1706 virtual ~BytestreamParser();
1708 // Opens a file for reading, parses enough data to provide a complete
1709 // set of stream metadata for the MXFWriter below.
1710 // The frame buffer's PlaintextOffset parameter will be set to the first
1711 // byte of the data segment. Set this value to zero if you want
1712 // encrypted headers.
1713 Result_t OpenReadFrame(const std::string& filename, FrameBuffer&) const;
1715 // Fill a DCDataDescriptor struct with the values from the file's bytestream.
1716 // Returns RESULT_INIT if the file is not open.
1717 Result_t FillDCDataDescriptor(DCDataDescriptor&) const;
1720 // An object which reads a sequence of files containing DC Data.
1721 class SequenceParser
1723 class h__SequenceParser;
1724 mem_ptr<h__SequenceParser> m_Parser;
1725 ASDCP_NO_COPY_CONSTRUCT(SequenceParser);
1729 virtual ~SequenceParser();
1731 // Opens a directory for reading. The directory is expected to contain one or
1732 // more files, each containing the bytestream for exactly one frame. The files
1733 // must be named such that the frames are in temporal order when sorted
1734 // alphabetically by filename.
1735 Result_t OpenRead(const std::string& filename) const;
1737 // Opens a file sequence for reading. The sequence is expected to contain one or
1738 // more filenames, each naming a file containing the bytestream for exactly one
1740 Result_t OpenRead(const std::list<std::string>& file_list) const;
1742 // Fill a DCDataDescriptor struct with default values.
1743 // Returns RESULT_INIT if the directory is not open.
1744 Result_t FillDCDataDescriptor(DCDataDescriptor&) const;
1746 // Rewind the directory to the beginning.
1747 Result_t Reset() const;
1749 // Reads the next sequential frame in the directory and places it in the
1750 // frame buffer. Fails if the buffer is too small or the direcdtory
1751 // contains no more files.
1752 // The frame buffer's PlaintextOffset parameter will be set to the first
1753 // byte of the data segment. Set this value to zero if you want
1754 // encrypted headers.
1755 Result_t ReadFrame(FrameBuffer&) const;
1762 mem_ptr<h__Writer> m_Writer;
1763 ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
1767 virtual ~MXFWriter();
1769 // Warning: direct manipulation of MXF structures can interfere
1770 // with the normal operation of the wrapper. Caveat emptor!
1771 virtual MXF::OP1aHeader& OP1aHeader();
1772 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1773 virtual MXF::RIP& RIP();
1775 // Open the file for writing. The file must not exist. Returns error if
1776 // the operation cannot be completed or if nonsensical data is discovered
1777 // in the essence descriptor.
1778 Result_t OpenWrite(const std::string& filename, const WriterInfo&,
1779 const DCDataDescriptor&, ui32_t HeaderSize = 16384);
1781 // Writes a frame of essence to the MXF file. If the optional AESEncContext
1782 // argument is present, the essence is encrypted prior to writing.
1783 // Fails if the file is not open, is finalized, or an operating system
1785 Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
1787 // Closes the MXF file, writing the index and revised header.
1788 Result_t Finalize();
1795 mem_ptr<h__Reader> m_Reader;
1796 ASDCP_NO_COPY_CONSTRUCT(MXFReader);
1800 virtual ~MXFReader();
1802 // Warning: direct manipulation of MXF structures can interfere
1803 // with the normal operation of the wrapper. Caveat emptor!
1804 virtual MXF::OP1aHeader& OP1aHeader();
1805 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1806 virtual MXF::RIP& RIP();
1808 // Open the file for reading. The file must exist. Returns error if the
1809 // operation cannot be completed.
1810 Result_t OpenRead(const std::string& filename) const;
1812 // Returns RESULT_INIT if the file is not open.
1813 Result_t Close() const;
1815 // Fill a DCDataDescriptor struct with the values from the file's header.
1816 // Returns RESULT_INIT if the file is not open.
1817 Result_t FillDCDataDescriptor(DCDataDescriptor&) const;
1819 // Fill a WriterInfo struct with the values from the file's header.
1820 // Returns RESULT_INIT if the file is not open.
1821 Result_t FillWriterInfo(WriterInfo&) const;
1823 // Reads a frame of essence from the MXF file. If the optional AESEncContext
1824 // argument is present, the essence is decrypted after reading. If the MXF
1825 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1826 // will contain the ciphertext frame data. If the HMACContext argument is
1827 // not NULL, the HMAC will be calculated (if the file supports it).
1828 // Returns RESULT_INIT if the file is not open, failure if the frame number is
1829 // out of range, or if optional decrypt or HAMC operations fail.
1830 Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1832 // Using the index table read from the footer partition, lookup the frame number
1833 // and return the offset into the file at which to read that frame of essence.
1834 // Returns RESULT_INIT if the file is not open, and RESULT_RANGE if the frame number is
1836 Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
1838 // Print debugging information to stream
1839 void DumpHeaderMetadata(FILE* = 0) const;
1840 void DumpIndex(FILE* = 0) const;
1843 } // namespace DCData
1845 //---------------------------------------------------------------------------------
1849 struct AtmosDescriptor : public DCData::DCDataDescriptor
1851 ui32_t FirstFrame; // Frame number of the frame to align with the FFOA of the picture track
1852 ui16_t MaxChannelCount; // Max number of channels in bitstream
1853 ui16_t MaxObjectCount; // Max number of objects in bitstream
1854 byte_t AtmosID[UUIDlen]; // UUID of Atmos Project
1855 ui8_t AtmosVersion; // ATMOS Coder Version used to create bitstream
1858 // Print AtmosDescriptor to std::ostream
1859 std::ostream& operator << (std::ostream& strm, const AtmosDescriptor& adesc);
1860 // Print debugging information to stream (stderr default)
1861 void AtmosDescriptorDump(const AtmosDescriptor&, FILE* = 0);
1862 // Determine if a file is a raw atmos file
1863 bool IsDolbyAtmos(const std::string& filename);
1870 mem_ptr<h__Writer> m_Writer;
1871 ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
1875 virtual ~MXFWriter();
1877 // Warning: direct manipulation of MXF structures can interfere
1878 // with the normal operation of the wrapper. Caveat emptor!
1879 virtual MXF::OP1aHeader& OP1aHeader();
1880 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1881 virtual MXF::RIP& RIP();
1883 // Open the file for writing. The file must not exist. Returns error if
1884 // the operation cannot be completed or if nonsensical data is discovered
1885 // in the essence descriptor.
1886 Result_t OpenWrite(const std::string& filename, const WriterInfo&,
1887 const AtmosDescriptor&, ui32_t HeaderSize = 16384);
1889 // Writes a frame of essence to the MXF file. If the optional AESEncContext
1890 // argument is present, the essence is encrypted prior to writing.
1891 // Fails if the file is not open, is finalized, or an operating system
1893 Result_t WriteFrame(const DCData::FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
1895 // Closes the MXF file, writing the index and revised header.
1896 Result_t Finalize();
1903 mem_ptr<h__Reader> m_Reader;
1904 ASDCP_NO_COPY_CONSTRUCT(MXFReader);
1908 virtual ~MXFReader();
1910 // Warning: direct manipulation of MXF structures can interfere
1911 // with the normal operation of the wrapper. Caveat emptor!
1912 virtual MXF::OP1aHeader& OP1aHeader();
1913 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1914 virtual MXF::RIP& RIP();
1916 // Open the file for reading. The file must exist. Returns error if the
1917 // operation cannot be completed.
1918 Result_t OpenRead(const std::string& filename) const;
1920 // Returns RESULT_INIT if the file is not open.
1921 Result_t Close() const;
1923 // Fill an AtmosDescriptor struct with the values from the file's header.
1924 // Returns RESULT_INIT if the file is not open.
1925 Result_t FillAtmosDescriptor(AtmosDescriptor&) const;
1927 // Fill a WriterInfo struct with the values from the file's header.
1928 // Returns RESULT_INIT if the file is not open.
1929 Result_t FillWriterInfo(WriterInfo&) const;
1931 // Reads a frame of essence from the MXF file. If the optional AESEncContext
1932 // argument is present, the essence is decrypted after reading. If the MXF
1933 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1934 // will contain the ciphertext frame data. If the HMACContext argument is
1935 // not NULL, the HMAC will be calculated (if the file supports it).
1936 // Returns RESULT_INIT if the file is not open, failure if the frame number is
1937 // out of range, or if optional decrypt or HAMC operations fail.
1938 Result_t ReadFrame(ui32_t frame_number, DCData::FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1940 // Using the index table read from the footer partition, lookup the frame number
1941 // and return the offset into the file at which to read that frame of essence.
1942 // Returns RESULT_INIT if the file is not open, and RESULT_RANGE if the frame number is
1944 Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
1946 // Print debugging information to stream
1947 void DumpHeaderMetadata(FILE* = 0) const;
1948 void DumpIndex(FILE* = 0) const;
1951 } // namespace ATMOS
1955 } // namespace ASDCP
1958 #endif // _AS_DCP_H_