the big-pre-as-02-refactor
[asdcplib.git] / src / AS_02.h
1 /*
2 Copyright (c) 2011-2013, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
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.
15
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.
26 */ 
27 /*! \file    AS_02.h
28     \version $Id$       
29     \brief   AS-02 library, public interface
30
31 This module implements MXF AS-02 is a set of file access objects that
32 offer simplified access to files conforming to the standards published
33 by the SMPTE Media and Packaging Technology Committee 35PM. The file
34 format, labeled IMF Essence Component (AKA "AS-02" for historical
35 reasons), is described in the following document:
36
37  o SMPTE 2067-5:201X (draft at this time) IMF Essence Component
38
39 The following use cases are supported by the module:
40
41  o Write essence to a plaintext or ciphertext AS-02 file:
42      JPEG 2000 codestreams
43      PCM audio streams
44
45  o Read essence from a plaintext or ciphertext AS-02 file:
46      JPEG 2000 codestreams
47      PCM audio streams
48
49  o Read header metadata from an AS-02 file
50 */
51
52 #ifndef _AS_02_H_
53 #define _AS_02_H_
54
55 #include "AS_DCP.h"
56 #include "MXF.h"
57
58
59 namespace ASDCP {
60   namespace MXF {
61     // #include<Metadata.h> to use this
62     class OPAtomHeader;
63   };
64 };
65
66 namespace AS_02
67 {
68   using Kumu::Result_t;
69
70   namespace MXF {
71 #if 1
72     //
73     class OP1aIndexBodyPartion : public ASDCP::MXF::Partition
74     {
75       ASDCP::MXF::IndexTableSegment*  m_CurrentSegment;
76       ASDCP::FrameBuffer  m_Buffer;
77       ASDCP::MXF::Rational m_EditRate;
78       ui32_t                            klv_fill_size;
79
80       ASDCP_NO_COPY_CONSTRUCT(OP1aIndexBodyPartion);
81
82     public:
83       const ASDCP::Dictionary*&  m_Dict;
84       Kumu::fpos_t        m_ECOffset;
85       ASDCP::IPrimerLookup*      m_Lookup;
86
87       ui32_t             m_BytesPerEditUnit;
88       ui32_t             m_FramesWritten;
89       
90       OP1aIndexBodyPartion(const ASDCP::Dictionary*&);
91       virtual ~OP1aIndexBodyPartion();
92       virtual Result_t InitFromFile(const Kumu::FileReader& Reader);
93       virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l);
94       virtual Result_t WriteToFile(Kumu::FileWriter& Writer, ASDCP::UL& PartitionLabel);
95       virtual void     Dump(FILE* = 0);
96
97       virtual bool Lookup(ui32_t frame_num, ASDCP::MXF::IndexTableSegment::IndexEntry&,ui32_t&) const;
98       virtual void PushIndexEntry(const ASDCP::MXF::IndexTableSegment::IndexEntry&);
99       virtual void SetIndexParamsCBR(ASDCP::IPrimerLookup* lookup, ui32_t size, const ASDCP::MXF::Rational& Rate);
100       virtual void SetIndexParamsVBR(ASDCP::IPrimerLookup* lookup, const ASDCP::MXF::Rational& Rate, Kumu::fpos_t offset);
101
102       //new
103       virtual ui64_t Duration();
104       virtual Result_t FillWriteToFile(Kumu::FileWriter& Writer, ui32_t numberOfIndexEntries);
105
106       //new for PCM
107       virtual void PCMSetIndexParamsCBR(ui32_t sizeFirst, ui32_t sizeOthers);
108       virtual void PCMIndexLookup(ui32_t frame_num, ASDCP::MXF::IndexTableSegment::IndexEntry& Entry) const;
109       
110     };
111
112     //
113     class OP1aIndexFooter : public ASDCP::MXF::Partition
114     {
115       ASDCP::MXF::IndexTableSegment*  m_CurrentSegment;
116       ASDCP::FrameBuffer  m_Buffer;
117       ui32_t              m_BytesPerEditUnit;
118       ASDCP::MXF::Rational m_EditRate;
119       ui32_t              m_BodySID;
120       ASDCP_NO_COPY_CONSTRUCT(OP1aIndexFooter);
121       OP1aIndexFooter();
122
123     public:
124       const ASDCP::Dictionary*&   m_Dict;
125       Kumu::fpos_t        m_ECOffset;
126       ASDCP::IPrimerLookup*      m_Lookup;
127
128       OP1aIndexFooter(const ASDCP::Dictionary*&);
129       virtual ~OP1aIndexFooter();
130       virtual Result_t InitFromFile(const Kumu::FileReader& Reader);
131       virtual Result_t InitFromPartitionBuffer(const byte_t* p, ui32_t l);
132       virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l);
133       virtual Result_t WriteToFile(Kumu::FileWriter& Writer, ui64_t duration);
134       virtual void     Dump(FILE* = 0);
135
136       virtual Result_t Lookup(ui32_t frame_num, ASDCP::MXF::IndexTableSegment::IndexEntry&) const;
137       virtual void     PushIndexEntry(const ASDCP::MXF::IndexTableSegment::IndexEntry&);
138       virtual void     SetIndexParamsCBR(ASDCP::IPrimerLookup* lookup, ui32_t size, const ASDCP::MXF::Rational& Rate);
139       virtual void     SetIndexParamsVBR(ASDCP::IPrimerLookup* lookup, const ASDCP::MXF::Rational& Rate, Kumu::fpos_t offset);
140     };
141
142 #endif
143
144     //
145     class AS02IndexReader
146     {
147       ASDCP::MXF::IndexTableSegment*  m_CurrentSegment;
148       ASDCP::FrameBuffer  m_Buffer;
149       ui32_t              m_BytesPerEditUnit;
150       ASDCP::Rational     m_EditRate;
151       ui32_t              m_BodySID;
152
153       ASDCP_NO_COPY_CONSTRUCT(AS02IndexReader);
154       AS02IndexReader();
155           
156     public:
157       const ASDCP::Dictionary*&   m_Dict;
158       Kumu::fpos_t        m_ECOffset;
159       ASDCP::IPrimerLookup *m_Lookup;
160     
161       AS02IndexReader(const ASDCP::Dictionary*&);
162       virtual ~AS02IndexReader();
163     
164       virtual Result_t InitFromFile(const Kumu::FileReader& Reader);
165       virtual void     Dump(FILE* = 0);
166     
167       virtual Result_t GetMDObjectByID(const Kumu::UUID&, ASDCP::MXF::InterchangeObject** = 0);
168       virtual Result_t GetMDObjectByType(const byte_t*, ASDCP::MXF::InterchangeObject** = 0);
169       virtual Result_t GetMDObjectsByType(const byte_t* ObjectID, std::list<ASDCP::MXF::InterchangeObject*>& ObjectList);
170     
171       virtual Result_t Lookup(ui32_t frame_num, ASDCP::MXF::IndexTableSegment::IndexEntry&) const;
172     };
173
174   } // namespace MXF
175
176   //---------------------------------------------------------------------------------
177   // Accessors in the MXFReader and MXFWriter classes below return these types to
178   // provide direct access to MXF metadata structures declared in MXF.h and Metadata.h
179
180   // See ST 2067-5 Sec. x.y.z
181   enum IndexStrategy_t
182   {
183     IS_LEAD,
184     IS_FOLLOW,
185     IS_FILE_SPECIFIC,
186   };
187  
188   namespace JP2K
189   {
190     //
191     class MXFWriter
192     {
193       class h__Writer;
194       ASDCP::mem_ptr<h__Writer> m_Writer;
195       ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
196       
197     public:
198       MXFWriter();
199       virtual ~MXFWriter();
200
201       // Warning: direct manipulation of MXF structures can interfere
202       // with the normal operation of the wrapper.  Caveat emptor!
203       virtual ASDCP::MXF::OP1aHeader& OP1aHeader();
204       virtual ASDCP::MXF::RIP& RIP();
205
206       // Open the file for writing. The file must not exist. Returns error if
207       // the operation cannot be completed or if nonsensical data is discovered
208       // in the essence descriptor.
209       Result_t OpenWrite(const char* filename, const ASDCP::WriterInfo&,
210                          const ASDCP::JP2K::PictureDescriptor&,
211                          const IndexStrategy_t& Strategy = IS_FOLLOW,
212                          const ui32_t& PartitionSpace = 60, /* seconds per partition */
213                          const ui32_t& HeaderSize = 16384);
214       
215       // Writes a frame of essence to the MXF file. If the optional AESEncContext
216       // argument is present, the essence is encrypted prior to writing.
217       // Fails if the file is not open, is finalized, or an operating system
218       // error occurs.
219       Result_t WriteFrame(const ASDCP::JP2K::FrameBuffer&, ASDCP::AESEncContext* = 0, ASDCP::HMACContext* = 0);
220
221       // Closes the MXF file, writing the index and revised header.
222       Result_t Finalize();
223     };
224
225     //
226     class MXFReader
227     {
228       class h__Reader;
229       ASDCP::mem_ptr<h__Reader> m_Reader;
230       ASDCP_NO_COPY_CONSTRUCT(MXFReader);
231
232     public:
233       MXFReader();
234       virtual ~MXFReader();
235
236       // Warning: direct manipulation of MXF structures can interfere
237       // with the normal operation of the wrapper.  Caveat emptor!
238       virtual ASDCP::MXF::OP1aHeader& OP1aHeader();
239       virtual AS_02::MXF::AS02IndexReader& AS02IndexReader();
240       virtual ASDCP::MXF::RIP& RIP();
241
242       // Open the file for reading. The file must exist. Returns error if the
243       // operation cannot be completed.
244       Result_t OpenRead(const char* filename) const;
245
246       // Returns RESULT_INIT if the file is not open.
247       Result_t Close() const;
248
249       // Fill an AudioDescriptor struct with the values from the file's header.
250       // Returns RESULT_INIT if the file is not open.
251       Result_t FillPictureDescriptor(ASDCP::JP2K::PictureDescriptor&) const;
252
253       // Fill a WriterInfo struct with the values from the file's header.
254       // Returns RESULT_INIT if the file is not open.
255       Result_t FillWriterInfo(ASDCP::WriterInfo&) const;
256
257       // Reads a frame of essence from the MXF file. If the optional AESEncContext
258       // argument is present, the essence is decrypted after reading. If the MXF
259       // file is encrypted and the AESDecContext argument is NULL, the frame buffer
260       // will contain the ciphertext frame data. If the HMACContext argument is
261       // not NULL, the HMAC will be calculated (if the file supports it).
262       // Returns RESULT_INIT if the file is not open, failure if the frame number is
263       // out of range, or if optional decrypt or HAMC operations fail.
264       Result_t ReadFrame(ui32_t frame_number, ASDCP::JP2K::FrameBuffer&, ASDCP::AESDecContext* = 0, ASDCP::HMACContext* = 0) const;
265
266       // Print debugging information to stream
267       void     DumpHeaderMetadata(FILE* = 0) const;
268       void     DumpIndex(FILE* = 0) const;
269     };
270     
271   } //namespace JP2K
272   
273
274   //---------------------------------------------------------------------------------
275   //
276   namespace PCM
277   {
278     // see AS_DCP.h for related data types
279
280     //
281     class MXFWriter
282     {
283       class h__Writer;
284       ASDCP::mem_ptr<h__Writer> m_Writer;
285       ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
286
287     public:
288       MXFWriter();
289       virtual ~MXFWriter();
290
291       // Warning: direct manipulation of MXF structures can interfere
292       // with the normal operation of the wrapper.  Caveat emptor!
293       virtual ASDCP::MXF::OP1aHeader& OP1aHeader();
294       virtual ASDCP::MXF::RIP& RIP();
295
296       // Open the file for writing. The file must not exist. Returns error if
297       // the operation cannot be completed or if nonsensical data is discovered
298       // in the essence descriptor.
299       Result_t OpenWrite(const char* filename, const ASDCP::WriterInfo&,
300                                 const ASDCP::PCM::AudioDescriptor&, ui32_t HeaderSize = 16384);
301
302       // Writes a frame of essence to the MXF file. If the optional AESEncContext
303       // argument is present, the essence is encrypted prior to writing.
304       // Fails if the file is not open, is finalized, or an operating system
305       // error occurs.
306       Result_t WriteFrame(const ASDCP::FrameBuffer&, ASDCP::AESEncContext* = 0, ASDCP::HMACContext* = 0);
307       
308       // Closes the MXF file, writing the index and revised header.
309       Result_t Finalize();
310     };
311
312     //
313     class MXFReader
314     {
315       class h__Reader;
316       ASDCP::mem_ptr<h__Reader> m_Reader;
317       ASDCP_NO_COPY_CONSTRUCT(MXFReader);
318
319     public:
320       MXFReader();
321       virtual ~MXFReader();
322
323       // Warning: direct manipulation of MXF structures can interfere
324       // with the normal operation of the wrapper.  Caveat emptor!
325       virtual ASDCP::MXF::OP1aHeader& OP1aHeader();
326       virtual AS_02::MXF::AS02IndexReader& AS02IndexReader();
327       virtual ASDCP::MXF::RIP& RIP();
328
329       // Open the file for reading. The file must exist. Returns error if the
330       // operation cannot be completed.
331       Result_t OpenRead(const char* filename) const;
332
333       // Returns RESULT_INIT if the file is not open.
334       Result_t Close() const;
335
336       // Fill an AudioDescriptor struct with the values from the file's header.
337       // Returns RESULT_INIT if the file is not open.
338       Result_t FillAudioDescriptor(ASDCP::PCM::AudioDescriptor&) const;
339
340       // Fill a WriterInfo struct with the values from the file's header.
341       // Returns RESULT_INIT if the file is not open.
342       Result_t FillWriterInfo(ASDCP::WriterInfo&) const;
343
344       // Reads a frame of essence from the MXF file. If the optional AESEncContext
345       // argument is present, the essence is decrypted after reading. If the MXF
346       // file is encrypted and the AESDecContext argument is NULL, the frame buffer
347       // will contain the ciphertext frame data. If the HMACContext argument is
348       // not NULL, the HMAC will be calculated (if the file supports it).
349       // Returns RESULT_INIT if the file is not open, failure if the frame number is
350       // out of range, or if optional decrypt or HAMC operations fail.
351       Result_t ReadFrame(ui32_t frame_number, ASDCP::PCM::FrameBuffer&, ASDCP::AESDecContext* = 0, ASDCP::HMACContext* = 0) const;
352       
353       // Print debugging information to stream
354       void     DumpHeaderMetadata(FILE* = 0) const;
355       void     DumpIndex(FILE* = 0) const;
356     };
357   } // namespace PCM
358
359
360
361 } // namespace AS_02
362
363 #endif // _AS_02_H_
364
365 //
366 // end AS_02.h
367 //