-//
-//
-//
+/*
+Copyright (c) 2005-2009, John Hurst
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*! \file MXF.h
+ \version $Id$
+ \brief MXF objects
+*/
#ifndef _MXF_H_
#define _MXF_H_
{
namespace MXF
{
+ class InterchangeObject;
+
+ //
+ typedef ASDCP::MXF::InterchangeObject* (*MXFObjectFactory_t)(const Dictionary*&);
+
+ //
+ void SetObjectFactory(UL label, MXFObjectFactory_t factory);
+
+ //
+ InterchangeObject* CreateObject(const Dictionary*& Dict, const UL& label);
+
+
// seek an open file handle to the start of the RIP KLV packet
- Result_t SeekToRIP(const FileReader&);
+ Result_t SeekToRIP(const Kumu::FileReader&);
//
class RIP : public ASDCP::KLVFilePacket
{
ASDCP_NO_COPY_CONSTRUCT(RIP);
+ RIP();
public:
//
- class Pair {
- public:
- ui32_t BodySID;
- ui64_t ByteOffset;
-
- ui32_t Size() { return sizeof(ui32_t) + sizeof(ui64_t); }
-
- inline const char* ToString(char* str_buf) const {
- char intbuf[IntBufferLen];
- sprintf(str_buf, "%-6lu: %s", BodySID, ui64sz(ByteOffset, intbuf));
- return str_buf;
- }
-
- inline Result_t ReadFrom(ASDCP::MemIOReader& Reader) {
- Result_t result = Reader.ReadUi32BE(&BodySID);
+ class Pair : public Kumu::IArchive
+ {
+ public:
+ ui32_t BodySID;
+ ui64_t ByteOffset;
- if ( ASDCP_SUCCESS(result) )
- result = Reader.ReadUi64BE(&ByteOffset);
+ Pair() : BodySID(0), ByteOffset(0) {}
+ Pair(ui32_t sid, ui64_t offset) : BodySID(sid), ByteOffset(offset) {}
+ virtual ~Pair() {}
- return result;
- }
+ ui32_t Size() { return sizeof(ui32_t) + sizeof(ui64_t); }
- inline Result_t WriteTo(ASDCP::MemIOWriter& Writer) {
- Result_t result = Writer.WriteUi32BE(BodySID);
+ inline const char* EncodeString(char* str_buf, ui32_t buf_len) const {
+ Kumu::ui64Printer offset_str(ByteOffset);
+ snprintf(str_buf, buf_len, "%-6u: %s", BodySID, offset_str.c_str());
+ return str_buf;
+ }
- if ( ASDCP_SUCCESS(result) )
- result = Writer.WriteUi64BE(ByteOffset);
+ inline bool HasValue() const { return true; }
+ inline ui32_t ArchiveLength() const { return sizeof(ui32_t) + sizeof(ui64_t); }
- return result;
- }
- };
+ inline bool Unarchive(Kumu::MemIOReader* Reader) {
+ if ( ! Reader->ReadUi32BE(&BodySID) ) return false;
+ if ( ! Reader->ReadUi64BE(&ByteOffset) ) return false;
+ return true;
+ }
+
+ inline bool Archive(Kumu::MemIOWriter* Writer) const {
+ if ( ! Writer->WriteUi32BE(BodySID) ) return false;
+ if ( ! Writer->WriteUi64BE(ByteOffset) ) return false;
+ return true;
+ }
+ };
+ const Dictionary*& m_Dict;
Array<Pair> PairArray;
- RIP() {}
+ RIP(const Dictionary*& d) : m_Dict(d) {}
virtual ~RIP() {}
- virtual Result_t InitFromFile(const ASDCP::FileReader& Reader);
- virtual Result_t WriteToFile(ASDCP::FileWriter& Writer);
+ virtual Result_t InitFromFile(const Kumu::FileReader& Reader);
+ virtual Result_t WriteToFile(Kumu::FileWriter& Writer);
+ virtual Result_t GetPairBySID(ui32_t, Pair&) const;
virtual void Dump(FILE* = 0);
};
//
class Partition : public ASDCP::KLVFilePacket
- {
+ {
ASDCP_NO_COPY_CONSTRUCT(Partition);
+ Partition();
+
+ protected:
+ class h__PacketList;
+ mem_ptr<h__PacketList> m_PacketList;
public:
+ const Dictionary*& m_Dict;
+
ui16_t MajorVersion;
ui16_t MinorVersion;
ui32_t KAGSize;
UL OperationalPattern;
Batch<UL> EssenceContainers;
- Partition() {}
- virtual ~Partition() {}
- virtual Result_t InitFromFile(const ASDCP::FileReader& Reader);
- virtual Result_t WriteToFile(ASDCP::FileWriter& Writer);
+ Partition(const Dictionary*&);
+ virtual ~Partition();
+ virtual void AddChildObject(InterchangeObject*);
+ virtual Result_t InitFromFile(const Kumu::FileReader& Reader);
+ virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l);
+ virtual Result_t WriteToFile(Kumu::FileWriter& Writer, UL& PartitionLabel);
+ virtual ui32_t ArchiveSize(); // returns the size of the archived structure
virtual void Dump(FILE* = 0);
};
//
- class Primer : public ASDCP::KLVPacket, public ASDCP::IPrimerLookup
+ class Primer : public ASDCP::KLVFilePacket, public ASDCP::IPrimerLookup
{
class h__PrimerLookup;
mem_ptr<h__PrimerLookup> m_Lookup;
+ ui8_t m_LocalTag;
ASDCP_NO_COPY_CONSTRUCT(Primer);
+ Primer();
public:
//
- class LocalTagEntry
+ class LocalTagEntry : Kumu::IArchive
{
public:
TagValue Tag;
ASDCP::UL UL;
- inline const char* ToString(char* str_buf) const {
- sprintf(str_buf, "%02x %02x: ", Tag.a, Tag.b);
- UL.ToString(str_buf + strlen(str_buf));
+ inline const char* EncodeString(char* str_buf, ui32_t buf_len) const {
+ snprintf(str_buf, buf_len, "%02x %02x: ", Tag.a, Tag.b);
+ UL.EncodeString(str_buf + strlen(str_buf), buf_len - strlen(str_buf));
return str_buf;
}
- inline Result_t ReadFrom(ASDCP::MemIOReader& Reader) {
- Result_t result = Reader.ReadUi8(&Tag.a);
-
- if ( ASDCP_SUCCESS(result) )
- result = Reader.ReadUi8(&Tag.b);
-
- if ( ASDCP_SUCCESS(result) )
- result = UL.ReadFrom(Reader);
+ inline bool HasValue() const { return UL.HasValue(); }
+ inline ui32_t ArchiveLength() const { return 2 + UL.ArchiveLength(); }
- return result;
+ inline bool Unarchive(Kumu::MemIOReader* Reader) {
+ if ( ! Reader->ReadUi8(&Tag.a) ) return false;
+ if ( ! Reader->ReadUi8(&Tag.b) ) return false;
+ return UL.Unarchive(Reader);
}
- inline Result_t WriteTo(ASDCP::MemIOWriter& Writer) {
- Result_t result = Writer.WriteUi8(Tag.a);
-
- if ( ASDCP_SUCCESS(result) )
- result = Writer.WriteUi8(Tag.b);
-
- if ( ASDCP_SUCCESS(result) )
- result = UL.WriteTo(Writer);
-
- return result;
+ inline bool Archive(Kumu::MemIOWriter* Writer) const {
+ if ( ! Writer->WriteUi8(Tag.a) ) return false;
+ if ( ! Writer->WriteUi8(Tag.b) ) return false;
+ return UL.Archive(Writer);
}
};
Batch<LocalTagEntry> LocalTagEntryBatch;
+ const Dictionary*& m_Dict;
- Primer();
+ Primer(const Dictionary*&);
virtual ~Primer();
virtual void ClearTagList();
- virtual Result_t InsertTag(const ASDCP::UL& Key, ASDCP::TagValue& Tag);
+ virtual Result_t InsertTag(const MDDEntry& Entry, ASDCP::TagValue& Tag);
virtual Result_t TagForKey(const ASDCP::UL& Key, ASDCP::TagValue& Tag);
virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l);
virtual Result_t WriteToBuffer(ASDCP::FrameBuffer&);
+ virtual Result_t WriteToFile(Kumu::FileWriter& Writer);
virtual void Dump(FILE* = 0);
};
//
class InterchangeObject : public ASDCP::KLVPacket
{
+ InterchangeObject();
+
+ protected:
+ const MDDEntry* m_Typeinfo;
+
public:
+ const Dictionary*& m_Dict;
IPrimerLookup* m_Lookup;
- UID InstanceUID;
+ UUID InstanceUID;
+ UUID GenerationUID;
- InterchangeObject() : m_Lookup(0) {}
+ InterchangeObject(const Dictionary*& d) : m_Typeinfo(0), m_Dict(d), m_Lookup(0) {}
virtual ~InterchangeObject() {}
+ virtual Result_t InitFromTLVSet(TLVReader& TLVSet);
+ virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l);
+ virtual Result_t WriteToTLVSet(TLVWriter& TLVSet);
virtual Result_t WriteToBuffer(ASDCP::FrameBuffer&);
virtual bool IsA(const byte_t* label);
-
- virtual void Dump(FILE* stream = 0) {
- KLVPacket::Dump(stream, true);
- }
+ virtual const char* ObjectName() { return "InterchangeObject"; }
+ virtual void Dump(FILE* stream = 0);
};
- //
- InterchangeObject* CreateObject(const byte_t* label);
-
-
//
class Preface : public InterchangeObject
{
ASDCP_NO_COPY_CONSTRUCT(Preface);
+ Preface();
public:
+ const Dictionary*& m_Dict;
UUID GenerationUID;
Timestamp LastModifiedDate;
ui16_t Version;
ui32_t ObjectModelVersion;
- UID PrimaryPackage;
- Batch<UID> Identifications;
- UID ContentStorage;
+ UUID PrimaryPackage;
+ Batch<UUID> Identifications;
+ UUID ContentStorage;
UL OperationalPattern;
Batch<UL> EssenceContainers;
Batch<UL> DMSchemes;
- Preface() {}
+ Preface(const Dictionary*& d) : InterchangeObject(d), m_Dict(d), Version(258), ObjectModelVersion(0) {}
virtual ~Preface() {}
- virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l);
- virtual Result_t WriteToBuffer(ASDCP::FrameBuffer& Buffer);
+ virtual Result_t InitFromTLVSet(TLVReader& TLVSet);
+ virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l);
+ virtual Result_t WriteToTLVSet(TLVWriter& TLVSet);
+ virtual Result_t WriteToBuffer(ASDCP::FrameBuffer&);
virtual void Dump(FILE* = 0);
};
+ const ui32_t MaxIndexSegmentSize = 65536;
+
//
class IndexTableSegment : public InterchangeObject
{
public:
//
- class DeltaEntry
+ class DeltaEntry : public Kumu::IArchive
{
public:
i8_t PosTableIndex;
ui8_t Slice;
ui32_t ElementData;
- Result_t ReadFrom(ASDCP::MemIOReader& Reader);
- Result_t WriteTo(ASDCP::MemIOWriter& Writer);
- inline const char* ToString(char* str_buf) const;
+ DeltaEntry() : PosTableIndex(-1), Slice(0), ElementData(0) {}
+ inline bool HasValue() const { return true; }
+ ui32_t ArchiveLength() const { return sizeof(ui32_t) + 2; }
+ bool Unarchive(Kumu::MemIOReader* Reader);
+ bool Archive(Kumu::MemIOWriter* Writer) const;
+ const char* EncodeString(char* str_buf, ui32_t buf_len) const;
};
//
- class IndexEntry
+ class IndexEntry : public Kumu::IArchive
{
public:
i8_t TemporalOffset;
i8_t KeyFrameOffset;
ui8_t Flags;
ui64_t StreamOffset;
- std::list<ui32_t> SliceOffset;
- Array<Rational> PosTable;
- Result_t ReadFrom(ASDCP::MemIOReader& Reader);
- Result_t WriteTo(ASDCP::MemIOWriter& Writer);
- inline const char* ToString(char* str_buf) const;
+ // if you use these, you will need to change CBRIndexEntriesPerSegment in MXF.cpp
+ // to a more suitable value
+ // std::list<ui32_t> SliceOffset;
+ // Array<Rational> PosTable;
+
+ IndexEntry() : TemporalOffset(0), KeyFrameOffset(0), Flags(0), StreamOffset() {}
+ inline bool HasValue() const { return true; }
+ ui32_t ArchiveLength() const { return sizeof(ui64_t) + 3; };
+ bool Unarchive(Kumu::MemIOReader* Reader);
+ bool Archive(Kumu::MemIOWriter* Writer) const;
+ const char* EncodeString(char* str_buf, ui32_t buf_len) const;
};
+ const Dictionary*& m_Dict;
+
Rational IndexEditRate;
ui64_t IndexStartPosition;
ui64_t IndexDuration;
Batch<DeltaEntry> DeltaEntryArray;
Batch<IndexEntry> IndexEntryArray;
- IndexTableSegment();
+ IndexTableSegment(const Dictionary*&);
virtual ~IndexTableSegment();
+ virtual Result_t InitFromTLVSet(TLVReader& TLVSet);
virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l);
- virtual Result_t WriteToBuffer(ASDCP::FrameBuffer& Buffer);
+ virtual Result_t WriteToTLVSet(TLVWriter& TLVSet);
+ virtual Result_t WriteToBuffer(ASDCP::FrameBuffer&);
virtual void Dump(FILE* = 0);
};
//---------------------------------------------------------------------------------
//
- class h__PacketList; // See MXF.cpp
class Identification;
+ class SourcePackage;
//
class OPAtomHeader : public Partition
{
- mem_ptr<h__PacketList> m_PacketList;
ASDCP_NO_COPY_CONSTRUCT(OPAtomHeader);
+ OPAtomHeader();
public:
- ASDCP::MXF::RIP m_RIP;
- ASDCP::MXF::Primer m_Primer;
- InterchangeObject* m_Preface;
- ASDCP::FrameBuffer m_Buffer;
- bool m_HasRIP;
-
- OPAtomHeader();
+ const Dictionary*& m_Dict;
+ ASDCP::MXF::RIP m_RIP;
+ ASDCP::MXF::Primer m_Primer;
+ Preface* m_Preface;
+ ASDCP::FrameBuffer m_Buffer;
+ bool m_HasRIP;
+
+ OPAtomHeader(const Dictionary*&);
virtual ~OPAtomHeader();
- virtual Result_t InitFromFile(const ASDCP::FileReader& Reader);
- virtual Result_t WriteToFile(ASDCP::FileWriter& Writer, ui32_t HeaderLength = 16384);
+ virtual Result_t InitFromFile(const Kumu::FileReader& Reader);
+ virtual Result_t InitFromPartitionBuffer(const byte_t* p, ui32_t l);
+ virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l);
+ virtual Result_t WriteToFile(Kumu::FileWriter& Writer, ui32_t HeaderLength = 16384);
virtual void Dump(FILE* = 0);
+ virtual Result_t GetMDObjectByID(const UUID&, InterchangeObject** = 0);
virtual Result_t GetMDObjectByType(const byte_t*, InterchangeObject** = 0);
- Identification* GetIdentification();
+ virtual Result_t GetMDObjectsByType(const byte_t* ObjectID, std::list<InterchangeObject*>& ObjectList);
+ Identification* GetIdentification();
+ SourcePackage* GetSourcePackage();
};
//
class OPAtomIndexFooter : public Partition
{
- mem_ptr<h__PacketList> m_PacketList;
- ASDCP::FrameBuffer m_Buffer;
+ IndexTableSegment* m_CurrentSegment;
+ ASDCP::FrameBuffer m_Buffer;
+ ui32_t m_BytesPerEditUnit;
+ Rational m_EditRate;
+ ui32_t m_BodySID;
ASDCP_NO_COPY_CONSTRUCT(OPAtomIndexFooter);
public:
- IPrimerLookup* m_Lookup;
+ const Dictionary*& m_Dict;
+ Kumu::fpos_t m_ECOffset;
+ IPrimerLookup* m_Lookup;
- OPAtomIndexFooter();
+ OPAtomIndexFooter(const Dictionary*&);
virtual ~OPAtomIndexFooter();
- virtual Result_t InitFromFile(const ASDCP::FileReader& Reader);
- virtual Result_t WriteToFile(ASDCP::FileWriter& Writer);
+ virtual Result_t InitFromFile(const Kumu::FileReader& Reader);
+ virtual Result_t InitFromPartitionBuffer(const byte_t* p, ui32_t l);
+ virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l);
+ virtual Result_t WriteToFile(Kumu::FileWriter& Writer, ui64_t duration);
virtual void Dump(FILE* = 0);
- virtual Result_t Lookup(ui32_t frame_num, IndexTableSegment::IndexEntry&);
+ virtual Result_t Lookup(ui32_t frame_num, IndexTableSegment::IndexEntry&) const;
+ virtual void PushIndexEntry(const IndexTableSegment::IndexEntry&);
+ virtual void SetIndexParamsCBR(IPrimerLookup* lookup, ui32_t size, const Rational& Rate);
+ virtual void SetIndexParamsVBR(IPrimerLookup* lookup, const Rational& Rate, Kumu::fpos_t offset);
};
} // namespace MXF