X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2FMXF.cpp;h=bf99e3e522271ebc4bc9dd4538fcfe92a98fe586;hb=3bb652da6ea2765b1538d0713cefa284238c8bdb;hp=28b156c650e11709a3e3c58d8771f997453aab39;hpb=6b5d04290663a89cb8666cdc1c0df238d065a981;p=asdcplib.git diff --git a/src/MXF.cpp b/src/MXF.cpp index 28b156c..bf99e3e 100755 --- a/src/MXF.cpp +++ b/src/MXF.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2005-2006, John Hurst +Copyright (c) 2005-2008, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -30,8 +30,11 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "MXF.h" +#include "Metadata.h" #include + using Kumu::DefaultLogSink; +using Kumu::GenRandomValue; // index segments must be < 64K // NOTE: this value may too high if advanced index entry elements are used. @@ -89,6 +92,23 @@ ASDCP::MXF::SeekToRIP(const Kumu::FileReader& Reader) return result; } +// +ASDCP::Result_t +ASDCP::MXF::RIP::GetPairBySID(ui32_t SID, Pair& outPair) const +{ + Array::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) @@ -146,8 +166,6 @@ ASDCP::MXF::RIP::Dump(FILE* stream) KLVFilePacket::Dump(stream, false); PairArray.Dump(stream, false); - - fputs("==========================================================================\n", stream); } //------------------------------------------------------------------------------------------ @@ -176,6 +194,23 @@ public: m_List.push_back(ThePacket); } + // + Result_t GetMDObjectByID(const UUID& ObjectID, InterchangeObject** Object) + { + ASDCP_TEST_NULL(Object); + + std::map::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) { @@ -195,6 +230,21 @@ public: return RESULT_FAIL; } + + // + Result_t GetMDObjectsByType(const byte_t* ObjectID, std::list& ObjectList) + { + ASDCP_TEST_NULL(ObjectID); + std::list::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; + } }; //------------------------------------------------------------------------------------------ @@ -219,9 +269,10 @@ void 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); } @@ -340,8 +391,6 @@ ASDCP::MXF::Partition::Dump(FILE* stream) 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); } @@ -502,7 +551,7 @@ ASDCP::MXF::Primer::Dump(FILE* stream) KLVPacket::Dump(stream, false); fprintf(stream, "Primer: %u %s\n", - LocalTagEntryBatch.size(), + (ui32_t)LocalTagEntryBatch.size(), ( LocalTagEntryBatch.size() == 1 ? "entry" : "entries" )); Batch::iterator i = LocalTagEntryBatch.begin(); @@ -511,8 +560,6 @@ ASDCP::MXF::Primer::Dump(FILE* stream) const MDDEntry* Entry = Dict::FindUL((*i).UL.Value()); fprintf(stream, " %s %s\n", (*i).EncodeString(identbuf, IdentBufferLen), (Entry ? Entry->name : "Unknown")); } - - fputs("==========================================================================\n", stream); } @@ -618,27 +665,22 @@ ASDCP::MXF::OPAtomHeader::InitFromFile(const Kumu::FileReader& Reader) 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::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; + } } } @@ -648,6 +690,9 @@ ASDCP::MXF::OPAtomHeader::InitFromFile(const Kumu::FileReader& Reader) 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)); @@ -663,24 +708,25 @@ ASDCP::MXF::OPAtomHeader::InitFromFile(const Kumu::FileReader& Reader) } // 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; } } @@ -710,14 +756,15 @@ ASDCP::MXF::OPAtomHeader::InitFromFile(const Kumu::FileReader& Reader) 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 @@ -730,6 +777,12 @@ ASDCP::MXF::OPAtomHeader::InitFromFile(const Kumu::FileReader& Reader) 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) @@ -742,6 +795,13 @@ ASDCP::MXF::OPAtomHeader::GetMDObjectByType(const byte_t* ObjectID, InterchangeO return m_PacketList->GetMDObjectByType(ObjectID, Object); } +// +ASDCP::Result_t +ASDCP::MXF::OPAtomHeader::GetMDObjectsByType(const byte_t* ObjectID, std::list& ObjectList) +{ + return m_PacketList->GetMDObjectsByType(ObjectID, ObjectList); +} + // ASDCP::MXF::Identification* ASDCP::MXF::OPAtomHeader::GetIdentification() @@ -782,7 +842,8 @@ ASDCP::MXF::OPAtomHeader::WriteToFile(Kumu::FileWriter& Writer, ui32_t HeaderSiz 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::iterator pl_i = m_PacketList->m_List.begin(); @@ -862,16 +923,11 @@ ASDCP::MXF::OPAtomHeader::Dump(FILE* stream) 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::iterator i = m_PacketList->m_List.begin(); for ( ; i != m_PacketList->m_List.end(); i++ ) @@ -901,7 +957,10 @@ 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); @@ -994,8 +1053,8 @@ ASDCP::MXF::OPAtomIndexFooter::WriteToFile(Kumu::FileWriter& Writer, ui64_t dura 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()); } @@ -1018,7 +1077,7 @@ ASDCP::MXF::OPAtomIndexFooter::Dump(FILE* stream) // 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::iterator li; for ( li = m_PacketList->m_List.begin(); li != m_PacketList->m_List.end(); li++ ) @@ -1042,7 +1101,9 @@ ASDCP::MXF::OPAtomIndexFooter::Lookup(ui32_t frame_num, IndexTableSegment::Index 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; } } @@ -1206,6 +1267,84 @@ ASDCP::MXF::InterchangeObject::IsA(const byte_t* label) } +//------------------------------------------------------------------------------------------ + + +typedef std::mapFactoryMap_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 //