o General review of Batch/Array distinction throughout the project
authorjhurst <jhurst@cinecert.com>
Fri, 9 Oct 2015 23:41:11 +0000 (23:41 +0000)
committerjhurst <>
Fri, 9 Oct 2015 23:41:11 +0000 (23:41 +0000)
 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

15 files changed:
src/AS_02_PHDR.cpp
src/AS_02_TimedText.cpp
src/AS_02_internal.h
src/AS_DCP_TimedText.cpp
src/JP2K_Codestream_Parser.cpp
src/MXF.cpp
src/MXF.h
src/MXFTypes.h
src/Metadata.h
src/asdcp-wrap.cpp
src/h__02_Reader.cpp
src/h__02_Writer.cpp
src/h__Reader.cpp
src/h__Writer.cpp
src/klvwalk.cpp

index dd413f968eb620502adb548aac30611426bb5510..1ecd8880aeb70739ccae049a470d9bebfe122d0a 100644 (file)
@@ -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<RIP::Pair>::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));
index bd85737103f20012fd501655d2a357980847042f..5361029957ba8fecf78b687f13cf29ec87d64316 100644 (file)
@@ -96,7 +96,7 @@ AS_02::TimedText::MXFReader::h__Reader::MD_to_TimedText_TDesc(TimedTextDescripto
   TDesc.NamespaceName = TDescObj->NamespaceURI;
   TDesc.EncodingName = TDescObj->UCSEncoding;
 
-  Batch<Kumu::UUID>::const_iterator sdi = TDescObj->SubDescriptors.begin();
+  Array<Kumu::UUID>::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<RIP::Pair>::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);
index 4bdb64cf1342daf7a7bd692ad2c41ba2c69f4747..bcee7a7b088c15423ae5d8f51391042fd873298c 100644 (file)
@@ -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<ASDCP::MXF::RIP::Pair>::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;
 
index 52740377048918ab1771da2778b703972eb59ac8..f738a59c440e6550a9d2c12b31ed32a45ce25d5e 100644 (file)
@@ -160,7 +160,7 @@ ASDCP::TimedText::MXFReader::h__Reader::MD_to_TimedText_TDesc(TimedText::TimedTe
   TDesc.NamespaceName = TDescObj->NamespaceURI;
   TDesc.EncodingName = TDescObj->UCSEncoding;
 
-  Batch<UUID>::const_iterator sdi = TDescObj->SubDescriptors.begin();
+  Array<UUID>::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<RIP::Pair>::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);
index c82064610a79fc599970194d0487f2e70b181fcb..0ed26492e82e4f8ccce9295d92c3247a219108e0 100755 (executable)
@@ -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;
            }
          
index d0ece08c42b7f45791543da4b06b17e0e9908fdf..30530478e3d77c1184526a01dde390c67900300c 100755 (executable)
@@ -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<Pair>::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<UL, TagValue>::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<UUID>::const_iterator i;
+  MXF::Array<UUID>::const_iterator i;
   MXF::SourcePackage *source_package = dynamic_cast<MXF::SourcePackage*>(temp_items.front());
   assert(source_package);
 
index 391e0cc5826bafb0bd16364790a06ae471ede56a..046a7b2d31dbeebf697152c18bcb29031ea11790 100755 (executable)
--- 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<Pair> PairArray;
+
+         typedef SimpleArray<PartitionPair>::iterator pair_iterator;
+         typedef SimpleArray<PartitionPair>::const_iterator const_pair_iterator;
+
+         SimpleArray<PartitionPair> 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<ui32_t> ObjectModelVersion;
          optional_property<UUID> PrimaryPackage;
-         Batch<UUID>  Identifications;
+         Array<UUID>  Identifications;
          UUID         ContentStorage;
          UL           OperationalPattern;
          Batch<UL>    EssenceContainers;
@@ -360,8 +368,8 @@ namespace ASDCP
          ui32_t      BodySID;
          ui8_t       SliceCount;
          ui8_t       PosTableCount;
-         Batch<DeltaEntry> DeltaEntryArray;
-         Batch<IndexEntry> IndexEntryArray;
+         Array<DeltaEntry> DeltaEntryArray;
+         Array<IndexEntry> IndexEntryArray;
 
          IndexTableSegment(const Dictionary*&);
          virtual ~IndexTableSegment();
index f49ef8b89085139318c7eb3e7c8e3a1af4b2b193..701dfa1152879d5f96fce2b4c7ec1db5d4135337 100755 (executable)
@@ -35,6 +35,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "KLV.h"
 #include <list>
 #include <vector>
+#include <set>
 #include <map>
 #include <wchar.h>
 
@@ -96,46 +97,32 @@ namespace ASDCP
        };
 
       //
