bugfix in indexing
[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               snprintf(str_buf, IdentBufferLen, "%-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                 snprintf(str_buf, IdentBufferLen, "%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           UUID           GenerationUID;
189
190           InterchangeObject() : m_Lookup(0) {}
191           virtual ~InterchangeObject() {}
192           virtual Result_t InitFromTLVSet(TLVReader& TLVSet);
193           virtual Result_t WriteToBuffer(ASDCP::FrameBuffer&);
194           virtual bool     IsA(const byte_t* label);
195           virtual void     Dump(FILE* stream = 0);
196         };
197
198       //
199       InterchangeObject* CreateObject(const byte_t* label);
200
201
202       //
203       class Preface : public InterchangeObject
204         {
205           ASDCP_NO_COPY_CONSTRUCT(Preface);
206
207         public:
208           UUID         GenerationUID;
209           Timestamp    LastModifiedDate;
210           ui16_t       Version;
211           ui32_t       ObjectModelVersion;
212           UID          PrimaryPackage;
213           Batch<UID>   Identifications;
214           UID          ContentStorage;
215           UL           OperationalPattern;
216           Batch<UL>    EssenceContainers;
217           Batch<UL>    DMSchemes;
218
219           Preface() {}
220           virtual ~Preface() {}
221           virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l);
222           virtual Result_t WriteToBuffer(ASDCP::FrameBuffer& Buffer);
223           virtual void     Dump(FILE* = 0);
224         };
225
226       //
227       class IndexTableSegment : public InterchangeObject
228         {
229           ASDCP_NO_COPY_CONSTRUCT(IndexTableSegment);
230
231         public:
232           //
233           class DeltaEntry
234             {
235             public:
236               i8_t    PosTableIndex;
237               ui8_t   Slice;
238               ui32_t  ElementData;
239
240               Result_t ReadFrom(ASDCP::MemIOReader& Reader);
241               Result_t WriteTo(ASDCP::MemIOWriter& Writer);
242               inline const char* ToString(char* str_buf) const;
243             };
244
245           //
246           class IndexEntry
247             {
248             public:
249               i8_t               TemporalOffset;
250               i8_t               KeyFrameOffset;
251               ui8_t              Flags;
252               ui64_t             StreamOffset;
253               std::list<ui32_t>  SliceOffset;
254               Array<Rational>    PosTable;
255
256               Result_t ReadFrom(ASDCP::MemIOReader& Reader);
257               Result_t WriteTo(ASDCP::MemIOWriter& Writer);
258               inline const char* ToString(char* str_buf) const;
259             };
260
261           Rational    IndexEditRate;
262           ui64_t      IndexStartPosition;
263           ui64_t      IndexDuration;
264           ui32_t      EditUnitByteCount;
265           ui32_t      IndexSID;
266           ui32_t      BodySID;
267           ui8_t       SliceCount;
268           ui8_t       PosTableCount;
269           Batch<DeltaEntry> DeltaEntryArray;
270           Batch<IndexEntry> IndexEntryArray;
271
272           IndexTableSegment();
273           virtual ~IndexTableSegment();
274           virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l);
275           virtual Result_t WriteToBuffer(ASDCP::FrameBuffer& Buffer);
276           virtual void     Dump(FILE* = 0);
277         };
278
279       //---------------------------------------------------------------------------------
280       //
281       class h__PacketList; // See MXF.cpp
282       class Identification;
283       class SourcePackage;
284
285       //
286       class OPAtomHeader : public Partition
287         {
288           mem_ptr<h__PacketList>   m_PacketList;
289           ASDCP_NO_COPY_CONSTRUCT(OPAtomHeader);
290
291         public:
292           ASDCP::MXF::RIP          m_RIP;
293           ASDCP::MXF::Primer       m_Primer;
294           InterchangeObject*       m_Preface;
295           ASDCP::FrameBuffer       m_Buffer;
296           bool                     m_HasRIP;
297
298           OPAtomHeader();
299           virtual ~OPAtomHeader();
300           virtual Result_t InitFromFile(const ASDCP::FileReader& Reader);
301           virtual Result_t WriteToFile(ASDCP::FileWriter& Writer, ui32_t HeaderLength = 16384);
302           virtual void     Dump(FILE* = 0);
303           virtual Result_t GetMDObjectByType(const byte_t*, InterchangeObject** = 0);
304           Identification*  GetIdentification();
305           SourcePackage*   GetSourcePackage();
306         };
307
308       //
309       class OPAtomIndexFooter : public Partition
310         {
311           mem_ptr<h__PacketList>   m_PacketList;
312           ASDCP::FrameBuffer       m_Buffer;
313           ASDCP_NO_COPY_CONSTRUCT(OPAtomIndexFooter);
314
315         public:
316           IPrimerLookup* m_Lookup;
317          
318           OPAtomIndexFooter();
319           virtual ~OPAtomIndexFooter();
320           virtual Result_t InitFromFile(const ASDCP::FileReader& Reader);
321           virtual Result_t WriteToFile(ASDCP::FileWriter& Writer);
322           virtual void     Dump(FILE* = 0);
323
324           virtual Result_t Lookup(ui32_t frame_num, IndexTableSegment::IndexEntry&);
325         };
326
327     } // namespace MXF
328 } // namespace ASDCP
329
330
331 #endif // _MXF_H_
332
333 //
334 // end MXF.h
335 //