X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2FMXF.cpp;h=952de7e7e3360fd1a54e249fadd224e923e0a84e;hb=19bd80c074e1dec35404fd85607a2a68c791b2d9;hp=d01393c9f26eab1e39c4d5c5c130f2a888de97ed;hpb=a6d7c84d3734a21dbe7112a3a83b791ec211a315;p=asdcplib.git diff --git a/src/MXF.cpp b/src/MXF.cpp index d01393c..952de7e 100755 --- a/src/MXF.cpp +++ b/src/MXF.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2005-2008, John Hurst +Copyright (c) 2005-2009, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -113,7 +113,8 @@ ASDCP::MXF::RIP::GetPairBySID(ui32_t SID, Pair& outPair) const 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) ) { @@ -131,12 +132,13 @@ ASDCP::MXF::RIP::InitFromFile(const Kumu::FileReader& Reader) 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) ) { @@ -164,7 +166,7 @@ ASDCP::MXF::RIP::Dump(FILE* stream) if ( stream == 0 ) stream = stderr; - KLVFilePacket::Dump(stream, false); + KLVFilePacket::Dump(stream, *m_Dict, false); PairArray.Dump(stream, false); } @@ -251,7 +253,8 @@ public: // -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), @@ -283,27 +286,33 @@ ASDCP::MXF::Partition::InitFromFile(const Kumu::FileReader& Reader) 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"); @@ -377,7 +386,7 @@ ASDCP::MXF::Partition::Dump(FILE* stream) 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); @@ -390,7 +399,7 @@ ASDCP::MXF::Partition::Dump(FILE* stream) 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("Essence Containers:\n", stream); EssenceContainers.Dump(stream); } @@ -411,7 +420,7 @@ public: // -ASDCP::MXF::Primer::Primer() : m_LocalTag(0xff) {} +ASDCP::MXF::Primer::Primer(const Dictionary*& d) : m_LocalTag(0xff), m_Dict(d) {} // ASDCP::MXF::Primer::~Primer() {} @@ -428,7 +437,8 @@ ASDCP::MXF::Primer::ClearTagList() 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) ) { @@ -468,6 +478,7 @@ ASDCP::MXF::Primer::WriteToFile(Kumu::FileWriter& Writer) 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; @@ -475,7 +486,7 @@ ASDCP::MXF::Primer::WriteToBuffer(ASDCP::FrameBuffer& Buffer) 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); @@ -544,12 +555,13 @@ ASDCP::MXF::Primer::TagForKey(const ASDCP::UL& Key, ASDCP::TagValue& Tag) 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", (ui32_t)LocalTagEntryBatch.size(), ( LocalTagEntryBatch.size() == 1 ? "entry" : "entries" )); @@ -557,7 +569,7 @@ ASDCP::MXF::Primer::Dump(FILE* stream) Batch::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")); } } @@ -604,7 +616,8 @@ ASDCP::MXF::Preface::WriteToTLVSet(TLVWriter& TLVSet) 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); } @@ -612,7 +625,8 @@ ASDCP::MXF::Preface::InitFromBuffer(const byte_t* p, ui32_t 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); } @@ -640,7 +654,7 @@ ASDCP::MXF::Preface::Dump(FILE* stream) //------------------------------------------------------------------------------------------ // -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() {} // @@ -695,15 +709,27 @@ ASDCP::MXF::OPAtomHeader::InitFromFile(const Kumu::FileReader& Reader) 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); } @@ -731,13 +757,42 @@ ASDCP::MXF::OPAtomHeader::InitFromFile(const Kumu::FileReader& Reader) } } - 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; @@ -748,11 +803,11 @@ ASDCP::MXF::OPAtomHeader::InitFromFile(const Kumu::FileReader& Reader) 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); @@ -761,11 +816,8 @@ ASDCP::MXF::OPAtomHeader::InitFromFile(const Kumu::FileReader& Reader) { m_PacketList->AddPacket(object); - if ( object->IsA(Dict::ul(MDD_Preface)) ) - { - assert(m_Preface == 0); - m_Preface = (Preface*)object; - } + if ( object->IsA(m_Dict->ul(MDD_Preface)) && m_Preface == 0 ) + m_Preface = (Preface*)object; } } else @@ -832,6 +884,7 @@ ASDCP::MXF::OPAtomHeader::GetSourcePackage() ASDCP::Result_t ASDCP::MXF::OPAtomHeader::WriteToFile(Kumu::FileWriter& Writer, ui32_t HeaderSize) { + assert(m_Dict); if ( m_Preface == 0 ) return RESULT_STATE; @@ -862,7 +915,7 @@ ASDCP::MXF::OPAtomHeader::WriteToFile(Kumu::FileWriter& Writer, ui32_t HeaderSiz if ( ASDCP_SUCCESS(result) ) { - UL TmpUL(Dict::ul(MDD_ClosedCompleteHeader)); + UL TmpUL(m_Dict->ul(MDD_ClosedCompleteHeader)); result = Partition::WriteToFile(Writer, TmpUL); } @@ -900,7 +953,7 @@ ASDCP::MXF::OPAtomHeader::WriteToFile(Kumu::FileWriter& Writer, ui32_t HeaderSiz } 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); @@ -938,7 +991,8 @@ ASDCP::MXF::OPAtomHeader::Dump(FILE* stream) //------------------------------------------------------------------------------------------ // -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) { @@ -948,7 +1002,7 @@ ASDCP::MXF::OPAtomIndexFooter::OPAtomIndexFooter() : ASDCP::MXF::OPAtomIndexFooter::~OPAtomIndexFooter() {} - +// ASDCP::Result_t ASDCP::MXF::OPAtomIndexFooter::InitFromFile(const Kumu::FileReader& Reader) { @@ -973,13 +1027,41 @@ ASDCP::MXF::OPAtomIndexFooter::InitFromFile(const Kumu::FileReader& Reader) 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; @@ -1007,6 +1089,7 @@ ASDCP::MXF::OPAtomIndexFooter::InitFromFile(const Kumu::FileReader& Reader) 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); @@ -1048,7 +1131,7 @@ ASDCP::MXF::OPAtomIndexFooter::WriteToFile(Kumu::FileWriter& Writer, ui64_t dura 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); } @@ -1122,7 +1205,7 @@ ASDCP::MXF::OPAtomIndexFooter::SetIndexParamsCBR(IPrimerLookup* lookup, ui32_t s 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; @@ -1152,7 +1235,7 @@ ASDCP::MXF::OPAtomIndexFooter::PushIndexEntry(const IndexTableSegment::IndexEntr // 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()); @@ -1164,7 +1247,7 @@ ASDCP::MXF::OPAtomIndexFooter::PushIndexEntry(const IndexTableSegment::IndexEntr 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()); @@ -1252,7 +1335,7 @@ ASDCP::MXF::InterchangeObject::Dump(FILE* stream) 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)); } @@ -1317,35 +1400,30 @@ ASDCP::MXF::SetObjectFactory(ASDCP::UL label, ASDCP::MXF::MXFObjectFactory_t fac s_FactoryList.Insert(label, factory); } - // ASDCP::MXF::InterchangeObject* -ASDCP::MXF::CreateObject(const byte_t* label) +ASDCP::MXF::CreateObject(const Dictionary*& Dict, const UL& label) { - if ( label == 0 ) - return 0; - if ( ! s_TypesInit ) { Kumu::AutoMutex BlockLock(s_InitLock); if ( ! s_TypesInit ) { - MXF::Metadata_InitTypes(); + MXF::Metadata_InitTypes(Dict); s_TypesInit = true; } } - FLi_t i = s_FactoryList.find(label); + FLi_t i = s_FactoryList.find(label.Value()); if ( i == s_FactoryList.end() ) - return new InterchangeObject; + return new InterchangeObject(Dict); - return i->second(); + return i->second(Dict); } - // // end MXF.cpp //