-      template <class T>
-       class Batch : public std::vector<T>, public Kumu::IArchive
+      template <class ContainerType>
+       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<T>::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<T>::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<ui32_t>(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<T>::iterator i = this->begin();
-             for ( ; i != this->end(); i++ )
-               fprintf(stream, "  %s\n", (*i).EncodeString(identbuf, IdentBufferLen));
-           }
-       };
-
-      //
-      template <class T>
-       class Array : public std::list<T>, 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<T>::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<T>::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<ui32_t>(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 item_type>
+       class PushSet : public std::set<item_type>
+      {
+      public:
+       PushSet() {}
+       virtual ~PushSet() {}
+       void push_back(const item_type& item) { this->insert(item); }
+      };
 
-             if ( stream == 0 )
-               stream = stderr;
+      template <class ItemType>
+       class Batch : public FixedSizeItemCollection<PushSet<ItemType> >
+      {
+      public:
+       Batch() {}
+       virtual ~Batch() {}
+      };
 
-             typename std::list<T>::iterator i = this->begin();
-             for ( ; i != this->end(); i++ )
-               fprintf(stream, "  %s\n", (*i).EncodeString(identbuf, IdentBufferLen));
-           }
-       };
+      template <class ItemType>
+       class Array : public FixedSizeItemCollection<std::vector<ItemType> >
+      {
+      public:
+       Array() {}
+       virtual ~Array() {}
+      };
 
       //
       template <class T>
-       class HeadlessArray : public std::list<T>, public Kumu::IArchive
+       class SimpleArray : public std::list<T>, public Kumu::IArchive
        {
        public:
-         HeadlessArray() {}
-         virtual ~HeadlessArray() {}
+         SimpleArray() {}
+         virtual ~SimpleArray() {}
 
          //
          virtual bool Unarchive(Kumu::MemIOReader* Reader)
index d76c477eb3071eb6b9af79588aadfce8d29b8d1c..bc62665ccfebbfd7d0ec47a48db06bc6c97b11ca 100755 (executable)
@@ -133,7 +133,7 @@ namespace ASDCP
           optional_property<UTF16String> Name;
           Kumu::Timestamp PackageCreationDate;
           Kumu::Timestamp PackageModifiedDate;
-          Batch<UUID> Tracks;
+          Array<UUID> Tracks;
 
       GenericPackage(const Dictionary*& d);
       GenericPackage(const GenericPackage& rhs);
@@ -292,7 +292,7 @@ namespace ASDCP
 
        public:
          const Dictionary*& m_Dict;
-          Batch<UUID> StructuralComponents;
+          Array<UUID> StructuralComponents;
 
       Sequence(const Dictionary*& d);
       Sequence(const Sequence& rhs);
@@ -365,8 +365,8 @@ namespace ASDCP
 
        public:
          const Dictionary*& m_Dict;
-          Batch<UUID> Locators;
-          Batch<UUID> SubDescriptors;
+          Array<UUID> Locators;
+          Array<UUID> SubDescriptors;
 
       GenericDescriptor(const Dictionary*& d);
       GenericDescriptor(const GenericDescriptor& rhs);
index a12f79ea50bf5b758c2858496e3ffc89de8d3068..97da552616a124181707a46ce4adfa8b23444b78 100755 (executable)
@@ -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;
index dd85330f5f8b40de5695f19aeb2d553072298ec3..cf2b00f340c27e89884f5a6b91cfe8d45d633456 100644 (file)
@@ -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<ASDCP::MXF::RIP::Pair>::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<RIP::Pair>::iterator r_i;
+      RIP::pair_iterator r_i;
 
       for ( r_i = m_RIP.PairArray.begin(); r_i != m_RIP.PairArray.end(); ++r_i )
        {
index 745166c2f951374262c938894eda0adfb11ea7d3..f400afdd9f9333d6afbb0c7204fd462b20a9eeac 100644 (file)
@@ -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;
index 707b71039649350be154ef400fd66c65adf7f442..d0c5168929f0889aad076b5f66e36599cee11187 100755 (executable)
@@ -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<RIP::Pair>::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);
index b407ce698b26a4d1882492c2ae7b3b38af601232..07d418f7035087bfc5c705c9be09bec1e898a560 100755 (executable)
@@ -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);
index bcdda85de40ceb7f71c9be50bfe2f20fc1ab4ab5..779ee72bd2944f365b70c9dfaaac55a6c6c03dd4 100755 (executable)
@@ -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<MXF::RIP::Pair>::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<MXF::RIP::Pair>::const_iterator i;
+             MXF::RIP::const_pair_iterator i;
              for ( i = RIP.PairArray.begin(); i != RIP.PairArray.end(); ++i )
                {
                  Reader.Seek(i->ByteOffset);