o Fixed missing-index-partion bugs for AS-02 files.
authorjhurst <jhurst@cinecert.com>
Thu, 2 Jan 2014 23:29:22 +0000 (23:29 +0000)
committerjhurst <>
Thu, 2 Jan 2014 23:29:22 +0000 (23:29 +0000)
  o Improved integration of ST 377-4 MCA concepts with ST 429-2 static
    labels.
  o Added new EssenceType_t values for IMF/AS-02 track files.
  o Added detection for AS-02 track files to ASDCP::EssenceType()
  o Changed lots of "const char*" to "const std::string&" in the
    APIs defined by KM_fileio.h and AS_DCP.h.
  o Fixed VBR Delta Segment entries to correctly flag progressive
    material.
  o Fixed PCM unwrapping bugs in as-02-unwrap.

34 files changed:
src/AS_02.h
src/AS_02_JP2K.cpp
src/AS_02_PCM.cpp
src/AS_02_internal.h
src/AS_DCP.h
src/AS_DCP_ATMOS.cpp
src/AS_DCP_DCData.cpp
src/AS_DCP_DCData_internal.h
src/AS_DCP_JP2K.cpp
src/AS_DCP_MPEG2.cpp
src/AS_DCP_MXF.cpp
src/AS_DCP_PCM.cpp
src/AS_DCP_TimedText.cpp
src/AS_DCP_internal.h
src/DCData_ByteStream_Parser.cpp
src/DCData_Sequence_Parser.cpp
src/JP2K_Codestream_Parser.cpp
src/JP2K_Sequence_Parser.cpp
src/KM_fileio.cpp
src/KM_fileio.h
src/MPEG2_Parser.cpp
src/MXF.cpp
src/MXF.h
src/Makefile.am
src/PCMParserList.cpp
src/PCMParserList.h
src/PCM_Parser.cpp
src/TimedText_Parser.cpp
src/as-02-unwrap.cpp
src/asdcp-test.cpp
src/asdcp-wrap.cpp
src/h__02_Reader.cpp
src/h__02_Writer.cpp
src/h__Reader.cpp

index 34371524b9654ef8e8e30239f3c224966f029eac..6b34c777134ad595e3b552c9eb43d8a7b03819cb 100644 (file)
@@ -97,7 +97,6 @@ namespace AS_02
       Result_t Lookup(ui32_t frame_num, ASDCP::MXF::IndexTableSegment::IndexEntry&) const;
     };
 
-
     
     // Returns size in bytes of a single sample of data described by ADesc
     inline ui32_t CalcSampleSize(const ASDCP::MXF::WaveAudioDescriptor& d)
@@ -119,7 +118,8 @@ namespace AS_02
     }
 
     // Returns number of frames for data described by ADesc, given a duration in samples and an edit rate
-    inline ui32_t CalcFramesFromDurationInSamples(const ui32_t durationInSamples, const ASDCP::MXF::WaveAudioDescriptor& d, const ASDCP::Rational& edit_rate)
+    inline ui32_t CalcFramesFromDurationInSamples(const ui32_t durationInSamples, const ASDCP::MXF::WaveAudioDescriptor& d,
+                                                 const ASDCP::Rational& edit_rate)
     {
       return static_cast<ui32_t>(static_cast<ui64_t>(durationInSamples) *
                                 static_cast<ui64_t>(d.AudioSamplingRate.Denominator * edit_rate.Numerator) /
@@ -142,7 +142,7 @@ namespace AS_02
   };
  
   namespace JP2K
-  {
+  { 
     //
     class MXFWriter
     {
@@ -167,7 +167,7 @@ namespace AS_02
                         ASDCP::MXF::InterchangeObject_list_t& essence_sub_descriptor_list,
                         const ASDCP::Rational& edit_rate, const ui32_t& header_size = 16384,
                         const IndexStrategy_t& strategy = IS_FOLLOW, const ui32_t& partition_space = 10);
-      
+
       // Writes a frame of essence to the MXF file. If the optional AESEncContext
       // argument is present, the essence is encrypted prior to writing.
       // Fails if the file is not open, is finalized, or an operating system
@@ -238,7 +238,7 @@ namespace AS_02
     // the reader to signal the number of samples to be read by each call to ReadFrame();
 
     //
-    class MXFWriter
+      class MXFWriter
     {
       class h__Writer;
       ASDCP::mem_ptr<h__Writer> m_Writer;
index a8eff1a4e91060e5bfefb0d4326fd386be49a159..48b98fec44d44fd7538b754dc9728fbf447cc8c9 100644 (file)
@@ -55,8 +55,6 @@ class AS_02::JP2K::MXFReader::h__Reader : public AS_02::h__AS02Reader
   ASDCP_NO_COPY_CONSTRUCT(h__Reader);
 
 public:
-  PictureDescriptor m_PDesc;        // codestream parameter list
-
   h__Reader(const Dictionary& d) :
     AS_02::h__AS02Reader(d) {}
 
@@ -229,7 +227,7 @@ AS_02::JP2K::MXFReader::FillWriterInfo(WriterInfo& Info) const
 //------------------------------------------------------------------------------------------
 
 //
-class AS_02::JP2K::MXFWriter::h__Writer : public AS_02::h__AS02Writer
+class AS_02::JP2K::MXFWriter::h__Writer : public AS_02::h__AS02WriterFrame
 {
   ASDCP_NO_COPY_CONSTRUCT(h__Writer);
   h__Writer();
@@ -237,10 +235,9 @@ class AS_02::JP2K::MXFWriter::h__Writer : public AS_02::h__AS02Writer
   JPEG2000PictureSubDescriptor* m_EssenceSubDescriptor;
 
 public:
-  PictureDescriptor m_PDesc;
   byte_t            m_EssenceUL[SMPTE_UL_LENGTH];
 
-  h__Writer(const Dictionary& d) : h__AS02Writer(d), m_EssenceSubDescriptor(0) {
+  h__Writer(const Dictionary& d) : h__AS02WriterFrame(d), m_EssenceSubDescriptor(0) {
     memset(m_EssenceUL, 0, SMPTE_UL_LENGTH);
   }
 
@@ -334,6 +331,11 @@ AS_02::JP2K::MXFWriter::h__Writer::SetSourceStream(const std::string& label, con
       result = WriteAS02Header(label, UL(m_Dict->ul(MDD_JPEG_2000WrappingFrame)),
                               PICT_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_PictureDataDef)),
                               edit_rate, derive_timecode_rate_from_edit_rate(edit_rate));
+
+      if ( KM_SUCCESS(result) )
+       {
+         this->m_IndexWriter.SetPrimerLookup(&this->m_HeaderPart.m_Primer);
+       }
     }
 
   return result;
index 2ffc45e0ccd4f89686e6fa969c91367e9141db85..9a6a98cf937567ca7aa306afbe23ff8fc9465831 100644 (file)
@@ -49,6 +49,7 @@ class AS_02::PCM::MXFReader::h__Reader : public AS_02::h__AS02Reader
 {
   ui64_t m_ClipEssenceBegin;
   ui64_t m_SamplesPerFrame;
+  ui32_t m_BytesPerFrame;
   ui32_t m_ContainerDuration;
 
   ASDCP_NO_COPY_CONSTRUCT(h__Reader);
@@ -56,7 +57,7 @@ class AS_02::PCM::MXFReader::h__Reader : public AS_02::h__AS02Reader
 
 public:
   h__Reader(const Dictionary& d) : AS_02::h__AS02Reader(d), m_ClipEssenceBegin(0),
-                                  m_SamplesPerFrame(0), m_ContainerDuration(0) {}
+                                  m_SamplesPerFrame(0), m_BytesPerFrame(0), m_ContainerDuration(0) {}
   virtual ~h__Reader() {}
 
   ASDCP::Result_t    OpenRead(const std::string&, const ASDCP::Rational& edit_rate);
@@ -75,17 +76,20 @@ AS_02::PCM::MXFReader::h__Reader::OpenRead(const std::string& filename, const AS
 
   if( KM_SUCCESS(result) )
     {
-      if ( KM_SUCCESS(m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(WaveAudioDescriptor),
-                                                    reinterpret_cast<InterchangeObject**>(&wave_descriptor))) )
+      InterchangeObject* tmp_obj = 0;
+
+      if ( KM_SUCCESS(m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(WaveAudioDescriptor), &tmp_obj)) )
        {
-         if ( wave_descriptor == 0 )
-           {
-             DefaultLogSink().Error("WaveAudioDescriptor object not found.\n");
-             return RESULT_AS02_FORMAT;
-           }
+         wave_descriptor = dynamic_cast<ASDCP::MXF::WaveAudioDescriptor*>(tmp_obj);
        }
     }
 
+  if ( wave_descriptor == 0 )
+    {
+      DefaultLogSink().Error("WaveAudioDescriptor object not found.\n");
+      result = RESULT_AS02_FORMAT;
+    }
+
   if ( KM_SUCCESS(result) )
     result = m_IndexAccess.Lookup(0, tmp_entry);
 
@@ -131,8 +135,9 @@ AS_02::PCM::MXFReader::h__Reader::OpenRead(const std::string& filename, const AS
 
          m_ClipEssenceBegin = m_File.Tell();
          m_SamplesPerFrame = AS_02::MXF::CalcSamplesPerFrame(*wave_descriptor, edit_rate);
-         m_ContainerDuration = static_cast<ui32_t>(8ULL * reader.Length() /
-                                                   (m_SamplesPerFrame * wave_descriptor->ChannelCount * wave_descriptor->QuantizationBits));
+         m_BytesPerFrame = AS_02::MXF::CalcFrameBufferSize(*wave_descriptor, edit_rate);
+         m_ContainerDuration = static_cast<ui32_t>(reader.Length() / ( m_SamplesPerFrame * AS_02::MXF::CalcSampleSize(*wave_descriptor)));
+
        }
     }
 
@@ -144,8 +149,6 @@ ASDCP::Result_t
 AS_02::PCM::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, ASDCP::PCM::FrameBuffer& FrameBuf,
                                            ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC)
 {
-  ASDCP::MXF::WaveAudioDescriptor* wave_descriptor = 0;
-
   if ( ! m_File.IsOpen() )
     {
       return RESULT_INIT;
@@ -157,23 +160,9 @@ AS_02::PCM::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, ASDCP::PCM::FrameBu
     }
 
   assert(m_ClipEssenceBegin);
+  ui64_t position = m_ClipEssenceBegin + ( FrameNum * m_BytesPerFrame );
   Result_t result = RESULT_OK;
 
-  if( KM_SUCCESS(result) )
-    {
-      if ( KM_SUCCESS(m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(WaveAudioDescriptor),
-                                                    reinterpret_cast<InterchangeObject**>(&wave_descriptor))) )
-       {
-         if ( wave_descriptor == 0 )
-           {
-             DefaultLogSink().Error("WaveAudioDescriptor object not found.\n");
-             return RESULT_AS02_FORMAT;
-           }
-       }
-    }
-
-  ui64_t position = m_ClipEssenceBegin + ( FrameNum * m_SamplesPerFrame * wave_descriptor->ChannelCount * wave_descriptor->BlockAlign );
-
   if ( m_File.Tell() != position )
     {
       result = m_File.Seek(position);
@@ -181,12 +170,12 @@ AS_02::PCM::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, ASDCP::PCM::FrameBu
 
   if ( KM_SUCCESS(result) )
     {
-      result = m_File.Read(FrameBuf.Data(), m_SamplesPerFrame * wave_descriptor->ChannelCount * wave_descriptor->BlockAlign);
+      result = m_File.Read(FrameBuf.Data(), m_BytesPerFrame);
     }
 
   if ( KM_SUCCESS(result) )
     {
-      FrameBuf.Size(m_SamplesPerFrame * wave_descriptor->ChannelCount * wave_descriptor->BlockAlign);
+      FrameBuf.Size(m_BytesPerFrame);
     }
 
   return result;
@@ -322,7 +311,7 @@ AS_02::PCM::MXFReader::DumpIndex(FILE* stream) const
 //------------------------------------------------------------------------------------------
 
 //
-class AS_02::PCM::MXFWriter::h__Writer : public AS_02::h__AS02Writer
+class AS_02::PCM::MXFWriter::h__Writer : public AS_02::h__AS02WriterClip
 {
   ASDCP_NO_COPY_CONSTRUCT(h__Writer);
   h__Writer();
@@ -333,7 +322,7 @@ public:
   ui32_t m_BytesPerFrame;
   ui32_t m_SamplesPerFrame;
 
-  h__Writer(const Dictionary& d) : AS_02::h__AS02Writer(d), m_WaveAudioDescriptor(0), m_BytesPerFrame(0), m_SamplesPerFrame(0)
+  h__Writer(const Dictionary& d) : AS_02::h__AS02WriterClip(d), m_WaveAudioDescriptor(0), m_BytesPerFrame(0), m_SamplesPerFrame(0)
   {
     memset(m_EssenceUL, 0, SMPTE_UL_LENGTH);
   }
@@ -355,15 +344,15 @@ AS_02::PCM::MXFWriter::h__Writer::OpenWrite(const std::string& filename, ASDCP::
 {
   assert(essence_descriptor);
 
-  if ( essence_descriptor->GetUL() != UL(m_Dict->ul(MDD_WaveAudioDescriptor)) )
+  m_WaveAudioDescriptor = dynamic_cast<ASDCP::MXF::WaveAudioDescriptor*>(essence_descriptor);
+
+  if ( m_WaveAudioDescriptor == 0 )
     {
       DefaultLogSink().Error("Essence descriptor is not a WaveAudioDescriptor.\n");
       essence_descriptor->Dump();
       return RESULT_AS02_FORMAT;
     }
 
-  m_WaveAudioDescriptor = reinterpret_cast<ASDCP::MXF::WaveAudioDescriptor*>(essence_descriptor);
-
   if ( ! m_State.Test_BEGIN() )
     {
       return RESULT_STATE;
@@ -420,10 +409,16 @@ AS_02::PCM::MXFWriter::h__Writer::SetSourceStream(const ASDCP::Rational& edit_ra
       m_BytesPerFrame = AS_02::MXF::CalcFrameBufferSize(*m_WaveAudioDescriptor, edit_rate);
       m_SamplesPerFrame = AS_02::MXF::CalcSamplesPerFrame(*m_WaveAudioDescriptor, edit_rate);
       m_WaveAudioDescriptor->ContainerDuration = 0;
-
+      assert(m_BytesPerFrame);
       result = WriteAS02Header(PCM_PACKAGE_LABEL, UL(m_Dict->ul(MDD_WAVWrappingClip)),
                               SOUND_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_SoundDataDef)),
-                              m_EssenceDescriptor->SampleRate, derive_timecode_rate_from_edit_rate(edit_rate), m_BytesPerFrame);
+                              m_EssenceDescriptor->SampleRate, derive_timecode_rate_from_edit_rate(edit_rate));
+
+      if ( KM_SUCCESS(result) )
+       {
+         this->m_IndexWriter.SetEditRate(m_WaveAudioDescriptor->AudioSamplingRate,
+                                         AS_02::MXF::CalcSampleSize(*m_WaveAudioDescriptor));
+       }
     }
 
   return result;
@@ -467,7 +462,7 @@ AS_02::PCM::MXFWriter::h__Writer::WriteFrame(const FrameBuffer& frame_buf, AESEn
 
   if ( KM_SUCCESS(result) )
     {
-      m_FramesWritten++;
+      m_FramesWritten += m_SamplesPerFrame;
     }
 
   return result;
@@ -483,14 +478,11 @@ AS_02::PCM::MXFWriter::h__Writer::Finalize()
 
   m_State.Goto_FINAL();
 
-  Result_t result = FinalizeClip(m_BytesPerFrame);
+  Result_t result = FinalizeClip(AS_02::MXF::CalcSampleSize(*m_WaveAudioDescriptor));
 
   if ( KM_SUCCESS(result) )
     {
-      m_FramesWritten = m_FramesWritten * m_SamplesPerFrame;
-      m_IndexWriter.ThisPartition = m_File.Tell();
-      m_IndexWriter.WriteToFile(m_File);
-      m_RIP.PairArray.push_back(RIP::Pair(0, m_IndexWriter.ThisPartition));
+      m_IndexWriter.m_Duration = m_FramesWritten;
       WriteAS02Footer();
     }
 
@@ -541,7 +533,6 @@ AS_02::PCM::MXFWriter::RIP()
   return m_Writer->m_RIP;
 }
 
-
 // Open the file for writing. The file must not exist. Returns error if
 // the operation cannot be completed.
 ASDCP::Result_t
index 0a45a2456d8d2e823be1b482c4f2f69a86048614..4bdb64cf1342daf7a7bd692ad2c41ba2c69f4747 100644 (file)
@@ -52,95 +52,273 @@ namespace AS_02
 
   void default_md_object_init();
 
+
+  //
+  class h__AS02Reader : public ASDCP::MXF::TrackFileReader<ASDCP::MXF::OP1aHeader, AS_02::MXF::AS02IndexReader>
+    {
+      ASDCP_NO_COPY_CONSTRUCT(h__AS02Reader);
+      h__AS02Reader();
+
+    public:
+      h__AS02Reader(const ASDCP::Dictionary&);
+      virtual ~h__AS02Reader();
+
+      Result_t OpenMXFRead(const char* filename);
+
+      // USE FRAME WRAPPING...
+      Result_t ReadEKLVFrame(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
+                            const byte_t* EssenceUL, ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC);
+
+     // OR CLIP WRAPPING...
+      // clip wrapping is handled directly by the essence-specific classes
+      //      Result_t ReadyClip(const ui32_t& FrameNum, const byte_t* EssenceUL, ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC, ui64_t& position);
+      ///      Result_t ReadClipBlock(ASDCP::FrameBuffer& FrameBuf, const ui32_t& read_size);
+
+      // NOT BOTH!
+    };
+
+
   namespace MXF
   {
     //
-    class AS02IndexWriter : public ASDCP::MXF::Partition
+    class AS02IndexWriterVBR : public ASDCP::MXF::Partition
       {
        ASDCP::MXF::IndexTableSegment*  m_CurrentSegment;
-       ui32_t  m_BytesPerEditUnit;
        ASDCP::MXF::Rational m_EditRate;
 
-       KM_NO_COPY_CONSTRUCT(AS02IndexWriter);
-       AS02IndexWriter();
+       KM_NO_COPY_CONSTRUCT(AS02IndexWriterVBR);
+       AS02IndexWriterVBR();
 
       public:
        const ASDCP::Dictionary*&  m_Dict;
        ASDCP::IPrimerLookup*      m_Lookup;
       
-       AS02IndexWriter(const ASDCP::Dictionary*&);
-       virtual ~AS02IndexWriter();
+       AS02IndexWriterVBR(const ASDCP::Dictionary*&);
+       virtual ~AS02IndexWriterVBR();
+
+       //
+       void SetPrimerLookup(ASDCP::IPrimerLookup* lookup) {
+         assert(lookup);
+         m_Lookup = lookup;
+       }
 
        Result_t WriteToFile(Kumu::FileWriter& Writer);
-       void     ResetCBR(Kumu::fpos_t offset);
        void     Dump(FILE* = 0);
 
        ui32_t GetDuration() const;
        void PushIndexEntry(const ASDCP::MXF::IndexTableSegment::IndexEntry&);
-       void SetIndexParamsCBR(ASDCP::IPrimerLookup* lookup, ui32_t size, const ASDCP::Rational& Rate);
-       void SetIndexParamsVBR(ASDCP::IPrimerLookup* lookup, const ASDCP::Rational& Rate, Kumu::fpos_t offset);
       };
-  }
 
-  //
-  class h__AS02Reader : public ASDCP::MXF::TrackFileReader<ASDCP::MXF::OP1aHeader, AS_02::MXF::AS02IndexReader>
-    {
-      ASDCP_NO_COPY_CONSTRUCT(h__AS02Reader);
-      h__AS02Reader();
 
-    public:
-      h__AS02Reader(const ASDCP::Dictionary&);
-      virtual ~h__AS02Reader();
+   //
+    class AS02IndexWriterCBR : public ASDCP::MXF::Partition
+      {
+       ASDCP::MXF::IndexTableSegment*  m_CurrentSegment;
+       ASDCP::MXF::Rational m_EditRate;
 
-      Result_t OpenMXFRead(const char* filename);
+       KM_NO_COPY_CONSTRUCT(AS02IndexWriterCBR);
+       AS02IndexWriterCBR();
 
-      // USE FRAME WRAPPING...
-      Result_t ReadEKLVFrame(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
-                            const byte_t* EssenceUL, ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC);
+      public:
+       const ASDCP::Dictionary*&  m_Dict;
+       ASDCP::IPrimerLookup* m_Lookup;
+       ui32_t m_Duration;
+       ui32_t m_SampleSize;
+      
+       AS02IndexWriterCBR(const ASDCP::Dictionary*&);
+       virtual ~AS02IndexWriterCBR();
 
-     // OR CLIP WRAPPING...
-      // clip wrapping is handled directly by the essence-specific classes
-      //      Result_t ReadyClip(const ui32_t& FrameNum, const byte_t* EssenceUL, ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC, ui64_t& position);
-      ///      Result_t ReadClipBlock(ASDCP::FrameBuffer& FrameBuf, const ui32_t& read_size);
+       //
+       void SetPrimerLookup(ASDCP::IPrimerLookup* lookup) {
+         assert(lookup);
+         m_Lookup = lookup;
+       }
 
-      // NOT BOTH!
-    };
+       Result_t WriteToFile(Kumu::FileWriter& Writer);
+       ui32_t GetDuration() const;
+       void SetEditRate(const ASDCP::Rational& edit_rate, const ui32_t& sample_size);
+      };
+  }
 
   //
+  template <class IndexWriterType>
   class h__AS02Writer : public ASDCP::MXF::TrackFileWriter<ASDCP::MXF::OP1aHeader>
     {
       ASDCP_NO_COPY_CONSTRUCT(h__AS02Writer);
       h__AS02Writer();
 
     public:
-      ui64_t  m_ECStart; // offset of the first essence element
-      ui64_t  m_ClipStart;  // state variable for clip-wrap-in-progress
       ui32_t  m_PartitionSpace;  // edit units per partition
-      AS_02::MXF::AS02IndexWriter m_IndexWriter;
-      IndexStrategy_t m_IndexStrategy; // per SMPTE ST 2067-5
+      IndexWriterType m_IndexWriter;
+      ui64_t  m_ECStart; // offset of the first essence element
+
+      //
+      h__AS02Writer(const ASDCP::Dictionary& d) :
+          ASDCP::MXF::TrackFileWriter<ASDCP::MXF::OP1aHeader>(d), m_IndexWriter(m_Dict), m_ECStart(0) {}
 
-      h__AS02Writer(const Dictionary&);
-      virtual ~h__AS02Writer();
+      ~h__AS02Writer() {}
 
+
+      
       // all the above for a single source clip
       Result_t WriteAS02Header(const std::string& PackageLabel, const ASDCP::UL& WrappingUL,
                               const std::string& TrackName, const ASDCP::UL& EssenceUL,
                               const ASDCP::UL& DataDefinition, const ASDCP::Rational& EditRate,
-                              ui32_t TCFrameRate, ui32_t BytesPerEditUnit = 0);
+                              const ui32_t& TCFrameRate)
+      {
+       if ( EditRate.Numerator == 0 || EditRate.Denominator == 0 )
+         {
+           DefaultLogSink().Error("Non-zero edit-rate reqired.\n");
+           return RESULT_PARAM;
+         }
+
+       InitHeader();
+
+       AddSourceClip(EditRate, EditRate/*TODO: for a moment*/, TCFrameRate, TrackName, EssenceUL, DataDefinition, PackageLabel);
+       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_IndexWriter.OperationalPattern = this->m_HeaderPart.OperationalPattern;
+       this->m_IndexWriter.EssenceContainers = this->m_HeaderPart.EssenceContainers;
+
+       Result_t result = this->m_HeaderPart.WriteToFile(this->m_File, this->m_HeaderSize);
+
+       if ( KM_SUCCESS(result) )
+         {
+           this->m_PartitionSpace *= floor( EditRate.Quotient() + 0.5 );  // convert seconds to edit units
+           this->m_ECStart = this->m_File.Tell();
+           this->m_IndexWriter.IndexSID = 129;
+
+           UL body_ul(this->m_Dict->ul(MDD_ClosedCompleteBodyPartition));
+           Partition body_part(this->m_Dict);
+           body_part.BodySID = 1;
+           body_part.OperationalPattern = this->m_HeaderPart.OperationalPattern;
+           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
+         }
+
+       return result;
+      }
+
+      // standard method of writing the header and footer of a completed AS-02 file
+      //
+      Result_t WriteAS02Footer()
+      {
+       if ( this->m_IndexWriter.GetDuration() > 0 )
+         {
+           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));
+         }
+
+       // update all Duration properties
+       ASDCP::MXF::Partition footer_part(this->m_Dict);
+       DurationElementList_t::iterator dli = this->m_DurationUpdateList.begin();
+
+       for (; dli != this->m_DurationUpdateList.end(); ++dli )
+         {
+           **dli = this->m_FramesWritten;
+         }
+
+       this->m_EssenceDescriptor->ContainerDuration = this->m_FramesWritten;
+       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_HeaderPart.FooterPartition = here;
+
+       assert(this->m_Dict);
+       footer_part.OperationalPattern = this->m_HeaderPart.OperationalPattern;
+       footer_part.EssenceContainers = this->m_HeaderPart.EssenceContainers;
+       footer_part.FooterPartition = here;
+       footer_part.ThisPartition = here;
+
+       UL footer_ul(this->m_Dict->ul(MDD_CompleteFooter));
+       Result_t result = footer_part.WriteToFile(this->m_File, footer_ul);
+
+       if ( KM_SUCCESS(result) )
+         result = this->m_RIP.WriteToFile(this->m_File);
+
+       if ( KM_SUCCESS(result) )
+         result = this->m_File.Seek(0);
+       
+       if ( KM_SUCCESS(result) )
+         result = m_HeaderPart.WriteToFile(this->m_File, this->m_HeaderSize);
+  
+       if ( KM_SUCCESS(result) )
+         {
+           ASDCP::MXF::Array<ASDCP::MXF::RIP::Pair>::const_iterator i = this->m_RIP.PairArray.begin();
+           ui64_t header_byte_count = this->m_HeaderPart.HeaderByteCount;
+           ui64_t previous_partition = 0;
+
+           for ( i = this->m_RIP.PairArray.begin(); KM_SUCCESS(result) && i != this->m_RIP.PairArray.end(); ++i )
+             {
+               ASDCP::MXF::Partition plain_part(this->m_Dict);
+               result = this->m_File.Seek(i->ByteOffset);
+
+               if ( KM_SUCCESS(result) )
+                 result = plain_part.InitFromFile(this->m_File);
+               
+               if ( KM_SUCCESS(result)
+                    && ( plain_part.IndexSID > 0 || plain_part.BodySID > 0 ) )
+                 {
+                   plain_part.PreviousPartition = previous_partition;
+                   plain_part.FooterPartition = footer_part.ThisPartition;
+                   previous_partition = plain_part.ThisPartition;
+                   result = this->m_File.Seek(i->ByteOffset);
+
+                   if ( KM_SUCCESS(result) )
+                     {
+                       UL tmp_ul = plain_part.GetUL();
+                       result = plain_part.WriteToFile(this->m_File, tmp_ul);
+                     }
+                 }
+             }
+         }
+       
+       this->m_File.Close();
+       return result;
+      }
+    };
+
+  //
+  class h__AS02WriterFrame : public h__AS02Writer<AS_02::MXF::AS02IndexWriterVBR>
+    {
+      ASDCP_NO_COPY_CONSTRUCT(h__AS02WriterFrame);
+      h__AS02WriterFrame();
+
+    public:
+      IndexStrategy_t m_IndexStrategy; // per SMPTE ST 2067-5
+
+      h__AS02WriterFrame(const Dictionary&);
+      virtual ~h__AS02WriterFrame();
 
-      // USE FRAME WRAPPING...
       Result_t WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf,const byte_t* EssenceUL,
                               AESEncContext* Ctx, HMACContext* HMAC);
