tweezes
[asdcplib.git] / src / AS_02.h
1 /*
2 Copyright (c) 2011-2013, Robert Scheler, Heiko Sparenberg Fraunhofer IIS,
3 John Hurst
4
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
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.
17
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.
28 */ 
29 /*! \file    AS_02.h
30     \version $Id$       
31     \brief   AS-02 library, public interface
32
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:
38
39  o SMPTE 2067-5:2013 IMF Essence Component
40
41 The following use cases are supported by the module:
42
43  o Write essence to a plaintext or ciphertext AS-02 file:
44      JPEG 2000 codestreams
45      PCM audio streams
46
47  o Read essence from a plaintext or ciphertext AS-02 file:
48      JPEG 2000 codestreams
49      PCM audio streams
50
51  o Read header metadata from an AS-02 file
52
53 NOTE: ciphertext support for clip-wrapped PCM is not yet complete.
54 */
55
56 #ifndef _AS_02_H_
57 #define _AS_02_H_
58
59 #include "Metadata.h"
60
61
62 namespace AS_02
63 {
64   using Kumu::Result_t;
65
66   KM_DECLARE_RESULT(AS02_FORMAT,        -116, "The file format is not proper OP-1a/AS-02.");
67
68   namespace MXF {
69     //
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
74     {
75       Kumu::ByteString m_IndexSegmentData;
76       ui32_t m_Duration;
77       ui32_t m_BytesPerEditUnit;
78
79       Result_t InitFromBuffer(const byte_t* p, ui32_t l, const ui64_t& body_offset, const ui64_t& essence_container_offset);
80
81       ASDCP_NO_COPY_CONSTRUCT(AS02IndexReader);
82       AS02IndexReader();
83           
84     public:
85       const ASDCP::Dictionary*&   m_Dict;
86       ASDCP::IPrimerLookup *m_Lookup;
87     
88       AS02IndexReader(const ASDCP::Dictionary*&);
89       virtual ~AS02IndexReader();
90     
91       Result_t InitFromFile(const Kumu::FileReader& reader, const ASDCP::MXF::RIP& rip, const bool has_header_essence);
92       ui32_t GetDuration() const;
93       void     Dump(FILE* = 0);
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;
98     };
99
100
101     
102     // Returns size in bytes of a single sample of data described by ADesc
103     inline ui32_t CalcSampleSize(const ASDCP::MXF::WaveAudioDescriptor& d)
104     {
105       return (d.QuantizationBits / 8) * d.ChannelCount;
106     }
107
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)
110     {
111       double tmpd = d.AudioSamplingRate.Quotient() / edit_rate.Quotient();
112       return (ui32_t)ceil(tmpd);
113     }
114
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)
117     {
118       return CalcSampleSize(d) * CalcSamplesPerFrame(d, edit_rate);
119     }
120
121   } // namespace MXF
122
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
126
127   // See ST 2067-5 Sec. x.y.z
128   enum IndexStrategy_t
129   {
130     IS_LEAD,
131     IS_FOLLOW,
132     IS_FILE_SPECIFIC,
133     IS_MAX
134   };
135  
136   namespace JP2K
137   {
138     //
139     class MXFWriter
140     {
141       class h__Writer;
142       ASDCP::mem_ptr<h__Writer> m_Writer;
143       ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
144       
145     public:
146       MXFWriter();
147       virtual ~MXFWriter();
148
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();
153
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);
162       
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
166       // error occurs.
167       Result_t WriteFrame(const ASDCP::JP2K::FrameBuffer&, ASDCP::AESEncContext* = 0, ASDCP::HMACContext* = 0);
168
169       // Closes the MXF file, writing the index and revised header.
170       Result_t Finalize();
171     };
172
173     //
174     class MXFReader
175     {
176       class h__Reader;
177       ASDCP::mem_ptr<h__Reader> m_Reader;
178       ASDCP_NO_COPY_CONSTRUCT(MXFReader);
179
180     public:
181       MXFReader();
182       virtual ~MXFReader();
183
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();
189
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;
193
194       // Returns RESULT_INIT if the file is not open.
195       Result_t Close() const;
196
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;
200
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;
209
210       // Print debugging information to stream
211       void     DumpHeaderMetadata(FILE* = 0) const;
212       void     DumpIndex(FILE* = 0) const;
213     };
214     
215   } //namespace JP2K
216   
217
218   //---------------------------------------------------------------------------------
219   //
220   namespace PCM
221   {
222     // see AS_DCP.h for related data types
223
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();
231
232     //
233     class MXFWriter
234     {
235       class h__Writer;
236       ASDCP::mem_ptr<h__Writer> m_Writer;
237       ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
238
239     public:
240       MXFWriter();
241       virtual ~MXFWriter();
242
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();
247
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);
255
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
259       // error occurs.
260       Result_t WriteFrame(const ASDCP::FrameBuffer&, ASDCP::AESEncContext* = 0, ASDCP::HMACContext* = 0);
261       
262       // Closes the MXF file, writing the index and revised header.
263       Result_t Finalize();
264     };
265
266     //
267     class MXFReader
268     {
269       class h__Reader;
270       ASDCP::mem_ptr<h__Reader> m_Reader;
271       ASDCP_NO_COPY_CONSTRUCT(MXFReader);
272
273     public:
274       MXFReader();
275       virtual ~MXFReader();
276
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();
282
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);
286
287       // Returns RESULT_INIT if the file is not open.
288       Result_t Close() const;
289
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;
293
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;
302       
303       // Print debugging information to stream
304       void     DumpHeaderMetadata(FILE* = 0) const;
305       void     DumpIndex(FILE* = 0) const;
306     };
307   } // namespace PCM
308
309
310
311 } // namespace AS_02
312
313 #endif // _AS_02_H_
314
315 //
316 // end AS_02.h
317 //