From: jhurst Date: Fri, 9 Oct 2015 23:41:11 +0000 (+0000) Subject: o General review of Batch/Array distinction throughout the project X-Git-Tag: rel_2_10_32~113 X-Git-Url: https://git.carlh.net/gitweb/?a=commitdiff_plain;h=f758bec505d45084d2563f20514ab4a81b27283a;p=asdcplib.git o General review of Batch/Array distinction throughout the project o Fixed a bug that caused incorrect failure when parsing JPEG 2000 codestreams having fewer than five decomposition levels. o Fixed missing UUID generation in some instances of the MCALinkID property o Added -w option to asdcp-wrap to support use of WTF label with MCA --- diff --git a/src/AS_02_PHDR.cpp b/src/AS_02_PHDR.cpp index dd413f9..1ecd888 100644 --- a/src/AS_02_PHDR.cpp +++ b/src/AS_02_PHDR.cpp @@ -144,8 +144,8 @@ AS_02::PHDR::MXFReader::h__Reader::OpenRead(const std::string& filename, std::st // if PHDRSimplePayload exists, go get it if ( KM_SUCCESS(result) && SimplePayloadSID ) { - Array::const_iterator pi; - RIP::Pair TmpPair; + RIP::const_pair_iterator pi; + RIP::PartitionPair TmpPair; // Look up the partition start in the RIP using the SID. for ( pi = m_RIP.PairArray.begin(); pi != m_RIP.PairArray.end(); ++pi ) @@ -485,7 +485,7 @@ AS_02::PHDR::MXFWriter::h__Writer::WritePHDRHeader(const std::string& PackageLab AddEssenceDescriptor(WrappingUL); m_IndexWriter.SetPrimerLookup(&m_HeaderPart.m_Primer); - m_RIP.PairArray.push_back(RIP::Pair(0, 0)); // Header partition RIP entry + m_RIP.PairArray.push_back(RIP::PartitionPair(0, 0)); // Header partition RIP entry m_IndexWriter.OperationalPattern = m_HeaderPart.OperationalPattern; m_IndexWriter.EssenceContainers = m_HeaderPart.EssenceContainers; @@ -504,7 +504,7 @@ AS_02::PHDR::MXFWriter::h__Writer::WritePHDRHeader(const std::string& PackageLab body_part.EssenceContainers = m_HeaderPart.EssenceContainers; body_part.ThisPartition = m_ECStart; result = body_part.WriteToFile(m_File, body_ul); - m_RIP.PairArray.push_back(RIP::Pair(1, body_part.ThisPartition)); // Second RIP Entry + m_RIP.PairArray.push_back(RIP::PartitionPair(1, body_part.ThisPartition)); // Second RIP Entry } return result; @@ -594,7 +594,7 @@ AS_02::PHDR::MXFWriter::h__Writer::WriteFrame(const AS_02::PHDR::FrameBuffer& Fr { m_IndexWriter.ThisPartition = m_File.Tell(); m_IndexWriter.WriteToFile(m_File); - m_RIP.PairArray.push_back(RIP::Pair(0, m_IndexWriter.ThisPartition)); + m_RIP.PairArray.push_back(RIP::PartitionPair(0, m_IndexWriter.ThisPartition)); UL body_ul(m_Dict->ul(MDD_ClosedCompleteBodyPartition)); Partition body_part(m_Dict); @@ -605,7 +605,7 @@ AS_02::PHDR::MXFWriter::h__Writer::WriteFrame(const AS_02::PHDR::FrameBuffer& Fr body_part.BodyOffset = m_StreamOffset; result = body_part.WriteToFile(m_File, body_ul); - m_RIP.PairArray.push_back(RIP::Pair(1, body_part.ThisPartition)); + m_RIP.PairArray.push_back(RIP::PartitionPair(1, body_part.ThisPartition)); } } @@ -633,7 +633,7 @@ AS_02::PHDR::MXFWriter::h__Writer::Finalize(const std::string& PHDR_master_metad { m_IndexWriter.ThisPartition = this->m_File.Tell(); m_IndexWriter.WriteToFile(this->m_File); - m_RIP.PairArray.push_back(RIP::Pair(0, this->m_IndexWriter.ThisPartition)); + m_RIP.PairArray.push_back(RIP::PartitionPair(0, this->m_IndexWriter.ThisPartition)); } if ( ! PHDR_master_metadata.empty() ) @@ -651,7 +651,7 @@ AS_02::PHDR::MXFWriter::h__Writer::Finalize(const std::string& PHDR_master_metad GSPart.BodySID = 2; m_MetadataTrackSubDescriptor->SimplePayloadSID = 2; - m_RIP.PairArray.push_back(RIP::Pair(2, here)); + m_RIP.PairArray.push_back(RIP::PartitionPair(2, here)); GSPart.EssenceContainers = m_HeaderPart.EssenceContainers; static UL gs_part_ul(m_Dict->ul(MDD_GenericStreamPartition)); diff --git a/src/AS_02_TimedText.cpp b/src/AS_02_TimedText.cpp index bd85737..5361029 100644 --- a/src/AS_02_TimedText.cpp +++ b/src/AS_02_TimedText.cpp @@ -96,7 +96,7 @@ AS_02::TimedText::MXFReader::h__Reader::MD_to_TimedText_TDesc(TimedTextDescripto TDesc.NamespaceName = TDescObj->NamespaceURI; TDesc.EncodingName = TDescObj->UCSEncoding; - Batch::const_iterator sdi = TDescObj->SubDescriptors.begin(); + Array::const_iterator sdi = TDescObj->SubDescriptors.begin(); TimedTextResourceSubDescriptor* DescObject = 0; Result_t result = RESULT_OK; @@ -203,8 +203,8 @@ AS_02::TimedText::MXFReader::h__Reader::ReadAncillaryResource(const Kumu::UUID& if ( KM_SUCCESS(result) ) { - Array::const_iterator pi; - RIP::Pair TmpPair; + RIP::const_pair_iterator pi; + RIP::PartitionPair TmpPair; ui32_t sequence = 0; // Look up the partition start in the RIP using the SID. @@ -602,7 +602,7 @@ AS_02::TimedText::MXFWriter::h__Writer::WriteAncillaryResource(const ASDCP::Time GSPart.BodySID = m_EssenceStreamID; GSPart.OperationalPattern = m_HeaderPart.OperationalPattern; - m_RIP.PairArray.push_back(RIP::Pair(m_EssenceStreamID++, here)); + m_RIP.PairArray.push_back(RIP::PartitionPair(m_EssenceStreamID++, here)); GSPart.EssenceContainers.push_back(UL(m_Dict->ul(MDD_TimedTextEssence))); UL TmpUL(m_Dict->ul(MDD_GenericStreamPartition)); Result_t result = GSPart.WriteToFile(m_File, TmpUL); diff --git a/src/AS_02_internal.h b/src/AS_02_internal.h index 4bdb64c..bcee7a7 100644 --- a/src/AS_02_internal.h +++ b/src/AS_02_internal.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2011-2013, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, +Copyright (c) 2011-2015, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst All rights reserved. @@ -178,7 +178,7 @@ namespace AS_02 AddEssenceDescriptor(WrappingUL); this->m_IndexWriter.SetPrimerLookup(&this->m_HeaderPart.m_Primer); - this->m_RIP.PairArray.push_back(RIP::Pair(0, 0)); // Header partition RIP entry + this->m_RIP.PairArray.push_back(RIP::PartitionPair(0, 0)); // Header partition RIP entry this->m_IndexWriter.OperationalPattern = this->m_HeaderPart.OperationalPattern; this->m_IndexWriter.EssenceContainers = this->m_HeaderPart.EssenceContainers; @@ -197,7 +197,7 @@ namespace AS_02 body_part.EssenceContainers = this->m_HeaderPart.EssenceContainers; body_part.ThisPartition = this->m_ECStart; result = body_part.WriteToFile(this->m_File, body_ul); - this->m_RIP.PairArray.push_back(RIP::Pair(1, body_part.ThisPartition)); // Second RIP Entry + this->m_RIP.PairArray.push_back(RIP::PartitionPair(1, body_part.ThisPartition)); // Second RIP Entry } return result; @@ -211,7 +211,7 @@ namespace AS_02 { this->m_IndexWriter.ThisPartition = this->m_File.Tell(); this->m_IndexWriter.WriteToFile(this->m_File); - this->m_RIP.PairArray.push_back(RIP::Pair(0, this->m_IndexWriter.ThisPartition)); + this->m_RIP.PairArray.push_back(RIP::PartitionPair(0, this->m_IndexWriter.ThisPartition)); } // update all Duration properties @@ -227,7 +227,7 @@ namespace AS_02 footer_part.PreviousPartition = this->m_RIP.PairArray.back().ByteOffset; Kumu::fpos_t here = this->m_File.Tell(); - this->m_RIP.PairArray.push_back(RIP::Pair(0, here)); // Last RIP Entry + this->m_RIP.PairArray.push_back(RIP::PartitionPair(0, here)); // Last RIP Entry this->m_HeaderPart.FooterPartition = here; assert(this->m_Dict); @@ -250,7 +250,7 @@ namespace AS_02 if ( KM_SUCCESS(result) ) { - ASDCP::MXF::Array::const_iterator i = this->m_RIP.PairArray.begin(); + ASDCP::MXF::RIP::const_pair_iterator i = this->m_RIP.PairArray.begin(); ui64_t header_byte_count = this->m_HeaderPart.HeaderByteCount; ui64_t previous_partition = 0; diff --git a/src/AS_DCP_TimedText.cpp b/src/AS_DCP_TimedText.cpp index 5274037..f738a59 100644 --- a/src/AS_DCP_TimedText.cpp +++ b/src/AS_DCP_TimedText.cpp @@ -160,7 +160,7 @@ ASDCP::TimedText::MXFReader::h__Reader::MD_to_TimedText_TDesc(TimedText::TimedTe TDesc.NamespaceName = TDescObj->NamespaceURI; TDesc.EncodingName = TDescObj->UCSEncoding; - Batch::const_iterator sdi = TDescObj->SubDescriptors.begin(); + Array::const_iterator sdi = TDescObj->SubDescriptors.begin(); TimedTextResourceSubDescriptor* DescObject = 0; Result_t result = RESULT_OK; @@ -265,8 +265,8 @@ ASDCP::TimedText::MXFReader::h__Reader::ReadAncillaryResource(const byte_t* uuid if ( KM_SUCCESS(result) ) { - Array::const_iterator pi; - RIP::Pair TmpPair; + RIP::const_pair_iterator pi; + RIP::PartitionPair TmpPair; ui32_t sequence = 0; // Look up the partition start in the RIP using the SID. @@ -584,7 +584,7 @@ ASDCP::TimedText::MXFWriter::h__Writer::SetSourceStream(ASDCP::TimedText::TimedT // First RIP Entry if ( m_Info.LabelSetType == LS_MXF_SMPTE ) // ERK { - m_RIP.PairArray.push_back(RIP::Pair(0, 0)); // 3-part, no essence in header + m_RIP.PairArray.push_back(RIP::PartitionPair(0, 0)); // 3-part, no essence in header } else { @@ -668,7 +668,7 @@ ASDCP::TimedText::MXFWriter::h__Writer::WriteAncillaryResource(const ASDCP::Time GSPart.BodySID = m_EssenceStreamID; GSPart.OperationalPattern = m_HeaderPart.OperationalPattern; - m_RIP.PairArray.push_back(RIP::Pair(m_EssenceStreamID++, here)); + m_RIP.PairArray.push_back(RIP::PartitionPair(m_EssenceStreamID++, here)); GSPart.EssenceContainers.push_back(UL(m_Dict->ul(MDD_TimedTextEssence))); UL TmpUL(m_Dict->ul(MDD_GenericStreamPartition)); Result_t result = GSPart.WriteToFile(m_File, TmpUL); diff --git a/src/JP2K_Codestream_Parser.cpp b/src/JP2K_Codestream_Parser.cpp index c820646..0ed2649 100755 --- a/src/JP2K_Codestream_Parser.cpp +++ b/src/JP2K_Codestream_Parser.cpp @@ -163,9 +163,9 @@ ASDCP::JP2K::ParseMetadataIntoDesc(const FrameBuffer& FB, PictureDescriptor& PDe case MRK_QCD: memset(&PDesc.QuantizationDefault, 0, sizeof(QuantizationDefault_t)); - if ( NextMarker.m_DataSize < 16 ) + if ( NextMarker.m_DataSize < 3 ) // ( Sqcd = 8 bits, SPqcd = 8 bits ) == 2 bytes, error if not greater { - DefaultLogSink().Error("No quantization signaled\n"); + DefaultLogSink().Error("No quantization signaled. QCD size=%s.\n", NextMarker.m_DataSize); return RESULT_RAW_FORMAT; } diff --git a/src/MXF.cpp b/src/MXF.cpp index d0ece08..3053047 100755 --- a/src/MXF.cpp +++ b/src/MXF.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2005-2014, John Hurst +Copyright (c) 2005-2015, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -100,20 +100,20 @@ ASDCP::MXF::SeekToRIP(const Kumu::FileReader& Reader) } // -ASDCP::Result_t -ASDCP::MXF::RIP::GetPairBySID(ui32_t SID, Pair& outPair) const +bool +ASDCP::MXF::RIP::GetPairBySID(ui32_t SID, PartitionPair& outPair) const { - Array::const_iterator pi = PairArray.begin(); - for ( ; pi != PairArray.end(); pi++ ) + RIP::const_pair_iterator i; + for ( i = PairArray.begin(); i != PairArray.end(); ++i ) { - if ( (*pi).BodySID == SID ) + if ( i->BodySID == SID ) { - outPair = *pi; - return RESULT_OK; + outPair = *i; + return true; } } - return RESULT_FAIL; + return false; } // @@ -526,7 +526,7 @@ ASDCP::MXF::Primer::InsertTag(const MDDEntry& Entry, ASDCP::TagValue& Tag) TmpEntry.UL = TestUL; TmpEntry.Tag = Tag; - LocalTagEntryBatch.push_back(TmpEntry); + LocalTagEntryBatch.insert(TmpEntry); m_Lookup->insert(std::map::value_type(TmpEntry.UL, TmpEntry.Tag)); } else @@ -1511,9 +1511,8 @@ ASDCP::MXF::decode_mca_string(const std::string& s, const mca_label_map_t& label } current_soundfield = new ASDCP::MXF::SoundfieldGroupLabelSubDescriptor(dict); - - GenRandomValue(current_soundfield->InstanceUID); GenRandomValue(current_soundfield->MCALinkID); + current_soundfield->MCATagSymbol = (i->second.requires_prefix ? "sg" : "") + i->first; current_soundfield->MCATagName = i->second.tag_name; current_soundfield->RFC5646SpokenLanguage = language; @@ -1543,12 +1542,12 @@ ASDCP::MXF::decode_mca_string(const std::string& s, const mca_label_map_t& label return false; } + assert(current_soundfield); + ASDCP::MXF::AudioChannelLabelSubDescriptor *channel_descr = new ASDCP::MXF::AudioChannelLabelSubDescriptor(dict); - - GenRandomValue(channel_descr->InstanceUID); GenRandomValue(channel_descr->MCALinkID); - assert(current_soundfield); + channel_descr->SoundfieldGroupLinkID = current_soundfield->MCALinkID; channel_descr->MCAChannelID = channel_count++ + 1; channel_descr->MCATagSymbol = (i->second.requires_prefix ? "ch" : "") + i->first; @@ -1584,8 +1583,7 @@ ASDCP::MXF::decode_mca_string(const std::string& s, const mca_label_map_t& label ASDCP::MXF::AudioChannelLabelSubDescriptor *channel_descr = new ASDCP::MXF::AudioChannelLabelSubDescriptor(dict); - - GenRandomValue(channel_descr->InstanceUID); + GenRandomValue(channel_descr->MCALinkID); if ( current_soundfield != 0 ) { @@ -1628,8 +1626,6 @@ ASDCP::MXF::decode_mca_string(const std::string& s, const mca_label_map_t& label ASDCP::MXF::AudioChannelLabelSubDescriptor *channel_descr = new ASDCP::MXF::AudioChannelLabelSubDescriptor(dict); - - GenRandomValue(channel_descr->InstanceUID); GenRandomValue(channel_descr->MCALinkID); if ( current_soundfield != 0 ) @@ -1742,7 +1738,7 @@ ASDCP::MXF::GetEditRateFromFP(ASDCP::MXF::OP1aHeader& header, ASDCP::Rational& e } char buf[64]; - MXF::Batch::const_iterator i; + MXF::Array::const_iterator i; MXF::SourcePackage *source_package = dynamic_cast(temp_items.front()); assert(source_package); diff --git a/src/MXF.h b/src/MXF.h index 391e0cc..046a7b2 100755 --- a/src/MXF.h +++ b/src/MXF.h @@ -64,15 +64,15 @@ namespace ASDCP public: // - class Pair : public Kumu::IArchive + class PartitionPair : public Kumu::IArchive { public: ui32_t BodySID; ui64_t ByteOffset; - Pair() : BodySID(0), ByteOffset(0) {} - Pair(ui32_t sid, ui64_t offset) : BodySID(sid), ByteOffset(offset) {} - virtual ~Pair() {} + PartitionPair() : BodySID(0), ByteOffset(0) {} + PartitionPair(ui32_t sid, ui64_t offset) : BodySID(sid), ByteOffset(offset) {} + virtual ~PartitionPair() {} ui32_t Size() { return sizeof(ui32_t) + sizeof(ui64_t); } @@ -99,13 +99,17 @@ namespace ASDCP }; const Dictionary*& m_Dict; - HeadlessArray PairArray; + + typedef SimpleArray::iterator pair_iterator; + typedef SimpleArray::const_iterator const_pair_iterator; + + SimpleArray PairArray; RIP(const Dictionary*& d) : m_Dict(d) {} virtual ~RIP() {} virtual Result_t InitFromFile(const Kumu::FileReader& Reader); virtual Result_t WriteToFile(Kumu::FileWriter& Writer); - virtual Result_t GetPairBySID(ui32_t, Pair&) const; + virtual bool GetPairBySID(ui32_t, PartitionPair&) const; virtual void Dump(FILE* = 0); }; @@ -180,6 +184,10 @@ namespace ASDCP LocalTagEntry() { Tag.a = Tag.b = 0; } LocalTagEntry(const TagValue& tag, ASDCP::UL& ul) : Tag(tag), UL(ul) {} + bool operator<(const LocalTagEntry& rhs) const { + return ( ( Tag.a < rhs.Tag.a ) || ( Tag.b < rhs.Tag.b ) ); + } + 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)); @@ -280,7 +288,7 @@ namespace ASDCP ui16_t Version; optional_property ObjectModelVersion; optional_property PrimaryPackage; - Batch Identifications; + Array Identifications; UUID ContentStorage; UL OperationalPattern; Batch
    EssenceContainers; @@ -360,8 +368,8 @@ namespace ASDCP ui32_t BodySID; ui8_t SliceCount; ui8_t PosTableCount; - Batch DeltaEntryArray; - Batch IndexEntryArray; + Array DeltaEntryArray; + Array IndexEntryArray; IndexTableSegment(const Dictionary*&); virtual ~IndexTableSegment(); diff --git a/src/MXFTypes.h b/src/MXFTypes.h index f49ef8b..701dfa1 100755 --- a/src/MXFTypes.h +++ b/src/MXFTypes.h @@ -35,6 +35,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "KLV.h" #include #include +#include #include #include @@ -96,46 +97,32 @@ namespace ASDCP }; // - template - class Batch : public std::vector, public Kumu::IArchive + template + class FixedSizeItemCollection : public ContainerType, public Kumu::IArchive { public: - Batch() {} - virtual ~Batch() {} + FixedSizeItemCollection() {} + virtual ~FixedSizeItemCollection() {} - inline virtual bool HasValue() const { return ! this->empty(); } + ui32_t ItemSize() const { + typename ContainerType::value_type tmp_item; + return tmp_item.ArchiveLength(); + } - virtual ui32_t ArchiveLength() const { - ui32_t arch_size = sizeof(ui32_t) * 2; - typename std::vector::const_iterator i; + bool HasValue() const { return ! this->empty(); } - for ( i = this->begin(); i != this->end(); ++i ) - { - arch_size += i->ArchiveLength(); - } - - return arch_size; + ui32_t ArchiveLength() const { + return ( sizeof(ui32_t) * 2 ) + ( this->size() * this->ItemSize() ); } - // - virtual bool Archive(Kumu::MemIOWriter* Writer) const { + bool Archive(Kumu::MemIOWriter* Writer) const { if ( ! Writer->WriteUi32BE(this->size()) ) return false; - byte_t* p = Writer->CurrentData(); - - if ( ! Writer->WriteUi32BE(0) ) return false; + if ( ! Writer->WriteUi32BE(this->ItemSize()) ) return false; if ( this->empty() ) return true; - typename std::vector::const_iterator i = this->begin(); - assert(i != this->end()); - - ui32_t ItemSize = Writer->Remainder(); - if ( ! i->Archive(Writer) ) return false; - ItemSize -= Writer->Remainder(); - Kumu::i2p(KM_i32_BE(ItemSize), p); - ++i; - + typename ContainerType::const_iterator i; bool result = true; - for ( ; i != this->end() && result; ++i ) + for ( i = this->begin(); i != this->end() && result; ++i ) { result = i->Archive(Writer); } @@ -144,141 +131,76 @@ namespace ASDCP } // - virtual bool Unarchive(Kumu::MemIOReader* Reader) { + bool Unarchive(Kumu::MemIOReader* Reader) { ui32_t item_count, item_size; if ( ! Reader->ReadUi32BE(&item_count) ) return false; if ( ! Reader->ReadUi32BE(&item_size) ) return false; - - if ( ( item_count > 65536 ) || ( item_size > 1024 ) ) - { - return false; - } + if ( this->ItemSize() != item_size ) return false; bool result = true; for ( ui32_t i = 0; i < item_count && result; ++i ) { - T Tmp; - result = Tmp.Unarchive(Reader); + typename ContainerType::value_type tmp_item; + result = tmp_item.Unarchive(Reader); if ( result ) { - this->push_back(Tmp); + this->push_back(tmp_item); } } return result; } - // - void Dump(FILE* stream = 0, ui32_t depth = 0) - { - char identbuf[IdentBufferLen]; + void Dump(FILE* stream = 0, ui32_t depth = 0) { + char identbuf[IdentBufferLen]; - if ( stream == 0 ) - stream = stderr; - - typename std::vector::iterator i = this->begin(); - for ( ; i != this->end(); i++ ) - fprintf(stream, " %s\n", (*i).EncodeString(identbuf, IdentBufferLen)); - } - }; - - // - template - class Array : public std::list, public Kumu::IArchive - { - public: - Array() {} - virtual ~Array() {} - - inline virtual bool HasValue() const { return ! this->empty(); } - - virtual ui32_t ArchiveLength() const { - ui32_t arch_size = sizeof(ui32_t) * 2; - typename std::list::const_iterator i; - - for ( i = this->begin(); i != this->end(); ++i ) + if ( stream == 0 ) { - arch_size += i->ArchiveLength(); + stream = stderr; } - - return arch_size; - } - - // - virtual bool Archive(Kumu::MemIOWriter* Writer) const { - if ( ! Writer->WriteUi32BE(this->size()) ) return false; - byte_t* p = Writer->CurrentData(); - - if ( ! Writer->WriteUi32BE(0) ) return false; - if ( this->empty() ) return true; - typename std::list::const_iterator i = this->begin(); - assert(i != this->end()); - - ui32_t ItemSize = Writer->Remainder(); - if ( ! i->Archive(Writer) ) return false; - ItemSize -= Writer->Remainder(); - Kumu::i2p(KM_i32_BE(ItemSize), p); - ++i; - - bool result = true; - for ( ; i != this->end() && result; ++i ) + typename ContainerType::const_iterator i; + for ( i = this->begin(); i != this->end(); ++i ) { - result = i->Archive(Writer); + fprintf(stream, " %s\n", (*i).EncodeString(identbuf, IdentBufferLen)); } - - return result; } + }; - // - virtual bool Unarchive(Kumu::MemIOReader* Reader) { - ui32_t item_count, item_size; - if ( ! Reader->ReadUi32BE(&item_count) ) return false; - if ( ! Reader->ReadUi32BE(&item_size) ) return false; - - if ( ( item_count > 65536 ) || ( item_size > 1024 ) ) - { - return false; - } - - bool result = true; - for ( ui32_t i = 0; i < item_count && result; ++i ) - { - T Tmp; - result = Tmp.Unarchive(Reader); - - if ( result ) - { - this->push_back(Tmp); - } - } - - return result; - } - - // - void Dump(FILE* stream = 0, ui32_t depth = 0) - { - char identbuf[IdentBufferLen]; + template + class PushSet : public std::set + { + public: + PushSet() {} + virtual ~PushSet() {} + void push_back(const item_type& item) { this->insert(item); } + }; - if ( stream == 0 ) - stream = stderr; + template + class Batch : public FixedSizeItemCollection > + { + public: + Batch() {} + virtual ~Batch() {} + }; - typename std::list::iterator i = this->begin(); - for ( ; i != this->end(); i++ ) - fprintf(stream, " %s\n", (*i).EncodeString(identbuf, IdentBufferLen)); - } - }; + template + class Array : public FixedSizeItemCollection > + { + public: + Array() {} + virtual ~Array() {} + }; // template - class HeadlessArray : public std::list, public Kumu::IArchive + class SimpleArray : public std::list, public Kumu::IArchive { public: - HeadlessArray() {} - virtual ~HeadlessArray() {} + SimpleArray() {} + virtual ~SimpleArray() {} // virtual bool Unarchive(Kumu::MemIOReader* Reader) diff --git a/src/Metadata.h b/src/Metadata.h index d76c477..bc62665 100755 --- a/src/Metadata.h +++ b/src/Metadata.h @@ -133,7 +133,7 @@ namespace ASDCP optional_property Name; Kumu::Timestamp PackageCreationDate; Kumu::Timestamp PackageModifiedDate; - Batch Tracks; + Array Tracks; GenericPackage(const Dictionary*& d); GenericPackage(const GenericPackage& rhs); @@ -292,7 +292,7 @@ namespace ASDCP public: const Dictionary*& m_Dict; - Batch StructuralComponents; + Array StructuralComponents; Sequence(const Dictionary*& d); Sequence(const Sequence& rhs); @@ -365,8 +365,8 @@ namespace ASDCP public: const Dictionary*& m_Dict; - Batch Locators; - Batch SubDescriptors; + Array Locators; + Array SubDescriptors; GenericDescriptor(const Dictionary*& d); GenericDescriptor(const GenericDescriptor& rhs); diff --git a/src/asdcp-wrap.cpp b/src/asdcp-wrap.cpp index a12f79e..97da552 100755 --- a/src/asdcp-wrap.cpp +++ b/src/asdcp-wrap.cpp @@ -169,7 +169,9 @@ Options:\n\ will overide -C and -l options with Configuration 4 \n\ Channel Assigment and no format label respectively. \n\ -v - Verbose, prints informative messages to stderr\n\ - -W - Read input file only, do not write source file\n\ + -w - When writing 377-4 MCA labels, use the WTF Channel\n\ + assignment label instead of the standard MCA label\n\ + -W - Read input file only, do not write output file\n\ -z - Fail if j2c inputs have unequal parameters (default)\n\ -Z - Ignore unequal parameters in j2c inputs\n\ \n\ @@ -241,9 +243,10 @@ public: UL picture_coding; UL aux_data_coding; bool dolby_atmos_sync_flag; // if true, insert a Dolby Atmos Synchronization channel. - ui32_t ffoa; /// first frame of action for atmos wrapping - ui32_t max_channel_count; /// max channel count for atmos wrapping - ui32_t max_object_count; /// max object count for atmos wrapping + ui32_t ffoa; // first frame of action for atmos wrapping + ui32_t max_channel_count; // max channel count for atmos wrapping + ui32_t max_object_count; // max object count for atmos wrapping + bool use_interop_sound_wtf; // make true to force WTF assignment label instead of MCA ASDCP::MXF::ASDCP_MCAConfigParser mca_config; // @@ -299,7 +302,8 @@ public: ffoa(0), max_channel_count(10), max_object_count(118), // hard-coded sample atmos properties dolby_atmos_sync_flag(false), show_ul_values_flag(false), - mca_config(g_dict) + mca_config(g_dict), + use_interop_sound_wtf(false) { memset(key_value, 0, KeyLen); memset(key_id_value, 0, UUIDlen); @@ -441,6 +445,7 @@ public: case 'u': show_ul_values_flag = true; break; case 'V': version_flag = true; break; case 'v': verbose_flag = true; break; + case 'w': use_interop_sound_wtf = true; break; case 'W': no_write_flag = true; break; case 'Z': j2c_pedantic = false; break; case 'z': j2c_pedantic = true; break; @@ -1035,7 +1040,14 @@ write_PCM_file(CommandOptions& Options) return RESULT_FAIL; } - essence_descriptor->ChannelAssignment = g_dict->ul(MDD_DCAudioChannelCfg_MCA); + if ( Options.use_interop_sound_wtf ) + { + essence_descriptor->ChannelAssignment = g_dict->ul(MDD_DCAudioChannelCfg_4_WTF); + } + else + { + essence_descriptor->ChannelAssignment = g_dict->ul(MDD_DCAudioChannelCfg_MCA); + } // add descriptors to the essence_descriptor and header ASDCP::MXF::InterchangeObject_list_t::iterator i; diff --git a/src/h__02_Reader.cpp b/src/h__02_Reader.cpp index dd85330..cf2b00f 100644 --- a/src/h__02_Reader.cpp +++ b/src/h__02_Reader.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2011-2013, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, +Copyright (c) 2011-2015, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst All rights reserved. @@ -77,7 +77,7 @@ AS_02::MXF::AS02IndexReader::InitFromFile(const Kumu::FileReader& reader, const body_part_array_t body_part_array; body_part_array_t::const_iterator body_part_iter; - ASDCP::MXF::Array::const_iterator i; + RIP::const_pair_iterator i; Result_t result = m_IndexSegmentData.Capacity(128*Kumu::Kilobyte); // will be grown if needed ui32_t first_body_sid = 0; @@ -429,7 +429,7 @@ AS_02::h__AS02Reader::OpenMXFRead(const char* filename) Kumu::fpos_t first_partition_after_header = 0; bool has_body_sid = false; - Array::iterator r_i; + RIP::pair_iterator r_i; for ( r_i = m_RIP.PairArray.begin(); r_i != m_RIP.PairArray.end(); ++r_i ) { diff --git a/src/h__02_Writer.cpp b/src/h__02_Writer.cpp index 745166c..f400afd 100644 --- a/src/h__02_Writer.cpp +++ b/src/h__02_Writer.cpp @@ -195,7 +195,7 @@ AS_02::h__AS02WriterFrame::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf,co { m_IndexWriter.ThisPartition = m_File.Tell(); m_IndexWriter.WriteToFile(m_File); - m_RIP.PairArray.push_back(RIP::Pair(0, m_IndexWriter.ThisPartition)); + m_RIP.PairArray.push_back(RIP::PartitionPair(0, m_IndexWriter.ThisPartition)); UL body_ul(m_Dict->ul(MDD_ClosedCompleteBodyPartition)); Partition body_part(m_Dict); @@ -206,7 +206,7 @@ AS_02::h__AS02WriterFrame::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf,co body_part.BodyOffset = m_StreamOffset; result = body_part.WriteToFile(m_File, body_ul); - m_RIP.PairArray.push_back(RIP::Pair(1, body_part.ThisPartition)); + m_RIP.PairArray.push_back(RIP::PartitionPair(1, body_part.ThisPartition)); } return result; diff --git a/src/h__Reader.cpp b/src/h__Reader.cpp index 707b710..d0c5168 100755 --- a/src/h__Reader.cpp +++ b/src/h__Reader.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2004-2013, John Hurst +Copyright (c) 2004-2015, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -126,7 +126,7 @@ ASDCP::h__ASDCPReader::OpenMXFRead(const std::string& filename) { // if this is a three partition file, go to the body // partition and read the partition pack - Array::iterator r_i = m_RIP.PairArray.begin(); + RIP::const_pair_iterator r_i = m_RIP.PairArray.begin(); r_i++; m_File.Seek((*r_i).ByteOffset); result = m_BodyPart.InitFromFile(m_File); diff --git a/src/h__Writer.cpp b/src/h__Writer.cpp index b407ce6..07d418f 100755 --- a/src/h__Writer.cpp +++ b/src/h__Writer.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2004-2013, John Hurst +Copyright (c) 2004-2015, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -106,7 +106,7 @@ ASDCP::h__ASDCPWriter::CreateBodyPart(const MXF::Rational& EditRate, ui32_t Byte m_BodyPart.BodySID = 1; UL OPAtomUL(m_Dict->ul(MDD_OPAtom)); m_BodyPart.OperationalPattern = OPAtomUL; - m_RIP.PairArray.push_back(RIP::Pair(1, m_BodyPart.ThisPartition)); // Second RIP Entry + m_RIP.PairArray.push_back(RIP::PartitionPair(1, m_BodyPart.ThisPartition)); // Second RIP Entry UL BodyUL(m_Dict->ul(MDD_ClosedCompleteBodyPartition)); result = m_BodyPart.WriteToFile(m_File, BodyUL); @@ -146,11 +146,11 @@ ASDCP::h__ASDCPWriter::WriteASDCPHeader(const std::string& PackageLabel, const U // First RIP Entry if ( m_Info.LabelSetType == LS_MXF_SMPTE ) // ERK { - m_RIP.PairArray.push_back(RIP::Pair(0, 0)); // 3-part, no essence in header + m_RIP.PairArray.push_back(RIP::PartitionPair(0, 0)); // 3-part, no essence in header } else { - m_RIP.PairArray.push_back(RIP::Pair(1, 0)); // 2-part, essence in header + m_RIP.PairArray.push_back(RIP::PartitionPair(1, 0)); // 2-part, essence in header } // timecode rate and essence rate are the same @@ -191,7 +191,7 @@ ASDCP::h__ASDCPWriter::WriteASDCPFooter() m_FooterPart.PreviousPartition = m_RIP.PairArray.back().ByteOffset; Kumu::fpos_t here = m_File.Tell(); - m_RIP.PairArray.push_back(RIP::Pair(0, here)); // Last RIP Entry + m_RIP.PairArray.push_back(RIP::PartitionPair(0, here)); // Last RIP Entry m_HeaderPart.FooterPartition = here; assert(m_Dict); diff --git a/src/klvwalk.cpp b/src/klvwalk.cpp index bcdda85..779ee72 100755 --- a/src/klvwalk.cpp +++ b/src/klvwalk.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2005-2013, John Hurst +Copyright (c) 2005-2015, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -236,7 +236,7 @@ main(int argc, const char** argv) if ( ASDCP_SUCCESS(result) && RIP.PairArray.size() > 2 ) { - MXF::Array::const_iterator pi = RIP.PairArray.begin(); + MXF::RIP::const_pair_iterator pi = RIP.PairArray.begin(); for ( pi++; pi != RIP.PairArray.end() && ASDCP_SUCCESS(result); pi++ ) { @@ -309,7 +309,7 @@ main(int argc, const char** argv) { RIP.Dump(); - MXF::Array::const_iterator i; + MXF::RIP::const_pair_iterator i; for ( i = RIP.PairArray.begin(); i != RIP.PairArray.end(); ++i ) { Reader.Seek(i->ByteOffset);