+    };
+
+  //
+  class h__AS02WriterClip : public h__AS02Writer<AS_02::MXF::AS02IndexWriterCBR>
+    {
+      ASDCP_NO_COPY_CONSTRUCT(h__AS02WriterClip);
+      h__AS02WriterClip();
+
+    public:
+      ui64_t  m_ECStart; // offset of the first essence element
+      ui64_t  m_ClipStart;  // state variable for clip-wrap-in-progress
+      //      AS_02::MXF::AS02IndexWriterCBR m_IndexWriter;
+      IndexStrategy_t m_IndexStrategy; // per SMPTE ST 2067-5
+
+      h__AS02WriterClip(const Dictionary&);
+      virtual ~h__AS02WriterClip();
 
-      // OR CLIP WRAPPING...
       bool HasOpenClip() const;
       Result_t StartClip(const byte_t* EssenceUL, AESEncContext* Ctx, HMACContext* HMAC);
       Result_t WriteClipBlock(const ASDCP::FrameBuffer& FrameBuf);
       Result_t FinalizeClip(ui32_t bytes_per_frame);
-
-      // NOT BOTH!
-
-      Result_t WriteAS02Footer();
     };
 
 } // namespace AS_02
index 6f9969805b37d017241aa33873931af49ec41b03..6b598cc301c14713763cbe10779b12e29d1bf876 100755 (executable)
@@ -208,8 +208,12 @@ namespace ASDCP {
   // The file accessors in this library implement a bounded set of essence types.
   // This list will be expanded when support for new types is added to the library.
   enum EssenceType_t {
-    ESS_UNKNOWN,              // the file is not a supported AS-DCP essence container
-    ESS_MPEG2_VES,            // the file contains an MPEG video elementary stream
+    ESS_UNKNOWN,              // the file is not a supported AS-DCP of AS-02 essence container
+
+    // 
+    ESS_MPEG2_VES,            // the file contains an MPEG-2 video elementary stream
+
+    // d-cinema essence types
     ESS_JPEG_2000,            // the file contains one or more JPEG 2000 codestreams
     ESS_PCM_24b_48k,          // the file contains one or more PCM audio pairs
     ESS_PCM_24b_96k,          // the file contains one or more PCM audio pairs
@@ -217,18 +221,25 @@ namespace ASDCP {
     ESS_JPEG_2000_S,          // the file contains one or more JPEG 2000 codestream pairs (stereoscopic)
     ESS_DCDATA_UNKNOWN,       // the file contains one or more D-Cinema Data bytestreams
     ESS_DCDATA_DOLBY_ATMOS,   // the file contains one or more DolbyATMOS bytestreams
+
+    // IMF essence types
+    ESS_AS02_JPEG_2000,       // the file contains one or more JPEG 2000 codestreams
+    ESS_AS02_PCM_24b_48k,     // the file contains one or more PCM audio pairs, clip wrapped
+    ESS_AS02_PCM_24b_96k,     // the file contains one or more PCM audio pairs, clip wrapped
+    ESS_AS02_TIMED_TEXT,      // the file contains a TTML document and zero or more resources
+
     ESS_MAX
   };
 
   // Determine the type of essence contained in the given MXF file. RESULT_OK
   // is returned if the file is successfully opened and contains a valid MXF
   // stream. If there is an error, the result code will indicate the reason.
-  Result_t EssenceType(const char* filename, EssenceType_t& type);
+  Result_t EssenceType(const std::string& filename, EssenceType_t& type);
 
   // Determine the type of essence contained in the given raw file. RESULT_OK
   // is returned if the file is successfully opened and contains a known
   // stream type. If there is an error, the result code will indicate the reason.
-  Result_t RawEssenceType(const char* filename, EssenceType_t& type);
+  Result_t RawEssenceType(const std::string& filename, EssenceType_t& type);
 
 
   //---------------------------------------------------------------------------------
@@ -707,7 +718,7 @@ namespace ASDCP {
 
          // Opens the stream for reading, parses enough data to provide a complete
          // set of stream metadata for the MXFWriter below.
-         Result_t OpenRead(const char* filename) const;
+         Result_t OpenRead(const std::string& filename) const;
 
          // Fill a VideoDescriptor struct with the values from the file's header.
          // Returns RESULT_INIT if the file is not open.
@@ -745,7 +756,7 @@ namespace ASDCP {
          // Open the file for writing. The file must not exist. Returns error if
          // the operation cannot be completed or if nonsensical data is discovered
          // in the essence descriptor.
-         Result_t OpenWrite(const char* filename, const WriterInfo&,
+         Result_t OpenWrite(const std::string& filename, const WriterInfo&,
                             const VideoDescriptor&, ui32_t HeaderSize = 16384);
 
          // Writes a frame of essence to the MXF file. If the optional AESEncContext
@@ -777,7 +788,7 @@ namespace ASDCP {
 
          // Open the file for reading. The file must exist. Returns error if the
          // operation cannot be completed.
-         Result_t OpenRead(const char* filename) const;
+         Result_t OpenRead(const std::string& filename) const;
 
          // Returns RESULT_INIT if the file is not open.
          Result_t Close() const;
@@ -848,6 +859,7 @@ namespace ASDCP {
        CF_CFG_3, // 7.1 (SDDS) with optional HI/VI
        CF_CFG_4, // Wild Track Format
        CF_CFG_5, // 7.1 DS with optional HI/VI
+       CF_CFG_6, // ST 377-4 (MCA) labels (see also ASDCP::MXF::decode_mca_string)
        CF_MAXIMUM
       };
 
@@ -918,7 +930,7 @@ namespace ASDCP {
          // Opens the stream for reading, parses enough data to provide a complete
          // set of stream metadata for the MXFWriter below. PictureRate controls
          // ther frame rate for the MXF frame wrapping option.
-         Result_t OpenRead(const char* filename, const Rational& PictureRate) const;
+         Result_t OpenRead(const std::string& filename, const Rational& PictureRate) const;
 
          // Fill an AudioDescriptor struct with the values from the file's header.
          // Returns RESULT_INIT if the file is not open.
@@ -953,7 +965,7 @@ namespace ASDCP {
          // Open the file for writing. The file must not exist. Returns error if
          // the operation cannot be completed or if nonsensical data is discovered
          // in the essence descriptor.
-         Result_t OpenWrite(const char* filename, const WriterInfo&,
+         Result_t OpenWrite(const std::string& filename, const WriterInfo&,
                             const AudioDescriptor&, ui32_t HeaderSize = 16384);
 
          // Writes a frame of essence to the MXF file. If the optional AESEncContext
@@ -985,7 +997,7 @@ namespace ASDCP {
 
          // Open the file for reading. The file must exist. Returns error if the
          // operation cannot be completed.
-         Result_t OpenRead(const char* filename) const;
+         Result_t OpenRead(const std::string& filename) const;
 
          // Returns RESULT_INIT if the file is not open.
          Result_t Close() const;
@@ -1124,7 +1136,7 @@ namespace ASDCP {
          // The frame buffer's PlaintextOffset parameter will be set to the first
          // byte of the data segment. Set this value to zero if you want
          // encrypted headers.
-         Result_t OpenReadFrame(const char* filename, FrameBuffer&) const;
+         Result_t OpenReadFrame(const std::string& filename, FrameBuffer&) const;
 
          // Fill a PictureDescriptor struct with the values from the file's codestream.
          // Returns RESULT_INIT if the file is not open.
@@ -1154,7 +1166,7 @@ namespace ASDCP {
          // MXFWriter below.  If the "pedantic" parameter is given and is true, the
          // parser will check the metadata for each codestream and fail if a
          // mismatch is detected.
-         Result_t OpenRead(const char* filename, bool pedantic = false) const;
+         Result_t OpenRead(const std::string& filename, bool pedantic = false) const;
 
          // Opens a file sequence for reading.  The sequence is expected to contain one or
          // more filenames, each naming a file containing the codestream for exactly one
@@ -1202,7 +1214,7 @@ namespace ASDCP {
          // Open the file for writing. The file must not exist. Returns error if
          // the operation cannot be completed or if nonsensical data is discovered
          // in the essence descriptor.
-         Result_t OpenWrite(const char* filename, const WriterInfo&,
+         Result_t OpenWrite(const std::string& filename, const WriterInfo&,
                             const PictureDescriptor&, ui32_t HeaderSize = 16384);
 
          // Writes a frame of essence to the MXF file. If the optional AESEncContext
@@ -1234,7 +1246,7 @@ namespace ASDCP {
 
          // Open the file for reading. The file must exist. Returns error if the
          // operation cannot be completed.
-         Result_t OpenRead(const char* filename) const;
+         Result_t OpenRead(const std::string& filename) const;
 
          // Returns RESULT_INIT if the file is not open.
          Result_t Close() const;
@@ -1307,7 +1319,7 @@ namespace ASDCP {
          // Open the file for writing. The file must not exist. Returns error if
          // the operation cannot be completed or if nonsensical data is discovered
          // in the essence descriptor.
-         Result_t OpenWrite(const char* filename, const WriterInfo&,
+         Result_t OpenWrite(const std::string& filename, const WriterInfo&,
                             const PictureDescriptor&, ui32_t HeaderSize = 16384);
 
          // Writes a pair of frames of essence to the MXF file. If the optional AESEncContext
@@ -1349,7 +1361,7 @@ namespace ASDCP {
 
          // Open the file for reading. The file must exist. Returns error if the
          // operation cannot be completed.
-         Result_t OpenRead(const char* filename) const;
+         Result_t OpenRead(const std::string& filename) const;
 
          // Returns RESULT_INIT if the file is not open.
          Result_t Close() const;
@@ -1486,12 +1498,12 @@ namespace ASDCP {
 
          // Opens an XML file for reading, parses data to provide a complete
          // set of stream metadata for the MXFWriter below.
-         Result_t OpenRead(const char* filename) const;
+         Result_t OpenRead(const std::string& filename) const;
 
          // Parses an XML document to provide a complete set of stream metadata
          // for the MXFWriter below. The optional filename argument is used to
          // initialize the default resource resolver (see ReadAncillaryResource).
-         Result_t OpenRead(const std::string& xml_doc, const char* filename = 0) const;
+         Result_t OpenRead(const std::string& xml_doc, const std::string& filename) const;
 
          // Fill a TimedTextDescriptor struct with the values from the file's contents.
          // Returns RESULT_INIT if the file is not open.
@@ -1531,7 +1543,7 @@ namespace ASDCP {
          // Open the file for writing. The file must not exist. Returns error if
          // the operation cannot be completed or if nonsensical data is discovered
          // in the essence descriptor.
-         Result_t OpenWrite(const char* filename, const WriterInfo&,
+         Result_t OpenWrite(const std::string& filename, const WriterInfo&,
                             const TimedTextDescriptor&, ui32_t HeaderSize = 16384);
 
          // Writes the Timed-Text Resource to the MXF file. The file must be UTF-8
@@ -1573,7 +1585,7 @@ namespace ASDCP {
 
          // Open the file for reading. The file must exist. Returns error if the
          // operation cannot be completed.
-         Result_t OpenRead(const char* filename) const;
+         Result_t OpenRead(const std::string& filename) const;
 
          // Returns RESULT_INIT if the file is not open.
          Result_t Close() const;
@@ -1662,7 +1674,7 @@ namespace ASDCP {
          // The frame buffer's PlaintextOffset parameter will be set to the first
          // byte of the data segment. Set this value to zero if you want
          // encrypted headers.
-         Result_t OpenReadFrame(const char* filename, FrameBuffer&) const;
+         Result_t OpenReadFrame(const std::string& filename, FrameBuffer&) const;
 
          // Fill a DCDataDescriptor struct with the values from the file's bytestream.
          // Returns RESULT_INIT if the file is not open.
@@ -1684,7 +1696,7 @@ namespace ASDCP {
          // more files, each containing the bytestream for exactly one frame. The files
       // must be named such that the frames are in temporal order when sorted
          // alphabetically by filename.
-         Result_t OpenRead(const char* filename) const;
+         Result_t OpenRead(const std::string& filename) const;
 
          // Opens a file sequence for reading.  The sequence is expected to contain one or
          // more filenames, each naming a file containing the bytestream for exactly one
@@ -1727,7 +1739,7 @@ namespace ASDCP {
          // Open the file for writing. The file must not exist. Returns error if
          // the operation cannot be completed or if nonsensical data is discovered
          // in the essence descriptor.
-         Result_t OpenWrite(const char* filename, const WriterInfo&,
+         Result_t OpenWrite(const std::string& filename, const WriterInfo&,
                             const DCDataDescriptor&, ui32_t HeaderSize = 16384);
 
          // Writes a frame of essence to the MXF file. If the optional AESEncContext
@@ -1759,7 +1771,7 @@ namespace ASDCP {
 
          // Open the file for reading. The file must exist. Returns error if the
          // operation cannot be completed.
-         Result_t OpenRead(const char* filename) const;
+         Result_t OpenRead(const std::string& filename) const;
 
          // Returns RESULT_INIT if the file is not open.
          Result_t Close() const;
@@ -1812,7 +1824,7 @@ namespace ASDCP {
     // Print debugging information to stream (stderr default)
     void AtmosDescriptorDump(const AtmosDescriptor&, FILE* = 0);
     // Determine if a file is a raw atmos file
-    bool IsDolbyAtmos(const char* filename);
+    bool IsDolbyAtmos(const std::string& filename);
 
     //
     class MXFWriter
@@ -1835,7 +1847,7 @@ namespace ASDCP {
          // Open the file for writing. The file must not exist. Returns error if
          // the operation cannot be completed or if nonsensical data is discovered
          // in the essence descriptor.
-         Result_t OpenWrite(const char* filename, const WriterInfo&,
+         Result_t OpenWrite(const std::string& filename, const WriterInfo&,
                             const AtmosDescriptor&, ui32_t HeaderSize = 16384);
 
          // Writes a frame of essence to the MXF file. If the optional AESEncContext
@@ -1867,7 +1879,7 @@ namespace ASDCP {
 
          // Open the file for reading. The file must exist. Returns error if the
          // operation cannot be completed.
-         Result_t OpenRead(const char* filename) const;
+         Result_t OpenRead(const std::string& filename) const;
 
          // Returns RESULT_INIT if the file is not open.
          Result_t Close() const;
index e8a2a8a21665d4a3a1dd383c5f1f64d7970487b6..7fa8c0917cb5e3e021d18d92283700c616e53a54 100644 (file)
@@ -93,11 +93,11 @@ ASDCP::ATMOS::AtmosDescriptorDump(const AtmosDescriptor& ADesc, FILE* stream)
 
 //
 bool
-ASDCP::ATMOS::IsDolbyAtmos(const char* filename)
+ASDCP::ATMOS::IsDolbyAtmos(const std::string& filename)
 {
     // TODO
     // For now use an atmos extension
-    bool result = (0 == (std::string("atmos").compare(Kumu::PathGetExtension(std::string(filename)))));
+    bool result = ( 0 == (std::string("atmos").compare(Kumu::PathGetExtension(filename))) );
     return result;
 }
 
@@ -118,7 +118,7 @@ class ASDCP::ATMOS::MXFReader::h__Reader : public ASDCP::DCData::h__Reader
   h__Reader(const Dictionary& d) : DCData::h__Reader(d),  m_EssenceSubDescriptor(NULL),
                                    m_ADesc() {}
   virtual ~h__Reader() {}
-  Result_t    OpenRead(const char*);
+  Result_t    OpenRead(const std::string&);
   Result_t    MD_to_Atmos_ADesc(ATMOS::AtmosDescriptor& ADesc);
 };
 
@@ -142,7 +142,7 @@ ASDCP::ATMOS::MXFReader::h__Reader::MD_to_Atmos_ADesc(ATMOS::AtmosDescriptor& AD
 //
 //
 ASDCP::Result_t
-ASDCP::ATMOS::MXFReader::h__Reader::OpenRead(const char* filename)
+ASDCP::ATMOS::MXFReader::h__Reader::OpenRead(const std::string& filename)
 {
   Result_t result = DCData::h__Reader::OpenRead(filename);
 
@@ -234,7 +234,7 @@ ASDCP::ATMOS::MXFReader::RIP()
 // Open the file for reading. The file must exist. Returns error if the
 // operation cannot be completed.
 ASDCP::Result_t
-ASDCP::ATMOS::MXFReader::OpenRead(const char* filename) const
+ASDCP::ATMOS::MXFReader::OpenRead(const std::string& filename) const
 {
   return m_Reader->OpenRead(filename);
 }
@@ -334,7 +334,7 @@ class ASDCP::ATMOS::MXFWriter::h__Writer : public DCData::h__Writer
 
   virtual ~h__Writer(){}
 
-  Result_t OpenWrite(const char*, ui32_t HeaderSize, const AtmosDescriptor& ADesc);
+  Result_t OpenWrite(const std::string&, ui32_t HeaderSize, const AtmosDescriptor& ADesc);
   Result_t Atmos_ADesc_to_MD(const AtmosDescriptor& ADesc);
 };
 
@@ -355,7 +355,7 @@ ASDCP::ATMOS::MXFWriter::h__Writer::Atmos_ADesc_to_MD(const AtmosDescriptor& ADe
 
 //
 ASDCP::Result_t
-ASDCP::ATMOS::MXFWriter::h__Writer::OpenWrite(const char* filename, ui32_t HeaderSize, const AtmosDescriptor& ADesc)
+ASDCP::ATMOS::MXFWriter::h__Writer::OpenWrite(const std::string& filename, ui32_t HeaderSize, const AtmosDescriptor& ADesc)
 {
 
   m_EssenceSubDescriptor = new DolbyAtmosSubDescriptor(m_Dict);
@@ -436,7 +436,7 @@ ASDCP::ATMOS::MXFWriter::RIP()
 // Open the file for writing. The file must not exist. Returns error if
 // the operation cannot be completed.
 ASDCP::Result_t
-ASDCP::ATMOS::MXFWriter::OpenWrite(const char* filename, const WriterInfo& Info,
+ASDCP::ATMOS::MXFWriter::OpenWrite(const std::string& filename, const WriterInfo& Info,
                                       const AtmosDescriptor& ADesc, ui32_t HeaderSize)
 {
   if ( Info.LabelSetType != LS_MXF_SMPTE )
index a1bb0435087fadd95467a7f132cb3f289d00b8cc..e145e1fd60ec8aae8a0c3bd7fc72cbc04e5c73b5 100644 (file)
@@ -91,7 +91,7 @@ ASDCP::DCData::h__Reader::MD_to_DCData_DDesc(DCData::DCDataDescriptor& DDesc)
 //
 //
 ASDCP::Result_t
-ASDCP::DCData::h__Reader::OpenRead(const char* filename)
+ASDCP::DCData::h__Reader::OpenRead(const std::string& filename)
 {
   Result_t result = OpenMXFRead(filename);
 
@@ -244,7 +244,7 @@ ASDCP::DCData::MXFReader::RIP()
 // Open the file for reading. The file must exist. Returns error if the
 // operation cannot be completed.
 ASDCP::Result_t
-ASDCP::DCData::MXFReader::OpenRead(const char* filename) const
+ASDCP::DCData::MXFReader::OpenRead(const std::string& filename) const
 {
   return m_Reader->OpenRead(filename);
 }
@@ -346,7 +346,7 @@ ASDCP::DCData::h__Writer::DCData_DDesc_to_MD(DCData::DCDataDescriptor& DDesc)
 
 //
 ASDCP::Result_t
-ASDCP::DCData::h__Writer::OpenWrite(char const* filename, ui32_t HeaderSize,
+ASDCP::DCData::h__Writer::OpenWrite(const std::string& filename, ui32_t HeaderSize,
                                     const SubDescriptorList_t& subDescriptors)
 {
   if ( ! m_State.Test_BEGIN() )
@@ -534,7 +534,7 @@ ASDCP::DCData::MXFWriter::RIP()
 // Open the file for writing. The file must not exist. Returns error if
 // the operation cannot be completed.
 ASDCP::Result_t
-ASDCP::DCData::MXFWriter::OpenWrite(const char* filename, const WriterInfo& Info,
+ASDCP::DCData::MXFWriter::OpenWrite(const std::string& filename, const WriterInfo& Info,
                                       const DCDataDescriptor& DDesc, ui32_t HeaderSize)
 {
   if ( Info.LabelSetType != LS_MXF_SMPTE )
index 93ccb7e11b22dd380db5d7c24feca00eb681f66a..a9e510d4839a3547cb5f4213d14e6a6482b17117 100644 (file)
@@ -60,7 +60,7 @@ namespace DCData
     h__Reader(const Dictionary& d) : ASDCP::h__ASDCPReader(d), m_EssenceDescriptor(0),
                                      m_DDesc() {}
     ~h__Reader() {}
-    Result_t    OpenRead(const char*);
+    Result_t    OpenRead(const std::string&);
     Result_t    ReadFrame(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*);
     Result_t    MD_to_DCData_DDesc(DCData::DCDataDescriptor& DDesc);
   };
@@ -80,7 +80,7 @@ namespace DCData
 
     ~h__Writer(){}
 
-    Result_t OpenWrite(const char*, ui32_t HeaderSize, const SubDescriptorList_t& subDescriptors);
+    Result_t OpenWrite(const std::string&, ui32_t HeaderSize, const SubDescriptorList_t& subDescriptors);
     Result_t SetSourceStream(const DCDataDescriptor&, const byte_t*, const std::string&, const std::string&);
     Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
     Result_t Finalize();
index 1b3bc5464bec3ea69861d261a62bed412e3db9aa..62c9e7897f96a20c1396e61361509585caad909d 100755 (executable)
@@ -339,7 +339,7 @@ public:
 
   virtual ~lh__Reader() {}
 
-  Result_t    OpenRead(const char*, EssenceType_t);
+  Result_t    OpenRead(const std::string&, EssenceType_t);
   Result_t    ReadFrame(ui32_t, JP2K::FrameBuffer&, AESDecContext*, HMACContext*);
 };
 
@@ -347,7 +347,7 @@ public:
 //
 //
 ASDCP::Result_t
-lh__Reader::OpenRead(const char* filename, EssenceType_t type)
+lh__Reader::OpenRead(const std::string& filename, EssenceType_t type)
 {
   Result_t result = OpenMXFRead(filename);
 
@@ -582,7 +582,7 @@ ASDCP::JP2K::MXFReader::RIP()
 // Open the file for reading. The file must exist. Returns error if the
 // operation cannot be completed.
 ASDCP::Result_t
-ASDCP::JP2K::MXFReader::OpenRead(const char* filename) const
+ASDCP::JP2K::MXFReader::OpenRead(const std::string& filename) const
 {
   return m_Reader->OpenRead(filename, ASDCP::ESS_JPEG_2000);
 }
@@ -809,7 +809,7 @@ ASDCP::JP2K::MXFSReader::RIP()
 // Open the file for reading. The file must exist. Returns error if the
 // operation cannot be completed.
 ASDCP::Result_t
-ASDCP::JP2K::MXFSReader::OpenRead(const char* filename) const
+ASDCP::JP2K::MXFSReader::OpenRead(const std::string& filename) const
 {
   return m_Reader->OpenRead(filename, ASDCP::ESS_JPEG_2000_S);
 }
@@ -929,7 +929,7 @@ public:
 
   virtual ~lh__Writer(){}
 
-  Result_t OpenWrite(const char*, EssenceType_t type, ui32_t HeaderSize);
+  Result_t OpenWrite(const std::string&, EssenceType_t type, ui32_t HeaderSize);
   Result_t SetSourceStream(const PictureDescriptor&, const std::string& label,
                           ASDCP::Rational LocalEditRate = ASDCP::Rational(0,0));
   Result_t WriteFrame(const JP2K::FrameBuffer&, bool add_index, AESEncContext*, HMACContext*);
@@ -939,7 +939,7 @@ public:
 // Open the file for writing. The file must not exist. Returns error if
 // the operation cannot be completed.
 ASDCP::Result_t
-lh__Writer::OpenWrite(const char* filename, EssenceType_t type, ui32_t HeaderSize)
+lh__Writer::OpenWrite(const std::string& filename, EssenceType_t type, ui32_t HeaderSize)
 {
   if ( ! m_State.Test_BEGIN() )
     return RESULT_STATE;
@@ -1137,7 +1137,7 @@ ASDCP::JP2K::MXFWriter::RIP()
 // Open the file for writing. The file must not exist. Returns error if
 // the operation cannot be completed.
 ASDCP::Result_t
-ASDCP::JP2K::MXFWriter::OpenWrite(const char* filename, const WriterInfo& Info,
+ASDCP::JP2K::MXFWriter::OpenWrite(const std::string& filename, const WriterInfo& Info,
                                  const PictureDescriptor& PDesc, ui32_t HeaderSize)
 {
   if ( Info.LabelSetType == LS_MXF_SMPTE )
@@ -1283,7 +1283,7 @@ ASDCP::JP2K::MXFSWriter::RIP()
 // Open the file for writing. The file must not exist. Returns error if
 // the operation cannot be completed.
 ASDCP::Result_t
-ASDCP::JP2K::MXFSWriter::OpenWrite(const char* filename, const WriterInfo& Info,
+ASDCP::JP2K::MXFSWriter::OpenWrite(const std::string& filename, const WriterInfo& Info,
                                   const PictureDescriptor& PDesc, ui32_t HeaderSize)
 {
   if ( Info.LabelSetType == LS_MXF_SMPTE )
index 21991bf0045265605f0a78171ddcd857e83511cd..8353ea4f1e7edae62bbd7df966291a63ba5b28dd 100755 (executable)
@@ -170,7 +170,7 @@ public:
 
   h__Reader(const Dictionary& d) : ASDCP::h__ASDCPReader(d) {}
   virtual ~h__Reader() {}
-  Result_t    OpenRead(const char*);
+  Result_t    OpenRead(const std::string&);
   Result_t    ReadFrame(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*);
   Result_t    ReadFrameGOPStart(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*);
   Result_t    FindFrameGOPStart(ui32_t, ui32_t&);
@@ -181,7 +181,7 @@ public:
 //
 //
 ASDCP::Result_t
-ASDCP::MPEG2::MXFReader::h__Reader::OpenRead(const char* filename)
+ASDCP::MPEG2::MXFReader::h__Reader::OpenRead(const std::string& filename)
 {
   Result_t result = OpenMXFRead(filename);
 
@@ -385,7 +385,7 @@ ASDCP::MPEG2::MXFReader::RIP()
 // Open the file for reading. The file must exist. Returns error if the
 // operation cannot be completed.
 ASDCP::Result_t
-ASDCP::MPEG2::MXFReader::OpenRead(const char* filename) const
+ASDCP::MPEG2::MXFReader::OpenRead(const std::string& filename) const
 {
   return m_Reader->OpenRead(filename);
 }
@@ -521,7 +521,7 @@ public:
 
   virtual ~h__Writer(){}
 
-  Result_t OpenWrite(const char*, ui32_t HeaderSize);
+  Result_t OpenWrite(const std::string&, ui32_t HeaderSize);
   Result_t SetSourceStream(const VideoDescriptor&);
   Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
   Result_t Finalize();
@@ -531,7 +531,7 @@ public:
 // Open the file for writing. The file must not exist. Returns error if
 // the operation cannot be completed.
 ASDCP::Result_t
-ASDCP::MPEG2::MXFWriter::h__Writer::OpenWrite(const char* filename, ui32_t HeaderSize)
+ASDCP::MPEG2::MXFWriter::h__Writer::OpenWrite(const std::string& filename, ui32_t HeaderSize)
 {
   if ( ! m_State.Test_BEGIN() )
     return RESULT_STATE;
@@ -568,6 +568,8 @@ ASDCP::MPEG2::MXFWriter::h__Writer::SetSourceStream(const VideoDescriptor& VDesc
 
   if ( ASDCP_SUCCESS(result) )
     {
+      m_FooterPart.SetDeltaParams(IndexTableSegment::DeltaEntry(-1, 0, 0));
+
       result = WriteASDCPHeader(MPEG_PACKAGE_LABEL, UL(m_Dict->ul(MDD_MPEG2_VESWrappingFrame)), 
                                PICT_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_PictureDataDef)),
                                m_VDesc.EditRate, derive_timecode_rate_from_edit_rate(m_VDesc.EditRate));
@@ -711,7 +713,7 @@ ASDCP::MPEG2::MXFWriter::RIP()
 // Open the file for writing. The file must not exist. Returns error if
 // the operation cannot be completed.
 ASDCP::Result_t
-ASDCP::MPEG2::MXFWriter::OpenWrite(const char* filename, const WriterInfo& Info,
+ASDCP::MPEG2::MXFWriter::OpenWrite(const std::string& filename, const WriterInfo& Info,
                                   const VideoDescriptor& VDesc, ui32_t HeaderSize)
 {
   if ( Info.LabelSetType == LS_MXF_SMPTE )
index f3ad310ed2bde3effb793e13f11a7b62213ee12b..82ec81c8445df8cdfe5ee3266be6a5b0cf42feb6 100755 (executable)
@@ -161,14 +161,12 @@ ASDCP::MD_to_CryptoInfo(CryptographicContext* InfoObj, WriterInfo& Info, const D
 //
 //
 ASDCP::Result_t
-ASDCP::EssenceType(const char* filename, EssenceType_t& type)
+ASDCP::EssenceType(const std::string& filename, EssenceType_t& type)
 {
   const Dictionary* m_Dict = &DefaultCompositeDict();
   InterchangeObject* md_object = 0;
 
   assert(m_Dict);
-
-  ASDCP_TEST_NULL_STR(filename);
   Kumu::FileReader   Reader;
   OP1aHeader TestHeader(m_Dict);
 
@@ -180,47 +178,80 @@ ASDCP::EssenceType(const char* filename, EssenceType_t& type)
   if ( ASDCP_SUCCESS(result) )
     {
       type = ESS_UNKNOWN;
-      if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(JPEG2000PictureSubDescriptor))) )
+
+      if ( TestHeader.OperationalPattern == UL(m_Dict->ul(MDD_OPAtom))
+          || TestHeader.OperationalPattern == UL(m_Dict->ul(MDD_MXFInterop_OPAtom)) )
        {
-         if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(StereoscopicPictureSubDescriptor))) )
+         if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(JPEG2000PictureSubDescriptor))) )
            {
-             type = ESS_JPEG_2000_S;
+             if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(StereoscopicPictureSubDescriptor))) )
+               {
+                 type = ESS_JPEG_2000_S;
+               }
+             else
+               {
+                 type = ESS_JPEG_2000;
+               }
            }
-         else
+         else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(WaveAudioDescriptor), &md_object)) )
            {
-             type = ESS_JPEG_2000;
+             assert(md_object);
+             if ( static_cast<ASDCP::MXF::WaveAudioDescriptor*>(md_object)->AudioSamplingRate == SampleRate_96k )
+               {
+                 type = ESS_PCM_24b_96k;
+               }
+             else
+               {
+                 type = ESS_PCM_24b_48k;
+               }
            }
-       }
-      else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(WaveAudioDescriptor), &md_object)) )
-       {
-         assert(md_object);
-         if ( static_cast<ASDCP::MXF::WaveAudioDescriptor*>(md_object)->AudioSamplingRate == SampleRate_96k )
+         else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(MPEG2VideoDescriptor))) )
            {
-             type = ESS_PCM_24b_96k;
+             type = ESS_MPEG2_VES;
            }
-         else
+         else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(TimedTextDescriptor))) )
            {
-             type = ESS_PCM_24b_48k;
+             type = ESS_TIMED_TEXT;
+           }
+         else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(DCDataDescriptor))) )
+           {
+             if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(DolbyAtmosSubDescriptor))) )
+               {
+                 type = ESS_DCDATA_DOLBY_ATMOS;
+               }
+             else
+               {
+                 type = ESS_DCDATA_UNKNOWN;
+               }
            }
        }
-      else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(MPEG2VideoDescriptor))) )
-       {
-       type = ESS_MPEG2_VES;
-       }
-      else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(TimedTextDescriptor))) )
-       {
-       type = ESS_TIMED_TEXT;
-       }
-      else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(DCDataDescriptor))) )
+      else if (  TestHeader.OperationalPattern == UL(m_Dict->ul(MDD_OP1a)) )
        {
-         if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(DolbyAtmosSubDescriptor))) )
+         if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(JPEG2000PictureSubDescriptor))) )
            {
-             type = ESS_DCDATA_DOLBY_ATMOS;
+             type = ESS_AS02_JPEG_2000;
            }
-         else
+         else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(WaveAudioDescriptor), &md_object)) )
            {
-             type = ESS_DCDATA_UNKNOWN;
+             assert(md_object);
+             if ( static_cast<ASDCP::MXF::WaveAudioDescriptor*>(md_object)->AudioSamplingRate == SampleRate_96k )
+               {
+                 type = ESS_AS02_PCM_24b_96k;
+               }
+             else
+               {
+                 type = ESS_AS02_PCM_24b_48k;
+               }
            }
+         else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(TimedTextDescriptor))) )
+           {
+             type = ESS_AS02_TIMED_TEXT;
+           }
+       }
+      else
+       {
+         DefaultLogSink().Error("Unsupported MXF Operational Pattern.\n");
+         return RESULT_FORMAT;
        }
     }
 
