o Fixed a bug in the index reader that allowed an out-of-bounds vector index to be...
[asdcplib.git] / src / AS_DCP_internal.h
index df342bf113cfdda87f0e681c84829e54777a2b32..c1df8aded6b09910a19ea989fe31a4618d717d34 100755 (executable)
@@ -60,7 +60,6 @@ extern MXF::RIP *g_RIP;
 
 namespace ASDCP
 {
-  void default_md_object_init();
 
   //
   static std::vector<int>
@@ -74,14 +73,14 @@ namespace ASDCP
       {
        assert(r >= pstr);
        if ( r > pstr )
-         result.push_back(atoi(pstr));
+         result.push_back(strtol(pstr, 0, 10));
 
        pstr = r + 1;
        r = strchr(pstr, '.');
       }
 
     if( strlen(pstr) > 0 )
-      result.push_back(atoi(pstr));
+      result.push_back(strtol(pstr, 0, 10));
 
     assert(result.size() == 3);
     return result;
@@ -134,25 +133,15 @@ namespace ASDCP
   Result_t EncryptFrameBuffer(const ASDCP::FrameBuffer&, ASDCP::FrameBuffer&, AESEncContext*);
   Result_t DecryptFrameBuffer(const ASDCP::FrameBuffer&, ASDCP::FrameBuffer&, AESDecContext*);
 
-  Result_t MD_to_JP2K_PDesc(const ASDCP::MXF::RGBAEssenceDescriptor&  EssenceDescriptor,
+  Result_t MD_to_JP2K_PDesc(const ASDCP::MXF::GenericPictureEssenceDescriptor&  EssenceDescriptor,
                            const ASDCP::MXF::JPEG2000PictureSubDescriptor& EssenceSubDescriptor,
                            const ASDCP::Rational& EditRate, const ASDCP::Rational& SampleRate,
                            ASDCP::JP2K::PictureDescriptor& PDesc);
 
   Result_t JP2K_PDesc_to_MD(const JP2K::PictureDescriptor& PDesc,
                            const ASDCP::Dictionary& dict,
-                           ASDCP::MXF::RGBAEssenceDescriptor *EssenceDescriptor,
-                           ASDCP::MXF::JPEG2000PictureSubDescriptor *EssenceSubDescriptor);
-
-  Result_t MD_to_JP2K_PDesc(const ASDCP::MXF::CDCIEssenceDescriptor&  EssenceDescriptor,
-                           const ASDCP::MXF::JPEG2000PictureSubDescriptor& EssenceSubDescriptor,
-                           const ASDCP::Rational& EditRate, const ASDCP::Rational& SampleRate,
-                           ASDCP::JP2K::PictureDescriptor& PDesc);
-
-  Result_t JP2K_PDesc_to_MD(const JP2K::PictureDescriptor& PDesc,
-                           const ASDCP::Dictionary& dict,
-                           ASDCP::MXF::CDCIEssenceDescriptor *EssenceDescriptor,
-                           ASDCP::MXF::JPEG2000PictureSubDescriptor *EssenceSubDescriptor);
+                           ASDCP::MXF::GenericPictureEssenceDescriptor& EssenceDescriptor,
+                           ASDCP::MXF::JPEG2000PictureSubDescriptor& EssenceSubDescriptor);
 
   Result_t PCM_ADesc_to_MD(PCM::AudioDescriptor& ADesc, ASDCP::MXF::WaveAudioDescriptor* ADescObj);
   Result_t MD_to_PCM_ADesc(ASDCP::MXF::WaveAudioDescriptor* ADescObj, PCM::AudioDescriptor& ADesc);
@@ -223,7 +212,7 @@ namespace ASDCP
        const MXF::RIP& GetRIP() const { return m_RIP; }
 
        //
-       Result_t OpenMXFRead(const char* filename)
+       Result_t OpenMXFRead(const std::string& filename)
        {
          m_LastPosition = 0;
          Result_t result = m_File.OpenRead(filename);
@@ -511,6 +500,7 @@ namespace ASDCP
 
        MaterialPackage*   m_MaterialPackage;
        SourcePackage*     m_FilePackage;
+       ContentStorage*    m_ContentStorage;
 
        FileDescriptor*    m_EssenceDescriptor;
        std::list<InterchangeObject*> m_EssenceSubDescriptorList;
@@ -525,9 +515,9 @@ namespace ASDCP
        DurationElementList_t m_DurationUpdateList;
 
       TrackFileWriter(const Dictionary& d) :
-       m_Dict(&d), m_HeaderPart(m_Dict), m_RIP(m_Dict),
-         m_HeaderSize(0), m_EssenceDescriptor(0),
-         m_FramesWritten(0), m_StreamOffset(0)
+       m_Dict(&d), m_HeaderSize(0), m_HeaderPart(m_Dict), m_RIP(m_Dict),
+         m_MaterialPackage(0), m_FilePackage(0), m_ContentStorage(0),
+         m_EssenceDescriptor(0), m_FramesWritten(0), m_StreamOffset(0)
          {
            default_md_object_init();
          }
@@ -579,14 +569,16 @@ namespace ASDCP
                           const std::string& TrackName, const UL& EssenceUL,
                           const UL& DataDefinition, const std::string& PackageLabel)
        {
-         //
-         ContentStorage* Storage = new ContentStorage(m_Dict);
-         m_HeaderPart.AddChildObject(Storage);
-         m_HeaderPart.m_Preface->ContentStorage = Storage->InstanceUID;
+         if ( m_ContentStorage == 0 )
+           {
+             m_ContentStorage = new ContentStorage(m_Dict);
+             m_HeaderPart.AddChildObject(m_ContentStorage);
+             m_HeaderPart.m_Preface->ContentStorage = m_ContentStorage->InstanceUID;
+           }
 
          EssenceContainerData* ECD = new EssenceContainerData(m_Dict);
          m_HeaderPart.AddChildObject(ECD);
-         Storage->EssenceContainerData.push_back(ECD->InstanceUID);
+         m_ContentStorage->EssenceContainerData.push_back(ECD->InstanceUID);
          ECD->IndexSID = 129;
          ECD->BodySID = 1;
 
@@ -602,19 +594,23 @@ namespace ASDCP
          m_MaterialPackage->Name = "AS-DCP Material Package";
          m_MaterialPackage->PackageUID = MaterialPackageUMID;
          m_HeaderPart.AddChildObject(m_MaterialPackage);
-         Storage->Packages.push_back(m_MaterialPackage->InstanceUID);
+         m_ContentStorage->Packages.push_back(m_MaterialPackage->InstanceUID);
 
          TrackSet<TimecodeComponent> MPTCTrack =
            CreateTimecodeTrack<MaterialPackage>(m_HeaderPart, *m_MaterialPackage,
                                                 tc_edit_rate, TCFrameRate, 0, m_Dict);
-         m_DurationUpdateList.push_back(&(MPTCTrack.Sequence->Duration));
-         m_DurationUpdateList.push_back(&(MPTCTrack.Clip->Duration));
+
+         MPTCTrack.Sequence->Duration.set_has_value();
+         m_DurationUpdateList.push_back(&(MPTCTrack.Sequence->Duration.get()));
+         MPTCTrack.Clip->Duration.set_has_value();
+         m_DurationUpdateList.push_back(&(MPTCTrack.Clip->Duration.get()));
 
          TrackSet<SourceClip> MPTrack =
            CreateTrackAndSequence<MaterialPackage, SourceClip>(m_HeaderPart, *m_MaterialPackage,
                                                                TrackName, clip_edit_rate, DataDefinition,
                                                                2, m_Dict);
-         m_DurationUpdateList.push_back(&(MPTrack.Sequence->Duration));
+         MPTrack.Sequence->Duration.set_has_value();
+         m_DurationUpdateList.push_back(&(MPTrack.Sequence->Duration.get()));
 
          MPTrack.Clip = new SourceClip(m_Dict);
          m_HeaderPart.AddChildObject(MPTrack.Clip);
@@ -622,7 +618,9 @@ namespace ASDCP
          MPTrack.Clip->DataDefinition = DataDefinition;
          MPTrack.Clip->SourcePackageID = SourcePackageUMID;
          MPTrack.Clip->SourceTrackID = 2;
-         m_DurationUpdateList.push_back(&(MPTrack.Clip->Duration));
+
+         MPTrack.Clip->Duration.set_has_value();
+         m_DurationUpdateList.push_back(&(MPTrack.Clip->Duration.get()));
 
   
          //
@@ -634,19 +632,25 @@ namespace ASDCP
          ECD->LinkedPackageUID = SourcePackageUMID;
 
          m_HeaderPart.AddChildObject(m_FilePackage);
-         Storage->Packages.push_back(m_FilePackage->InstanceUID);
+         m_ContentStorage->Packages.push_back(m_FilePackage->InstanceUID);
 
          TrackSet<TimecodeComponent> FPTCTrack =
            CreateTimecodeTrack<SourcePackage>(m_HeaderPart, *m_FilePackage,
                                               tc_edit_rate, TCFrameRate,
                                               ui64_C(3600) * TCFrameRate, m_Dict);
-         m_DurationUpdateList.push_back(&(FPTCTrack.Sequence->Duration));
-         m_DurationUpdateList.push_back(&(FPTCTrack.Clip->Duration));
+
+         FPTCTrack.Sequence->Duration.set_has_value();
+         m_DurationUpdateList.push_back(&(FPTCTrack.Sequence->Duration.get()));
+         FPTCTrack.Clip->Duration.set_has_value();
+         m_DurationUpdateList.push_back(&(FPTCTrack.Clip->Duration.get()));
+
          TrackSet<SourceClip> FPTrack =
            CreateTrackAndSequence<SourcePackage, SourceClip>(m_HeaderPart, *m_FilePackage,
                                                              TrackName, clip_edit_rate, DataDefinition,
                                                              2, m_Dict);
-         m_DurationUpdateList.push_back(&(FPTrack.Sequence->Duration));
+
+         FPTrack.Sequence->Duration.set_has_value();
+         m_DurationUpdateList.push_back(&(FPTrack.Sequence->Duration.get()));
 
          // Consult ST 379:2004 Sec. 6.3, "Element to track relationship" to see where "12" comes from.
          FPTrack.Track->TrackNumber = KM_i32_BE(Kumu::cp2i<ui32_t>((EssenceUL.Value() + 12)));
@@ -659,7 +663,9 @@ namespace ASDCP
          // for now we do not allow setting this value, so all files will be 'original'
          FPTrack.Clip->SourceTrackID = 0;
          FPTrack.Clip->SourcePackageID = NilUMID;
-         m_DurationUpdateList.push_back(&(FPTrack.Clip->Duration));
+
+         FPTrack.Clip->Duration.set_has_value();
+         m_DurationUpdateList.push_back(&(FPTrack.Clip->Duration.get()));
 
          m_EssenceDescriptor->LinkedTrackID = FPTrack.Track->TrackID;
        }
@@ -670,14 +676,16 @@ namespace ASDCP
                          const std::string& TrackName, const UL& DataDefinition,
                          const std::string& PackageLabel)
        {
-         //
-         ContentStorage* Storage = new ContentStorage(m_Dict);
-         m_HeaderPart.AddChildObject(Storage);
-         m_HeaderPart.m_Preface->ContentStorage = Storage->InstanceUID;
+         if ( m_ContentStorage == 0 )
+           {
+             m_ContentStorage = new ContentStorage(m_Dict);
+             m_HeaderPart.AddChildObject(m_ContentStorage);
+             m_HeaderPart.m_Preface->ContentStorage = m_ContentStorage->InstanceUID;
+           }
 
          EssenceContainerData* ECD = new EssenceContainerData(m_Dict);
          m_HeaderPart.AddChildObject(ECD);
-         Storage->EssenceContainerData.push_back(ECD->InstanceUID);
+         m_ContentStorage->EssenceContainerData.push_back(ECD->InstanceUID);
          ECD->IndexSID = 129;
          ECD->BodySID = 1;
 
@@ -693,19 +701,23 @@ namespace ASDCP
          m_MaterialPackage->Name = "AS-DCP Material Package";
          m_MaterialPackage->PackageUID = MaterialPackageUMID;
          m_HeaderPart.AddChildObject(m_MaterialPackage);
-         Storage->Packages.push_back(m_MaterialPackage->InstanceUID);
+         m_ContentStorage->Packages.push_back(m_MaterialPackage->InstanceUID);
 
          TrackSet<TimecodeComponent> MPTCTrack =
            CreateTimecodeTrack<MaterialPackage>(m_HeaderPart, *m_MaterialPackage,
                                                 tc_edit_rate, tc_frame_rate, 0, m_Dict);
-         m_DurationUpdateList.push_back(&(MPTCTrack.Sequence->Duration));
-         m_DurationUpdateList.push_back(&(MPTCTrack.Clip->Duration));
+
+         MPTCTrack.Sequence->Duration.set_has_value();
+         m_DurationUpdateList.push_back(&(MPTCTrack.Sequence->Duration.get()));
+         MPTCTrack.Clip->Duration.set_has_value();
+         m_DurationUpdateList.push_back(&(MPTCTrack.Clip->Duration.get()));
 
          TrackSet<DMSegment> MPTrack =
            CreateTrackAndSequence<MaterialPackage, DMSegment>(m_HeaderPart, *m_MaterialPackage,
                                                               TrackName, clip_edit_rate, DataDefinition,
                                                               2, m_Dict);
-         m_DurationUpdateList.push_back(&(MPTrack.Sequence->Duration));
+         MPTrack.Sequence->Duration.set_has_value();
+         m_DurationUpdateList.push_back(&(MPTrack.Sequence->Duration.get()));
 
          MPTrack.Clip = new DMSegment(m_Dict);
          m_HeaderPart.AddChildObject(MPTrack.Clip);
@@ -713,6 +725,7 @@ namespace ASDCP
          MPTrack.Clip->DataDefinition = DataDefinition;
          //  MPTrack.Clip->SourcePackageID = SourcePackageUMID;
          //  MPTrack.Clip->SourceTrackID = 2;
+
          m_DurationUpdateList.push_back(&(MPTrack.Clip->Duration));
 
   
@@ -725,20 +738,25 @@ namespace ASDCP
          ECD->LinkedPackageUID = SourcePackageUMID;
 
          m_HeaderPart.AddChildObject(m_FilePackage);
-         Storage->Packages.push_back(m_FilePackage->InstanceUID);
+         m_ContentStorage->Packages.push_back(m_FilePackage->InstanceUID);
 
          TrackSet<TimecodeComponent> FPTCTrack =
            CreateTimecodeTrack<SourcePackage>(m_HeaderPart, *m_FilePackage,
                                               clip_edit_rate, tc_frame_rate,
                                               ui64_C(3600) * tc_frame_rate, m_Dict);
-         m_DurationUpdateList.push_back(&(FPTCTrack.Sequence->Duration));
-         m_DurationUpdateList.push_back(&(FPTCTrack.Clip->Duration));
+
+         FPTCTrack.Sequence->Duration.set_has_value();
+         m_DurationUpdateList.push_back(&(FPTCTrack.Sequence->Duration.get()));
+         FPTCTrack.Clip->Duration.set_has_value();
+         m_DurationUpdateList.push_back(&(FPTCTrack.Clip->Duration.get()));
 
          TrackSet<DMSegment> FPTrack =
            CreateTrackAndSequence<SourcePackage, DMSegment>(m_HeaderPart, *m_FilePackage,
                                                             TrackName, clip_edit_rate, DataDefinition,
                                                             2, m_Dict);
-         m_DurationUpdateList.push_back(&(FPTrack.Sequence->Duration));
+
+         FPTrack.Sequence->Duration.set_has_value();
+         m_DurationUpdateList.push_back(&(FPTrack.Sequence->Duration.get()));
 
          FPTrack.Clip = new DMSegment(m_Dict);
          m_HeaderPart.AddChildObject(FPTrack.Clip);
@@ -747,6 +765,7 @@ namespace ASDCP
          FPTrack.Clip->EventComment = "ST 429-5 Timed Text";
 
          m_DurationUpdateList.push_back(&(FPTrack.Clip->Duration));
+
          m_EssenceDescriptor->LinkedTrackID = FPTrack.Track->TrackID;
        }
 
@@ -772,6 +791,7 @@ namespace ASDCP
              m_HeaderPart.EssenceContainers.push_back(CryptEssenceUL);
              m_HeaderPart.m_Preface->DMSchemes.push_back(UL(m_Dict->ul(MDD_CryptographicFrameworkLabel)));
              AddDMScrypt(m_HeaderPart, *m_FilePackage, m_Info, WrappingUL, m_Dict);
+             //// TODO: fix DMSegment Duration value
            }
          else
            {
@@ -813,7 +833,7 @@ namespace ASDCP
       h__ASDCPReader(const Dictionary&);
       virtual ~h__ASDCPReader();
 
-      Result_t OpenMXFRead(const char* filename);
+      Result_t OpenMXFRead(const std::string& filename);
       Result_t ReadEKLVFrame(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
                             const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC);
       Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset,