2 Copyright (c) 2011-2013, Robert Scheler, Heiko Sparenberg Fraunhofer IIS,
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
10 1. Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15 3. The name of the author may not be used to endorse or promote products
16 derived from this software without specific prior written permission.
18 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 \brief AS-02 library, public interface
33 This module implements MXF AS-02 is a set of file access objects that
34 offer simplified access to files conforming to the standards published
35 by the SMPTE Media and Packaging Technology Committee 35PM. The file
36 format, labeled IMF Essence Component (AKA "AS-02" for historical
37 reasons), is described in the following document:
39 o SMPTE 2067-5:2013 IMF Essence Component
41 The following use cases are supported by the module:
43 o Write essence to a plaintext or ciphertext AS-02 file:
47 o Read essence from a plaintext or ciphertext AS-02 file:
51 o Read header metadata from an AS-02 file
53 NOTE: ciphertext support for clip-wrapped PCM is not yet complete.
66 KM_DECLARE_RESULT(AS02_FORMAT, -116, "The file format is not proper OP-1a/AS-02.");
70 // reads distributed index tables and provides a uniform lookup with
71 // translated StreamOffest values (that is, StreamOffest is adjusted
72 // to the actual file position
73 class AS02IndexReader : public ASDCP::MXF::Partition
75 Kumu::ByteString m_IndexSegmentData;
77 ui32_t m_BytesPerEditUnit;
79 Result_t InitFromBuffer(const byte_t* p, ui32_t l, const ui64_t& body_offset, const ui64_t& essence_container_offset);
81 ASDCP_NO_COPY_CONSTRUCT(AS02IndexReader);
85 const ASDCP::Dictionary*& m_Dict;
86 ASDCP::IPrimerLookup *m_Lookup;
88 AS02IndexReader(const ASDCP::Dictionary*&);
89 virtual ~AS02IndexReader();
91 Result_t InitFromFile(const Kumu::FileReader& reader, const ASDCP::MXF::RIP& rip, const bool has_header_essence);
92 ui32_t GetDuration() const;
94 Result_t GetMDObjectByID(const Kumu::UUID&, ASDCP::MXF::InterchangeObject** = 0);
95 Result_t GetMDObjectByType(const byte_t*, ASDCP::MXF::InterchangeObject** = 0);
96 Result_t GetMDObjectsByType(const byte_t* ObjectID, std::list<ASDCP::MXF::InterchangeObject*>& ObjectList);
97 Result_t Lookup(ui32_t frame_num, ASDCP::MXF::IndexTableSegment::IndexEntry&) const;
102 // Returns size in bytes of a single sample of data described by ADesc
103 inline ui32_t CalcSampleSize(const ASDCP::MXF::WaveAudioDescriptor& d)
105 return (d.QuantizationBits / 8) * d.ChannelCount;
108 // Returns number of samples per frame of data described by ADesc
109 inline ui32_t CalcSamplesPerFrame(const ASDCP::MXF::WaveAudioDescriptor& d, const ASDCP::Rational& edit_rate)
111 double tmpd = d.AudioSamplingRate.Quotient() / edit_rate.Quotient();
112 return (ui32_t)ceil(tmpd);
115 // Returns the size in bytes of a frame of data described by ADesc
116 inline ui32_t CalcFrameBufferSize(const ASDCP::MXF::WaveAudioDescriptor& d, const ASDCP::Rational& edit_rate)
118 return CalcSampleSize(d) * CalcSamplesPerFrame(d, edit_rate);
123 //---------------------------------------------------------------------------------
124 // Accessors in the MXFReader and MXFWriter classes below return these types to
125 // provide direct access to MXF metadata structures declared in MXF.h and Metadata.h
127 // See ST 2067-5 Sec. x.y.z
142 ASDCP::mem_ptr<h__Writer> m_Writer;
143 ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
147 virtual ~MXFWriter();
149 // Warning: direct manipulation of MXF structures can interfere
150 // with the normal operation of the wrapper. Caveat emptor!
151 virtual ASDCP::MXF::OP1aHeader& OP1aHeader();
152 virtual ASDCP::MXF::RIP& RIP();
154 // Open the file for writing. The file must not exist. Returns error if
155 // the operation cannot be completed or if nonsensical data is discovered
156 // in the essence descriptor.
157 Result_t OpenWrite(const std::string& filename, const ASDCP::WriterInfo&,
158 ASDCP::MXF::FileDescriptor* essence_descriptor,
159 ASDCP::MXF::InterchangeObject_list_t& essence_sub_descriptor_list,
160 const ASDCP::Rational& edit_rate, const ui32_t& header_size = 16384,
161 const IndexStrategy_t& strategy = IS_FOLLOW, const ui32_t& partition_space = 10);
163 // Writes a frame of essence to the MXF file. If the optional AESEncContext
164 // argument is present, the essence is encrypted prior to writing.
165 // Fails if the file is not open, is finalized, or an operating system
167 Result_t WriteFrame(const ASDCP::JP2K::FrameBuffer&, ASDCP::AESEncContext* = 0, ASDCP::HMACContext* = 0);
169 // Closes the MXF file, writing the index and revised header.
177 ASDCP::mem_ptr<h__Reader> m_Reader;
178 ASDCP_NO_COPY_CONSTRUCT(MXFReader);
182 virtual ~MXFReader();
184 // Warning: direct manipulation of MXF structures can interfere
185 // with the normal operation of the wrapper. Caveat emptor!
186 virtual ASDCP::MXF::OP1aHeader& OP1aHeader();
187 virtual AS_02::MXF::AS02IndexReader& AS02IndexReader();
188 virtual ASDCP::MXF::RIP& RIP();
190 // Open the file for reading. The file must exist. Returns error if the
191 // operation cannot be completed.
192 Result_t OpenRead(const std::string& filename) const;
194 // Returns RESULT_INIT if the file is not open.
195 Result_t Close() const;
197 // Fill a WriterInfo struct with the values from the file's header.
198 // Returns RESULT_INIT if the file is not open.
199 Result_t FillWriterInfo(ASDCP::WriterInfo&) const;
201 // Reads a frame of essence from the MXF file. If the optional AESEncContext
202 // argument is present, the essence is decrypted after reading. If the MXF
203 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
204 // will contain the ciphertext frame data. If the HMACContext argument is
205 // not NULL, the HMAC will be calculated (if the file supports it).
206 // Returns RESULT_INIT if the file is not open, failure if the frame number is
207 // out of range, or if optional decrypt or HAMC operations fail.
208 Result_t ReadFrame(ui32_t frame_number, ASDCP::JP2K::FrameBuffer&, ASDCP::AESDecContext* = 0, ASDCP::HMACContext* = 0) const;
210 // Print debugging information to stream
211 void DumpHeaderMetadata(FILE* = 0) const;
212 void DumpIndex(FILE* = 0) const;
218 //---------------------------------------------------------------------------------
222 // see AS_DCP.h for related data types
224 // An AS-02 PCM file is clip-wrapped, but the interface defined below mimics that used
225 // for frame-wrapped essence elsewhere in this library. The concept of frame rate
226 // therefore is only relevant to these classes and is not reflected in or affected by
227 // the contents of the MXF file. The frame rate that is set on the writer is only
228 // for compatibility with the existing parsers, samples are packed contiguously into
229 // the same clip-wrapped packet. Similarly, the edit rate must be set when initializing
230 // the reader to signal the number of samples to be read by each call to ReadFrame();
236 ASDCP::mem_ptr<h__Writer> m_Writer;
237 ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
241 virtual ~MXFWriter();
243 // Warning: direct manipulation of MXF structures can interfere
244 // with the normal operation of the wrapper. Caveat emptor!
245 virtual ASDCP::MXF::OP1aHeader& OP1aHeader();
246 virtual ASDCP::MXF::RIP& RIP();
248 // Open the file for writing. The file must not exist. Returns error if
249 // the operation cannot be completed or if nonsensical data is discovered
250 // in the essence descriptor.
251 Result_t OpenWrite(const std::string& filename, const ASDCP::WriterInfo&,
252 ASDCP::MXF::FileDescriptor* essence_descriptor,
253 ASDCP::MXF::InterchangeObject_list_t& essence_sub_descriptor_list,
254 const ASDCP::Rational& edit_rate, ui32_t HeaderSize = 16384);
256 // Writes a frame of essence to the MXF file. If the optional AESEncContext
257 // argument is present, the essence is encrypted prior to writing.
258 // Fails if the file is not open, is finalized, or an operating system
260 Result_t WriteFrame(const ASDCP::FrameBuffer&, ASDCP::AESEncContext* = 0, ASDCP::HMACContext* = 0);
262 // Closes the MXF file, writing the index and revised header.
270 ASDCP::mem_ptr<h__Reader> m_Reader;
271 ASDCP_NO_COPY_CONSTRUCT(MXFReader);
275 virtual ~MXFReader();
277 // Warning: direct manipulation of MXF structures can interfere
278 // with the normal operation of the wrapper. Caveat emptor!
279 virtual ASDCP::MXF::OP1aHeader& OP1aHeader();
280 virtual AS_02::MXF::AS02IndexReader& AS02IndexReader();
281 virtual ASDCP::MXF::RIP& RIP();
283 // Open the file for reading. The file must exist. Returns error if the
284 // operation cannot be completed.
285 Result_t OpenRead(const std::string& filename, const ASDCP::Rational& EditRate);
287 // Returns RESULT_INIT if the file is not open.
288 Result_t Close() const;
290 // Fill a WriterInfo struct with the values from the file's header.
291 // Returns RESULT_INIT if the file is not open.
292 Result_t FillWriterInfo(ASDCP::WriterInfo&) const;
294 // Reads a frame of essence from the MXF file. If the optional AESEncContext
295 // argument is present, the essence is decrypted after reading. If the MXF
296 // file is encrypted and the AESDecContext argument is NULL, the frame buffer
297 // will contain the ciphertext frame data. If the HMACContext argument is
298 // not NULL, the HMAC will be calculated (if the file supports it).
299 // Returns RESULT_INIT if the file is not open, failure if the frame number is
300 // out of range, or if optional decrypt or HAMC operations fail.
301 Result_t ReadFrame(ui32_t frame_number, ASDCP::PCM::FrameBuffer&, ASDCP::AESDecContext* = 0, ASDCP::HMACContext* = 0) const;
303 // Print debugging information to stream
304 void DumpHeaderMetadata(FILE* = 0) const;
305 void DumpIndex(FILE* = 0) const;