@@ -229,9 +260,8 @@ ASDCP::EssenceType(const char* filename, EssenceType_t& type)
 
 //
 ASDCP::Result_t
-ASDCP::RawEssenceType(const char* filename, EssenceType_t& type)
+ASDCP::RawEssenceType(const std::string& filename, EssenceType_t& type)
 {
-  ASDCP_TEST_NULL_STR(filename);
   type = ESS_UNKNOWN;
   ASDCP::FrameBuffer FB;
   Kumu::FileReader Reader;
@@ -317,10 +347,7 @@ ASDCP::RawEssenceType(const char* filename, EssenceType_t& type)
              if ( next_file[0] == '.' ) // no hidden files or internal links
                continue;
 
-             std::string Str(filename);
-             Str += "/";
-             Str += next_file;
-             result = Reader.OpenRead(Str.c_str());
+             result = Reader.OpenRead(Kumu::PathJoin(filename, next_file));
 
              if ( ASDCP_SUCCESS(result) )
                {
@@ -354,7 +381,7 @@ ASDCP::RawEssenceType(const char* filename, EssenceType_t& type)
                          return RESULT_FORMAT;
                        }
                    }
-                 else if ( ASDCP::ATMOS::IsDolbyAtmos(Str.c_str()) )
+                 else if ( ASDCP::ATMOS::IsDolbyAtmos(Kumu::PathJoin(filename, next_file)) )
                    {
                      type = ESS_DCDATA_DOLBY_ATMOS;
                    }
