2 Copyright (c) 2003-2014, 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
228 // Determine the type of essence contained in the given MXF file. RESULT_OK
229 // is returned if the file is successfully opened and contains a valid MXF
230 // stream. If there is an error, the result code will indicate the reason.
231 Result_t EssenceType(const std::string& filename, EssenceType_t& type);
233 // Determine the type of essence contained in the given raw file. RESULT_OK
234 // is returned if the file is successfully opened and contains a known
235 // stream type. If there is an error, the result code will indicate the reason.
236 Result_t RawEssenceType(const std::string& filename, EssenceType_t& type);
239 //---------------------------------------------------------------------------------
242 // A simple container for rational numbers.
249 Rational() : Numerator(0), Denominator(0) {}
250 Rational(i32_t n, i32_t d) : Numerator(n), Denominator(d) {}
252 inline double Quotient() const {
253 return (double)Numerator / (double)Denominator;
256 inline bool operator==(const Rational& rhs) const {
257 return ( rhs.Numerator == Numerator && rhs.Denominator == Denominator );
260 inline bool operator!=(const Rational& rhs) const {
261 return ( rhs.Numerator != Numerator || rhs.Denominator != Denominator );
264 inline bool operator<(const Rational& rhs) {
265 if ( Numerator < rhs.Numerator ) return true;
266 if ( Numerator == rhs.Numerator && Denominator < rhs.Denominator ) return true;
270 inline bool operator>(const Rational& rhs) {
271 if ( Numerator > rhs.Numerator ) return true;
272 if ( Numerator == rhs.Numerator && Denominator > rhs.Denominator ) return true;
277 // Encodes a rational number as a string having a single delimiter character between
278 // numerator and denominator. Retuns the buffer pointer to allow convenient in-line use.
279 const char* EncodeRational(const Rational&, char* str_buf, ui32_t buf_len, char delimiter = ' ');
281 // Decodes a rational number havng a single non-digit delimiter character between
282 // the numerator and denominator. Returns false if the string does not contain
283 // the expected syntax.
284 bool DecodeRational(const char* str_rat, Rational&);
287 // common edit rates, use these instead of hard coded constants
288 const Rational EditRate_24 = Rational(24,1);
289 const Rational EditRate_23_98 = Rational(24000,1001); // Not a DCI-compliant value!
290 const Rational EditRate_48 = Rational(48,1);
291 const Rational SampleRate_48k = Rational(48000,1);
292 const Rational SampleRate_96k = Rational(96000,1);
294 // Additional frame rates, see ST 428-11, ST 429-13
295 // These rates are new and not supported by all systems. Do not assume that
296 // a package made using one of these rates will work just anywhere!
297 const Rational EditRate_25 = Rational(25,1);
298 const Rational EditRate_30 = Rational(30,1);
299 const Rational EditRate_50 = Rational(50,1);
300 const Rational EditRate_60 = Rational(60,1);
301 const Rational EditRate_96 = Rational(96,1);
302 const Rational EditRate_100 = Rational(100,1);
303 const Rational EditRate_120 = Rational(120,1);
305 // Archival frame rates, see ST 428-21
306 // These rates are new and not supported by all systems. Do not assume that
307 // a package made using one of these rates will work just anywhere!
308 const Rational EditRate_16 = Rational(16,1);
309 const Rational EditRate_18 = Rational(200,11); // 18.182
310 const Rational EditRate_20 = Rational(20,1);
311 const Rational EditRate_22 = Rational(240,11); // 21.818
314 // Non-reference counting container for internal member objects.
315 // Please do not use this class for any other purpose.
319 T* m_p; // the thing we point to
323 mem_ptr() : m_p(0) {}
324 mem_ptr(T* p) : m_p(p) {}
325 ~mem_ptr() { delete m_p; }
327 inline T& operator*() const { return *m_p; }
328 inline T* operator->() const { return m_p; }
329 inline operator T*()const { return m_p; }
330 inline const mem_ptr<T>& operator=(T* p) { set(p); return *this; }
331 inline T* set(T* p) { delete m_p; m_p = p; return m_p; }
332 inline T* get() const { return m_p; }
333 inline void release() { m_p = 0; }
334 inline bool empty() const { return m_p == 0; }
338 //---------------------------------------------------------------------------------
339 // WriterInfo class - encapsulates writer identification details used for
340 // OpenWrite() calls. Replace these values at runtime to identify your product.
342 // MXF files use SMPTE Universal Labels to identify data items. The set of Labels
343 // in a file is determined by the MXF Operational Pattern and any constraining
344 // documentation. There are currently two flavors of AS-DCP file in use: MXF Interop
345 // (AKA JPEG Interop) and SMPTE. The two differ in the values of three labels:
348 // Interop : 06 0e 2b 34 04 01 01 01 0d 01 02 01 10 00 00 00
349 // SMPTE : 06 0e 2b 34 04 01 01 02 0d 01 02 01 10 00 00 00
352 // Interop : 06 0e 2b 34 02 04 01 07 0d 01 03 01 02 7e 01 00
353 // SMPTE : 06 0e 2b 34 02 04 01 01 0d 01 03 01 02 7e 01 00
355 // GenericDescriptor/SubDescriptors:
356 // Interop : 06 0e 2b 34 01 01 01 02 06 01 01 04 06 10 00 00
357 // SMPTE : 06 0e 2b 34 01 01 01 09 06 01 01 04 06 10 00 00
359 // asdcplib will read any (otherwise valid) file which has any combination of the
360 // above values. When writing files, MXF Interop labels are used by default. To
361 // write a file containing SMPTE labels, replace the default label set value in
362 // the WriterInfo before calling OpenWrite()
376 byte_t ProductUUID[UUIDlen];
377 byte_t AssetUUID[UUIDlen];
378 byte_t ContextID[UUIDlen];
379 byte_t CryptographicKeyID[UUIDlen];
380 bool EncryptedEssence; // true if essence data is (or is going to be) encrypted
381 bool UsesHMAC; // true if HMAC exists or is to be calculated
382 std::string ProductVersion;
383 std::string CompanyName;
384 std::string ProductName;
385 LabelSet_t LabelSetType;
387 WriterInfo() : EncryptedEssence(false), UsesHMAC(false), LabelSetType(LS_MXF_INTEROP)
389 static byte_t default_ProductUUID_Data[UUIDlen] = {
390 0x43, 0x05, 0x9a, 0x1d, 0x04, 0x32, 0x41, 0x01,
391 0xb8, 0x3f, 0x73, 0x68, 0x15, 0xac, 0xf3, 0x1d };
393 memcpy(ProductUUID, default_ProductUUID_Data, UUIDlen);
394 memset(AssetUUID, 0, UUIDlen);
395 memset(ContextID, 0, UUIDlen);
396 memset(CryptographicKeyID, 0, UUIDlen);
398 ProductVersion = "Unreleased ";
399 ProductVersion += Version();
401 ProductName = "asdcplib";
405 // Print WriterInfo to std::ostream
406 std::ostream& operator << (std::ostream& strm, const WriterInfo& winfo);
407 // Print WriterInfo to stream, stderr by default.
408 void WriterInfoDump(const WriterInfo&, FILE* = 0);
410 //---------------------------------------------------------------------------------
411 // cryptographic support
413 // The following classes define interfaces to Rijndael contexts having the following properties:
415 // o CBC mode with 16 byte block size
416 const ui32_t CBC_KEY_SIZE = 16;
417 const ui32_t CBC_BLOCK_SIZE = 16;
418 const ui32_t HMAC_SIZE = 20;
424 mem_ptr<h__AESContext> m_Context;
425 ASDCP_NO_COPY_CONSTRUCT(AESEncContext);
431 // Initializes Rijndael CBC encryption context.
432 // Returns error if the key argument is NULL.
433 Result_t InitKey(const byte_t* key);
435 // Initializes 16 byte CBC Initialization Vector. This operation may be performed
436 // any number of times for a given key.
437 // Returns error if the i_vec argument is NULL.
438 Result_t SetIVec(const byte_t* i_vec);
439 Result_t GetIVec(byte_t* i_vec) const;
441 // Encrypt a block of data. The block size must be a multiple of CBC_BLOCK_SIZE.
442 // Returns error if either argument is NULL.
443 Result_t EncryptBlock(const byte_t* pt_buf, byte_t* ct_buf, ui32_t block_size);
450 mem_ptr<h__AESContext> m_Context;
451 ASDCP_NO_COPY_CONSTRUCT(AESDecContext);
457 // Initializes Rijndael CBC decryption context.
458 // Returns error if the key argument is NULL.
459 Result_t InitKey(const byte_t* key);
461 // Initializes 16 byte CBC Initialization Vector. This operation may be performed
462 // any number of times for a given key.
463 // Returns error if the i_vec argument is NULL.
464 Result_t SetIVec(const byte_t* i_vec);
466 // Decrypt a block of data. The block size must be a multiple of CBC_BLOCK_SIZE.
467 // Returns error if either argument is NULL.
468 Result_t DecryptBlock(const byte_t* ct_buf, byte_t* pt_buf, ui32_t block_size);
474 class h__HMACContext;
475 mem_ptr<h__HMACContext> m_Context;
476 ASDCP_NO_COPY_CONSTRUCT(HMACContext);
482 // Initializes HMAC context. The key argument must point to a binary
483 // key that is CBC_KEY_SIZE bytes in length. Returns error if the key
485 Result_t InitKey(const byte_t* key, LabelSet_t);
487 // Reset internal state, allows repeated cycles of Update -> Finalize
490 // Add data to the digest. Returns error if the key argument is NULL or
491 // if the digest has been finalized.
492 Result_t Update(const byte_t* buf, ui32_t buf_len);
494 // Finalize digest. Returns error if the digest has already been finalized.
497 // Writes HMAC value to given buffer. buf must point to a writable area of
498 // memory that is at least HMAC_SIZE bytes in length. Returns error if the
499 // buf argument is NULL or if the digest has not been finalized.
500 Result_t GetHMACValue(byte_t* buf) const;
502 // Tests the given value against the finalized value in the object. buf must
503 // point to a readable area of memory that is at least HMAC_SIZE bytes in length.
504 // Returns error if the buf argument is NULL or if the values do ot match.
505 Result_t TestHMACValue(const byte_t* buf) const;
508 //---------------------------------------------------------------------------------
509 // frame buffer base class
511 // The supported essence types are stored using per-frame KLV packetization. The
512 // following class implements essence-neutral functionality for managing a buffer
513 // containing a frame of essence.
517 ASDCP_NO_COPY_CONSTRUCT(FrameBuffer);
520 byte_t* m_Data; // pointer to memory area containing frame data
521 ui32_t m_Capacity; // size of memory area pointed to by m_Data
522 bool m_OwnMem; // if false, m_Data points to externally allocated memory
523 ui32_t m_Size; // size of frame data in memory area pointed to by m_Data
524 ui32_t m_FrameNumber; // delivery-order frame number
526 // It is possible to read raw ciphertext from an encrypted AS-DCP file.
527 // After reading an encrypted AS-DCP file in raw mode, the frame buffer will
528 // contain the encrypted source value portion of the Encrypted Triplet, followed
529 // by the integrity pack, if it exists.
530 // The buffer will begin with the IV and CheckValue, followed by encrypted essence
531 // and optional integrity pack
532 // The SourceLength and PlaintextOffset values from the packet will be held in the
533 // following variables:
534 ui32_t m_SourceLength; // plaintext length (delivered plaintext+decrypted ciphertext)
535 ui32_t m_PlaintextOffset; // offset to first byte of ciphertext
539 virtual ~FrameBuffer();
541 // Instructs the object to use an externally allocated buffer. The external
542 // buffer will not be cleaned up by the frame buffer when it exits.
543 // Call with (0,0) to revert to internally allocated buffer.
544 // Returns error if the buf_addr argument is NULL and buf_size is non-zero.
545 Result_t SetData(byte_t* buf_addr, ui32_t buf_size);
547 // Sets the size of the internally allocate buffer. Returns RESULT_CAPEXTMEM
548 // if the object is using an externally allocated buffer via SetData();
549 // Resets content size to zero.
550 Result_t Capacity(ui32_t cap);
552 // returns the size of the buffer
553 inline ui32_t Capacity() const { return m_Capacity; }
555 // returns a const pointer to the essence data
556 inline const byte_t* RoData() const { return m_Data; }
558 // returns a non-const pointer to the essence data
559 inline byte_t* Data() { return m_Data; }
561 // set the size of the buffer's contents
562 inline ui32_t Size(ui32_t size) { return m_Size = size; }
564 // returns the size of the buffer's contents
565 inline ui32_t Size() const { return m_Size; }
567 // Sets the absolute frame number of this frame in the file in delivery order.
568 inline void FrameNumber(ui32_t num) { m_FrameNumber = num; }
570 // Returns the absolute frame number of this frame in the file in delivery order.
571 inline ui32_t FrameNumber() const { return m_FrameNumber; }
573 // Sets the length of the plaintext essence data
574 inline void SourceLength(ui32_t len) { m_SourceLength = len; }
576 // When this value is 0 (zero), the buffer contains only plaintext. When it is
577 // non-zero, the buffer contains raw ciphertext and the return value is the length
578 // of the original plaintext.
579 inline ui32_t SourceLength() const { return m_SourceLength; }
581 // Sets the offset into the buffer at which encrypted data begins
582 inline void PlaintextOffset(ui32_t ofst) { m_PlaintextOffset = ofst; }
584 // Returns offset into buffer of first byte of ciphertext.
585 inline ui32_t PlaintextOffset() const { return m_PlaintextOffset; }
588 //---------------------------------------------------------------------------------
589 // Accessors in the MXFReader and MXFWriter classes below return these types to
590 // provide direct access to MXF metadata structures declared in MXF.h and Metadata.h
593 // #include<Metadata.h> to use these
595 class OPAtomIndexFooter;
599 //---------------------------------------------------------------------------------
600 // MPEG2 video elementary stream support
605 // MPEG picture coding type
607 FRAME_U = 0x00, // Unknown
608 FRAME_I = 0x01, // I-Frame
609 FRAME_P = 0x02, // P-Frame
610 FRAME_B = 0x03 // B-Frame
613 // convert FrameType_t to char
614 inline char FrameTypeChar(FrameType_t type)
618 case FRAME_I: return 'I';
619 case FRAME_B: return 'B';
620 case FRAME_P: return 'P';
625 // Structure represents the metadata elements in the file header's
626 // MPEG2VideoDescriptor object.
627 struct VideoDescriptor
629 Rational EditRate; //
631 Rational SampleRate; //
632 ui8_t FrameLayout; //
633 ui32_t StoredWidth; //
634 ui32_t StoredHeight; //
635 Rational AspectRatio; //
636 ui32_t ComponentDepth; //
637 ui32_t HorizontalSubsampling; //
638 ui32_t VerticalSubsampling; //
639 ui8_t ColorSiting; //
640 ui8_t CodedContentType; //
643 ui8_t ProfileAndLevel; //
644 ui32_t ContainerDuration; //
647 // Print VideoDescriptor to std::ostream
648 std::ostream& operator << (std::ostream& strm, const VideoDescriptor& vdesc);
649 // Print VideoDescriptor to stream, stderr by default.
650 void VideoDescriptorDump(const VideoDescriptor&, FILE* = 0);
652 // A container for MPEG frame data.
653 class FrameBuffer : public ASDCP::FrameBuffer
655 ASDCP_NO_COPY_CONSTRUCT(FrameBuffer); // TODO: should have copy construct
658 FrameType_t m_FrameType;
659 ui8_t m_TemporalOffset;
665 m_FrameType(FRAME_U), m_TemporalOffset(0),
666 m_ClosedGOP(false), m_GOPStart(false) {}
668 FrameBuffer(ui32_t size) :
669 m_FrameType(FRAME_U), m_TemporalOffset(0),
670 m_ClosedGOP(false), m_GOPStart(false)
675 virtual ~FrameBuffer() {}
677 // Sets the MPEG frame type of the picture data in the frame buffer.
678 inline void FrameType(FrameType_t type) { m_FrameType = type; }
680 // Returns the MPEG frame type of the picture data in the frame buffer.
681 inline FrameType_t FrameType() const { return m_FrameType; }
683 // Sets the MPEG temporal offset of the picture data in the frame buffer.
684 inline void TemporalOffset(ui8_t offset) { m_TemporalOffset = offset; }
686 // Returns the MPEG temporal offset of the picture data in the frame buffer.
687 inline ui8_t TemporalOffset() const { return m_TemporalOffset; }
689 // Sets the MPEG GOP 'start' attribute for the frame buffer.
690 inline void GOPStart(bool start) { m_GOPStart = start; }
692 // True if the frame in the buffer is the first in the GOP (in transport order)
693 inline bool GOPStart() const { return m_GOPStart; }
695 // Sets the MPEG GOP 'closed' attribute for the frame buffer.
696 inline void ClosedGOP(bool closed) { m_ClosedGOP = closed; }
698 // Returns true if the frame in the buffer is from a closed GOP, false if
699 // the frame is from an open GOP. Always returns false unless GOPStart()
701 inline bool ClosedGOP() const { return m_ClosedGOP; }
703 // Print object state to stream, include n bytes of frame data if indicated.
704 // Default stream is stderr.
705 void Dump(FILE* = 0, ui32_t dump_len = 0) const;
709 // An object which opens and reads an MPEG2 Video Elementary Stream file. The call to
710 // OpenRead() reads metadata from the file and populates an internal VideoDescriptor object.
711 // Each subsequent call to ReadFrame() reads exactly one frame from the stream into the
712 // given FrameBuffer object.
716 mem_ptr<h__Parser> m_Parser;
717 ASDCP_NO_COPY_CONSTRUCT(Parser);
723 // Opens the stream for reading, parses enough data to provide a complete
724 // set of stream metadata for the MXFWriter below.
725 Result_t OpenRead(const std::string& filename) const;
727 // Fill a VideoDescriptor struct with the values from the file's header.
728 // Returns RESULT_INIT if the file is not open.
729 Result_t FillVideoDescriptor(VideoDescriptor&) const;
731 // Rewind the stream to the beginning.
732 Result_t Reset() const;
734 // Reads the next sequential frame in the input file and places it in the
735 // frame buffer. Fails if the buffer is too small or the stream is empty.
736 // The frame buffer's PlaintextOffset parameter will be set to the first
737 // data byte of the first slice. Set this value to zero if you want
738 // encrypted headers.
739 Result_t ReadFrame(FrameBuffer&) const;
742 // A class which creates and writes MPEG frame data to an AS-DCP format MXF file.
743 // Not yet implemented
747 mem_ptr<h__Writer> m_Writer;
748 ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
752 virtual ~MXFWriter();
754 // Warning: direct manipulation of MXF structures can interfere
755 // with the normal operation of the wrapper. Caveat emptor!
756 virtual MXF::OP1aHeader& OP1aHeader();
757 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
758 virtual MXF::RIP& RIP();
760 // Open the file for writing. The file must not exist. Returns error if
761 // the operation cannot be completed or if nonsensical data is discovered
762 // in the essence descriptor.
763 Result_t OpenWrite(const std::string& filename, const WriterInfo&,
764 const VideoDescriptor&, ui32_t HeaderSize = 16384);
766 // Writes a frame of essence to the MXF file. If the optional AESEncContext
767 // argument is present, the essence is encrypted prior to writing.
768 // Fails if the file is not open, is finalized, or an operating system
770 Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
772 // Closes the MXF file, writing the index and revised header.
776 // A class which reads MPEG frame data from an AS-DCP format MXF file.
780 mem_ptr<h__Reader> m_Reader;
781 ASDCP_NO_COPY_CONSTRUCT(MXFReader);
785 virtual ~MXFReader();
787 // Warning: direct manipulation of MXF structures can interfere
788 // with the normal operation of the wrapper. Caveat emptor!
789 virtual MXF::OP1aHeader& OP1aHeader();
790 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
791 virtual MXF::RIP& RIP();
793 // Open the file for reading. The file must exist. Returns error if the
794 // operation cannot be completed.
795 Result_t OpenRead(const std::string& filename) const;
797 // Returns RESULT_INIT if the file is not open.
798 Result_t Close() const;
800 // Fill a VideoDescriptor struct with the values from the file's header.
801 // Returns RESULT_INIT if the file is not open.
802 Result_t FillVideoDescriptor(VideoDescriptor&) const;
804 // Fill a WriterInfo struct with the values from the file's header.
805 // Returns RESULT_INIT if the file is not open.
806 Result_t FillWriterInfo(WriterInfo&) const;
808 // Reads a frame of essence from the MXF file. If the optional AESEncContext
809 // argument is present, the essence is decrypted after reading. If the MXF
810 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
811 // will contain the ciphertext frame data. If the HMACContext argument is
812 // not NULL, the HMAC will be calculated (if the file supports it).
813 // Returns RESULT_INIT if the file is not open, failure if the frame number is
814 // out of range, or if optional decrypt or HAMC operations fail.
815 Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
817 // Using the index table read from the footer partition, lookup the frame number
818 // and return the offset into the file at which to read that frame of essence.
819 // Returns RESULT_INIT if the file is not open, and RESULT_RANGE if the frame number is
821 Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
823 // Calculates the first frame in transport order of the GOP in which the requested
824 // frame is located. Calls ReadFrame() to fetch the frame at the calculated position.
825 // Returns RESULT_INIT if the file is not open.
826 Result_t ReadFrameGOPStart(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
828 // Calculates the first frame in transport order of the GOP in which the requested
829 // frame is located. Sets key_frame_number to the number of the frame at the calculated position.
830 // Returns RESULT_INIT if the file is not open.
831 Result_t FindFrameGOPStart(ui32_t frame_number, ui32_t& key_frame_number) const;
833 // Returns the type of the frame at the given position.
834 // Returns RESULT_INIT if the file is not open or RESULT_RANGE if the index is out of range.
835 Result_t FrameType(ui32_t frame_number, FrameType_t&) const;
837 // Print debugging information to stream
838 void DumpHeaderMetadata(FILE* = 0) const;
839 void DumpIndex(FILE* = 0) const;
843 //---------------------------------------------------------------------------------
850 // The default value of the ChannelFormat element of the AudioDescriptor struct
851 // is CF_NONE. If the value is set to one of the other ChannelFormat_t enum
852 // values, the file's Wave Audio Descriptor will contain a Channel Assignment
855 // The channel format should be one of (CF_CFG_1, CF_CFG_2, or CF_CFG_3) for
856 // SMPTE 429-2 files. It should normally be CF_NONE for JPEG Interop files, but
857 // the 429-2 may also be used.
859 enum ChannelFormat_t {
861 CF_CFG_1, // 5.1 with optional HI/VI
862 CF_CFG_2, // 6.1 (5.1 + center surround) with optional HI/VI
863 CF_CFG_3, // 7.1 (SDDS) with optional HI/VI
864 CF_CFG_4, // Wild Track Format
865 CF_CFG_5, // 7.1 DS with optional HI/VI
866 CF_CFG_6, // ST 377-4 (MCA) labels (see also ASDCP::MXF::decode_mca_string)
870 struct AudioDescriptor
872 Rational EditRate; // rate of frame wrapping
873 Rational AudioSamplingRate; // rate of audio sample
875 ui32_t ChannelCount; // number of channels
876 ui32_t QuantizationBits; // number of bits per single-channel sample
877 ui32_t BlockAlign; // number of bytes ber sample, all channels
879 ui32_t LinkedTrackID; //
880 ui32_t ContainerDuration; // number of frames
881 ChannelFormat_t ChannelFormat; // audio channel arrangement
884 // Print AudioDescriptor to std::ostream
885 std::ostream& operator << (std::ostream& strm, const AudioDescriptor& adesc);
886 // Print debugging information to stream (stderr default)
887 void AudioDescriptorDump(const AudioDescriptor&, FILE* = 0);
889 // Returns size in bytes of a single sample of data described by ADesc
890 inline ui32_t CalcSampleSize(const AudioDescriptor& ADesc)
892 return (ADesc.QuantizationBits / 8) * ADesc.ChannelCount;
895 // Returns number of samples per frame of data described by ADesc
896 inline ui32_t CalcSamplesPerFrame(const AudioDescriptor& ADesc)
898 double tmpd = ADesc.AudioSamplingRate.Quotient() / ADesc.EditRate.Quotient();
899 return (ui32_t)ceil(tmpd);
902 // Returns the size in bytes of a frame of data described by ADesc
903 inline ui32_t CalcFrameBufferSize(const AudioDescriptor& ADesc)
905 return CalcSampleSize(ADesc) * CalcSamplesPerFrame(ADesc);
909 class FrameBuffer : public ASDCP::FrameBuffer
913 FrameBuffer(ui32_t size) { Capacity(size); }
914 virtual ~FrameBuffer() {}
916 // Print debugging information to stream (stderr default)
917 void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
920 // An object which opens and reads a WAV file. The call to OpenRead() reads metadata from
921 // the file and populates an internal AudioDescriptor object. Each subsequent call to
922 // ReadFrame() reads exactly one frame from the stream into the given FrameBuffer object.
923 // A "frame" is either 2000 or 2002 samples, depending upon the value of PictureRate.
927 mem_ptr<h__WAVParser> m_Parser;
928 ASDCP_NO_COPY_CONSTRUCT(WAVParser);
932 virtual ~WAVParser();
934 // Opens the stream for reading, parses enough data to provide a complete
935 // set of stream metadata for the MXFWriter below. PictureRate controls
936 // ther frame rate for the MXF frame wrapping option.
937 Result_t OpenRead(const std::string& filename, const Rational& PictureRate) const;
939 // Fill an AudioDescriptor struct with the values from the file's header.
940 // Returns RESULT_INIT if the file is not open.
941 Result_t FillAudioDescriptor(AudioDescriptor&) const;
943 // Rewind the stream to the beginning.
944 Result_t Reset() const;
946 // Reads the next sequential frame in the input file and places it in the
947 // frame buffer. Fails if the buffer is too small or the stream is empty.
948 Result_t ReadFrame(FrameBuffer&) const;
956 mem_ptr<h__Writer> m_Writer;
957 ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
961 virtual ~MXFWriter();
963 // Warning: direct manipulation of MXF structures can interfere
964 // with the normal operation of the wrapper. Caveat emptor!
965 virtual MXF::OP1aHeader& OP1aHeader();
966 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
967 virtual MXF::RIP& RIP();
969 // Open the file for writing. The file must not exist. Returns error if
970 // the operation cannot be completed or if nonsensical data is discovered
971 // in the essence descriptor.
972 Result_t OpenWrite(const std::string& filename, const WriterInfo&,
973 const AudioDescriptor&, ui32_t HeaderSize = 16384);
975 // Writes a frame of essence to the MXF file. If the optional AESEncContext
976 // argument is present, the essence is encrypted prior to writing.
977 // Fails if the file is not open, is finalized, or an operating system
979 Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
981 // Closes the MXF file, writing the index and revised header.
989 mem_ptr<h__Reader> m_Reader;
990 ASDCP_NO_COPY_CONSTRUCT(MXFReader);
994 virtual ~MXFReader();
996 // Warning: direct manipulation of MXF structures can interfere
997 // with the normal operation of the wrapper. Caveat emptor!
998 virtual MXF::OP1aHeader& OP1aHeader();
999 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1000 virtual MXF::RIP& RIP();
1002 // Open the file for reading. The file must exist. Returns error if the
1003 // operation cannot be completed.
1004 Result_t OpenRead(const std::string& filename) const;
1006 // Returns RESULT_INIT if the file is not open.
1007 Result_t Close() const;
1009 // Fill an AudioDescriptor struct with the values from the file's header.
1010 // Returns RESULT_INIT if the file is not open.
1011 Result_t FillAudioDescriptor(AudioDescriptor&) const;
1013 // Fill a WriterInfo struct with the values from the file's header.
1014 // Returns RESULT_INIT if the file is not open.
1015 Result_t FillWriterInfo(WriterInfo&) const;
1017 // Reads a frame of essence from the MXF file. If the optional AESEncContext
1018 // argument is present, the essence is decrypted after reading. If the MXF
1019 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1020 // will contain the ciphertext frame data. If the HMACContext argument is
1021 // not NULL, the HMAC will be calculated (if the file supports it).
1022 // Returns RESULT_INIT if the file is not open, failure if the frame number is
1023 // out of range, or if optional decrypt or HAMC operations fail.
1024 Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1026 // Using the index table read from the footer partition, lookup the frame number
1027 // and return the offset into the file at which to read that frame of essence.
1028 // Returns RESULT_INIT if the file is not open, and RESULT_RANGE if the frame number is
1030 Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
1032 // Print debugging information to stream
1033 void DumpHeaderMetadata(FILE* = 0) const;
1034 void DumpIndex(FILE* = 0) const;
1038 //---------------------------------------------------------------------------------
1042 const ui32_t MaxComponents = 3;
1043 const ui32_t MaxPrecincts = 32; // ISO 15444-1 Annex A.6.1
1044 const ui32_t MaxDefaults = 256; // made up
1047 struct ImageComponent_t // ISO 15444-1 Annex A.5.1
1054 struct CodingStyleDefault_t // ISO 15444-1 Annex A.6.1
1060 ui8_t ProgressionOrder;
1061 ui8_t NumberOfLayers[sizeof(ui16_t)];
1062 ui8_t MultiCompTransform;
1067 ui8_t DecompositionLevels;
1068 ui8_t CodeblockWidth;
1069 ui8_t CodeblockHeight;
1070 ui8_t CodeblockStyle;
1071 ui8_t Transformation;
1072 ui8_t PrecinctSize[MaxPrecincts];
1076 struct QuantizationDefault_t // ISO 15444-1 Annex A.6.4
1079 ui8_t SPqcd[MaxDefaults];
1084 struct PictureDescriptor
1087 ui32_t ContainerDuration;
1088 Rational SampleRate;
1090 ui32_t StoredHeight;
1091 Rational AspectRatio;
1102 ImageComponent_t ImageComponents[MaxComponents];
1103 CodingStyleDefault_t CodingStyleDefault;
1104 QuantizationDefault_t QuantizationDefault;
1107 // Print debugging information to std::ostream
1108 std::ostream& operator << (std::ostream& strm, const PictureDescriptor& pdesc);
1109 // Print debugging information to stream (stderr default)
1110 void PictureDescriptorDump(const PictureDescriptor&, FILE* = 0);
1113 class FrameBuffer : public ASDCP::FrameBuffer
1117 FrameBuffer(ui32_t size) { Capacity(size); }
1118 virtual ~FrameBuffer() {}
1120 // Print debugging information to stream (stderr default)
1121 void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
1125 // An object which opens and reads a JPEG 2000 codestream file. The file is expected
1126 // to contain exactly one complete frame of picture essence as an unwrapped (raw)
1127 // ISO/IEC 15444 codestream.
1128 class CodestreamParser
1130 class h__CodestreamParser;
1131 mem_ptr<h__CodestreamParser> m_Parser;
1132 ASDCP_NO_COPY_CONSTRUCT(CodestreamParser);
1136 virtual ~CodestreamParser();
1138 // Opens a file for reading, parses enough data to provide a complete
1139 // set of stream metadata for the MXFWriter below.
1140 // The frame buffer's PlaintextOffset parameter will be set to the first
1141 // byte of the data segment. Set this value to zero if you want
1142 // encrypted headers.
1143 Result_t OpenReadFrame(const std::string& filename, FrameBuffer&) const;
1145 Result_t OpenReadFrame(const unsigned char * data, unsigned int size, FrameBuffer&) const;
1147 // Fill a PictureDescriptor struct with the values from the file's codestream.
1148 // Returns RESULT_INIT if the file is not open.
1149 Result_t FillPictureDescriptor(PictureDescriptor&) const;
1152 // Parses the data in the frame buffer to fill in the picture descriptor. Copies
1153 // the offset of the image data into start_of_data. Returns error if the parser fails.
1154 Result_t ParseMetadataIntoDesc(const FrameBuffer&, PictureDescriptor&, byte_t* start_of_data = 0);
1156 // An object which reads a sequence of files containing JPEG 2000 pictures.
1157 class SequenceParser
1159 class h__SequenceParser;
1160 mem_ptr<h__SequenceParser> m_Parser;
1161 ASDCP_NO_COPY_CONSTRUCT(SequenceParser);
1165 virtual ~SequenceParser();
1167 // Opens a directory for reading. The directory is expected to contain one or
1168 // more files, each containing the codestream for exactly one picture. The
1169 // files must be named such that the frames are in temporal order when sorted
1170 // alphabetically by filename. The parser will automatically parse enough data
1171 // from the first file to provide a complete set of stream metadata for the
1172 // MXFWriter below. If the "pedantic" parameter is given and is true, the
1173 // parser will check the metadata for each codestream and fail if a
1174 // mismatch is detected.
1175 Result_t OpenRead(const std::string& filename, bool pedantic = false) const;
1177 // Opens a file sequence for reading. The sequence is expected to contain one or
1178 // more filenames, each naming a file containing the codestream for exactly one
1179 // picture. The parser will automatically parse enough data
1180 // from the first file to provide a complete set of stream metadata for the
1181 // MXFWriter below. If the "pedantic" parameter is given and is true, the
1182 // parser will check the metadata for each codestream and fail if a
1183 // mismatch is detected.
1184 Result_t OpenRead(const std::list<std::string>& file_list, bool pedantic = false) const;
1186 // Fill a PictureDescriptor struct with the values from the first file's codestream.
1187 // Returns RESULT_INIT if the directory is not open.
1188 Result_t FillPictureDescriptor(PictureDescriptor&) const;
1190 // Rewind the directory to the beginning.
1191 Result_t Reset() const;
1193 // Reads the next sequential frame in the directory and places it in the
1194 // frame buffer. Fails if the buffer is too small or the direcdtory
1195 // contains no more files.
1196 // The frame buffer's PlaintextOffset parameter will be set to the first
1197 // byte of the data segment. Set this value to zero if you want
1198 // encrypted headers.
1199 Result_t ReadFrame(FrameBuffer&) const;
1207 mem_ptr<h__Writer> m_Writer;
1208 ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
1212 virtual ~MXFWriter();
1214 // Warning: direct manipulation of MXF structures can interfere
1215 // with the normal operation of the wrapper. Caveat emptor!
1216 virtual MXF::OP1aHeader& OP1aHeader();
1217 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1218 virtual MXF::RIP& RIP();
1220 // Open the file for writing. The file must not exist unless overwrite is true. Returns error if
1221 // the operation cannot be completed or if nonsensical data is discovered
1222 // in the essence descriptor.
1223 Result_t OpenWrite(const std::string& filename, const WriterInfo&,
1224 const PictureDescriptor&, ui32_t HeaderSize = 16384, bool overwrite = false);
1226 // Writes a frame of essence to the MXF file. If the optional AESEncContext
1227 // argument is present, the essence is encrypted prior to writing.
1228 // A MD5 hash of the data that we write is written to hash if it is not 0
1229 // Fails if the file is not open, is finalized, or an operating system
1231 Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0, std::string* hash = 0);
1233 Result_t FakeWriteFrame(int size);
1235 // Closes the MXF file, writing the index and revised header.
1236 Result_t Finalize();
1238 // Return the current file offset in the MXF file that we are writing
1239 ui64_t Tell() const;
1246 mem_ptr<h__Reader> m_Reader;
1247 ASDCP_NO_COPY_CONSTRUCT(MXFReader);
1251 virtual ~MXFReader();
1253 // Warning: direct manipulation of MXF structures can interfere
1254 // with the normal operation of the wrapper. Caveat emptor!
1255 virtual MXF::OP1aHeader& OP1aHeader();
1256 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1257 virtual MXF::RIP& RIP();
1259 // Open the file for reading. The file must exist. Returns error if the
1260 // operation cannot be completed.
1261 Result_t OpenRead(const std::string& filename) const;
1263 // Returns RESULT_INIT if the file is not open.
1264 Result_t Close() const;
1266 // Fill an AudioDescriptor struct with the values from the file's header.
1267 // Returns RESULT_INIT if the file is not open.
1268 Result_t FillPictureDescriptor(PictureDescriptor&) const;
1270 // Fill a WriterInfo struct with the values from the file's header.
1271 // Returns RESULT_INIT if the file is not open.
1272 Result_t FillWriterInfo(WriterInfo&) const;
1274 // Reads a frame of essence from the MXF file. If the optional AESEncContext
1275 // argument is present, the essence is decrypted after reading. If the MXF
1276 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1277 // will contain the ciphertext frame data. If the HMACContext argument is
1278 // not NULL, the HMAC will be calculated (if the file supports it).
1279 // Returns RESULT_INIT if the file is not open, failure if the frame number is
1280 // out of range, or if optional decrypt or HAMC operations fail.
1281 Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1283 // Using the index table read from the footer partition, lookup the frame number
1284 // and return the offset into the file at which to read that frame of essence.
1285 // Returns RESULT_INIT if the file is not open, and RESULT_FRAME if the frame number is
1287 Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
1289 // Print debugging information to stream
1290 void DumpHeaderMetadata(FILE* = 0) const;
1291 void DumpIndex(FILE* = 0) const;
1295 // Stereoscopic Image support
1298 enum StereoscopicPhase_t
1306 JP2K::FrameBuffer Left;
1307 JP2K::FrameBuffer Right;
1309 SFrameBuffer(ui32_t size) {
1310 Left.Capacity(size);
1311 Right.Capacity(size);
1318 mem_ptr<h__SWriter> m_Writer;
1319 ASDCP_NO_COPY_CONSTRUCT(MXFSWriter);
1323 virtual ~MXFSWriter();
1325 // Warning: direct manipulation of MXF structures can interfere
1326 // with the normal operation of the wrapper. Caveat emptor!
1327 virtual MXF::OP1aHeader& OP1aHeader();
1328 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1329 virtual MXF::RIP& RIP();
1331 // Open the file for writing. The file must not exist unless overwrite is true. Returns error if
1332 // the operation cannot be completed or if nonsensical data is discovered
1333 // in the essence descriptor.
1334 Result_t OpenWrite(const std::string& filename, const WriterInfo&,
1335 const PictureDescriptor&, ui32_t HeaderSize = 16384, bool overwrite = false);
1337 // Writes a pair of frames of essence to the MXF file. If the optional AESEncContext
1338 // argument is present, the essence is encrypted prior to writing.
1339 // Fails if the file is not open, is finalized, or an operating system
1341 Result_t WriteFrame(const SFrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
1343 // Writes a frame of essence to the MXF file. If the optional AESEncContext
1344 // argument is present, the essence is encrypted prior to writing.
1345 // Fails if the file is not open, is finalized, or an operating system
1346 // error occurs. Frames must be written in the proper phase (L-R-L-R),
1347 // RESULT_SPHASE will be returned if phase is reversed. The first frame
1348 // written must be left eye.
1349 Result_t WriteFrame(const FrameBuffer&, StereoscopicPhase_t phase,
1350 AESEncContext* = 0, HMACContext* = 0, std::string* hash = 0);
1352 Result_t FakeWriteFrame(int size, StereoscopicPhase_t phase);
1354 // Closes the MXF file, writing the index and revised header. Returns
1355 // RESULT_SPHASE if WriteFrame was called an odd number of times.
1356 Result_t Finalize();
1358 // Return the current file offset in the MXF file that we are writing
1359 ui64_t Tell() const;
1366 mem_ptr<h__SReader> m_Reader;
1367 ASDCP_NO_COPY_CONSTRUCT(MXFSReader);
1371 virtual ~MXFSReader();
1373 // Warning: direct manipulation of MXF structures can interfere
1374 // with the normal operation of the wrapper. Caveat emptor!
1375 virtual MXF::OP1aHeader& OP1aHeader();
1376 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1377 virtual MXF::RIP& RIP();
1379 // Open the file for reading. The file must exist. Returns error if the
1380 // operation cannot be completed.
1381 Result_t OpenRead(const std::string& filename) const;
1383 // Returns RESULT_INIT if the file is not open.
1384 Result_t Close() const;
1386 // Fill an AudioDescriptor struct with the values from the file's header.
1387 // Returns RESULT_INIT if the file is not open.
1388 Result_t FillPictureDescriptor(PictureDescriptor&) const;
1390 // Fill a WriterInfo struct with the values from the file's header.
1391 // Returns RESULT_INIT if the file is not open.
1392 Result_t FillWriterInfo(WriterInfo&) const;
1394 // Reads a pair of frames of essence from the MXF file. If the optional AESEncContext
1395 // argument is present, the essence is decrypted after reading. If the MXF
1396 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1397 // will contain the ciphertext frame data. If the HMACContext argument is
1398 // not NULL, the HMAC will be calculated (if the file supports it).
1399 // Returns RESULT_INIT if the file is not open, failure if the frame number is
1400 // out of range, or if optional decrypt or HAMC operations fail.
1401 Result_t ReadFrame(ui32_t frame_number, SFrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1403 // Reads a frame of essence from the MXF file. If the optional AESEncContext
1404 // argument is present, the essence is decrypted after reading. If the MXF
1405 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1406 // will contain the ciphertext frame data. If the HMACContext argument is
1407 // not NULL, the HMAC will be calculated (if the file supports it).
1408 // Returns RESULT_INIT if the file is not open, failure if the frame number is
1409 // out of range, or if optional decrypt or HAMC operations fail.
1410 Result_t ReadFrame(ui32_t frame_number, StereoscopicPhase_t phase,
1411 FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1413 // Using the index table read from the footer partition, lookup the frame number
1414 // and return the offset into the file at which to read that frame of essence.
1415 // Returns RESULT_INIT if the file is not open, and RESULT_FRAME if the frame number is
1417 Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
1419 // Print debugging information to stream
1420 void DumpHeaderMetadata(FILE* = 0) const;
1421 void DumpIndex(FILE* = 0) const;
1425 //---------------------------------------------------------------------------------
1429 enum MIMEType_t { MT_BIN, MT_PNG, MT_OPENTYPE };
1431 struct TimedTextResourceDescriptor
1433 byte_t ResourceID[UUIDlen];
1436 TimedTextResourceDescriptor() : Type(MT_BIN) {}
1439 typedef std::list<TimedTextResourceDescriptor> ResourceList_t;
1441 struct TimedTextDescriptor
1443 Rational EditRate; //
1444 ui32_t ContainerDuration;
1445 byte_t AssetID[UUIDlen];
1446 std::string NamespaceName;
1447 std::string EncodingName;
1448 ResourceList_t ResourceList;
1450 TimedTextDescriptor() : ContainerDuration(0), EncodingName("UTF-8") {} // D-Cinema format is always UTF-8
1453 // Print debugging information to std::ostream
1454 std::ostream& operator << (std::ostream& strm, const TimedTextDescriptor& tinfo);
1455 // Print debugging information to stream (stderr default)
1456 void DescriptorDump(const TimedTextDescriptor&, FILE* = 0);
1459 class FrameBuffer : public ASDCP::FrameBuffer
1461 ASDCP_NO_COPY_CONSTRUCT(FrameBuffer); // TODO: should have copy construct
1464 byte_t m_AssetID[UUIDlen];
1465 std::string m_MIMEType;
1468 FrameBuffer() { memset(m_AssetID, 0, UUIDlen); }
1469 FrameBuffer(ui32_t size) { Capacity(size); memset(m_AssetID, 0, UUIDlen); }
1470 virtual ~FrameBuffer() {}
1472 inline const byte_t* AssetID() const { return m_AssetID; }
1473 inline void AssetID(const byte_t* buf) { memcpy(m_AssetID, buf, UUIDlen); }
1474 inline const char* MIMEType() const { return m_MIMEType.c_str(); }
1475 inline void MIMEType(const std::string& s) { m_MIMEType = s; }
1477 // Print debugging information to stream (stderr default)
1478 void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
1481 // An abstract base for a lookup service that returns the resource data
1482 // identified by the given ancillary resource id.
1484 class IResourceResolver
1487 virtual ~IResourceResolver() {}
1488 virtual Result_t ResolveRID(const byte_t* uuid, FrameBuffer&) const = 0; // return data for RID
1491 // Resolves resource references by testing the named directory for file names containing
1492 // the respective UUID.
1494 class LocalFilenameResolver : public ASDCP::TimedText::IResourceResolver
1496 std::string m_Dirname;
1497 ASDCP_NO_COPY_CONSTRUCT(LocalFilenameResolver);
1500 LocalFilenameResolver();
1501 virtual ~LocalFilenameResolver();
1502 Result_t OpenRead(const std::string& dirname);
1503 Result_t ResolveRID(const byte_t* uuid, FrameBuffer& FrameBuf) const;
1507 class DCSubtitleParser
1509 class h__SubtitleParser;
1510 mem_ptr<h__SubtitleParser> m_Parser;
1511 ASDCP_NO_COPY_CONSTRUCT(DCSubtitleParser);
1515 virtual ~DCSubtitleParser();
1517 // Opens an XML file for reading, parses data to provide a complete
1518 // set of stream metadata for the MXFWriter below.
1519 Result_t OpenRead(const std::string& filename) const;
1521 // Parses an XML document to provide a complete set of stream metadata
1522 // for the MXFWriter below. The optional filename argument is used to
1523 // initialize the default resource resolver (see ReadAncillaryResource).
1524 Result_t OpenRead(const std::string& xml_doc, const std::string& filename) const;
1526 // Fill a TimedTextDescriptor struct with the values from the file's contents.
1527 // Returns RESULT_INIT if the file is not open.
1528 Result_t FillTimedTextDescriptor(TimedTextDescriptor&) const;
1530 // Reads the complete Timed Text Resource into the given string.
1531 Result_t ReadTimedTextResource(std::string&) const;
1533 // Reads the Ancillary Resource having the given ID. Fails if the buffer
1534 // is too small or the resource does not exist. The optional Resolver
1535 // argument can be provided which will be used to retrieve the resource
1536 // having a particulat UUID. If a Resolver is not supplied, the default
1537 // internal resolver will return the contents of the file having the UUID
1538 // as the filename. The filename must exist in the same directory as the
1539 // XML file opened with OpenRead().
1540 Result_t ReadAncillaryResource(const byte_t* uuid, FrameBuffer&,
1541 const IResourceResolver* Resolver = 0) const;
1548 mem_ptr<h__Writer> m_Writer;
1549 ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
1553 virtual ~MXFWriter();
1555 // Warning: direct manipulation of MXF structures can interfere
1556 // with the normal operation of the wrapper. Caveat emptor!
1557 virtual MXF::OP1aHeader& OP1aHeader();
1558 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1559 virtual MXF::RIP& RIP();
1561 // Open the file for writing. The file must not exist. Returns error if
1562 // the operation cannot be completed or if nonsensical data is discovered
1563 // in the essence descriptor.
1564 Result_t OpenWrite(const std::string& filename, const WriterInfo&,
1565 const TimedTextDescriptor&, ui32_t HeaderSize = 16384);
1567 // Writes the Timed-Text Resource to the MXF file. The file must be UTF-8
1568 // encoded. If the optional AESEncContext argument is present, the essence
1569 // is encrypted prior to writing. Fails if the file is not open, is finalized,
1570 // or an operating system error occurs.
1571 // This method may only be called once, and it must be called before any
1572 // call to WriteAncillaryResource(). RESULT_STATE will be returned if these
1573 // conditions are not met.
1574 Result_t WriteTimedTextResource(const std::string& XMLDoc, AESEncContext* = 0, HMACContext* = 0);
1576 // Writes an Ancillary Resource to the MXF file. If the optional AESEncContext
1577 // argument is present, the essence is encrypted prior to writing.
1578 // Fails if the file is not open, is finalized, or an operating system
1579 // error occurs. RESULT_STATE will be returned if the method is called before
1580 // WriteTimedTextResource()
1581 Result_t WriteAncillaryResource(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
1583 // Closes the MXF file, writing the index and revised header.
1584 Result_t Finalize();
1591 mem_ptr<h__Reader> m_Reader;
1592 ASDCP_NO_COPY_CONSTRUCT(MXFReader);
1596 virtual ~MXFReader();
1598 // Warning: direct manipulation of MXF structures can interfere
1599 // with the normal operation of the wrapper. Caveat emptor!
1600 virtual MXF::OP1aHeader& OP1aHeader();
1601 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1602 virtual MXF::RIP& RIP();
1604 // Open the file for reading. The file must exist. Returns error if the
1605 // operation cannot be completed.
1606 Result_t OpenRead(const std::string& filename) const;
1608 // Returns RESULT_INIT if the file is not open.
1609 Result_t Close() const;
1611 // Fill a TimedTextDescriptor struct with the values from the file's header.
1612 // Returns RESULT_INIT if the file is not open.
1613 Result_t FillTimedTextDescriptor(TimedTextDescriptor&) const;
1615 // Fill a WriterInfo struct with the values from the file's header.
1616 // Returns RESULT_INIT if the file is not open.
1617 Result_t FillWriterInfo(WriterInfo&) const;
1619 // Reads the complete Timed Text Resource into the given string. Fails if the resource
1620 // is encrypted and AESDecContext is NULL (use the following method to retrieve the
1621 // raw ciphertet block).
1622 Result_t ReadTimedTextResource(std::string&, AESDecContext* = 0, HMACContext* = 0) const;
1624 // Reads the complete Timed Text Resource from the MXF file. If the optional AESEncContext
1625 // argument is present, the resource is decrypted after reading. If the MXF
1626 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1627 // will contain the ciphertext frame data. If the HMACContext argument is
1628 // not NULL, the HMAC will be calculated (if the file supports it).
1629 // Returns RESULT_INIT if the file is not open, failure if the frame number is
1630 // out of range, or if optional decrypt or HAMC operations fail.
1631 Result_t ReadTimedTextResource(FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1633 // Reads the timed-text resource having the given UUID from the MXF file. If the
1634 // optional AESEncContext argument is present, the resource is decrypted after
1635 // reading. If the MXF file is encrypted and the AESDecContext argument is NULL,
1636 // the frame buffer will contain the ciphertext frame data. If the HMACContext
1637 // argument is not NULL, the HMAC will be calculated (if the file supports it).
1638 // Returns RESULT_INIT if the file is not open, failure if the frame number is
1639 // out of range, or if optional decrypt or HAMC operations fail.
1640 Result_t ReadAncillaryResource(const byte_t* uuid, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1642 // Print debugging information to stream
1643 void DumpHeaderMetadata(FILE* = 0) const;
1644 void DumpIndex(FILE* = 0) const;
1646 } // namespace TimedText
1648 //---------------------------------------------------------------------------------
1652 struct DCDataDescriptor
1654 Rational EditRate; // Sample rate
1655 ui32_t ContainerDuration; // number of frames
1656 byte_t AssetID[UUIDlen]; // The UUID for the DCData track
1657 byte_t DataEssenceCoding[UUIDlen]; // The coding for the data carried
1660 // Print DCDataDescriptor to std::ostream
1661 std::ostream& operator << (std::ostream& strm, const DCDataDescriptor& ddesc);
1662 // Print debugging information to stream (stderr default)
1663 void DCDataDescriptorDump(const DCDataDescriptor&, FILE* = 0);
1666 class FrameBuffer : public ASDCP::FrameBuffer
1670 FrameBuffer(ui32_t size) { Capacity(size); }
1671 virtual ~FrameBuffer() {}
1673 // Print debugging information to stream (stderr default)
1674 void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
1677 // An object which opens and reads a DC Data file. The file is expected
1678 // to contain exactly one complete frame of DC data essence as an unwrapped (raw)
1680 class BytestreamParser
1682 class h__BytestreamParser;
1683 mem_ptr<h__BytestreamParser> m_Parser;
1684 ASDCP_NO_COPY_CONSTRUCT(BytestreamParser);
1688 virtual ~BytestreamParser();
1690 // Opens a file for reading, parses enough data to provide a complete
1691 // set of stream metadata for the MXFWriter below.
1692 // The frame buffer's PlaintextOffset parameter will be set to the first
1693 // byte of the data segment. Set this value to zero if you want
1694 // encrypted headers.
1695 Result_t OpenReadFrame(const std::string& filename, FrameBuffer&) const;
1697 // Fill a DCDataDescriptor struct with the values from the file's bytestream.
1698 // Returns RESULT_INIT if the file is not open.
1699 Result_t FillDCDataDescriptor(DCDataDescriptor&) const;
1702 // An object which reads a sequence of files containing DC Data.
1703 class SequenceParser
1705 class h__SequenceParser;
1706 mem_ptr<h__SequenceParser> m_Parser;
1707 ASDCP_NO_COPY_CONSTRUCT(SequenceParser);
1711 virtual ~SequenceParser();
1713 // Opens a directory for reading. The directory is expected to contain one or
1714 // more files, each containing the bytestream for exactly one frame. The files
1715 // must be named such that the frames are in temporal order when sorted
1716 // alphabetically by filename.
1717 Result_t OpenRead(const std::string& filename) const;
1719 // Opens a file sequence for reading. The sequence is expected to contain one or
1720 // more filenames, each naming a file containing the bytestream for exactly one
1722 Result_t OpenRead(const std::list<std::string>& file_list) const;
1724 // Fill a DCDataDescriptor struct with default values.
1725 // Returns RESULT_INIT if the directory is not open.
1726 Result_t FillDCDataDescriptor(DCDataDescriptor&) const;
1728 // Rewind the directory to the beginning.
1729 Result_t Reset() const;
1731 // Reads the next sequential frame in the directory and places it in the
1732 // frame buffer. Fails if the buffer is too small or the direcdtory
1733 // contains no more files.
1734 // The frame buffer's PlaintextOffset parameter will be set to the first
1735 // byte of the data segment. Set this value to zero if you want
1736 // encrypted headers.
1737 Result_t ReadFrame(FrameBuffer&) const;
1744 mem_ptr<h__Writer> m_Writer;
1745 ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
1749 virtual ~MXFWriter();
1751 // Warning: direct manipulation of MXF structures can interfere
1752 // with the normal operation of the wrapper. Caveat emptor!
1753 virtual MXF::OP1aHeader& OP1aHeader();
1754 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1755 virtual MXF::RIP& RIP();
1757 // Open the file for writing. The file must not exist. Returns error if
1758 // the operation cannot be completed or if nonsensical data is discovered
1759 // in the essence descriptor.
1760 Result_t OpenWrite(const std::string& filename, const WriterInfo&,
1761 const DCDataDescriptor&, ui32_t HeaderSize = 16384);
1763 // Writes a frame of essence to the MXF file. If the optional AESEncContext
1764 // argument is present, the essence is encrypted prior to writing.
1765 // Fails if the file is not open, is finalized, or an operating system
1767 Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
1769 // Closes the MXF file, writing the index and revised header.
1770 Result_t Finalize();
1777 mem_ptr<h__Reader> m_Reader;
1778 ASDCP_NO_COPY_CONSTRUCT(MXFReader);
1782 virtual ~MXFReader();
1784 // Warning: direct manipulation of MXF structures can interfere
1785 // with the normal operation of the wrapper. Caveat emptor!
1786 virtual MXF::OP1aHeader& OP1aHeader();
1787 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1788 virtual MXF::RIP& RIP();
1790 // Open the file for reading. The file must exist. Returns error if the
1791 // operation cannot be completed.
1792 Result_t OpenRead(const std::string& filename) const;
1794 // Returns RESULT_INIT if the file is not open.
1795 Result_t Close() const;
1797 // Fill a DCDataDescriptor struct with the values from the file's header.
1798 // Returns RESULT_INIT if the file is not open.
1799 Result_t FillDCDataDescriptor(DCDataDescriptor&) const;
1801 // Fill a WriterInfo struct with the values from the file's header.
1802 // Returns RESULT_INIT if the file is not open.
1803 Result_t FillWriterInfo(WriterInfo&) const;
1805 // Reads a frame of essence from the MXF file. If the optional AESEncContext
1806 // argument is present, the essence is decrypted after reading. If the MXF
1807 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1808 // will contain the ciphertext frame data. If the HMACContext argument is
1809 // not NULL, the HMAC will be calculated (if the file supports it).
1810 // Returns RESULT_INIT if the file is not open, failure if the frame number is
1811 // out of range, or if optional decrypt or HAMC operations fail.
1812 Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1814 // Using the index table read from the footer partition, lookup the frame number
1815 // and return the offset into the file at which to read that frame of essence.
1816 // Returns RESULT_INIT if the file is not open, and RESULT_RANGE if the frame number is
1818 Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
1820 // Print debugging information to stream
1821 void DumpHeaderMetadata(FILE* = 0) const;
1822 void DumpIndex(FILE* = 0) const;
1825 } // namespace DCData
1827 //---------------------------------------------------------------------------------
1831 struct AtmosDescriptor : public DCData::DCDataDescriptor
1833 ui32_t FirstFrame; // Frame number of the frame to align with the FFOA of the picture track
1834 ui16_t MaxChannelCount; // Max number of channels in bitstream
1835 ui16_t MaxObjectCount; // Max number of objects in bitstream
1836 byte_t AtmosID[UUIDlen]; // UUID of Atmos Project
1837 ui8_t AtmosVersion; // ATMOS Coder Version used to create bitstream
1840 // Print AtmosDescriptor to std::ostream
1841 std::ostream& operator << (std::ostream& strm, const AtmosDescriptor& adesc);
1842 // Print debugging information to stream (stderr default)
1843 void AtmosDescriptorDump(const AtmosDescriptor&, FILE* = 0);
1844 // Determine if a file is a raw atmos file
1845 bool IsDolbyAtmos(const std::string& filename);
1852 mem_ptr<h__Writer> m_Writer;
1853 ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
1857 virtual ~MXFWriter();
1859 // Warning: direct manipulation of MXF structures can interfere
1860 // with the normal operation of the wrapper. Caveat emptor!
1861 virtual MXF::OP1aHeader& OP1aHeader();
1862 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1863 virtual MXF::RIP& RIP();
1865 // Open the file for writing. The file must not exist. Returns error if
1866 // the operation cannot be completed or if nonsensical data is discovered
1867 // in the essence descriptor.
1868 Result_t OpenWrite(const std::string& filename, const WriterInfo&,
1869 const AtmosDescriptor&, ui32_t HeaderSize = 16384);
1871 // Writes a frame of essence to the MXF file. If the optional AESEncContext
1872 // argument is present, the essence is encrypted prior to writing.
1873 // Fails if the file is not open, is finalized, or an operating system
1875 Result_t WriteFrame(const DCData::FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
1877 // Closes the MXF file, writing the index and revised header.
1878 Result_t Finalize();
1885 mem_ptr<h__Reader> m_Reader;
1886 ASDCP_NO_COPY_CONSTRUCT(MXFReader);
1890 virtual ~MXFReader();
1892 // Warning: direct manipulation of MXF structures can interfere
1893 // with the normal operation of the wrapper. Caveat emptor!
1894 virtual MXF::OP1aHeader& OP1aHeader();
1895 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1896 virtual MXF::RIP& RIP();
1898 // Open the file for reading. The file must exist. Returns error if the
1899 // operation cannot be completed.
1900 Result_t OpenRead(const std::string& filename) const;
1902 // Returns RESULT_INIT if the file is not open.
1903 Result_t Close() const;
1905 // Fill an AtmosDescriptor struct with the values from the file's header.
1906 // Returns RESULT_INIT if the file is not open.
1907 Result_t FillAtmosDescriptor(AtmosDescriptor&) const;
1909 // Fill a WriterInfo struct with the values from the file's header.
1910 // Returns RESULT_INIT if the file is not open.
1911 Result_t FillWriterInfo(WriterInfo&) const;
1913 // Reads a frame of essence from the MXF file. If the optional AESEncContext
1914 // argument is present, the essence is decrypted after reading. If the MXF
1915 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1916 // will contain the ciphertext frame data. If the HMACContext argument is
1917 // not NULL, the HMAC will be calculated (if the file supports it).
1918 // Returns RESULT_INIT if the file is not open, failure if the frame number is
1919 // out of range, or if optional decrypt or HAMC operations fail.
1920 Result_t ReadFrame(ui32_t frame_number, DCData::FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1922 // Using the index table read from the footer partition, lookup the frame number
1923 // and return the offset into the file at which to read that frame of essence.
1924 // Returns RESULT_INIT if the file is not open, and RESULT_RANGE if the frame number is
1926 Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
1928 // Print debugging information to stream
1929 void DumpHeaderMetadata(FILE* = 0) const;
1930 void DumpIndex(FILE* = 0) const;
1933 } // namespace ATMOS
1937 } // namespace ASDCP
1940 #endif // _AS_DCP_H_