pre-release commit
[asdcplib.git] / src / MXF.h
1 /*
2 Copyright (c) 2005-2006, 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    MXF.h
28     \version $Id$
29     \brief   MXF objects
30 */
31
32 #ifndef _MXF_H_
33 #define _MXF_H_
34
35 #include "MXFTypes.h"
36
37 namespace ASDCP
38 {
39   namespace MXF
40     {
41       // seek an open file handle to the start of the RIP KLV packet
42       Result_t SeekToRIP(const FileReader&);
43       
44       //
45       class RIP : public ASDCP::KLVFilePacket
46         {
47           ASDCP_NO_COPY_CONSTRUCT(RIP);
48
49         public:
50           //
51           class Pair {
52           public:
53             ui32_t BodySID;
54             ui64_t ByteOffset;
55
56             ui32_t Size() { return sizeof(ui32_t) + sizeof(ui64_t); }
57
58             inline const char* ToString(char* str_buf) const {
59               char intbuf[IntBufferLen];
60               sprintf(str_buf, "%-6lu: %s", BodySID, ui64sz(ByteOffset, intbuf));
61               return str_buf;
62             }
63
64             inline Result_t ReadFrom(ASDCP::MemIOReader& Reader) {
65               Result_t result = Reader.ReadUi32BE(&BodySID);
66
67               if ( ASDCP_SUCCESS(result) )
68                 result = Reader.ReadUi64BE(&ByteOffset);
69
70               return result;
71             }
72
73             inline Result_t WriteTo(ASDCP::MemIOWriter& Writer) {
74               Result_t result = Writer.WriteUi32BE(BodySID);
75
76               if ( ASDCP_SUCCESS(result) )
77                 result = Writer.WriteUi64BE(ByteOffset);
78
79               return result;
80             }
81           };
82
83           Array<Pair> PairArray;
84
85           RIP() {}
86           virtual ~RIP() {}
87           virtual Result_t InitFromFile(const ASDCP::FileReader& Reader);
88           virtual Result_t WriteToFile(ASDCP::FileWriter& Writer);
89           virtual void     Dump(FILE* = 0);
90         };
91
92
93       //
94       class Partition : public ASDCP::KLVFilePacket
95         {       
96           ASDCP_NO_COPY_CONSTRUCT(Partition);
97
98         public:
99           ui16_t    MajorVersion;
100           ui16_t    MinorVersion;
101           ui32_t    KAGSize;
102           ui64_t    ThisPartition;
103           ui64_t    PreviousPartition;
104           ui64_t    FooterPartition;
105           ui64_t    HeaderByteCount;
106           ui64_t    IndexByteCount;
107           ui32_t    IndexSID;
108           ui64_t    BodyOffset;
109           ui32_t    BodySID;
110           UL        OperationalPattern;
111           Batch<UL> EssenceContainers;
112
113           Partition() {}
114           virtual ~Partition() {}
115           virtual Result_t InitFromFile(const ASDCP::FileReader& Reader);
116           virtual Result_t WriteToFile(ASDCP::FileWriter& Writer);
117           virtual void     Dump(FILE* = 0);
118         };
119
120
121       //
122       class Primer : public ASDCP::KLVPacket, public ASDCP::IPrimerLookup
123         {
124           class h__PrimerLookup;
125           mem_ptr<h__PrimerLookup> m_Lookup;
126           ASDCP_NO_COPY_CONSTRUCT(Primer);
127
128         public:
129           //
130           class LocalTagEntry
131             {
132             public:
133               TagValue    Tag;
134               ASDCP::UL   UL;
135
136               inline const char* ToString(char* str_buf) const {
137                 sprintf(str_buf, "%02x %02x: ", Tag.a, Tag.b);
138                 UL.ToString(str_buf + strlen(str_buf));
139                 return str_buf;
140               }
141
142               inline Result_t ReadFrom(ASDCP::MemIOReader& Reader) {
143                 Result_t result = Reader.ReadUi8(&Tag.a);
144                 
145                 if ( ASDCP_SUCCESS(result) )
146                   result = Reader.ReadUi8(&Tag.b);
147
148                 if ( ASDCP_SUCCESS(result) )
149                   result = UL.ReadFrom(Reader);
150
151                 return result;
152               }
153
154               inline Result_t WriteTo(ASDCP::MemIOWriter& Writer) {
155                 Result_t result = Writer.WriteUi8(Tag.a);
156                 
157                 if ( ASDCP_SUCCESS(result) )
158                   result = Writer.WriteUi8(Tag.b);
159
160                 if ( ASDCP_SUCCESS(result) )
161                   result = UL.WriteTo(Writer);
162
163                 return result;
164               }
165             };
166
167           Batch<LocalTagEntry> LocalTagEntryBatch;
168
169           Primer();
170           virtual ~Primer();
171
172           virtual void     ClearTagList();
173           virtual Result_t InsertTag(const ASDCP::UL& Key, ASDCP::TagValue& Tag);
174           virtual Result_t TagForKey(const ASDCP::UL& Key, ASDCP::TagValue& Tag);
175
176           virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l);
177           virtual Result_t WriteToBuffer(ASDCP::FrameBuffer&);
178           virtual void     Dump(FILE* = 0);
179         };
180
181
182       //
183       class InterchangeObject : public ASDCP::KLVPacket
184         {
185         public:
186           IPrimerLookup* m_Lookup;
187           UID            InstanceUID;
188
189           InterchangeObject() : m_Lookup(0) {}
190           virtual ~InterchangeObject() {}
191           virtual Result_t WriteToBuffer(ASDCP::FrameBuffer&);
192           virtual bool     IsA(const byte_t* label);
193
194           virtual void Dump(FILE* stream = 0) {
195             KLVPacket::Dump(stream, true);
196           }
197         };
198
199       //
200       InterchangeObject* CreateObject(const byte_t* label);
201
202
203       //
204       class Preface : public InterchangeObject
205         {
206           ASDCP_NO_COPY_CONSTRUCT(Preface);
207
208         public:
209           UUID         GenerationUID;
210           Timestamp    LastModifiedDate;
211           ui16_t       Version;
212           ui32_t       ObjectModelVersion;
213           UID          PrimaryPackage;
214           Batch<UID>   Identifications;
215           UID          ContentStorage;
216           UL           OperationalPattern;
217           Batch<UL>    EssenceContainers;
218           Batch<UL>    DMSchemes;
219
220           Preface() {}
221           virtual ~Preface() {}
222           virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l);
223           virtual Result_t WriteToBuffer(ASDCP::FrameBuffer& Buffer);
224           virtual void     Dump(FILE* = 0);
225         };
226
227       //
228       class IndexTableSegment : public InterchangeObject
229         {
230           ASDCP_NO_COPY_CONSTRUCT(IndexTableSegment);
231
232         public:
233           //
234           class DeltaEntry
235             {
236             public:
237               i8_t    PosTableIndex;
238               ui8_t   Slice;
239               ui32_t  ElementData;
240
241               Result_t ReadFrom(ASDCP::MemIOReader& Reader);
242               Result_t WriteTo(ASDCP::MemIOWriter& Writer);
243               inline const char* ToString(char* str_buf) const;
244             };
245
246           //
247           class IndexEntry
248             {
249             public:
250               i8_t               TemporalOffset;
251               i8_t               KeyFrameOffset;
252               ui8_t              Flags;
253               ui64_t             StreamOffset;
254               std::list<ui32_t>  SliceOffset;
255               Array<Rational>    PosTable;
256
257               Result_t ReadFrom(ASDCP::MemIOReader& Reader);
258               Result_t WriteTo(ASDCP::MemIOWriter& Writer);
259               inline const char* ToString(char* str_buf) const;
260             };
261
262           Rational    IndexEditRate;
263           ui64_t      IndexStartPosition;
264           ui64_t      IndexDuration;
265           ui32_t      EditUnitByteCount;
266           ui32_t      IndexSID;
267           ui32_t      BodySID;
268           ui8_t       SliceCount;
269           ui8_t       PosTableCount;
270           Batch<DeltaEntry> DeltaEntryArray;
271           Batch<IndexEntry> IndexEntryArray;
272
273           IndexTableSegment();
274           virtual ~IndexTableSegment();
275           virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l);
276           virtual Result_t WriteToBuffer(ASDCP::FrameBuffer& Buffer);
277           virtual void     Dump(FILE* = 0);
278         };
279
280       //---------------------------------------------------------------------------------
281       //
282       class h__PacketList; // See MXF.cpp
283       class Identification;
284       class SourcePackage;
285
286       //
287       class OPAtomHeader : public Partition
288         {
289           mem_ptr<h__PacketList>   m_PacketList;
290           ASDCP_NO_COPY_CONSTRUCT(OPAtomHeader);
291
292         public:
293           ASDCP::MXF::RIP          m_RIP;
294           ASDCP::MXF::Primer       m_Primer;
295           InterchangeObject*       m_Preface;
296           ASDCP::FrameBuffer       m_Buffer;
297           bool                     m_HasRIP;
298
299           OPAtomHeader();
300           virtual ~OPAtomHeader();
301           virtual Result_t InitFromFile(const ASDCP::FileReader& Reader);
302           virtual Result_t WriteToFile(ASDCP::FileWriter& Writer, ui32_t HeaderLength = 16384);
303           virtual void     Dump(FILE* = 0);
304           virtual Result_t GetMDObjectByType(const byte_t*, InterchangeObject** = 0);
305           Identification*  GetIdentification();
306           SourcePackage*   GetSourcePackage();
307         };
308
309       //
310       class OPAtomIndexFooter : public Partition
311         {
312           mem_ptr<h__PacketList>   m_PacketList;
313           ASDCP::FrameBuffer       m_Buffer;
314           ASDCP_NO_COPY_CONSTRUCT(OPAtomIndexFooter);
315
316         public:
317           IPrimerLookup* m_Lookup;
318          
319           OPAtomIndexFooter();
320           virtual ~OPAtomIndexFooter();
321           virtual Result_t InitFromFile(const ASDCP::FileReader& Reader);
322           virtual Result_t WriteToFile(ASDCP::FileWriter& Writer);
323           virtual void     Dump(FILE* = 0);
324
325           virtual Result_t Lookup(ui32_t frame_num, IndexTableSegment::IndexEntry&);
326         };
327
328     } // namespace MXF
329 } // namespace ASDCP
330
331
332 #endif // _MXF_H_
333
334 //
335 // end MXF.h
336 //