index 8011a550a66bbc05f83c992158e67d5f3c996bc4..88ccd1f5d671e5247134022f0fd30f48572144ca 100755 (executable)
@@ -77,6 +77,10 @@ ASDCP::PCM_ADesc_to_MD(PCM::AudioDescriptor& ADesc, MXF::WaveAudioDescriptor* AD
       case PCM::CF_CFG_5:
        ADescObj->ChannelAssignment = DefaultSMPTEDict().Type(MDD_DCAudioChannelCfg_5_7p1_DS).ul;
        break;
+
+      case PCM::CF_CFG_6:
+       ADescObj->ChannelAssignment = DefaultSMPTEDict().Type(MDD_DCAudioChannelCfg_MCA).ul;
+       break;
     }
 
   return RESULT_OK;
@@ -116,6 +120,9 @@ ASDCP::MD_to_PCM_ADesc(MXF::WaveAudioDescriptor* ADescObj, PCM::AudioDescriptor&
 
       else if ( ADescObj->ChannelAssignment == DefaultSMPTEDict().Type(MDD_DCAudioChannelCfg_5_7p1_DS).ul )
        ADesc.ChannelFormat = PCM::CF_CFG_5;
+
+      else if ( ADescObj->ChannelAssignment == DefaultSMPTEDict().Type(MDD_DCAudioChannelCfg_MCA).ul )
+       ADesc.ChannelFormat = PCM::CF_CFG_6;
     }
 
   return RESULT_OK;
@@ -161,6 +168,10 @@ ASDCP::PCM::operator << (std::ostream& strm, const AudioDescriptor& ADesc)
     case CF_CFG_5:
       strm << "Config 5 (7.1 DS with optional HI/VI)";
       break;
+
+    case CF_CFG_6:
+      strm << "Config 6 (ST 377-1 MCA)";
+      break;
   }
   strm << std::endl;
 
@@ -237,7 +248,7 @@ public:
 
   h__Reader(const Dictionary& d) : ASDCP::h__ASDCPReader(d) {}
   virtual ~h__Reader() {}
-  Result_t    OpenRead(const char*);
+  Result_t    OpenRead(const std::string&);
   Result_t    ReadFrame(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*);
 };
 
@@ -245,7 +256,7 @@ public:
 //
 //
 ASDCP::Result_t
