/*
-Copyright (c) 2005-2007, John Hurst
+Copyright (c) 2005-2008, 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.
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)
KLVFilePacket::Dump(stream, 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;
+ }
};
//------------------------------------------------------------------------------------------
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);
}
KLVPacket::Dump(stream, false);
fprintf(stream, "Primer: %u %s\n",
- LocalTagEntryBatch.size(),
+ (ui32_t)LocalTagEntryBatch.size(),
( LocalTagEntryBatch.size() == 1 ? "entry" : "entries" ));
Batch<LocalTagEntry>::iterator i = LocalTagEntryBatch.begin();
const MDDEntry* Entry = Dict::FindUL((*i).UL.Value());
fprintf(stream, " %s %s\n", (*i).EncodeString(identbuf, IdentBufferLen), (Entry ? Entry->name : "Unknown"));
}
-
- fputs("==========================================================================\n", stream);
}
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 || 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().Warn("RIP count is not 2 or 3: %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));
}
// 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;
}
}
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(Dict::ul(MDD_Preface)) )
+ {
+ assert(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::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 ( 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++ )
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);
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;
}
}
}
+//------------------------------------------------------------------------------------------
+
+
+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 byte_t* label)
+{
+ if ( label == 0 )
+ return 0;
+
+ if ( ! s_TypesInit )
+ {
+ Kumu::AutoMutex BlockLock(s_InitLock);
+
+ if ( ! s_TypesInit )
+ {
+ MXF::Metadata_InitTypes();
+ s_TypesInit = true;
+ }
+ }
+
+ FLi_t i = s_FactoryList.find(label);
+
+ if ( i == s_FactoryList.end() )
+ return new InterchangeObject;
+
+ return i->second();
+}
+
+
+
//
// end MXF.cpp
//