2 Copyright (c) 2005-2006, 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)();
47 void SetObjectFactory(UL label, MXFObjectFactory_t factory);
50 InterchangeObject* CreateObject(const byte_t* 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);
63 class Pair : public Kumu::IArchive
69 Pair() : BodySID(0), ByteOffset(0) {}
70 Pair(ui32_t sid, ui64_t offset) : BodySID(sid), ByteOffset(offset) {}
73 ui32_t Size() { return sizeof(ui32_t) + sizeof(ui64_t); }
75 inline const char* EncodeString(char* str_buf, ui32_t buf_len) const {
76 Kumu::ui64Printer offset_str(ByteOffset);
77 snprintf(str_buf, buf_len, "%-6u: %s", BodySID, offset_str.c_str());
81 inline bool HasValue() const { return true; }
82 inline ui32_t ArchiveLength() const { return sizeof(ui32_t) + sizeof(ui64_t); }
84 inline bool Unarchive(Kumu::MemIOReader* Reader) {
85 if ( ! Reader->ReadUi32BE(&BodySID) ) return false;
86 if ( ! Reader->ReadUi64BE(&ByteOffset) ) return false;
90 inline bool Archive(Kumu::MemIOWriter* Writer) const {
91 if ( ! Writer->WriteUi32BE(BodySID) ) return false;
92 if ( ! Writer->WriteUi64BE(ByteOffset) ) return false;
97 Array<Pair> PairArray;
101 virtual Result_t InitFromFile(const Kumu::FileReader& Reader);
102 virtual Result_t WriteToFile(Kumu::FileWriter& Writer);
103 virtual Result_t GetPairBySID(ui32_t, Pair&) const;
104 virtual void Dump(FILE* = 0);
109 class Partition : public ASDCP::KLVFilePacket
111 ASDCP_NO_COPY_CONSTRUCT(Partition);
115 mem_ptr<h__PacketList> m_PacketList;
121 ui64_t ThisPartition;
122 ui64_t PreviousPartition;
123 ui64_t FooterPartition;
124 ui64_t HeaderByteCount;
125 ui64_t IndexByteCount;
129 UL OperationalPattern;
130 Batch<UL> EssenceContainers;
133 virtual ~Partition();
134 virtual void AddChildObject(InterchangeObject*);
135 virtual Result_t InitFromFile(const Kumu::FileReader& Reader);
136 virtual Result_t WriteToFile(Kumu::FileWriter& Writer, UL& PartitionLabel);
137 virtual ui32_t ArchiveSize(); // returns the size of the archived structure
138 virtual void Dump(FILE* = 0);
143 class Primer : public ASDCP::KLVFilePacket, public ASDCP::IPrimerLookup
145 class h__PrimerLookup;
146 mem_ptr<h__PrimerLookup> m_Lookup;
148 ASDCP_NO_COPY_CONSTRUCT(Primer);
152 class LocalTagEntry : Kumu::IArchive
158 inline const char* EncodeString(char* str_buf, ui32_t buf_len) const {
159 snprintf(str_buf, buf_len, "%02x %02x: ", Tag.a, Tag.b);
160 UL.EncodeString(str_buf + strlen(str_buf), buf_len - strlen(str_buf));
164 inline bool HasValue() const { return UL.HasValue(); }
165 inline ui32_t ArchiveLength() const { return 2 + UL.ArchiveLength(); }
167 inline bool Unarchive(Kumu::MemIOReader* Reader) {
168 if ( ! Reader->ReadUi8(&Tag.a) ) return false;
169 if ( ! Reader->ReadUi8(&Tag.b) ) return false;
170 return UL.Unarchive(Reader);
173 inline bool Archive(Kumu::MemIOWriter* Writer) const {
174 if ( ! Writer->WriteUi8(Tag.a) ) return false;
175 if ( ! Writer->WriteUi8(Tag.b) ) return false;
176 return UL.Archive(Writer);
180 Batch<LocalTagEntry> LocalTagEntryBatch;
185 virtual void ClearTagList();
186 virtual Result_t InsertTag(const MDDEntry& Entry, ASDCP::TagValue& Tag);
187 virtual Result_t TagForKey(const ASDCP::UL& Key, ASDCP::TagValue& Tag);
189 virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l);
190 virtual Result_t WriteToBuffer(ASDCP::FrameBuffer&);
191 virtual Result_t WriteToFile(Kumu::FileWriter& Writer);
192 virtual void Dump(FILE* = 0);
197 class InterchangeObject : public ASDCP::KLVPacket
200 const MDDEntry* m_Typeinfo;
203 IPrimerLookup* m_Lookup;
207 InterchangeObject() : m_Typeinfo(0), m_Lookup(0) {}
208 virtual ~InterchangeObject() {}
209 virtual Result_t InitFromTLVSet(TLVReader& TLVSet);
210 virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l);
211 virtual Result_t WriteToTLVSet(TLVWriter& TLVSet);
212 virtual Result_t WriteToBuffer(ASDCP::FrameBuffer&);
213 virtual bool IsA(const byte_t* label);
214 virtual const char* ObjectName() { return "InterchangeObject"; }
215 virtual void Dump(FILE* stream = 0);
219 class Preface : public InterchangeObject
221 ASDCP_NO_COPY_CONSTRUCT(Preface);
225 Timestamp LastModifiedDate;
227 ui32_t ObjectModelVersion;
229 Batch<UUID> Identifications;
231 UL OperationalPattern;
232 Batch<UL> EssenceContainers;
235 Preface() : Version(258), ObjectModelVersion(0) {}
236 virtual ~Preface() {}
237 virtual Result_t InitFromTLVSet(TLVReader& TLVSet);
238 virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l);
239 virtual Result_t WriteToTLVSet(TLVWriter& TLVSet);
240 virtual Result_t WriteToBuffer(ASDCP::FrameBuffer&);
241 virtual void Dump(FILE* = 0);
244 const ui32_t MaxIndexSegmentSize = 65536;
247 class IndexTableSegment : public InterchangeObject
249 ASDCP_NO_COPY_CONSTRUCT(IndexTableSegment);
253 class DeltaEntry : public Kumu::IArchive
260 DeltaEntry() : PosTableIndex(-1), Slice(0), ElementData(0) {}
261 inline bool HasValue() const { return true; }
262 ui32_t ArchiveLength() const { return sizeof(ui32_t) + 2; }
263 bool Unarchive(Kumu::MemIOReader* Reader);
264 bool Archive(Kumu::MemIOWriter* Writer) const;
265 const char* EncodeString(char* str_buf, ui32_t buf_len) const;
269 class IndexEntry : public Kumu::IArchive
277 // if you use these, you will need to change CBRIndexEntriesPerSegment in MXF.cpp
278 // to a more suitable value
279 // std::list<ui32_t> SliceOffset;
280 // Array<Rational> PosTable;
282 IndexEntry() : TemporalOffset(0), KeyFrameOffset(0), Flags(0), StreamOffset() {}
283 inline bool HasValue() const { return true; }
284 ui32_t ArchiveLength() const { return sizeof(ui64_t) + 3; };
285 bool Unarchive(Kumu::MemIOReader* Reader);
286 bool Archive(Kumu::MemIOWriter* Writer) const;
287 const char* EncodeString(char* str_buf, ui32_t buf_len) const;
290 Rational IndexEditRate;
291 ui64_t IndexStartPosition;
292 ui64_t IndexDuration;
293 ui32_t EditUnitByteCount;
298 Batch<DeltaEntry> DeltaEntryArray;
299 Batch<IndexEntry> IndexEntryArray;
302 virtual ~IndexTableSegment();
303 virtual Result_t InitFromTLVSet(TLVReader& TLVSet);
304 virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l);
305 virtual Result_t WriteToTLVSet(TLVWriter& TLVSet);
306 virtual Result_t WriteToBuffer(ASDCP::FrameBuffer&);
307 virtual void Dump(FILE* = 0);
310 //---------------------------------------------------------------------------------
312 class Identification;
316 class OPAtomHeader : public Partition
318 ASDCP_NO_COPY_CONSTRUCT(OPAtomHeader);
321 ASDCP::MXF::RIP m_RIP;
322 ASDCP::MXF::Primer m_Primer;
324 ASDCP::FrameBuffer m_Buffer;
328 virtual ~OPAtomHeader();
329 virtual Result_t InitFromFile(const Kumu::FileReader& Reader);
330 virtual Result_t WriteToFile(Kumu::FileWriter& Writer, ui32_t HeaderLength = 16384);
331 virtual void Dump(FILE* = 0);
332 virtual Result_t GetMDObjectByID(const UUID&, InterchangeObject** = 0);
333 virtual Result_t GetMDObjectByType(const byte_t*, InterchangeObject** = 0);
334 virtual Result_t GetMDObjectsByType(const byte_t* ObjectID, std::list<InterchangeObject*>& ObjectList);
335 Identification* GetIdentification();
336 SourcePackage* GetSourcePackage();
340 class OPAtomIndexFooter : public Partition
342 IndexTableSegment* m_CurrentSegment;
343 ASDCP::FrameBuffer m_Buffer;
344 ui32_t m_BytesPerEditUnit;
347 ASDCP_NO_COPY_CONSTRUCT(OPAtomIndexFooter);
350 Kumu::fpos_t m_ECOffset;
351 IPrimerLookup* m_Lookup;
354 virtual ~OPAtomIndexFooter();
355 virtual Result_t InitFromFile(const Kumu::FileReader& Reader);
356 virtual Result_t WriteToFile(Kumu::FileWriter& Writer, ui64_t duration);
357 virtual void Dump(FILE* = 0);
359 virtual Result_t Lookup(ui32_t frame_num, IndexTableSegment::IndexEntry&) const;
360 virtual void PushIndexEntry(const IndexTableSegment::IndexEntry&);
361 virtual void SetIndexParamsCBR(IPrimerLookup* lookup, ui32_t size, const Rational& Rate);
362 virtual void SetIndexParamsVBR(IPrimerLookup* lookup, const Rational& Rate, Kumu::fpos_t offset);