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