-ASDCP::PCM::MXFReader::h__Reader::OpenRead(const char* filename)
+ASDCP::PCM::MXFReader::h__Reader::OpenRead(const std::string& filename)
 {
   Result_t result = OpenMXFRead(filename);
 
@@ -397,7 +408,7 @@ ASDCP::PCM::MXFReader::RIP()
 // Open the file for reading. The file must exist. Returns error if the
 // operation cannot be completed.
 ASDCP::Result_t
-ASDCP::PCM::MXFReader::OpenRead(const char* filename) const
+ASDCP::PCM::MXFReader::OpenRead(const std::string& filename) const
 {
   return m_Reader->OpenRead(filename);
 }
@@ -500,7 +511,7 @@ public:
 
   virtual ~h__Writer(){}
 
-  Result_t OpenWrite(const char*, ui32_t HeaderSize);
+  Result_t OpenWrite(const std::string&, ui32_t HeaderSize);
   Result_t SetSourceStream(const AudioDescriptor&);
   Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
   Result_t Finalize();
@@ -511,7 +522,7 @@ public:
 // Open the file for writing. The file must not exist. Returns error if
 // the operation cannot be completed.
 ASDCP::Result_t
-ASDCP::PCM::MXFWriter::h__Writer::OpenWrite(const char* filename, ui32_t HeaderSize)
+ASDCP::PCM::MXFWriter::h__Writer::OpenWrite(const std::string& filename, ui32_t HeaderSize)
 {
   if ( ! m_State.Test_BEGIN() )
     return RESULT_STATE;
@@ -682,7 +693,7 @@ ASDCP::PCM::MXFWriter::RIP()
 // Open the file for writing. The file must not exist. Returns error if
 // the operation cannot be completed.
 ASDCP::Result_t
-ASDCP::PCM::MXFWriter::OpenWrite(const char* filename, const WriterInfo& Info,
+ASDCP::PCM::MXFWriter::OpenWrite(const std::string& filename, const WriterInfo& Info,
                                 const AudioDescriptor& ADesc, ui32_t HeaderSize)
 {
   if ( Info.LabelSetType == LS_MXF_SMPTE )
index e5425b4e4f1e45b7dd49b64c2c65876cc06c5cfe..e158cde25edf09e28e41b9f97652aedd5f6a8a24 100644 (file)
@@ -139,7 +139,7 @@ public:
 
   virtual ~h__Reader() {}
 
-  Result_t    OpenRead(const char*);
+  Result_t    OpenRead(const std::string&);
   Result_t    MD_to_TimedText_TDesc(TimedText::TimedTextDescriptor& TDesc);
   Result_t    ReadTimedTextResource(FrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC);
   Result_t    ReadAncillaryResource(const byte_t*, FrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC);
@@ -201,7 +201,7 @@ ASDCP::TimedText::MXFReader::h__Reader::MD_to_TimedText_TDesc(TimedText::TimedTe
 
 //
 ASDCP::Result_t
-ASDCP::TimedText::MXFReader::h__Reader::OpenRead(char const* filename)
+ASDCP::TimedText::MXFReader::h__Reader::OpenRead(const std::string& filename)
 {
   Result_t result = OpenMXFRead(filename);
   
@@ -385,7 +385,7 @@ ASDCP::TimedText::MXFReader::RIP()
 // Open the file for reading. The file must exist. Returns error if the
 // operation cannot be completed.
 ASDCP::Result_t
-ASDCP::TimedText::MXFReader::OpenRead(const char* filename) const
+ASDCP::TimedText::MXFReader::OpenRead(const std::string& filename) const
 {
   return m_Reader->OpenRead(filename);
 }
@@ -506,7 +506,7 @@ public:
 
   virtual ~h__Writer() {}
 
-  Result_t OpenWrite(const char*, ui32_t HeaderSize);
+  Result_t OpenWrite(const std::string&, ui32_t HeaderSize);
   Result_t SetSourceStream(const TimedTextDescriptor&);
   Result_t WriteTimedTextResource(const std::string& XMLDoc, AESEncContext* = 0, HMACContext* = 0);
   Result_t WriteAncillaryResource(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
@@ -532,7 +532,7 @@ ASDCP::TimedText::MXFWriter::h__Writer::TimedText_TDesc_to_MD(TimedText::TimedTe
 
 //
 ASDCP::Result_t
-ASDCP::TimedText::MXFWriter::h__Writer::OpenWrite(char const* filename, ui32_t HeaderSize)
+ASDCP::TimedText::MXFWriter::h__Writer::OpenWrite(const std::string& filename, ui32_t HeaderSize)
 {
   if ( ! m_State.Test_BEGIN() )
     return RESULT_STATE;
@@ -749,7 +749,7 @@ ASDCP::TimedText::MXFWriter::RIP()
 // Open the file for writing. The file must not exist. Returns error if
 // the operation cannot be completed.
 ASDCP::Result_t
-ASDCP::TimedText::MXFWriter::OpenWrite(const char* filename, const WriterInfo& Info,
+ASDCP::TimedText::MXFWriter::OpenWrite(const std::string& filename, const WriterInfo& Info,
                                       const TimedTextDescriptor& TDesc, ui32_t HeaderSize)
 {
   if ( Info.LabelSetType != LS_MXF_SMPTE )
index 675f96de93bec1a35bf1782d389921e48329efcc..24020e536f90cc80601ec552dea0e25a1e7ccf84 100755 (executable)
@@ -213,7 +213,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);
@@ -803,7 +803,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,
index 73565d4a7d5564f7e573038ed353259875e64f3c..28e18694486ebde72e73b4b083c323f65652fc1f 100644 (file)
@@ -52,9 +52,8 @@ public:
 
   ~h__BytestreamParser() {}
 
-  Result_t OpenReadFrame(const char* filename, FrameBuffer& FB)
+  Result_t OpenReadFrame(const std::string& filename, FrameBuffer& FB)
   {
-    ASDCP_TEST_NULL_STR(filename);
     m_File.Close();
     Result_t result = m_File.OpenRead(filename);
 
@@ -95,7 +94,7 @@ ASDCP::DCData::BytestreamParser::~BytestreamParser()
 // Opens the stream for reading, parses enough data to provide a complete
 // set of stream metadata for the MXFWriter below.
 ASDCP::Result_t
-ASDCP::DCData::BytestreamParser::OpenReadFrame(const char* filename, FrameBuffer& FB) const
+ASDCP::DCData::BytestreamParser::OpenReadFrame(const std::string& filename, FrameBuffer& FB) const
 {
   const_cast<ASDCP::DCData::BytestreamParser*>(this)->m_Parser = new h__BytestreamParser;
   return m_Parser->OpenReadFrame(filename, FB);
index 45594c5e52e7e661a36fddbd814b4d7fdfa5bae6..de9f39a4dcd6513360db4d230b03b78123a5b064 100644 (file)
@@ -66,7 +66,7 @@ class ASDCP::DCData::FileList : public std::list<std::string>
     }
 
     //
-    Result_t InitFromDirectory(const char* path)
+    Result_t InitFromDirectory(const std::string& path)
     {
         char next_file[Kumu::MaxFilePath];
         Kumu::DirScanner Scanner;
@@ -125,7 +125,7 @@ class ASDCP::DCData::SequenceParser::h__SequenceParser
     Close();
   }
 
-  Result_t OpenRead(const char* filename);
+  Result_t OpenRead(const std::string& filename);
   Result_t OpenRead(const std::list<std::string>& file_list);
   void     Close() {}
 
@@ -174,10 +174,8 @@ ASDCP::DCData::SequenceParser::h__SequenceParser::OpenRead()
 
 //
 ASDCP::Result_t
-ASDCP::DCData::SequenceParser::h__SequenceParser::OpenRead(const char* filename)
+ASDCP::DCData::SequenceParser::h__SequenceParser::OpenRead(const std::string& filename)
 {
-  ASDCP_TEST_NULL_STR(filename);
-
   Result_t result = m_FileList.InitFromDirectory(filename);
 
   if ( ASDCP_SUCCESS(result) )
@@ -228,7 +226,7 @@ ASDCP::DCData::SequenceParser::~SequenceParser()
 // Opens the stream for reading, parses enough data to provide a complete
 // set of stream metadata for the MXFWriter below.
 ASDCP::Result_t
-ASDCP::DCData::SequenceParser::OpenRead(const char* filename) const
+ASDCP::DCData::SequenceParser::OpenRead(const std::string& filename) const
 {
   const_cast<ASDCP::DCData::SequenceParser*>(this)->m_Parser = new h__SequenceParser;
 
index a1385d1b693e78f53c4cb406c5ce812429fa029e..c82064610a79fc599970194d0487f2e70b181fcb 100755 (executable)
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2004-2009, John Hurst
+Copyright (c) 2004-2013, John Hurst
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -55,9 +55,8 @@ public:
 
   ~h__CodestreamParser() {}
 
-  Result_t OpenReadFrame(const char* filename, FrameBuffer& FB)
+  Result_t OpenReadFrame(const std::string& filename, FrameBuffer& FB)
   {
-    ASDCP_TEST_NULL_STR(filename);
     m_File.Close();
     Result_t result = m_File.OpenRead(filename);
 
@@ -198,7 +197,7 @@ ASDCP::JP2K::CodestreamParser::~CodestreamParser()
 // Opens the stream for reading, parses enough data to provide a complete
 // set of stream metadata for the MXFWriter below.
 ASDCP::Result_t
-ASDCP::JP2K::CodestreamParser::OpenReadFrame(const char* filename, FrameBuffer& FB) const
+ASDCP::JP2K::CodestreamParser::OpenReadFrame(const std::string& filename, FrameBuffer& FB) const
 {
   const_cast<ASDCP::JP2K::CodestreamParser*>(this)->m_Parser = new h__CodestreamParser;
   return m_Parser->OpenReadFrame(filename, FB);
index c33321e285cbb53b04732e140647b0198494c434..a0fd5d0b9c2fde47ac8143fe13a5cd5b1cd228b4 100755 (executable)
@@ -59,7 +59,7 @@ public:
   }
 
   //
-  Result_t InitFromDirectory(const char* path)
+  Result_t InitFromDirectory(const std::string& path)
   {
     char next_file[Kumu::MaxFilePath];
     Kumu::DirScanner Scanner;
@@ -119,7 +119,7 @@ public:
     Close();
   }
 
-  Result_t OpenRead(const char* filename, bool pedantic);
+  Result_t OpenRead(const std::string& filename, bool pedantic);
   Result_t OpenRead(const std::list<std::string>& file_list, bool pedantic);
   void     Close() {}
 
@@ -168,9 +168,8 @@ ASDCP::JP2K::SequenceParser::h__SequenceParser::OpenRead()
 
 //
 ASDCP::Result_t
-ASDCP::JP2K::SequenceParser::h__SequenceParser::OpenRead(const char* filename, bool pedantic)
+ASDCP::JP2K::SequenceParser::h__SequenceParser::OpenRead(const std::string& filename, bool pedantic)
 {
-  ASDCP_TEST_NULL_STR(filename);
   m_Pedantic = pedantic;
 
   Result_t result = m_FileList.InitFromDirectory(filename);
@@ -327,7 +326,7 @@ ASDCP::JP2K::SequenceParser::~SequenceParser()
 // Opens the stream for reading, parses enough data to provide a complete
 // set of stream metadata for the MXFWriter below.
 ASDCP::Result_t
-ASDCP::JP2K::SequenceParser::OpenRead(const char* filename, bool pedantic) const
+ASDCP::JP2K::SequenceParser::OpenRead(const std::string& filename, bool pedantic) const
 {
   const_cast<ASDCP::JP2K::SequenceParser*>(this)->m_Parser = new h__SequenceParser;
 
index fdd47198f34627d49fc952233a910b1b27dd338f..0866acd9e0ab8adf3f6702fe7550b0397dcf1204 100644 (file)
@@ -684,9 +684,8 @@ Kumu::FileWriter::Writev(const byte_t* buf, ui32_t buf_len)
 //
 
 Kumu::Result_t
-Kumu::FileReader::OpenRead(const char* filename) const
+Kumu::FileReader::OpenRead(const std::string& filename) const
 {
-  KM_TEST_NULL_STR_L(filename);
   const_cast<FileReader*>(this)->m_Filename = filename;
   
   // suppress popup window on error
@@ -809,15 +808,14 @@ Kumu::FileReader::Read(byte_t* buf, ui32_t buf_len, ui32_t* read_count) const
 
 //
 Kumu::Result_t
-Kumu::FileWriter::OpenWrite(const char* filename)
+Kumu::FileWriter::OpenWrite(const std::string& filename)
 {
-  KM_TEST_NULL_STR_L(filename);
   m_Filename = filename;
   
   // suppress popup window on error
   UINT prev = ::SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
 
-  m_Handle = ::CreateFileA(filename,
+  m_Handle = ::CreateFileA(filename.c_str(),
                          (GENERIC_WRITE|GENERIC_READ),  // open for reading
                          FILE_SHARE_READ,               // share for reading
                          NULL,                          // no security
@@ -908,11 +906,10 @@ Kumu::FileWriter::Write(const byte_t* buf, ui32_t buf_len, ui32_t* bytes_written
 
 //
 Kumu::Result_t
-Kumu::FileReader::OpenRead(const char* filename) const
+Kumu::FileReader::OpenRead(const std::string& filename) const
 {
-  KM_TEST_NULL_STR_L(filename);
   const_cast<FileReader*>(this)->m_Filename = filename;
-  const_cast<FileReader*>(this)->m_Handle = open(filename, O_RDONLY, 0);
+  const_cast<FileReader*>(this)->m_Handle = open(filename.c_str(), O_RDONLY, 0);
   return ( m_Handle == -1L ) ? RESULT_FILEOPEN : RESULT_OK;
 }
 
@@ -988,15 +985,14 @@ Kumu::FileReader::Read(byte_t* buf, ui32_t buf_len, ui32_t* read_count) const
 
 //
 Kumu::Result_t
-Kumu::FileWriter::OpenWrite(const char* filename)
+Kumu::FileWriter::OpenWrite(const std::string& filename)
 {
-  KM_TEST_NULL_STR_L(filename);
   m_Filename = filename;
-  m_Handle = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0664);
+  m_Handle = open(filename.c_str(), O_RDWR|O_CREAT|O_TRUNC, 0664);
 
   if ( m_Handle == -1L )
     {
-      DefaultLogSink().Error("Error opening file %s: %s\n", filename, strerror(errno));
+      DefaultLogSink().Error("Error opening file %s: %s\n", filename.c_str(), strerror(errno));
       return RESULT_FILEOPEN;
     }
 
@@ -1006,15 +1002,14 @@ Kumu::FileWriter::OpenWrite(const char* filename)
 
 //
 Kumu::Result_t
-Kumu::FileWriter::OpenModify(const char* filename)
+Kumu::FileWriter::OpenModify(const std::string& filename)
 {
-  KM_TEST_NULL_STR_L(filename);
   m_Filename = filename;
-  m_Handle = open(filename, O_RDWR|O_CREAT, 0664);
+  m_Handle = open(filename.c_str(), O_RDWR|O_CREAT, 0664);
 
   if ( m_Handle == -1L )
     {
-      DefaultLogSink().Error("Error opening file %s: %s\n", filename, strerror(errno));
+      DefaultLogSink().Error("Error opening file %s: %s\n", filename.c_str(), strerror(errno));
       return RESULT_FILEOPEN;
     }
 
@@ -1080,15 +1075,13 @@ Kumu::FileWriter::Write(const byte_t* buf, ui32_t buf_len, ui32_t* bytes_written
 
 //
 Kumu::Result_t
-Kumu::ReadFileIntoString(const char* filename, std::string& outString, ui32_t max_size)
+Kumu::ReadFileIntoString(const std::string& filename, std::string& outString, ui32_t max_size)
 {
   fsize_t    fsize = 0;
   ui32_t     read_size = 0;
   FileReader File;
   ByteString ReadBuf;
 
-  KM_TEST_NULL_STR_L(filename);
-
   Result_t result = File.OpenRead(filename);
 
   if ( KM_SUCCESS(result) )
@@ -1097,13 +1090,13 @@ Kumu::ReadFileIntoString(const char* filename, std::string& outString, ui32_t ma
 
       if ( fsize > (Kumu::fpos_t)max_size )
        {
-         DefaultLogSink().Error("%s: exceeds available buffer size (%u)\n", filename, max_size);
+         DefaultLogSink().Error("%s: exceeds available buffer size (%u)\n", filename.c_str(), max_size);
          return RESULT_ALLOC;
        }
 
       if ( fsize == 0 )
        {
-         DefaultLogSink().Error("%s: zero file size\n", filename);
+         DefaultLogSink().Error("%s: zero file size\n", filename.c_str());
          return RESULT_READFAIL;
        }
 
@@ -1122,11 +1115,10 @@ Kumu::ReadFileIntoString(const char* filename, std::string& outString, ui32_t ma
 
 //
 Kumu::Result_t
-Kumu::WriteStringIntoFile(const char* filename, const std::string& inString)
+Kumu::WriteStringIntoFile(const std::string& filename, const std::string& inString)
 {
   FileWriter File;
   ui32_t write_count = 0;
-  KM_TEST_NULL_STR_L(filename);
 
   Result_t result = File.OpenWrite(filename);
 
@@ -1152,7 +1144,7 @@ Kumu::ReadFileIntoObject(const std::string& Filename, Kumu::IArchive& Object, ui
       ui32_t read_count = 0;
       FileWriter Reader;
 
-      result = Reader.OpenRead(Filename.c_str());
+      result = Reader.OpenRead(Filename);
 
       if ( KM_SUCCESS(result) )
        result = Reader.Read(Buffer.Data(), file_size, &read_count);
@@ -1187,7 +1179,7 @@ Kumu::WriteObjectIntoFile(const Kumu::IArchive& Object, const std::string& Filen
       if ( KM_SUCCESS(result) )
        {
          Buffer.Length(MemWriter.Length());
-         result = Writer.OpenWrite(Filename.c_str());
+         result = Writer.OpenWrite(Filename);
        }
 
       if ( KM_SUCCESS(result) )
@@ -1212,7 +1204,7 @@ Kumu::ReadFileIntoBuffer(const std::string& Filename, Kumu::ByteString& Buffer,
       ui32_t read_count = 0;
       FileWriter Reader;
 
-      result = Reader.OpenRead(Filename.c_str());
+      result = Reader.OpenRead(Filename);
 
       if ( KM_SUCCESS(result) )
        result = Reader.Read(Buffer.Data(), file_size, &read_count);
@@ -1236,7 +1228,7 @@ Kumu::WriteBufferIntoFile(const Kumu::ByteString& Buffer, const std::string& Fil
   ui32_t write_count = 0;
   FileWriter Writer;
 
-  Result_t result = Writer.OpenWrite(Filename.c_str());
+  Result_t result = Writer.OpenWrite(Filename);
 
   if ( KM_SUCCESS(result) )
     result = Writer.Write(Buffer.RoData(), Buffer.Length(), &write_count);
@@ -1261,18 +1253,16 @@ Kumu::DirScanner::DirScanner(void) : m_Handle(-1) {}
 //
 //
 Result_t
-Kumu::DirScanner::Open(const char* filename)
+Kumu::DirScanner::Open(const std::string& filename)
 {
-  KM_TEST_NULL_STR_L(filename);
-
   // we need to append a '*' to read the entire directory
-  ui32_t fn_len = strlen(filename); 
+  ui32_t fn_len = filename.size(); 
   char* tmp_file = (char*)malloc(fn_len + 8);
 
   if ( tmp_file == 0 )
     return RESULT_ALLOC;
 
-  strcpy(tmp_file, filename);
+  strcpy(tmp_file, filename.c_str());
   char* p = &tmp_file[fn_len] - 1;
 
   if ( *p != '/' && *p != '\\' )
@@ -1348,13 +1338,11 @@ Kumu::DirScanner::DirScanner(void) : m_Handle(NULL) {}
 
 //
 Result_t
-Kumu::DirScanner::Open(const char* filename)
+Kumu::DirScanner::Open(const std::string& dirname)
 {
-  KM_TEST_NULL_STR_L(filename);
-
   Result_t result = RESULT_OK;
 
-  if ( ( m_Handle = opendir(filename) ) == NULL )
+  if ( ( m_Handle = opendir(dirname.c_str()) ) == NULL )
     {
       switch ( errno )
        {
@@ -1370,7 +1358,7 @@ Kumu::DirScanner::Open(const char* filename)
        case ENFILE:
          result = RESULT_STATE;
        default:
-         DefaultLogSink().Error("DirScanner::Open(%s): %s\n", filename, strerror(errno));
+         DefaultLogSink().Error("DirScanner::Open(%s): %s\n", dirname.c_str(), strerror(errno));
          result = RESULT_FAIL;
        }
     }
index a051e8e99b0a66eb96818a7c0f4eb70a562b39e5..46e200086b8fe0b0694487f777831ceaef7e09c0 100755 (executable)
@@ -65,7 +65,7 @@ namespace Kumu
       DirScanner(void);
       ~DirScanner() { Close(); }
 
-      Result_t Open(const char*);
+      Result_t Open(const std::string&);
       Result_t Close();
       Result_t GetNext(char*);
     };
@@ -242,10 +242,10 @@ namespace Kumu
   // Instant IO for strings
   //
   // Reads an entire file into a string.
-  Result_t ReadFileIntoString(const char* filename, std::string& outString, ui32_t max_size = 8 * Megabyte);
+  Result_t ReadFileIntoString(const std::string& filename, std::string& outString, ui32_t max_size = 8 * Megabyte);
 
   // Writes a string to a file, overwrites the existing file if present.
-  Result_t WriteStringIntoFile(const char* filename, const std::string& inString);
+  Result_t WriteStringIntoFile(const std::string& filename, const std::string& inString);
 
   // Instant IO for archivable objects
   //
@@ -282,7 +282,7 @@ namespace Kumu
       FileReader() : m_Handle(INVALID_HANDLE_VALUE) {}
       virtual ~FileReader() { Close(); }
 
-      Result_t OpenRead(const char*) const;                          // open the file for reading
+      Result_t OpenRead(const std::string&) const;                          // open the file for reading
       Result_t Close() const;                                        // close the file
       fsize_t  Size() const;                                         // returns the file's current size
       Result_t Seek(Kumu::fpos_t = 0, SeekPos_t = SP_BEGIN) const;   // move the file pointer
@@ -312,8 +312,8 @@ namespace Kumu
       FileWriter();
       virtual ~FileWriter();
 
-      Result_t OpenWrite(const char*);                               // open a new file, overwrites existing
-      Result_t OpenModify(const char*);                              // open a file for read/write
+      Result_t OpenWrite(const std::string&);                               // open a new file, overwrites existing
+      Result_t OpenModify(const std::string&);                              // open a file for read/write
 
       // this part of the interface takes advantage of the iovec structure on
       // platforms that support it. For each call to Writev(const byte_t*, ui32_t, ui32_t*),
index 140a53f399ac174591b0458357f800b35ba34b61..89abbfd30a790cdcdc498fc30990b6829b0bd551 100755 (executable)
@@ -371,7 +371,7 @@ public:
   h__Parser() : m_TmpBuffer(VESReadSize*8) {}
   ~h__Parser() { Close(); }
 
-  Result_t OpenRead(const char* filename);
+  Result_t OpenRead(const std::string& filename);
   void     Close();
   Result_t Reset();
   Result_t ReadFrame(FrameBuffer&);
@@ -399,9 +399,8 @@ ASDCP::MPEG2::Parser::h__Parser::Close()
 
 //
 ASDCP::Result_t
-ASDCP::MPEG2::Parser::h__Parser::OpenRead(const char* filename)
+ASDCP::MPEG2::Parser::h__Parser::OpenRead(const std::string& filename)
 {
-  ASDCP_TEST_NULL_STR(filename)
   ui32_t read_count = 0;
 
   Result_t result = m_FileReader.OpenRead(filename);
@@ -443,7 +442,7 @@ ASDCP::MPEG2::Parser::h__Parser::OpenRead(const char* filename)
 
   if ( ASDCP_FAILURE(result) )
     {
-      DefaultLogSink().Error("Unable to identify a wrapping mode for the essence in file \"%s\"\n", filename);
+      DefaultLogSink().Error("Unable to identify a wrapping mode for the essence in file \"%s\"\n", filename.c_str());
       m_FileReader.Close();
     }
 
@@ -566,7 +565,7 @@ ASDCP::MPEG2::Parser::~Parser()
 // Opens the stream for reading, parses enough data to provide a complete
 // set of stream metadata for the MXFWriter below.
 ASDCP::Result_t
-ASDCP::MPEG2::Parser::OpenRead(const char* filename) const
+ASDCP::MPEG2::Parser::OpenRead(const std::string& filename) const
 {
   const_cast<ASDCP::MPEG2::Parser*>(this)->m_Parser = new h__Parser;
 
index 02bf1e9b48d5bb3b53f00dbbaca4f92bbabeb8c0..ac4bb1d2da2d89da2d39b9bffbcbe8cd7cbbef56 100755 (executable)
@@ -694,7 +694,7 @@ ASDCP::MXF::OP1aHeader::~OP1aHeader() {}
 ASDCP::Result_t
 ASDCP::MXF::OP1aHeader::InitFromFile(const Kumu::FileReader& Reader)
 {
-  Result_t result = result = Partition::InitFromFile(Reader);
+  Result_t result = Partition::InitFromFile(Reader);
 
   if ( ASDCP_FAILURE(result) )
     return result;
@@ -714,10 +714,15 @@ ASDCP::MXF::OP1aHeader::InitFromFile(const Kumu::FileReader& Reader)
 
   // slurp up the remainder of the header
   if ( HeaderByteCount < 1024 )
-    DefaultLogSink().Warn("Improbably small HeaderByteCount value: %u\n", HeaderByteCount);
-
-  assert (HeaderByteCount <= 0xFFFFFFFFL);
-  result = m_HeaderData.Capacity((ui32_t)HeaderByteCount);
+    {
+      DefaultLogSink().Warn("Improbably small HeaderByteCount value: %qu\n", HeaderByteCount);
+    }
+  else if (HeaderByteCount > ( 4 * Kumu::Megabyte ) )
+    {
+      DefaultLogSink().Warn("Improbably huge HeaderByteCount value: %qu\n", HeaderByteCount);
+    }
+  
+  result = m_HeaderData.Capacity(Kumu::xmin(4*Kumu::Megabyte, static_cast<ui32_t>(HeaderByteCount)));
 
   if ( ASDCP_SUCCESS(result) )
     {
@@ -1217,6 +1222,13 @@ ASDCP::MXF::OPAtomIndexFooter::Lookup(ui32_t frame_num, IndexTableSegment::Index
   return RESULT_FAIL;
 }
 
+//
+void
+ASDCP::MXF::OPAtomIndexFooter::SetDeltaParams(const IndexTableSegment::DeltaEntry& delta)
+{
+  m_DefaultDeltaEntry = delta;
+}
+
 //
 void
 ASDCP::MXF::OPAtomIndexFooter::SetIndexParamsCBR(IPrimerLookup* lookup, ui32_t size, const Rational& Rate)
@@ -1259,7 +1271,7 @@ ASDCP::MXF::OPAtomIndexFooter::PushIndexEntry(const IndexTableSegment::IndexEntr
       m_CurrentSegment = new IndexTableSegment(m_Dict);
       assert(m_CurrentSegment);
       AddChildObject(m_CurrentSegment);
-      m_CurrentSegment->DeltaEntryArray.push_back(IndexTableSegment::DeltaEntry());
+      m_CurrentSegment->DeltaEntryArray.push_back(m_DefaultDeltaEntry);
       m_CurrentSegment->IndexEditRate = m_EditRate;
       m_CurrentSegment->IndexStartPosition = 0;
     }
@@ -1271,7 +1283,7 @@ ASDCP::MXF::OPAtomIndexFooter::PushIndexEntry(const IndexTableSegment::IndexEntr
       m_CurrentSegment = new IndexTableSegment(m_Dict);
       assert(m_CurrentSegment);
       AddChildObject(m_CurrentSegment);
-      m_CurrentSegment->DeltaEntryArray.push_back(IndexTableSegment::DeltaEntry());
+      m_CurrentSegment->DeltaEntryArray.push_back(m_DefaultDeltaEntry);
       m_CurrentSegment->IndexEditRate = m_EditRate;
       m_CurrentSegment->IndexStartPosition = StartPosition;
     }
@@ -1427,7 +1439,7 @@ static bool        s_TypesInit = false;
 
 //
 void
-ASDCP::MXF::SetObjectFactory(ASDCP::UL label, ASDCP::MXF::MXFObjectFactory_t factory)
+ASDCP::MXF::SetObjectFactory(const ASDCP::UL& label, ASDCP::MXF::MXFObjectFactory_t factory)
 {
   s_FactoryList.Insert(label, factory);
 }
@@ -1460,10 +1472,9 @@ ASDCP::MXF::CreateObject(const Dictionary*& Dict, const UL& label)
 
 //
 bool
-ASDCP::MXF::decode_mca_string(const std::string& s, const mca_label_map_t& labels, const Dictionary& dict, const std::string& language,
+ASDCP::MXF::decode_mca_string(const std::string& s, const mca_label_map_t& labels, const Dictionary*& dict, const std::string& language,
                              InterchangeObject_list_t& descriptor_list, ui32_t& channel_count)
 {
-  const Dictionary *dictp = &dict;
   std::string symbol_buf;
   channel_count = 0;
   ASDCP::MXF::SoundfieldGroupLabelSubDescriptor *current_soundfield = 0;
@@ -1475,13 +1486,13 @@ ASDCP::MXF::decode_mca_string(const std::string& s, const mca_label_map_t& label
        {
          if ( current_soundfield != 0 )
            {
-             fprintf(stderr, "Encountered '(', already processing a soundfield group.\n");
+             DefaultLogSink().Error("Encountered '(', already processing a soundfield group.\n");
              return false;
            }
 
          if ( symbol_buf.empty() )
            {
-             fprintf(stderr, "Encountered '(', without leading soundfield group symbol.\n");
+             DefaultLogSink().Error("Encountered '(', without leading soundfield group symbol.\n");
              return false;
            }
 
@@ -1489,17 +1500,17 @@ ASDCP::MXF::decode_mca_string(const std::string& s, const mca_label_map_t& label
       
          if ( i == labels.end() )
            {
-             fprintf(stderr, "Unknown symbol: '%s'\n", symbol_buf.c_str());
+             DefaultLogSink().Error("Unknown symbol: '%s'\n", symbol_buf.c_str());
              return false;
            }
       
          if ( i->second.Value()[10] != 2 ) // magic depends on UL "Essence Facet" byte (see ST 428-12)
            {
-             fprintf(stderr, "Not a soundfield group symbol: '%s'\n", symbol_buf.c_str());
+             DefaultLogSink().Error("Not a soundfield group symbol: '%s'\n", symbol_buf.c_str());
              return false;
            }
 
-         current_soundfield = new ASDCP::MXF::SoundfieldGroupLabelSubDescriptor(dictp);
+         current_soundfield = new ASDCP::MXF::SoundfieldGroupLabelSubDescriptor(dict);
 
          GenRandomValue(current_soundfield->InstanceUID);
          GenRandomValue(current_soundfield->MCALinkID);
@@ -1514,13 +1525,13 @@ ASDCP::MXF::decode_mca_string(const std::string& s, const mca_label_map_t& label
        {
          if ( current_soundfield == 0 )
            {
-             fprintf(stderr, "Encountered ')', not currently processing a soundfield group.\n");
+             DefaultLogSink().Error("Encountered ')', not currently processing a soundfield group.\n");
              return false;
            }
 
          if ( symbol_buf.empty() )
            {
-             fprintf(stderr, "Soundfield group description contains no channels.\n");
+             DefaultLogSink().Error("Soundfield group description contains no channels.\n");
              return false;
            }
 
@@ -1528,16 +1539,16 @@ ASDCP::MXF::decode_mca_string(const std::string& s, const mca_label_map_t& label
       
          if ( i == labels.end() )
            {
-             fprintf(stderr, "Unknown symbol: '%s'\n", symbol_buf.c_str());
+             DefaultLogSink().Error("Unknown symbol: '%s'\n", symbol_buf.c_str());
              return false;
            }
 
          ASDCP::MXF::AudioChannelLabelSubDescriptor *channel_descr =
-           new ASDCP::MXF::AudioChannelLabelSubDescriptor(dictp);
+           new ASDCP::MXF::AudioChannelLabelSubDescriptor(dict);
 
          GenRandomValue(channel_descr->InstanceUID);
          assert(current_soundfield);
-         channel_descr->MCALinkID = current_soundfield->MCALinkID;
+         channel_descr->SoundfieldGroupLinkID = current_soundfield->MCALinkID;
          channel_descr->MCAChannelID = channel_count++;
          channel_descr->MCATagSymbol = "ch" + i->first;
          channel_descr->MCATagName = i->first;
@@ -1555,24 +1566,24 @@ ASDCP::MXF::decode_mca_string(const std::string& s, const mca_label_map_t& label
 
              if ( i == labels.end() )
                {
-                 fprintf(stderr, "Unknown symbol: '%s'\n", symbol_buf.c_str());
+                 DefaultLogSink().Error("Unknown symbol: '%s'\n", symbol_buf.c_str());
                  return false;
                }
 
              if ( i->second.Value()[10] != 1 ) // magic depends on UL "Essence Facet" byte (see ST 428-12)
                {
-                 fprintf(stderr, "Not a channel symbol: '%s'\n", symbol_buf.c_str());
+                 DefaultLogSink().Error("Not a channel symbol: '%s'\n", symbol_buf.c_str());
                  return false;
                }
 
              ASDCP::MXF::AudioChannelLabelSubDescriptor *channel_descr =
-               new ASDCP::MXF::AudioChannelLabelSubDescriptor(dictp);
+               new ASDCP::MXF::AudioChannelLabelSubDescriptor(dict);
 
              GenRandomValue(channel_descr->InstanceUID);
 
              if ( current_soundfield != 0 )
                {
-                 channel_descr->MCALinkID = current_soundfield->MCALinkID;
+                 channel_descr->SoundfieldGroupLinkID = current_soundfield->MCALinkID;
                }
 
              channel_descr->MCAChannelID = channel_count++;
@@ -1590,7 +1601,7 @@ ASDCP::MXF::decode_mca_string(const std::string& s, const mca_label_map_t& label
        }
       else if ( ! isspace(*i) )
        {
-         fprintf(stderr, "Unexpected character '%c'.\n", *i);
+         DefaultLogSink().Error("Unexpected character '%c'.\n", *i);
          return false;
        }
     }
@@ -1601,18 +1612,18 @@ ASDCP::MXF::decode_mca_string(const std::string& s, const mca_label_map_t& label
       
       if ( i == labels.end() )
        {
-         fprintf(stderr, "Unknown symbol: '%s'\n", symbol_buf.c_str());
+         DefaultLogSink().Error("Unknown symbol: '%s'\n", symbol_buf.c_str());
          return false;
        }
 
       ASDCP::MXF::AudioChannelLabelSubDescriptor *channel_descr =
-       new ASDCP::MXF::AudioChannelLabelSubDescriptor(dictp);
+       new ASDCP::MXF::AudioChannelLabelSubDescriptor(dict);
 
       GenRandomValue(channel_descr->InstanceUID);
 
       if ( current_soundfield != 0 )
        {
-         channel_descr->MCALinkID = current_soundfield->MCALinkID;
+         channel_descr->SoundfieldGroupLinkID = current_soundfield->MCALinkID;
        }
 
       channel_descr->MCAChannelID = channel_count++;
@@ -1626,7 +1637,7 @@ ASDCP::MXF::decode_mca_string(const std::string& s, const mca_label_map_t& label
   return true;
 }
 
-
+//
 ASDCP::MXF::ASDCP_MCAConfigParser::ASDCP_MCAConfigParser(const Dictionary*& d) : m_Dict(d), m_ChannelCount(0)
 {
   m_LabelMap.insert(mca_label_map_t::value_type("L", m_Dict->ul(MDD_DCAudioChannel_L)));
@@ -1662,7 +1673,7 @@ ASDCP::MXF::ASDCP_MCAConfigParser::ChannelCount() const
 bool
 ASDCP::MXF::ASDCP_MCAConfigParser::DecodeString(const std::string& s, const std::string& language)
 {
-  return decode_mca_string(s, m_LabelMap, *m_Dict, language, *this, m_ChannelCount);
+  return decode_mca_string(s, m_LabelMap, m_Dict, language, *this, m_ChannelCount);
 }
 
 
index 4af89932d7c680439692e16ab85f56bf8325a035..6e6a47afd154e4326661e51888a2d60f0ee9efbd 100755 (executable)
--- a/src/MXF.h
+++ b/src/MXF.h
@@ -47,7 +47,7 @@ namespace ASDCP
       typedef ASDCP::MXF::InterchangeObject* (*MXFObjectFactory_t)(const Dictionary*&);
 
       //
-      void SetObjectFactory(UL label, MXFObjectFactory_t factory);
+      void SetObjectFactory(const UL& label, MXFObjectFactory_t factory);
 
       //
       InterchangeObject* CreateObject(const Dictionary*& Dict, const UL& label);
@@ -303,6 +303,7 @@ namespace ASDCP
       //
       class IndexTableSegment : public InterchangeObject
        {
+         IndexTableSegment();
          ASDCP_NO_COPY_CONSTRUCT(IndexTableSegment);
 
        public:
@@ -314,7 +315,7 @@ namespace ASDCP
              ui8_t   Slice;
              ui32_t  ElementData;
 
-             DeltaEntry() : PosTableIndex(-1), Slice(0), ElementData(0) {}
+             DeltaEntry() : PosTableIndex(0), Slice(0), ElementData(0) {}
              DeltaEntry(i8_t pos, ui8_t slice, ui32_t data) : PosTableIndex(pos), Slice(slice), ElementData(data) {}
              inline bool HasValue() const { return true; }
              ui32_t      ArchiveLength() const { return sizeof(ui32_t) + 2; }
@@ -412,6 +413,7 @@ namespace ASDCP
          ui32_t              m_BytesPerEditUnit;
          Rational            m_EditRate;
          ui32_t              m_BodySID;
+         IndexTableSegment::DeltaEntry m_DefaultDeltaEntry;
 
          ASDCP_NO_COPY_CONSTRUCT(OPAtomIndexFooter);
          OPAtomIndexFooter();
@@ -435,6 +437,7 @@ namespace ASDCP
 
          virtual Result_t Lookup(ui32_t frame_num, IndexTableSegment::IndexEntry&) const;
          virtual void     PushIndexEntry(const IndexTableSegment::IndexEntry&);
+         virtual void     SetDeltaParams(const IndexTableSegment::DeltaEntry&);
          virtual void     SetIndexParamsCBR(IPrimerLookup* lookup, ui32_t size, const Rational& Rate);
          virtual void     SetIndexParamsVBR(IPrimerLookup* lookup, const Rational& Rate, Kumu::fpos_t offset);
        };
@@ -457,7 +460,8 @@ namespace ASDCP
       };
 
       typedef std::map<const std::string, const UL, ci_comp> mca_label_map_t;
-      bool decode_mca_string(const std::string& s, const mca_label_map_t& labels, const Dictionary& dict, const std::string& language, InterchangeObject_list_t&, ui32_t&);
+      bool decode_mca_string(const std::string& s, const mca_label_map_t& labels,
+                            const Dictionary*& dict, const std::string& language, InterchangeObject_list_t&, ui32_t&);
 
       //
       class ASDCP_MCAConfigParser : public InterchangeObject_list_t
index c1bcf004fe7691cc62bb9ea8a8b1233d9c608f57..83f85975b861978c6792c20b9aac1d2ae1ffc66a 100644 (file)
@@ -129,9 +129,9 @@ libas02_la_SOURCES  = \
        h__02_Reader.cpp \
        h__02_Writer.cpp \
        ST2052_TextParser.cpp \
-       AS_02_TimedText.cpp \
        AS_02_JP2K.cpp \
-       AS_02_PCM.cpp
+       AS_02_PCM.cpp \
+       AS_02_TimedText.cpp
 
 libas02_la_LDFLAGS = -release @VERSION@
 libas02_la_LIBADD = libasdcp.la libkumu.la
@@ -161,6 +161,10 @@ libpyasdcp_la_CPPFLAGS = @PYTHON_CPPFLAGS@
 libpyasdcp_la_LDFLAGS = @PYTHON_LSPEC@  -release @VERSION@
 libpyasdcp_la_LIBADD = libkumu.la libasdcp.la
 
+if USE_AS_02
+libpyasdcp_la_LIBADD   += libas02.la
+endif
+
 pyexecdir = @PYTHON_EXECDIR@
 pyexec_includedir = $(PYTHON_PREFIX)/include/python$(PYTHON_SHORTVERSION)
 nodist_pyexec_include_HEADERS = kumu_python.h asdcp_python.h asdcp_wrappers.h
index 2ebdfa0b69f9c26ca3e7905d4654f8a7562e538c..8b8161947266926cec2326e500ca5ed1b18f856f 100755 (executable)
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2004-2012, John Hurst
+Copyright (c) 2004-2013, John Hurst
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -48,10 +48,8 @@ ASDCP::ParserInstance::~ParserInstance()
 
 // PCM::CalcSampleSize(ADesc);
 Result_t
-ASDCP::ParserInstance::OpenRead(const char* filename, const Rational& PictureRate)
+ASDCP::ParserInstance::OpenRead(const std::string& filename, const Rational& PictureRate)
 {
-  ASDCP_TEST_NULL_STR(filename);
-
   Result_t result = Parser.OpenRead(filename, PictureRate);
 
   if ( ASDCP_SUCCESS(result) )
index 80c1d52f194d65d9ceb09205491d03b7ef178d15..dbacd685a715e2ca20e82ce905a3827937470999 100755 (executable)
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2004-2012, John Hurst
+Copyright (c) 2004-2013, John Hurst
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -54,7 +54,7 @@ namespace ASDCP
       ParserInstance();
       virtual ~ParserInstance();
 
-      Result_t OpenRead(const char* filename, const Rational& PictureRate);
+      Result_t OpenRead(const std::string& filename, const Rational& PictureRate);
       Result_t PutSample(byte_t* p);
       Result_t ReadFrame();
       inline ui32_t SampleSize()  { return m_SampleSize; }
index e3b693d6bcf01928b88fc21362e0eeb7483ef1fc..30e5d2884ece6122322b732d03a04284bfa88509 100755 (executable)
@@ -69,7 +69,7 @@ public:
     Close();
    }
 
-  Result_t OpenRead(const char* filename, const Rational& PictureRate);
+  Result_t OpenRead(const std::string& filename, const Rational& PictureRate);
   void     Close();
   void     Reset();
   Result_t ReadFrame(FrameBuffer&);
@@ -94,10 +94,8 @@ ASDCP::PCM::WAVParser::h__WAVParser::Reset()
 
 //
 ASDCP::Result_t
-ASDCP::PCM::WAVParser::h__WAVParser::OpenRead(const char* filename, const Rational& PictureRate)
+ASDCP::PCM::WAVParser::h__WAVParser::OpenRead(const std::string& filename, const Rational& PictureRate)
 {
-  ASDCP_TEST_NULL_STR(filename);
-
   Result_t result = m_FileReader.OpenRead(filename);
 
   if ( ASDCP_SUCCESS(result) )
@@ -203,7 +201,7 @@ ASDCP::PCM::WAVParser::~WAVParser()
 // Opens the stream for reading, parses enough data to provide a complete
 // set of stream metadata for the MXFWriter below.
 ASDCP::Result_t
-ASDCP::PCM::WAVParser::OpenRead(const char* filename, const Rational& PictureRate) const
+ASDCP::PCM::WAVParser::OpenRead(const std::string& filename, const Rational& PictureRate) const
 {
   const_cast<ASDCP::PCM::WAVParser*>(this)->m_Parser = new h__WAVParser;
 
index b7b58c5575f84dc2ee8c038dcf565a40243a6983..3312b58eb1e3206325c94fb3b3a5ffbbccc21245 100644 (file)
@@ -136,8 +136,8 @@ public:
     return m_DefaultResolver;
   }
 
-  Result_t OpenRead(const char* filename);
-  Result_t OpenRead(const std::string& xml_doc, const char* filename);
+  Result_t OpenRead(const std::string& filename);
+  Result_t OpenRead(const std::string& xml_doc, const std::string& filename);
   Result_t ReadAncillaryResource(const byte_t* uuid, FrameBuffer& FrameBuf, const IResourceResolver& Resolver) const;
 };
 
@@ -178,7 +178,7 @@ decode_rational(const char* str_rat)
 
 //
 Result_t
-ASDCP::TimedText::DCSubtitleParser::h__SubtitleParser::OpenRead(const char* filename)
+ASDCP::TimedText::DCSubtitleParser::h__SubtitleParser::OpenRead(const std::string& filename)
 {
   Result_t result = ReadFileIntoString(filename, m_XMLDoc);
 
@@ -191,14 +191,18 @@ ASDCP::TimedText::DCSubtitleParser::h__SubtitleParser::OpenRead(const char* file
 
 //
 Result_t
-ASDCP::TimedText::DCSubtitleParser::h__SubtitleParser::OpenRead(const std::string& xml_doc, const char* filename)
+ASDCP::TimedText::DCSubtitleParser::h__SubtitleParser::OpenRead(const std::string& xml_doc, const std::string& filename)
 {
   m_XMLDoc = xml_doc;
 
-  if ( filename != 0 )
-    m_Filename = filename;
+  if ( filename.empty() )
+    {
+      m_Filename = "<string>";
+    }
   else
-    m_Filename = "<string>";
+    {
+      m_Filename = filename;
+    }
 
   return OpenRead();
 }
@@ -394,7 +398,7 @@ ASDCP::TimedText::DCSubtitleParser::~DCSubtitleParser()
 // Opens the stream for reading, parses enough data to provide a complete
 // set of stream metadata for the MXFWriter below.
 ASDCP::Result_t
-ASDCP::TimedText::DCSubtitleParser::OpenRead(const char* filename) const
+ASDCP::TimedText::DCSubtitleParser::OpenRead(const std::string& filename) const
 {
   const_cast<ASDCP::TimedText::DCSubtitleParser*>(this)->m_Parser = new h__SubtitleParser;
 
@@ -408,7 +412,7 @@ ASDCP::TimedText::DCSubtitleParser::OpenRead(const char* filename) const
 
 // Parses an XML document to provide a complete set of stream metadata for the MXFWriter below.
 Result_t
-ASDCP::TimedText::DCSubtitleParser::OpenRead(const std::string& xml_doc, const char* filename) const
+ASDCP::TimedText::DCSubtitleParser::OpenRead(const std::string& xml_doc, const std::string& filename) const
 {
   const_cast<ASDCP::TimedText::DCSubtitleParser*>(this)->m_Parser = new h__SubtitleParser;
 
index b85781d065ac9ef08116eaf4b1127b652345d274..ae66df7eea6463e22ab385472531448c576a8080 100755 (executable)
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2011-2012, Robert Scheler, Heiko Sparenberg Fraunhofer IIS,
+Copyright (c) 2011-2013, Robert Scheler, Heiko Sparenberg Fraunhofer IIS,
 John Hurst
 
 All rights reserved.
@@ -420,44 +420,51 @@ read_PCM_file(CommandOptions& Options)
 
   Result_t result = Reader.OpenRead(Options.input_filename, Options.edit_rate);
 
-  if ( ASDCP_SUCCESS(result) )
+  if ( KM_SUCCESS(result) )
     {
       if ( Options.verbose_flag )
        {
          fprintf(stderr, "Frame Buffer size: %u\n", Options.fb_size);
        }
+      
+      ASDCP::MXF::InterchangeObject* tmp_obj = 0;
 
-      result = Reader.OP1aHeader().GetMDObjectByType(DefaultCompositeDict().ul(MDD_WaveAudioDescriptor),
-                                                    reinterpret_cast<MXF::InterchangeObject**>(&wave_descriptor));
+      result = Reader.OP1aHeader().GetMDObjectByType(DefaultCompositeDict().ul(MDD_WaveAudioDescriptor), &tmp_obj);
 
       if ( KM_SUCCESS(result) )
        {
-         assert(wave_descriptor);
-         last_frame = wave_descriptor->ContainerDuration;
+         wave_descriptor = dynamic_cast<ASDCP::MXF::WaveAudioDescriptor*>(tmp_obj);
 
+         if ( wave_descriptor == 0 )
+           {
+             fprintf(stderr, "File does not contain an essence descriptor.\n");
+             return RESULT_FAIL;
+           }
+      
          if ( Options.verbose_flag )
            {
              wave_descriptor->Dump();
            }
-       }
-      else
-       {
-         fprintf(stderr, "File does not contain an essence descriptor.\n");
-         last_frame = Reader.AS02IndexReader().GetDuration();
-       }
 
-      if ( last_frame == 0 )
-       {
-         fprintf(stderr, "Unable to determine file duration.\n");
-         return RESULT_FAIL;
-       }
+         if ( wave_descriptor->ContainerDuration.get() == 0 )
+           {
+             fprintf(stderr, "ContainerDuration not set in file descriptor, attempting to use index duration.\n");
+             last_frame = Reader.AS02IndexReader().GetDuration();
+           }
+         else
+           {
+             last_frame = wave_descriptor->ContainerDuration;
+           }
 
-      FrameBuffer.Capacity(AS_02::MXF::CalcFrameBufferSize(*wave_descriptor, Options.edit_rate));
-      last_frame = AS_02::MXF::CalcFramesFromDurationInSamples(last_frame, *wave_descriptor, Options.edit_rate);
+         if ( last_frame == 0 )
+           {
+             fprintf(stderr, "Unable to determine file duration.\n");
+             return RESULT_FAIL;
+           }
 
-      if ( Options.verbose_flag )
-       {
-         wave_descriptor->Dump();
+         assert(wave_descriptor);
+         FrameBuffer.Capacity(AS_02::MXF::CalcFrameBufferSize(*wave_descriptor, Options.edit_rate));
+         last_frame = AS_02::MXF::CalcFramesFromDurationInSamples(last_frame, *wave_descriptor, Options.edit_rate);
        }
     }
 
@@ -565,12 +572,12 @@ main(int argc, const char** argv)
     {
       switch ( EssenceType )
        {
-       case ESS_JPEG_2000:
+       case ESS_AS02_JPEG_2000:
          result = read_JP2K_file(Options);
          break;
 
-       case ESS_PCM_24b_48k:
-       case ESS_PCM_24b_96k:
+       case ESS_AS02_PCM_24b_48k:
+       case ESS_AS02_PCM_24b_96k:
          result = read_PCM_file(Options);
          break;
 
@@ -584,11 +591,7 @@ main(int argc, const char** argv)
     {
       fputs("Program stopped on error.\n", stderr);
 
-      if ( result == RESULT_SFORMAT )
-       {
-         fputs("Use option '-3' to force stereoscopic mode.\n", stderr);
-       }
-      else if ( result != RESULT_FAIL )
+      if ( result != RESULT_FAIL )
        {
          fputs(result, stderr);
          fputc('\n', stderr);
index 24d6b1e4ed689d5cdc80da627bea81f756d38c7a..a35770a3e7bc1b76bcac3dd0805c248066d07668 100755 (executable)
@@ -241,6 +241,9 @@ decode_channel_fmt(const std::string& label_name)
   else if ( label_name == "7.1DS" )
     return PCM::CF_CFG_5;
 
+  else if ( label_name == "MCA" )
+    return PCM::CF_CFG_6;
+
   fprintf(stderr, "Error decoding channel format string: %s\n", label_name.c_str());
   fprintf(stderr, "Expecting '5.1', '6.1', '7.1', '7.1DS' or 'WTF'\n");
   return PCM::CF_NONE;
index 3bad03e937c545f4c66e647823498d20d2edd8f6..fd4a6d931b5d7bf2594eaf68a99e8968dd3404c2 100755 (executable)
@@ -187,6 +187,9 @@ decode_channel_fmt(const std::string& label_name)
   else if ( label_name == "7.1DS" )
     return PCM::CF_CFG_5;
 
+  else if ( label_name == "MCA" )
+    return PCM::CF_CFG_6;
+
   fprintf(stderr, "Error decoding channel format string: %s\n", label_name.c_str());
   fprintf(stderr, "Expecting '5.1', '6.1', '7.1', '7.1DS' or 'WTF'\n");
   return PCM::CF_NONE;
@@ -475,7 +478,7 @@ write_MPEG2_file(CommandOptions& Options)
   Kumu::FortunaRNG   RNG;
 
   // set up essence parser
-  Result_t result = Parser.OpenRead(Options.filenames.front().c_str());
+  Result_t result = Parser.OpenRead(Options.filenames.front());
 
   // set up MXF writer
   if ( ASDCP_SUCCESS(result) )
@@ -531,7 +534,7 @@ write_MPEG2_file(CommandOptions& Options)
        }
 
       if ( ASDCP_SUCCESS(result) )
-       result = Writer.OpenWrite(Options.out_file.c_str(), Info, VDesc);
+       result = Writer.OpenWrite(Options.out_file, Info, VDesc);
     }
 
   if ( ASDCP_SUCCESS(result) )
@@ -631,12 +634,12 @@ write_JP2K_S_file(CommandOptions& Options)
     }
 
   // set up essence parser
-  Result_t result = ParserLeft.OpenRead(Options.filenames.front().c_str(), Options.j2c_pedantic);
+  Result_t result = ParserLeft.OpenRead(Options.filenames.front(), Options.j2c_pedantic);
 
   if ( ASDCP_SUCCESS(result) )
     {
       Options.filenames.pop_front();
-      result = ParserRight.OpenRead(Options.filenames.front().c_str(), Options.j2c_pedantic);
+      result = ParserRight.OpenRead(Options.filenames.front(), Options.j2c_pedantic);
     }
 
   // set up MXF writer
@@ -696,7 +699,7 @@ write_JP2K_S_file(CommandOptions& Options)
        }
 
       if ( ASDCP_SUCCESS(result) )
-       result = Writer.OpenWrite(Options.out_file.c_str(), Info, PDesc);
+       result = Writer.OpenWrite(Options.out_file, Info, PDesc);
 
       if ( ASDCP_SUCCESS(result) && Options.picture_coding.HasValue() )
        {
@@ -771,7 +774,7 @@ write_JP2K_file(CommandOptions& Options)
   Kumu::FortunaRNG        RNG;
 
   // set up essence parser
-  Result_t result = Parser.OpenRead(Options.filenames.front().c_str(), Options.j2c_pedantic);
+  Result_t result = Parser.OpenRead(Options.filenames.front(), Options.j2c_pedantic);
 
   // set up MXF writer
   if ( ASDCP_SUCCESS(result) )
@@ -831,7 +834,7 @@ write_JP2K_file(CommandOptions& Options)
        }
 
       if ( ASDCP_SUCCESS(result) )
-       result = Writer.OpenWrite(Options.out_file.c_str(), Info, PDesc);
+       result = Writer.OpenWrite(Options.out_file, Info, PDesc);
 
       if ( ASDCP_SUCCESS(result) && Options.picture_coding.HasValue() )
        {
@@ -915,9 +918,9 @@ write_PCM_file(CommandOptions& Options)
       FrameBuffer.Capacity(PCM::CalcFrameBufferSize(ADesc));
       ADesc.ChannelFormat = Options.channel_fmt;
 
-      if ( Options.use_smpte_labels && ADesc.ChannelFormat == PCM::CF_NONE)
+      if ( Options.use_smpte_labels && ADesc.ChannelFormat == PCM::CF_NONE && Options.mca_config.empty() )
        {
-         fprintf(stderr, "ATTENTION! Writing SMPTE audio without ChannelAssignment property (see option -l)\n");
+         fprintf(stderr, "ATTENTION! Writing SMPTE audio without ChannelAssignment property (see options -C, -l and -m)\n");
        }
 
       if ( Options.verbose_flag )
@@ -971,7 +974,7 @@ write_PCM_file(CommandOptions& Options)
        }
 
       if ( ASDCP_SUCCESS(result) )
-       result = Writer.OpenWrite(Options.out_file.c_str(), Info, ADesc);
+       result = Writer.OpenWrite(Options.out_file, Info, ADesc);
 
       if ( ASDCP_SUCCESS(result)
           && ( Options.channel_assignment.HasValue()
@@ -1139,7 +1142,7 @@ write_PCM_with_ATMOS_sync_file(CommandOptions& Options)
        }
 
     if ( ASDCP_SUCCESS(result) )
-      result = Writer.OpenWrite(Options.out_file.c_str(), Info, ADesc);
+      result = Writer.OpenWrite(Options.out_file, Info, ADesc);
   }
 
   if ( ASDCP_SUCCESS(result) )
@@ -1209,7 +1212,7 @@ write_timed_text_file(CommandOptions& Options)
   Kumu::FortunaRNG  RNG;
 
   // set up essence parser
-  Result_t result = Parser.OpenRead(Options.filenames.front().c_str());
+  Result_t result = Parser.OpenRead(Options.filenames.front());
 
   // set up MXF writer
   if ( ASDCP_SUCCESS(result) )
@@ -1262,7 +1265,7 @@ write_timed_text_file(CommandOptions& Options)
        }
 
       if ( ASDCP_SUCCESS(result) )
-       result = Writer.OpenWrite(Options.out_file.c_str(), Info, TDesc);
+       result = Writer.OpenWrite(Options.out_file, Info, TDesc);
     }
 
   if ( ASDCP_FAILURE(result) )
@@ -1324,7 +1327,7 @@ write_dolby_atmos_file(CommandOptions& Options)
   Kumu::FortunaRNG        RNG;
 
   // set up essence parser
-  Result_t result = Parser.OpenRead(Options.filenames.front().c_str());
+  Result_t result = Parser.OpenRead(Options.filenames.front());
 
   // set up MXF writer
   if ( ASDCP_SUCCESS(result) )
@@ -1382,7 +1385,7 @@ write_dolby_atmos_file(CommandOptions& Options)
        }
 
     if ( ASDCP_SUCCESS(result) )
-      result = Writer.OpenWrite(Options.out_file.c_str(), Info, ADesc);
+      result = Writer.OpenWrite(Options.out_file, Info, ADesc);
   }
 
   if ( ASDCP_SUCCESS(result) )
@@ -1460,7 +1463,7 @@ main(int argc, const char** argv)
     }
 
   EssenceType_t EssenceType;
-  result = ASDCP::RawEssenceType(Options.filenames.front().c_str(), EssenceType);
+  result = ASDCP::RawEssenceType(Options.filenames.front(), EssenceType);
 
   if ( ASDCP_SUCCESS(result) )
     {
index 1a0de1175151c0caa721bb220f9d7bb42bf50ef3..b67f9c83a60ce7a3b0806845f97fc7a12dff4e4a 100644 (file)
@@ -341,10 +341,10 @@ AS_02::MXF::AS02IndexReader::GetDuration() const
 Result_t
 AS_02::MXF::AS02IndexReader::Lookup(ui32_t frame_num, ASDCP::MXF::IndexTableSegment::IndexEntry& Entry) const
 {
-  std::list<InterchangeObject*>::iterator li;
-  for ( li = m_PacketList->m_List.begin(); li != m_PacketList->m_List.end(); li++ )
+  std::list<InterchangeObject*>::iterator i;
+  for ( i = m_PacketList->m_List.begin(); i != m_PacketList->m_List.end(); ++i )
     {
-      IndexTableSegment *segment = dynamic_cast<IndexTableSegment*>(*li);
+      IndexTableSegment *segment = dynamic_cast<IndexTableSegment*>(*i);
 
       if ( segment != 0 )
        {
@@ -373,6 +373,7 @@ AS_02::MXF::AS02IndexReader::Lookup(ui32_t frame_num, ASDCP::MXF::IndexTableSegm
        }
     }
 
+  DefaultLogSink().Error("AS_02::MXF::AS02IndexReader::Lookup FAILED: frame_num=%d\n", frame_num);
   return RESULT_FAIL;
 }
 
index c81da5c16c95ddcfbd3a63e2560f4a5eed032411..1de439214f363b48cf015cda61dc926855173278 100644 (file)
@@ -42,18 +42,18 @@ static const ui32_t CBRIndexEntriesPerSegment = 5000;
 //------------------------------------------------------------------------------------------
 //
 
-AS_02::MXF::AS02IndexWriter::AS02IndexWriter(const ASDCP::Dictionary*& d) :
-  Partition(d), m_CurrentSegment(0), m_BytesPerEditUnit(0), m_Dict(d), m_Lookup(0)
+AS_02::MXF::AS02IndexWriterVBR::AS02IndexWriterVBR(const ASDCP::Dictionary*& d) :
+  Partition(d), m_CurrentSegment(0), m_Dict(d), m_Lookup(0)
 {
   BodySID = 0;
   IndexSID = 129;
 }
 
-AS_02::MXF::AS02IndexWriter::~AS02IndexWriter() {}
+AS_02::MXF::AS02IndexWriterVBR::~AS02IndexWriterVBR() {}
 
 //
 Result_t
-AS_02::MXF::AS02IndexWriter::WriteToFile(Kumu::FileWriter& Writer)
+AS_02::MXF::AS02IndexWriterVBR::WriteToFile(Kumu::FileWriter& Writer)
 {
   assert(m_Dict);
   ASDCP::FrameBuffer index_body_buffer;
@@ -114,7 +114,7 @@ AS_02::MXF::AS02IndexWriter::WriteToFile(Kumu::FileWriter& Writer)
 
 //
 void
-AS_02::MXF::AS02IndexWriter::Dump(FILE* stream)
+AS_02::MXF::AS02IndexWriterVBR::Dump(FILE* stream)
 {
   if ( stream == 0 )
     stream = stderr;
@@ -130,7 +130,7 @@ AS_02::MXF::AS02IndexWriter::Dump(FILE* stream)
 
 //
 ui32_t
-AS_02::MXF::AS02IndexWriter::GetDuration() const
+AS_02::MXF::AS02IndexWriterVBR::GetDuration() const
 {
   ui32_t duration = 0;
   std::list<InterchangeObject*>::const_iterator i;
@@ -149,39 +149,8 @@ AS_02::MXF::AS02IndexWriter::GetDuration() const
 
 //
 void
-AS_02::MXF::AS02IndexWriter::SetIndexParamsCBR(IPrimerLookup* lookup, ui32_t size, const ASDCP::Rational& Rate)
+AS_02::MXF::AS02IndexWriterVBR::PushIndexEntry(const IndexTableSegment::IndexEntry& Entry)
 {
-  assert(lookup);
-  m_Lookup = lookup;
-  m_BytesPerEditUnit = size;
-  m_EditRate = Rate;
-
-  IndexTableSegment* Index = new IndexTableSegment(m_Dict);
-  AddChildObject(Index);
-  Index->EditUnitByteCount = m_BytesPerEditUnit;
-  Index->IndexEditRate = Rate;
-}
-
-//
-void
-AS_02::MXF::AS02IndexWriter::SetIndexParamsVBR(IPrimerLookup* lookup, const ASDCP::Rational& Rate, Kumu::fpos_t offset)
-{
-  assert(lookup);
-  m_Lookup = lookup;
-  m_BytesPerEditUnit = 0;
-  m_EditRate = Rate;
-}
-
-//
-void
-AS_02::MXF::AS02IndexWriter::PushIndexEntry(const IndexTableSegment::IndexEntry& Entry)
-{
-  if ( m_BytesPerEditUnit != 0 )  // are we CBR? that's bad 
-    {
-      DefaultLogSink().Error("Call to PushIndexEntry() failed: index is CBR\n");
-      return;
-    }
-
   // do we have an available segment?
   if ( m_CurrentSegment == 0 )
     { // no, set up a new segment
@@ -192,19 +161,6 @@ AS_02::MXF::AS02IndexWriter::PushIndexEntry(const IndexTableSegment::IndexEntry&
       m_CurrentSegment->IndexEditRate = m_EditRate;
       m_CurrentSegment->IndexStartPosition = 0;
     }
-  else if ( m_CurrentSegment->IndexEntryArray.size() >= CBRIndexEntriesPerSegment )
-    { // no, this one is full, start another
-      DefaultLogSink().Warn("%s, line %d: This has never been tested.\n", __FILE__, __LINE__);
-      m_CurrentSegment->IndexDuration = m_CurrentSegment->IndexEntryArray.size();
-      ui64_t start_position = m_CurrentSegment->IndexStartPosition + m_CurrentSegment->IndexDuration;
-
-      m_CurrentSegment = new IndexTableSegment(m_Dict);
-      assert(m_CurrentSegment);
-      AddChildObject(m_CurrentSegment);
-      m_CurrentSegment->DeltaEntryArray.push_back(IndexTableSegment::DeltaEntry());
-      m_CurrentSegment->IndexEditRate = m_EditRate;
-      m_CurrentSegment->IndexStartPosition = start_position;
-    }
 
   m_CurrentSegment->IndexEntryArray.push_back(Entry);
 }
@@ -214,65 +170,14 @@ AS_02::MXF::AS02IndexWriter::PushIndexEntry(const IndexTableSegment::IndexEntry&
 //
 
 //
-AS_02::h__AS02Writer::h__AS02Writer(const ASDCP::Dictionary& d) : ASDCP::MXF::TrackFileWriter<ASDCP::MXF::OP1aHeader>(d),
-                                                                 m_ECStart(0), m_ClipStart(0), m_IndexWriter(m_Dict), m_PartitionSpace(0),
-                                                                 m_IndexStrategy(AS_02::IS_FOLLOW) {}
+AS_02::h__AS02WriterFrame::h__AS02WriterFrame(const ASDCP::Dictionary& d) :
+  h__AS02Writer<AS_02::MXF::AS02IndexWriterVBR>(d), m_IndexStrategy(AS_02::IS_FOLLOW) {}
 
-AS_02::h__AS02Writer::~h__AS02Writer() {}
+AS_02::h__AS02WriterFrame::~h__AS02WriterFrame() {}
 
 //
 Result_t
-AS_02::h__AS02Writer::WriteAS02Header(const std::string& PackageLabel, const ASDCP::UL& WrappingUL,
-                                     const std::string& TrackName, const ASDCP::UL& EssenceUL, const ASDCP::UL& DataDefinition,
-                                     const ASDCP::Rational& EditRate, ui32_t TCFrameRate, ui32_t BytesPerEditUnit)
-{
-  if ( EditRate.Numerator == 0 || EditRate.Denominator == 0 )
-    {
-      DefaultLogSink().Error("Non-zero edit-rate reqired.\n");
-      return RESULT_PARAM;
-    }
-
-  InitHeader();
-
-  AddSourceClip(EditRate, EditRate/*TODO: for a moment*/, TCFrameRate, TrackName, EssenceUL, DataDefinition, PackageLabel);
-  AddEssenceDescriptor(WrappingUL);
-  m_RIP.PairArray.push_back(RIP::Pair(0, 0)); // Header partition RIP entry
-  m_IndexWriter.OperationalPattern = m_HeaderPart.OperationalPattern;
-  m_IndexWriter.EssenceContainers = m_HeaderPart.EssenceContainers;
-
-  Result_t result = m_HeaderPart.WriteToFile(m_File, m_HeaderSize);
-
-  if ( ASDCP_SUCCESS(result) )
-    {
-      m_PartitionSpace *= ceil(EditRate.Quotient());  // convert seconds to edit units
-      m_ECStart = m_File.Tell();
-      m_IndexWriter.IndexSID = 129;
-
-      if ( BytesPerEditUnit == 0 )
-       {
-         m_IndexWriter.SetIndexParamsVBR(&m_HeaderPart.m_Primer, EditRate, m_ECStart);
-       }
-      else
-       {
-         m_IndexWriter.SetIndexParamsCBR(&m_HeaderPart.m_Primer, BytesPerEditUnit, EditRate);
-       }
-
-      UL body_ul(m_Dict->ul(MDD_ClosedCompleteBodyPartition));
-      Partition body_part(m_Dict);
-      body_part.BodySID = 1;
-      body_part.OperationalPattern = m_HeaderPart.OperationalPattern;
-      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
-    }
-
-  return result;
-}
-
-//     
-Result_t
-AS_02::h__AS02Writer::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf,const byte_t* EssenceUL, AESEncContext* Ctx, HMACContext* HMAC)
+AS_02::h__AS02WriterFrame::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf,const byte_t* EssenceUL, AESEncContext* Ctx, HMACContext* HMAC)
 {
   ui64_t this_stream_offset = m_StreamOffset; // m_StreamOffset will be changed by the call to Write_EKLV_Packet
 
@@ -307,16 +212,101 @@ AS_02::h__AS02Writer::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf,const b
   return result;
 }
 
+
+//------------------------------------------------------------------------------------------
+//
+
+
+AS_02::MXF::AS02IndexWriterCBR::AS02IndexWriterCBR(const ASDCP::Dictionary*& d) :
+  Partition(d), m_CurrentSegment(0), m_Dict(d), m_Lookup(0), m_Duration(0), m_SampleSize(0)
+{
+  BodySID = 0;
+  IndexSID = 129;
+}
+
+AS_02::MXF::AS02IndexWriterCBR::~AS02IndexWriterCBR() {}
+
+//
+Result_t
+AS_02::MXF::AS02IndexWriterCBR::WriteToFile(Kumu::FileWriter& Writer)
+{
+  assert(m_Dict);
+  ASDCP::FrameBuffer index_body_buffer;
+  ui32_t   index_body_size = MaxIndexSegmentSize; // segment-count * max-segment-size
+  Result_t result = index_body_buffer.Capacity(index_body_size); 
+
+  m_CurrentSegment = new IndexTableSegment(m_Dict);
+  assert(m_CurrentSegment);
+  m_CurrentSegment->m_Lookup = m_Lookup;
+  m_CurrentSegment->IndexEditRate = m_EditRate;
+  m_CurrentSegment->IndexStartPosition = 0;
+  m_CurrentSegment->IndexDuration = m_Duration;
+  m_CurrentSegment->EditUnitByteCount = m_SampleSize;
+  AddChildObject(m_CurrentSegment);
+
+  ASDCP::FrameBuffer WriteWrapper;
+  WriteWrapper.SetData(index_body_buffer.Data() + index_body_buffer.Size(),
+                      index_body_buffer.Capacity() - index_body_buffer.Size());
+
+  result = m_CurrentSegment->WriteToBuffer(WriteWrapper);
+  index_body_buffer.Size(index_body_buffer.Size() + WriteWrapper.Size());
+  delete m_CurrentSegment;
+  m_CurrentSegment = 0;
+  m_PacketList->m_List.clear();
+
+  if ( KM_SUCCESS(result) )
+    {
+      IndexByteCount = index_body_buffer.Size();
+      UL body_ul(m_Dict->ul(MDD_ClosedCompleteBodyPartition));
+      result = Partition::WriteToFile(Writer, body_ul);
+    }
+
+  if ( KM_SUCCESS(result) )
+    {
+      ui32_t write_count = 0;
+      result = Writer.Write(index_body_buffer.RoData(), index_body_buffer.Size(), &write_count);
+      assert(write_count == index_body_buffer.Size());
+    }
+
+  return result;
+}
+
+//
+ui32_t
+AS_02::MXF::AS02IndexWriterCBR::GetDuration() const
+{
+  return m_Duration;
+}
+
+//
+void
+AS_02::MXF::AS02IndexWriterCBR::SetEditRate(const ASDCP::Rational& edit_rate, const ui32_t& sample_size)
+{
+  m_EditRate = edit_rate;
+  m_SampleSize = sample_size;
+}
+
+
+//------------------------------------------------------------------------------------------
+//
+
+//
+AS_02::h__AS02WriterClip::h__AS02WriterClip(const ASDCP::Dictionary& d) :
+  h__AS02Writer<AS_02::MXF::AS02IndexWriterCBR>(d),
+  m_ECStart(0), m_ClipStart(0), m_IndexStrategy(AS_02::IS_FOLLOW) {}
+
+AS_02::h__AS02WriterClip::~h__AS02WriterClip() {}
+
 //
 bool
-AS_02::h__AS02Writer::HasOpenClip() const
+AS_02::h__AS02WriterClip::HasOpenClip() const
 {
   return m_ClipStart != 0;
 }
 
 //
 Result_t
-AS_02::h__AS02Writer::StartClip(const byte_t* EssenceUL, AESEncContext* Ctx, HMACContext* HMAC)
+AS_02::h__AS02WriterClip::StartClip(const byte_t* EssenceUL, AESEncContext* Ctx, HMACContext* HMAC)
 {
   if ( Ctx != 0 )
     {
@@ -340,7 +330,7 @@ AS_02::h__AS02Writer::StartClip(const byte_t* EssenceUL, AESEncContext* Ctx, HMA
 
 //
 Result_t
-AS_02::h__AS02Writer::WriteClipBlock(const ASDCP::FrameBuffer& FrameBuf)
+AS_02::h__AS02WriterClip::WriteClipBlock(const ASDCP::FrameBuffer& FrameBuf)
 {
   if ( m_ClipStart == 0 )
     {
@@ -353,7 +343,7 @@ AS_02::h__AS02Writer::WriteClipBlock(const ASDCP::FrameBuffer& FrameBuf)
 
 //
 Result_t
-AS_02::h__AS02Writer::FinalizeClip(ui32_t bytes_per_frame)
+AS_02::h__AS02WriterClip::FinalizeClip(ui32_t bytes_per_frame)
 {
   if ( m_ClipStart == 0 )
     {
@@ -377,86 +367,7 @@ AS_02::h__AS02Writer::FinalizeClip(ui32_t bytes_per_frame)
   return result;
 }
 
-// standard method of writing the header and footer of a completed AS-02 file
-//
-Result_t
-AS_02::h__AS02Writer::WriteAS02Footer()
-{
-  if ( m_IndexWriter.GetDuration() > 0 )
-    {
-      m_IndexWriter.ThisPartition = m_File.Tell();
-      m_IndexWriter.WriteToFile(m_File);
-      m_RIP.PairArray.push_back(RIP::Pair(0, m_IndexWriter.ThisPartition));
-    }
-
-  // update all Duration properties
-  ASDCP::MXF::Partition footer_part(m_Dict);
-  DurationElementList_t::iterator dli = m_DurationUpdateList.begin();
-
-  for (; dli != m_DurationUpdateList.end(); ++dli )
-    {
-      **dli = m_FramesWritten;
-    }
-
-  m_EssenceDescriptor->ContainerDuration = m_FramesWritten;
-  footer_part.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_HeaderPart.FooterPartition = here;
-
-  assert(m_Dict);
-  footer_part.OperationalPattern = m_HeaderPart.OperationalPattern;
-  footer_part.EssenceContainers = m_HeaderPart.EssenceContainers;
-  footer_part.FooterPartition = here;
-  footer_part.ThisPartition = here;
 
-  UL footer_ul(m_Dict->ul(MDD_CompleteFooter));
-  Result_t result = footer_part.WriteToFile(m_File, footer_ul);
-
-  if ( ASDCP_SUCCESS(result) )
-    result = m_RIP.WriteToFile(m_File);
-
-  if ( ASDCP_SUCCESS(result) )
-    result = m_File.Seek(0);
-
-  if ( ASDCP_SUCCESS(result) )
-    result = m_HeaderPart.WriteToFile(m_File, m_HeaderSize);
-
-  if ( ASDCP_SUCCESS(result) )
-    {
-      ASDCP::MXF::Array<ASDCP::MXF::RIP::Pair>::const_iterator i = m_RIP.PairArray.begin();
-      ui64_t header_byte_count = m_HeaderPart.HeaderByteCount;
-      ui64_t previous_partition = 0;
-
-      for ( i = m_RIP.PairArray.begin(); ASDCP_SUCCESS(result) && i != m_RIP.PairArray.end(); ++i )
-       {
-         ASDCP::MXF::Partition plain_part(m_Dict);
-         result = m_File.Seek(i->ByteOffset);
-
-         if ( ASDCP_SUCCESS(result) )
-           result = plain_part.InitFromFile(m_File);
-      
-         if ( KM_SUCCESS(result)
-              && ( plain_part.IndexSID > 0 || plain_part.BodySID > 0 ) )
-           {
-             plain_part.PreviousPartition = previous_partition;
-             plain_part.FooterPartition = footer_part.ThisPartition;
-             previous_partition = plain_part.ThisPartition;
-             result = m_File.Seek(i->ByteOffset);
-
-             if ( ASDCP_SUCCESS(result) )
-               {
-                 UL tmp_ul = plain_part.GetUL();
-                 result = plain_part.WriteToFile(m_File, tmp_ul);
-               }
-           }
-       }
-    }
-
-  m_File.Close();
-  return result;
-}
 
 
 //
index b1c055591aaf0c478a8c4f54111f399d82ca4625..a427fb5760558e804be06686a0c1e0c36a3b4878 100755 (executable)
@@ -70,7 +70,7 @@ ASDCP::h__ASDCPReader::~h__ASDCPReader() {}
 
 // AS-DCP method of opening an MXF file for read
 Result_t
-ASDCP::h__ASDCPReader::OpenMXFRead(const char* filename)
+ASDCP::h__ASDCPReader::OpenMXFRead(const std::string& filename)
 {
   Result_t result = ASDCP::MXF::TrackFileReader<OP1aHeader, OPAtomIndexFooter>::OpenMXFRead(filename);