Fix HMAC sequence count on MXF read.
[asdcplib.git] / src / AS_DCP_internal.h
index 73b9e7a45fd89a8e93262d207a18c2d4031ad44c..57ed006a04dffcee8351ae8362d489e2603a6ba3 100755 (executable)
@@ -47,6 +47,10 @@ using namespace ASDCP::MXF;
 #endif
 
 
+// uncomment to remove MXFGCGenericEssenceMultipleMappings from your AS-02 files
+// #define ASDCP_GCMULTI_PATCH
+
+
 #ifdef DEFAULT_MD_DECL
 ASDCP::MXF::OP1aHeader *g_OP1aHeader;
 ASDCP::MXF::OPAtomIndexFooter *g_OPAtomIndexFooter;
@@ -178,6 +182,7 @@ namespace ASDCP
   Result_t 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);
 
   //
@@ -399,7 +404,8 @@ namespace ASDCP
        // Reads a Generic Stream Partition payload. Returns RESULT_FORMAT if the SID is
        // not present in the  RIP, or if the actual partition at ByteOffset does not have
        // a matching BodySID value. Encryption is not currently supported.
-       Result_t ReadGenericStreamPartitionPayload(const ui32_t sid, ASDCP::FrameBuffer& frame_buf)
+       Result_t ReadGenericStreamPartitionPayload(const ui32_t sid, ASDCP::FrameBuffer& frame_buf,
+                                                  AESDecContext* Ctx, HMACContext* HMAC)
        {
          Kumu::fpos_t start_offset = 0, end_offset = 0;
          ui32_t sequence = 0;
@@ -408,17 +414,23 @@ namespace ASDCP
          // Count the sequence length in because this is the sequence
          // value needed to  complete the HMAC.
          ASDCP::MXF::RIP::const_pair_iterator i;
-         for ( i = m_RIP.PairArray.begin(); i != m_RIP.PairArray.end(); ++i, ++sequence )
+         for ( i = m_RIP.PairArray.begin(); i != m_RIP.PairArray.end(); ++i)
            {
-             if ( sid == i->BodySID )
-               {
-                 start_offset = i->ByteOffset;
-               }
-             else if ( start_offset != 0 )
-               {
-                 end_offset = i->ByteOffset;
-                 break;
-               }
+              if ( sid == i->BodySID )
+                {
+                  assert( start_offset == 0);
+                  start_offset = i->ByteOffset;
+                }
+              else if ( start_offset != 0 )
+                {
+                  end_offset = i->ByteOffset;
+                  break;
+                }
+
+              if ( i->BodySID > 0 )
+                {
+                  ++sequence;
+                }
            }
 
          if ( start_offset == 0 || end_offset == 0 )
@@ -451,7 +463,7 @@ namespace ASDCP
                    }
                  else
                    {
-                     result = ReadEKLVPacket(0, sequence, frame_buf, m_Dict->ul(MDD_GenericStream_DataElement), 0, 0);
+                     result = ReadEKLVPacket(0, sequence, frame_buf, m_Dict->ul(MDD_GenericStream_DataElement), Ctx, HMAC);
                    }
                }
            }
@@ -629,14 +641,14 @@ namespace ASDCP
          if ( mxf_ver == MXFVersion_2004 )
            {
              m_HeaderPart.MinorVersion = MXF_2004_MinorVersion;
-             m_HeaderPart.m_Preface->Version = ((MXF_ObjectModelVersion < 8) | MXF_2004_MinorVersion);
+             m_HeaderPart.m_Preface->Version = ((MXF_ObjectModelVersion << 8) | MXF_2004_MinorVersion);
              m_HeaderPart.m_Preface->ObjectModelVersion = MXF_ObjectModelVersion;
            }
          else
            {
              assert(mxf_ver == MXFVersion_2011);
              m_HeaderPart.MinorVersion = MXF_2011_MinorVersion;
-             m_HeaderPart.m_Preface->Version = ((MXF_ObjectModelVersion < 8) | MXF_2011_MinorVersion);
+             m_HeaderPart.m_Preface->Version = ((MXF_ObjectModelVersion << 8) | MXF_2011_MinorVersion);
              m_HeaderPart.m_Preface->ObjectModelVersion = MXF_ObjectModelVersion;
            }
 
@@ -780,8 +792,10 @@ namespace ASDCP
          // Essence Descriptors
          //
          assert(m_Dict);
+#ifndef ASDCP_GCMULTI_PATCH
          UL GenericContainerUL(m_Dict->ul(MDD_GCMulti));
          m_HeaderPart.EssenceContainers.push_back(GenericContainerUL);
+#endif
 
          if ( m_Info.EncryptedEssence )
            {
@@ -840,7 +854,8 @@ namespace ASDCP
              if ( KM_SUCCESS(result) )
                {
                  result = Write_EKLV_Packet(m_File, *m_Dict, m_HeaderPart, m_Info, m_CtFrameBuf, m_FramesWritten,
-                                            m_StreamOffset, frame_buffer, GenericStream_DataElement.Value(), enc, hmac);
+                                            m_StreamOffset, frame_buffer, GenericStream_DataElement.Value(),
+                                            MXF_BER_LENGTH, enc, hmac);
                }
            }
 
@@ -900,6 +915,7 @@ namespace ASDCP
 
       Result_t CreateBodyPart(const MXF::Rational& EditRate, ui32_t BytesPerEditUnit = 0);
       Result_t WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf,const byte_t* EssenceUL,
+                              const ui32_t& MinEssenceElementBerLength,
                               AESEncContext* Ctx, HMACContext* HMAC);
       Result_t WriteASDCPFooter();
     };