/*
-Copyright (c) 2005-2006, John Hurst
+Copyright (c) 2005-2009, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
*/
#include "MXF.h"
+#include "Metadata.h"
#include <KM_log.h>
+
using Kumu::DefaultLogSink;
+using Kumu::GenRandomValue;
+
+// index segments must be < 64K
+// NOTE: this value may too high if advanced index entry elements are used.
+const ui32_t CBRIndexEntriesPerSegment = 5000;
//------------------------------------------------------------------------------------------
//
return result;
}
+//
+ASDCP::Result_t
+ASDCP::MXF::RIP::GetPairBySID(ui32_t SID, Pair& outPair) const
+{
+ Array<Pair>::const_iterator pi = PairArray.begin();
+ for ( ; pi != PairArray.end(); pi++ )
+ {
+ if ( (*pi).BodySID == SID )
+ {
+ outPair = *pi;
+ return RESULT_OK;
+ }
+ }
+
+ return RESULT_FAIL;
+}
+
//
ASDCP::Result_t
ASDCP::MXF::RIP::InitFromFile(const Kumu::FileReader& Reader)
{
- Result_t result = KLVFilePacket::InitFromFile(Reader, Dict::ul(MDD_RandomIndexMetadata));
+ assert(m_Dict);
+ Result_t result = KLVFilePacket::InitFromFile(Reader, m_Dict->ul(MDD_RandomIndexMetadata));
if ( ASDCP_SUCCESS(result) )
{
ASDCP::Result_t
ASDCP::MXF::RIP::WriteToFile(Kumu::FileWriter& Writer)
{
+ assert(m_Dict);
ASDCP::FrameBuffer Buffer;
ui32_t RIPSize = ( PairArray.size() * (sizeof(ui32_t) + sizeof(ui64_t)) ) + 4;
Result_t result = Buffer.Capacity(RIPSize);
if ( ASDCP_SUCCESS(result) )
- result = WriteKLToFile(Writer, Dict::ul(MDD_RandomIndexMetadata), RIPSize);
+ result = WriteKLToFile(Writer, m_Dict->ul(MDD_RandomIndexMetadata), RIPSize);
if ( ASDCP_SUCCESS(result) )
{
if ( stream == 0 )
stream = stderr;
- KLVFilePacket::Dump(stream, false);
+ KLVFilePacket::Dump(stream, *m_Dict, false);
PairArray.Dump(stream, false);
-
- fputs("==========================================================================\n", stream);
}
//------------------------------------------------------------------------------------------
m_List.push_back(ThePacket);
}
+ //
+ Result_t GetMDObjectByID(const UUID& ObjectID, InterchangeObject** Object)
+ {
+ ASDCP_TEST_NULL(Object);
+
+ std::map<UUID, InterchangeObject*>::iterator mi = m_Map.find(ObjectID);
+
+ if ( mi == m_Map.end() )
+ {
+ *Object = 0;
+ return RESULT_FAIL;
+ }
+
+ *Object = (*mi).second;
+ return RESULT_OK;
+ }
+
//
Result_t GetMDObjectByType(const byte_t* ObjectID, InterchangeObject** Object)
{
return RESULT_FAIL;
}
+
+ //
+ Result_t GetMDObjectsByType(const byte_t* ObjectID, std::list<InterchangeObject*>& ObjectList)
+ {
+ ASDCP_TEST_NULL(ObjectID);
+ std::list<InterchangeObject*>::iterator li;
+
+ for ( li = m_List.begin(); li != m_List.end(); li++ )
+ {
+ if ( (*li)->HasUL(ObjectID) )
+ ObjectList.push_back(*li);
+ }
+
+ return ObjectList.empty() ? RESULT_FAIL : RESULT_OK;
+ }
};
//------------------------------------------------------------------------------------------
//
-ASDCP::MXF::Partition::Partition() :
+ASDCP::MXF::Partition::Partition(const Dictionary*& d) :
+ m_Dict(d),
MajorVersion(1), MinorVersion(2),
KAGSize(1), ThisPartition(0), PreviousPartition(0),
FooterPartition(0), HeaderByteCount(0), IndexByteCount(0), IndexSID(0),
ASDCP::MXF::Partition::AddChildObject(InterchangeObject* Object)
{
assert(Object);
- UUID TmpID;
- Kumu::GenRandomValue(TmpID);
- Object->InstanceUID = TmpID;
+
+ if ( ! Object->InstanceUID.HasValue() )
+ GenRandomValue(Object->InstanceUID);
+
m_PacketList->AddPacket(Object);
}
Result_t result = KLVFilePacket::InitFromFile(Reader);
// test the UL
// could be one of several values
-
if ( ASDCP_SUCCESS(result) )
- {
- Kumu::MemIOReader MemRDR(m_ValueStart, m_ValueLength);
- result = RESULT_KLV_CODING;
+ result = ASDCP::MXF::Partition::InitFromBuffer(m_ValueStart, m_ValueLength);
+
+ return result;
+}
- if ( MemRDR.ReadUi16BE(&MajorVersion) )
- if ( MemRDR.ReadUi16BE(&MinorVersion) )
- if ( MemRDR.ReadUi32BE(&KAGSize) )
- if ( MemRDR.ReadUi64BE(&ThisPartition) )
- if ( MemRDR.ReadUi64BE(&PreviousPartition) )
- if ( MemRDR.ReadUi64BE(&FooterPartition) )
- if ( MemRDR.ReadUi64BE(&HeaderByteCount) )
- if ( MemRDR.ReadUi64BE(&IndexByteCount) )
- if ( MemRDR.ReadUi32BE(&IndexSID) )
- if ( MemRDR.ReadUi64BE(&BodyOffset) )
- if ( MemRDR.ReadUi32BE(&BodySID) )
- if ( OperationalPattern.Unarchive(&MemRDR) )
- if ( EssenceContainers.Unarchive(&MemRDR) )
- result = RESULT_OK;
- }
+//
+ASDCP::Result_t
+ASDCP::MXF::Partition::InitFromBuffer(const byte_t* p, ui32_t l)
+{
+ Kumu::MemIOReader MemRDR(p, l);
+ Result_t result = RESULT_KLV_CODING;
+
+ if ( MemRDR.ReadUi16BE(&MajorVersion) )
+ if ( MemRDR.ReadUi16BE(&MinorVersion) )
+ if ( MemRDR.ReadUi32BE(&KAGSize) )
+ if ( MemRDR.ReadUi64BE(&ThisPartition) )
+ if ( MemRDR.ReadUi64BE(&PreviousPartition) )
+ if ( MemRDR.ReadUi64BE(&FooterPartition) )
+ if ( MemRDR.ReadUi64BE(&HeaderByteCount) )
+ if ( MemRDR.ReadUi64BE(&IndexByteCount) )
+ if ( MemRDR.ReadUi32BE(&IndexSID) )
+ if ( MemRDR.ReadUi64BE(&BodyOffset) )
+ if ( MemRDR.ReadUi32BE(&BodySID) )
+ if ( OperationalPattern.Unarchive(&MemRDR) )
+ if ( EssenceContainers.Unarchive(&MemRDR) )
+ result = RESULT_OK;
if ( ASDCP_FAILURE(result) )
DefaultLogSink().Error("Failed to initialize Partition\n");
if ( stream == 0 )
stream = stderr;
- KLVFilePacket::Dump(stream, false);
+ KLVFilePacket::Dump(stream, *m_Dict, false);
fprintf(stream, " MajorVersion = %hu\n", MajorVersion);
fprintf(stream, " MinorVersion = %hu\n", MinorVersion);
fprintf(stream, " KAGSize = %u\n", KAGSize);
fprintf(stream, " BodyOffset = %s\n", ui64sz(BodyOffset, identbuf));
fprintf(stream, " BodySID = %u\n", BodySID);
fprintf(stream, " OperationalPattern = %s\n", OperationalPattern.EncodeString(identbuf, IdentBufferLen));
- fputs("Essence Containers:\n", stream); EssenceContainers.Dump(stream, false);
-
- fputs("==========================================================================\n", stream);
+ fputs("Essence Containers:\n", stream); EssenceContainers.Dump(stream);
}
//
-ASDCP::MXF::Primer::Primer() : m_LocalTag(0xff) {}
+ASDCP::MXF::Primer::Primer(const Dictionary*& d) : m_LocalTag(0xff), m_Dict(d) {}
//
ASDCP::MXF::Primer::~Primer() {}
ASDCP::Result_t
ASDCP::MXF::Primer::InitFromBuffer(const byte_t* p, ui32_t l)
{
- Result_t result = KLVPacket::InitFromBuffer(p, l, Dict::ul(MDD_Primer));
+ assert(m_Dict);
+ Result_t result = KLVPacket::InitFromBuffer(p, l, m_Dict->ul(MDD_Primer));
if ( ASDCP_SUCCESS(result) )
{
ASDCP::Result_t
ASDCP::MXF::Primer::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
{
+ assert(m_Dict);
ASDCP::FrameBuffer LocalTagBuffer;
Kumu::MemIOWriter MemWRT(Buffer.Data() + kl_length, Buffer.Capacity() - kl_length);
Result_t result = LocalTagEntryBatch.Archive(&MemWRT) ? RESULT_OK : RESULT_KLV_CODING;
if ( ASDCP_SUCCESS(result) )
{
ui32_t packet_length = MemWRT.Length();
- result = WriteKLToBuffer(Buffer, Dict::ul(MDD_Primer), packet_length);
+ result = WriteKLToBuffer(Buffer, m_Dict->ul(MDD_Primer), packet_length);
if ( ASDCP_SUCCESS(result) )
Buffer.Size(Buffer.Size() + packet_length);
void
ASDCP::MXF::Primer::Dump(FILE* stream)
{
+ assert(m_Dict);
char identbuf[IdentBufferLen];
if ( stream == 0 )
stream = stderr;
- KLVPacket::Dump(stream, false);
+ KLVPacket::Dump(stream, *m_Dict, false);
fprintf(stream, "Primer: %u %s\n",
- LocalTagEntryBatch.size(),
+ (ui32_t)LocalTagEntryBatch.size(),
( LocalTagEntryBatch.size() == 1 ? "entry" : "entries" ));
Batch<LocalTagEntry>::iterator i = LocalTagEntryBatch.begin();
for ( ; i != LocalTagEntryBatch.end(); i++ )
{
- const MDDEntry* Entry = Dict::FindUL((*i).UL.Value());
+ const MDDEntry* Entry = m_Dict->FindUL((*i).UL.Value());
fprintf(stream, " %s %s\n", (*i).EncodeString(identbuf, IdentBufferLen), (Entry ? Entry->name : "Unknown"));
}
-
- fputs("==========================================================================\n", stream);
}
ASDCP::Result_t
ASDCP::MXF::Preface::InitFromBuffer(const byte_t* p, ui32_t l)
{
- m_Typeinfo = &Dict::Type(MDD_Preface);
+ assert(m_Dict);
+ m_Typeinfo = &(m_Dict->Type(MDD_Preface));
return InterchangeObject::InitFromBuffer(p, l);
}
ASDCP::Result_t
ASDCP::MXF::Preface::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
{
- m_Typeinfo = &Dict::Type(MDD_Preface);
+ assert(m_Dict);
+ m_Typeinfo = &(m_Dict->Type(MDD_Preface));
return InterchangeObject::WriteToBuffer(Buffer);
}
//------------------------------------------------------------------------------------------
//
-ASDCP::MXF::OPAtomHeader::OPAtomHeader() : m_Preface(0), m_HasRIP(false) {}
+ASDCP::MXF::OPAtomHeader::OPAtomHeader(const Dictionary*& d) : Partition(d), m_Dict(d), m_RIP(d), m_Primer(d), m_Preface(0), m_HasRIP(false) {}
ASDCP::MXF::OPAtomHeader::~OPAtomHeader() {}
//
DefaultLogSink().Error("RIP contains no Pairs.\n");
result = RESULT_FORMAT;
}
- else if ( test_s < 2 || test_s > 3 )
- {
- // OP-Atom states that there will be either two or three partitions,
- // one closed header and one closed footer with an optional body
- DefaultLogSink().Error("RIP count is not 2 or 3: %u\n", test_s);
- return RESULT_FORMAT;
- }
else
{
- m_HasRIP = true;
- }
- }
+ if ( test_s < 2 )
+ {
+ // OP-Atom states that there will be either two or three partitions:
+ // one closed header and one closed footer with an optional body
+ // SMPTE 429-5 files may have many partitions, see SMPTE 410M
+ DefaultLogSink().Warn("RIP count is less than 2: %u\n", test_s);
+ }
- if ( ASDCP_SUCCESS(result) )
- {
- Array<RIP::Pair>::iterator r_i = m_RIP.PairArray.begin();
+ m_HasRIP = true;
- if ( (*r_i).ByteOffset != 0 )
- {
- DefaultLogSink().Error("First Partition in RIP is not at offset 0.\n");
- result = RESULT_FORMAT;
+ if ( m_RIP.PairArray.front().ByteOffset != 0 )
+ {
+ DefaultLogSink().Error("First Partition in RIP is not at offset 0.\n");
+ result = RESULT_FORMAT;
+ }
}
}
if ( ASDCP_SUCCESS(result) )
result = Partition::InitFromFile(Reader); // test UL and OP
+ if ( ASDCP_FAILURE(result) )
+ return result;
+
// is it really OP-Atom?
- UL OPAtomUL(Dict::ul(MDD_OPAtom));
- UL InteropOPAtomUL(Dict::ul(MDD_MXFInterop_OPAtom));
+ assert(m_Dict);
+ UL OPAtomUL(SMPTE_390_OPAtom_Entry().ul);
+ UL InteropOPAtomUL(MXFInterop_OPAtom_Entry().ul);
- if ( ! ( OperationalPattern == OPAtomUL || OperationalPattern == InteropOPAtomUL ) )
+ if ( OperationalPattern == OPAtomUL ) // SMPTE
+ {
+ if ( m_Dict == &DefaultCompositeDict() )
+ m_Dict = &DefaultSMPTEDict();
+ }
+ else if ( OperationalPattern == InteropOPAtomUL ) // Interop
+ {
+ if ( m_Dict == &DefaultCompositeDict() )
+ m_Dict = &DefaultInteropDict();
+ }
+ else
{
char strbuf[IdentBufferLen];
- const MDDEntry* Entry = Dict::FindUL(OperationalPattern.Value());
+ const MDDEntry* Entry = m_Dict->FindUL(OperationalPattern.Value());
if ( Entry == 0 )
- DefaultLogSink().Warn("Operational pattern is not OP-Atom: %s\n", OperationalPattern.EncodeString(strbuf, IdentBufferLen));
+ DefaultLogSink().Warn("Operational pattern is not OP-Atom: %s\n",
+ OperationalPattern.EncodeString(strbuf, IdentBufferLen));
else
DefaultLogSink().Warn("Operational pattern is not OP-Atom: %s\n", Entry->name);
}
// slurp up the remainder of the header
- if ( ASDCP_SUCCESS(result) )
- {
- if ( HeaderByteCount < 1024 )
- DefaultLogSink().Warn("Improbably small HeaderByteCount value: %u\n", HeaderByteCount);
+ if ( HeaderByteCount < 1024 )
+ DefaultLogSink().Warn("Improbably small HeaderByteCount value: %u\n", HeaderByteCount);
- result = m_Buffer.Capacity(HeaderByteCount);
- }
+ assert (HeaderByteCount <= 0xFFFFFFFFL);
+ result = m_Buffer.Capacity((ui32_t) HeaderByteCount);
if ( ASDCP_SUCCESS(result) )
{
ui32_t read_count;
result = Reader.Read(m_Buffer.Data(), m_Buffer.Capacity(), &read_count);
- if ( ASDCP_SUCCESS(result) && read_count != m_Buffer.Capacity() )
+ if ( ASDCP_FAILURE(result) )
+ return result;
+
+ if ( read_count != m_Buffer.Capacity() )
{
DefaultLogSink().Error("Short read of OP-Atom header metadata; wanted %u, got %u\n",
m_Buffer.Capacity(), read_count);
- return RESULT_FAIL;
+ return RESULT_KLV_CODING;
}
}
- const byte_t* p = m_Buffer.RoData();
- const byte_t* end_p = p + m_Buffer.Capacity();
+ if ( ASDCP_SUCCESS(result) )
+ result = InitFromBuffer(m_Buffer.RoData(), m_Buffer.Capacity());
+
+ return result;
+}
+
+//
+ASDCP::Result_t
+ASDCP::MXF::OPAtomHeader::InitFromPartitionBuffer(const byte_t* p, ui32_t l)
+{
+ Result_t result = KLVPacket::InitFromBuffer(p, l);
+
+ if ( ASDCP_SUCCESS(result) )
+ result = Partition::InitFromBuffer(m_ValueStart, m_ValueLength); // test UL and OP
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ ui32_t pp_len = KLVPacket::PacketLength();
+ result = InitFromBuffer(p + pp_len, l - pp_len);
+ }
+
+ return result;
+}
+
+//
+ASDCP::Result_t
+ASDCP::MXF::OPAtomHeader::InitFromBuffer(const byte_t* p, ui32_t l)
+{
+ assert(m_Dict);
+ Result_t result = RESULT_OK;
+ const byte_t* end_p = p + l;
while ( ASDCP_SUCCESS(result) && p < end_p )
{
// parse the packets and index them by uid, discard KLVFill items
- InterchangeObject* object = CreateObject(p);
+ InterchangeObject* object = CreateObject(m_Dict, p);
assert(object);
object->m_Lookup = &m_Primer;
if ( ASDCP_SUCCESS(result) )
{
- if ( object->IsA(Dict::ul(MDD_KLVFill)) )
+ if ( object->IsA(m_Dict->ul(MDD_KLVFill)) )
{
delete object;
}
- else if ( object->IsA(Dict::ul(MDD_Primer)) )
+ else if ( object->IsA(m_Dict->ul(MDD_Primer)) ) // TODO: only one primer should be found
{
delete object;
result = m_Primer.InitFromBuffer(redo_p, end_p - redo_p);
}
- else if ( object->IsA(Dict::ul(MDD_Preface)) )
- {
- assert(m_Preface == 0);
- m_Preface = (Preface*)object;
- }
- else
+ else
{
m_PacketList->AddPacket(object);
+
+ if ( object->IsA(m_Dict->ul(MDD_Preface)) && m_Preface == 0 )
+ m_Preface = (Preface*)object;
}
}
else
return result;
}
+ASDCP::Result_t
+ASDCP::MXF::OPAtomHeader::GetMDObjectByID(const UUID& ObjectID, InterchangeObject** Object)
+{
+ return m_PacketList->GetMDObjectByID(ObjectID, Object);
+}
+
//
ASDCP::Result_t
ASDCP::MXF::OPAtomHeader::GetMDObjectByType(const byte_t* ObjectID, InterchangeObject** Object)
return m_PacketList->GetMDObjectByType(ObjectID, Object);
}
+//
+ASDCP::Result_t
+ASDCP::MXF::OPAtomHeader::GetMDObjectsByType(const byte_t* ObjectID, std::list<InterchangeObject*>& ObjectList)
+{
+ return m_PacketList->GetMDObjectsByType(ObjectID, ObjectList);
+}
+
//
ASDCP::MXF::Identification*
ASDCP::MXF::OPAtomHeader::GetIdentification()
ASDCP::Result_t
ASDCP::MXF::OPAtomHeader::WriteToFile(Kumu::FileWriter& Writer, ui32_t HeaderSize)
{
+ assert(m_Dict);
if ( m_Preface == 0 )
return RESULT_STATE;
ASDCP::FrameBuffer HeaderBuffer;
HeaderByteCount = HeaderSize - ArchiveSize();
- Result_t result = HeaderBuffer.Capacity(HeaderByteCount);
+ assert (HeaderByteCount <= 0xFFFFFFFFL);
+ Result_t result = HeaderBuffer.Capacity((ui32_t) HeaderByteCount);
m_Preface->m_Lookup = &m_Primer;
std::list<InterchangeObject*>::iterator pl_i = m_PacketList->m_List.begin();
if ( ASDCP_SUCCESS(result) )
{
- UL TmpUL(Dict::ul(MDD_ClosedCompleteHeader));
+ UL TmpUL(m_Dict->ul(MDD_ClosedCompleteHeader));
result = Partition::WriteToFile(Writer, TmpUL);
}
}
klv_fill_length -= kl_length;
- result = WriteKLToFile(Writer, Dict::ul(MDD_KLVFill), klv_fill_length);
+ result = WriteKLToFile(Writer, m_Dict->ul(MDD_KLVFill), klv_fill_length);
if ( ASDCP_SUCCESS(result) )
result = NilBuf.Capacity(klv_fill_length);
if ( stream == 0 )
stream = stderr;
- if ( m_HasRIP )
- m_RIP.Dump(stream);
-
Partition::Dump(stream);
m_Primer.Dump(stream);
if ( m_Preface == 0 )
fputs("No Preface loaded\n", stream);
- else
- m_Preface->Dump(stream);
std::list<InterchangeObject*>::iterator i = m_PacketList->m_List.begin();
for ( ; i != m_PacketList->m_List.end(); i++ )
//------------------------------------------------------------------------------------------
//
-ASDCP::MXF::OPAtomIndexFooter::OPAtomIndexFooter() :
+ASDCP::MXF::OPAtomIndexFooter::OPAtomIndexFooter(const Dictionary*& d) :
+ Partition(d), m_Dict(d),
m_CurrentSegment(0), m_BytesPerEditUnit(0), m_BodySID(0),
m_ECOffset(0), m_Lookup(0)
{
ASDCP::MXF::OPAtomIndexFooter::~OPAtomIndexFooter() {}
-
+//
ASDCP::Result_t
ASDCP::MXF::OPAtomIndexFooter::InitFromFile(const Kumu::FileReader& Reader)
{
ui32_t read_count;
if ( ASDCP_SUCCESS(result) )
- result = m_Buffer.Capacity(IndexByteCount);
+ {
+ assert (IndexByteCount <= 0xFFFFFFFFL);
+ result = m_Buffer.Capacity((ui32_t) IndexByteCount);
+ }
if ( ASDCP_SUCCESS(result) )
result = Reader.Read(m_Buffer.Data(), m_Buffer.Capacity(), &read_count);
return RESULT_FAIL;
}
- const byte_t* p = m_Buffer.RoData();
- const byte_t* end_p = p + m_Buffer.Capacity();
+ if ( ASDCP_SUCCESS(result) )
+ result = InitFromBuffer(m_Buffer.RoData(), m_Buffer.Capacity());
+
+ return result;
+}
+
+//
+ASDCP::Result_t
+ASDCP::MXF::OPAtomIndexFooter::InitFromPartitionBuffer(const byte_t* p, ui32_t l)
+{
+ Result_t result = KLVPacket::InitFromBuffer(p, l);
+
+ if ( ASDCP_SUCCESS(result) )
+ result = Partition::InitFromBuffer(m_ValueStart, m_ValueLength); // test UL and OP
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ ui32_t pp_len = KLVPacket::PacketLength();
+ result = InitFromBuffer(p + pp_len, l - pp_len);
+ }
+
+ return result;
+}
+
+//
+ASDCP::Result_t
+ASDCP::MXF::OPAtomIndexFooter::InitFromBuffer(const byte_t* p, ui32_t l)
+{
+ Result_t result = RESULT_OK;
+ const byte_t* end_p = p + l;
while ( ASDCP_SUCCESS(result) && p < end_p )
{
// parse the packets and index them by uid, discard KLVFill items
- InterchangeObject* object = CreateObject(p);
+ InterchangeObject* object = CreateObject(m_Dict, p);
assert(object);
object->m_Lookup = m_Lookup;
ASDCP::Result_t
ASDCP::MXF::OPAtomIndexFooter::WriteToFile(Kumu::FileWriter& Writer, ui64_t duration)
{
+ assert(m_Dict);
ASDCP::FrameBuffer FooterBuffer;
ui32_t footer_size = m_PacketList->m_List.size() * MaxIndexSegmentSize; // segment-count * max-segment-size
Result_t result = FooterBuffer.Capacity(footer_size);
if ( ASDCP_SUCCESS(result) )
{
IndexByteCount = FooterBuffer.Size();
- UL FooterUL(Dict::ul(MDD_CompleteFooter));
+ UL FooterUL(m_Dict->ul(MDD_CompleteFooter));
result = Partition::WriteToFile(Writer, FooterUL);
}
if ( ASDCP_SUCCESS(result) )
{
- ui32_t write_count;
- Writer.Write(FooterBuffer.RoData(), FooterBuffer.Size(), &write_count);
+ ui32_t write_count = 0;
+ result = Writer.Write(FooterBuffer.RoData(), FooterBuffer.Size(), &write_count);
assert(write_count == FooterBuffer.Size());
}
//
ASDCP::Result_t
-ASDCP::MXF::OPAtomIndexFooter::Lookup(ui32_t frame_num, IndexTableSegment::IndexEntry& Entry)
+ASDCP::MXF::OPAtomIndexFooter::Lookup(ui32_t frame_num, IndexTableSegment::IndexEntry& Entry) const
{
std::list<InterchangeObject*>::iterator li;
for ( li = m_PacketList->m_List.begin(); li != m_PacketList->m_List.end(); li++ )
else if ( (ui64_t)frame_num >= start_pos
&& (ui64_t)frame_num < (start_pos + Segment->IndexDuration) )
{
- Entry = Segment->IndexEntryArray[frame_num-start_pos];
+ ui64_t tmp = frame_num - start_pos;
+ assert(tmp <= 0xFFFFFFFFL);
+ Entry = Segment->IndexEntryArray[(ui32_t) tmp];
return RESULT_OK;
}
}
m_BytesPerEditUnit = size;
m_EditRate = Rate;
- IndexTableSegment* Index = new IndexTableSegment;
+ IndexTableSegment* Index = new IndexTableSegment(m_Dict);
AddChildObject(Index);
Index->EditUnitByteCount = m_BytesPerEditUnit;
Index->IndexEditRate = Rate;
// do we have an available segment?
if ( m_CurrentSegment == 0 )
{ // no, set up a new segment
- m_CurrentSegment = new IndexTableSegment;
+ m_CurrentSegment = new IndexTableSegment(m_Dict);
assert(m_CurrentSegment);
AddChildObject(m_CurrentSegment);
m_CurrentSegment->DeltaEntryArray.push_back(IndexTableSegment::DeltaEntry());
m_CurrentSegment->IndexEditRate = m_EditRate;
m_CurrentSegment->IndexStartPosition = 0;
}
- else if ( m_CurrentSegment->IndexEntryArray.size() >= 1486 ) // 1486 gets us 16K packets
+ else if ( m_CurrentSegment->IndexEntryArray.size() >= CBRIndexEntriesPerSegment )
{ // no, this one is full, start another
m_CurrentSegment->IndexDuration = m_CurrentSegment->IndexEntryArray.size();
ui64_t StartPosition = m_CurrentSegment->IndexStartPosition + m_CurrentSegment->IndexDuration;
- m_CurrentSegment = new IndexTableSegment;
+ m_CurrentSegment = new IndexTableSegment(m_Dict);
assert(m_CurrentSegment);
AddChildObject(m_CurrentSegment);
m_CurrentSegment->DeltaEntryArray.push_back(IndexTableSegment::DeltaEntry());
char identbuf[IdentBufferLen];
fputc('\n', stream);
- KLVPacket::Dump(stream, false);
+ KLVPacket::Dump(stream, *m_Dict, false);
fprintf(stream, " InstanceUID = %s\n", InstanceUID.EncodeHex(identbuf, IdentBufferLen));
fprintf(stream, " GenerationUID = %s\n", GenerationUID.EncodeHex(identbuf, IdentBufferLen));
}
}
+//------------------------------------------------------------------------------------------
+
+
+typedef std::map<ASDCP::UL, ASDCP::MXF::MXFObjectFactory_t>FactoryMap_t;
+typedef FactoryMap_t::iterator FLi_t;
+
+//
+class FactoryList : public FactoryMap_t
+{
+ Kumu::Mutex m_Lock;
+
+public:
+ FactoryList() {}
+ ~FactoryList() {}
+
+ bool Empty() {
+ Kumu::AutoMutex BlockLock(m_Lock);
+ return empty();
+ }
+
+ FLi_t Find(const byte_t* label) {
+ Kumu::AutoMutex BlockLock(m_Lock);
+ return find(label);
+ }
+
+ FLi_t End() {
+ Kumu::AutoMutex BlockLock(m_Lock);
+ return end();
+ }
+
+ void Insert(ASDCP::UL label, ASDCP::MXF::MXFObjectFactory_t factory) {
+ Kumu::AutoMutex BlockLock(m_Lock);
+ insert(FactoryList::value_type(label, factory));
+ }
+};
+
+//
+static FactoryList s_FactoryList;
+static Kumu::Mutex s_InitLock;
+static bool s_TypesInit = false;
+
+
+//
+void
+ASDCP::MXF::SetObjectFactory(ASDCP::UL label, ASDCP::MXF::MXFObjectFactory_t factory)
+{
+ s_FactoryList.Insert(label, factory);
+}
+
+//
+ASDCP::MXF::InterchangeObject*
+ASDCP::MXF::CreateObject(const Dictionary*& Dict, const UL& label)
+{
+ if ( ! s_TypesInit )
+ {
+ Kumu::AutoMutex BlockLock(s_InitLock);
+
+ if ( ! s_TypesInit )
+ {
+ MXF::Metadata_InitTypes(Dict);
+ s_TypesInit = true;
+ }
+ }
+
+ FLi_t i = s_FactoryList.find(label.Value());
+
+ if ( i == s_FactoryList.end() )
+ return new InterchangeObject(Dict);
+
+ return i->second(Dict);
+}
+
+
//
// end MXF.cpp
//