2 Copyright (c) 2005-2009, John Hurst
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
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.
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.
41 class InterchangeObject;
44 typedef ASDCP::MXF::InterchangeObject* (*MXFObjectFactory_t)(const Dictionary*&);
47 void SetObjectFactory(UL label, MXFObjectFactory_t factory);
50 InterchangeObject* CreateObject(const Dictionary*& Dict, const UL& label);
53 // seek an open file handle to the start of the RIP KLV packet
54 Result_t SeekToRIP(const Kumu::FileReader&);
57 class RIP : public ASDCP::KLVFilePacket
59 ASDCP_NO_COPY_CONSTRUCT(RIP);
64 class Pair : public Kumu::IArchive
70 Pair() : BodySID(0), ByteOffset(0) {}
71 Pair(ui32_t sid, ui64_t offset) : BodySID(sid), ByteOffset(offset) {}
74 ui32_t Size() { return sizeof(ui32_t) + sizeof(ui64_t); }
76 inline const char* EncodeString(char* str_buf, ui32_t buf_len) const {
77 Kumu::ui64Printer offset_str(ByteOffset);
78 snprintf(str_buf, buf_len, "%-6u: %s", BodySID, offset_str.c_str());
82 inline bool HasValue() const { return true; }
83 inline ui32_t ArchiveLength() const { return sizeof(ui32_t) + sizeof(ui64_t); }
85 inline bool Unarchive(Kumu::MemIOReader* Reader) {
86 if ( ! Reader->ReadUi32BE(&BodySID) ) return false;
87 if ( ! Reader->ReadUi64BE(&ByteOffset) ) return false;
91 inline bool Archive(Kumu::MemIOWriter* Writer) const {
92 if ( ! Writer->WriteUi32BE(BodySID) ) return false;
93 if ( ! Writer->WriteUi64BE(ByteOffset) ) return false;
98 const Dictionary*& m_Dict;
99 Array<Pair> PairArray;
101 RIP(const Dictionary*& d) : m_Dict(d) {}
103 virtual Result_t InitFromFile(const Kumu::FileReader& Reader);
104 virtual Result_t WriteToFile(Kumu::FileWriter& Writer);
105 virtual Result_t GetPairBySID(ui32_t, Pair&) const;
106 virtual void Dump(FILE* = 0);
111 class Partition : public ASDCP::KLVFilePacket
113 ASDCP_NO_COPY_CONSTRUCT(Partition);
118 mem_ptr<h__PacketList> m_PacketList;
121 const Dictionary*& m_Dict;
126 ui64_t ThisPartition;
127 ui64_t PreviousPartition;
128 ui64_t FooterPartition;
129 ui64_t HeaderByteCount;
130 ui64_t IndexByteCount;
134 UL OperationalPattern;
135 Batch<UL> EssenceContainers;
137 Partition(const Dictionary*&);
138 virtual ~Partition();
139 virtual void AddChildObject(InterchangeObject*);
140 virtual Result_t InitFromFile(const Kumu::FileReader& Reader);
141 virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l);
142 virtual Result_t WriteToFile(Kumu::FileWriter& Writer, UL& PartitionLabel);
143 virtual ui32_t ArchiveSize(); // returns the size of the archived structure
144 virtual void Dump(FILE* = 0);
149 class Primer : public ASDCP::KLVFilePacket, public ASDCP::IPrimerLookup
151 class h__PrimerLookup;
152 mem_ptr<h__PrimerLookup> m_Lookup;
154 ASDCP_NO_COPY_CONSTRUCT(Primer);
159 class LocalTagEntry : Kumu::IArchive
165 inline const char* EncodeString(char* str_buf, ui32_t buf_len) const {
166 snprintf(str_buf, buf_len, "%02x %02x: ", Tag.a, Tag.b);
167 UL.EncodeString(str_buf + strlen(str_buf), buf_len - strlen(str_buf));
171 inline bool HasValue() const { return UL.HasValue(); }
172 inline ui32_t ArchiveLength() const { return 2 + UL.ArchiveLength(); }
174 inline bool Unarchive(Kumu::MemIOReader* Reader) {
175 if ( ! Reader->ReadUi8(&Tag.a) ) return false;
176 if ( ! Reader->ReadUi8(&Tag.b) ) return false;
177 return UL.Unarchive(Reader);
180 inline bool Archive(Kumu::MemIOWriter* Writer) const {
181 if ( ! Writer->WriteUi8(Tag.a) ) return false;
182 if ( ! Writer->WriteUi8(Tag.b) ) return false;
183 return UL.Archive(Writer);
187 Batch<LocalTagEntry> LocalTagEntryBatch;
188 const Dictionary*& m_Dict;
190 Primer(const Dictionary*&);
193 virtual void ClearTagList();
194 virtual Result_t InsertTag(const MDDEntry& Entry, ASDCP::TagValue& Tag);
195 virtual Result_t TagForKey(const ASDCP::UL& Key, ASDCP::TagValue& Tag);
197 virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l);
198 virtual Result_t WriteToBuffer(ASDCP::FrameBuffer&);
199 virtual Result_t WriteToFile(Kumu::FileWriter& Writer);
200 virtual void Dump(FILE* = 0);
205 class InterchangeObject : public ASDCP::KLVPacket
210 const MDDEntry* m_Typeinfo;
213 const Dictionary*& m_Dict;
214 IPrimerLookup* m_Lookup;
218 InterchangeObject(const Dictionary*& d) : m_Typeinfo(0), m_Dict(d), m_Lookup(0) {}
219 virtual ~InterchangeObject() {}
220 virtual Result_t InitFromTLVSet(TLVReader& TLVSet);
221 virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l);
222 virtual Result_t WriteToTLVSet(TLVWriter& TLVSet);
223 virtual Result_t WriteToBuffer(ASDCP::FrameBuffer&);
224 virtual bool IsA(const byte_t* label);
225 virtual const char* ObjectName() { return "InterchangeObject"; }
226 virtual void Dump(FILE* stream = 0);
230 class Preface : public InterchangeObject
232 ASDCP_NO_COPY_CONSTRUCT(Preface);
236 const Dictionary*& m_Dict;
238 Timestamp LastModifiedDate;
240 ui32_t ObjectModelVersion;
242 Batch<UUID> Identifications;
244 UL OperationalPattern;
245 Batch<UL> EssenceContainers;
248 Preface(const Dictionary*& d) : InterchangeObject(d), m_Dict(d), Version(258), ObjectModelVersion(0) {}
249 virtual ~Preface() {}
250 virtual Result_t InitFromTLVSet(TLVReader& TLVSet);
251 virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l);
252 virtual Result_t WriteToTLVSet(TLVWriter& TLVSet);
253 virtual Result_t WriteToBuffer(ASDCP::FrameBuffer&);
254 virtual void Dump(FILE* = 0);
257 const ui32_t MaxIndexSegmentSize = 65536;
260 class IndexTableSegment : public InterchangeObject
262 ASDCP_NO_COPY_CONSTRUCT(IndexTableSegment);
266 class DeltaEntry : public Kumu::IArchive
273 DeltaEntry() : PosTableIndex(-1), Slice(0), ElementData(0) {}
274 inline bool HasValue() const { return true; }
275 ui32_t ArchiveLength() const { return sizeof(ui32_t) + 2; }
276 bool Unarchive(Kumu::MemIOReader* Reader);
277 bool Archive(Kumu::MemIOWriter* Writer) const;
278 const char* EncodeString(char* str_buf, ui32_t buf_len) const;
282 class IndexEntry : public Kumu::IArchive
290 // if you use these, you will need to change CBRIndexEntriesPerSegment in MXF.cpp
291 // to a more suitable value
292 // std::list<ui32_t> SliceOffset;
293 // Array<Rational> PosTable;
295 IndexEntry() : TemporalOffset(0), KeyFrameOffset(0), Flags(0), StreamOffset() {}
296 inline bool HasValue() const { return true; }
297 ui32_t ArchiveLength() const { return sizeof(ui64_t) + 3; };
298 bool Unarchive(Kumu::MemIOReader* Reader);
299 bool Archive(Kumu::MemIOWriter* Writer) const;
300 const char* EncodeString(char* str_buf, ui32_t buf_len) const;
303 const Dictionary*& m_Dict;
305 Rational IndexEditRate;
306 ui64_t IndexStartPosition;
307 ui64_t IndexDuration;
308 ui32_t EditUnitByteCount;
313 Batch<DeltaEntry> DeltaEntryArray;
314 Batch<IndexEntry> IndexEntryArray;
316 IndexTableSegment(const Dictionary*&);
317 virtual ~IndexTableSegment();
318 virtual Result_t InitFromTLVSet(TLVReader& TLVSet);
319 virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l);
320 virtual Result_t WriteToTLVSet(TLVWriter& TLVSet);
321 virtual Result_t WriteToBuffer(ASDCP::FrameBuffer&);
322 virtual void Dump(FILE* = 0);
325 //---------------------------------------------------------------------------------
327 class Identification;
331 class OPAtomHeader : public Partition
333 ASDCP_NO_COPY_CONSTRUCT(OPAtomHeader);
337 const Dictionary*& m_Dict;
338 ASDCP::MXF::RIP m_RIP;
339 ASDCP::MXF::Primer m_Primer;
341 ASDCP::FrameBuffer m_Buffer;
344 OPAtomHeader(const Dictionary*&);
345 virtual ~OPAtomHeader();
346 virtual Result_t InitFromFile(const Kumu::FileReader& Reader);
347 virtual Result_t InitFromPartitionBuffer(const byte_t* p, ui32_t l);
348 virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l);
349 virtual Result_t WriteToFile(Kumu::FileWriter& Writer, ui32_t HeaderLength = 16384);
350 virtual void Dump(FILE* = 0);
351 virtual Result_t GetMDObjectByID(const UUID&, InterchangeObject** = 0);
352 virtual Result_t GetMDObjectByType(const byte_t*, InterchangeObject** = 0);
353 virtual Result_t GetMDObjectsByType(const byte_t* ObjectID, std::list<InterchangeObject*>& ObjectList);
354 Identification* GetIdentification();
355 SourcePackage* GetSourcePackage();
359 class OPAtomIndexFooter : public Partition
361 IndexTableSegment* m_CurrentSegment;
362 ASDCP::FrameBuffer m_Buffer;
363 ui32_t m_BytesPerEditUnit;
366 ASDCP_NO_COPY_CONSTRUCT(OPAtomIndexFooter);
369 const Dictionary*& m_Dict;
370 Kumu::fpos_t m_ECOffset;
371 IPrimerLookup* m_Lookup;
373 OPAtomIndexFooter(const Dictionary*&);
374 virtual ~OPAtomIndexFooter();
375 virtual Result_t InitFromFile(const Kumu::FileReader& Reader);
376 virtual Result_t InitFromPartitionBuffer(const byte_t* p, ui32_t l);
377 virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l);
378 virtual Result_t WriteToFile(Kumu::FileWriter& Writer, ui64_t duration);
379 virtual void Dump(FILE* = 0);
381 virtual Result_t Lookup(ui32_t frame_num, IndexTableSegment::IndexEntry&) const;
382 virtual void PushIndexEntry(const IndexTableSegment::IndexEntry&);
383 virtual void SetIndexParamsCBR(IPrimerLookup* lookup, ui32_t size, const Rational& Rate);
384 virtual void SetIndexParamsVBR(IPrimerLookup* lookup, const Rational& Rate, Kumu::fpos_t offset);