2 Copyright (c) 2003-2012, 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.
28 \version $Id: AS_DCP.h,v 1.43 2012/02/02 01:58:43 jhurst Exp $
29 \brief AS-DCP library, public interface
31 The asdcplib library is a set of file access objects that offer simplified
32 access to files conforming to the standards published by the SMPTE
33 D-Cinema Technology Committee 21DC. The file format, labeled AS-DCP,
34 is described in series of separate documents which include but may not
37 o SMPTE ST 429-2:2011 DCP Operational Constraints
38 o SMPTE ST 429-3:2006 Sound and Picture Track File
39 o SMPTE ST 429-4:2006 MXF JPEG 2000 Application
40 o SMPTE ST 429-5:2009 Timed Text Track File
41 o SMPTE ST 429-6:2006 MXF Track File Essence Encryption
42 o SMPTE ST 429-10:2008 Stereoscopic Picture Track File
43 o SMPTE ST 330:2004 - UMID
44 o SMPTE ST 336:2001 - KLV
45 o SMPTE ST 377-1:2011 - MXF
46 o SMPTE ST 377-4:2012 - MXF Multichannel Audio Labeling Framework
47 o SMPTE ST 390:2011 - MXF OP-Atom
48 o SMPTE ST 379-1:2009 - MXF Generic Container (GC)
49 o SMPTE ST 381-1:2005 - MPEG2 picture in GC
50 o SMPTE ST 422:2006 - JPEG 2000 picture in GC
51 o SMPTE ST 382:2007 - WAV/PCM sound in GC
52 o IETF RFC 2104 - HMAC/SHA1
53 o NIST FIPS 197 - AES (Rijndael) (via OpenSSL)
55 o MXF Interop Track File Specification
56 o MXF Interop Track File Essence Encryption Specification
57 o MXF Interop Operational Constraints Specification
58 - Note: the MXF Interop documents are not formally published.
59 Contact the asdcplib support address to get copies.
61 The following use cases are supported by the library:
63 o Write essence to a plaintext or ciphertext AS-DCP file:
64 MPEG2 Video Elementary Stream
66 JPEG 2000 stereoscopic codestream pairs
68 SMPTE 429-7 Timed Text XML with font and image resources
70 o Read essence from a plaintext or ciphertext AS-DCP file:
71 MPEG2 Video Elementary Stream
73 JPEG 2000 stereoscopic codestream pairs
75 SMPTE 429-7 Timed Text XML with font and image resources
77 o Read header metadata from an AS-DCP file
79 This project depends upon the following libraries:
80 - OpenSSL http://www.openssl.org/
81 - Expat http://expat.sourceforge.net/ or
82 Xerces-C http://xerces.apache.org/xerces-c/
83 An XML library is not needed if you don't need support for SMPTE ST 429-5:2009.
90 #include <KM_platform.h>
99 //--------------------------------------------------------------------------------
100 // common integer types
101 // supply your own by defining ASDCP_NO_BASE_TYPES
103 #ifndef ASDCP_NO_BASE_TYPES
104 typedef unsigned char byte_t;
106 typedef unsigned char ui8_t;
108 typedef unsigned short ui16_t;
110 typedef unsigned int ui32_t;
114 //--------------------------------------------------------------------------------
115 // convenience macros
117 // Convenience macros for managing return values in predicates
118 #define ASDCP_SUCCESS(v) (((v) < 0) ? 0 : 1)
119 #define ASDCP_FAILURE(v) (((v) < 0) ? 1 : 0)
122 // Returns RESULT_PTR if the given argument is NULL.
123 // See Result_t below for an explanation of RESULT_* symbols.
124 #define ASDCP_TEST_NULL(p) \
126 return ASDCP::RESULT_PTR; \
129 // Returns RESULT_PTR if the given argument is NULL. See Result_t
130 // below for an explanation of RESULT_* symbols. It then assumes
131 // that the argument is a pointer to a string and returns
132 // RESULT_NULL_STR if the first character is '\0'.
134 #define ASDCP_TEST_NULL_STR(p) \
135 ASDCP_TEST_NULL(p); \
136 if ( (p)[0] == '\0' ) { \
137 return ASDCP::RESULT_NULL_STR; \
140 // Produces copy constructor boilerplate. Allows convenient private
141 // declatarion of copy constructors to prevent the compiler from
142 // silently manufacturing default methods.
143 #define ASDCP_NO_COPY_CONSTRUCT(T) \
145 T& operator=(const T&)
147 //--------------------------------------------------------------------------------
148 // All library components are defined in the namespace ASDCP
152 // The version number declaration and explanation have moved to ../configure.ac
153 const char* Version();
155 // UUIDs are passed around as strings of UUIDlen bytes
156 const ui32_t UUIDlen = 16;
158 // Encryption keys are passed around as strings of KeyLen bytes
159 const ui32_t KeyLen = 16;
161 //---------------------------------------------------------------------------------
164 using Kumu::Result_t;
166 using Kumu::RESULT_FALSE;
167 using Kumu::RESULT_OK;
168 using Kumu::RESULT_FAIL;
169 using Kumu::RESULT_PTR;
170 using Kumu::RESULT_NULL_STR;
171 using Kumu::RESULT_ALLOC;
172 using Kumu::RESULT_PARAM;
173 using Kumu::RESULT_SMALLBUF;
174 using Kumu::RESULT_INIT;
175 using Kumu::RESULT_NOT_FOUND;
176 using Kumu::RESULT_NO_PERM;
177 using Kumu::RESULT_FILEOPEN;
178 using Kumu::RESULT_BADSEEK;
179 using Kumu::RESULT_READFAIL;
180 using Kumu::RESULT_WRITEFAIL;
181 using Kumu::RESULT_STATE;
182 using Kumu::RESULT_ENDOFFILE;
183 using Kumu::RESULT_CONFIG;
185 KM_DECLARE_RESULT(FORMAT, -101, "The file format is not proper OP-Atom/AS-DCP.");
186 KM_DECLARE_RESULT(RAW_ESS, -102, "Unknown raw essence file type.");
187 KM_DECLARE_RESULT(RAW_FORMAT, -103, "Raw essence format invalid.");
188 KM_DECLARE_RESULT(RANGE, -104, "Frame number out of range.");
189 KM_DECLARE_RESULT(CRYPT_CTX, -105, "AESEncContext required when writing to encrypted file.");
190 KM_DECLARE_RESULT(LARGE_PTO, -106, "Plaintext offset exceeds frame buffer size.");
191 KM_DECLARE_RESULT(CAPEXTMEM, -107, "Cannot resize externally allocated memory.");
192 KM_DECLARE_RESULT(CHECKFAIL, -108, "The check value did not decrypt correctly.");
193 KM_DECLARE_RESULT(HMACFAIL, -109, "HMAC authentication failure.");
194 KM_DECLARE_RESULT(HMAC_CTX, -110, "HMAC context required.");
195 KM_DECLARE_RESULT(CRYPT_INIT, -111, "Error initializing block cipher context.");
196 KM_DECLARE_RESULT(EMPTY_FB, -112, "Empty frame buffer.");
197 KM_DECLARE_RESULT(KLV_CODING, -113, "KLV coding error.");
198 KM_DECLARE_RESULT(SPHASE, -114, "Stereoscopic phase mismatch.");
199 KM_DECLARE_RESULT(SFORMAT, -115, "Rate mismatch, file may contain stereoscopic essence.");
201 //---------------------------------------------------------------------------------
202 // file identification
204 // The file accessors in this library implement a bounded set of essence types.
205 // This list will be expanded when support for new types is added to the library.
207 ESS_UNKNOWN, // the file is not a supported AS-DCP essence container
208 ESS_MPEG2_VES, // the file contains an MPEG video elementary stream
209 ESS_JPEG_2000, // the file contains one or more JPEG 2000 codestreams
210 ESS_PCM_24b_48k, // the file contains one or more PCM audio pairs
211 ESS_PCM_24b_96k, // the file contains one or more PCM audio pairs
212 ESS_TIMED_TEXT, // the file contains an XML timed text document and one or more resources
213 ESS_JPEG_2000_S, // the file contains one or more JPEG 2000 codestream pairs (stereoscopic)
216 // Determine the type of essence contained in the given MXF file. RESULT_OK
217 // is returned if the file is successfully opened and contains a valid MXF
218 // stream. If there is an error, the result code will indicate the reason.
219 Result_t EssenceType(const char* filename, EssenceType_t& type);
221 // Determine the type of essence contained in the given raw file. RESULT_OK
222 // is returned if the file is successfully opened and contains a known
223 // stream type. If there is an error, the result code will indicate the reason.
224 Result_t RawEssenceType(const char* filename, EssenceType_t& type);
227 //---------------------------------------------------------------------------------
230 // A simple container for rational numbers.
237 Rational() : Numerator(0), Denominator(0) {}
238 Rational(i32_t n, i32_t d) : Numerator(n), Denominator(d) {}
240 inline double Quotient() const {
241 return (double)Numerator / (double)Denominator;
244 inline bool operator==(const Rational& rhs) const {
245 return ( rhs.Numerator == Numerator && rhs.Denominator == Denominator );
248 inline bool operator!=(const Rational& rhs) const {
249 return ( rhs.Numerator != Numerator || rhs.Denominator != Denominator );
252 inline bool operator<(const Rational& rhs) {
253 if ( Numerator < rhs.Numerator ) return true;
254 if ( Numerator == rhs.Numerator && Denominator < rhs.Denominator ) return true;
258 inline bool operator>(const Rational& rhs) {
259 if ( Numerator > rhs.Numerator ) return true;
260 if ( Numerator == rhs.Numerator && Denominator > rhs.Denominator ) return true;
265 // common edit rates, use these instead of hard coded constants
266 const Rational EditRate_24 = Rational(24,1);
267 const Rational EditRate_23_98 = Rational(24000,1001); // Not a DCI-compliant value!
268 const Rational EditRate_48 = Rational(48,1);
269 const Rational SampleRate_48k = Rational(48000,1);
270 const Rational SampleRate_96k = Rational(96000,1);
272 // Additional frame rates, see ST 428-11, ST 429-13
273 // These rates are new and not supported by all systems. Do not assume that
274 // a package made using one of these rates will work just anywhere!
275 const Rational EditRate_25 = Rational(25,1);
276 const Rational EditRate_30 = Rational(30,1);
277 const Rational EditRate_50 = Rational(50,1);
278 const Rational EditRate_60 = Rational(60,1);
279 const Rational EditRate_96 = Rational(96,1);
280 const Rational EditRate_100 = Rational(100,1);
281 const Rational EditRate_120 = Rational(120,1);
283 // Non-reference counting container for internal member objects.
284 // Please do not use this class for any other purpose.
288 T* m_p; // the thing we point to
292 mem_ptr() : m_p(0) {}
293 mem_ptr(T* p) : m_p(p) {}
294 ~mem_ptr() { delete m_p; }
296 inline T& operator*() const { return *m_p; }
297 inline T* operator->() const { return m_p; }
298 inline operator T*()const { return m_p; }
299 inline const mem_ptr<T>& operator=(T* p) { set(p); return *this; }
300 inline T* set(T* p) { delete m_p; m_p = p; return m_p; }
301 inline T* get() const { return m_p; }
302 inline void release() { m_p = 0; }
303 inline bool empty() const { return m_p == 0; }
307 //---------------------------------------------------------------------------------
308 // WriterInfo class - encapsulates writer identification details used for
309 // OpenWrite() calls. Replace these values at runtime to identify your product.
311 // MXF files use SMPTE Universal Labels to identify data items. The set of Labels
312 // in a file is determined by the MXF Operational Pattern and any constraining
313 // documentation. There are currently two flavors of AS-DCP file in use: MXF Interop
314 // (AKA JPEG Interop) and SMPTE. The two differ in the values of three labels:
317 // Interop : 06 0e 2b 34 04 01 01 01 0d 01 02 01 10 00 00 00
318 // SMPTE : 06 0e 2b 34 04 01 01 02 0d 01 02 01 10 00 00 00
321 // Interop : 06 0e 2b 34 02 04 01 07 0d 01 03 01 02 7e 01 00
322 // SMPTE : 06 0e 2b 34 02 04 01 01 0d 01 03 01 02 7e 01 00
324 // GenericDescriptor/SubDescriptors:
325 // Interop : 06 0e 2b 34 01 01 01 02 06 01 01 04 06 10 00 00
326 // SMPTE : 06 0e 2b 34 01 01 01 09 06 01 01 04 06 10 00 00
328 // asdcplib will read any (otherwise valid) file which has any combination of the
329 // above values. When writing files, MXF Interop labels are used by default. To
330 // write a file containing SMPTE labels, replace the default label set value in
331 // the WriterInfo before calling OpenWrite()
344 byte_t ProductUUID[UUIDlen];
345 byte_t AssetUUID[UUIDlen];
346 byte_t ContextID[UUIDlen];
347 byte_t CryptographicKeyID[UUIDlen];
348 bool EncryptedEssence; // true if essence data is (or is going to be) encrypted
349 bool UsesHMAC; // true if HMAC exists or is to be calculated
350 std::string ProductVersion;
351 std::string CompanyName;
352 std::string ProductName;
353 LabelSet_t LabelSetType;
355 WriterInfo() : EncryptedEssence(false), UsesHMAC(false), LabelSetType(LS_MXF_INTEROP)
357 static byte_t default_ProductUUID_Data[UUIDlen] = {
358 0x43, 0x05, 0x9a, 0x1d, 0x04, 0x32, 0x41, 0x01,
359 0xb8, 0x3f, 0x73, 0x68, 0x15, 0xac, 0xf3, 0x1d };
361 memcpy(ProductUUID, default_ProductUUID_Data, UUIDlen);
362 memset(AssetUUID, 0, UUIDlen);
363 memset(ContextID, 0, UUIDlen);
364 memset(CryptographicKeyID, 0, UUIDlen);
366 ProductVersion = "Unreleased ";
367 ProductVersion += Version();
369 ProductName = "asdcplib";
373 // Print WriterInfo to std::ostream
374 std::ostream& operator << (std::ostream& strm, const WriterInfo& winfo);
375 // Print WriterInfo to stream, stderr by default.
376 void WriterInfoDump(const WriterInfo&, FILE* = 0);
378 //---------------------------------------------------------------------------------
379 // cryptographic support
381 // The following classes define interfaces to Rijndael contexts having the following properties:
383 // o CBC mode with 16 byte block size
384 const ui32_t CBC_KEY_SIZE = 16;
385 const ui32_t CBC_BLOCK_SIZE = 16;
386 const ui32_t HMAC_SIZE = 20;
392 mem_ptr<h__AESContext> m_Context;
393 ASDCP_NO_COPY_CONSTRUCT(AESEncContext);
399 // Initializes Rijndael CBC encryption context.
400 // Returns error if the key argument is NULL.
401 Result_t InitKey(const byte_t* key);
403 // Initializes 16 byte CBC Initialization Vector. This operation may be performed
404 // any number of times for a given key.
405 // Returns error if the i_vec argument is NULL.
406 Result_t SetIVec(const byte_t* i_vec);
407 Result_t GetIVec(byte_t* i_vec) const;
409 // Encrypt a block of data. The block size must be a multiple of CBC_BLOCK_SIZE.
410 // Returns error if either argument is NULL.
411 Result_t EncryptBlock(const byte_t* pt_buf, byte_t* ct_buf, ui32_t block_size);
418 mem_ptr<h__AESContext> m_Context;
419 ASDCP_NO_COPY_CONSTRUCT(AESDecContext);
425 // Initializes Rijndael CBC decryption context.
426 // Returns error if the key argument is NULL.
427 Result_t InitKey(const byte_t* key);
429 // Initializes 16 byte CBC Initialization Vector. This operation may be performed
430 // any number of times for a given key.
431 // Returns error if the i_vec argument is NULL.
432 Result_t SetIVec(const byte_t* i_vec);
434 // Decrypt a block of data. The block size must be a multiple of CBC_BLOCK_SIZE.
435 // Returns error if either argument is NULL.
436 Result_t DecryptBlock(const byte_t* ct_buf, byte_t* pt_buf, ui32_t block_size);
442 class h__HMACContext;
443 mem_ptr<h__HMACContext> m_Context;
444 ASDCP_NO_COPY_CONSTRUCT(HMACContext);
450 // Initializes HMAC context. The key argument must point to a binary
451 // key that is CBC_KEY_SIZE bytes in length. Returns error if the key
453 Result_t InitKey(const byte_t* key, LabelSet_t);
455 // Reset internal state, allows repeated cycles of Update -> Finalize
458 // Add data to the digest. Returns error if the key argument is NULL or
459 // if the digest has been finalized.
460 Result_t Update(const byte_t* buf, ui32_t buf_len);
462 // Finalize digest. Returns error if the digest has already been finalized.
465 // Writes HMAC value to given buffer. buf must point to a writable area of
466 // memory that is at least HMAC_SIZE bytes in length. Returns error if the
467 // buf argument is NULL or if the digest has not been finalized.
468 Result_t GetHMACValue(byte_t* buf) const;
470 // Tests the given value against the finalized value in the object. buf must
471 // point to a readable area of memory that is at least HMAC_SIZE bytes in length.
472 // Returns error if the buf argument is NULL or if the values do ot match.
473 Result_t TestHMACValue(const byte_t* buf) const;
476 //---------------------------------------------------------------------------------
477 // frame buffer base class
479 // The supported essence types are stored using per-frame KLV packetization. The
480 // following class implements essence-neutral functionality for managing a buffer
481 // containing a frame of essence.
485 ASDCP_NO_COPY_CONSTRUCT(FrameBuffer);
488 byte_t* m_Data; // pointer to memory area containing frame data
489 ui32_t m_Capacity; // size of memory area pointed to by m_Data
490 bool m_OwnMem; // if false, m_Data points to externally allocated memory
491 ui32_t m_Size; // size of frame data in memory area pointed to by m_Data
492 ui32_t m_FrameNumber; // delivery-order frame number
494 // It is possible to read raw ciphertext from an encrypted AS-DCP file.
495 // After reading an encrypted AS-DCP file in raw mode, the frame buffer will
496 // contain the encrypted source value portion of the Encrypted Triplet, followed
497 // by the integrity pack, if it exists.
498 // The buffer will begin with the IV and CheckValue, followed by encrypted essence
499 // and optional integrity pack
500 // The SourceLength and PlaintextOffset values from the packet will be held in the
501 // following variables:
502 ui32_t m_SourceLength; // plaintext length (delivered plaintext+decrypted ciphertext)
503 ui32_t m_PlaintextOffset; // offset to first byte of ciphertext
507 virtual ~FrameBuffer();
509 // Instructs the object to use an externally allocated buffer. The external
510 // buffer will not be cleaned up by the frame buffer when it exits.
511 // Call with (0,0) to revert to internally allocated buffer.
512 // Returns error if the buf_addr argument is NULL and buf_size is non-zero.
513 Result_t SetData(byte_t* buf_addr, ui32_t buf_size);
515 // Sets the size of the internally allocate buffer. Returns RESULT_CAPEXTMEM
516 // if the object is using an externally allocated buffer via SetData();
517 // Resets content size to zero.
518 Result_t Capacity(ui32_t cap);
520 // returns the size of the buffer
521 inline ui32_t Capacity() const { return m_Capacity; }
523 // returns a const pointer to the essence data
524 inline const byte_t* RoData() const { return m_Data; }
526 // returns a non-const pointer to the essence data
527 inline byte_t* Data() { return m_Data; }
529 // set the size of the buffer's contents
530 inline ui32_t Size(ui32_t size) { return m_Size = size; }
532 // returns the size of the buffer's contents
533 inline ui32_t Size() const { return m_Size; }
535 // Sets the absolute frame number of this frame in the file in delivery order.
536 inline void FrameNumber(ui32_t num) { m_FrameNumber = num; }
538 // Returns the absolute frame number of this frame in the file in delivery order.
539 inline ui32_t FrameNumber() const { return m_FrameNumber; }
541 // Sets the length of the plaintext essence data
542 inline void SourceLength(ui32_t len) { m_SourceLength = len; }
544 // When this value is 0 (zero), the buffer contains only plaintext. When it is
545 // non-zero, the buffer contains raw ciphertext and the return value is the length
546 // of the original plaintext.
547 inline ui32_t SourceLength() const { return m_SourceLength; }
549 // Sets the offset into the buffer at which encrypted data begins
550 inline void PlaintextOffset(ui32_t ofst) { m_PlaintextOffset = ofst; }
552 // Returns offset into buffer of first byte of ciphertext.
553 inline ui32_t PlaintextOffset() const { return m_PlaintextOffset; }
556 //---------------------------------------------------------------------------------
557 // Accessors in the MXFReader and MXFWriter classes below return these types to
558 // provide direct access to MXF metadata structures declared in MXF.h and Metadata.h
561 // #include<Metadata.h> to use these
563 class OPAtomIndexFooter;
566 //---------------------------------------------------------------------------------
567 // MPEG2 video elementary stream support
572 // MPEG picture coding type
574 FRAME_U = 0x00, // Unknown
575 FRAME_I = 0x01, // I-Frame
576 FRAME_P = 0x02, // P-Frame
577 FRAME_B = 0x03 // B-Frame
580 // convert FrameType_t to char
581 inline char FrameTypeChar(FrameType_t type)
585 case FRAME_I: return 'I';
586 case FRAME_B: return 'B';
587 case FRAME_P: return 'P';
592 // Structure represents the metadata elements in the file header's
593 // MPEG2VideoDescriptor object.
594 struct VideoDescriptor
596 Rational EditRate; //
598 Rational SampleRate; //
599 ui8_t FrameLayout; //
600 ui32_t StoredWidth; //
601 ui32_t StoredHeight; //
602 Rational AspectRatio; //
603 ui32_t ComponentDepth; //
604 ui32_t HorizontalSubsampling; //
605 ui32_t VerticalSubsampling; //
606 ui8_t ColorSiting; //
607 ui8_t CodedContentType; //
610 ui8_t ProfileAndLevel; //
611 ui32_t ContainerDuration; //
614 // Print VideoDescriptor to std::ostream
615 std::ostream& operator << (std::ostream& strm, const VideoDescriptor& vdesc);
616 // Print VideoDescriptor to stream, stderr by default.
617 void VideoDescriptorDump(const VideoDescriptor&, FILE* = 0);
619 // A container for MPEG frame data.
620 class FrameBuffer : public ASDCP::FrameBuffer
622 ASDCP_NO_COPY_CONSTRUCT(FrameBuffer); // TODO: should have copy construct
625 FrameType_t m_FrameType;
626 ui8_t m_TemporalOffset;
632 m_FrameType(FRAME_U), m_TemporalOffset(0),
633 m_ClosedGOP(false), m_GOPStart(false) {}
635 FrameBuffer(ui32_t size) :
636 m_FrameType(FRAME_U), m_TemporalOffset(0),
637 m_ClosedGOP(false), m_GOPStart(false)
642 virtual ~FrameBuffer() {}
644 // Sets the MPEG frame type of the picture data in the frame buffer.
645 inline void FrameType(FrameType_t type) { m_FrameType = type; }
647 // Returns the MPEG frame type of the picture data in the frame buffer.
648 inline FrameType_t FrameType() const { return m_FrameType; }
650 // Sets the MPEG temporal offset of the picture data in the frame buffer.
651 inline void TemporalOffset(ui8_t offset) { m_TemporalOffset = offset; }
653 // Returns the MPEG temporal offset of the picture data in the frame buffer.
654 inline ui8_t TemporalOffset() const { return m_TemporalOffset; }
656 // Sets the MPEG GOP 'start' attribute for the frame buffer.
657 inline void GOPStart(bool start) { m_GOPStart = start; }
659 // True if the frame in the buffer is the first in the GOP (in transport order)
660 inline bool GOPStart() const { return m_GOPStart; }
662 // Sets the MPEG GOP 'closed' attribute for the frame buffer.
663 inline void ClosedGOP(bool closed) { m_ClosedGOP = closed; }
665 // Returns true if the frame in the buffer is from a closed GOP, false if
666 // the frame is from an open GOP. Always returns false unless GOPStart()
668 inline bool ClosedGOP() const { return m_ClosedGOP; }
670 // Print object state to stream, include n bytes of frame data if indicated.
671 // Default stream is stderr.
672 void Dump(FILE* = 0, ui32_t dump_len = 0) const;
676 // An object which opens and reads an MPEG2 Video Elementary Stream file. The call to
677 // OpenRead() reads metadata from the file and populates an internal VideoDescriptor object.
678 // Each subsequent call to ReadFrame() reads exactly one frame from the stream into the
679 // given FrameBuffer object.
683 mem_ptr<h__Parser> m_Parser;
684 ASDCP_NO_COPY_CONSTRUCT(Parser);
690 // Opens the stream for reading, parses enough data to provide a complete
691 // set of stream metadata for the MXFWriter below.
692 Result_t OpenRead(const char* filename) const;
694 // Fill a VideoDescriptor struct with the values from the file's header.
695 // Returns RESULT_INIT if the file is not open.
696 Result_t FillVideoDescriptor(VideoDescriptor&) const;
698 // Rewind the stream to the beginning.
699 Result_t Reset() const;
701 // Reads the next sequential frame in the input file and places it in the
702 // frame buffer. Fails if the buffer is too small or the stream is empty.
703 // The frame buffer's PlaintextOffset parameter will be set to the first
704 // data byte of the first slice. Set this value to zero if you want
705 // encrypted headers.
706 Result_t ReadFrame(FrameBuffer&) const;
709 // A class which creates and writes MPEG frame data to an AS-DCP format MXF file.
710 // Not yet implemented
714 mem_ptr<h__Writer> m_Writer;
715 ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
719 virtual ~MXFWriter();
721 // Warning: direct manipulation of MXF structures can interfere
722 // with the normal operation of the wrapper. Caveat emptor!
723 virtual MXF::OPAtomHeader& OPAtomHeader();
724 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
726 // Open the file for writing. The file must not exist. Returns error if
727 // the operation cannot be completed or if nonsensical data is discovered
728 // in the essence descriptor.
729 Result_t OpenWrite(const char* filename, const WriterInfo&,
730 const VideoDescriptor&, ui32_t HeaderSize = 16384);
732 // Writes a frame of essence to the MXF file. If the optional AESEncContext
733 // argument is present, the essence is encrypted prior to writing.
734 // Fails if the file is not open, is finalized, or an operating system
736 Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
738 // Closes the MXF file, writing the index and revised header.
742 // A class which reads MPEG frame data from an AS-DCP format MXF file.
746 mem_ptr<h__Reader> m_Reader;
747 ASDCP_NO_COPY_CONSTRUCT(MXFReader);
751 virtual ~MXFReader();
753 // Warning: direct manipulation of MXF structures can interfere
754 // with the normal operation of the wrapper. Caveat emptor!
755 virtual MXF::OPAtomHeader& OPAtomHeader();
756 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
758 // Open the file for reading. The file must exist. Returns error if the
759 // operation cannot be completed.
760 Result_t OpenRead(const char* filename) const;
762 // Returns RESULT_INIT if the file is not open.
763 Result_t Close() const;
765 // Fill a VideoDescriptor struct with the values from the file's header.
766 // Returns RESULT_INIT if the file is not open.
767 Result_t FillVideoDescriptor(VideoDescriptor&) const;
769 // Fill a WriterInfo struct with the values from the file's header.
770 // Returns RESULT_INIT if the file is not open.
771 Result_t FillWriterInfo(WriterInfo&) const;
773 // Reads a frame of essence from the MXF file. If the optional AESEncContext
774 // argument is present, the essence is decrypted after reading. If the MXF
775 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
776 // will contain the ciphertext frame data. If the HMACContext argument is
777 // not NULL, the HMAC will be calculated (if the file supports it).
778 // Returns RESULT_INIT if the file is not open, failure if the frame number is
779 // out of range, or if optional decrypt or HAMC operations fail.
780 Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
782 // Calculates the first frame in transport order of the GOP in which the requested
783 // frame is located. Calls ReadFrame() to fetch the frame at the calculated position.
784 // Returns RESULT_INIT if the file is not open.
785 Result_t ReadFrameGOPStart(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
787 // Calculates the first frame in transport order of the GOP in which the requested
788 // frame is located. Sets key_frame_number to the number of the frame at the calculated position.
789 // Returns RESULT_INIT if the file is not open.
790 Result_t FindFrameGOPStart(ui32_t frame_number, ui32_t& key_frame_number) const;
792 // Returns the type of the frame at the given position.
793 // Returns RESULT_INIT if the file is not open or RESULT_RANGE if the index is out of range.
794 Result_t FrameType(ui32_t frame_number, FrameType_t&) const;
796 // Print debugging information to stream
797 void DumpHeaderMetadata(FILE* = 0) const;
798 void DumpIndex(FILE* = 0) const;
802 //---------------------------------------------------------------------------------
809 // The default value of the ChannelFormat element of the AudioDescriptor struct
810 // is CF_NONE. If the value is set to one of the other ChannelFormat_t enum
811 // values, the file's Wave Audio Descriptor will contain a Channel Assignment
814 // The channel format should be one of (CF_CFG_1, CF_CFG_2, or CF_CFG_3) for
815 // SMPTE 429-2 files. It should normally be CF_NONE for JPEG Interop files, but
816 // the 429-2 may also be used.
818 enum ChannelFormat_t {
820 CF_CFG_1, // 5.1 with optional HI/VI
821 CF_CFG_2, // 6.1 (5.1 + center surround) with optional HI/VI
822 CF_CFG_3, // 7.1 (SDDS) with optional HI/VI
823 CF_CFG_4, // Wild Track Format
824 CF_CFG_5, // 7.1 DS with optional HI/VI
827 struct AudioDescriptor
829 Rational EditRate; // rate of frame wrapping
830 Rational AudioSamplingRate; // rate of audio sample
832 ui32_t ChannelCount; // number of channels
833 ui32_t QuantizationBits; // number of bits per single-channel sample
834 ui32_t BlockAlign; // number of bytes ber sample, all channels
836 ui32_t LinkedTrackID; //
837 ui32_t ContainerDuration; // number of frames
838 ChannelFormat_t ChannelFormat; // audio channel arrangement
841 // Print AudioDescriptor to std::ostream
842 std::ostream& operator << (std::ostream& strm, const AudioDescriptor& adesc);
843 // Print debugging information to stream (stderr default)
844 void AudioDescriptorDump(const AudioDescriptor&, FILE* = 0);
846 // Returns size in bytes of a single sample of data described by ADesc
847 inline ui32_t CalcSampleSize(const AudioDescriptor& ADesc)
849 return (ADesc.QuantizationBits / 8) * ADesc.ChannelCount;
852 // Returns number of samples per frame of data described by ADesc
853 inline ui32_t CalcSamplesPerFrame(const AudioDescriptor& ADesc)
855 double tmpd = ADesc.AudioSamplingRate.Quotient() / ADesc.EditRate.Quotient();
856 return (ui32_t)ceil(tmpd);
859 // Returns the size in bytes of a frame of data described by ADesc
860 inline ui32_t CalcFrameBufferSize(const AudioDescriptor& ADesc)
862 return CalcSampleSize(ADesc) * CalcSamplesPerFrame(ADesc);
866 class FrameBuffer : public ASDCP::FrameBuffer
870 FrameBuffer(ui32_t size) { Capacity(size); }
871 virtual ~FrameBuffer() {}
873 // Print debugging information to stream (stderr default)
874 void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
877 // An object which opens and reads a WAV file. The call to OpenRead() reads metadata from
878 // the file and populates an internal AudioDescriptor object. Each subsequent call to
879 // ReadFrame() reads exactly one frame from the stream into the given FrameBuffer object.
880 // A "frame" is either 2000 or 2002 samples, depending upon the value of PictureRate.
884 mem_ptr<h__WAVParser> m_Parser;
885 ASDCP_NO_COPY_CONSTRUCT(WAVParser);
889 virtual ~WAVParser();
891 // Opens the stream for reading, parses enough data to provide a complete
892 // set of stream metadata for the MXFWriter below. PictureRate controls
893 // ther frame rate for the MXF frame wrapping option.
894 Result_t OpenRead(const char* filename, const Rational& PictureRate) const;
896 // Fill an AudioDescriptor struct with the values from the file's header.
897 // Returns RESULT_INIT if the file is not open.
898 Result_t FillAudioDescriptor(AudioDescriptor&) const;
900 // Rewind the stream to the beginning.
901 Result_t Reset() const;
903 // Reads the next sequential frame in the input file and places it in the
904 // frame buffer. Fails if the buffer is too small or the stream is empty.
905 Result_t ReadFrame(FrameBuffer&) const;
913 mem_ptr<h__Writer> m_Writer;
914 ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
918 virtual ~MXFWriter();
920 // Warning: direct manipulation of MXF structures can interfere
921 // with the normal operation of the wrapper. Caveat emptor!
922 virtual MXF::OPAtomHeader& OPAtomHeader();
923 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
925 // Open the file for writing. The file must not exist. Returns error if
926 // the operation cannot be completed or if nonsensical data is discovered
927 // in the essence descriptor.
928 Result_t OpenWrite(const char* filename, const WriterInfo&,
929 const AudioDescriptor&, ui32_t HeaderSize = 16384);
931 // Writes a frame of essence to the MXF file. If the optional AESEncContext
932 // argument is present, the essence is encrypted prior to writing.
933 // Fails if the file is not open, is finalized, or an operating system
935 Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
937 // Closes the MXF file, writing the index and revised header.
945 mem_ptr<h__Reader> m_Reader;
946 ASDCP_NO_COPY_CONSTRUCT(MXFReader);
950 virtual ~MXFReader();
952 // Warning: direct manipulation of MXF structures can interfere
953 // with the normal operation of the wrapper. Caveat emptor!
954 virtual MXF::OPAtomHeader& OPAtomHeader();
955 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
957 // Open the file for reading. The file must exist. Returns error if the
958 // operation cannot be completed.
959 Result_t OpenRead(const char* filename) const;
961 // Returns RESULT_INIT if the file is not open.
962 Result_t Close() const;
964 // Fill an AudioDescriptor struct with the values from the file's header.
965 // Returns RESULT_INIT if the file is not open.
966 Result_t FillAudioDescriptor(AudioDescriptor&) const;
968 // Fill a WriterInfo struct with the values from the file's header.
969 // Returns RESULT_INIT if the file is not open.
970 Result_t FillWriterInfo(WriterInfo&) const;
972 // Reads a frame of essence from the MXF file. If the optional AESEncContext
973 // argument is present, the essence is decrypted after reading. If the MXF
974 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
975 // will contain the ciphertext frame data. If the HMACContext argument is
976 // not NULL, the HMAC will be calculated (if the file supports it).
977 // Returns RESULT_INIT if the file is not open, failure if the frame number is
978 // out of range, or if optional decrypt or HAMC operations fail.
979 Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
981 // Print debugging information to stream
982 void DumpHeaderMetadata(FILE* = 0) const;
983 void DumpIndex(FILE* = 0) const;
987 //---------------------------------------------------------------------------------
991 const ui32_t MaxComponents = 3;
992 const ui32_t MaxPrecincts = 32; // ISO 15444-1 Annex A.6.1
993 const ui32_t MaxDefaults = 256; // made up
996 struct ImageComponent_t // ISO 15444-1 Annex A.5.1
1003 struct CodingStyleDefault_t // ISO 15444-1 Annex A.6.1
1009 ui8_t ProgressionOrder;
1010 ui8_t NumberOfLayers[sizeof(ui16_t)];
1011 ui8_t MultiCompTransform;
1016 ui8_t DecompositionLevels;
1017 ui8_t CodeblockWidth;
1018 ui8_t CodeblockHeight;
1019 ui8_t CodeblockStyle;
1020 ui8_t Transformation;
1021 ui8_t PrecinctSize[MaxPrecincts];
1025 struct QuantizationDefault_t // ISO 15444-1 Annex A.6.4
1028 ui8_t SPqcd[MaxDefaults];
1033 struct PictureDescriptor
1036 ui32_t ContainerDuration;
1037 Rational SampleRate;
1039 ui32_t StoredHeight;
1040 Rational AspectRatio;
1051 ImageComponent_t ImageComponents[MaxComponents];
1052 CodingStyleDefault_t CodingStyleDefault;
1053 QuantizationDefault_t QuantizationDefault;
1056 // Print debugging information to std::ostream
1057 std::ostream& operator << (std::ostream& strm, const PictureDescriptor& pdesc);
1058 // Print debugging information to stream (stderr default)
1059 void PictureDescriptorDump(const PictureDescriptor&, FILE* = 0);
1062 class FrameBuffer : public ASDCP::FrameBuffer
1066 FrameBuffer(ui32_t size) { Capacity(size); }
1067 virtual ~FrameBuffer() {}
1069 // Print debugging information to stream (stderr default)
1070 void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
1074 // An object which opens and reads a JPEG 2000 codestream file. The file is expected
1075 // to contain exactly one complete frame of picture essence as an unwrapped (raw)
1076 // ISO/IEC 15444 codestream.
1077 class CodestreamParser
1079 class h__CodestreamParser;
1080 mem_ptr<h__CodestreamParser> m_Parser;
1081 ASDCP_NO_COPY_CONSTRUCT(CodestreamParser);
1085 virtual ~CodestreamParser();
1087 // Opens a file for reading, parses enough data to provide a complete
1088 // set of stream metadata for the MXFWriter below.
1089 // The frame buffer's PlaintextOffset parameter will be set to the first
1090 // byte of the data segment. Set this value to zero if you want
1091 // encrypted headers.
1092 Result_t OpenReadFrame(const char* filename, FrameBuffer&) const;
1094 Result_t OpenReadFrame(const unsigned char * data, unsigned int size, FrameBuffer&) const;
1096 // Fill a PictureDescriptor struct with the values from the file's codestream.
1097 // Returns RESULT_INIT if the file is not open.
1098 Result_t FillPictureDescriptor(PictureDescriptor&) const;
1101 // Parses the data in the frame buffer to fill in the picture descriptor. Copies
1102 // the offset of the image data into start_of_data. Returns error if the parser fails.
1103 Result_t ParseMetadataIntoDesc(const FrameBuffer&, PictureDescriptor&, byte_t* start_of_data = 0);
1105 // An object which reads a sequence of files containing JPEG 2000 pictures.
1106 class SequenceParser
1108 class h__SequenceParser;
1109 mem_ptr<h__SequenceParser> m_Parser;
1110 ASDCP_NO_COPY_CONSTRUCT(SequenceParser);
1114 virtual ~SequenceParser();
1116 // Opens a directory for reading. The directory is expected to contain one or
1117 // more files, each containing the codestream for exactly one picture. The
1118 // files must be named such that the frames are in temporal order when sorted
1119 // alphabetically by filename. The parser will automatically parse enough data
1120 // from the first file to provide a complete set of stream metadata for the
1121 // MXFWriter below. If the "pedantic" parameter is given and is true, the
1122 // parser will check the metadata for each codestream and fail if a
1123 // mismatch is detected.
1124 Result_t OpenRead(const char* filename, bool pedantic = false) const;
1126 // Opens a file sequence for reading. The sequence is expected to contain one or
1127 // more filenames, each naming a file containing the codestream for exactly one
1128 // picture. The parser will automatically parse enough data
1129 // from the first file to provide a complete set of stream metadata for the
1130 // MXFWriter below. If the "pedantic" parameter is given and is true, the
1131 // parser will check the metadata for each codestream and fail if a
1132 // mismatch is detected.
1133 Result_t OpenRead(const std::list<std::string>& file_list, bool pedantic = false) const;
1135 // Fill a PictureDescriptor struct with the values from the first file's codestream.
1136 // Returns RESULT_INIT if the directory is not open.
1137 Result_t FillPictureDescriptor(PictureDescriptor&) const;
1139 // Rewind the directory to the beginning.
1140 Result_t Reset() const;
1142 // Reads the next sequential frame in the directory and places it in the
1143 // frame buffer. Fails if the buffer is too small or the direcdtory
1144 // contains no more files.
1145 // The frame buffer's PlaintextOffset parameter will be set to the first
1146 // byte of the data segment. Set this value to zero if you want
1147 // encrypted headers.
1148 Result_t ReadFrame(FrameBuffer&) const;
1156 mem_ptr<h__Writer> m_Writer;
1157 ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
1161 virtual ~MXFWriter();
1163 // Warning: direct manipulation of MXF structures can interfere
1164 // with the normal operation of the wrapper. Caveat emptor!
1165 virtual MXF::OPAtomHeader& OPAtomHeader();
1166 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1168 // Open the file for writing. The file must not exist unless overwrite is true. Returns error if
1169 // the operation cannot be completed or if nonsensical data is discovered
1170 // in the essence descriptor.
1171 Result_t OpenWrite(const char* filename, const WriterInfo&,
1172 const PictureDescriptor&, ui32_t HeaderSize, bool overwrite);
1174 // Writes a frame of essence to the MXF file. If the optional AESEncContext
1175 // argument is present, the essence is encrypted prior to writing.
1176 // A MD5 hash of the data that we write is written to hash if it is not 0
1177 // Fails if the file is not open, is finalized, or an operating system
1179 Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0, std::string* hash = 0);
1181 Result_t FakeWriteFrame(int size);
1183 // Closes the MXF file, writing the index and revised header.
1184 Result_t Finalize();
1186 // Return the current file offset in the MXF file that we are writing
1187 ui64_t Tell() const;
1194 mem_ptr<h__Reader> m_Reader;
1195 ASDCP_NO_COPY_CONSTRUCT(MXFReader);
1199 virtual ~MXFReader();
1201 // Warning: direct manipulation of MXF structures can interfere
1202 // with the normal operation of the wrapper. Caveat emptor!
1203 virtual MXF::OPAtomHeader& OPAtomHeader();
1204 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1206 // Open the file for reading. The file must exist. Returns error if the
1207 // operation cannot be completed.
1208 Result_t OpenRead(const char* filename) const;
1210 // Returns RESULT_INIT if the file is not open.
1211 Result_t Close() const;
1213 // Fill an AudioDescriptor struct with the values from the file's header.
1214 // Returns RESULT_INIT if the file is not open.
1215 Result_t FillPictureDescriptor(PictureDescriptor&) const;
1217 // Fill a WriterInfo struct with the values from the file's header.
1218 // Returns RESULT_INIT if the file is not open.
1219 Result_t FillWriterInfo(WriterInfo&) const;
1221 // Reads a frame of essence from the MXF file. If the optional AESEncContext
1222 // argument is present, the essence is decrypted after reading. If the MXF
1223 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1224 // will contain the ciphertext frame data. If the HMACContext argument is
1225 // not NULL, the HMAC will be calculated (if the file supports it).
1226 // Returns RESULT_INIT if the file is not open, failure if the frame number is
1227 // out of range, or if optional decrypt or HAMC operations fail.
1228 Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1230 // Print debugging information to stream
1231 void DumpHeaderMetadata(FILE* = 0) const;
1232 void DumpIndex(FILE* = 0) const;
1236 // Stereoscopic Image support
1239 enum StereoscopicPhase_t
1247 JP2K::FrameBuffer Left;
1248 JP2K::FrameBuffer Right;
1250 SFrameBuffer(ui32_t size) {
1251 Left.Capacity(size);
1252 Right.Capacity(size);
1259 mem_ptr<h__SWriter> m_Writer;
1260 ASDCP_NO_COPY_CONSTRUCT(MXFSWriter);
1264 virtual ~MXFSWriter();
1266 // Warning: direct manipulation of MXF structures can interfere
1267 // with the normal operation of the wrapper. Caveat emptor!
1268 virtual MXF::OPAtomHeader& OPAtomHeader();
1269 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1271 // Open the file for writing. The file must not exist. Returns error if
1272 // the operation cannot be completed or if nonsensical data is discovered
1273 // in the essence descriptor.
1274 Result_t OpenWrite(const char* filename, const WriterInfo&,
1275 const PictureDescriptor&, ui32_t HeaderSize = 16384);
1277 // Writes a pair of frames of essence to the MXF file. If the optional AESEncContext
1278 // argument is present, the essence is encrypted prior to writing.
1279 // Fails if the file is not open, is finalized, or an operating system
1281 Result_t WriteFrame(const SFrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
1283 // Writes a frame of essence to the MXF file. If the optional AESEncContext
1284 // argument is present, the essence is encrypted prior to writing.
1285 // Fails if the file is not open, is finalized, or an operating system
1286 // error occurs. Frames must be written in the proper phase (L-R-L-R),
1287 // RESULT_SPHASE will be returned if phase is reversed. The first frame
1288 // written must be left eye.
1289 Result_t WriteFrame(const FrameBuffer&, StereoscopicPhase_t phase,
1290 AESEncContext* = 0, HMACContext* = 0);
1292 // Closes the MXF file, writing the index and revised header. Returns
1293 // RESULT_SPHASE if WriteFrame was called an odd number of times.
1294 Result_t Finalize();
1301 mem_ptr<h__SReader> m_Reader;
1302 ASDCP_NO_COPY_CONSTRUCT(MXFSReader);
1306 virtual ~MXFSReader();
1308 // Warning: direct manipulation of MXF structures can interfere
1309 // with the normal operation of the wrapper. Caveat emptor!
1310 virtual MXF::OPAtomHeader& OPAtomHeader();
1311 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1313 // Open the file for reading. The file must exist. Returns error if the
1314 // operation cannot be completed.
1315 Result_t OpenRead(const char* filename) const;
1317 // Returns RESULT_INIT if the file is not open.
1318 Result_t Close() const;
1320 // Fill an AudioDescriptor struct with the values from the file's header.
1321 // Returns RESULT_INIT if the file is not open.
1322 Result_t FillPictureDescriptor(PictureDescriptor&) const;
1324 // Fill a WriterInfo struct with the values from the file's header.
1325 // Returns RESULT_INIT if the file is not open.
1326 Result_t FillWriterInfo(WriterInfo&) const;
1328 // Reads a pair of frames of essence from the MXF file. If the optional AESEncContext
1329 // argument is present, the essence is decrypted after reading. If the MXF
1330 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1331 // will contain the ciphertext frame data. If the HMACContext argument is
1332 // not NULL, the HMAC will be calculated (if the file supports it).
1333 // Returns RESULT_INIT if the file is not open, failure if the frame number is
1334 // out of range, or if optional decrypt or HAMC operations fail.
1335 Result_t ReadFrame(ui32_t frame_number, SFrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1337 // Reads a frame of essence from the MXF file. If the optional AESEncContext
1338 // argument is present, the essence is decrypted after reading. If the MXF
1339 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1340 // will contain the ciphertext frame data. If the HMACContext argument is
1341 // not NULL, the HMAC will be calculated (if the file supports it).
1342 // Returns RESULT_INIT if the file is not open, failure if the frame number is
1343 // out of range, or if optional decrypt or HAMC operations fail.
1344 Result_t ReadFrame(ui32_t frame_number, StereoscopicPhase_t phase,
1345 FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1347 // Print debugging information to stream
1348 void DumpHeaderMetadata(FILE* = 0) const;
1349 void DumpIndex(FILE* = 0) const;
1353 //---------------------------------------------------------------------------------
1357 enum MIMEType_t { MT_BIN, MT_PNG, MT_OPENTYPE };
1359 struct TimedTextResourceDescriptor
1361 byte_t ResourceID[UUIDlen];
1364 TimedTextResourceDescriptor() : Type(MT_BIN) {}
1367 typedef std::list<TimedTextResourceDescriptor> ResourceList_t;
1369 struct TimedTextDescriptor
1371 Rational EditRate; //
1372 ui32_t ContainerDuration;
1373 byte_t AssetID[UUIDlen];
1374 std::string NamespaceName;
1375 std::string EncodingName;
1376 ResourceList_t ResourceList;
1378 TimedTextDescriptor() : ContainerDuration(0), EncodingName("UTF-8") {} // D-Cinema format is always UTF-8
1381 // Print debugging information to std::ostream
1382 std::ostream& operator << (std::ostream& strm, const TimedTextDescriptor& tinfo);
1383 // Print debugging information to stream (stderr default)
1384 void DescriptorDump(const TimedTextDescriptor&, FILE* = 0);
1387 class FrameBuffer : public ASDCP::FrameBuffer
1389 ASDCP_NO_COPY_CONSTRUCT(FrameBuffer); // TODO: should have copy construct
1392 byte_t m_AssetID[UUIDlen];
1393 std::string m_MIMEType;
1396 FrameBuffer() { memset(m_AssetID, 0, UUIDlen); }
1397 FrameBuffer(ui32_t size) { Capacity(size); memset(m_AssetID, 0, UUIDlen); }
1398 virtual ~FrameBuffer() {}
1400 inline const byte_t* AssetID() const { return m_AssetID; }
1401 inline void AssetID(const byte_t* buf) { memcpy(m_AssetID, buf, UUIDlen); }
1402 inline const char* MIMEType() const { return m_MIMEType.c_str(); }
1403 inline void MIMEType(const std::string& s) { m_MIMEType = s; }
1405 // Print debugging information to stream (stderr default)
1406 void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
1410 class IResourceResolver
1413 virtual ~IResourceResolver() {}
1414 virtual Result_t ResolveRID(const byte_t* uuid, FrameBuffer&) const = 0; // return data for RID
1418 class DCSubtitleParser
1420 class h__SubtitleParser;
1421 mem_ptr<h__SubtitleParser> m_Parser;
1422 ASDCP_NO_COPY_CONSTRUCT(DCSubtitleParser);
1426 virtual ~DCSubtitleParser();
1428 // Opens an XML file for reading, parses data to provide a complete
1429 // set of stream metadata for the MXFWriter below.
1430 Result_t OpenRead(const char* filename) const;
1432 // Parses an XML document to provide a complete set of stream metadata
1433 // for the MXFWriter below. The optional filename argument is used to
1434 // initialize the default resource resolver (see ReadAncillaryResource).
1435 Result_t OpenRead(const std::string& xml_doc, const char* filename = 0) const;
1437 // Fill a TimedTextDescriptor struct with the values from the file's contents.
1438 // Returns RESULT_INIT if the file is not open.
1439 Result_t FillTimedTextDescriptor(TimedTextDescriptor&) const;
1441 // Reads the complete Timed Text Resource into the given string.
1442 Result_t ReadTimedTextResource(std::string&) const;
1444 // Reads the Ancillary Resource having the given ID. Fails if the buffer
1445 // is too small or the resource does not exist. The optional Resolver
1446 // argument can be provided which will be used to retrieve the resource
1447 // having a particulat UUID. If a Resolver is not supplied, the default
1448 // internal resolver will return the contents of the file having the UUID
1449 // as the filename. The filename must exist in the same directory as the
1450 // XML file opened with OpenRead().
1451 Result_t ReadAncillaryResource(const byte_t* uuid, FrameBuffer&,
1452 const IResourceResolver* Resolver = 0) const;
1459 mem_ptr<h__Writer> m_Writer;
1460 ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
1464 virtual ~MXFWriter();
1466 // Warning: direct manipulation of MXF structures can interfere
1467 // with the normal operation of the wrapper. Caveat emptor!
1468 virtual MXF::OPAtomHeader& OPAtomHeader();
1469 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1471 // Open the file for writing. The file must not exist. Returns error if
1472 // the operation cannot be completed or if nonsensical data is discovered
1473 // in the essence descriptor.
1474 Result_t OpenWrite(const char* filename, const WriterInfo&,
1475 const TimedTextDescriptor&, ui32_t HeaderSize = 16384);
1477 // Writes the Timed-Text Resource to the MXF file. The file must be UTF-8
1478 // encoded. If the optional AESEncContext argument is present, the essence
1479 // is encrypted prior to writing. Fails if the file is not open, is finalized,
1480 // or an operating system error occurs.
1481 // This method may only be called once, and it must be called before any
1482 // call to WriteAncillaryResource(). RESULT_STATE will be returned if these
1483 // conditions are not met.
1484 Result_t WriteTimedTextResource(const std::string& XMLDoc, AESEncContext* = 0, HMACContext* = 0);
1486 // Writes an Ancillary Resource to the MXF file. If the optional AESEncContext
1487 // argument is present, the essence is encrypted prior to writing.
1488 // Fails if the file is not open, is finalized, or an operating system
1489 // error occurs. RESULT_STATE will be returned if the method is called before
1490 // WriteTimedTextResource()
1491 Result_t WriteAncillaryResource(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
1493 // Closes the MXF file, writing the index and revised header.
1494 Result_t Finalize();
1501 mem_ptr<h__Reader> m_Reader;
1502 ASDCP_NO_COPY_CONSTRUCT(MXFReader);
1506 virtual ~MXFReader();
1508 // Warning: direct manipulation of MXF structures can interfere
1509 // with the normal operation of the wrapper. Caveat emptor!
1510 virtual MXF::OPAtomHeader& OPAtomHeader();
1511 virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1513 // Open the file for reading. The file must exist. Returns error if the
1514 // operation cannot be completed.
1515 Result_t OpenRead(const char* filename) const;
1517 // Returns RESULT_INIT if the file is not open.
1518 Result_t Close() const;
1520 // Fill a TimedTextDescriptor struct with the values from the file's header.
1521 // Returns RESULT_INIT if the file is not open.
1522 Result_t FillTimedTextDescriptor(TimedTextDescriptor&) const;
1524 // Fill a WriterInfo struct with the values from the file's header.
1525 // Returns RESULT_INIT if the file is not open.
1526 Result_t FillWriterInfo(WriterInfo&) const;
1528 // Reads the complete Timed Text Resource into the given string. Fails if the resource
1529 // is encrypted and AESDecContext is NULL (use the following method to retrieve the
1530 // raw ciphertet block).
1531 Result_t ReadTimedTextResource(std::string&, AESDecContext* = 0, HMACContext* = 0) const;
1533 // Reads the complete Timed Text Resource from the MXF file. If the optional AESEncContext
1534 // argument is present, the resource is decrypted after reading. If the MXF
1535 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1536 // will contain the ciphertext frame data. If the HMACContext argument is
1537 // not NULL, the HMAC will be calculated (if the file supports it).
1538 // Returns RESULT_INIT if the file is not open, failure if the frame number is
1539 // out of range, or if optional decrypt or HAMC operations fail.
1540 Result_t ReadTimedTextResource(FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1542 // Reads the timed-text resource having the given UUID from the MXF file. If the
1543 // optional AESEncContext argument is present, the resource is decrypted after
1544 // reading. If the MXF file is encrypted and the AESDecContext argument is NULL,
1545 // the frame buffer will contain the ciphertext frame data. If the HMACContext
1546 // argument is not NULL, the HMAC will be calculated (if the file supports it).
1547 // Returns RESULT_INIT if the file is not open, failure if the frame number is
1548 // out of range, or if optional decrypt or HAMC operations fail.
1549 Result_t ReadAncillaryResource(const byte_t* uuid, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1551 // Print debugging information to stream
1552 void DumpHeaderMetadata(FILE* = 0) const;
1553 void DumpIndex(FILE* = 0) const;
1555 } // namespace TimedText
1558 } // namespace ASDCP
1561 #endif // _AS_DCP_H_