Modified to enforce execution order of the predicates
[asdcplib.git] / src / h__Writer.cpp
index 4d11786145a49bf92459de942317117e8df8998e..71e9ce63bc268897cbd1fe1b712b2424738b77a5 100755 (executable)
@@ -133,6 +133,7 @@ ASDCP::AddDmsTrackGenericPartUtf8Text(Kumu::FileWriter& file_writer, MXF::OP1aHe
       StaticTrack_obj = 0;
     }
 
+  // find the Sequence associated with this Track
   if ( StaticTrack_obj )
     {
       object_list.clear();
@@ -151,6 +152,7 @@ ASDCP::AddDmsTrackGenericPartUtf8Text(Kumu::FileWriter& file_writer, MXF::OP1aHe
 
   if ( Sequence_obj == 0 )
     {
+      // this is the first insertion, create the static track
       assert(Dict);
       StaticTrack* static_track = new StaticTrack(Dict);
       header_part.AddChildObject(static_track);
@@ -166,7 +168,7 @@ ASDCP::AddDmsTrackGenericPartUtf8Text(Kumu::FileWriter& file_writer, MXF::OP1aHe
     }
 
   assert(Sequence_obj);
-  // 
+  // Create the DM segment and framework packs
   DMSegment* Segment = new DMSegment(Dict);
   header_part.AddChildObject(Segment);
   Sequence_obj->StructuralComponents.push_back(Segment->InstanceUID);
@@ -180,8 +182,7 @@ ASDCP::AddDmsTrackGenericPartUtf8Text(Kumu::FileWriter& file_writer, MXF::OP1aHe
   Segment->DMFramework = dmf_obj->InstanceUID;
   GenRandomValue(dmf_obj->ObjectRef);
 
-
-  // Create new SID in DMF
+  // Create a new SID on the RIP, located at the current file position
   ui32_t max_sid = 0;
   ASDCP::MXF::RIP::pair_iterator i;
   for ( i = rip.PairArray.begin(); i != rip.PairArray.end(); ++i )
@@ -192,6 +193,12 @@ ASDCP::AddDmsTrackGenericPartUtf8Text(Kumu::FileWriter& file_writer, MXF::OP1aHe
        }
     }
 
+  if ( max_sid == 0 )
+    {
+      DefaultLogSink().Error("Unable to add a GS Partition before the essence container has been established.\n");
+      return RESULT_FORMAT;
+    }
+
   rip.PairArray.push_back(RIP::PartitionPair(max_sid + 1, file_writer.Tell()));
 
   // Add new GSTBS linked to DMF
@@ -278,6 +285,11 @@ ASDCP::h__ASDCPWriter::WriteASDCPHeader(const std::string& PackageLabel, const U
   AddSourceClip(EditRate, EditRate, TCFrameRate, TrackName, EssenceUL, DataDefinition, PackageLabel);
   AddEssenceDescriptor(WrappingUL);
 
+#ifdef ASDCP_GCMULTI_PATCH
+  UL GenericContainerUL(m_Dict->ul(MDD_GCMulti));
+  m_HeaderPart.EssenceContainers.push_back(GenericContainerUL);
+#endif
+
   Result_t result = m_HeaderPart.WriteToFile(m_File, m_HeaderSize);
 
   if ( KM_SUCCESS(result) )
@@ -289,10 +301,12 @@ ASDCP::h__ASDCPWriter::WriteASDCPHeader(const std::string& PackageLabel, const U
 //
 Result_t
 ASDCP::h__ASDCPWriter::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf,const byte_t* EssenceUL,
+                                      const ui32_t& MinEssenceElementBerLength,               
                                       AESEncContext* Ctx, HMACContext* HMAC)
 {
   return Write_EKLV_Packet(m_File, *m_Dict, m_HeaderPart, m_Info, m_CtFrameBuf, m_FramesWritten,
-                          m_StreamOffset, FrameBuf, EssenceUL, Ctx, HMAC);
+                          m_StreamOffset, FrameBuf, EssenceUL, MinEssenceElementBerLength,
+                          Ctx, HMAC);
 }
 
 // standard method of writing the header and footer of a completed MXF file
@@ -351,6 +365,7 @@ Result_t
 ASDCP::Write_EKLV_Packet(Kumu::FileWriter& File, const ASDCP::Dictionary& Dict, const MXF::OP1aHeader& HeaderPart,
                         const ASDCP::WriterInfo& Info, ASDCP::FrameBuffer& CtFrameBuf, ui32_t& FramesWritten,
                         ui64_t & StreamOffset, const ASDCP::FrameBuffer& FrameBuf, const byte_t* EssenceUL,
+                        const ui32_t& MinEssenceElementBerLength,
                         AESEncContext* Ctx, HMACContext* HMAC)
 {
   Result_t result = RESULT_OK;
@@ -389,7 +404,7 @@ ASDCP::Write_EKLV_Packet(Kumu::FileWriter& File, const ASDCP::Dictionary& Dict,
 
          // construct encrypted triplet header
          ui32_t ETLength = klv_cryptinfo_size + CtFrameBuf.Size();
-         ui32_t BER_length = MXF_BER_LENGTH;
+         ui32_t essence_element_BER_length = MinEssenceElementBerLength;
 
          if ( Info.UsesHMAC )
            ETLength += klv_intpack_size;
@@ -398,18 +413,18 @@ ASDCP::Write_EKLV_Packet(Kumu::FileWriter& File, const ASDCP::Dictionary& Dict,
 
          if ( ETLength > 0x00ffffff ) // Need BER integer longer than MXF_BER_LENGTH bytes
            {
-             BER_length = Kumu::get_BER_length_for_value(ETLength);
+             essence_element_BER_length = Kumu::get_BER_length_for_value(ETLength);
 
              // the packet is longer by the difference in expected vs. actual BER length
-             ETLength += BER_length - MXF_BER_LENGTH;
+             ETLength += essence_element_BER_length - MXF_BER_LENGTH;
 
-             if ( BER_length == 0 )
+             if ( essence_element_BER_length == 0 )
                result = RESULT_KLV_CODING;
            }
 
          if ( ASDCP_SUCCESS(result) )
            {
-             if ( ! ( Overhead.WriteBER(ETLength, BER_length)                      // write encrypted triplet length
+             if ( ! ( Overhead.WriteBER(ETLength, essence_element_BER_length)                      // write encrypted triplet length
                       && Overhead.WriteBER(UUIDlen, MXF_BER_LENGTH)                // write ContextID length
                       && Overhead.WriteRaw(Info.ContextID, UUIDlen)              // write ContextID
                       && Overhead.WriteBER(sizeof(ui64_t), MXF_BER_LENGTH)         // write PlaintextOffset length
@@ -418,7 +433,7 @@ ASDCP::Write_EKLV_Packet(Kumu::FileWriter& File, const ASDCP::Dictionary& Dict,
                       && Overhead.WriteRaw((byte_t*)EssenceUL, SMPTE_UL_LENGTH)    // write the essence UL
                       && Overhead.WriteBER(sizeof(ui64_t), MXF_BER_LENGTH)         // write SourceLength length
                       && Overhead.WriteUi64BE(FrameBuf.Size())                     // write SourceLength
-                      && Overhead.WriteBER(CtFrameBuf.Size(), BER_length) ) )    // write ESV length
+                      && Overhead.WriteBER(CtFrameBuf.Size(), essence_element_BER_length) ) )    // write ESV length
                {
                  result = RESULT_KLV_CODING;
                }
@@ -460,18 +475,18 @@ ASDCP::Write_EKLV_Packet(Kumu::FileWriter& File, const ASDCP::Dictionary& Dict,
     }
   else
     {
-      ui32_t BER_length = MXF_BER_LENGTH;
+      ui32_t essence_element_BER_length = MinEssenceElementBerLength;
 
       if ( FrameBuf.Size() > 0x00ffffff ) // Need BER integer longer than MXF_BER_LENGTH bytes
        {
-         BER_length = Kumu::get_BER_length_for_value(FrameBuf.Size());
+         essence_element_BER_length = Kumu::get_BER_length_for_value(FrameBuf.Size());
 
-         if ( BER_length == 0 )
+         if ( essence_element_BER_length == 0 )
            result = RESULT_KLV_CODING;
        }
 
       Overhead.WriteRaw((byte_t*)EssenceUL, SMPTE_UL_LENGTH);
-      Overhead.WriteBER(FrameBuf.Size(), BER_length);
+      Overhead.WriteBER(FrameBuf.Size(), essence_element_BER_length);
 
       if ( ASDCP_SUCCESS(result) )
        result = File.Writev(Overhead.Data(), Overhead.Length());