2 Copyright (c) 2003-2006, 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 wrapper objects that offer simplified
32 access to files conforming to the file formats proposed by the SMPTE
33 D-Cinema packaging working group DC28.20. The file format, labeled
34 AS-DCP, is described in series of separate documents which include but
35 may not be limited to:
37 o AS-DCP Track File Specification
38 o AS-DCP Track File Essence Encryption Specification
39 o AS-DCP Operational Constraints Specification
43 o SMPTE 390M - OP-Atom
44 o SMPTE 379M - Generic Container
45 o SMPTE 381M - MPEG2 picture
46 o SMPTE XXXM - JPEG 2000 picture
47 o SMPTE 382M - WAV/PCM sound
48 o IETF RFC 2104 - HMAC/SHA1
49 o NIST FIPS 197 - AES (Rijndael)
51 The following use cases are supported by the library:
53 o Write a plaintext MPEG2 Video Elementary Stream to a plaintext ASDCP file
54 o Write a plaintext MPEG2 Video Elementary Stream to a ciphertext ASDCP file
55 o Read a plaintext MPEG2 Video Elementary Stream from a plaintext ASDCP file
56 o Read a plaintext MPEG2 Video Elementary Stream from a ciphertext ASDCP file
57 o Read a ciphertext MPEG2 Video Elementary Stream from a ciphertext ASDCP file
58 o Write one or more plaintext JPEG 2000 codestreams to a plaintext ASDCP file
59 o Write one or more plaintext JPEG 2000 codestreams to a ciphertext ASDCP file
60 o Read one or more plaintext JPEG 2000 codestreams from a plaintext ASDCP file
61 o Read one or more plaintext JPEG 2000 codestreams from a ciphertext ASDCP file
62 o Read one or more ciphertext JPEG 2000 codestreams from a ciphertext ASDCP file
63 o Write one or more plaintext PCM audio streams to a plaintext ASDCP file
64 o Write one or more plaintext PCM audio streams to a ciphertext ASDCP file
65 o Read one or more plaintext PCM audio streams from a plaintext ASDCP file
66 o Read one or more plaintext PCM audio streams from a ciphertext ASDCP file
67 o Read one or more ciphertext PCM audio streams from a ciphertext ASDCP file
68 o Read header metadata from an ASDCP file
70 This project depends upon the following library:
71 - OpenSSL http://www.openssl.org/
84 //--------------------------------------------------------------------------------
85 // common integer types
86 // supply your own by defining ASDCP_NO_BASE_TYPES
88 #ifndef ASDCP_NO_BASE_TYPES
89 typedef unsigned char byte_t;
91 typedef unsigned char ui8_t;
93 typedef unsigned short ui16_t;
95 typedef unsigned int ui32_t;
99 //--------------------------------------------------------------------------------
100 // convenience macros
102 // Convenience macros for managing return values in predicates
103 #define ASDCP_SUCCESS(v) (((v) < 0) ? 0 : 1)
104 #define ASDCP_FAILURE(v) (((v) < 0) ? 1 : 0)
107 // Returns RESULT_PTR if the given argument is NULL.
108 // See Result_t below for an explanation of RESULT_* symbols.
109 #define ASDCP_TEST_NULL(p) \
111 return ASDCP::RESULT_PTR; \
114 // Returns RESULT_PTR if the given argument is NULL. See Result_t
115 // below for an explanation of RESULT_* symbols. It then assumes
116 // that the argument is a pointer to a string and returns
117 // RESULT_NULL_STR if the first character is '\0'.
119 #define ASDCP_TEST_NULL_STR(p) \
120 ASDCP_TEST_NULL(p); \
121 if ( (p)[0] == '\0' ) { \
122 return ASDCP::RESULT_NULL_STR; \
125 // Produces copy constructor boilerplate. Allows convenient private
126 // declatarion of copy constructors to prevent the compiler from
127 // silently manufacturing default methods.
128 #define ASDCP_NO_COPY_CONSTRUCT(T) \
130 T& operator=(const T&)
132 //--------------------------------------------------------------------------------
133 // All library components are defined in the namespace ASDCP
136 // The version number consists of three segments: major, API minor, and
137 // implementation minor. Whenever a change is made to AS_DCP.h, the API minor
138 // version will increment. Changes made to the internal implementation will
139 // result in the incrementing of the implementation minor version.
141 // For example, if asdcplib version 1.0.0 were modified to accomodate changes
142 // in file format, and if no changes were made to AS_DCP.h, the new version would be
143 // 1.0.1. If changes were also required in AS_DCP.h, the new version would be 1.1.1.
144 const ui32_t VERSION_MAJOR = 1;
145 const ui32_t VERSION_APIMINOR = 1;
146 const ui32_t VERSION_IMPMINOR = 8;
147 const char* Version();
149 // UUIDs are passed around as strings of UUIDlen bytes
150 const ui32_t UUIDlen = 16;
152 // Encryption keys are passed around as strings of KeyLen bytes
153 const ui32_t KeyLen = 16;
155 //---------------------------------------------------------------------------------
158 using Kumu::Result_t;
160 using Kumu::RESULT_FALSE;
161 using Kumu::RESULT_OK;
162 using Kumu::RESULT_FAIL;
163 using Kumu::RESULT_PTR;
164 using Kumu::RESULT_NULL_STR;
165 using Kumu::RESULT_ALLOC;
166 using Kumu::RESULT_PARAM;
167 using Kumu::RESULT_SMALLBUF;
168 using Kumu::RESULT_INIT;
169 using Kumu::RESULT_NOT_FOUND;
170 using Kumu::RESULT_NO_PERM;
171 using Kumu::RESULT_FILEOPEN;
172 using Kumu::RESULT_BADSEEK;
173 using Kumu::RESULT_READFAIL;
174 using Kumu::RESULT_WRITEFAIL;
175 using Kumu::RESULT_STATE;
176 using Kumu::RESULT_ENDOFFILE;
177 using Kumu::RESULT_CONFIG;
179 const Kumu::Result_t RESULT_FORMAT (-101, "The file format is not proper OP-Atom/AS-DCP.");
180 const Kumu::Result_t RESULT_RAW_ESS (-102, "Unknown raw essence file type.");
181 const Kumu::Result_t RESULT_RAW_FORMAT (-103, "Raw essence format invalid.");
182 const Kumu::Result_t RESULT_RANGE (-104, "Frame number out of range.");
183 const Kumu::Result_t RESULT_CRYPT_CTX (-105, "AESEncContext required when writing to encrypted file.");
184 const Kumu::Result_t RESULT_LARGE_PTO (-106, "Plaintext offset exceeds frame buffer size.");
185 const Kumu::Result_t RESULT_CAPEXTMEM (-107, "Cannot resize externally allocated memory.");
186 const Kumu::Result_t RESULT_CHECKFAIL (-108, "The check value did not decrypt correctly.");
187 const Kumu::Result_t RESULT_HMACFAIL (-109, "HMAC authentication failure.");
188 const Kumu::Result_t RESULT_HMAC_CTX (-110, "HMAC context required.");
189 const Kumu::Result_t RESULT_CRYPT_INIT (-111, "Error initializing block cipher context.");
190 const Kumu::Result_t RESULT_EMPTY_FB (-112, "Empty frame buffer.");
191 const Kumu::Result_t RESULT_KLV_CODING (-113, "KLV coding error.");
193 //---------------------------------------------------------------------------------
194 // file identification
196 // The file accessors in this library implement a bounded set of essence types.
197 // This list will be expanded when support for new types is added to the library.
199 ESS_UNKNOWN, // the file is not a supported AS-DCP essence container
200 ESS_MPEG2_VES, // the file contains an MPEG video elementary stream
201 ESS_JPEG_2000, // the file contains one or more JPEG 2000 codestreams
202 ESS_PCM_24b_48k, // the file contains one or more PCM audio pairs
203 ESS_PCM_24b_96k, // the file contains one or more PCM audio pairs
204 ESS_UTF8_XML, // the file contains UTF-8 encoded XML data
205 ESS_PNG // the file contains a Portable Network Graphics image
208 // Determine the type of essence contained in the given MXF file. RESULT_OK
209 // is returned if the file is successfully opened and contains a valid MXF
210 // stream. If there is an error, the result code will indicate the reason.
211 Result_t EssenceType(const char* filename, EssenceType_t& type);
213 // Determine the type of essence contained in the given raw file. RESULT_OK
214 // is returned if the file is successfully opened and contains a known
215 // stream type. If there is an error, the result code will indicate the reason.
216 Result_t RawEssenceType(const char* filename, EssenceType_t& type);
219 //---------------------------------------------------------------------------------
222 // A simple container for rational numbers.
229 Rational() : Numerator(0), Denominator(0) {}
230 Rational(i32_t n, i32_t d) : Numerator(n), Denominator(d) {}
232 inline double Quotient() const {
233 return (double)Numerator / (double)Denominator;
236 inline bool operator==(const Rational& rhs) const {
237 return ( rhs.Numerator == Numerator && rhs.Denominator == Denominator );
240 inline bool operator!=(const Rational& rhs) const {
241 return ( rhs.Numerator != Numerator || rhs.Denominator != Denominator );
245 // common edit rates, use these instead of hard coded constants
246 const Rational EditRate_24(24,1);
247 const Rational EditRate_23_98(24000,1001);
248 const Rational EditRate_48(48,1);
249 const Rational SampleRate_48k(48000,1);
251 // Non-reference counting container for internal member objects.
252 // Please do not use this class for any other purpose.
256 T* m_p; // the thing we point to
260 mem_ptr() : m_p(0) {}
261 mem_ptr(T* p) : m_p(p) {}
262 ~mem_ptr() { delete m_p; }
264 inline T& operator*() const { return *m_p; }
265 inline T* operator->() const { return m_p; }
266 inline operator T*()const { return m_p; }
267 inline const mem_ptr<T>& operator=(T* p) { set(p); return *this; }
268 inline T* set(T* p) { delete m_p; m_p = p; return m_p; }
269 inline T* get() const { return m_p; }
270 inline void release() { m_p = 0; }
271 inline bool empty() const { return m_p == 0; }
275 //---------------------------------------------------------------------------------
276 // WriterInfo class - encapsulates writer identification details used for
277 // OpenWrite() calls. Replace these values at runtime to identify your product.
279 // MXF files use SMPTE Universal Labels to identify data items. The set of Labels
280 // in a file is determined by the MXF Operational Pattern and any constraining
281 // documentation. There are currently two flavors of AS-DCP file in use: MXF Interop
282 // and SMPTE. The two differ only in the values of two labels:
284 // OP Atom / Interop : 06 0e 2b 34 04 01 01 01 0d 01 02 01 10 00 00 00
285 // OP Atom / SMPTE : 06 0e 2b 34 04 01 01 02 0d 01 02 01 10 00 00 00
287 // EKLV Packet / Interop : 06 0e 2b 34 02 04 01 07 0d 01 03 01 02 7e 01 00
288 // EKLV Packet / SMPTE : 06 0e 2b 34 02 04 01 01 0d 01 03 01 02 7e 01 00
290 // asdcplib will read any (otherwise valid) file which has any combination of the
291 // above values. When writing files, MXF Interop labels are used by default. To
292 // write a file containing SMPTE labels, replace the default label set value in
293 // the WriterInfo before calling OpenWrite()
305 byte_t ProductUUID[UUIDlen];
306 byte_t AssetUUID[UUIDlen];
307 byte_t ContextID[UUIDlen];
308 byte_t CryptographicKeyID[UUIDlen];
309 bool EncryptedEssence; // true if essence data is (or is going to be) encrypted
310 bool UsesHMAC; // true if HMAC exists or is to be calculated
311 std::string ProductVersion;
312 std::string CompanyName;
313 std::string ProductName;
314 LabelSet_t LabelSetType;
316 WriterInfo() : EncryptedEssence(false), UsesHMAC(false), LabelSetType(LS_MXF_INTEROP)
318 static byte_t default_ProductUUID_Data[UUIDlen] = {
319 0x43, 0x05, 0x9a, 0x1d, 0x04, 0x32, 0x41, 0x01,
320 0xb8, 0x3f, 0x73, 0x68, 0x15, 0xac, 0xf3, 0x1d };
322 memcpy(ProductUUID, default_ProductUUID_Data, UUIDlen);
323 memset(AssetUUID, 0, UUIDlen);
324 memset(ContextID, 0, UUIDlen);
325 memset(CryptographicKeyID, 0, UUIDlen);
327 ProductVersion = "Unreleased ";
328 ProductVersion += Version();
330 ProductName = "asdcplib";
334 // Print WriterInfo to stream, stderr by default.
335 void WriterInfoDump(const WriterInfo&, FILE* = 0);
337 //---------------------------------------------------------------------------------
338 // cryptographic support
340 // The following classes define interfaces to Rijndael contexts having the following properties:
342 // o CBC mode with 16 byte block size
343 const ui32_t CBC_KEY_SIZE = 16;
344 const ui32_t CBC_BLOCK_SIZE = 16;
345 const ui32_t HMAC_SIZE = 20;
351 mem_ptr<h__AESContext> m_Context;
352 ASDCP_NO_COPY_CONSTRUCT(AESEncContext);
358 // Initializes Rijndael CBC encryption context.
359 // Returns error if the key argument is NULL.
360 Result_t InitKey(const byte_t* key);
362 // Initializes 16 byte CBC Initialization Vector. This operation may be performed
363 // any number of times for a given key.
364 // Returns error if the i_vec argument is NULL.
365 Result_t SetIVec(const byte_t* i_vec);
366 Result_t GetIVec(byte_t* i_vec) const;
368 // Encrypt a block of data. The block size must be a multiple of CBC_BLOCK_SIZE.
369 // Returns error if either argument is NULL.
370 Result_t EncryptBlock(const byte_t* pt_buf, byte_t* ct_buf, ui32_t block_size);
377 mem_ptr<h__AESContext> m_Context;
378 ASDCP_NO_COPY_CONSTRUCT(AESDecContext);
384 // Initializes Rijndael CBC decryption context.
385 // Returns error if the key argument is NULL.
386 Result_t InitKey(const byte_t* key);
388 // Initializes 16 byte CBC Initialization Vector. This operation may be performed
389 // any number of times for a given key.
390 // Returns error if the i_vec argument is NULL.
391 Result_t SetIVec(const byte_t* i_vec);
393 // Decrypt a block of data. The block size must be a multiple of CBC_BLOCK_SIZE.
394 // Returns error if either argument is NULL.
395 Result_t DecryptBlock(const byte_t* ct_buf, byte_t* pt_buf, ui32_t block_size);
401 class h__HMACContext;
402 mem_ptr<h__HMACContext> m_Context;
403 ASDCP_NO_COPY_CONSTRUCT(HMACContext);
409 // Initializes HMAC context. The key argument must point to a binary
410 // key that is CBC_KEY_SIZE bytes in length. Returns error if the key
412 Result_t InitKey(const byte_t* key, LabelSet_t = LS_MXF_INTEROP);
414 // Reset internal state, allows repeated cycles of Update -> Finalize
417 // Add data to the digest. Returns error if the key argument is NULL or
418 // if the digest has been finalized.
419 Result_t Update(const byte_t* buf, ui32_t buf_len);
421 // Finalize digest. Returns error if the digest has already been finalized.
424 // Writes HMAC value to given buffer. buf must point to a writable area of
425 // memory that is at least HMAC_SIZE bytes in length. Returns error if the
426 // buf argument is NULL or if the digest has not been finalized.
427 Result_t GetHMACValue(byte_t* buf) const;
429 // Tests the given value against the finalized value in the object. buf must
430 // point to a readable area of memory that is at least HMAC_SIZE bytes in length.
431 // Returns error if the buf argument is NULL or if the values do ot match.
432 Result_t TestHMACValue(const byte_t* buf) const;
435 //---------------------------------------------------------------------------------
436 // frame buffer base class
438 // The supported essence types are stored using per-frame KLV packetization. The
439 // following class implements essence-neutral functionality for managing a buffer
440 // containing a frame of essence.
444 ASDCP_NO_COPY_CONSTRUCT(FrameBuffer);
447 byte_t* m_Data; // pointer to memory area containing frame data
448 ui32_t m_Capacity; // size of memory area pointed to by m_Data
449 bool m_OwnMem; // if false, m_Data points to externally allocated memory
450 ui32_t m_Size; // size of frame data in memory area pointed to by m_Data
451 ui32_t m_FrameNumber; // delivery-order frame number
453 // It is possible to read raw ciphertext from an encrypted AS-DCP file.
454 // After reading an encrypted AS-DCP file in raw mode, the frame buffer will
455 // contain the encrypted source value portion of the Encrypted Triplet, followed
456 // by the integrity pack, if it exists.
457 // The buffer will begin with the IV and CheckValue, followed by encrypted essence
458 // and optional integrity pack
459 // The SourceLength and PlaintextOffset values from the packet will be held in the
460 // following variables:
461 ui32_t m_SourceLength; // plaintext length (delivered plaintext+decrypted ciphertext)
462 ui32_t m_PlaintextOffset; // offset to first byte of ciphertext
466 virtual ~FrameBuffer();
468 // Instructs the object to use an externally allocated buffer. The external
469 // buffer will not be cleaned up by the frame buffer when it exits.
470 // Call with (0,0) to revert to internally allocated buffer.
471 // Returns error if the buf_addr argument is NULL and buf_size is non-zero.
472 Result_t SetData(byte_t* buf_addr, ui32_t buf_size);
474 // Sets the size of the internally allocate buffer. Returns RESULT_CAPEXTMEM
475 // if the object is using an externally allocated buffer via SetData();
476 // Resets content size to zero.
477 Result_t Capacity(ui32_t cap);
479 // returns the size of the buffer
480 inline ui32_t Capacity() const { return m_Capacity; }
482 // returns a const pointer to the essence data
483 inline const byte_t* RoData() const { return m_Data; }
485 // returns a non-const pointer to the essence data
486 inline byte_t* Data() { return m_Data; }
488 // set the size of the buffer's contents
489 inline ui32_t Size(ui32_t size) { return m_Size = size; }
491 // returns the size of the buffer's contents
492 inline ui32_t Size() const { return m_Size; }
494 // Sets the absolute frame number of this frame in the file in delivery order.
495 inline void FrameNumber(ui32_t num) { m_FrameNumber = num; }
497 // Returns the absolute frame number of this frame in the file in delivery order.
498 inline ui32_t FrameNumber() const { return m_FrameNumber; }
500 // Sets the length of the plaintext essence data
501 inline void SourceLength(ui32_t len) { m_SourceLength = len; }
503 // When this value is 0 (zero), the buffer contains only plaintext. When it is
504 // non-zero, the buffer contains raw ciphertext and the return value is the length
505 // of the original plaintext.
506 inline ui32_t SourceLength() const { return m_SourceLength; }
508 // Sets the offset into the buffer at which encrypted data begins
509 inline void PlaintextOffset(ui32_t ofst) { m_PlaintextOffset = ofst; }
511 // Returns offset into buffer of first byte of ciphertext.
512 inline ui32_t PlaintextOffset() const { return m_PlaintextOffset; }
516 //---------------------------------------------------------------------------------
517 // MPEG2 video elementary stream support
522 // MPEG picture coding type
524 FRAME_U = 0x00, // Unknown
525 FRAME_I = 0x01, // I-Frame
526 FRAME_P = 0x02, // P-Frame
527 FRAME_B = 0x03 // B-Frame
530 // convert FrameType_t to char
531 inline char FrameTypeChar(FrameType_t type)
535 case FRAME_I: return 'I';
536 case FRAME_B: return 'B';
537 case FRAME_P: return 'P';
542 // Structure represents the metadata elements in the file header's
543 // MPEG2VideoDescriptor object.
544 struct VideoDescriptor
546 Rational EditRate; //
548 Rational SampleRate; //
549 ui8_t FrameLayout; //
550 ui32_t StoredWidth; //
551 ui32_t StoredHeight; //
552 Rational AspectRatio; //
553 ui32_t ComponentDepth; //
554 ui32_t HorizontalSubsampling; //
555 ui32_t VerticalSubsampling; //
556 ui8_t ColorSiting; //
557 ui8_t CodedContentType; //
560 ui8_t ProfileAndLevel; //
561 ui32_t ContainerDuration; //
564 // Print VideoDescriptor to stream, stderr by default.
565 void VideoDescriptorDump(const VideoDescriptor&, FILE* = 0);
567 // A container for MPEG frame data.
568 class FrameBuffer : public ASDCP::FrameBuffer
570 ASDCP_NO_COPY_CONSTRUCT(FrameBuffer); // TODO: should have copy construct
573 FrameType_t m_FrameType;
574 ui8_t m_TemporalOffset;
580 m_FrameType(FRAME_U), m_TemporalOffset(0),
581 m_ClosedGOP(false), m_GOPStart(false) {}
583 FrameBuffer(ui32_t size) :
584 m_FrameType(FRAME_U), m_TemporalOffset(0),
585 m_ClosedGOP(false), m_GOPStart(false)
590 virtual ~FrameBuffer() {}
592 // Sets the MPEG frame type of the picture data in the frame buffer.
593 inline void FrameType(FrameType_t type) { m_FrameType = type; }
595 // Returns the MPEG frame type of the picture data in the frame buffer.
596 inline FrameType_t FrameType() const { return m_FrameType; }
598 // Sets the MPEG temporal offset of the picture data in the frame buffer.
599 inline void TemporalOffset(ui8_t offset) { m_TemporalOffset = offset; }
601 // Returns the MPEG temporal offset of the picture data in the frame buffer.
602 inline ui8_t TemporalOffset() const { return m_TemporalOffset; }
604 // Sets the MPEG GOP 'start' attribute for the frame buffer.
605 inline void GOPStart(bool start) { m_GOPStart = start; }
607 // True if the frame in the buffer is the first in the GOP (in transport order)
608 inline bool GOPStart() const { return m_GOPStart; }
610 // Sets the MPEG GOP 'closed' attribute for the frame buffer.
611 inline void ClosedGOP(bool closed) { m_ClosedGOP = closed; }
613 // Returns true if the frame in the buffer is from a closed GOP, false if
614 // the frame is from an open GOP. Always returns false unless GOPStart()
616 inline bool ClosedGOP() const { return m_ClosedGOP; }
618 // Print object state to stream, include n bytes of frame data if indicated.
619 // Default stream is stderr.
620 void Dump(FILE* = 0, ui32_t dump_len = 0) const;
624 // An object which opens and reads an MPEG2 Video Elementary Stream file. The call to
625 // OpenRead() reads metadata from the file and populates an internal VideoDescriptor object.
626 // Each subsequent call to ReadFrame() reads exactly one frame from the stream into the
627 // given FrameBuffer object.
631 mem_ptr<h__Parser> m_Parser;
632 ASDCP_NO_COPY_CONSTRUCT(Parser);
638 // Opens the stream for reading, parses enough data to provide a complete
639 // set of stream metadata for the MXFWriter below.
640 Result_t OpenRead(const char* filename) const;
642 // Fill a VideoDescriptor struct with the values from the file's header.
643 // Returns RESULT_INIT if the file is not open.
644 Result_t FillVideoDescriptor(VideoDescriptor&) const;
646 // Rewind the stream to the beginning.
647 Result_t Reset() const;
649 // Reads the next sequential frame in the input file and places it in the
650 // frame buffer. Fails if the buffer is too small or the stream is empty.
651 // The frame buffer's PlaintextOffset parameter will be set to the first
652 // data byte of the first slice. Set this value to zero if you want
653 // encrypted headers.
654 Result_t ReadFrame(FrameBuffer&) const;
657 // A class which creates and writes MPEG frame data to an AS-DCP format MXF file.
658 // Not yet implemented
662 mem_ptr<h__Writer> m_Writer;
663 ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
667 virtual ~MXFWriter();
669 // Open the file for writing. The file must not exist. Returns error if
670 // the operation cannot be completed or if nonsensical data is discovered
671 // in the essence descriptor.
672 Result_t OpenWrite(const char* filename, const WriterInfo&,
673 const VideoDescriptor&, ui32_t HeaderSize = 16384);
675 // Writes a frame of essence to the MXF file. If the optional AESEncContext
676 // argument is present, the essence is encrypted prior to writing.
677 // Fails if the file is not open, is finalized, or an operating system
679 Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
681 // Closes the MXF file, writing the index and revised header.
685 // A class which reads MPEG frame data from an AS-DCP format MXF file.
689 mem_ptr<h__Reader> m_Reader;
690 ASDCP_NO_COPY_CONSTRUCT(MXFReader);
694 virtual ~MXFReader();
696 // Open the file for reading. The file must exist. Returns error if the
697 // operation cannot be completed.
698 Result_t OpenRead(const char* filename) const;
700 // Returns RESULT_INIT if the file is not open.
701 Result_t Close() const;
703 // Fill a VideoDescriptor struct with the values from the file's header.
704 // Returns RESULT_INIT if the file is not open.
705 Result_t FillVideoDescriptor(VideoDescriptor&) const;
707 // Fill a WriterInfo struct with the values from the file's header.
708 // Returns RESULT_INIT if the file is not open.
709 Result_t FillWriterInfo(WriterInfo&) const;
711 // Reads a frame of essence from the MXF file. If the optional AESEncContext
712 // argument is present, the essence is decrypted after reading. If the MXF
713 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
714 // will contain the ciphertext frame data. If the HMACContext argument is
715 // not NULL, the HMAC will be calculated (if the file supports it).
716 // Returns RESULT_INIT if the file is not open, failure if the frame number is
717 // out of range, or if optional decrypt or HAMC operations fail.
718 Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
720 // Calculates the first frame in transport order of the GOP in which the requested
721 // frame is located. Calls ReadFrame() to fetch the frame at the calculated position.
722 // Returns RESULT_INIT if the file is not open.
723 Result_t ReadFrameGOPStart(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
725 // Calculates the first frame in transport order of the GOP in which the requested
726 // frame is located. Sets key_frame_number to the number of the frame at the calculated position.
727 // Returns RESULT_INIT if the file is not open.
728 Result_t FindFrameGOPStart(ui32_t frame_number, ui32_t& key_frame_number) const;
730 // Returns the type of the frame at the given position.
731 // Returns RESULT_INIT if the file is not open or RESULT_RANGE if the index is out of range.
732 Result_t FrameType(ui32_t frame_number, FrameType_t&) const;
734 // Print debugging information to stream
735 void DumpHeaderMetadata(FILE* = 0) const;
736 void DumpIndex(FILE* = 0) const;
743 struct AudioDescriptor
745 Rational SampleRate; // rate of frame wrapping
746 Rational AudioSamplingRate; // rate of audio sample
748 ui32_t ChannelCount; // number of channels
749 ui32_t QuantizationBits; // number of bits per single-channel sample
750 ui32_t BlockAlign; // number of bytes ber sample, all channels
752 ui32_t LinkedTrackID; //
753 ui32_t ContainerDuration; // number of frames
756 // Print debugging information to stream (stderr default)
757 void AudioDescriptorDump(const AudioDescriptor&, FILE* = 0);
759 // Returns size in bytes of a single sample of data described by ADesc
760 inline ui32_t CalcSampleSize(const AudioDescriptor& ADesc)
762 return (ADesc.QuantizationBits / 8) * ADesc.ChannelCount;
765 // Returns number of samples per frame of data described by ADesc
766 inline ui32_t CalcSamplesPerFrame(const AudioDescriptor& ADesc)
768 double tmpd = ADesc.AudioSamplingRate.Quotient() / ADesc.SampleRate.Quotient();
769 return (ui32_t)ceil(tmpd);
772 // Returns the size in bytes of a frame of data described by ADesc
773 inline ui32_t CalcFrameBufferSize(const AudioDescriptor& ADesc)
775 return CalcSampleSize(ADesc) * CalcSamplesPerFrame(ADesc);
779 class FrameBuffer : public ASDCP::FrameBuffer
783 FrameBuffer(ui32_t size) { Capacity(size); }
784 virtual ~FrameBuffer() {}
786 // Print debugging information to stream (stderr default)
787 void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
790 // An object which opens and reads a WAV file. The call to OpenRead() reads metadata from
791 // the file and populates an internal AudioDescriptor object. Each subsequent call to
792 // ReadFrame() reads exactly one frame from the stream into the given FrameBuffer object.
793 // A "frame" is either 2000 or 2002 samples, depending upon the value of PictureRate.
797 mem_ptr<h__WAVParser> m_Parser;
798 ASDCP_NO_COPY_CONSTRUCT(WAVParser);
802 virtual ~WAVParser();
804 // Opens the stream for reading, parses enough data to provide a complete
805 // set of stream metadata for the MXFWriter below. PictureRate controls
806 // ther frame rate for the MXF frame wrapping option.
807 Result_t OpenRead(const char* filename, const Rational& PictureRate) const;
809 // Fill an AudioDescriptor struct with the values from the file's header.
810 // Returns RESULT_INIT if the file is not open.
811 Result_t FillAudioDescriptor(AudioDescriptor&) const;
813 // Rewind the stream to the beginning.
814 Result_t Reset() const;
816 // Reads the next sequential frame in the input file and places it in the
817 // frame buffer. Fails if the buffer is too small or the stream is empty.
818 Result_t ReadFrame(FrameBuffer&) const;
826 mem_ptr<h__Writer> m_Writer;
827 ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
831 virtual ~MXFWriter();
833 // Open the file for writing. The file must not exist. Returns error if
834 // the operation cannot be completed or if nonsensical data is discovered
835 // in the essence descriptor.
836 Result_t OpenWrite(const char* filename, const WriterInfo&,
837 const AudioDescriptor&, ui32_t HeaderSize = 16384);
839 // Writes a frame of essence to the MXF file. If the optional AESEncContext
840 // argument is present, the essence is encrypted prior to writing.
841 // Fails if the file is not open, is finalized, or an operating system
843 Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
845 // Closes the MXF file, writing the index and revised header.
853 mem_ptr<h__Reader> m_Reader;
854 ASDCP_NO_COPY_CONSTRUCT(MXFReader);
858 virtual ~MXFReader();
860 // Open the file for reading. The file must exist. Returns error if the
861 // operation cannot be completed.
862 Result_t OpenRead(const char* filename) const;
864 // Returns RESULT_INIT if the file is not open.
865 Result_t Close() const;
867 // Fill an AudioDescriptor struct with the values from the file's header.
868 // Returns RESULT_INIT if the file is not open.
869 Result_t FillAudioDescriptor(AudioDescriptor&) const;
871 // Fill a WriterInfo struct with the values from the file's header.
872 // Returns RESULT_INIT if the file is not open.
873 Result_t FillWriterInfo(WriterInfo&) const;
875 // Reads a frame of essence from the MXF file. If the optional AESEncContext
876 // argument is present, the essence is decrypted after reading. If the MXF
877 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
878 // will contain the ciphertext frame data. If the HMACContext argument is
879 // not NULL, the HMAC will be calculated (if the file supports it).
880 // Returns RESULT_INIT if the file is not open, failure if the frame number is
881 // out of range, or if optional decrypt or HAMC operations fail.
882 Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
884 // Print debugging information to stream
885 void DumpHeaderMetadata(FILE* = 0) const;
886 void DumpIndex(FILE* = 0) const;
893 const ui32_t MaxComponents = 3;
894 const ui32_t DefaultCodingDataLength = 64;
896 struct ImageComponent
903 struct PictureDescriptor
906 ui32_t ContainerDuration;
910 Rational AspectRatio;
921 ImageComponent ImageComponents[MaxComponents];
922 byte_t CodingStyle[DefaultCodingDataLength];
923 ui32_t CodingStyleLength;
924 byte_t QuantDefault[DefaultCodingDataLength];
925 ui32_t QuantDefaultLength;
928 // Print debugging information to stream (stderr default)
929 void PictureDescriptorDump(const PictureDescriptor&, FILE* = 0);
932 class FrameBuffer : public ASDCP::FrameBuffer
936 FrameBuffer(ui32_t size) { Capacity(size); }
937 virtual ~FrameBuffer() {}
939 // Print debugging information to stream (stderr default)
940 void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
944 // An object which opens and reads a JPEG 2000 codestream file. The file is expected
945 // to contain exactly one complete frame of picture essence as an unwrapped (raw)
946 // ISO/IEC 15444 codestream.
947 class CodestreamParser
949 class h__CodestreamParser;
950 mem_ptr<h__CodestreamParser> m_Parser;
951 ASDCP_NO_COPY_CONSTRUCT(CodestreamParser);
955 virtual ~CodestreamParser();
957 // Opens a file for reading, parses enough data to provide a complete
958 // set of stream metadata for the MXFWriter below.
959 // The frame buffer's PlaintextOffset parameter will be set to the first
960 // byte of the data segment. Set this value to zero if you want
961 // encrypted headers.
962 Result_t OpenReadFrame(const char* filename, FrameBuffer&) const;
964 // Fill a PictureDescriptor struct with the values from the file's codestream.
965 // Returns RESULT_INIT if the file is not open.
966 Result_t FillPictureDescriptor(PictureDescriptor&) const;
969 // An object which reads a sequence of files containing JPEG 2000 pictures.
972 class h__SequenceParser;
973 mem_ptr<h__SequenceParser> m_Parser;
974 ASDCP_NO_COPY_CONSTRUCT(SequenceParser);
978 virtual ~SequenceParser();
980 // Opens a directory for reading. The directory is expected to contain one or
981 // more files, each containing the codestream for exactly one picture. The
982 // files must be named such that the frames are in temporal order when sorted
983 // alphabetically by filename. The parser will automatically parse enough data
984 // from the first file to provide a complete set of stream metadata for the
985 // MXFWriter below. If the "pedantic" parameter is given and is true, the
986 // parser will check the metadata for each codestream and fail if a
987 // mismatch is detected.
988 Result_t OpenRead(const char* filename, bool pedantic = false) const;
990 // Fill a PictureDescriptor struct with the values from the first file's codestream.
991 // Returns RESULT_INIT if the directory is not open.
992 Result_t FillPictureDescriptor(PictureDescriptor&) const;
994 // Rewind the directory to the beginning.
995 Result_t Reset() const;
997 // Reads the next sequential frame in the directory and places it in the
998 // frame buffer. Fails if the buffer is too small or the direcdtory
999 // contains no more files.
1000 // The frame buffer's PlaintextOffset parameter will be set to the first
1001 // byte of the data segment. Set this value to zero if you want
1002 // encrypted headers.
1003 Result_t ReadFrame(FrameBuffer&) const;
1011 mem_ptr<h__Writer> m_Writer;
1012 ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
1016 virtual ~MXFWriter();
1018 // Open the file for writing. The file must not exist. Returns error if
1019 // the operation cannot be completed or if nonsensical data is discovered
1020 // in the essence descriptor.
1021 Result_t OpenWrite(const char* filename, const WriterInfo&,
1022 const PictureDescriptor&, ui32_t HeaderSize = 16384);
1024 // Writes a frame of essence to the MXF file. If the optional AESEncContext
1025 // argument is present, the essence is encrypted prior to writing.
1026 // Fails if the file is not open, is finalized, or an operating system
1028 Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
1030 // Closes the MXF file, writing the index and revised header.
1031 Result_t Finalize();
1038 mem_ptr<h__Reader> m_Reader;
1039 ASDCP_NO_COPY_CONSTRUCT(MXFReader);
1043 virtual ~MXFReader();
1045 // Open the file for reading. The file must exist. Returns error if the
1046 // operation cannot be completed.
1047 Result_t OpenRead(const char* filename) const;
1049 // Returns RESULT_INIT if the file is not open.
1050 Result_t Close() const;
1052 // Fill an AudioDescriptor struct with the values from the file's header.
1053 // Returns RESULT_INIT if the file is not open.
1054 Result_t FillPictureDescriptor(PictureDescriptor&) const;
1056 // Fill a WriterInfo struct with the values from the file's header.
1057 // Returns RESULT_INIT if the file is not open.
1058 Result_t FillWriterInfo(WriterInfo&) const;
1060 // Reads a frame of essence from the MXF file. If the optional AESEncContext
1061 // argument is present, the essence is decrypted after reading. If the MXF
1062 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1063 // will contain the ciphertext frame data. If the HMACContext argument is
1064 // not NULL, the HMAC will be calculated (if the file supports it).
1065 // Returns RESULT_INIT if the file is not open, failure if the frame number is
1066 // out of range, or if optional decrypt or HAMC operations fail.
1067 Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1069 // Print debugging information to stream
1070 void DumpHeaderMetadata(FILE* = 0) const;
1071 void DumpIndex(FILE* = 0) const;
1074 } // namespace ASDCP
1077 #endif // _AS_DCP_H_