the big-pre-as-02-refactor
authorjhurst <jhurst@cinecert.com>
Mon, 3 Jun 2013 00:12:31 +0000 (00:12 +0000)
committerjhurst <>
Mon, 3 Jun 2013 00:12:31 +0000 (00:12 +0000)
26 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/MXF.cpp
src/MXF.h
src/Makefile.am
src/as-02-wrap.cpp
src/asdcp-info.cpp
src/asdcp-test.cpp
src/asdcp-wrap.cpp
src/h__02_Reader.cpp
src/h__02_Writer.cpp
src/h__Reader.cpp
src/h__Writer.cpp
src/klvwalk.cpp

index caad97af051a975b6ba067b2a59fc13cca9ad77c..ff1bfc381083a8e5988cfb5ed0c25528a892359d 100644 (file)
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2011-2012, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst
+Copyright (c) 2011-2013, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -68,7 +68,7 @@ namespace AS_02
   using Kumu::Result_t;
 
   namespace MXF {
-
+#if 1
     //
     class OP1aIndexBodyPartion : public ASDCP::MXF::Partition
     {
@@ -118,6 +118,7 @@ namespace AS_02
       ASDCP::MXF::Rational m_EditRate;
       ui32_t              m_BodySID;
       ASDCP_NO_COPY_CONSTRUCT(OP1aIndexFooter);
+      OP1aIndexFooter();
 
     public:
       const ASDCP::Dictionary*&   m_Dict;
@@ -138,8 +139,39 @@ namespace AS_02
       virtual void     SetIndexParamsVBR(ASDCP::IPrimerLookup* lookup, const ASDCP::MXF::Rational& Rate, Kumu::fpos_t offset);
     };
 
-  } // namespace MXF
+#endif
+
+    //
+    class AS02IndexReader
+    {
+      ASDCP::MXF::IndexTableSegment*  m_CurrentSegment;
+      ASDCP::FrameBuffer  m_Buffer;
+      ui32_t              m_BytesPerEditUnit;
+      ASDCP::Rational     m_EditRate;
+      ui32_t              m_BodySID;
+
+      ASDCP_NO_COPY_CONSTRUCT(AS02IndexReader);
+      AS02IndexReader();
+         
+    public:
+      const ASDCP::Dictionary*&   m_Dict;
+      Kumu::fpos_t        m_ECOffset;
+      ASDCP::IPrimerLookup *m_Lookup;
+    
+      AS02IndexReader(const ASDCP::Dictionary*&);
+      virtual ~AS02IndexReader();
+    
+      virtual Result_t InitFromFile(const Kumu::FileReader& Reader);
+      virtual void     Dump(FILE* = 0);
+    
+      virtual Result_t GetMDObjectByID(const Kumu::UUID&, ASDCP::MXF::InterchangeObject** = 0);
+      virtual Result_t GetMDObjectByType(const byte_t*, ASDCP::MXF::InterchangeObject** = 0);
+      virtual Result_t GetMDObjectsByType(const byte_t* ObjectID, std::list<ASDCP::MXF::InterchangeObject*>& ObjectList);
+    
+      virtual Result_t Lookup(ui32_t frame_num, ASDCP::MXF::IndexTableSegment::IndexEntry&) const;
+    };
 
+  } // namespace MXF
 
   //---------------------------------------------------------------------------------
   // Accessors in the MXFReader and MXFWriter classes below return these types to
@@ -168,7 +200,8 @@ namespace AS_02
 
       // Warning: direct manipulation of MXF structures can interfere
       // with the normal operation of the wrapper.  Caveat emptor!
-      virtual ASDCP::MXF::OPAtomHeader& OPAtomHeader();
+      virtual ASDCP::MXF::OP1aHeader& OP1aHeader();
+      virtual ASDCP::MXF::RIP& RIP();
 
       // Open the file for writing. The file must not exist. Returns error if
       // the operation cannot be completed or if nonsensical data is discovered
@@ -202,7 +235,9 @@ namespace AS_02
 
       // Warning: direct manipulation of MXF structures can interfere
       // with the normal operation of the wrapper.  Caveat emptor!
-      virtual ASDCP::MXF::OPAtomHeader& OPAtomHeader();
+      virtual ASDCP::MXF::OP1aHeader& OP1aHeader();
+      virtual AS_02::MXF::AS02IndexReader& AS02IndexReader();
+      virtual ASDCP::MXF::RIP& RIP();
 
       // Open the file for reading. The file must exist. Returns error if the
       // operation cannot be completed.
@@ -255,7 +290,8 @@ namespace AS_02
 
       // Warning: direct manipulation of MXF structures can interfere
       // with the normal operation of the wrapper.  Caveat emptor!
-      virtual ASDCP::MXF::OPAtomHeader& OPAtomHeader();
+      virtual ASDCP::MXF::OP1aHeader& OP1aHeader();
+      virtual ASDCP::MXF::RIP& RIP();
 
       // Open the file for writing. The file must not exist. Returns error if
       // the operation cannot be completed or if nonsensical data is discovered
@@ -286,7 +322,9 @@ namespace AS_02
 
       // Warning: direct manipulation of MXF structures can interfere
       // with the normal operation of the wrapper.  Caveat emptor!
-      virtual ASDCP::MXF::OPAtomHeader& OPAtomHeader();
+      virtual ASDCP::MXF::OP1aHeader& OP1aHeader();
+      virtual AS_02::MXF::AS02IndexReader& AS02IndexReader();
+      virtual ASDCP::MXF::RIP& RIP();
 
       // Open the file for reading. The file must exist. Returns error if the
       // operation cannot be completed.
index 4b1db707714e949905ea5d112c937c81726338bf..136fd278c7e08d746c13e6d6ab84e3475d2b999f 100644 (file)
@@ -1,5 +1,5 @@
 /*
-  Copyright (c) 2011-2012, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst
+  Copyright (c) 2011-2013, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst
   All rights reserved.
 
   Redistribution and use in source and binary forms, with or without
 #include <iostream>
 #include <iomanip>
 
+using namespace ASDCP;
 using namespace ASDCP::JP2K;
 using Kumu::GenRandomValue;
 
 //------------------------------------------------------------------------------------------
 
-static std::string JP2K_PACKAGE_LABEL = "File Package: SMPTE 429-4 frame wrapping of JPEG 2000 codestreams";
+static std::string JP2K_PACKAGE_LABEL = "File Package: SMPTE ST 422 frame wrapping of JPEG 2000 codestreams";
 static std::string PICT_DEF_LABEL = "Image Track";
 
 //------------------------------------------------------------------------------------------
@@ -47,7 +48,7 @@ static std::string PICT_DEF_LABEL = "Image Track";
 // hidden, internal implementation of JPEG 2000 reader
 
 
-class lf__Reader : public AS_02::h__Reader
+class AS_02::JP2K::MXFReader::h__Reader : public AS_02::h__AS02Reader
 {
   RGBAEssenceDescriptor*        m_EssenceDescriptor;
   JPEG2000PictureSubDescriptor* m_EssenceSubDescriptor;
@@ -55,16 +56,19 @@ class lf__Reader : public AS_02::h__Reader
   ASDCP::Rational               m_SampleRate;
   EssenceType_t                 m_Format;
 
-  ASDCP_NO_COPY_CONSTRUCT(lf__Reader);
+  ASDCP_NO_COPY_CONSTRUCT(h__Reader);
 
 public:
   PictureDescriptor m_PDesc;        // codestream parameter list
 
-  lf__Reader(const Dictionary& d) :
-    AS_02::h__Reader(d), m_EssenceDescriptor(0), m_EssenceSubDescriptor(0), m_Format(ESS_UNKNOWN) {}
+  h__Reader(const Dictionary& d) :
+    AS_02::h__AS02Reader(d), m_EssenceDescriptor(0), m_EssenceSubDescriptor(0), m_Format(ESS_UNKNOWN) {}
+
+  virtual ~h__Reader() {}
+
   Result_t    OpenRead(const char*, EssenceType_t);
-  Result_t    ReadFrame(ui32_t, JP2K::FrameBuffer&, AESDecContext*, HMACContext*);
-  Result_t    MD_to_JP2K_PDesc(JP2K::PictureDescriptor& PDesc);
+  Result_t    ReadFrame(ui32_t, ASDCP::JP2K::FrameBuffer&, AESDecContext*, HMACContext*);
+  Result_t    MD_to_JP2K_PDesc(ASDCP::JP2K::PictureDescriptor& PDesc);
 
   Result_t OpenMXFRead(const char* filename);
   // positions file before reading
@@ -79,10 +83,10 @@ public:
 
 //
 ASDCP::Result_t
-lf__Reader::MD_to_JP2K_PDesc(ASDCP::JP2K::PictureDescriptor& PDesc)
+AS_02::JP2K::MXFReader::h__Reader::MD_to_JP2K_PDesc(ASDCP::JP2K::PictureDescriptor& PDesc)
 {
   memset(&PDesc, 0, sizeof(PDesc));
-  MXF::RGBAEssenceDescriptor* PDescObj = (MXF::RGBAEssenceDescriptor*)m_EssenceDescriptor;
+  ASDCP::MXF::RGBAEssenceDescriptor* PDescObj = (ASDCP::MXF::RGBAEssenceDescriptor*)m_EssenceDescriptor;
 
   PDesc.EditRate           = m_EditRate;
   PDesc.SampleRate         = m_SampleRate;
@@ -135,7 +139,7 @@ lf__Reader::MD_to_JP2K_PDesc(ASDCP::JP2K::PictureDescriptor& PDesc)
 //
 //
 ASDCP::Result_t
-lf__Reader::OpenRead(const char* filename, ASDCP::EssenceType_t type)
+AS_02::JP2K::MXFReader::h__Reader::OpenRead(const char* filename, ASDCP::EssenceType_t type)
 {
   Result_t result = OpenMXFRead(filename);
 
@@ -176,39 +180,6 @@ lf__Reader::OpenRead(const char* filename, ASDCP::EssenceType_t type)
              return RESULT_FORMAT;
            }
        }
-      else if ( type == ASDCP::ESS_JPEG_2000_S )
-       {
-         if ( m_EditRate == EditRate_24 )
-           {
-             if ( m_SampleRate != EditRate_48 )
-               {
-                 DefaultLogSink().Error("EditRate and SampleRate not correct for 24/48 stereoscopic essence.\n");
-                 return RESULT_FORMAT;
-               }
-           }
-         else if ( m_EditRate == EditRate_25 )
-           {
-             if ( m_SampleRate != EditRate_50 )
-               {
-                 DefaultLogSink().Error("EditRate and SampleRate not correct for 25/50 stereoscopic essence.\n");
-                 return RESULT_FORMAT;
-               }
-           }
-         else if ( m_EditRate == EditRate_30 )
-           {
-             if ( m_SampleRate != EditRate_60 )
-               {
-                 DefaultLogSink().Error("EditRate and SampleRate not correct for 30/60 stereoscopic essence.\n");
-                 return RESULT_FORMAT;
-               }
-           }
-         else
-           {
-             DefaultLogSink().Error("EditRate not correct for stereoscopic essence: %d/%d.\n",
-                                    m_EditRate.Numerator, m_EditRate.Denominator);
-             return RESULT_FORMAT;
-           }
-       }
       else
        {
          DefaultLogSink().Error("'type' argument unexpected: %x\n", type);
@@ -218,20 +189,14 @@ lf__Reader::OpenRead(const char* filename, ASDCP::EssenceType_t type)
       result = MD_to_JP2K_PDesc(m_PDesc);
     }
 
-  if( ASDCP_SUCCESS(result) )
-    result = InitMXFIndex();
-
-  if( ASDCP_SUCCESS(result) )
-    result = InitInfo();
-
   return result;
 }
 
 //
 //
 ASDCP::Result_t
-lf__Reader::ReadFrame(ui32_t FrameNum, JP2K::FrameBuffer& FrameBuf,
-                     AESDecContext* Ctx, HMACContext* HMAC)
+AS_02::JP2K::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, ASDCP::JP2K::FrameBuffer& FrameBuf,
+                     ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC)
 {
   if ( ! m_File.IsOpen() )
     return RESULT_INIT;
@@ -240,16 +205,8 @@ lf__Reader::ReadFrame(ui32_t FrameNum, JP2K::FrameBuffer& FrameBuf,
   return ReadEKLVFrame(FrameNum, FrameBuf, m_Dict->ul(MDD_JPEG2000Essence), Ctx, HMAC);
 }
 
-
+//------------------------------------------------------------------------------------------
 //
-class AS_02::JP2K::MXFReader::h__Reader : public lf__Reader
-{
-  ASDCP_NO_COPY_CONSTRUCT(h__Reader);
-  h__Reader();
-
-public:
-  h__Reader(const Dictionary& d) : lf__Reader(d) {}
-};
 
 AS_02::JP2K::MXFReader::MXFReader()
 {
@@ -264,13 +221,13 @@ AS_02::JP2K::MXFReader::~MXFReader()
 // Warning: direct manipulation of MXF structures can interfere
 // with the normal operation of the wrapper.  Caveat emptor!
 //
-ASDCP::MXF::OPAtomHeader&
-AS_02::JP2K::MXFReader::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+AS_02::JP2K::MXFReader::OP1aHeader()
 {
   if ( m_Reader.empty() )
     {
-      assert(g_OPAtomHeader);
-      return *g_OPAtomHeader;
+      assert(g_OP1aHeader);
+      return *g_OP1aHeader;
     }
 
   return m_Reader->m_HeaderPart;
@@ -279,29 +236,44 @@ AS_02::JP2K::MXFReader::OPAtomHeader()
 // Warning: direct manipulation of MXF structures can interfere
 // with the normal operation of the wrapper.  Caveat emptor!
 //
-/*
-ASDCP::MXF::OPAtomIndexFooter&
-AS_02::JP2K::MXFReader::OPAtomIndexFooter()
+AS_02::MXF::AS02IndexReader&
+AS_02::JP2K::MXFReader::AS02IndexReader()
 {
   if ( m_Reader.empty() )
     {
-      assert(g_OPAtomIndexFooter);
-      return *g_OPAtomIndexFooter;
+      assert(g_AS02IndexReader);
+      return *g_AS02IndexReader;
     }
 
-  return m_Reader->m_FooterPart;
+  return m_Reader->m_IndexAccess;
+}
+
+// Warning: direct manipulation of MXF structures can interfere
+// with the normal operation of the wrapper.  Caveat emptor!
+//
+ASDCP::MXF::RIP&
+AS_02::JP2K::MXFReader::RIP()
+{
+  if ( m_Reader.empty() )
+    {
+      assert(g_RIP);
+      return *g_RIP;
+    }
+
+  return m_Reader->m_RIP;
 }
-*/
 
 // Open the file for reading. The file must exist. Returns error if the
 // operation cannot be completed.
-Result_t AS_02::JP2K::MXFReader::OpenRead(const char* filename) const
+Result_t
+AS_02::JP2K::MXFReader::OpenRead(const char* filename) const
 {
   return m_Reader->OpenRead(filename, ASDCP::ESS_JPEG_2000);
 }
 
 //
-Result_t AS_02::JP2K::MXFReader::ReadFrame(ui32_t FrameNum, ASDCP::JP2K::FrameBuffer& FrameBuf,
+Result_t
+AS_02::JP2K::MXFReader::ReadFrame(ui32_t FrameNum, ASDCP::JP2K::FrameBuffer& FrameBuf,
                                           ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC) const
 {
   if ( m_Reader && m_Reader->m_File.IsOpen() )
@@ -338,110 +310,14 @@ ASDCP::Result_t AS_02::JP2K::MXFReader::FillWriterInfo(WriterInfo& Info) const
   return RESULT_INIT;
 }
 
-//
-void
-AS_02::JP2K::MXFReader::DumpHeaderMetadata(FILE* stream) const
-{
-  if ( m_Reader->m_File.IsOpen() )
-    m_Reader->m_HeaderPart.Dump(stream);
-}
-
-
-//
-void
-AS_02::JP2K::MXFReader::DumpIndex(FILE* stream) const
-{
-  if ( m_Reader->m_File.IsOpen() )
-    m_Reader->m_FooterPart.Dump(stream);
-}
-
-// standard method of opening an MXF file for read
-Result_t
-lf__Reader::OpenMXFRead(const char* filename)
-{
-  m_LastPosition = 0;
-  AS_02::MXF::OP1aIndexBodyPartion* pCurrentBodyPartIndex = NULL;
-  Partition* pPart = NULL;
-  ui64_t EssenceStart = 0;
-  Result_t result = m_File.OpenRead(filename);
 
-  if ( ASDCP_SUCCESS(result) )
-    result = m_HeaderPart.InitFromFile(m_File);
-
-  if ( ASDCP_SUCCESS(result) )
-    {
-      ui32_t partition_size = m_HeaderPart.m_RIP.PairArray.size();
-      
-      if ( partition_size > 3 )
-       {
-         //for all entry except the first and the last(header&footer)
-         Array<RIP::Pair>::iterator r_i = m_HeaderPart.m_RIP.PairArray.begin();
-         r_i++;
-         ui32_t i=2;
-
-         while(r_i != m_HeaderPart.m_RIP.PairArray.end() && i<partition_size)
-           {
-             m_File.Seek((*r_i).ByteOffset);
-             pPart = new Partition(this->m_Dict);
-             result = pPart->InitFromFile(m_File);
-
-             if(pPart->BodySID != 0 && pPart->IndexSID == 0)
-               { // AS_02::IS_FOLLOW
-                 r_i++; i++;
-                 EssenceStart = m_File.Tell();
-
-                 m_File.Seek((*r_i).ByteOffset);
-                 pCurrentBodyPartIndex = new AS_02::MXF::OP1aIndexBodyPartion(this->m_Dict);
-                 pCurrentBodyPartIndex->m_Lookup = &m_HeaderPart.m_Primer;
-                 result = pCurrentBodyPartIndex->InitFromFile(m_File);
-               }
-             else
-               { // AS_02::IS_LEAD
-                 delete pPart;
-                 m_File.Seek((*r_i).ByteOffset);
-                 pCurrentBodyPartIndex = new AS_02::MXF::OP1aIndexBodyPartion(this->m_Dict);
-                 pCurrentBodyPartIndex->m_Lookup = &m_HeaderPart.m_Primer;
-                 result = pCurrentBodyPartIndex->InitFromFile(m_File);
-                 
-                 if ( ASDCP_FAILURE(result) )
-                   {
-                     break;
-                   }
-       
-                 r_i++; i++;
-                 m_File.Seek((*r_i).ByteOffset);
-                 pPart = new Partition(this->m_Dict);
-                 result = pPart->InitFromFile(m_File);
-                 EssenceStart = m_File.Tell();
-               }
-
-             if ( ASDCP_FAILURE(result) )
-               {
-                 break;
-               }
-
-             if(i==3)
-               {
-                 this->m_EssenceStart = EssenceStart;
-                 this->m_pCurrentBodyPartition = pPart;
-                 this->m_pCurrentIndexPartition = pCurrentBodyPartIndex;
-               }
-
-             this->m_BodyPartList.push_back(pCurrentBodyPartIndex);
-             this->m_BodyPartList.push_back(pPart);
-             r_i++; i++;
-           }
-       }
-    }
-
-  return result;
-}
+//------------------------------------------------------------------------------------------
 
 //
-class lf__Writer : public AS_02::h__Writer
+class AS_02::JP2K::MXFWriter::h__Writer : public AS_02::h__AS02Writer
 {
-  ASDCP_NO_COPY_CONSTRUCT(lf__Writer);
-  lf__Writer();
+  ASDCP_NO_COPY_CONSTRUCT(h__Writer);
+  h__Writer();
 
   JPEG2000PictureSubDescriptor* m_EssenceSubDescriptor;
 
@@ -453,19 +329,19 @@ public:
   AS_02::IndexStrategy_t m_IndexStrategy; //Shim parameter index_strategy_frame/clip
   ui32_t m_PartitionSpace; //Shim parameter partition_spacing
 
-  lf__Writer(const Dictionary& d) : h__Writer(d), m_EssenceSubDescriptor(0), m_IndexStrategy(AS_02::IS_FOLLOW), m_PartitionSpace(60) {
+  h__Writer(const Dictionary& d) : h__AS02Writer(d), m_EssenceSubDescriptor(0), m_IndexStrategy(AS_02::IS_FOLLOW), m_PartitionSpace(60) {
     memset(m_EssenceUL, 0, SMPTE_UL_LENGTH);
   }
 
-  ~lf__Writer(){}
+  virtual ~h__Writer(){}
 
   Result_t OpenWrite(const char*, EssenceType_t type, const AS_02::IndexStrategy_t& IndexStrategy,
                     const ui32_t& PartitionSpace, const 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*);
+  Result_t WriteFrame(const ASDCP::JP2K::FrameBuffer&, bool add_index, ASDCP::AESEncContext*, ASDCP::HMACContext*);
   Result_t Finalize();
-  Result_t JP2K_PDesc_to_MD(JP2K::PictureDescriptor& PDesc);
+  Result_t JP2K_PDesc_to_MD(ASDCP::JP2K::PictureDescriptor& PDesc);
 
   //void AddSourceClip(const MXF::Rational& EditRate, ui32_t TCFrameRate,
   // const std::string& TrackName, const UL& EssenceUL,
@@ -495,11 +371,11 @@ static const byte_t s_PixelLayoutXYZ[PixelLayoutSize] = { 0xd8, 0x0c, 0xd9, 0x0c
 
 //
 ASDCP::Result_t
-lf__Writer::JP2K_PDesc_to_MD(JP2K::PictureDescriptor& PDesc)
+AS_02::JP2K::MXFWriter::h__Writer::JP2K_PDesc_to_MD(ASDCP::JP2K::PictureDescriptor& PDesc)
 {
   assert(m_EssenceDescriptor);
   assert(m_EssenceSubDescriptor);
-  MXF::RGBAEssenceDescriptor* PDescObj = (MXF::RGBAEssenceDescriptor*)m_EssenceDescriptor;
+  ASDCP::MXF::RGBAEssenceDescriptor* PDescObj = (ASDCP::MXF::RGBAEssenceDescriptor*)m_EssenceDescriptor;
 
   PDescObj->ContainerDuration = PDesc.ContainerDuration;
   PDescObj->SampleRate = PDesc.EditRate;
@@ -578,7 +454,7 @@ lf__Writer::JP2K_PDesc_to_MD(JP2K::PictureDescriptor& PDesc)
 // Open the file for writing. The file must not exist. Returns error if
 // the operation cannot be completed.
 ASDCP::Result_t
-lf__Writer::OpenWrite(const char* filename, EssenceType_t type, const AS_02::IndexStrategy_t& IndexStrategy,
+AS_02::JP2K::MXFWriter::h__Writer::OpenWrite(const char* filename, EssenceType_t type, const AS_02::IndexStrategy_t& IndexStrategy,
                      const ui32_t& PartitionSpace, const ui32_t& HeaderSize)
 {
   if ( ! m_State.Test_BEGIN() )
@@ -609,7 +485,7 @@ lf__Writer::OpenWrite(const char* filename, EssenceType_t type, const AS_02::Ind
 
 // Automatically sets the MXF file's metadata from the first jpeg codestream stream.
 ASDCP::Result_t
-lf__Writer::SetSourceStream(const PictureDescriptor& PDesc, const std::string& label, ASDCP::Rational LocalEditRate)
+AS_02::JP2K::MXFWriter::h__Writer::SetSourceStream(const PictureDescriptor& PDesc, const std::string& label, ASDCP::Rational LocalEditRate)
 {
   assert(m_Dict);
   if ( ! m_State.Test_INIT() )
@@ -632,9 +508,9 @@ lf__Writer::SetSourceStream(const PictureDescriptor& PDesc, const std::string& l
     {
       ui32_t TCFrameRate = ( m_PDesc.EditRate == EditRate_23_98  ) ? 24 : m_PDesc.EditRate.Numerator;
 
-      result = WriteMXFHeader(label, UL(m_Dict->ul(MDD_JPEG_2000Wrapping)),
-                             PICT_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_PictureDataDef)),
-                             LocalEditRate, TCFrameRate);
+      result = WriteAS02Header(label, UL(m_Dict->ul(MDD_JPEG_2000Wrapping)),
+                              PICT_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_PictureDataDef)),
+                              LocalEditRate, TCFrameRate);
     }
 
   return result;
@@ -646,7 +522,7 @@ lf__Writer::SetSourceStream(const PictureDescriptor& PDesc, const std::string& l
 // error occurs.
 //
 ASDCP::Result_t
-lf__Writer::WriteFrame(const ASDCP::JP2K::FrameBuffer& FrameBuf, bool add_index,
+AS_02::JP2K::MXFWriter::h__Writer::WriteFrame(const ASDCP::JP2K::FrameBuffer& FrameBuf, bool add_index,
                       AESEncContext* Ctx, HMACContext* HMAC)
 {
   Result_t result = RESULT_OK;
@@ -691,7 +567,7 @@ lf__Writer::WriteFrame(const ASDCP::JP2K::FrameBuffer& FrameBuf, bool add_index,
 // Closes the MXF file, writing the index and other closing information.
 //
 ASDCP::Result_t
-lf__Writer::Finalize()
+AS_02::JP2K::MXFWriter::h__Writer::Finalize()
 {
   Result_t result = RESULT_OK;
 
@@ -709,18 +585,6 @@ lf__Writer::Finalize()
   return WriteMXFFooter();
 }
 
-
-//
-class AS_02::JP2K::MXFWriter::h__Writer : public lf__Writer
-{
-  ASDCP_NO_COPY_CONSTRUCT(h__Writer);
-  h__Writer();
-
-public:
-  h__Writer(const Dictionary& d) : lf__Writer(d) {}
-};
-
-
 //------------------------------------------------------------------------------------------
 
 
@@ -736,13 +600,13 @@ AS_02::JP2K::MXFWriter::~MXFWriter()
 // Warning: direct manipulation of MXF structures can interfere
 // with the normal operation of the wrapper.  Caveat emptor!
 //
-ASDCP::MXF::OPAtomHeader&
-AS_02::JP2K::MXFWriter::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+AS_02::JP2K::MXFWriter::OP1aHeader()
 {
   if ( m_Writer.empty() )
     {
-      assert(g_OPAtomHeader);
-      return *g_OPAtomHeader;
+      assert(g_OP1aHeader);
+      return *g_OP1aHeader;
     }
 
   return m_Writer->m_HeaderPart;
@@ -751,19 +615,17 @@ AS_02::JP2K::MXFWriter::OPAtomHeader()
 // Warning: direct manipulation of MXF structures can interfere
 // with the normal operation of the wrapper.  Caveat emptor!
 //
-/*
-ASDCP::MXF::OPAtomIndexFooter&
-AS_02::JP2K::MXFWriter::OPAtomIndexFooter()
+ASDCP::MXF::RIP&
+AS_02::JP2K::MXFWriter::RIP()
 {
   if ( m_Writer.empty() )
     {
-      assert(g_OPAtomIndexFooter);
-      return *g_OPAtomIndexFooter;
+      assert(g_RIP);
+      return *g_RIP;
     }
 
-  return m_Writer->m_FooterPart;
+  return m_Writer->m_RIP;
 }
-*/
 
 // Open the file for writing. The file must not exist. Returns error if
 // the operation cannot be completed.
@@ -813,327 +675,6 @@ AS_02::JP2K::MXFWriter::Finalize()
 }
 
 
-//------------------------------------------------------------------------------------------
-
-// standard method of reading a plaintext or encrypted frame
-Result_t
-lf__Reader::ReadEKLVFrame(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
-                         const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC)
-{
-  Result_t result = RESULT_OK;
-  IndexTableSegment::IndexEntry TmpEntry;
-
-  assert(m_pCurrentIndexPartition != NULL);
-
-  if( m_pCurrentIndexPartition->Lookup(FrameNum, TmpEntry, m_start_pos) == false)
-    {
-      m_start_pos = 0;
-
-      //compute new indexPartition for this FrameNum
-      for (ui32_t i = 0; i < m_BodyPartList.size(); i+=2 )
-       {
-         if( m_IndexStrategy == AS_02::IS_FOLLOW )
-           {
-             m_pCurrentBodyPartition = m_BodyPartList.at(i);
-             m_pCurrentIndexPartition = dynamic_cast<AS_02::MXF::OP1aIndexBodyPartion*> (m_BodyPartList.at(i+1));
-           }
-         else if( m_IndexStrategy == AS_02::IS_LEAD )
-           {
-             m_pCurrentIndexPartition = dynamic_cast<AS_02::MXF::OP1aIndexBodyPartion*> (m_BodyPartList.at(i));
-             m_pCurrentBodyPartition = m_BodyPartList.at(i+1);
-           }
-         else
-           {
-             return RESULT_FORMAT; //return error
-           }
-         
-         if( m_pCurrentIndexPartition == 0 )
-           return RESULT_FORMAT;
-         
-         if(m_pCurrentIndexPartition->Lookup(FrameNum, TmpEntry, m_start_pos))
-           {
-             if ( FrameNum % m_PartitionSpace == 0 )
-               {
-                 ui64_t offset = m_pCurrentBodyPartition->ThisPartition - m_pCurrentBodyPartition->PreviousPartition;
-                 offset += m_pCurrentBodyPartition->ArchiveSize();//Offset for the BodyPartitionHeader - Partition::ArchiveSize();
-                 m_EssenceStart += offset;
-               }
-             break;
-           }
-       }
-    }
-  
-  // get frame position and go read the frame's key and length
-  Kumu::fpos_t FilePosition = this->m_EssenceStart + TmpEntry.StreamOffset;
-
-  if ( FilePosition != m_LastPosition )
-    {
-      m_LastPosition = FilePosition;
-      result = m_File.Seek(FilePosition);
-    }
-
-  if( ASDCP_SUCCESS(result) )
-    result = ReadEKLVPacket(FrameNum, FrameNum + 1, FrameBuf, EssenceUL, Ctx, HMAC);
-
-  return result;
-}
-
-//
-Result_t
-lf__Reader::ReadEKLVPacket(ui32_t FrameNum, ui32_t SequenceNum, ASDCP::FrameBuffer& FrameBuf,
-                          const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC)
-{
-  KLReader Reader;
-  Result_t result = Reader.ReadKLFromFile(m_File);
-
-  if ( ASDCP_FAILURE(result) )
-    return result;
-
-  UL Key(Reader.Key());
-  ui64_t PacketLength = Reader.Length();
-  m_LastPosition = m_LastPosition + Reader.KLLength() + PacketLength;
-  assert(m_Dict);
-
-  if ( memcmp(Key.Value(), m_Dict->ul(MDD_CryptEssence), Key.Size() - 1) == 0 )  // ignore the stream numbers
-    {
-      if ( ! m_Info.EncryptedEssence )
-       {
-         DefaultLogSink().Error("EKLV packet found, no Cryptographic Context in header.\n");
-         return RESULT_FORMAT;
-       }
-
-      // read encrypted triplet value into internal buffer
-      assert(PacketLength <= 0xFFFFFFFFL);
-      m_CtFrameBuf.Capacity((ui32_t) PacketLength);
-      ui32_t read_count;
-      result = m_File.Read(m_CtFrameBuf.Data(), (ui32_t) PacketLength,
-                          &read_count);
-
-      if ( ASDCP_FAILURE(result) )
-       return result;
-
-      if ( read_count != PacketLength )
-       {
-         DefaultLogSink().Error("read length is smaller than EKLV packet length.\n");
-         return RESULT_FORMAT;
-       }
-
-      m_CtFrameBuf.Size((ui32_t) PacketLength);
-
-      // should be const but mxflib::ReadBER is not
-      byte_t* ess_p = m_CtFrameBuf.Data();
-
-      // read context ID length
-      if ( ! Kumu::read_test_BER(&ess_p, UUIDlen) )
-       return RESULT_FORMAT;
-
-      // test the context ID
-      if ( memcmp(ess_p, m_Info.ContextID, UUIDlen) != 0 )
-       {
-         DefaultLogSink().Error("Packet's Cryptographic Context ID does not match the header.\n");
-         return RESULT_FORMAT;
-       }
-      ess_p += UUIDlen;
-
-      // read PlaintextOffset length
-      if ( ! Kumu::read_test_BER(&ess_p, sizeof(ui64_t)) )
-       return RESULT_FORMAT;
-
-      ui32_t PlaintextOffset = (ui32_t)KM_i64_BE(Kumu::cp2i<ui64_t>(ess_p));
-      ess_p += sizeof(ui64_t);
-
-      // read essence UL length
-      if ( ! Kumu::read_test_BER(&ess_p, SMPTE_UL_LENGTH) )
-       return RESULT_FORMAT;
-
-      // test essence UL
-      if ( memcmp(ess_p, EssenceUL, SMPTE_UL_LENGTH - 1) != 0 ) // ignore the stream number
-       {
-         char strbuf[IntBufferLen];
-         const MDDEntry* Entry = m_Dict->FindUL(Key.Value());
-         if ( Entry == 0 )
-           DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Key.EncodeString(strbuf, IntBufferLen));
-         else
-           DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Entry->name);
-         return RESULT_FORMAT;
-       }
-      ess_p += SMPTE_UL_LENGTH;
-
-      // read SourceLength length
-      if ( ! Kumu::read_test_BER(&ess_p, sizeof(ui64_t)) )
-       return RESULT_FORMAT;
-
-      ui32_t SourceLength = (ui32_t)KM_i64_BE(Kumu::cp2i<ui64_t>(ess_p));
-      ess_p += sizeof(ui64_t);
-      assert(SourceLength);
-
-      if ( FrameBuf.Capacity() < SourceLength )
-       {
-         DefaultLogSink().Error("FrameBuf.Capacity: %u SourceLength: %u\n", FrameBuf.Capacity(), SourceLength);
-         return RESULT_SMALLBUF;
-       }
-
-      ui32_t esv_length = calc_esv_length(SourceLength, PlaintextOffset);
-
-      // read ESV length
-      if ( ! Kumu::read_test_BER(&ess_p, esv_length) )
-       {
-         DefaultLogSink().Error("read_test_BER did not return %u\n", esv_length);
-         return RESULT_FORMAT;
-       }
-
-      ui32_t tmp_len = esv_length + (m_Info.UsesHMAC ? klv_intpack_size : 0);
-
-      if ( PacketLength < tmp_len )
-       {
-         DefaultLogSink().Error("Frame length is larger than EKLV packet length.\n");
-         return RESULT_FORMAT;
-       }
-
-      if ( Ctx )
-       {
-         // wrap the pointer and length as a FrameBuffer for use by
-         // DecryptFrameBuffer() and TestValues()
-         ASDCP::FrameBuffer TmpWrapper;
-         TmpWrapper.SetData(ess_p, tmp_len);
-         TmpWrapper.Size(tmp_len);
-         TmpWrapper.SourceLength(SourceLength);
-         TmpWrapper.PlaintextOffset(PlaintextOffset);
-
-         result = DecryptFrameBuffer(TmpWrapper, FrameBuf, Ctx);
-         FrameBuf.FrameNumber(FrameNum);
-
-         // detect and test integrity pack
-         if ( ASDCP_SUCCESS(result) && m_Info.UsesHMAC && HMAC )
-           {
-             IntegrityPack IntPack;
-             result = IntPack.TestValues(TmpWrapper, m_Info.AssetUUID, SequenceNum, HMAC);
-           }
-       }
-      else // return ciphertext to caller
-       {
-         if ( FrameBuf.Capacity() < tmp_len )
-           {
-             char intbuf[IntBufferLen];
-             DefaultLogSink().Error("FrameBuf.Capacity: %u FrameLength: %s\n",
-                                    FrameBuf.Capacity(), ui64sz(PacketLength, intbuf));
-             return RESULT_SMALLBUF;
-           }
-
-         memcpy(FrameBuf.Data(), ess_p, tmp_len);
-         FrameBuf.Size(tmp_len);
-         FrameBuf.FrameNumber(FrameNum);
-         FrameBuf.SourceLength(SourceLength);
-         FrameBuf.PlaintextOffset(PlaintextOffset);
-       }
-    }
-  else if ( memcmp(Key.Value(), EssenceUL, Key.Size() - 1) == 0 ) // ignore the stream number
-    { // read plaintext frame
-      if ( FrameBuf.Capacity() < PacketLength )
-       {
-         char intbuf[IntBufferLen];
-         DefaultLogSink().Error("FrameBuf.Capacity: %u FrameLength: %s\n",
-                                FrameBuf.Capacity(), ui64sz(PacketLength, intbuf));
-         return RESULT_SMALLBUF;
-       }
-
-      // read the data into the supplied buffer
-      ui32_t read_count;
-      assert(PacketLength <= 0xFFFFFFFFL);
-      result = m_File.Read(FrameBuf.Data(), (ui32_t) PacketLength, &read_count);
-
-      if ( ASDCP_FAILURE(result) )
-       return result;
-
-      if ( read_count != PacketLength )
-       {
-         char intbuf1[IntBufferLen];
-         char intbuf2[IntBufferLen];
-         DefaultLogSink().Error("read_count: %s != FrameLength: %s\n",
-                                ui64sz(read_count, intbuf1),
-                                ui64sz(PacketLength, intbuf2) );
-
-         return RESULT_READFAIL;
-       }
-
-      FrameBuf.FrameNumber(FrameNum);
-      FrameBuf.Size(read_count);
-    }
-  else
-    {
-      char strbuf[IntBufferLen];
-      const MDDEntry* Entry = m_Dict->FindUL(Key.Value());
-      if ( Entry == 0 )
-       DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Key.EncodeString(strbuf, IntBufferLen));
-      else
-       DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Entry->name);
-      return RESULT_FORMAT;
-    }
-
-  return result;
-}
-
-
-// standard method of writing the header and footer of a completed MXF file
-//
-Result_t
-lf__Writer::WriteMXFFooter()
-{
-  // Set top-level file package correctly for OP-Atom
-
-  //  m_MPTCSequence->Duration = m_MPTimecode->Duration = m_MPClSequence->Duration = m_MPClip->Duration = 
-  //    m_FPTCSequence->Duration = m_FPTimecode->Duration = m_FPClSequence->Duration = m_FPClip->Duration = 
-
-  DurationElementList_t::iterator dli = m_DurationUpdateList.begin();
-
-  for (; dli != m_DurationUpdateList.end(); dli++ )
-    **dli = m_FramesWritten;
-
-  m_EssenceDescriptor->ContainerDuration = m_FramesWritten;
-  m_FooterPart.PreviousPartition = m_HeaderPart.m_RIP.PairArray.back().ByteOffset;
-
-  Kumu::fpos_t here = m_File.Tell();
-  m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(0, here)); // Last RIP Entry
-  m_HeaderPart.FooterPartition = here;
-
-  assert(m_Dict);
-  // re-label the partition
-  UL OPAtomUL(m_Dict->ul(MDD_OP1a));
-  m_HeaderPart.OperationalPattern = OPAtomUL;
-  m_HeaderPart.m_Preface->OperationalPattern = m_HeaderPart.OperationalPattern;
-
-  m_FooterPart.OperationalPattern = m_HeaderPart.OperationalPattern;
-  m_FooterPart.EssenceContainers = m_HeaderPart.EssenceContainers;
-  m_FooterPart.FooterPartition = here;
-  m_FooterPart.ThisPartition = here;
-
-  Result_t result = m_FooterPart.WriteToFile(m_File, m_FramesWritten);
-
-  if ( ASDCP_SUCCESS(result) )
-    result = m_HeaderPart.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);
-
-  //update the value of FooterPartition in all Partitions
-  std::vector<Partition*>::iterator iter = this->m_BodyPartList.begin();
-  for (; iter != this->m_BodyPartList.end(); iter++ ){
-    (*iter)->FooterPartition =  m_FooterPart.ThisPartition;
-    if ( ASDCP_SUCCESS(result) )
-      result = m_File.Seek((*iter)->ThisPartition);
-    if ( ASDCP_SUCCESS(result) ){
-      UL BodyUL(m_Dict->ul(MDD_ClosedCompleteBodyPartition));
-      result = (*iter)->WriteToFile(m_File, BodyUL);
-    }
-  } 
-
-  m_File.Close();
-  return result;
-}
-
 //
 // end AS_02_JP2K.cpp
 //
index cf8995e45d9c135494a6369e961237b1268fefbe..b82e1f062fd72c8f8e8100da270b5f8639fd0417 100644 (file)
@@ -1,5 +1,5 @@
 /*
-  Copyright (c) 2011-2012, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst
+  Copyright (c) 2011-2013, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst
   All rights reserved.
 
   Redistribution and use in source and binary forms, with or without
 static std::string PCM_PACKAGE_LABEL = "File Package: SMPTE 382M clip wrapping of wave audio";
 static std::string SOUND_DEF_LABEL = "Sound Track";
 
-static byte_t SNDFMT_CFG_1_UL[16] = { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0b,
-                                     0x04, 0x02, 0x02, 0x10, 0x03, 0x01, 0x01, 0x00 };
-
-static byte_t SNDFMT_CFG_2_UL[16] = { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0b,
-                                     0x04, 0x02, 0x02, 0x10, 0x03, 0x01, 0x02, 0x00 };
-
-static byte_t SNDFMT_CFG_3_UL[16] = { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0b,
-                                     0x04, 0x02, 0x02, 0x10, 0x03, 0x01, 0x03, 0x00 };
-
 //this must be changed because the CBR_frame_size is only   
 //
 static ui32_t
@@ -78,7 +69,7 @@ calc_CBR_frame_size(ASDCP::WriterInfo& Info, const ASDCP::PCM::AudioDescriptor&
 //------------------------------------------------------------------------------------------
 
 
-class AS_02::PCM::MXFReader::h__Reader : public AS_02::h__Reader
+class AS_02::PCM::MXFReader::h__Reader : public AS_02::h__AS02Reader
 {
   ASDCP_NO_COPY_CONSTRUCT(h__Reader);
   h__Reader();
@@ -86,8 +77,9 @@ class AS_02::PCM::MXFReader::h__Reader : public AS_02::h__Reader
 public:
   ASDCP::PCM::AudioDescriptor m_ADesc;
 
-  h__Reader(const Dictionary& d) : AS_02::h__Reader(d) {}
-  ~h__Reader() {}
+  h__Reader(const Dictionary& d) : AS_02::h__AS02Reader(d) {}
+  virtual ~h__Reader() {}
+
   ASDCP::Result_t    OpenRead(const char*);
   ASDCP::Result_t    ReadFrame(ui32_t, ASDCP::PCM::FrameBuffer&, ASDCP::AESDecContext*, ASDCP::HMACContext*);
 
@@ -148,12 +140,6 @@ AS_02::PCM::MXFReader::h__Reader::OpenRead(const char* filename)
        }
     }
 
-  if( ASDCP_SUCCESS(result) )
-    result = InitMXFIndex();
-
-  if( ASDCP_SUCCESS(result) )
-    result = InitInfo();
-
   // TODO: test file for sane CBR index BytesPerEditUnit
 
   return result;
@@ -189,13 +175,13 @@ AS_02::PCM::MXFReader::~MXFReader()
 // Warning: direct manipulation of MXF structures can interfere
 // with the normal operation of the wrapper.  Caveat emptor!
 //
-ASDCP::MXF::OPAtomHeader&
-AS_02::PCM::MXFReader::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+AS_02::PCM::MXFReader::OP1aHeader()
 {
   if ( m_Reader.empty() )
     {
-      assert(g_OPAtomHeader);
-      return *g_OPAtomHeader;
+      assert(g_OP1aHeader);
+      return *g_OP1aHeader;
     }
 
   return m_Reader->m_HeaderPart;
@@ -204,19 +190,32 @@ AS_02::PCM::MXFReader::OPAtomHeader()
 // Warning: direct manipulation of MXF structures can interfere
 // with the normal operation of the wrapper.  Caveat emptor!
 //
-/*
-ASDCP::MXF::OPAtomIndexFooter&
-AS_02::PCM::MXFReader::OPAtomIndexFooter()
+AS_02::MXF::AS02IndexReader&
+AS_02::PCM::MXFReader::AS02IndexReader()
 {
   if ( m_Reader.empty() )
     {
-      assert(g_OPAtomIndexFooter);
-      return *g_OPAtomIndexFooter;
+      assert(g_AS02IndexReader);
+      return *g_AS02IndexReader;
     }
 
-  return m_Reader->m_FooterPart;
+  return m_Reader->m_IndexAccess;
+}
+
+// Warning: direct manipulation of MXF structures can interfere
+// with the normal operation of the wrapper.  Caveat emptor!
+//
+ASDCP::MXF::RIP&
+AS_02::PCM::MXFReader::RIP()
+{
+  if ( m_Reader.empty() )
+    {
+      assert(g_RIP);
+      return *g_RIP;
+    }
+
+  return m_Reader->m_RIP;
 }
-*/
 
 // Open the file for reading. The file must exist. Returns error if the
 // operation cannot be completed.
@@ -283,14 +282,14 @@ void
 AS_02::PCM::MXFReader::DumpIndex(FILE* stream) const
 {
   if ( m_Reader->m_File.IsOpen() )
-    m_Reader->m_FooterPart.Dump(stream);
+    m_Reader->m_IndexAccess.Dump(stream);
 }
 
 
 //------------------------------------------------------------------------------------------
 
 //
-class AS_02::PCM::MXFWriter::h__Writer : public AS_02::h__Writer
+class AS_02::PCM::MXFWriter::h__Writer : public AS_02::h__AS02Writer
 {
   ASDCP_NO_COPY_CONSTRUCT(h__Writer);
   h__Writer();
@@ -300,12 +299,12 @@ public:
   byte_t          m_EssenceUL[SMPTE_UL_LENGTH];
   ui64_t                       m_KLV_start;
 
-  h__Writer(const Dictionary& d) : AS_02::h__Writer(d), m_KLV_start(0){
+  h__Writer(const Dictionary& d) : AS_02::h__AS02Writer(d), m_KLV_start(0){
     memset(m_EssenceUL, 0, SMPTE_UL_LENGTH);
 
   }
 
-  ~h__Writer(){}
+  virtual ~h__Writer(){}
 
   Result_t OpenWrite(const char*, ui32_t HeaderSize);
   Result_t SetSourceStream(const ASDCP::PCM::AudioDescriptor&);
@@ -330,7 +329,7 @@ public:
   // reimplement these functions in AS_02_PCM to support modifications for AS-02
   Result_t WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf,
                           const byte_t* EssenceUL, AESEncContext* Ctx, HMACContext* HMAC);
-  Result_t WriteMXFFooter();
+  Result_t WriteAS02Footer();
 
 };
 
@@ -400,9 +399,9 @@ AS_02::PCM::MXFWriter::h__Writer::SetSourceStream(const ASDCP::PCM::AudioDescrip
     {
       ui32_t TCFrameRate = ( m_ADesc.EditRate == EditRate_23_98  ) ? 24 : m_ADesc.EditRate.Numerator;
 
-      result = WriteMXFHeader(PCM_PACKAGE_LABEL, UL(m_Dict->ul(MDD_WAVWrapping)),
-                             SOUND_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_SoundDataDef)),
-                             m_ADesc.EditRate, TCFrameRate, calc_CBR_frame_size(m_Info, m_ADesc));
+      result = WriteAS02Header(PCM_PACKAGE_LABEL, UL(m_Dict->ul(MDD_WAVWrapping)),
+                              SOUND_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_SoundDataDef)),
+                              m_ADesc.EditRate, TCFrameRate, calc_CBR_frame_size(m_Info, m_ADesc));
     }
 
   return result;
@@ -439,7 +438,7 @@ AS_02::PCM::MXFWriter::h__Writer::Finalize()
 
   m_State.Goto_FINAL();
 
-  return WriteMXFFooter();
+  return WriteAS02Footer();
 }
 
 
@@ -459,13 +458,13 @@ AS_02::PCM::MXFWriter::~MXFWriter()
 // Warning: direct manipulation of MXF structures can interfere
 // with the normal operation of the wrapper.  Caveat emptor!
 //
-ASDCP::MXF::OPAtomHeader&
-AS_02::PCM::MXFWriter::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+AS_02::PCM::MXFWriter::OP1aHeader()
 {
   if ( m_Writer.empty() )
     {
-      assert(g_OPAtomHeader);
-      return *g_OPAtomHeader;
+      assert(g_OP1aHeader);
+      return *g_OP1aHeader;
     }
 
   return m_Writer->m_HeaderPart;
@@ -474,19 +473,18 @@ AS_02::PCM::MXFWriter::OPAtomHeader()
 // Warning: direct manipulation of MXF structures can interfere
 // with the normal operation of the wrapper.  Caveat emptor!
 //
-/*
-ASDCP::MXF::OPAtomIndexFooter&
-AS_02::PCM::MXFWriter::OPAtomIndexFooter()
+ASDCP::MXF::RIP&
+AS_02::PCM::MXFWriter::RIP()
 {
   if ( m_Writer.empty() )
     {
-      assert(g_OPAtomIndexFooter);
-      return *g_OPAtomIndexFooter;
+      assert(g_RIP);
+      return *g_RIP;
     }
 
-  return m_Writer->m_FooterPart;
+  return m_Writer->m_RIP;
 }
-*/
+
 
 // Open the file for writing. The file must not exist. Returns error if
 // the operation cannot be completed.
@@ -531,563 +529,7 @@ AS_02::PCM::MXFWriter::Finalize()
   return m_Writer->Finalize();
 }
 
-// standard method of opening an MXF file for read
-Result_t
-AS_02::PCM::MXFReader::h__Reader::OpenMXFRead(const char* filename)
-{
-  m_LastPosition = 0;
-  AS_02::MXF::OP1aIndexBodyPartion* pCurrentBodyPartIndex = NULL;
-  Partition* pPart = NULL;
-  ui64_t EssenceStart = 0;
-  Result_t result = m_File.OpenRead(filename);
-
-  if ( ASDCP_SUCCESS(result) )
-    result = m_HeaderPart.InitFromFile(m_File);
-
-  if ( ASDCP_SUCCESS(result) )
-    {
-      ui32_t partition_size = m_HeaderPart.m_RIP.PairArray.size();
-
-      if ( partition_size > 3 )
-       {
-         //for all entry except the first and the last(header&footer)
-         Array<RIP::Pair>::iterator r_i = m_HeaderPart.m_RIP.PairArray.begin();
-         r_i++;
-         ui32_t i=2;
-
-         while ( r_i != m_HeaderPart.m_RIP.PairArray.end() && i < partition_size )
-           {
-             m_File.Seek((*r_i).ByteOffset);
-             pPart = new Partition(this->m_Dict);
-             result = pPart->InitFromFile(m_File);
-
-             // TODO:: expect Index partition
-             delete pPart;
-             m_File.Seek((*r_i).ByteOffset);
-             pCurrentBodyPartIndex = new AS_02::MXF::OP1aIndexBodyPartion(this->m_Dict);
-             pCurrentBodyPartIndex->m_Lookup = &m_HeaderPart.m_Primer;
-             result = pCurrentBodyPartIndex->InitFromFile(m_File);
-             
-             if ( ASDCP_FAILURE(result) )
-               {
-                 break;
-               }
-
-             r_i++; i++;
-
-             m_File.Seek((*r_i).ByteOffset);
-             pPart = new Partition(this->m_Dict);
-             result = pPart->InitFromFile(m_File);
-             EssenceStart = m_File.Tell();
-
-             if ( ASDCP_FAILURE(result) )
-               {
-                 break;
-               }
-
-             if(i==3)
-               {
-                 m_EssenceStart = EssenceStart;
-                 m_pCurrentBodyPartition = pPart;
-                 m_pCurrentIndexPartition = pCurrentBodyPartIndex;
-               }
-         
-             m_BodyPartList.push_back(pCurrentBodyPartIndex);
-             m_BodyPartList.push_back(pPart);
-             r_i++; i++;
-           }
-       }
-    }
-
-  return result;
-}
-
-// standard method of reading a plaintext or encrypted frame
-Result_t
-AS_02::PCM::MXFReader::h__Reader::ReadEKLVFrame(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
-                                               const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC)
-{
-  Result_t result = RESULT_OK;
-  // look up frame index node
-  IndexTableSegment::IndexEntry TmpEntry;
-  ui32_t i = 0;
-
-  if(m_pCurrentIndexPartition == NULL)
-    {
-      m_pCurrentIndexPartition = dynamic_cast<AS_02::MXF::OP1aIndexBodyPartion*> (m_BodyPartList.at(i));
-      m_pCurrentBodyPartition = m_BodyPartList.at(i+1);
-    }          
-  else
-    {
-      return RESULT_FORMAT; //return error
-    }
-                               
-  if(m_pCurrentIndexPartition == NULL)
-    {
-      return RESULT_FORMAT; //return error\r
-    }
-
-  m_pCurrentIndexPartition->PCMIndexLookup(FrameNum,TmpEntry);
-  // get frame position and go read the frame's key and length
-  Kumu::fpos_t FilePosition = this->m_EssenceStart + TmpEntry.StreamOffset;
-
-  if ( FilePosition != m_LastPosition )
-    {
-      m_LastPosition = FilePosition;
-      result = m_File.Seek(FilePosition);
-    }
-
-  if( ASDCP_SUCCESS(result) )
-    result = ReadEKLVPacket(FrameNum, FrameNum + 1, FrameBuf, EssenceUL, Ctx, HMAC);
-
-  return result;
-}
-
-Result_t
-AS_02::PCM::MXFReader::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ui32_t SequenceNum, ASDCP::FrameBuffer& FrameBuf,
-                                                const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC)
-{
-  KLReader Reader;
-
-  //save position to read KLV packet
-  Kumu::fpos_t SaveFilePosition = m_File.Tell();
-  //Seek backward to KLV start
-  m_File.Seek(this->m_EssenceStart);
-  Result_t result = Reader.ReadKLFromFile(m_File);
-  //set old position
-  m_File.Seek(SaveFilePosition);
-
-  if ( ASDCP_FAILURE(result) )
-    return result;
-
-  UL Key(Reader.Key());
-  ui64_t PacketLength = Reader.Length();
-  m_LastPosition = m_LastPosition + PacketLength;
-  if(FrameNum = 0){
-    m_LastPosition+= Reader.KLLength();
-  }
-  assert(m_Dict);
-
-  //TODO: for AS_02 PCM - not in the dictionary
-
-  static const byte_t WaveClipEssenceUL_Data[SMPTE_UL_LENGTH] =\r
-    { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x02, 0x01, 0x01,\r
-      0x0d, 0x01, 0x03, 0x01, 0x16, 0x01, 0x02, 0x01 };
-
-  \r
-    if( memcmp(Key.Value(), WaveClipEssenceUL_Data, SMPTE_UL_LENGTH) == 0 ){
-      byte_t WaveFrameEssenceUL_Data[SMPTE_UL_LENGTH] =\r
-       { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x02, 0x01, 0x01,\r
-         0x0d, 0x01, 0x03, 0x01, 0x16, 0x01, 0x01, 0x01 };
-
-      Key.Set(WaveFrameEssenceUL_Data);
-    }
-
-
-    if ( memcmp(Key.Value(), m_Dict->ul(MDD_CryptEssence), Key.Size() - 1) == 0 )  // ignore the stream numbers
-      {
-       if ( ! m_Info.EncryptedEssence )
-         {
-           DefaultLogSink().Error("EKLV packet found, no Cryptographic Context in header.\n");
-           return RESULT_FORMAT;
-         }
-
-       // read encrypted triplet value into internal buffer
-       assert(PacketLength <= 0xFFFFFFFFL);
-       m_CtFrameBuf.Capacity((ui32_t) PacketLength);
-       ui32_t read_count;
-       result = m_File.Read(m_CtFrameBuf.Data(), (ui32_t) PacketLength,
-                            &read_count);
-
-       if ( ASDCP_FAILURE(result) )
-         return result;
-
-       if ( read_count != PacketLength )
-         {
-           DefaultLogSink().Error("read length is smaller than EKLV packet length.\n");
-           return RESULT_FORMAT;
-         }
-
-       m_CtFrameBuf.Size((ui32_t) PacketLength);
-
-       // should be const but mxflib::ReadBER is not
-       byte_t* ess_p = m_CtFrameBuf.Data();
-
-       // read context ID length
-       if ( ! Kumu::read_test_BER(&ess_p, UUIDlen) )
-         return RESULT_FORMAT;
-
-       // test the context ID
-       if ( memcmp(ess_p, m_Info.ContextID, UUIDlen) != 0 )
-         {
-           DefaultLogSink().Error("Packet's Cryptographic Context ID does not match the header.\n");
-           return RESULT_FORMAT;
-         }
-       ess_p += UUIDlen;
-
-       // read PlaintextOffset length
-       if ( ! Kumu::read_test_BER(&ess_p, sizeof(ui64_t)) )
-         return RESULT_FORMAT;
-
-       ui32_t PlaintextOffset = (ui32_t)KM_i64_BE(Kumu::cp2i<ui64_t>(ess_p));
-       ess_p += sizeof(ui64_t);
-
-       // read essence UL length
-       if ( ! Kumu::read_test_BER(&ess_p, SMPTE_UL_LENGTH) )
-         return RESULT_FORMAT;
-
-       // test essence UL
-       if ( memcmp(ess_p, EssenceUL, SMPTE_UL_LENGTH - 1) != 0 ) // ignore the stream number
-         {
-           char strbuf[IntBufferLen];
-           const MDDEntry* Entry = m_Dict->FindUL(Key.Value());
-           if ( Entry == 0 )
-             DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Key.EncodeString(strbuf, IntBufferLen));
-           else
-             DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Entry->name);
-           return RESULT_FORMAT;
-         }
-       ess_p += SMPTE_UL_LENGTH;
-
-       // read SourceLength length
-       if ( ! Kumu::read_test_BER(&ess_p, sizeof(ui64_t)) )
-         return RESULT_FORMAT;
-
-       ui32_t SourceLength = (ui32_t)KM_i64_BE(Kumu::cp2i<ui64_t>(ess_p));
-       ess_p += sizeof(ui64_t);
-       assert(SourceLength);
-
-       if ( FrameBuf.Capacity() < SourceLength )
-         {
-           DefaultLogSink().Error("FrameBuf.Capacity: %u SourceLength: %u\n", FrameBuf.Capacity(), SourceLength);
-           return RESULT_SMALLBUF;
-         }
-
-       ui32_t esv_length = calc_esv_length(SourceLength, PlaintextOffset);
-
-       // read ESV length
-       if ( ! Kumu::read_test_BER(&ess_p, esv_length) )
-         {
-           DefaultLogSink().Error("read_test_BER did not return %u\n", esv_length);
-           return RESULT_FORMAT;
-         }
-
-       ui32_t tmp_len = esv_length + (m_Info.UsesHMAC ? klv_intpack_size : 0);
-
-       if ( PacketLength < tmp_len )
-         {
-           DefaultLogSink().Error("Frame length is larger than EKLV packet length.\n");
-           return RESULT_FORMAT;
-         }
-
-       if ( Ctx )
-         {
-           // wrap the pointer and length as a FrameBuffer for use by
-           // DecryptFrameBuffer() and TestValues()
-           FrameBuffer TmpWrapper;
-           TmpWrapper.SetData(ess_p, tmp_len);
-           TmpWrapper.Size(tmp_len);
-           TmpWrapper.SourceLength(SourceLength);
-           TmpWrapper.PlaintextOffset(PlaintextOffset);
-
-           result = DecryptFrameBuffer(TmpWrapper, FrameBuf, Ctx);
-           FrameBuf.FrameNumber(FrameNum);
-
-           // detect and test integrity pack
-           if ( ASDCP_SUCCESS(result) && m_Info.UsesHMAC && HMAC )
-             {
-               IntegrityPack IntPack;
-               result = IntPack.TestValues(TmpWrapper, m_Info.AssetUUID, SequenceNum, HMAC);
-             }
-         }
-       else // return ciphertext to caller
-         {
-           if ( FrameBuf.Capacity() < tmp_len )
-             {
-               char intbuf[IntBufferLen];
-               DefaultLogSink().Error("FrameBuf.Capacity: %u FrameLength: %s\n",
-                                      FrameBuf.Capacity(), ui64sz(PacketLength, intbuf));
-               return RESULT_SMALLBUF;
-             }
-
-           memcpy(FrameBuf.Data(), ess_p, tmp_len);
-           FrameBuf.Size(tmp_len);
-           FrameBuf.FrameNumber(FrameNum);
-           FrameBuf.SourceLength(SourceLength);
-           FrameBuf.PlaintextOffset(PlaintextOffset);
-         }
-      }
-    else if ( memcmp(Key.Value(), EssenceUL, Key.Size() - 1) == 0 ) // ignore the stream number
-      { // read plaintext frame
-       if ( FrameBuf.Capacity() < PacketLength )
-         {
-           char intbuf[IntBufferLen];
-           DefaultLogSink().Error("FrameBuf.Capacity: %u FrameLength: %s\n",
-                                  FrameBuf.Capacity(), ui64sz(PacketLength, intbuf));
-           return RESULT_SMALLBUF;
-         }
-
-       // read the data into the supplied buffer
-       ui32_t read_count;
-       assert(PacketLength <= 0xFFFFFFFFL);
-       result = m_File.Read(FrameBuf.Data(), (ui32_t) PacketLength, &read_count);
-
-       if ( ASDCP_FAILURE(result) )
-         return result;
-
-       if ( read_count != PacketLength )
-         {
-           char intbuf1[IntBufferLen];
-           char intbuf2[IntBufferLen];
-           DefaultLogSink().Error("read_count: %s != FrameLength: %s\n",
-                                  ui64sz(read_count, intbuf1),
-                                  ui64sz(PacketLength, intbuf2) );
-
-           return RESULT_READFAIL;
-         }
-
-       FrameBuf.FrameNumber(FrameNum);
-       FrameBuf.Size(read_count);
-      }
-    else
-      {
-       char strbuf[IntBufferLen];
-       const MDDEntry* Entry = m_Dict->FindUL(Key.Value());
-       if ( Entry == 0 )
-         DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Key.EncodeString(strbuf, IntBufferLen));
-       else
-         DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Entry->name);
-       return RESULT_FORMAT;
-      }
-
-    return result;
-}
-
-// standard method of writing the header and footer of a completed MXF file
-//
-Result_t
-AS_02::PCM::MXFWriter::h__Writer::WriteMXFFooter()
-{
-  // Set top-level file package correctly for OP-Atom
-
-  //  m_MPTCSequence->Duration = m_MPTimecode->Duration = m_MPClSequence->Duration = m_MPClip->Duration = 
-  //    m_FPTCSequence->Duration = m_FPTimecode->Duration = m_FPClSequence->Duration = m_FPClip->Duration = 
-
-  //
-  m_CurrentIndexBodyPartition->m_FramesWritten = m_FramesWritten;
-  m_CurrentIndexBodyPartition->PCMSetIndexParamsCBR(m_CurrentIndexBodyPartition->m_BytesPerEditUnit+24,m_CurrentIndexBodyPartition->m_BytesPerEditUnit);
-  CompleteIndexBodyPart();
-
-  DurationElementList_t::iterator dli = m_DurationUpdateList.begin();
-
-  for (; dli != m_DurationUpdateList.end(); dli++ )
-    **dli = m_FramesWritten;
-
-  m_EssenceDescriptor->ContainerDuration = m_FramesWritten;
-  m_FooterPart.PreviousPartition = m_HeaderPart.m_RIP.PairArray.back().ByteOffset;
-
-  Kumu::fpos_t here = m_File.Tell();
-  m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(0, here)); // Last RIP Entry
-  m_HeaderPart.FooterPartition = here;
-
-  assert(m_Dict);
-  // re-label the partition
-  UL OP1aUL(m_Dict->ul(MDD_OP1a));
-  m_HeaderPart.OperationalPattern = OP1aUL;
-  m_HeaderPart.m_Preface->OperationalPattern = m_HeaderPart.OperationalPattern;
-
-  m_FooterPart.OperationalPattern = m_HeaderPart.OperationalPattern;
-  m_FooterPart.EssenceContainers = m_HeaderPart.EssenceContainers;
-  m_FooterPart.FooterPartition = here;
-  m_FooterPart.ThisPartition = here;
-
-  Result_t result = m_FooterPart.WriteToFile(m_File, m_FramesWritten);
-
-  if ( ASDCP_SUCCESS(result) )
-    result = m_HeaderPart.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);
-
-  //update the value of FooterPartition in all Partitions
-  std::vector<Partition*>::iterator bl_i = this->m_BodyPartList.begin();
-  for (; bl_i != m_BodyPartList.end(); bl_i++ ){
-    (*bl_i)->FooterPartition =  m_FooterPart.ThisPartition;
-    if ( ASDCP_SUCCESS(result) )
-      result = m_File.Seek((*bl_i)->ThisPartition);
-    if ( ASDCP_SUCCESS(result) ){
-      UL BodyUL(m_Dict->ul(MDD_ClosedCompleteBodyPartition));
-      result = (*bl_i)->WriteToFile(m_File, BodyUL);
-    }
-  } 
-
-  m_File.Close();
-  return result;
-}
-
-// standard method of writing a plaintext or encrypted frame
-Result_t
-AS_02::PCM::MXFWriter::h__Writer::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf, const byte_t* EssenceUL,
-                                                 AESEncContext* Ctx, HMACContext* HMAC)
-{
-  Result_t result = RESULT_OK;
-  IntegrityPack IntPack;
-       
-  const ui32_t AS_02_PCM_MXF_BER_LENGTH = 8;
-  //TODO: AS_02_PCM_MXF_BER_LENGTH - customize for EncryptedEssence 
-
-  byte_t overhead[128];
-  Kumu::MemIOWriter Overhead(overhead, 128);
-  assert(m_Dict);
-
-  if ( FrameBuf.Size() == 0 )
-    {
-      DefaultLogSink().Error("Cannot write empty frame buffer\n");
-      return RESULT_EMPTY_FB;
-    }
-
-  if ( m_Info.EncryptedEssence )
-    {
-      if ( ! Ctx )
-       return RESULT_CRYPT_CTX;
-
-      if ( m_Info.UsesHMAC && ! HMAC )
-       return RESULT_HMAC_CTX;
-
-      if ( FrameBuf.PlaintextOffset() > FrameBuf.Size() )
-       return RESULT_LARGE_PTO;
-
-      // encrypt the essence data (create encrypted source value)
-      result = EncryptFrameBuffer(FrameBuf, m_CtFrameBuf, Ctx);
-
-      // create HMAC
-      if ( ASDCP_SUCCESS(result) && m_Info.UsesHMAC )
-       result = IntPack.CalcValues(m_CtFrameBuf, m_Info.AssetUUID, m_FramesWritten + 1, HMAC);
-
-      if ( ASDCP_SUCCESS(result) )
-       { // write UL
-         Overhead.WriteRaw(m_Dict->ul(MDD_CryptEssence), SMPTE_UL_LENGTH);
-
-         // construct encrypted triplet header
-         ui32_t ETLength = klv_cryptinfo_size + m_CtFrameBuf.Size();
-         ui32_t BER_length = MXF_BER_LENGTH;
-
-         if ( m_Info.UsesHMAC )
-           ETLength += klv_intpack_size;
-         else
-           ETLength += (MXF_BER_LENGTH * 3); // for empty intpack
-
-         if ( ETLength > 0x00ffffff ) // Need BER integer longer than MXF_BER_LENGTH bytes
-           {
-             BER_length = Kumu::get_BER_length_for_value(ETLength);
-
-             // the packet is longer by the difference in expected vs. actual BER length
-             ETLength += BER_length - MXF_BER_LENGTH;
-
-             if ( BER_length == 0 )
-               result = RESULT_KLV_CODING;
-           }
-
-         if ( ASDCP_SUCCESS(result) )
-           {
-             if ( ! ( Overhead.WriteBER(ETLength, BER_length)                      // write encrypted triplet length
-                      && Overhead.WriteBER(UUIDlen, MXF_BER_LENGTH)                // write ContextID length
-                      && Overhead.WriteRaw(m_Info.ContextID, UUIDlen)              // write ContextID
-                      && Overhead.WriteBER(sizeof(ui64_t), MXF_BER_LENGTH)         // write PlaintextOffset length
-                      && Overhead.WriteUi64BE(FrameBuf.PlaintextOffset())          // write PlaintextOffset
-                      && Overhead.WriteBER(SMPTE_UL_LENGTH, MXF_BER_LENGTH)        // write essence UL length
-                      && Overhead.WriteRaw((byte_t*)EssenceUL, SMPTE_UL_LENGTH)    // write the essence UL
-                      && Overhead.WriteBER(sizeof(ui64_t), MXF_BER_LENGTH)         // write SourceLength length
-                      && Overhead.WriteUi64BE(FrameBuf.Size())                     // write SourceLength
-                      && Overhead.WriteBER(m_CtFrameBuf.Size(), BER_length) ) )    // write ESV length
-               {
-                 result = RESULT_KLV_CODING;
-               }
-           }
-
-         if ( ASDCP_SUCCESS(result) )
-           result = m_File.Writev(Overhead.Data(), Overhead.Length());
-       }
-
-      if ( ASDCP_SUCCESS(result) )
-       {
-         m_StreamOffset += Overhead.Length();
-         // write encrypted source value
-         result = m_File.Writev((byte_t*)m_CtFrameBuf.RoData(), m_CtFrameBuf.Size());
-       }
-
-      if ( ASDCP_SUCCESS(result) )
-       {
-         m_StreamOffset += m_CtFrameBuf.Size();
-
-         byte_t hmoverhead[512];
-         Kumu::MemIOWriter HMACOverhead(hmoverhead, 512);
-
-         // write the HMAC
-         if ( m_Info.UsesHMAC )
-           {
-             HMACOverhead.WriteRaw(IntPack.Data, klv_intpack_size);
-           }
-         else
-           { // we still need the var-pack length values if the intpack is empty
-             for ( ui32_t i = 0; i < 3 ; i++ )
-               HMACOverhead.WriteBER(0, MXF_BER_LENGTH);
-           }
-
-         // write HMAC
-         result = m_File.Writev(HMACOverhead.Data(), HMACOverhead.Length());
-         m_StreamOffset += HMACOverhead.Length();
-       }
-    }
-  else
-    {
-      if(m_FramesWritten == 0){
-       ui32_t BER_length = AS_02_PCM_MXF_BER_LENGTH; //MXF_BER_LENGTH;
-
-       if ( FrameBuf.Size() > 0x00ffffff ) // Need BER integer longer than MXF_BER_LENGTH bytes
-         {
-           BER_length = Kumu::get_BER_length_for_value(FrameBuf.Size());
-
-           if ( BER_length == 0 )
-             result = RESULT_KLV_CODING;
-         }
-
-       Overhead.WriteRaw((byte_t*)EssenceUL, SMPTE_UL_LENGTH);
-       Overhead.WriteBER(FrameBuf.Size(), BER_length);
-
-       //position of the KLV start
-       m_KLV_start = m_File.Tell();
-
-       if ( ASDCP_SUCCESS(result) )
-         result = m_File.Writev(Overhead.Data(), Overhead.Length());
 
-       if ( ASDCP_SUCCESS(result) )
-         result = m_File.Writev((byte_t*)FrameBuf.RoData(), FrameBuf.Size());
-
-       if ( ASDCP_SUCCESS(result) )
-         m_StreamOffset += Overhead.Length() + FrameBuf.Size();
-      }
-      else{
-       //update the KLV - length; new value plus old value from length field
-       //necessary to know position of length field -> bodyPartition + 8
-       //update every time when writing new essence or at the end of writing
-
-       if ( ASDCP_SUCCESS(result) )
-         result = m_File.Writev((byte_t*)FrameBuf.RoData(), FrameBuf.Size());
-
-       if ( ASDCP_SUCCESS(result) )
-         m_StreamOffset += FrameBuf.Size();
-      }
-    }
-
-  if ( ASDCP_SUCCESS(result) )
-    result = m_File.Writev();
-
-  return result;
-}
 
 //
 // end AS_02_PCM.cpp
index 64fe83603c7de4e9f4141b4e2b42c70834279acf..0439ae4704f5329c690396751d121e6702a3472f 100644 (file)
@@ -1,5 +1,5 @@
 /*
-  Copyright (c) 2011-2012, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst
+  Copyright (c) 2011-2013, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst
   All rights reserved.
 
   Redistribution and use in source and binary forms, with or without
 #ifndef _AS_02_INTERNAL_H_
 #define _AS_02_INTERNAL_H_
 
-#include "KM_platform.h"
-#include "KM_util.h"
 #include "KM_log.h"
-#include "Metadata.h"
 #include "AS_DCP_internal.h"
 #include "AS_02.h"
 
 using Kumu::DefaultLogSink;
 
-using namespace ASDCP;
-using namespace ASDCP::MXF;
+#ifdef DEFAULT_MD_DECL
+AS_02::MXF::AS02IndexReader *g_AS02IndexReader;
+#else
+extern AS_02::MXF::AS02IndexReader *g_AS02IndexReader;
+#endif
+
 
 namespace AS_02
 {
+
+  void default_md_object_init();
+
   static void CalculateIndexPartitionSize(ui32_t& size,ui32_t numberOfIndexEntries)
   {
     if(numberOfIndexEntries){
@@ -68,127 +72,59 @@ namespace AS_02
   }
 
   //
-  class h__Reader
-  {
-    ASDCP_NO_COPY_CONSTRUCT(h__Reader);
-    h__Reader();
-
-  public:
-    const Dictionary*  m_Dict;
-    Kumu::FileReader   m_File;
-    OPAtomHeader       m_HeaderPart;
-    //more than one Body-Partition use a list 
-    std::vector<Partition*> m_BodyPartList;
-    OPAtomIndexFooter  m_FooterPart;
-    ui64_t             m_EssenceStart;
-    WriterInfo         m_Info;
-    ASDCP::FrameBuffer m_CtFrameBuf;
-    Kumu::fpos_t       m_LastPosition;
-
-    IndexStrategy_t    m_IndexStrategy; //Shim parameter index_strategy_frame/clip
-    ui32_t             m_PartitionSpace;
-
-    ////new elements for AS-02
-    Partition*         m_pCurrentBodyPartition;
-    AS_02::MXF::OP1aIndexBodyPartion* m_pCurrentIndexPartition;
-    ui32_t            m_start_pos;
-
-    h__Reader(const Dictionary&);
-    virtual ~h__Reader();
-
-    Result_t InitInfo();
-    virtual Result_t OpenMXFRead(const char* filename) = 0;
-    Result_t InitMXFIndex();
-
-    // positions file before reading
-    virtual Result_t ReadEKLVFrame(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
-                                  const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC) = 0;
-
-    // reads from current position
-    virtual Result_t ReadEKLVPacket(ui32_t FrameNum, ui32_t SequenceNum, ASDCP::FrameBuffer& FrameBuf,
-                                   const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC) = 0;
-    void     Close();
-  };
+  class h__AS02Reader : public ASDCP::MXF::TrackFileReader<ASDCP::MXF::OP1aHeader, AS_02::MXF::AS02IndexReader>
+    {
+      ASDCP_NO_COPY_CONSTRUCT(h__AS02Reader);
+      h__AS02Reader();
+
+    public:
+      Partition *m_pCurrentBodyPartition;
+      AS_02::MXF::OP1aIndexBodyPartion* m_pCurrentIndexPartition;
+      ui64_t     m_EssenceStart;
+      std::vector<Partition*> m_BodyPartList;
+      ui32_t     m_start_pos;
+      ui32_t     m_PartitionSpace;
+      IndexStrategy_t    m_IndexStrategy; //Shim parameter index_strategy_frame/clip
+
+      h__AS02Reader(const ASDCP::Dictionary&);
+      virtual ~h__AS02Reader();
+
+      Result_t OpenMXFRead(const char* filename);
+      Result_t ReadEKLVFrame(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
+                            const byte_t* EssenceUL, ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC);
+      Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset,
+                          i8_t& temporalOffset, i8_t& keyFrameOffset);
+
+    };
 
   //
-  class h__Writer
-  {
-    ASDCP_NO_COPY_CONSTRUCT(h__Writer);
-    h__Writer();
-
-  public:
-    const Dictionary*  m_Dict;
-    Kumu::FileWriter   m_File;
-    ui32_t             m_HeaderSize;
-    OPAtomHeader       m_HeaderPart;
-    //more than one Body-Partition -> use a list of Partitions
-    std::vector<Partition*> m_BodyPartList;
-    //we don't use the footer like in the dcps but we need also a footer
-    AS_02::MXF::OP1aIndexFooter    m_FooterPart;
-    ui64_t             m_EssenceStart;
-
-    MaterialPackage*   m_MaterialPackage;
-    SourcePackage*     m_FilePackage;
-
-    FileDescriptor*    m_EssenceDescriptor;
-    std::list<InterchangeObject*> m_EssenceSubDescriptorList;
-
-    ui32_t             m_FramesWritten;
-    ui64_t             m_StreamOffset;
-    ASDCP::FrameBuffer m_CtFrameBuf;
-    h__WriterState     m_State;
-    WriterInfo         m_Info;
-    DurationElementList_t m_DurationUpdateList;
-
-    //new elements for AS-02
-    ui64_t             m_BodyOffset;
-    //TODO: Currently not used, delete if not necessary
-    // Counter values for BodySID and IndexSID
-    ui32_t             m_CurrentBodySID;
-    ui32_t             m_CurrentIndexSID;
-    //TODO: maybe set this to the lf__Writer class because this is only in JP2K creation necessary
-    //our computed PartitionSpace
-    ui32_t             m_PartitionSpace;
-    IndexStrategy_t    m_IndexStrategy; //Shim parameter index_strategy_frame/clip
-
-    //the EditRate
-    ASDCP::MXF::Rational      m_EditRate;
-    //the BytesPerEditUnit
-    ui32_t                        m_BytesPerEditUnit;
-    //pointer to the current Body Partition(Index)
-    AS_02::MXF::OP1aIndexBodyPartion*  m_CurrentIndexBodyPartition;
-
-    h__Writer(const Dictionary&);
-    virtual ~h__Writer();
-
-    //virtual methods, implementation details for JP2K or PCM are in the MXFWriter::h__Writer classes if they are different
-    virtual void InitHeader();
-    /*virtual*/ void AddSourceClip(const ASDCP::MXF::Rational& EditRate, ui32_t TCFrameRate,
-                                  const std::string& TrackName, const UL& EssenceUL,
-                                  const UL& DataDefinition, const std::string& PackageLabel);
-    /*virtual*/ void AddDMSegment(const ASDCP::MXF::Rational& EditRate, ui32_t TCFrameRate,
-                                 const std::string& TrackName, const UL& DataDefinition,
-                                 const std::string& PackageLabel);
-    /*virtual*/ void AddEssenceDescriptor(const ASDCP::UL& WrappingUL);
-    virtual Result_t CreateBodyPart(const ASDCP::MXF::Rational& EditRate, ui32_t BytesPerEditUnit = 0);
-
-    //new method to create BodyPartition for essence and index
-    virtual Result_t CreateBodyPartPair();
-    //new method to finalize BodyPartion(index)
-    virtual Result_t CompleteIndexBodyPart();
-
-    // all the above for a single source clip
-    virtual Result_t WriteMXFHeader(const std::string& PackageLabel, const UL& WrappingUL,
-                                   const std::string& TrackName, const UL& EssenceUL,
-                                   const UL& DataDefinition, const ASDCP::MXF::Rational& EditRate,
-                                   ui32_t TCFrameRate, ui32_t BytesPerEditUnit = 0);
-
-    virtual Result_t WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf,
-                                    const byte_t* EssenceUL, AESEncContext* Ctx, HMACContext* HMAC);
-
-    virtual Result_t WriteMXFFooter() = 0;
-
-  };
+  class h__AS02Writer : public ASDCP::MXF::TrackFileWriter<ASDCP::MXF::OP1aHeader>
+    {
+      ASDCP_NO_COPY_CONSTRUCT(h__AS02Writer);
+      h__AS02Writer();
+
+    public:
+      AS_02::MXF::OP1aIndexBodyPartion*  m_CurrentIndexBodyPartition;
+      ui64_t     m_BodyOffset;
+      ui32_t     m_PartitionSpace;
+      IndexStrategy_t    m_IndexStrategy; //Shim parameter index_strategy_frame/clip
+      std::vector<Partition*> m_BodyPartList;
+
+      h__AS02Writer(const Dictionary&);
+      virtual ~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);
+
+      Result_t CreateBodyPart(const ASDCP::MXF::Rational& EditRate, ui32_t BytesPerEditUnit);
+      Result_t CreateBodyPartPair();
+      Result_t CompleteIndexBodyPart();
+
+      Result_t WriteAS02Footer();
+    };
 
 } // namespace AS_02
 
index b9aba837651a94f69b47f5238f3727a562056fe6..4f6b0974f06bfe9554256bc5a16749c8576fea9a 100755 (executable)
@@ -570,8 +570,9 @@ namespace ASDCP {
 
   namespace MXF {
     // #include<Metadata.h> to use these
-    class OPAtomHeader;
+    class OP1aHeader;
     class OPAtomIndexFooter;
+    class RIP;
   };
 
   //---------------------------------------------------------------------------------
@@ -731,8 +732,9 @@ namespace ASDCP {
 
          // Warning: direct manipulation of MXF structures can interfere
          // with the normal operation of the wrapper.  Caveat emptor!
-         virtual MXF::OPAtomHeader& OPAtomHeader();
+         virtual MXF::OP1aHeader& OP1aHeader();
          virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+         virtual MXF::RIP& RIP();
 
          // Open the file for writing. The file must not exist. Returns error if
          // the operation cannot be completed or if nonsensical data is discovered
@@ -763,8 +765,9 @@ namespace ASDCP {
 
          // Warning: direct manipulation of MXF structures can interfere
          // with the normal operation of the wrapper.  Caveat emptor!
-         virtual MXF::OPAtomHeader& OPAtomHeader();
+         virtual MXF::OP1aHeader& OP1aHeader();
          virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+         virtual MXF::RIP& RIP();
 
          // Open the file for reading. The file must exist. Returns error if the
          // operation cannot be completed.
@@ -936,8 +939,9 @@ namespace ASDCP {
 
          // Warning: direct manipulation of MXF structures can interfere
          // with the normal operation of the wrapper.  Caveat emptor!
-         virtual MXF::OPAtomHeader& OPAtomHeader();
+         virtual MXF::OP1aHeader& OP1aHeader();
          virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+         virtual MXF::RIP& RIP();
 
          // Open the file for writing. The file must not exist. Returns error if
          // the operation cannot be completed or if nonsensical data is discovered
@@ -968,8 +972,9 @@ namespace ASDCP {
 
          // Warning: direct manipulation of MXF structures can interfere
          // with the normal operation of the wrapper.  Caveat emptor!
-         virtual MXF::OPAtomHeader& OPAtomHeader();
+         virtual MXF::OP1aHeader& OP1aHeader();
          virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+         virtual MXF::RIP& RIP();
 
          // Open the file for reading. The file must exist. Returns error if the
          // operation cannot be completed.
@@ -1183,8 +1188,9 @@ namespace ASDCP {
 
          // Warning: direct manipulation of MXF structures can interfere
          // with the normal operation of the wrapper.  Caveat emptor!
-         virtual MXF::OPAtomHeader& OPAtomHeader();
+         virtual MXF::OP1aHeader& OP1aHeader();
          virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+         virtual MXF::RIP& RIP();
 
          // Open the file for writing. The file must not exist. Returns error if
          // the operation cannot be completed or if nonsensical data is discovered
@@ -1215,8 +1221,9 @@ namespace ASDCP {
 
          // Warning: direct manipulation of MXF structures can interfere
          // with the normal operation of the wrapper.  Caveat emptor!
-         virtual MXF::OPAtomHeader& OPAtomHeader();
+         virtual MXF::OP1aHeader& OP1aHeader();
          virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+         virtual MXF::RIP& RIP();
 
          // Open the file for reading. The file must exist. Returns error if the
          // operation cannot be completed.
@@ -1286,8 +1293,9 @@ namespace ASDCP {
 
          // Warning: direct manipulation of MXF structures can interfere
          // with the normal operation of the wrapper.  Caveat emptor!
-         virtual MXF::OPAtomHeader& OPAtomHeader();
+         virtual MXF::OP1aHeader& OP1aHeader();
          virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+         virtual MXF::RIP& RIP();
 
          // Open the file for writing. The file must not exist. Returns error if
          // the operation cannot be completed or if nonsensical data is discovered
@@ -1328,8 +1336,9 @@ namespace ASDCP {
 
          // Warning: direct manipulation of MXF structures can interfere
          // with the normal operation of the wrapper.  Caveat emptor!
-         virtual MXF::OPAtomHeader& OPAtomHeader();
+         virtual MXF::OP1aHeader& OP1aHeader();
          virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+         virtual MXF::RIP& RIP();
 
          // Open the file for reading. The file must exist. Returns error if the
          // operation cannot be completed.
@@ -1492,8 +1501,9 @@ namespace ASDCP {
 
          // Warning: direct manipulation of MXF structures can interfere
          // with the normal operation of the wrapper.  Caveat emptor!
-         virtual MXF::OPAtomHeader& OPAtomHeader();
+         virtual MXF::OP1aHeader& OP1aHeader();
          virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+         virtual MXF::RIP& RIP();
 
          // Open the file for writing. The file must not exist. Returns error if
          // the operation cannot be completed or if nonsensical data is discovered
@@ -1534,8 +1544,9 @@ namespace ASDCP {
 
          // Warning: direct manipulation of MXF structures can interfere
          // with the normal operation of the wrapper.  Caveat emptor!
-         virtual MXF::OPAtomHeader& OPAtomHeader();
+         virtual MXF::OP1aHeader& OP1aHeader();
          virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+         virtual MXF::RIP& RIP();
 
          // Open the file for reading. The file must exist. Returns error if the
          // operation cannot be completed.
@@ -1686,8 +1697,9 @@ namespace ASDCP {
 
          // Warning: direct manipulation of MXF structures can interfere
          // with the normal operation of the wrapper.  Caveat emptor!
-         virtual MXF::OPAtomHeader& OPAtomHeader();
+         virtual MXF::OP1aHeader& OP1aHeader();
          virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+         virtual MXF::RIP& RIP();
 
          // Open the file for writing. The file must not exist. Returns error if
          // the operation cannot be completed or if nonsensical data is discovered
@@ -1718,8 +1730,9 @@ namespace ASDCP {
 
          // Warning: direct manipulation of MXF structures can interfere
          // with the normal operation of the wrapper.  Caveat emptor!
-         virtual MXF::OPAtomHeader& OPAtomHeader();
+         virtual MXF::OP1aHeader& OP1aHeader();
          virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+         virtual MXF::RIP& RIP();
 
          // Open the file for reading. The file must exist. Returns error if the
          // operation cannot be completed.
@@ -1792,8 +1805,9 @@ namespace ASDCP {
 
          // Warning: direct manipulation of MXF structures can interfere
          // with the normal operation of the wrapper.  Caveat emptor!
-         virtual MXF::OPAtomHeader& OPAtomHeader();
+         virtual MXF::OP1aHeader& OP1aHeader();
          virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+         virtual MXF::RIP& RIP();
 
          // Open the file for writing. The file must not exist. Returns error if
          // the operation cannot be completed or if nonsensical data is discovered
@@ -1824,8 +1838,9 @@ namespace ASDCP {
 
          // Warning: direct manipulation of MXF structures can interfere
          // with the normal operation of the wrapper.  Caveat emptor!
-         virtual MXF::OPAtomHeader& OPAtomHeader();
+         virtual MXF::OP1aHeader& OP1aHeader();
          virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
+         virtual MXF::RIP& RIP();
 
          // Open the file for reading. The file must exist. Returns error if the
          // operation cannot be completed.
index da23a0adedff83df6aa67fec283408e6ceabc2b1..63b55577f4bda85c67d73905e541ffbfdd7efb3d 100644 (file)
@@ -40,7 +40,7 @@ namespace ASDCP
 {
 namespace ATMOS
 {
-  static std::string ATMOS_PACKAGE_LABEL = "File Package: SMPTE 382M frame wrapping of Dolby ATMOS data";
+  static std::string ATMOS_PACKAGE_LABEL = "File Package: SMPTE-GC frame wrapping of Dolby ATMOS data";
   static std::string ATMOS_DEF_LABEL = "Dolby ATMOS Data Track";
   static byte_t ATMOS_ESSENCE_CODING[SMPTE_UL_LENGTH] = { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x05,
                                                           0x0e, 0x09, 0x06, 0x04, 0x00, 0x00, 0x00, 0x00 };
@@ -117,7 +117,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() {}
-  ~h__Reader() {}
+  virtual ~h__Reader() {}
   Result_t    OpenRead(const char*);
   Result_t    MD_to_Atmos_ADesc(ATMOS::AtmosDescriptor& ADesc);
 };
@@ -183,13 +183,13 @@ ASDCP::ATMOS::MXFReader::~MXFReader()
 // Warning: direct manipulation of MXF structures can interfere
 // with the normal operation of the wrapper.  Caveat emptor!
 //
-ASDCP::MXF::OPAtomHeader&
-ASDCP::ATMOS::MXFReader::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+ASDCP::ATMOS::MXFReader::OP1aHeader()
 {
   if ( m_Reader.empty() )
   {
-    assert(g_OPAtomHeader);
-    return *g_OPAtomHeader;
+    assert(g_OP1aHeader);
+    return *g_OP1aHeader;
   }
 
   return m_Reader->m_HeaderPart;
@@ -207,7 +207,22 @@ ASDCP::ATMOS::MXFReader::OPAtomIndexFooter()
     return *g_OPAtomIndexFooter;
   }
 
-  return m_Reader->m_FooterPart;
+  return m_Reader->m_IndexAccess;
+}
+
+// Warning: direct manipulation of MXF structures can interfere
+// with the normal operation of the wrapper.  Caveat emptor!
+//
+ASDCP::MXF::RIP&
+ASDCP::ATMOS::MXFReader::RIP()
+{
+  if ( m_Reader.empty() )
+    {
+      assert(g_RIP);
+      return *g_RIP;
+    }
+
+  return m_Reader->m_RIP;
 }
 
 // Open the file for reading. The file must exist. Returns error if the
@@ -278,7 +293,7 @@ void
 ASDCP::ATMOS::MXFReader::DumpIndex(FILE* stream) const
 {
   if ( m_Reader->m_File.IsOpen() )
-    m_Reader->m_FooterPart.Dump(stream);
+    m_Reader->m_IndexAccess.Dump(stream);
 }
 
 //
@@ -311,7 +326,7 @@ class ASDCP::ATMOS::MXFWriter::h__Writer : public DCData::h__Writer
   h__Writer(const Dictionary& d) : DCData::h__Writer(d),
       m_EssenceSubDescriptor(NULL), m_ADesc() {}
 
-  ~h__Writer(){}
+  virtual ~h__Writer(){}
 
   Result_t OpenWrite(const char*, ui32_t HeaderSize, const AtmosDescriptor& ADesc);
   Result_t Atmos_ADesc_to_MD(const AtmosDescriptor& ADesc);
@@ -370,13 +385,13 @@ ASDCP::ATMOS::MXFWriter::~MXFWriter()
 // Warning: direct manipulation of MXF structures can interfere
 // with the normal operation of the wrapper.  Caveat emptor!
 //
-ASDCP::MXF::OPAtomHeader&
-ASDCP::ATMOS::MXFWriter::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+ASDCP::ATMOS::MXFWriter::OP1aHeader()
 {
   if ( m_Writer.empty() )
   {
-    assert(g_OPAtomHeader);
-    return *g_OPAtomHeader;
+    assert(g_OP1aHeader);
+    return *g_OP1aHeader;
     }
 
   return m_Writer->m_HeaderPart;
@@ -397,6 +412,21 @@ ASDCP::ATMOS::MXFWriter::OPAtomIndexFooter()
   return m_Writer->m_FooterPart;
 }
 
+// Warning: direct manipulation of MXF structures can interfere
+// with the normal operation of the wrapper.  Caveat emptor!
+//
+ASDCP::MXF::RIP&
+ASDCP::ATMOS::MXFWriter::RIP()
+{
+  if ( m_Writer.empty() )
+    {
+      assert(g_RIP);
+      return *g_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 53e4497fc404b1b56d7d1db2032b624013f8ffcd..6ee1098d46ca95f07fdcfa63ff5bad0956fdec64 100644 (file)
@@ -39,7 +39,7 @@ namespace ASDCP
 {
 namespace DCData
 {
-  static std::string DC_DATA_PACKAGE_LABEL = "File Package: SMPTE 382M frame wrapping of D-Cinema Generic data";
+  static std::string DC_DATA_PACKAGE_LABEL = "File Package: SMPTE-GC frame wrapping of D-Cinema Generic data";
   static std::string DC_DATA_DEF_LABEL = "D-Cinema Generic Data Track";
 } // namespace DCData
 } // namespace ASDCP
@@ -128,12 +128,6 @@ ASDCP::DCData::h__Reader::OpenRead(const char* filename)
     return RESULT_FORMAT;
   }
 
-  if( ASDCP_SUCCESS(result) )
-    result = InitMXFIndex();
-
-  if( ASDCP_SUCCESS(result) )
-    result = InitInfo();
-
   return result;
 }
 
@@ -161,6 +155,7 @@ class ASDCP::DCData::MXFReader::h__Reader : public DCData::h__Reader
 
   public:
     h__Reader(const Dictionary& d) : DCData::h__Reader(d) {}
+  virtual ~h__Reader() {}
 };
 
 
@@ -198,13 +193,13 @@ ASDCP::DCData::MXFReader::~MXFReader()
 // Warning: direct manipulation of MXF structures can interfere
 // with the normal operation of the wrapper.  Caveat emptor!
 //
-ASDCP::MXF::OPAtomHeader&
-ASDCP::DCData::MXFReader::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+ASDCP::DCData::MXFReader::OP1aHeader()
 {
   if ( m_Reader.empty() )
     {
-      assert(g_OPAtomHeader);
-      return *g_OPAtomHeader;
+      assert(g_OP1aHeader);
+      return *g_OP1aHeader;
     }
 
   return m_Reader->m_HeaderPart;
@@ -222,7 +217,22 @@ ASDCP::DCData::MXFReader::OPAtomIndexFooter()
       return *g_OPAtomIndexFooter;
     }
 
-  return m_Reader->m_FooterPart;
+  return m_Reader->m_IndexAccess;
+}
+
+// Warning: direct manipulation of MXF structures can interfere
+// with the normal operation of the wrapper.  Caveat emptor!
+//
+ASDCP::MXF::RIP&
+ASDCP::DCData::MXFReader::RIP()
+{
+  if ( m_Reader.empty() )
+    {
+      assert(g_RIP);
+      return *g_RIP;
+    }
+
+  return m_Reader->m_RIP;
 }
 
 // Open the file for reading. The file must exist. Returns error if the
@@ -294,7 +304,7 @@ void
 ASDCP::DCData::MXFReader::DumpIndex(FILE* stream) const
 {
   if ( m_Reader->m_File.IsOpen() )
-    m_Reader->m_FooterPart.Dump(stream);
+    m_Reader->m_IndexAccess.Dump(stream);
 }
 
 //
@@ -398,9 +408,9 @@ ASDCP::DCData::h__Writer::SetSourceStream(DCDataDescriptor const& DDesc,
   {
     ui32_t TCFrameRate = m_DDesc.EditRate.Numerator;
 
-    result = WriteMXFHeader(packageLabel, UL(m_Dict->ul(MDD_DCDataWrapping)),
-                            defLabel, UL(m_EssenceUL), UL(m_Dict->ul(MDD_DataDataDef)),
-                            m_DDesc.EditRate, TCFrameRate);
+    result = WriteASDCPHeader(packageLabel, UL(m_Dict->ul(MDD_DCDataWrapping)),
+                             defLabel, UL(m_EssenceUL), UL(m_Dict->ul(MDD_DataDataDef)),
+                             m_DDesc.EditRate, TCFrameRate);
   }
 
   return result;
@@ -441,7 +451,7 @@ ASDCP::DCData::h__Writer::Finalize()
 
   m_State.Goto_FINAL();
 
-  return WriteMXFFooter();
+  return WriteASDCPFooter();
 }
 
 
@@ -456,6 +466,7 @@ class ASDCP::DCData::MXFWriter::h__Writer : public DCData::h__Writer
 
   public:
     h__Writer(const Dictionary& d) : DCData::h__Writer(d) {}
+  virtual ~h__Writer() {}
 };
 
 
@@ -472,13 +483,13 @@ ASDCP::DCData::MXFWriter::~MXFWriter()
 // Warning: direct manipulation of MXF structures can interfere
 // with the normal operation of the wrapper.  Caveat emptor!
 //
-ASDCP::MXF::OPAtomHeader&
-ASDCP::DCData::MXFWriter::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+ASDCP::DCData::MXFWriter::OP1aHeader()
 {
   if ( m_Writer.empty() )
     {
-      assert(g_OPAtomHeader);
-      return *g_OPAtomHeader;
+      assert(g_OP1aHeader);
+      return *g_OP1aHeader;
     }
 
   return m_Writer->m_HeaderPart;
@@ -499,6 +510,21 @@ ASDCP::DCData::MXFWriter::OPAtomIndexFooter()
   return m_Writer->m_FooterPart;
 }
 
+// Warning: direct manipulation of MXF structures can interfere
+// with the normal operation of the wrapper.  Caveat emptor!
+//
+ASDCP::MXF::RIP&
+ASDCP::DCData::MXFWriter::RIP()
+{
+  if ( m_Writer.empty() )
+    {
+      assert(g_RIP);
+      return *g_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 65d6c41f285b5f58f564b1161cf3f6d7ceb86606..93ccb7e11b22dd380db5d7c24feca00eb681f66a 100644 (file)
@@ -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
@@ -65,7 +65,7 @@ namespace DCData
     Result_t    MD_to_DCData_DDesc(DCData::DCDataDescriptor& DDesc);
   };
 
-  class h__Writer : public ASDCP::h__Writer
+  class h__Writer : public ASDCP::h__ASDCPWriter
   {
     ASDCP_NO_COPY_CONSTRUCT(h__Writer);
     h__Writer();
@@ -74,7 +74,7 @@ namespace DCData
     DCDataDescriptor m_DDesc;
     byte_t           m_EssenceUL[SMPTE_UL_LENGTH];
 
-    h__Writer(const Dictionary& d) : ASDCP::h__Writer(d) {
+    h__Writer(const Dictionary& d) : ASDCP::h__ASDCPWriter(d) {
       memset(m_EssenceUL, 0, SMPTE_UL_LENGTH);
     }
 
index 300a6a284118e673696e3f1493019ed41abae8f6..d5cbc85cc36793a23e11b8451748cd685ceddaca 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
@@ -220,6 +220,9 @@ public:
 
   lh__Reader(const Dictionary& d) :
     ASDCP::h__ASDCPReader(d), m_EssenceDescriptor(0), m_EssenceSubDescriptor(0), m_Format(ESS_UNKNOWN) {}
+
+  virtual ~lh__Reader() {}
+
   Result_t    OpenRead(const char*, EssenceType_t);
   Result_t    ReadFrame(ui32_t, JP2K::FrameBuffer&, AESDecContext*, HMACContext*);
   Result_t    MD_to_JP2K_PDesc(JP2K::PictureDescriptor& PDesc);
@@ -411,12 +414,6 @@ lh__Reader::OpenRead(const char* filename, EssenceType_t type)
       result = MD_to_JP2K_PDesc(m_PDesc);
     }
 
-  if( ASDCP_SUCCESS(result) )
-    result = InitMXFIndex();
-
-  if( ASDCP_SUCCESS(result) )
-    result = InitInfo();
-
   return result;
 }
 
@@ -482,13 +479,13 @@ ASDCP::JP2K::MXFReader::~MXFReader()
 // Warning: direct manipulation of MXF structures can interfere
 // with the normal operation of the wrapper.  Caveat emptor!
 //
-ASDCP::MXF::OPAtomHeader&
-ASDCP::JP2K::MXFReader::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+ASDCP::JP2K::MXFReader::OP1aHeader()
 {
   if ( m_Reader.empty() )
     {
-      assert(g_OPAtomHeader);
-      return *g_OPAtomHeader;
+      assert(g_OP1aHeader);
+      return *g_OP1aHeader;
     }
 
   return m_Reader->m_HeaderPart;
@@ -506,7 +503,22 @@ ASDCP::JP2K::MXFReader::OPAtomIndexFooter()
       return *g_OPAtomIndexFooter;
     }
 
-  return m_Reader->m_FooterPart;
+  return m_Reader->m_IndexAccess;
+}
+
+// Warning: direct manipulation of MXF structures can interfere
+// with the normal operation of the wrapper.  Caveat emptor!
+//
+ASDCP::MXF::RIP&
+ASDCP::JP2K::MXFReader::RIP()
+{
+  if ( m_Reader.empty() )
+    {
+      assert(g_RIP);
+      return *g_RIP;
+    }
+
+  return m_Reader->m_RIP;
 }
 
 // Open the file for reading. The file must exist. Returns error if the
@@ -578,7 +590,7 @@ void
 ASDCP::JP2K::MXFReader::DumpIndex(FILE* stream) const
 {
   if ( m_Reader->m_File.IsOpen() )
-    m_Reader->m_FooterPart.Dump(stream);
+    m_Reader->m_IndexAccess.Dump(stream);
 }
 
 //
@@ -612,7 +624,7 @@ public:
     // look up frame index node
     IndexTableSegment::IndexEntry TmpEntry;
 
-    if ( ASDCP_FAILURE(m_FooterPart.Lookup(FrameNum, TmpEntry)) )
+    if ( ASDCP_FAILURE(m_IndexAccess.Lookup(FrameNum, TmpEntry)) )
       {
        DefaultLogSink().Error("Frame value out of range: %u\n", FrameNum);
        return RESULT_RANGE;
@@ -694,13 +706,13 @@ ASDCP::JP2K::MXFSReader::~MXFSReader()
 // Warning: direct manipulation of MXF structures can interfere
 // with the normal operation of the wrapper.  Caveat emptor!
 //
-ASDCP::MXF::OPAtomHeader&
-ASDCP::JP2K::MXFSReader::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+ASDCP::JP2K::MXFSReader::OP1aHeader()
 {
   if ( m_Reader.empty() )
     {
-      assert(g_OPAtomHeader);
-      return *g_OPAtomHeader;
+      assert(g_OP1aHeader);
+      return *g_OP1aHeader;
     }
 
   return m_Reader->m_HeaderPart;
@@ -718,7 +730,22 @@ ASDCP::JP2K::MXFSReader::OPAtomIndexFooter()
       return *g_OPAtomIndexFooter;
     }
 
-  return m_Reader->m_FooterPart;
+  return m_Reader->m_IndexAccess;
+}
+
+// Warning: direct manipulation of MXF structures can interfere
+// with the normal operation of the wrapper.  Caveat emptor!
+//
+ASDCP::MXF::RIP&
+ASDCP::JP2K::MXFSReader::RIP()
+{
+  if ( m_Reader.empty() )
+    {
+      assert(g_RIP);
+      return *g_RIP;
+    }
+
+  return m_Reader->m_RIP;
 }
 
 // Open the file for reading. The file must exist. Returns error if the
@@ -806,7 +833,7 @@ void
 ASDCP::JP2K::MXFSReader::DumpIndex(FILE* stream) const
 {
   if ( m_Reader->m_File.IsOpen() )
-    m_Reader->m_FooterPart.Dump(stream);
+    m_Reader->m_IndexAccess.Dump(stream);
 }
 
 //
@@ -827,7 +854,7 @@ ASDCP::JP2K::MXFSReader::Close() const
 
 
 //
-class lh__Writer : public ASDCP::h__Writer
+class lh__Writer : public ASDCP::h__ASDCPWriter
 {
   ASDCP_NO_COPY_CONSTRUCT(lh__Writer);
   lh__Writer();
@@ -838,11 +865,11 @@ public:
   PictureDescriptor m_PDesc;
   byte_t            m_EssenceUL[SMPTE_UL_LENGTH];
 
-  lh__Writer(const Dictionary& d) : ASDCP::h__Writer(d), m_EssenceSubDescriptor(0) {
+  lh__Writer(const Dictionary& d) : ASDCP::h__ASDCPWriter(d), m_EssenceSubDescriptor(0) {
     memset(m_EssenceUL, 0, SMPTE_UL_LENGTH);
   }
 
-  ~lh__Writer(){}
+  virtual ~lh__Writer(){}
 
   Result_t OpenWrite(const char*, EssenceType_t type, ui32_t HeaderSize);
   Result_t SetSourceStream(const PictureDescriptor&, const std::string& label,
@@ -993,9 +1020,9 @@ lh__Writer::SetSourceStream(const PictureDescriptor& PDesc, const std::string& l
     {
       ui32_t TCFrameRate = ( m_PDesc.EditRate == EditRate_23_98  ) ? 24 : m_PDesc.EditRate.Numerator;
 
-      result = WriteMXFHeader(label, UL(m_Dict->ul(MDD_JPEG_2000Wrapping)),
-                             PICT_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_PictureDataDef)),
-                             LocalEditRate, TCFrameRate);
+      result = WriteASDCPHeader(label, UL(m_Dict->ul(MDD_JPEG_2000Wrapping)),
+                               PICT_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_PictureDataDef)),
+                               LocalEditRate, TCFrameRate);
     }
 
   return result;
@@ -1042,7 +1069,7 @@ lh__Writer::Finalize()
 
   m_State.Goto_FINAL();
 
-  return WriteMXFFooter();
+  return WriteASDCPFooter();
 }
 
 
@@ -1072,13 +1099,13 @@ ASDCP::JP2K::MXFWriter::~MXFWriter()
 // Warning: direct manipulation of MXF structures can interfere
 // with the normal operation of the wrapper.  Caveat emptor!
 //
-ASDCP::MXF::OPAtomHeader&
-ASDCP::JP2K::MXFWriter::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+ASDCP::JP2K::MXFWriter::OP1aHeader()
 {
   if ( m_Writer.empty() )
     {
-      assert(g_OPAtomHeader);
-      return *g_OPAtomHeader;
+      assert(g_OP1aHeader);
+      return *g_OP1aHeader;
     }
 
   return m_Writer->m_HeaderPart;
@@ -1099,6 +1126,21 @@ ASDCP::JP2K::MXFWriter::OPAtomIndexFooter()
   return m_Writer->m_FooterPart;
 }
 
+// Warning: direct manipulation of MXF structures can interfere
+// with the normal operation of the wrapper.  Caveat emptor!
+//
+ASDCP::MXF::RIP&
+ASDCP::JP2K::MXFWriter::RIP()
+{
+  if ( m_Writer.empty() )
+    {
+      assert(g_RIP);
+      return *g_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
@@ -1203,13 +1245,13 @@ ASDCP::JP2K::MXFSWriter::~MXFSWriter()
 // Warning: direct manipulation of MXF structures can interfere
 // with the normal operation of the wrapper.  Caveat emptor!
 //
-ASDCP::MXF::OPAtomHeader&
-ASDCP::JP2K::MXFSWriter::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+ASDCP::JP2K::MXFSWriter::OP1aHeader()
 {
   if ( m_Writer.empty() )
     {
-      assert(g_OPAtomHeader);
-      return *g_OPAtomHeader;
+      assert(g_OP1aHeader);
+      return *g_OP1aHeader;
     }
 
   return m_Writer->m_HeaderPart;
@@ -1230,6 +1272,21 @@ ASDCP::JP2K::MXFSWriter::OPAtomIndexFooter()
   return m_Writer->m_FooterPart;
 }
 
+// Warning: direct manipulation of MXF structures can interfere
+// with the normal operation of the wrapper.  Caveat emptor!
+//
+ASDCP::MXF::RIP&
+ASDCP::JP2K::MXFSWriter::RIP()
+{
+  if ( m_Writer.empty() )
+    {
+      assert(g_RIP);
+      return *g_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 61ab7b7d83cd10239a796957f28a4c71483f4325..0ddfa45e6b1eba804daaf231f3e36a2db979cfb7 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
@@ -169,7 +169,7 @@ public:
   VideoDescriptor m_VDesc;        // video parameter list
 
   h__Reader(const Dictionary& d) : ASDCP::h__ASDCPReader(d) {}
-  ~h__Reader() {}
+  virtual ~h__Reader() {}
   Result_t    OpenRead(const char*);
   Result_t    ReadFrame(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*);
   Result_t    ReadFrameGOPStart(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*);
@@ -195,12 +195,6 @@ ASDCP::MPEG2::MXFReader::h__Reader::OpenRead(const char* filename)
        }
     }
 
-  if( ASDCP_SUCCESS(result) )
-    result = InitMXFIndex();
-
-  if( ASDCP_SUCCESS(result) )
-    result = InitInfo();
-
   return result;
 }
 
@@ -235,7 +229,7 @@ ASDCP::MPEG2::MXFReader::h__Reader::FindFrameGOPStart(ui32_t FrameNum, ui32_t& K
   // look up frame index node
   IndexTableSegment::IndexEntry TmpEntry;
 
-  if ( ASDCP_FAILURE(m_FooterPart.Lookup(FrameNum, TmpEntry)) )
+  if ( ASDCP_FAILURE(m_IndexAccess.Lookup(FrameNum, TmpEntry)) )
     {
       DefaultLogSink().Error("Frame value out of range: %u\n", FrameNum);
       return RESULT_RANGE;
@@ -256,7 +250,7 @@ ASDCP::MPEG2::MXFReader::h__Reader::FrameType(ui32_t FrameNum, FrameType_t& type
   // look up frame index node
   IndexTableSegment::IndexEntry TmpEntry;
 
-  if ( ASDCP_FAILURE(m_FooterPart.Lookup(FrameNum, TmpEntry)) )
+  if ( ASDCP_FAILURE(m_IndexAccess.Lookup(FrameNum, TmpEntry)) )
     {
       DefaultLogSink().Error("Frame value out of range: %u\n", FrameNum);
       return RESULT_RANGE;
@@ -283,7 +277,7 @@ ASDCP::MPEG2::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, FrameBuffer& Fram
     return result;
 
   IndexTableSegment::IndexEntry TmpEntry;
-  m_FooterPart.Lookup(FrameNum, TmpEntry);
+  m_IndexAccess.Lookup(FrameNum, TmpEntry);
 
   switch ( ( TmpEntry.Flags >> 4 ) & 0x03 )
     {
@@ -340,13 +334,13 @@ ASDCP::MPEG2::MXFReader::~MXFReader()
 // Warning: direct manipulation of MXF structures can interfere
 // with the normal operation of the wrapper.  Caveat emptor!
 //
-ASDCP::MXF::OPAtomHeader&
-ASDCP::MPEG2::MXFReader::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+ASDCP::MPEG2::MXFReader::OP1aHeader()
 {
   if ( m_Reader.empty() )
     {
-      assert(g_OPAtomHeader);
-      return *g_OPAtomHeader;
+      assert(g_OP1aHeader);
+      return *g_OP1aHeader;
     }
 
   return m_Reader->m_HeaderPart;
@@ -364,7 +358,22 @@ ASDCP::MPEG2::MXFReader::OPAtomIndexFooter()
       return *g_OPAtomIndexFooter;
     }
 
-  return m_Reader->m_FooterPart;
+  return m_Reader->m_IndexAccess;
+}
+
+// Warning: direct manipulation of MXF structures can interfere
+// with the normal operation of the wrapper.  Caveat emptor!
+//
+ASDCP::MXF::RIP&
+ASDCP::MPEG2::MXFReader::RIP()
+{
+  if ( m_Reader.empty() )
+    {
+      assert(g_RIP);
+      return *g_RIP;
+    }
+
+  return m_Reader->m_RIP;
 }
 
 // Open the file for reading. The file must exist. Returns error if the
@@ -460,7 +469,7 @@ void
 ASDCP::MPEG2::MXFReader::DumpIndex(FILE* stream) const
 {
   if ( m_Reader->m_File.IsOpen() )
-    m_Reader->m_FooterPart.Dump(stream);
+    m_Reader->m_IndexAccess.Dump(stream);
 }
 
 //
@@ -490,7 +499,7 @@ ASDCP::MPEG2::MXFReader::FrameType(ui32_t FrameNum, FrameType_t& type) const
 //------------------------------------------------------------------------------------------
 
 //
-class ASDCP::MPEG2::MXFWriter::h__Writer : public ASDCP::h__Writer
+class ASDCP::MPEG2::MXFWriter::h__Writer : public ASDCP::h__ASDCPWriter
 {
   ASDCP_NO_COPY_CONSTRUCT(h__Writer);
   h__Writer();
@@ -500,11 +509,11 @@ public:
   ui32_t          m_GOPOffset;
   byte_t          m_EssenceUL[SMPTE_UL_LENGTH];
 
-  h__Writer(const Dictionary& d) : ASDCP::h__Writer(d), m_GOPOffset(0) {
+  h__Writer(const Dictionary& d) : ASDCP::h__ASDCPWriter(d), m_GOPOffset(0) {
     memset(m_EssenceUL, 0, SMPTE_UL_LENGTH);
   }
 
-  ~h__Writer(){}
+  virtual ~h__Writer(){}
 
   Result_t OpenWrite(const char*, ui32_t HeaderSize);
   Result_t SetSourceStream(const VideoDescriptor&);
@@ -555,9 +564,9 @@ ASDCP::MPEG2::MXFWriter::h__Writer::SetSourceStream(const VideoDescriptor& VDesc
     {
       ui32_t TCFrameRate = ( m_VDesc.EditRate == EditRate_23_98  ) ? 24 : m_VDesc.EditRate.Numerator;
 
-      result = WriteMXFHeader(MPEG_PACKAGE_LABEL, UL(m_Dict->ul(MDD_MPEG2_VESWrapping)), 
-                             PICT_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_PictureDataDef)),
-                             m_VDesc.EditRate, TCFrameRate);
+      result = WriteASDCPHeader(MPEG_PACKAGE_LABEL, UL(m_Dict->ul(MDD_MPEG2_VESWrapping)), 
+                               PICT_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_PictureDataDef)),
+                               m_VDesc.EditRate, TCFrameRate);
     }
 
   return result;
@@ -634,7 +643,7 @@ ASDCP::MPEG2::MXFWriter::h__Writer::Finalize()
 
   m_State.Goto_FINAL();
 
-  return WriteMXFFooter();
+  return WriteASDCPFooter();
 }
 
 
@@ -653,13 +662,13 @@ ASDCP::MPEG2::MXFWriter::~MXFWriter()
 // Warning: direct manipulation of MXF structures can interfere
 // with the normal operation of the wrapper.  Caveat emptor!
 //
-ASDCP::MXF::OPAtomHeader&
-ASDCP::MPEG2::MXFWriter::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+ASDCP::MPEG2::MXFWriter::OP1aHeader()
 {
   if ( m_Writer.empty() )
     {
-      assert(g_OPAtomHeader);
-      return *g_OPAtomHeader;
+      assert(g_OP1aHeader);
+      return *g_OP1aHeader;
     }
 
   return m_Writer->m_HeaderPart;
@@ -680,6 +689,21 @@ ASDCP::MPEG2::MXFWriter::OPAtomIndexFooter()
   return m_Writer->m_FooterPart;
 }
 
+// Warning: direct manipulation of MXF structures can interfere
+// with the normal operation of the wrapper.  Caveat emptor!
+//
+ASDCP::MXF::RIP&
+ASDCP::MPEG2::MXFWriter::RIP()
+{
+  if ( m_Writer.empty() )
+    {
+      assert(g_RIP);
+      return *g_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 4d039f00f83a0148e1c51fe6518749fae21b7e36..a9ff152730ebc931c430e68ad9e9fb38b2ebd437 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
@@ -168,7 +168,7 @@ ASDCP::EssenceType(const char* filename, EssenceType_t& type)
 
   ASDCP_TEST_NULL_STR(filename);
   Kumu::FileReader   Reader;
-  OPAtomHeader TestHeader(m_Dict);
+  OP1aHeader TestHeader(m_Dict);
 
   Result_t result = Reader.OpenRead(filename);
 
@@ -274,10 +274,10 @@ ASDCP::RawEssenceType(const char* filename, EssenceType_t& type)
            {
              type = ESS_TIMED_TEXT;
            }
-      else if ( ASDCP::ATMOS::IsDolbyAtmos(filename) )
-      {
-        type = ESS_DCDATA_DOLBY_ATMOS;
-      }
+         else if ( ASDCP::ATMOS::IsDolbyAtmos(filename) )
+           {
+             type = ESS_DCDATA_DOLBY_ATMOS;
+           }
        }
     }
   else if ( Kumu::PathIsDirectory(filename) )
@@ -320,23 +320,22 @@ ASDCP::RawEssenceType(const char* filename, EssenceType_t& type)
                          return RESULT_FORMAT;
                        }
                    }
-             else if ( ASDCP_SUCCESS(RF64Header.ReadFromBuffer(FB.RoData(), read_count, &data_offset)) )
-            {
-              switch ( RF64Header.samplespersec )
-            {
-            case 48000: type = ESS_PCM_24b_48k; break;
-            case 96000: type = ESS_PCM_24b_96k; break;
-            default:
-              return RESULT_FORMAT;
-            }
-               }
-          else if ( ASDCP::ATMOS::IsDolbyAtmos(Str.c_str()) )
-          {
-            type = ESS_DCDATA_DOLBY_ATMOS;
-          }
-
+                 else if ( ASDCP_SUCCESS(RF64Header.ReadFromBuffer(FB.RoData(), read_count, &data_offset)) )
+                   {
+                     switch ( RF64Header.samplespersec )
+                       {
+                       case 48000: type = ESS_PCM_24b_48k; break;
+                       case 96000: type = ESS_PCM_24b_96k; break;
+                       default:
+                         return RESULT_FORMAT;
+                       }
+                   }
+                 else if ( ASDCP::ATMOS::IsDolbyAtmos(Str.c_str()) )
+                   {
+                     type = ESS_DCDATA_DOLBY_ATMOS;
+                   }
                }
-
+             
              break;
            }
        }
index e52b27f3b1106353206454c55c617897d430698b..2109999df868a4ea253b63152e7baf6dcaed14c6 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
@@ -236,7 +236,7 @@ public:
   AudioDescriptor m_ADesc;
 
   h__Reader(const Dictionary& d) : ASDCP::h__ASDCPReader(d) {}
-  ~h__Reader() {}
+  virtual ~h__Reader() {}
   Result_t    OpenRead(const char*);
   Result_t    ReadFrame(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*);
 };
@@ -293,12 +293,6 @@ ASDCP::PCM::MXFReader::h__Reader::OpenRead(const char* filename)
        }
     }
 
-  if( ASDCP_SUCCESS(result) )
-    result = InitMXFIndex();
-
-  if( ASDCP_SUCCESS(result) )
-    result = InitInfo();
-
   // TODO: test file for sane CBR index BytesPerEditUnit
 
   return result;
@@ -352,13 +346,13 @@ ASDCP::PCM::MXFReader::~MXFReader()
 // Warning: direct manipulation of MXF structures can interfere
 // with the normal operation of the wrapper.  Caveat emptor!
 //
-ASDCP::MXF::OPAtomHeader&
-ASDCP::PCM::MXFReader::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+ASDCP::PCM::MXFReader::OP1aHeader()
 {
   if ( m_Reader.empty() )
     {
-      assert(g_OPAtomHeader);
-      return *g_OPAtomHeader;
+      assert(g_OP1aHeader);
+      return *g_OP1aHeader;
     }
 
   return m_Reader->m_HeaderPart;
@@ -376,7 +370,22 @@ ASDCP::PCM::MXFReader::OPAtomIndexFooter()
       return *g_OPAtomIndexFooter;
     }
 
-  return m_Reader->m_FooterPart;
+  return m_Reader->m_IndexAccess;
+}
+
+// Warning: direct manipulation of MXF structures can interfere
+// with the normal operation of the wrapper.  Caveat emptor!
+//
+ASDCP::MXF::RIP&
+ASDCP::PCM::MXFReader::RIP()
+{
+  if ( m_Reader.empty() )
+    {
+      assert(g_RIP);
+      return *g_RIP;
+    }
+
+  return m_Reader->m_RIP;
 }
 
 // Open the file for reading. The file must exist. Returns error if the
@@ -450,7 +459,7 @@ void
 ASDCP::PCM::MXFReader::DumpIndex(FILE* stream) const
 {
   if ( m_Reader->m_File.IsOpen() )
-    m_Reader->m_FooterPart.Dump(stream);
+    m_Reader->m_IndexAccess.Dump(stream);
 }
 
 //
@@ -470,7 +479,7 @@ ASDCP::PCM::MXFReader::Close() const
 //------------------------------------------------------------------------------------------
 
 //
-class ASDCP::PCM::MXFWriter::h__Writer : public ASDCP::h__Writer
+class ASDCP::PCM::MXFWriter::h__Writer : public ASDCP::h__ASDCPWriter
 {
   ASDCP_NO_COPY_CONSTRUCT(h__Writer);
   h__Writer();
@@ -479,11 +488,11 @@ public:
   AudioDescriptor m_ADesc;
   byte_t          m_EssenceUL[SMPTE_UL_LENGTH];
   
-  h__Writer(const Dictionary& d) : ASDCP::h__Writer(d) {
+  h__Writer(const Dictionary& d) : ASDCP::h__ASDCPWriter(d) {
     memset(m_EssenceUL, 0, SMPTE_UL_LENGTH);
   }
 
-  ~h__Writer(){}
+  virtual ~h__Writer(){}
 
   Result_t OpenWrite(const char*, ui32_t HeaderSize);
   Result_t SetSourceStream(const AudioDescriptor&);
@@ -571,9 +580,9 @@ ASDCP::PCM::MXFWriter::h__Writer::SetSourceStream(const AudioDescriptor& ADesc)
       else if ( m_ADesc.EditRate == EditRate_22  )
        TCFrameRate = 22;
       
-      result = WriteMXFHeader(PCM_PACKAGE_LABEL, UL(m_Dict->ul(MDD_WAVWrapping)),
-                             SOUND_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_SoundDataDef)),
-                             m_ADesc.EditRate, TCFrameRate, calc_CBR_frame_size(m_Info, m_ADesc));
+      result = WriteASDCPHeader(PCM_PACKAGE_LABEL, UL(m_Dict->ul(MDD_WAVWrapping)),
+                               SOUND_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_SoundDataDef)),
+                               m_ADesc.EditRate, TCFrameRate, calc_CBR_frame_size(m_Info, m_ADesc));
     }
 
   return result;
@@ -610,7 +619,7 @@ ASDCP::PCM::MXFWriter::h__Writer::Finalize()
 
   m_State.Goto_FINAL();
 
-  return WriteMXFFooter();
+  return WriteASDCPFooter();
 }
 
 
@@ -630,13 +639,13 @@ ASDCP::PCM::MXFWriter::~MXFWriter()
 // Warning: direct manipulation of MXF structures can interfere
 // with the normal operation of the wrapper.  Caveat emptor!
 //
-ASDCP::MXF::OPAtomHeader&
-ASDCP::PCM::MXFWriter::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+ASDCP::PCM::MXFWriter::OP1aHeader()
 {
   if ( m_Writer.empty() )
     {
-      assert(g_OPAtomHeader);
-      return *g_OPAtomHeader;
+      assert(g_OP1aHeader);
+      return *g_OP1aHeader;
     }
 
   return m_Writer->m_HeaderPart;
@@ -657,6 +666,21 @@ ASDCP::PCM::MXFWriter::OPAtomIndexFooter()
   return m_Writer->m_FooterPart;
 }
 
+// Warning: direct manipulation of MXF structures can interfere
+// with the normal operation of the wrapper.  Caveat emptor!
+//
+ASDCP::MXF::RIP&
+ASDCP::PCM::MXFWriter::RIP()
+{
+  if ( m_Writer.empty() )
+    {
+      assert(g_RIP);
+      return *g_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 694676d7327180bc30ea87ecdc3dcce2d513530f..56407ed4e026f0a18980e8b1d81c1d29c143da76 100644 (file)
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2008-2012, John Hurst
+Copyright (c) 2008-2013, John Hurst
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -137,6 +137,8 @@ public:
     memset(&m_TDesc.AssetID, 0, UUIDlen);
   }
 
+  virtual ~h__Reader() {}
+
   Result_t    OpenRead(const char*);
   Result_t    MD_to_TimedText_TDesc(TimedText::TimedTextDescriptor& TDesc);
   Result_t    ReadTimedTextResource(FrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC);
@@ -216,12 +218,6 @@ ASDCP::TimedText::MXFReader::h__Reader::OpenRead(char const* filename)
        result = MD_to_TimedText_TDesc(m_TDesc);
     }
 
-  if( ASDCP_SUCCESS(result) )
-    result = InitMXFIndex();
-
-  if( ASDCP_SUCCESS(result) )
-    result = InitInfo();
-
   return result;
 }
 
@@ -276,7 +272,7 @@ ASDCP::TimedText::MXFReader::h__Reader::ReadAncillaryResource(const byte_t* uuid
       // Look up the partition start in the RIP using the SID.
       // Count the sequence length in because this is the sequence
       // value needed to  complete the HMAC.
-      for ( pi = m_HeaderPart.m_RIP.PairArray.begin(); pi != m_HeaderPart.m_RIP.PairArray.end(); ++pi, ++sequence )
+      for ( pi = m_RIP.PairArray.begin(); pi != m_RIP.PairArray.end(); ++pi, ++sequence )
        {
          if ( (*pi).BodySID == DescObject->EssenceStreamID )
            {
@@ -344,13 +340,13 @@ ASDCP::TimedText::MXFReader::~MXFReader()
 // Warning: direct manipulation of MXF structures can interfere
 // with the normal operation of the wrapper.  Caveat emptor!
 //
-ASDCP::MXF::OPAtomHeader&
-ASDCP::TimedText::MXFReader::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+ASDCP::TimedText::MXFReader::OP1aHeader()
 {
   if ( m_Reader.empty() )
     {
-      assert(g_OPAtomHeader);
-      return *g_OPAtomHeader;
+      assert(g_OP1aHeader);
+      return *g_OP1aHeader;
     }
 
   return m_Reader->m_HeaderPart;
@@ -368,7 +364,22 @@ ASDCP::TimedText::MXFReader::OPAtomIndexFooter()
       return *g_OPAtomIndexFooter;
     }
 
-  return m_Reader->m_FooterPart;
+  return m_Reader->m_IndexAccess;
+}
+
+// Warning: direct manipulation of MXF structures can interfere
+// with the normal operation of the wrapper.  Caveat emptor!
+//
+ASDCP::MXF::RIP&
+ASDCP::TimedText::MXFReader::RIP()
+{
+  if ( m_Reader.empty() )
+    {
+      assert(g_RIP);
+      return *g_RIP;
+    }
+
+  return m_Reader->m_RIP;
 }
 
 // Open the file for reading. The file must exist. Returns error if the
@@ -458,7 +469,7 @@ void
 ASDCP::TimedText::MXFReader::DumpIndex(FILE* stream) const
 {
   if ( m_Reader->m_File.IsOpen() )
-    m_Reader->m_FooterPart.Dump(stream);
+    m_Reader->m_IndexAccess.Dump(stream);
 }
 
 //
@@ -479,7 +490,7 @@ ASDCP::TimedText::MXFReader::Close() const
 
 
 //
-class ASDCP::TimedText::MXFWriter::h__Writer : public ASDCP::h__Writer
+class ASDCP::TimedText::MXFWriter::h__Writer : public ASDCP::h__ASDCPWriter
 {
   ASDCP_NO_COPY_CONSTRUCT(h__Writer);
   h__Writer();
@@ -489,11 +500,11 @@ public:
   byte_t              m_EssenceUL[SMPTE_UL_LENGTH];
   ui32_t              m_EssenceStreamID;
 
-  h__Writer(const Dictionary& d) : ASDCP::h__Writer(d), m_EssenceStreamID(10) {
+  h__Writer(const Dictionary& d) : ASDCP::h__ASDCPWriter(d), m_EssenceStreamID(10) {
     memset(m_EssenceUL, 0, SMPTE_UL_LENGTH);
   }
 
-  ~h__Writer(){}
+  virtual ~h__Writer() {}
 
   Result_t OpenWrite(const char*, ui32_t HeaderSize);
   Result_t SetSourceStream(const TimedTextDescriptor&);
@@ -637,11 +648,11 @@ ASDCP::TimedText::MXFWriter::h__Writer::WriteAncillaryResource(const ASDCP::Time
   MXF::Partition GSPart(m_Dict);
 
   GSPart.ThisPartition = here;
-  GSPart.PreviousPartition = m_HeaderPart.m_RIP.PairArray.back().ByteOffset;
+  GSPart.PreviousPartition = m_RIP.PairArray.back().ByteOffset;
   GSPart.BodySID = m_EssenceStreamID;
   GSPart.OperationalPattern = m_HeaderPart.OperationalPattern;
 
-  m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(m_EssenceStreamID++, here));
+  m_RIP.PairArray.push_back(RIP::Pair(m_EssenceStreamID++, here));
   GSPart.EssenceContainers.push_back(UL(m_Dict->ul(MDD_TimedTextEssence)));
   UL TmpUL(m_Dict->ul(MDD_GenericStreamPartition));
   Result_t result = GSPart.WriteToFile(m_File, TmpUL);
@@ -663,7 +674,7 @@ ASDCP::TimedText::MXFWriter::h__Writer::Finalize()
   m_FramesWritten = m_TDesc.ContainerDuration;
   m_State.Goto_FINAL();
 
-  return WriteMXFFooter();
+  return WriteASDCPFooter();
 }
 
 
@@ -680,13 +691,13 @@ ASDCP::TimedText::MXFWriter::~MXFWriter()
 // Warning: direct manipulation of MXF structures can interfere
 // with the normal operation of the wrapper.  Caveat emptor!
 //
-ASDCP::MXF::OPAtomHeader&
-ASDCP::TimedText::MXFWriter::OPAtomHeader()
+ASDCP::MXF::OP1aHeader&
+ASDCP::TimedText::MXFWriter::OP1aHeader()
 {
   if ( m_Writer.empty() )
     {
-      assert(g_OPAtomHeader);
-      return *g_OPAtomHeader;
+      assert(g_OP1aHeader);
+      return *g_OP1aHeader;
     }
 
   return m_Writer->m_HeaderPart;
@@ -707,6 +718,21 @@ ASDCP::TimedText::MXFWriter::OPAtomIndexFooter()
   return m_Writer->m_FooterPart;
 }
 
+// Warning: direct manipulation of MXF structures can interfere
+// with the normal operation of the wrapper.  Caveat emptor!
+//
+ASDCP::MXF::RIP&
+ASDCP::TimedText::MXFWriter::RIP()
+{
+  if ( m_Writer.empty() )
+    {
+      assert(g_RIP);
+      return *g_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 53101001335238af49abab6d632aee8797103ede..493fae6efa69e00c78d4818f38609bd6550ab8c6 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
@@ -38,16 +38,23 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "Metadata.h"
 
 using Kumu::DefaultLogSink;
-// using namespace std;
 using namespace ASDCP;
 using namespace ASDCP::MXF;
 
+// a magic number identifying asdcplib
+#ifndef ASDCP_BUILD_NUMBER
+#define ASDCP_BUILD_NUMBER 0x6A68
+#endif
+
+
 #ifdef DEFAULT_MD_DECL
-ASDCP::MXF::OPAtomHeader *g_OPAtomHeader;
+ASDCP::MXF::OP1aHeader *g_OP1aHeader;
 ASDCP::MXF::OPAtomIndexFooter *g_OPAtomIndexFooter;
+ASDCP::MXF::RIP *g_RIP;
 #else
-extern MXF::OPAtomHeader *g_OPAtomHeader;
+extern MXF::OP1aHeader *g_OP1aHeader;
 extern MXF::OPAtomIndexFooter *g_OPAtomIndexFooter;
+extern MXF::RIP *g_RIP;
 #endif
 
 
@@ -128,11 +135,16 @@ namespace ASDCP
   void     AddDMScrypt(Partition& HeaderPart, SourcePackage& Package,
                       WriterInfo& Descr, const UL& WrappingUL, const Dictionary*& Dict);
 
-  Result_t Read_EKLV_Packet(Kumu::FileReader& File, const ASDCP::Dictionary& Dict, const MXF::OPAtomHeader& HeaderPart,
+  Result_t Read_EKLV_Packet(Kumu::FileReader& File, const ASDCP::Dictionary& Dict, const MXF::OP1aHeader& HeaderPart,
                            const ASDCP::WriterInfo& Info, Kumu::fpos_t& LastPosition, ASDCP::FrameBuffer& CtFrameBuf,
                            ui32_t FrameNum, ui32_t SequenceNum, ASDCP::FrameBuffer& FrameBuf,
                            const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC);
 
+  Result_t Write_EKLV_Packet(Kumu::FileWriter& File, const ASDCP::Dictionary& Dict, const MXF::OP1aHeader& HeaderPart,
+                            const ASDCP::WriterInfo& Info, ASDCP::FrameBuffer& CtFrameBuf, ui32_t& FramesWritten,
+                            ui64_t & StreamOffset, const ASDCP::FrameBuffer& FrameBuf, const byte_t* EssenceUL,
+                            AESEncContext* Ctx, HMACContext* HMAC);
+
   //
  class KLReader : public ASDCP::KLVPacket
     {
@@ -157,7 +169,7 @@ namespace ASDCP
 
     ///      void default_md_object_init();
 
-      template <class HeaderType, class FooterType>
+      template <class HeaderType, class IndexAccessType>
       class TrackFileReader
       {
        KM_NO_COPY_CONSTRUCT(TrackFileReader);
@@ -167,13 +179,14 @@ namespace ASDCP
        const Dictionary*  m_Dict;
        Kumu::FileReader   m_File;
        HeaderType         m_HeaderPart;
-       FooterType         m_FooterPart;
+       IndexAccessType    m_IndexAccess;
+       RIP                m_RIP;
        WriterInfo         m_Info;
        ASDCP::FrameBuffer m_CtFrameBuf;
        Kumu::fpos_t       m_LastPosition;
 
       TrackFileReader(const Dictionary& d) :
-       m_HeaderPart(m_Dict), m_FooterPart(m_Dict), m_Dict(&d)
+       m_HeaderPart(m_Dict), m_IndexAccess(m_Dict), m_RIP(m_Dict), m_Dict(&d)
          {
            default_md_object_init();
          }
@@ -182,6 +195,48 @@ namespace ASDCP
          Close();
        }
 
+       const MXF::RIP& GetRIP() const { return m_RIP; }
+
+       //
+       Result_t OpenMXFRead(const char* filename)
+       {
+         m_LastPosition = 0;
+         Result_t result = m_File.OpenRead(filename);
+
+         if ( ASDCP_SUCCESS(result) )
+           result = SeekToRIP(m_File);
+
+         if ( ASDCP_SUCCESS(result) )
+           {
+             result = m_RIP.InitFromFile(m_File);
+             ui32_t test_s = m_RIP.PairArray.size();
+
+             if ( ASDCP_FAILURE(result) )
+               {
+                 DefaultLogSink().Error("File contains no RIP\n");
+               }
+             else if ( m_RIP.PairArray.empty() )
+               {
+                 DefaultLogSink().Error("RIP contains no Pairs.\n");
+               }
+           }
+         else
+           {
+             DefaultLogSink().Error("TrackFileReader::OpenMXFRead, SeekToRIP failed\n");
+           }
+
+         m_File.Seek(0);
+         result = m_HeaderPart.InitFromFile(m_File);
+
+         if ( KM_FAILURE(result) )
+           {
+             DefaultLogSink().Error("TrackFileReader::OpenMXFRead, header init failed\n");
+           }
+
+         return result;
+       }
+
+       //
        Result_t InitInfo()
        {
          assert(m_Dict);
@@ -215,20 +270,6 @@ namespace ASDCP
          return result;
        }
 
-       //
-       Result_t OpenMXFRead(const char* filename)
-       {
-         m_LastPosition = 0;
-         Result_t result = m_File.OpenRead(filename);
-
-         if ( KM_SUCCESS(result) )
-           result = m_HeaderPart.InitFromFile(m_File);
-      else
-        DefaultLogSink().Error("ASDCP::h__Reader::OpenMXFRead, OpenRead failed\n");
-
-         return result;
-       }
-
        // positions file before reading
        Result_t ReadEKLVFrame(const ASDCP::MXF::Partition& CurrentPartition,
                               ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
@@ -237,7 +278,7 @@ namespace ASDCP
          // look up frame index node
          IndexTableSegment::IndexEntry TmpEntry;
 
-         if ( KM_FAILURE(m_FooterPart.Lookup(FrameNum, TmpEntry)) )
+         if ( KM_FAILURE(m_IndexAccess.Lookup(FrameNum, TmpEntry)) )
            {
              DefaultLogSink().Error("Frame value out of range: %u\n", FrameNum);
              return RESULT_RANGE;
@@ -268,38 +309,440 @@ namespace ASDCP
                                  FrameNum, SequenceNum, FrameBuf, EssenceUL, Ctx, HMAC);
        }
 
-    // Get the position of a frame from a track file
-    Result_t LocateFrame(const ASDCP::MXF::Partition& CurrentPartition,
-                         ui32_t FrameNum, Kumu::fpos_t& streamOffset,
-                         i8_t& temporalOffset, i8_t& keyFrameOffset)
-    {
-      // look up frame index node
-      IndexTableSegment::IndexEntry TmpEntry;
+       // Get the position of a frame from a track file
+       Result_t LocateFrame(const ASDCP::MXF::Partition& CurrentPartition,
+                            ui32_t FrameNum, Kumu::fpos_t& streamOffset,
+                            i8_t& temporalOffset, i8_t& keyFrameOffset)
+       {
+         // look up frame index node
+         IndexTableSegment::IndexEntry TmpEntry;
+
+         if ( KM_FAILURE(m_IndexAccess.Lookup(FrameNum, TmpEntry)) )
+           {
+             DefaultLogSink().Error("Frame value out of range: %u\n", FrameNum);
+             return RESULT_RANGE;
+           }
+
+         // get frame position, temporal offset, and key frame ofset
+         streamOffset = CurrentPartition.BodyOffset + TmpEntry.StreamOffset;
+         temporalOffset = TmpEntry.TemporalOffset;
+         keyFrameOffset = TmpEntry.KeyFrameOffset;
+         
+         return RESULT_OK;
+       }
+
+       //
+       void Close()
+       {
+         m_File.Close();
+       }
+      };
+      
+
+      //
+      //
+      template <class ClipT>
+       struct TrackSet
+       {
+         MXF::Track*    Track;
+         MXF::Sequence* Sequence;
+         ClipT*         Clip;
+
+       TrackSet() : Track(0), Sequence(0), Clip(0) {}
+       };
+
+      //
+      template <class PackageT, class ClipT>
+       TrackSet<ClipT>
+       CreateTrackAndSequence(OP1aHeader& Header, PackageT& Package, const std::string TrackName,
+                              const MXF::Rational& EditRate, const UL& Definition, ui32_t TrackID, const Dictionary*& Dict)
+       {
+         TrackSet<ClipT> NewTrack;
+
+         NewTrack.Track = new Track(Dict);
+         Header.AddChildObject(NewTrack.Track);
+         NewTrack.Track->EditRate = EditRate;
+         Package.Tracks.push_back(NewTrack.Track->InstanceUID);
+         NewTrack.Track->TrackID = TrackID;
+         NewTrack.Track->TrackName = TrackName.c_str();
+
+         NewTrack.Sequence = new Sequence(Dict);
+         Header.AddChildObject(NewTrack.Sequence);
+         NewTrack.Track->Sequence = NewTrack.Sequence->InstanceUID;
+         NewTrack.Sequence->DataDefinition = Definition;
+
+         return NewTrack;
+       }
+
+      //
+      template <class PackageT>
+       TrackSet<TimecodeComponent>
+       CreateTimecodeTrack(OP1aHeader& Header, PackageT& Package,
+                           const MXF::Rational& EditRate, ui32_t TCFrameRate, ui64_t TCStart, const Dictionary*& Dict)
+       {
+         assert(Dict);
+         UL TCUL(Dict->ul(MDD_TimecodeDataDef));
+
+         TrackSet<TimecodeComponent> NewTrack = CreateTrackAndSequence<PackageT, TimecodeComponent>(Header, Package, "Timecode Track", EditRate, TCUL, 1, Dict);
+
+         NewTrack.Clip = new TimecodeComponent(Dict);
+         Header.AddChildObject(NewTrack.Clip);
+         NewTrack.Sequence->StructuralComponents.push_back(NewTrack.Clip->InstanceUID);
+         NewTrack.Clip->RoundedTimecodeBase = TCFrameRate;
+         NewTrack.Clip->StartTimecode = TCStart;
+         NewTrack.Clip->DataDefinition = TCUL;
+
+         return NewTrack;
+       }
+
+
+      // state machine for mxf writer
+      enum WriterState_t {
+       ST_BEGIN,   // waiting for Open()
+       ST_INIT,    // waiting for SetSourceStream()
+       ST_READY,   // ready to write frames
+       ST_RUNNING, // one or more frames written
+       ST_FINAL,   // index written, file closed
+      };
 
-      if ( KM_FAILURE(m_FooterPart.Lookup(FrameNum, TmpEntry)) )
+      // implementation of h__WriterState class Goto_* methods
+#define Goto_body(s1,s2)                       \
+      if ( m_State != (s1) ) {                 \
+       return RESULT_STATE;                    \
+      }                                                \
+      m_State = (s2);                          \
+      return RESULT_OK
+      //
+      class h__WriterState
       {
-        DefaultLogSink().Error("Frame value out of range: %u\n", FrameNum);
-        return RESULT_RANGE;
-      }
+       ASDCP_NO_COPY_CONSTRUCT(h__WriterState);
+
+      public:
+       WriterState_t m_State;
+      h__WriterState() : m_State(ST_BEGIN) {}
+       ~h__WriterState() {}
+
+       inline bool     Test_BEGIN()   { return m_State == ST_BEGIN; }
+       inline bool     Test_INIT()    { return m_State == ST_INIT; }
+       inline bool     Test_READY()   { return m_State == ST_READY;}
+       inline bool     Test_RUNNING() { return m_State == ST_RUNNING; }
+       inline bool     Test_FINAL()   { return m_State == ST_FINAL; }
+       inline Result_t Goto_INIT()    { Goto_body(ST_BEGIN,   ST_INIT); }
+       inline Result_t Goto_READY()   { Goto_body(ST_INIT,    ST_READY); }
+       inline Result_t Goto_RUNNING() { Goto_body(ST_READY,   ST_RUNNING); }
+       inline Result_t Goto_FINAL()   { Goto_body(ST_RUNNING, ST_FINAL); }
+      };
 
-      // get frame position, temporal offset, and key frame ofset
-      streamOffset = CurrentPartition.BodyOffset + TmpEntry.StreamOffset;
-      temporalOffset = TmpEntry.TemporalOffset;
-      keyFrameOffset = TmpEntry.KeyFrameOffset;
+      //
+      //
+      template <class HeaderType>
+       class TrackFileWriter
+      {
+       KM_NO_COPY_CONSTRUCT(TrackFileWriter);
+       TrackFileWriter();
 
-      return RESULT_OK;
-    }
+      public:
+       const Dictionary*  m_Dict;
+       Kumu::FileWriter   m_File;
+       ui32_t             m_HeaderSize;
+       HeaderType         m_HeaderPart;
+       RIP                m_RIP;
+       ui64_t             m_EssenceStart;
+
+       MaterialPackage*   m_MaterialPackage;
+       SourcePackage*     m_FilePackage;
+
+       FileDescriptor*    m_EssenceDescriptor;
+       std::list<InterchangeObject*> m_EssenceSubDescriptorList;
+
+       ui32_t             m_FramesWritten;
+       ui64_t             m_StreamOffset;
+       ASDCP::FrameBuffer m_CtFrameBuf;
+       h__WriterState     m_State;
+       WriterInfo         m_Info;
+
+       typedef std::list<ui64_t*> DurationElementList_t;
+       DurationElementList_t m_DurationUpdateList;
+
+      TrackFileWriter(const Dictionary& d) :
+       m_Dict(&d), m_HeaderPart(m_Dict), m_RIP(m_Dict),
+         m_HeaderSize(0), m_EssenceStart(0), m_EssenceDescriptor(0),
+         m_FramesWritten(0), m_StreamOffset(0)
+         {
+           default_md_object_init();
+         }
+
+       virtual ~TrackFileWriter() {}
+
+       const MXF::RIP& GetRIP() const { return m_RIP; }
+
+       void InitHeader()
+       {
+         assert(m_Dict);
+         assert(m_EssenceDescriptor);
+
+         m_HeaderPart.m_Primer.ClearTagList();
+         m_HeaderPart.m_Preface = new Preface(m_Dict);
+         m_HeaderPart.AddChildObject(m_HeaderPart.m_Preface);
+
+         // Set the Operational Pattern label -- we're just starting and have no RIP or index,
+         // so we tell the world by using OP1a
+         m_HeaderPart.m_Preface->OperationalPattern = UL(m_Dict->ul(MDD_OP1a));
+         m_HeaderPart.OperationalPattern = m_HeaderPart.m_Preface->OperationalPattern;
+
+         // Identification
+         Identification* Ident = new Identification(m_Dict);
+         m_HeaderPart.AddChildObject(Ident);
+         m_HeaderPart.m_Preface->Identifications.push_back(Ident->InstanceUID);
+
+         Kumu::GenRandomValue(Ident->ThisGenerationUID);
+         Ident->CompanyName = m_Info.CompanyName.c_str();
+         Ident->ProductName = m_Info.ProductName.c_str();
+         Ident->VersionString = m_Info.ProductVersion.c_str();
+         Ident->ProductUID.Set(m_Info.ProductUUID);
+         Ident->Platform = ASDCP_PLATFORM;
+
+         std::vector<int> version = version_split(Version());
+
+         Ident->ToolkitVersion.Major = version[0];
+         Ident->ToolkitVersion.Minor = version[1];
+         Ident->ToolkitVersion.Patch = version[2];
+         Ident->ToolkitVersion.Build = ASDCP_BUILD_NUMBER;
+         Ident->ToolkitVersion.Release = VersionType::RL_RELEASE;
+       }
 
        //
-       void     Close() {
+       void AddSourceClip(const MXF::Rational& EditRate, ui32_t TCFrameRate,
+                          const std::string& TrackName, const UL& EssenceUL,
+                          const UL& DataDefinition, const std::string& PackageLabel)
+       {
+         //
+         ContentStorage* Storage = new ContentStorage(m_Dict);
+         m_HeaderPart.AddChildObject(Storage);
+         m_HeaderPart.m_Preface->ContentStorage = Storage->InstanceUID;
+
+         EssenceContainerData* ECD = new EssenceContainerData(m_Dict);
+         m_HeaderPart.AddChildObject(ECD);
+         Storage->EssenceContainerData.push_back(ECD->InstanceUID);
+         ECD->IndexSID = 129;
+         ECD->BodySID = 1;
+
+         UUID assetUUID(m_Info.AssetUUID);
+         UMID SourcePackageUMID, MaterialPackageUMID;
+         SourcePackageUMID.MakeUMID(0x0f, assetUUID);
+         MaterialPackageUMID.MakeUMID(0x0f); // unidentified essence
+
+         //
+         // Material Package
+         //
+         m_MaterialPackage = new MaterialPackage(m_Dict);
+         m_MaterialPackage->Name = "AS-DCP Material Package";
+         m_MaterialPackage->PackageUID = MaterialPackageUMID;
+         m_HeaderPart.AddChildObject(m_MaterialPackage);
+         Storage->Packages.push_back(m_MaterialPackage->InstanceUID);
+
+         TrackSet<TimecodeComponent> MPTCTrack =
+           CreateTimecodeTrack<MaterialPackage>(m_HeaderPart, *m_MaterialPackage,
+                                                EditRate, TCFrameRate, 0, m_Dict);
+         m_DurationUpdateList.push_back(&(MPTCTrack.Sequence->Duration));
+         m_DurationUpdateList.push_back(&(MPTCTrack.Clip->Duration));
+
+         TrackSet<SourceClip> MPTrack =
+           CreateTrackAndSequence<MaterialPackage, SourceClip>(m_HeaderPart, *m_MaterialPackage,
+                                                               TrackName, EditRate, DataDefinition,
+                                                               2, m_Dict);
+         m_DurationUpdateList.push_back(&(MPTrack.Sequence->Duration));
+
+         MPTrack.Clip = new SourceClip(m_Dict);
+         m_HeaderPart.AddChildObject(MPTrack.Clip);
+         MPTrack.Sequence->StructuralComponents.push_back(MPTrack.Clip->InstanceUID);
+         MPTrack.Clip->DataDefinition = DataDefinition;
+         MPTrack.Clip->SourcePackageID = SourcePackageUMID;
+         MPTrack.Clip->SourceTrackID = 2;
+         m_DurationUpdateList.push_back(&(MPTrack.Clip->Duration));
+
+  
+         //
+         // File (Source) Package
+         //
+         m_FilePackage = new SourcePackage(m_Dict);
+         m_FilePackage->Name = PackageLabel.c_str();
+         m_FilePackage->PackageUID = SourcePackageUMID;
+         ECD->LinkedPackageUID = SourcePackageUMID;
+
+         m_HeaderPart.AddChildObject(m_FilePackage);
+         Storage->Packages.push_back(m_FilePackage->InstanceUID);
+
+         TrackSet<TimecodeComponent> FPTCTrack =
+           CreateTimecodeTrack<SourcePackage>(m_HeaderPart, *m_FilePackage,
+                                              EditRate, TCFrameRate,
+                                              ui64_C(3600) * TCFrameRate, m_Dict);
+         m_DurationUpdateList.push_back(&(FPTCTrack.Sequence->Duration));
+         m_DurationUpdateList.push_back(&(FPTCTrack.Clip->Duration));
+         TrackSet<SourceClip> FPTrack =
+           CreateTrackAndSequence<SourcePackage, SourceClip>(m_HeaderPart, *m_FilePackage,
+                                                             TrackName, EditRate, DataDefinition,
+                                                             2, m_Dict);
+         m_DurationUpdateList.push_back(&(FPTrack.Sequence->Duration));
+
+         // Consult ST 379:2004 Sec. 6.3, "Element to track relationship" to see where "12" comes from.
+         FPTrack.Track->TrackNumber = KM_i32_BE(Kumu::cp2i<ui32_t>((EssenceUL.Value() + 12)));
+
+         FPTrack.Clip = new SourceClip(m_Dict);
+         m_HeaderPart.AddChildObject(FPTrack.Clip);
+         FPTrack.Sequence->StructuralComponents.push_back(FPTrack.Clip->InstanceUID);
+         FPTrack.Clip->DataDefinition = DataDefinition;
+
+         // for now we do not allow setting this value, so all files will be 'original'
+         FPTrack.Clip->SourceTrackID = 0;
+         FPTrack.Clip->SourcePackageID = NilUMID;
+         m_DurationUpdateList.push_back(&(FPTrack.Clip->Duration));
+
+         m_EssenceDescriptor->LinkedTrackID = FPTrack.Track->TrackID;
+       }
+
+       //
+       void AddDMSegment(const MXF::Rational& EditRate, ui32_t TCFrameRate,
+                         const std::string& TrackName, const UL& DataDefinition,
+                         const std::string& PackageLabel)
+       {
+         //
+         ContentStorage* Storage = new ContentStorage(m_Dict);
+         m_HeaderPart.AddChildObject(Storage);
+         m_HeaderPart.m_Preface->ContentStorage = Storage->InstanceUID;
+
+         EssenceContainerData* ECD = new EssenceContainerData(m_Dict);
+         m_HeaderPart.AddChildObject(ECD);
+         Storage->EssenceContainerData.push_back(ECD->InstanceUID);
+         ECD->IndexSID = 129;
+         ECD->BodySID = 1;
+
+         UUID assetUUID(m_Info.AssetUUID);
+         UMID SourcePackageUMID, MaterialPackageUMID;
+         SourcePackageUMID.MakeUMID(0x0f, assetUUID);
+         MaterialPackageUMID.MakeUMID(0x0f); // unidentified essence
+
+         //
+         // Material Package
+         //
+         m_MaterialPackage = new MaterialPackage(m_Dict);
+         m_MaterialPackage->Name = "AS-DCP Material Package";
+         m_MaterialPackage->PackageUID = MaterialPackageUMID;
+         m_HeaderPart.AddChildObject(m_MaterialPackage);
+         Storage->Packages.push_back(m_MaterialPackage->InstanceUID);
+
+         TrackSet<TimecodeComponent> MPTCTrack =
+           CreateTimecodeTrack<MaterialPackage>(m_HeaderPart, *m_MaterialPackage,
+                                                EditRate, TCFrameRate, 0, m_Dict);
+         m_DurationUpdateList.push_back(&(MPTCTrack.Sequence->Duration));
+         m_DurationUpdateList.push_back(&(MPTCTrack.Clip->Duration));
+
+         TrackSet<DMSegment> MPTrack =
+           CreateTrackAndSequence<MaterialPackage, DMSegment>(m_HeaderPart, *m_MaterialPackage,
+                                                              TrackName, EditRate, DataDefinition,
+                                                              2, m_Dict);
+         m_DurationUpdateList.push_back(&(MPTrack.Sequence->Duration));
+
+         MPTrack.Clip = new DMSegment(m_Dict);
+         m_HeaderPart.AddChildObject(MPTrack.Clip);
+         MPTrack.Sequence->StructuralComponents.push_back(MPTrack.Clip->InstanceUID);
+         MPTrack.Clip->DataDefinition = DataDefinition;
+         //  MPTrack.Clip->SourcePackageID = SourcePackageUMID;
+         //  MPTrack.Clip->SourceTrackID = 2;
+         m_DurationUpdateList.push_back(&(MPTrack.Clip->Duration));
+
+  
+         //
+         // File (Source) Package
+         //
+         m_FilePackage = new SourcePackage(m_Dict);
+         m_FilePackage->Name = PackageLabel.c_str();
+         m_FilePackage->PackageUID = SourcePackageUMID;
+         ECD->LinkedPackageUID = SourcePackageUMID;
+
+         m_HeaderPart.AddChildObject(m_FilePackage);
+         Storage->Packages.push_back(m_FilePackage->InstanceUID);
+
+         TrackSet<TimecodeComponent> FPTCTrack =
+           CreateTimecodeTrack<SourcePackage>(m_HeaderPart, *m_FilePackage,
+                                              EditRate, TCFrameRate,
+                                              ui64_C(3600) * TCFrameRate, m_Dict);
+         m_DurationUpdateList.push_back(&(FPTCTrack.Sequence->Duration));
+         m_DurationUpdateList.push_back(&(FPTCTrack.Clip->Duration));
+
+         TrackSet<DMSegment> FPTrack =
+           CreateTrackAndSequence<SourcePackage, DMSegment>(m_HeaderPart, *m_FilePackage,
+                                                            TrackName, EditRate, DataDefinition,
+                                                            2, m_Dict);
+         m_DurationUpdateList.push_back(&(FPTrack.Sequence->Duration));
+
+         FPTrack.Clip = new DMSegment(m_Dict);
+         m_HeaderPart.AddChildObject(FPTrack.Clip);
+         FPTrack.Sequence->StructuralComponents.push_back(FPTrack.Clip->InstanceUID);
+         FPTrack.Clip->DataDefinition = DataDefinition;
+         FPTrack.Clip->EventComment = "D-Cinema Timed Text";
+
+         m_DurationUpdateList.push_back(&(FPTrack.Clip->Duration));
+         m_EssenceDescriptor->LinkedTrackID = FPTrack.Track->TrackID;
+       }
+
+       //
+       void AddEssenceDescriptor(const UL& WrappingUL)
+       {
+         //
+         // Essence Descriptor
+         //
+         m_EssenceDescriptor->EssenceContainer = WrappingUL;
+         m_HeaderPart.m_Preface->PrimaryPackage = m_FilePackage->InstanceUID;
+
+         //
+         // Essence Descriptors
+         //
+         assert(m_Dict);
+         UL GenericContainerUL(m_Dict->ul(MDD_GCMulti));
+         m_HeaderPart.EssenceContainers.push_back(GenericContainerUL);
+
+         if ( m_Info.EncryptedEssence )
+           {
+             UL CryptEssenceUL(m_Dict->ul(MDD_EncryptedContainerLabel));
+             m_HeaderPart.EssenceContainers.push_back(CryptEssenceUL);
+             m_HeaderPart.m_Preface->DMSchemes.push_back(UL(m_Dict->ul(MDD_CryptographicFrameworkLabel)));
+             AddDMScrypt(m_HeaderPart, *m_FilePackage, m_Info, WrappingUL, m_Dict);
+           }
+         else
+           {
+             m_HeaderPart.EssenceContainers.push_back(WrappingUL);
+           }
+
+         m_HeaderPart.m_Preface->EssenceContainers = m_HeaderPart.EssenceContainers;
+         m_HeaderPart.AddChildObject(m_EssenceDescriptor);
+
+         std::list<InterchangeObject*>::iterator sdli = m_EssenceSubDescriptorList.begin();
+         for ( ; sdli != m_EssenceSubDescriptorList.end(); sdli++ )
+           m_HeaderPart.AddChildObject(*sdli);
+
+         m_FilePackage->Descriptor = m_EssenceDescriptor->InstanceUID;
+       }
+
+       //      
+       Result_t WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf,const byte_t* EssenceUL, AESEncContext* Ctx, HMACContext* HMAC)
+       {
+         return Write_EKLV_Packet(m_File, *m_Dict, m_HeaderPart, m_Info, m_CtFrameBuf, m_FramesWritten,
+                                  m_StreamOffset, FrameBuf, EssenceUL, Ctx, HMAC);
+       }
+
+       //
+       void Close()
+       {
          m_File.Close();
        }
-      };
 
+      };
+      
   }/// namespace MXF
 
   //
-  class h__ASDCPReader : public MXF::TrackFileReader<OPAtomHeader, OPAtomIndexFooter>
+  class h__ASDCPReader : public MXF::TrackFileReader<OP1aHeader, OPAtomIndexFooter>
     {
       ASDCP_NO_COPY_CONSTRUCT(h__ASDCPReader);
       h__ASDCPReader();
@@ -311,106 +754,35 @@ namespace ASDCP
       virtual ~h__ASDCPReader();
 
       Result_t OpenMXFRead(const char* filename);
-      Result_t InitInfo();
-      Result_t InitMXFIndex();
       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,
                            i8_t& temporalOffset, i8_t& keyFrameOffset);
-
-    };
-
-
-  // state machine for mxf writer
-  enum WriterState_t {
-    ST_BEGIN,   // waiting for Open()
-    ST_INIT,    // waiting for SetSourceStream()
-    ST_READY,   // ready to write frames
-    ST_RUNNING, // one or more frames written
-    ST_FINAL,   // index written, file closed
-  };
-
-  // implementation of h__WriterState class Goto_* methods
-#define Goto_body(s1,s2) if ( m_State != (s1) ) \
-                           return RESULT_STATE; \
-                         m_State = (s2); \
-                         return RESULT_OK
-  //
-  class h__WriterState
-    {
-      ASDCP_NO_COPY_CONSTRUCT(h__WriterState);
-
-    public:
-      WriterState_t m_State;
-      h__WriterState() : m_State(ST_BEGIN) {}
-      ~h__WriterState() {}
-
-      inline bool     Test_BEGIN()   { return m_State == ST_BEGIN; }
-      inline bool     Test_INIT()    { return m_State == ST_INIT; }
-      inline bool     Test_READY()   { return m_State == ST_READY;}
-      inline bool     Test_RUNNING() { return m_State == ST_RUNNING; }
-      inline bool     Test_FINAL()   { return m_State == ST_FINAL; }
-      inline Result_t Goto_INIT()    { Goto_body(ST_BEGIN,   ST_INIT); }
-      inline Result_t Goto_READY()   { Goto_body(ST_INIT,    ST_READY); }
-      inline Result_t Goto_RUNNING() { Goto_body(ST_READY,   ST_RUNNING); }
-      inline Result_t Goto_FINAL()   { Goto_body(ST_RUNNING, ST_FINAL); }
     };
 
-  typedef std::list<ui64_t*> DurationElementList_t;
-
   //
-  class h__Writer
+  class h__ASDCPWriter : public MXF::TrackFileWriter<OP1aHeader>
     {
-      ASDCP_NO_COPY_CONSTRUCT(h__Writer);
-      h__Writer();
+      ASDCP_NO_COPY_CONSTRUCT(h__ASDCPWriter);
+      h__ASDCPWriter();
 
     public:
-      const Dictionary*  m_Dict;
-      Kumu::FileWriter   m_File;
-      ui32_t             m_HeaderSize;
-      OPAtomHeader       m_HeaderPart;
       Partition          m_BodyPart;
       OPAtomIndexFooter  m_FooterPart;
-      ui64_t             m_EssenceStart;
-
-      MaterialPackage*   m_MaterialPackage;
-      SourcePackage*     m_FilePackage;
-
-      FileDescriptor*    m_EssenceDescriptor;
-      std::list<InterchangeObject*> m_EssenceSubDescriptorList;
-
-      ui32_t             m_FramesWritten;
-      ui64_t             m_StreamOffset;
-      ASDCP::FrameBuffer m_CtFrameBuf;
-      h__WriterState     m_State;
-      WriterInfo         m_Info;
-      DurationElementList_t m_DurationUpdateList;
-
-      h__Writer(const Dictionary&);
-      virtual ~h__Writer();
-
-      void InitHeader();
-      void AddSourceClip(const MXF::Rational& EditRate, ui32_t TCFrameRate,
-                        const std::string& TrackName, const UL& EssenceUL,
-                        const UL& DataDefinition, const std::string& PackageLabel);
-      void AddDMSegment(const MXF::Rational& EditRate, ui32_t TCFrameRate,
-                       const std::string& TrackName, const UL& DataDefinition,
-                       const std::string& PackageLabel);
-      void AddEssenceDescriptor(const UL& WrappingUL);
-      Result_t CreateBodyPart(const MXF::Rational& EditRate, ui32_t BytesPerEditUnit = 0);
 
-      // all the above for a single source clip
-      Result_t WriteMXFHeader(const std::string& PackageLabel, const UL& WrappingUL,
-                             const std::string& TrackName, const UL& EssenceUL,
-                             const UL& DataDefinition, const MXF::Rational& EditRate,
-                             ui32_t TCFrameRate, ui32_t BytesPerEditUnit = 0);
+      h__ASDCPWriter(const Dictionary&);
+      virtual ~h__ASDCPWriter();
 
-      Result_t WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf,
-                              const byte_t* EssenceUL, AESEncContext* Ctx, HMACContext* HMAC);
+      Result_t CreateBodyPart(const MXF::Rational& EditRate, ui32_t BytesPerEditUnit = 0);
 
-      Result_t WriteMXFFooter();
+      // all the above for a single source clip
+      Result_t WriteASDCPHeader(const std::string& PackageLabel, const UL& WrappingUL,
+                               const std::string& TrackName, const UL& EssenceUL,
+                               const UL& DataDefinition, const MXF::Rational& EditRate,
+                               ui32_t TCFrameRate, ui32_t BytesPerEditUnit = 0);
 
-   };
+      Result_t WriteASDCPFooter();
+    };
 
 
   // helper class for calculating Integrity Packs, used by WriteEKLVPacket() below.
index 1b9e558592688d4ea842c6fa52b6ce7f43529bbc..92b29d03ca103ab38fef04832a4dfd4baeced5ff 100755 (executable)
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2005-2012, John Hurst
+Copyright (c) 2005-2013, John Hurst
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -681,129 +681,66 @@ ASDCP::MXF::Preface::Dump(FILE* stream)
 //------------------------------------------------------------------------------------------
 //
 
-ASDCP::MXF::OPAtomHeader::OPAtomHeader(const Dictionary*& d) : Partition(d), m_Dict(d), m_RIP(d), m_Primer(d), m_Preface(0), m_HasRIP(false) {}
-ASDCP::MXF::OPAtomHeader::~OPAtomHeader() {}
+ASDCP::MXF::OP1aHeader::OP1aHeader(const Dictionary*& d) : Partition(d), m_Dict(d), m_Primer(d), m_Preface(0) {}
+ASDCP::MXF::OP1aHeader::~OP1aHeader() {}
 
 //
 ASDCP::Result_t
-ASDCP::MXF::OPAtomHeader::InitFromFile(const Kumu::FileReader& Reader)
+ASDCP::MXF::OP1aHeader::InitFromFile(const Kumu::FileReader& Reader)
 {
-  m_HasRIP = false;
-  Result_t result = SeekToRIP(Reader);
+  Result_t result = result = Partition::InitFromFile(Reader);
 
-  if ( ASDCP_SUCCESS(result) )
-    {
-      result = m_RIP.InitFromFile(Reader);
-      ui32_t test_s = m_RIP.PairArray.size();
+  if ( ASDCP_FAILURE(result) )
+    return result;
 
-      if ( ASDCP_FAILURE(result) )
-       {
-         DefaultLogSink().Error("File contains no RIP\n");
-         result = RESULT_OK;
-       }
-      else if ( test_s == 0 )
+  if ( m_Dict == &DefaultCompositeDict() )
+    {
+      // select more explicit dictionary if one is available
+      if ( OperationalPattern.ExactMatch(MXFInterop_OPAtom_Entry().ul) )
        {
-         DefaultLogSink().Error("RIP contains no Pairs.\n");
-         result = RESULT_FORMAT;
+         m_Dict = &DefaultInteropDict();
        }
-      else
+      else if ( OperationalPattern.ExactMatch(SMPTE_390_OPAtom_Entry().ul) )
        {
-         if ( test_s < 2 )
-           {
-             // OP-Atom states that there will be either two or three partitions:
-             // one closed header and one closed footer with an optional body
-             // SMPTE 429-5 files may have many partitions, see SMPTE 410M
-             DefaultLogSink().Warn("RIP count is less than 2: %u\n", test_s);
-           }
-
-         m_HasRIP = true;
-      
-         if ( m_RIP.PairArray.front().ByteOffset !=  0 )
-           {
-             DefaultLogSink().Error("First Partition in RIP is not at offset 0.\n");
-             result = RESULT_FORMAT;
-           }
+         m_Dict = &DefaultSMPTEDict();
        }
     }
-  else
-  {
-    DefaultLogSink().Error("OPAtomHeader::InitFromFile, SeekToRIP failed\n");
-  }
-
-  if ( ASDCP_SUCCESS(result) )
-    result = Reader.Seek(0);
-  else
-    DefaultLogSink().Error("OPAtomHeader::InitFromFile, Seek failed\n");
-
-  if ( ASDCP_SUCCESS(result) )
-    result = Partition::InitFromFile(Reader); // test UL and OP
-  else
-    DefaultLogSink().Error("OPAtomHeader::InitFromFile, Partition::InitFromFile failed\n");
-
-  if ( ASDCP_FAILURE(result) )
-    return result;
-
-  // is it really OP-Atom?
-  assert(m_Dict);
-  UL OPAtomUL(SMPTE_390_OPAtom_Entry().ul);
-  UL InteropOPAtomUL(MXFInterop_OPAtom_Entry().ul);
-
-  if ( OperationalPattern.ExactMatch(OPAtomUL) ) // SMPTE
-    {
-      if ( m_Dict == &DefaultCompositeDict() )
-       m_Dict = &DefaultSMPTEDict();
-    }
-  else if ( OperationalPattern.ExactMatch(InteropOPAtomUL) ) // Interop
-    {
-      if ( m_Dict == &DefaultCompositeDict() )
-       m_Dict = &DefaultInteropDict();
-    }
-  else
-    {
-      char strbuf[IdentBufferLen];
-      const MDDEntry* Entry = m_Dict->FindUL(OperationalPattern.Value());
-      if ( Entry == 0 )
-       DefaultLogSink().Warn("Operational pattern is not OP-Atom: %s\n",
-                             OperationalPattern.EncodeString(strbuf, IdentBufferLen));
-      else
-       DefaultLogSink().Warn("Operational pattern is not OP-Atom: %s\n", Entry->name);
-    }
 
   // slurp up the remainder of the header
   if ( HeaderByteCount < 1024 )
     DefaultLogSink().Warn("Improbably small HeaderByteCount value: %u\n", HeaderByteCount);
 
   assert (HeaderByteCount <= 0xFFFFFFFFL);
-  result = m_Buffer.Capacity((ui32_t) HeaderByteCount);
+  result = m_HeaderData.Capacity((ui32_t)HeaderByteCount);
 
   if ( ASDCP_SUCCESS(result) )
     {
       ui32_t read_count;
-      result = Reader.Read(m_Buffer.Data(), m_Buffer.Capacity(), &read_count);
+      result = Reader.Read(m_HeaderData.Data(), m_HeaderData.Capacity(), &read_count);
 
       if ( ASDCP_FAILURE(result) )
         {
-         DefaultLogSink().Error("OPAtomHeader::InitFromFile, Read failed\n");
+         DefaultLogSink().Error("OP1aHeader::InitFromFile, Read failed\n");
          return result;
         }
 
-      if ( read_count != m_Buffer.Capacity() )
+      if ( read_count != m_HeaderData.Capacity() )
        {
          DefaultLogSink().Error("Short read of OP-Atom header metadata; wanted %u, got %u\n",
-                                m_Buffer.Capacity(), read_count);
+                                m_HeaderData.Capacity(), read_count);
          return RESULT_KLV_CODING;
        }
     }
 
   if ( ASDCP_SUCCESS(result) )
-    result = InitFromBuffer(m_Buffer.RoData(), m_Buffer.Capacity());
+    result = InitFromBuffer(m_HeaderData.RoData(), m_HeaderData.Capacity());
 
   return result;
 }
 
 //
 ASDCP::Result_t
-ASDCP::MXF::OPAtomHeader::InitFromPartitionBuffer(const byte_t* p, ui32_t l)
+ASDCP::MXF::OP1aHeader::InitFromPartitionBuffer(const byte_t* p, ui32_t l)
 {
   Result_t result = KLVPacket::InitFromBuffer(p, l);
 
@@ -821,7 +758,7 @@ ASDCP::MXF::OPAtomHeader::InitFromPartitionBuffer(const byte_t* p, ui32_t l)
 
 //
 ASDCP::Result_t
-ASDCP::MXF::OPAtomHeader::InitFromBuffer(const byte_t* p, ui32_t l)
+ASDCP::MXF::OP1aHeader::InitFromBuffer(const byte_t* p, ui32_t l)
 {
   assert(m_Dict);
   Result_t result = RESULT_OK;
@@ -869,14 +806,14 @@ ASDCP::MXF::OPAtomHeader::InitFromBuffer(const byte_t* p, ui32_t l)
 }
 
 ASDCP::Result_t
-ASDCP::MXF::OPAtomHeader::GetMDObjectByID(const UUID& ObjectID, InterchangeObject** Object)
+ASDCP::MXF::OP1aHeader::GetMDObjectByID(const UUID& ObjectID, InterchangeObject** Object)
 {
   return m_PacketList->GetMDObjectByID(ObjectID, Object);
 }
 
 //
 ASDCP::Result_t
-ASDCP::MXF::OPAtomHeader::GetMDObjectByType(const byte_t* ObjectID, InterchangeObject** Object)
+ASDCP::MXF::OP1aHeader::GetMDObjectByType(const byte_t* ObjectID, InterchangeObject** Object)
 {
   InterchangeObject* TmpObject;
 
@@ -888,14 +825,14 @@ ASDCP::MXF::OPAtomHeader::GetMDObjectByType(const byte_t* ObjectID, InterchangeO
 
 //
 ASDCP::Result_t
-ASDCP::MXF::OPAtomHeader::GetMDObjectsByType(const byte_t* ObjectID, std::list<InterchangeObject*>& ObjectList)
+ASDCP::MXF::OP1aHeader::GetMDObjectsByType(const byte_t* ObjectID, std::list<InterchangeObject*>& ObjectList)
 {
   return m_PacketList->GetMDObjectsByType(ObjectID, ObjectList);
 }
 
 //
 ASDCP::MXF::Identification*
-ASDCP::MXF::OPAtomHeader::GetIdentification()
+ASDCP::MXF::OP1aHeader::GetIdentification()
 {
   InterchangeObject* Object;
 
@@ -907,7 +844,7 @@ ASDCP::MXF::OPAtomHeader::GetIdentification()
 
 //
 ASDCP::MXF::SourcePackage*
-ASDCP::MXF::OPAtomHeader::GetSourcePackage()
+ASDCP::MXF::OP1aHeader::GetSourcePackage()
 {
   InterchangeObject* Object;
 
@@ -917,13 +854,9 @@ ASDCP::MXF::OPAtomHeader::GetSourcePackage()
   return 0;
 }
 
-//
-ASDCP::MXF::RIP&
-ASDCP::MXF::OPAtomHeader::GetRIP() { return m_RIP; }
-
 //
 ASDCP::Result_t
-ASDCP::MXF::OPAtomHeader::WriteToFile(Kumu::FileWriter& Writer, ui32_t HeaderSize)
+ASDCP::MXF::OP1aHeader::WriteToFile(Kumu::FileWriter& Writer, ui32_t HeaderSize)
 {
   assert(m_Dict);
   if ( m_Preface == 0 )
@@ -1013,7 +946,7 @@ ASDCP::MXF::OPAtomHeader::WriteToFile(Kumu::FileWriter& Writer, ui32_t HeaderSiz
 
 //
 void
-ASDCP::MXF::OPAtomHeader::Dump(FILE* stream)
+ASDCP::MXF::OP1aHeader::Dump(FILE* stream)
 {
   if ( stream == 0 )
     stream = stderr;
@@ -1049,38 +982,38 @@ ASDCP::MXF::OPAtomIndexFooter::InitFromFile(const Kumu::FileReader& Reader)
 {
   Result_t result = Partition::InitFromFile(Reader); // test UL and OP
 
-       // slurp up the remainder of the footer
-       ui32_t read_count = 0;
+  // slurp up the remainder of the footer
+  ui32_t read_count = 0;
 
-       if ( ASDCP_SUCCESS(result) )
+  if ( ASDCP_SUCCESS(result) )
     {
-               assert (IndexByteCount <= 0xFFFFFFFFL);
-               // At this point, m_Buffer may not have been initialized
-               // so it's capacity is zero and data pointer is NULL
-               // However, if IndexByteCount is zero then the capacity
-               // doesn't change and the data pointer is not set.
-               result = m_Buffer.Capacity((ui32_t) IndexByteCount);
+      assert (IndexByteCount <= 0xFFFFFFFFL);
+      // At this point, m_FooterData may not have been initialized
+      // so it's capacity is zero and data pointer is NULL
+      // However, if IndexByteCount is zero then the capacity
+      // doesn't change and the data pointer is not set.
+      result = m_FooterData.Capacity((ui32_t) IndexByteCount);
     }
 
-       if ( ASDCP_SUCCESS(result) && m_Buffer.Data() )
-               result = Reader.Read(m_Buffer.Data(), m_Buffer.Capacity(), &read_count);
+  if ( ASDCP_SUCCESS(result) && m_FooterData.Data() )
+    result = Reader.Read(m_FooterData.Data(), m_FooterData.Capacity(), &read_count);
 
-  if ( ASDCP_SUCCESS(result) && read_count != m_Buffer.Capacity() )
+  if ( ASDCP_SUCCESS(result) && read_count != m_FooterData.Capacity() )
     {
       DefaultLogSink().Error("Short read of footer partition: got %u, expecting %u\n",
-                            read_count, m_Buffer.Capacity());
+                            read_count, m_FooterData.Capacity());
+      return RESULT_FAIL;
+    }
+  else if( ASDCP_SUCCESS(result) && !m_FooterData.Data() )
+    {
+      DefaultLogSink().Error( "Buffer for footer partition not created: IndexByteCount = %u\n",
+                             IndexByteCount );
       return RESULT_FAIL;
     }
-       else if( ASDCP_SUCCESS(result) && !m_Buffer.Data() )
-       {
-               DefaultLogSink().Error( "Buffer for footer partition not created: IndexByteCount = %u\n",
-                                                               IndexByteCount );
-               return RESULT_FAIL;
-       }
 
   if ( ASDCP_SUCCESS(result) )
-    result = InitFromBuffer(m_Buffer.RoData(), m_Buffer.Capacity());
-
+    result = InitFromBuffer(m_FooterData.RoData(), m_FooterData.Capacity());
+  
   return result;
 }
 
index 9c7b592f982d9858807545fa31df39ad882399b7..50574c29b700dcff39c2ea1e81ac69459618de7a 100755 (executable)
--- a/src/MXF.h
+++ b/src/MXF.h
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2005-2012, John Hurst
+Copyright (c) 2005-2013, John Hurst
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -350,21 +350,19 @@ namespace ASDCP
       class SourcePackage;
 
       //
-      class OPAtomHeader : public Partition
+      class OP1aHeader : public Partition
        {
-         ASDCP_NO_COPY_CONSTRUCT(OPAtomHeader);
-         OPAtomHeader();
+         Kumu::ByteString m_HeaderData;
+         ASDCP_NO_COPY_CONSTRUCT(OP1aHeader);
+         OP1aHeader();
 
        public:
-         const Dictionary*&   m_Dict;
-         ASDCP::MXF::RIP     m_RIP;
+         const Dictionary*&  m_Dict;
          ASDCP::MXF::Primer  m_Primer;
          Preface*            m_Preface;
-         ASDCP::FrameBuffer  m_Buffer;
-         bool                m_HasRIP;
 
-         OPAtomHeader(const Dictionary*&);
-         virtual ~OPAtomHeader();
+         OP1aHeader(const Dictionary*&);
+         virtual ~OP1aHeader();
          virtual Result_t InitFromFile(const Kumu::FileReader& Reader);
          virtual Result_t InitFromPartitionBuffer(const byte_t* p, ui32_t l);
          virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l);
@@ -373,7 +371,6 @@ namespace ASDCP
          virtual Result_t GetMDObjectByID(const UUID&, InterchangeObject** = 0);
          virtual Result_t GetMDObjectByType(const byte_t*, InterchangeObject** = 0);
          virtual Result_t GetMDObjectsByType(const byte_t* ObjectID, std::list<InterchangeObject*>& ObjectList);
-         virtual ASDCP::MXF::RIP& GetRIP();
          Identification*  GetIdentification();
          SourcePackage*   GetSourcePackage();
        };
@@ -381,8 +378,8 @@ namespace ASDCP
       //
       class OPAtomIndexFooter : public Partition
        {
+         Kumu::ByteString    m_FooterData;
          IndexTableSegment*  m_CurrentSegment;
-         ASDCP::FrameBuffer  m_Buffer;
          ui32_t              m_BytesPerEditUnit;
          Rational            m_EditRate;
          ui32_t              m_BodySID;
@@ -413,6 +410,7 @@ namespace ASDCP
          virtual void     SetIndexParamsVBR(IPrimerLookup* lookup, const Rational& Rate, Kumu::fpos_t offset);
        };
 
+
     } // namespace MXF
 } // namespace ASDCP
 
index fdbf3c481f9825a0d9a83219d15cf8eafc4a51d1..b7f75ef49f1643ecb360e3149564d8642a293ece 100644 (file)
@@ -1,7 +1,8 @@
 ## Makefile.am -- Process this file with automake to produce Makefile.in
 #
 # $Id$
-# Copyright (c) 2007-2011 John Hurst. All rights reserved.
+#
+# Copyright (c) 2007-2013 John Hurst. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions
@@ -25,6 +26,8 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+ACLOCAL_AMFLAGS = -I m4
+
 # Allow for configure's changes to this makefile
 AM_CPPFLAGS =
 AM_LDFLAGS =
@@ -63,12 +66,22 @@ include_HEADERS += \
        Wav.h \
        PCMParserList.h \
        AtmosSyncChannel_Generator.h
+
 nodist_include_HEADERS = TimedText_Transform.h
 endif
 
+if AS_02_USE
+include_HEADERS                += AS_02.h
+endif
+
 # list of the libraries to build and install
+
 lib_LTLIBRARIES = libkumu.la libasdcp.la
 
+if AS_02_USE
+lib_LTLIBRARIES                += libas02.la
+endif
+
 # sources for kumu library
 libkumu_la_SOURCES = KM_error.h KM_fileio.cpp KM_fileio.h KM_log.cpp KM_log.h \
                KM_memio.h KM_mutex.h KM_platform.h KM_prng.cpp KM_prng.h KM_util.cpp \
@@ -99,7 +112,6 @@ libasdcp_la_SOURCES = MPEG2_Parser.cpp MPEG.cpp JP2K_Codestream_Parser.cpp \
                SyncEncoder.c SyncEncoder.h SyncCommon.h CRC16.c CRC16.h \
                UUIDInformation.c UUIDInformation.h
 
-
 if DEV_HEADERS
 nodist_libasdcp_la_SOURCES += TimedText_Transform.h TimedText_Transform.cpp
 endif
@@ -109,6 +121,22 @@ libasdcp_la_LDFLAGS = -release @VERSION@
 libasdcp_la_LIBADD = libkumu.la
 libasdcp_la_CPPFLAGS = -DASDCP_PLATFORM=\"@host@\"
 
+if AS_02_USE
+# sources for as-02 library
+libas02_la_SOURCES     = \
+       AS_02.h \
+       AS_02_MXF.cpp \
+       AS_02_JP2K.cpp \
+       AS_02_PCM.cpp \
+       h__02_Reader.cpp \
+       h__02_Writer.cpp \
+       AS_02_internal.h
+
+libas02_la_LDFLAGS = -release @VERSION@
+libas02_la_LIBADD = libasdcp.la libkumu.la
+libas02_la_CPPFLAGS = -DASDCP_PLATFORM=\"@host@\"
+endif
+
 # Python extension
 if PYTHON_USE
 lib_LTLIBRARIES += libpyasdcp.la
@@ -154,6 +182,13 @@ bin_PROGRAMS = \
        j2c-test blackwave klvwalk wavesplit \
        kmfilegen kmrandgen kmuuidgen
 
+if AS_02_USE
+bin_PROGRAMS += \
+       as-02-wrap \
+       as-02-unwrap
+endif
+
+
 # sources and linkage for CLI utilities
 asdcp_test_SOURCES = asdcp-test.cpp
 asdcp_test_LDADD = libasdcp.la
@@ -191,6 +226,14 @@ wavesplit_LDADD = libasdcp.la
 j2c_test_SOURCES = j2c-test.cpp
 j2c_test_LDADD = libasdcp.la
 
+if AS_02_USE
+as_02_wrap_SOURCES = as-02-wrap.cpp
+as_02_wrap_LDADD = libas02.la
+
+as_02_unwrap_SOURCES = as-02-unwrap.cpp
+as_02_unwrap_LDADD = libas02.la
+endif
+
 # list of programs that need to be compiled for use in test suite
 check_PROGRAMS = asdcp-mem-test path-test \
        fips-186-rng-test asdcp-version
index b6a2cdd145c5217da51fa081610818824dd2b61d..e6981bc22831ed1d92c98584997178eeba8811cb 100755 (executable)
@@ -407,18 +407,15 @@ write_JP2K_file(CommandOptions& Options)
 
       while ( ASDCP_SUCCESS(result) && duration++ < Options.duration )
        {
-         if ( duration == 1 )
+         result = Parser.ReadFrame(FrameBuffer);
+         
+         if ( ASDCP_SUCCESS(result) )
            {
-             result = Parser.ReadFrame(FrameBuffer);
-
-             if ( ASDCP_SUCCESS(result) )
-               {
-                 if ( Options.verbose_flag )
-                   FrameBuffer.Dump(stderr, Options.fb_dump_size);
-                 
-                 if ( Options.encrypt_header_flag )
-                   FrameBuffer.PlaintextOffset(0);
-               }
+             if ( Options.verbose_flag )
+               FrameBuffer.Dump(stderr, Options.fb_dump_size);
+             
+             if ( Options.encrypt_header_flag )
+               FrameBuffer.PlaintextOffset(0);
            }
 
          if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag )
@@ -527,8 +524,8 @@ write_PCM_file(CommandOptions& Options)
       if ( ASDCP_SUCCESS(result) && Options.channel_assignment.HasValue() )
        {
          MXF::WaveAudioDescriptor *descriptor = 0;
-         Writer.OPAtomHeader().GetMDObjectByType(DefaultSMPTEDict().ul(MDD_WaveAudioDescriptor),
-                                                 reinterpret_cast<MXF::InterchangeObject**>(&descriptor));
+         Writer.OP1aHeader().GetMDObjectByType(DefaultSMPTEDict().ul(MDD_WaveAudioDescriptor),
+                                               reinterpret_cast<MXF::InterchangeObject**>(&descriptor));
          descriptor->ChannelAssignment = Options.channel_assignment;
        }
     }
index cbc43811b4234b797d3b20d6f19d13184f304603..a8746bf177686a58c5d247b124641c1dcd24c2c3 100755 (executable)
@@ -355,8 +355,8 @@ public:
     const Dictionary& Dict = DefaultCompositeDict();
     MXF::RGBAEssenceDescriptor *descriptor = 0;
 
-    Result_t result = m_Reader.OPAtomHeader().GetMDObjectByType(DefaultCompositeDict().ul(MDD_RGBAEssenceDescriptor),
-                                                               reinterpret_cast<MXF::InterchangeObject**>(&descriptor));
+    Result_t result = m_Reader.OP1aHeader().GetMDObjectByType(DefaultCompositeDict().ul(MDD_RGBAEssenceDescriptor),
+                                                             reinterpret_cast<MXF::InterchangeObject**>(&descriptor));
 
     if ( KM_SUCCESS(result) )
       m_PictureEssenceCoding = descriptor->PictureEssenceCoding;
@@ -511,8 +511,8 @@ public:
     const Dictionary& Dict = DefaultCompositeDict();
     MXF::WaveAudioDescriptor *descriptor = 0;
 
-    Result_t result = m_Reader.OPAtomHeader().GetMDObjectByType(DefaultCompositeDict().ul(MDD_WaveAudioDescriptor),
-                                                               reinterpret_cast<MXF::InterchangeObject**>(&descriptor));
+    Result_t result = m_Reader.OP1aHeader().GetMDObjectByType(DefaultCompositeDict().ul(MDD_WaveAudioDescriptor),
+                                                             reinterpret_cast<MXF::InterchangeObject**>(&descriptor));
 
     if ( KM_SUCCESS(result) )
       {
@@ -631,7 +631,7 @@ show_file_info(CommandOptions& Options)
       fprintf(stderr, "File is not AS-DCP: %s\n", Options.filenames.front().c_str());
       Kumu::FileReader   Reader;
       const Dictionary* Dict = &DefaultCompositeDict();
-      MXF::OPAtomHeader TestHeader(Dict);
+      MXF::OP1aHeader TestHeader(Dict);
 
       result = Reader.OpenRead(Options.filenames.front().c_str());
 
index 56bc5ab5b8cd4c9ec6d91ac6979836350bcc8a45..13e30365211496dc4cdaad76214fddf9e98c02d1 100755 (executable)
@@ -1802,13 +1802,13 @@ show_file_info(CommandOptions& Options)
        {
          const Dictionary* Dict = &DefaultCompositeDict();
          PCM::MXFReader Reader;
-         MXF::OPAtomHeader OPAtomHeader(Dict);
+         MXF::OP1aHeader Header(Dict);
          MXF::WaveAudioDescriptor *descriptor = 0;
 
          result = Reader.OpenRead(Options.filenames[0]);
 
          if ( ASDCP_SUCCESS(result) )
-           result = Reader.OPAtomHeader().GetMDObjectByType(Dict->ul(MDD_WaveAudioDescriptor), reinterpret_cast<MXF::InterchangeObject**>(&descriptor));
+           result = Reader.OP1aHeader().GetMDObjectByType(Dict->ul(MDD_WaveAudioDescriptor), reinterpret_cast<MXF::InterchangeObject**>(&descriptor));
 
          if ( ASDCP_SUCCESS(result) )
            {
@@ -1844,7 +1844,7 @@ show_file_info(CommandOptions& Options)
       fprintf(stderr, "File is not AS-DCP: %s\n", Options.filenames[0]);
       Kumu::FileReader   Reader;
       const Dictionary* Dict = &DefaultCompositeDict();
-      MXF::OPAtomHeader TestHeader(Dict);
+      MXF::OP1aHeader TestHeader(Dict);
 
       result = Reader.OpenRead(Options.filenames[0]);
 
index 12435ce341062abd91adb4b881ac4efb66dc5b03..4439f7efc200c8a2af2b4479c1783b354d812733 100755 (executable)
@@ -686,8 +686,8 @@ write_JP2K_S_file(CommandOptions& Options)
       if ( ASDCP_SUCCESS(result) && Options.picture_coding.HasValue() )
        {
          MXF::RGBAEssenceDescriptor *descriptor = 0;
-         Writer.OPAtomHeader().GetMDObjectByType(DefaultSMPTEDict().ul(MDD_RGBAEssenceDescriptor),
-                                                 reinterpret_cast<MXF::InterchangeObject**>(&descriptor));
+         Writer.OP1aHeader().GetMDObjectByType(DefaultSMPTEDict().ul(MDD_RGBAEssenceDescriptor),
+                                               reinterpret_cast<MXF::InterchangeObject**>(&descriptor));
          descriptor->PictureEssenceCoding = Options.picture_coding;
        }
     }
@@ -821,8 +821,8 @@ write_JP2K_file(CommandOptions& Options)
       if ( ASDCP_SUCCESS(result) && Options.picture_coding.HasValue() )
        {
          MXF::RGBAEssenceDescriptor *descriptor = 0;
-         Writer.OPAtomHeader().GetMDObjectByType(DefaultSMPTEDict().ul(MDD_RGBAEssenceDescriptor),
-                                                 reinterpret_cast<MXF::InterchangeObject**>(&descriptor));
+         Writer.OP1aHeader().GetMDObjectByType(DefaultSMPTEDict().ul(MDD_RGBAEssenceDescriptor),
+                                               reinterpret_cast<MXF::InterchangeObject**>(&descriptor));
          descriptor->PictureEssenceCoding = Options.picture_coding;
        }
     }
@@ -961,8 +961,8 @@ write_PCM_file(CommandOptions& Options)
       if ( ASDCP_SUCCESS(result) && Options.channel_assignment.HasValue() )
        {
          MXF::WaveAudioDescriptor *descriptor = 0;
-         Writer.OPAtomHeader().GetMDObjectByType(DefaultSMPTEDict().ul(MDD_WaveAudioDescriptor),
-                                                 reinterpret_cast<MXF::InterchangeObject**>(&descriptor));
+         Writer.OP1aHeader().GetMDObjectByType(DefaultSMPTEDict().ul(MDD_WaveAudioDescriptor),
+                                               reinterpret_cast<MXF::InterchangeObject**>(&descriptor));
          descriptor->ChannelAssignment = Options.channel_assignment;
        }
     }
index 2a21165ecf51a1896139c427f12890477d277813..261b526a193f60ab46ceb42b6a8c2d99c7b0672d 100644 (file)
@@ -1,5 +1,5 @@
 /*
-  Copyright (c) 2011-2012, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst
+  Copyright (c) 2011-2013, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst
   All rights reserved.
 
   Redistribution and use in source and binary forms, with or without
 using namespace ASDCP;
 using namespace ASDCP::MXF;
 
+
+static Kumu::Mutex sg_DefaultMDInitLock;
+static bool        sg_DefaultMDTypesInit = false;
+static const ASDCP::Dictionary *sg_dict;
+
+//
+void
+AS_02::default_md_object_init()
+{
+  if ( ! sg_DefaultMDTypesInit )
+    {
+      Kumu::AutoMutex BlockLock(sg_DefaultMDInitLock);
+
+      if ( ! sg_DefaultMDTypesInit )
+       {
+         sg_dict = &DefaultSMPTEDict();
+         g_AS02IndexReader = new AS_02::MXF::AS02IndexReader(sg_dict);
+         sg_DefaultMDTypesInit = true;
+       }
+    }
+}
+
+
+
+
+AS_02::h__AS02Reader::h__AS02Reader(const ASDCP::Dictionary& d) : ASDCP::MXF::TrackFileReader<ASDCP::MXF::OP1aHeader, AS_02::MXF::AS02IndexReader>(d) {}
+AS_02::h__AS02Reader::~h__AS02Reader() {}
+
+
+#if 0
 //
-AS_02::h__Reader::h__Reader(const Dictionary& d) :
-  m_HeaderPart(m_Dict), m_FooterPart(m_Dict), m_Dict(&d), m_EssenceStart(0)
+AS_02::h__AS02Reader::h__Reader(const Dictionary& d) :
+  m_HeaderPart(m_Dict), m_IndexAccess(m_Dict), m_Dict(&d), m_EssenceStart(0)
 {
   m_pCurrentIndexPartition = 0;
   //// start_pos = 0;
 }
 
-AS_02::h__Reader::~h__Reader()
+AS_02::h__AS02Reader::~h__Reader()
 {
   std::vector<Partition*>::iterator bli = m_BodyPartList.begin();
   for ( ; bli != m_BodyPartList.end(); bli++ ){
@@ -51,78 +81,11 @@ AS_02::h__Reader::~h__Reader()
   }
   Close();
 }
-
-void
-AS_02::h__Reader::Close()
-{
-  m_File.Close();
-}
+#endif
 
 //------------------------------------------------------------------------------------------
 //
 
-//
-Result_t
-AS_02::h__Reader::InitInfo()
-{
-  assert(m_Dict);
-  InterchangeObject* Object;
-
-  UL OPAtomUL(SMPTE_390_OPAtom_Entry().ul);
-  UL Interop_OPAtomUL(MXFInterop_OPAtom_Entry().ul);
-  m_Info.LabelSetType = LS_MXF_SMPTE;
-
-  // Identification
-  Result_t result = m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(Identification), &Object);
-
-  if( ASDCP_SUCCESS(result) )
-    MD_to_WriterInfo((Identification*)Object, m_Info);
-
-  // SourcePackage
-  if( ASDCP_SUCCESS(result) )
-    result = m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(SourcePackage), &Object);
-
-  if( ASDCP_SUCCESS(result) )
-    {
-      SourcePackage* SP = (SourcePackage*)Object;
-      memcpy(m_Info.AssetUUID, SP->PackageUID.Value() + 16, UUIDlen);
-    }
-
-  // optional CryptographicContext
-  if( ASDCP_SUCCESS(result) )
-    {
-      Result_t cr_result = m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(CryptographicContext), &Object);
-
-      if( ASDCP_SUCCESS(cr_result) )
-       MD_to_CryptoInfo((CryptographicContext*)Object, m_Info, *m_Dict);
-    }
-
-  return result;
-}
-
-// standard method of populating the in-memory index
-Result_t
-AS_02::h__Reader::InitMXFIndex()
-{
-  if ( ! m_File.IsOpen() )
-    return RESULT_INIT;
-
-  Result_t result = m_File.Seek(m_HeaderPart.FooterPartition);
-
-  if ( ASDCP_SUCCESS(result) )
-    {
-      m_FooterPart.m_Lookup = &m_HeaderPart.m_Primer;
-      //Footer don't need to be initialized because there is no index table in the footer
-      //result = m_FooterPart.InitFromFile(m_File);
-    }
-
-  if ( ASDCP_SUCCESS(result) )
-    m_File.Seek(m_EssenceStart);
-
-  return result;
-}
-
-
 //
 // end h__02_Reader.cpp
 //
index 919e89a687ef21f5925bca8e4163023bdfc38445..cf68f3a99d51a85058b96846cc2711cce0e76beb 100644 (file)
@@ -1,5 +1,5 @@
 /*
-  Copyright (c) 2011-2012, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst
+  Copyright (c) 2011-2013, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst
   All rights reserved.
 
   Redistribution and use in source and binary forms, with or without
 using namespace ASDCP;
 using namespace ASDCP::MXF;
 
-// a magic number identifying asdcplib
-#ifndef ASDCP_BUILD_NUMBER
-#define ASDCP_BUILD_NUMBER 0x6A68
-#endif
 
 //
-AS_02::h__Writer::h__Writer(const Dictionary& d) :
-  m_HeaderPart(m_Dict), m_FooterPart(m_Dict), m_Dict(&d),
-  m_HeaderSize(0), m_EssenceStart(0),
-  m_EssenceDescriptor(0), m_FramesWritten(0),
-  m_StreamOffset(0), m_BodyOffset(0),
-  m_CurrentBodySID(0), m_CurrentIndexSID(0),
-  m_PartitionSpace(60), m_IndexStrategy(AS_02::IS_FOLLOW)
-{
-}
-
-AS_02::h__Writer::~h__Writer()
-{
-  while (! m_BodyPartList.empty() )
-    {
-      delete m_BodyPartList.back();
-      m_BodyPartList.pop_back();
-    }
-}
-
-//
-void
-AS_02::h__Writer::InitHeader()
-{
-  assert(m_Dict);
-  assert(m_EssenceDescriptor);
-
-  m_HeaderPart.m_Primer.ClearTagList();
-  m_HeaderPart.m_Preface = new Preface(m_Dict);
-  m_HeaderPart.AddChildObject(m_HeaderPart.m_Preface);
-
-  // Set the Operational Pattern label -- we're just starting and have no RIP or index,
-  // so we tell the world by using OP1a
-  m_HeaderPart.m_Preface->OperationalPattern = UL(m_Dict->ul(MDD_OP1a));
-  m_HeaderPart.OperationalPattern = m_HeaderPart.m_Preface->OperationalPattern;
-
-  //always more than 3 partition in AS-02; essence is not permitted to be existent in the header
-  m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(0, 0)); // no essence in header
-
-  //
-  // Identification
-  //
-  Identification* Ident = new Identification(m_Dict);
-  m_HeaderPart.AddChildObject(Ident);
-  m_HeaderPart.m_Preface->Identifications.push_back(Ident->InstanceUID);
-
-  Kumu::GenRandomValue(Ident->ThisGenerationUID);
-  Ident->CompanyName = m_Info.CompanyName.c_str();
-  Ident->ProductName = m_Info.ProductName.c_str();
-  Ident->VersionString = m_Info.ProductVersion.c_str();
-  Ident->ProductUID.Set(m_Info.ProductUUID);
-  Ident->Platform = ASDCP_PLATFORM;
-
-  std::vector<int> version = version_split(Version());
-
-  Ident->ToolkitVersion.Major = version[0];
-  Ident->ToolkitVersion.Minor = version[1];
-  Ident->ToolkitVersion.Patch = version[2];
-  Ident->ToolkitVersion.Build = ASDCP_BUILD_NUMBER;
-  Ident->ToolkitVersion.Release = VersionType::RL_RELEASE;
-}
-
-template <class ClipT>
-struct TrackSet
-{
-  MXF::Track*    Track;
-  MXF::Sequence* Sequence;
-  ClipT*         Clip;
-
-  TrackSet() : Track(0), Sequence(0), Clip(0) {}
-};
-
-//
-template <class PackageT, class ClipT>
-TrackSet<ClipT>
-CreateTrackAndSequence(OPAtomHeader& Header, PackageT& Package, const std::string TrackName,
-                      const MXF::Rational& EditRate, const UL& Definition, ui32_t TrackID, const Dictionary*& Dict)
-{
-  TrackSet<ClipT> NewTrack;
-
-  NewTrack.Track = new Track(Dict);
-  Header.AddChildObject(NewTrack.Track);
-  NewTrack.Track->EditRate = EditRate;
-  Package.Tracks.push_back(NewTrack.Track->InstanceUID);
-  NewTrack.Track->TrackID = TrackID;
-  NewTrack.Track->TrackName = TrackName.c_str();
-
-  NewTrack.Sequence = new Sequence(Dict);
-  Header.AddChildObject(NewTrack.Sequence);
-  NewTrack.Track->Sequence = NewTrack.Sequence->InstanceUID;
-  NewTrack.Sequence->DataDefinition = Definition;
-
-  return NewTrack;
-}
-
-//
-template <class PackageT>
-TrackSet<TimecodeComponent>
-CreateTimecodeTrack(OPAtomHeader& Header, PackageT& Package,
-                   const MXF::Rational& EditRate, ui32_t TCFrameRate, ui64_t TCStart, const Dictionary*& Dict)
-{
-  assert(Dict);
-  UL TCUL(Dict->ul(MDD_TimecodeDataDef));
-
-  TrackSet<TimecodeComponent> NewTrack = CreateTrackAndSequence<PackageT, TimecodeComponent>(Header, Package, "Timecode Track", EditRate, TCUL, 1, Dict);
-
-  NewTrack.Clip = new TimecodeComponent(Dict);
-  Header.AddChildObject(NewTrack.Clip);
-  NewTrack.Sequence->StructuralComponents.push_back(NewTrack.Clip->InstanceUID);
-  NewTrack.Clip->RoundedTimecodeBase = TCFrameRate;
-  NewTrack.Clip->StartTimecode = TCStart;
-  NewTrack.Clip->DataDefinition = TCUL;
-
-  return NewTrack;
-}
-
-
-//
-void
-AS_02::h__Writer::AddSourceClip(const ASDCP::MXF::Rational& EditRate, ui32_t TCFrameRate,
-                               const std::string& TrackName, const UL& EssenceUL,
-                               const UL& DataDefinition, const std::string& PackageLabel)
-{
-  //
-  ContentStorage* Storage = new ContentStorage(m_Dict);
-  m_HeaderPart.AddChildObject(Storage);
-  m_HeaderPart.m_Preface->ContentStorage = Storage->InstanceUID;
-
-  EssenceContainerData* ECD = new EssenceContainerData(m_Dict);
-  m_HeaderPart.AddChildObject(ECD);
-  Storage->EssenceContainerData.push_back(ECD->InstanceUID);
-  ECD->IndexSID = 129;
-  ECD->BodySID = 1;
-
-  UUID assetUUID(m_Info.AssetUUID);
-  UMID SourcePackageUMID, MaterialPackageUMID;
-  SourcePackageUMID.MakeUMID(0x0f, assetUUID);
-  MaterialPackageUMID.MakeUMID(0x0f); // unidentified essence
-
-  //
-  // Material Package
-  //
-  m_MaterialPackage = new MaterialPackage(m_Dict);
-  m_MaterialPackage->Name = "AS_02 Material Package";
-  m_MaterialPackage->PackageUID = MaterialPackageUMID;
-  m_HeaderPart.AddChildObject(m_MaterialPackage);
-  Storage->Packages.push_back(m_MaterialPackage->InstanceUID);
-
-  TrackSet<TimecodeComponent> MPTCTrack =
-    CreateTimecodeTrack<MaterialPackage>(m_HeaderPart, *m_MaterialPackage,
-                                        EditRate, TCFrameRate, 0, m_Dict);
-  m_DurationUpdateList.push_back(&(MPTCTrack.Sequence->Duration));
-  m_DurationUpdateList.push_back(&(MPTCTrack.Clip->Duration));
-
-  TrackSet<SourceClip> MPTrack =
-    CreateTrackAndSequence<MaterialPackage, SourceClip>(m_HeaderPart, *m_MaterialPackage,
-                                                       TrackName, EditRate, DataDefinition,
-                                                       2, m_Dict);
-  m_DurationUpdateList.push_back(&(MPTrack.Sequence->Duration));
-
-  MPTrack.Clip = new SourceClip(m_Dict);
-  m_HeaderPart.AddChildObject(MPTrack.Clip);
-  MPTrack.Sequence->StructuralComponents.push_back(MPTrack.Clip->InstanceUID);
-  MPTrack.Clip->DataDefinition = DataDefinition;
-  MPTrack.Clip->SourcePackageID = SourcePackageUMID;
-  MPTrack.Clip->SourceTrackID = 2;
-  m_DurationUpdateList.push_back(&(MPTrack.Clip->Duration));
-
-
-  //
-  // File (Source) Package
-  //
-  m_FilePackage = new SourcePackage(m_Dict);
-  m_FilePackage->Name = PackageLabel.c_str();
-  m_FilePackage->PackageUID = SourcePackageUMID;
-  ECD->LinkedPackageUID = SourcePackageUMID;
-
-  m_HeaderPart.AddChildObject(m_FilePackage);
-  Storage->Packages.push_back(m_FilePackage->InstanceUID);
-
-  TrackSet<TimecodeComponent> FPTCTrack =
-    CreateTimecodeTrack<SourcePackage>(m_HeaderPart, *m_FilePackage,
-                                      EditRate, TCFrameRate,
-                                      ui64_C(3600) * TCFrameRate, m_Dict);
-  m_DurationUpdateList.push_back(&(FPTCTrack.Sequence->Duration));
-  m_DurationUpdateList.push_back(&(FPTCTrack.Clip->Duration));
-  TrackSet<SourceClip> FPTrack =
-    CreateTrackAndSequence<SourcePackage, SourceClip>(m_HeaderPart, *m_FilePackage,
-                                                     TrackName, EditRate, DataDefinition,
-                                                     2, m_Dict);
-  m_DurationUpdateList.push_back(&(FPTrack.Sequence->Duration));
-
-  // Consult ST 379:2004 Sec. 6.3, "Element to track relationship" to see where "12" comes from.
-  FPTrack.Track->TrackNumber = KM_i32_BE(Kumu::cp2i<ui32_t>((EssenceUL.Value() + 12)));
-
-  FPTrack.Clip = new SourceClip(m_Dict);
-  m_HeaderPart.AddChildObject(FPTrack.Clip);
-  FPTrack.Sequence->StructuralComponents.push_back(FPTrack.Clip->InstanceUID);
-  FPTrack.Clip->DataDefinition = DataDefinition;
-
-  // for now we do not allow setting this value, so all files will be 'original'
-  FPTrack.Clip->SourceTrackID = 0;
-  FPTrack.Clip->SourcePackageID = NilUMID;
-  m_DurationUpdateList.push_back(&(FPTrack.Clip->Duration));
-
-  m_EssenceDescriptor->LinkedTrackID = FPTrack.Track->TrackID;
-}
-
-//
-void
-AS_02::h__Writer::AddDMSegment(const ASDCP::MXF::Rational& EditRate, ui32_t TCFrameRate,
-                              const std::string& TrackName, const UL& DataDefinition,
-                              const std::string& PackageLabel)
-{
-  //
-  ContentStorage* Storage = new ContentStorage(m_Dict);
-  m_HeaderPart.AddChildObject(Storage);
-  m_HeaderPart.m_Preface->ContentStorage = Storage->InstanceUID;
-
-  EssenceContainerData* ECD = new EssenceContainerData(m_Dict);
-  m_HeaderPart.AddChildObject(ECD);
-  Storage->EssenceContainerData.push_back(ECD->InstanceUID);
-  ECD->IndexSID = 129;
-  ECD->BodySID = 1;
-
-  UUID assetUUID(m_Info.AssetUUID);
-  UMID SourcePackageUMID, MaterialPackageUMID;
-  SourcePackageUMID.MakeUMID(0x0f, assetUUID);
-  MaterialPackageUMID.MakeUMID(0x0f); // unidentified essence
-
-  //
-  // Material Package
-  //
-  m_MaterialPackage = new MaterialPackage(m_Dict);
-  m_MaterialPackage->Name = "AS_02 Material Package";
-  m_MaterialPackage->PackageUID = MaterialPackageUMID;
-  m_HeaderPart.AddChildObject(m_MaterialPackage);
-  Storage->Packages.push_back(m_MaterialPackage->InstanceUID);
-
-  TrackSet<TimecodeComponent> MPTCTrack =
-    CreateTimecodeTrack<MaterialPackage>(m_HeaderPart, *m_MaterialPackage,
-                                        EditRate, TCFrameRate, 0, m_Dict);
-  m_DurationUpdateList.push_back(&(MPTCTrack.Sequence->Duration));
-  m_DurationUpdateList.push_back(&(MPTCTrack.Clip->Duration));
-
-  TrackSet<DMSegment> MPTrack =
-    CreateTrackAndSequence<MaterialPackage, DMSegment>(m_HeaderPart, *m_MaterialPackage,
-                                                      TrackName, EditRate, DataDefinition,
-                                                      2, m_Dict);
-  m_DurationUpdateList.push_back(&(MPTrack.Sequence->Duration));
-
-  MPTrack.Clip = new DMSegment(m_Dict);
-  m_HeaderPart.AddChildObject(MPTrack.Clip);
-  MPTrack.Sequence->StructuralComponents.push_back(MPTrack.Clip->InstanceUID);
-  MPTrack.Clip->DataDefinition = DataDefinition;
-  //  MPTrack.Clip->SourcePackageID = SourcePackageUMID;
-  //  MPTrack.Clip->SourceTrackID = 2;
-  m_DurationUpdateList.push_back(&(MPTrack.Clip->Duration));
-
-
-  //
-  // File (Source) Package
-  //
-  m_FilePackage = new SourcePackage(m_Dict);
-  m_FilePackage->Name = PackageLabel.c_str();
-  m_FilePackage->PackageUID = SourcePackageUMID;
-  ECD->LinkedPackageUID = SourcePackageUMID;
-
-  m_HeaderPart.AddChildObject(m_FilePackage);
-  Storage->Packages.push_back(m_FilePackage->InstanceUID);
-
-  TrackSet<TimecodeComponent> FPTCTrack =
-    CreateTimecodeTrack<SourcePackage>(m_HeaderPart, *m_FilePackage,
-                                      EditRate, TCFrameRate,
-                                      ui64_C(3600) * TCFrameRate, m_Dict);
-  m_DurationUpdateList.push_back(&(FPTCTrack.Sequence->Duration));
-  m_DurationUpdateList.push_back(&(FPTCTrack.Clip->Duration));
-
-  TrackSet<DMSegment> FPTrack =
-    CreateTrackAndSequence<SourcePackage, DMSegment>(m_HeaderPart, *m_FilePackage,
-                                                    TrackName, EditRate, DataDefinition,
-                                                    2, m_Dict);
-  m_DurationUpdateList.push_back(&(FPTrack.Sequence->Duration));
-
-  FPTrack.Clip = new DMSegment(m_Dict);
-  m_HeaderPart.AddChildObject(FPTrack.Clip);
-  FPTrack.Sequence->StructuralComponents.push_back(FPTrack.Clip->InstanceUID);
-  FPTrack.Clip->DataDefinition = DataDefinition;
-  FPTrack.Clip->EventComment = "D-Cinema Timed Text";
-
-  m_DurationUpdateList.push_back(&(FPTrack.Clip->Duration));
-  m_EssenceDescriptor->LinkedTrackID = FPTrack.Track->TrackID;
-}
-
-//
-void
-AS_02::h__Writer::AddEssenceDescriptor(const UL& WrappingUL)
-{
-  //
-  // Essence Descriptor
-  //
-  m_EssenceDescriptor->EssenceContainer = WrappingUL;
-  m_HeaderPart.m_Preface->PrimaryPackage = m_FilePackage->InstanceUID;
-
-  //
-  // Essence Descriptors
-  //
-  assert(m_Dict);
-  //TODO: Mono Essence, only one GenericContainer ? 
-  //UL GenericContainerUL(m_Dict->ul(MDD_GCMulti));
-  //m_HeaderPart.EssenceContainers.push_back(GenericContainerUL);
-
-  if ( m_Info.EncryptedEssence )
-    {
-      UL CryptEssenceUL(m_Dict->ul(MDD_EncryptedContainerLabel));
-      m_HeaderPart.EssenceContainers.push_back(CryptEssenceUL);
-      m_HeaderPart.m_Preface->DMSchemes.push_back(UL(m_Dict->ul(MDD_CryptographicFrameworkLabel)));
-      AddDMScrypt(m_HeaderPart, *m_FilePackage, m_Info, WrappingUL, m_Dict);
-    }
-  else
-    {
-      m_HeaderPart.EssenceContainers.push_back(WrappingUL);
-    }
-
-  m_HeaderPart.m_Preface->EssenceContainers = m_HeaderPart.EssenceContainers;
-  m_HeaderPart.AddChildObject(m_EssenceDescriptor);
-
-  std::list<InterchangeObject*>::iterator sdli = m_EssenceSubDescriptorList.begin();
-  for ( ; sdli != m_EssenceSubDescriptorList.end(); sdli++ )
-    m_HeaderPart.AddChildObject(*sdli);
-
-  m_FilePackage->Descriptor = m_EssenceDescriptor->InstanceUID;
-}
-
-//
-Result_t
-AS_02::h__Writer::CreateBodyPart(const ASDCP::MXF::Rational& EditRate, ui32_t BytesPerEditUnit)
-{
-  assert(m_Dict);
-  Result_t result = RESULT_OK;
-  m_EditRate = EditRate;
-  m_BytesPerEditUnit = BytesPerEditUnit;
-
-  result = CreateBodyPartPair();
-
-  //TODO: no IndexTables in the footer -> The spec is silent on that topic
-  m_FooterPart.IndexSID = 0;//129;
-
-  return result;
-}
-
-// standard method of creating a new BodyPartition Pair for Essence and IndexTables
-Result_t AS_02::h__Writer::CreateBodyPartPair()
-{
-  Result_t result = RESULT_OK;
-
-  if ( m_IndexStrategy == AS_02::IS_FILE_SPECIFIC ){
-    result = RESULT_FAIL;
-  }
-
-  //similar to both index strategies  
-
-  Partition *m_BodyPartEssence = new ASDCP::MXF::Partition(m_Dict);       
-  m_BodyPartEssence->EssenceContainers = m_HeaderPart.EssenceContainers;
-  //necessary? - here we must increment the BodySID, when a new BodyPartion is created
-  m_BodyPartEssence->BodySID = 1;//++m_CurrentBodySID;
-  UL OperationalPattern(m_Dict->ul(MDD_OP1a));
-  m_BodyPartEssence->OperationalPattern = OperationalPattern;
-
-  m_BodyPartEssence->FooterPartition = 0;
-  m_BodyPartEssence->IndexSID = 0;
-  m_BodyPartEssence->BodyOffset = m_BodyOffset;
-
-  m_CurrentIndexBodyPartition = new AS_02::MXF::OP1aIndexBodyPartion(this->m_Dict);    
-  m_CurrentIndexBodyPartition->EssenceContainers = m_HeaderPart.EssenceContainers;
-  m_CurrentIndexBodyPartition->BodySID = 0;
-  m_CurrentIndexBodyPartition->OperationalPattern = OperationalPattern;
-  m_CurrentIndexBodyPartition->FooterPartition = 0;
-  m_CurrentIndexBodyPartition->IndexSID = 129;//++m_CurrentIndexSID;
-
-  //we must differentiate between index_strategy "lead" and "follow"
-  if ( m_IndexStrategy == AS_02::IS_FOLLOW )
-    {
-      if(m_BodyPartList.size()>0){
-       m_BodyPartEssence->PreviousPartition = m_BodyPartList.back()->ThisPartition;
-      }
-      else{
-       m_BodyPartEssence->PreviousPartition = m_HeaderPart.ThisPartition;
-      }
-      /* Write partition header for the body partition and create IndexBodyPartition.
-        When "all" essence packets are written, write out index table. */
-      m_CurrentIndexBodyPartition->ThisPartition = 0;
-      m_BodyPartEssence->ThisPartition = m_File.Tell();
-      m_CurrentIndexBodyPartition->PreviousPartition = m_BodyPartEssence->ThisPartition;\r
-       m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(m_CurrentIndexBodyPartition->BodySID, m_CurrentIndexBodyPartition->ThisPartition));
-
-       this->m_BodyPartList.push_back(m_CurrentIndexBodyPartition);
-       this->m_BodyPartList.push_back(m_BodyPartEssence);
-    }
-  else if ( m_IndexStrategy == AS_02::IS_LEAD )
-    {
-      /* Write KLVFill packet large enough to hold the completed index data */
-      m_CurrentIndexBodyPartition->ThisPartition = m_File.Tell();
-      m_CurrentIndexBodyPartition->FillWriteToFile(m_File,m_PartitionSpace);
-      m_BodyPartEssence->ThisPartition = m_File.Tell();
-      m_BodyPartEssence->PreviousPartition = m_CurrentIndexBodyPartition->ThisPartition;\r
-       m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(m_CurrentIndexBodyPartition->BodySID, m_CurrentIndexBodyPartition->ThisPartition));
-
-       if(m_BodyPartList.size()>0)
-         {
-           m_CurrentIndexBodyPartition->PreviousPartition = m_BodyPartList.back()->ThisPartition;
-         }
-       else
-         {
-           m_CurrentIndexBodyPartition->PreviousPartition = m_HeaderPart.ThisPartition;
-         }
-
-       //necessary to traverse across all of the body partition packs and update the FooterPartition entries at the end of writing                     
-       this->m_BodyPartList.push_back(m_CurrentIndexBodyPartition);
-       this->m_BodyPartList.push_back(m_BodyPartEssence);
-    }
-
-  /* similar to both index strategies */
-
-  m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(m_BodyPartEssence->BodySID, m_BodyPartEssence->ThisPartition));
-  UL BodyUL(m_Dict->ul(MDD_ClosedCompleteBodyPartition));
-  result = m_BodyPartEssence->WriteToFile(m_File, BodyUL);
-
-  if ( ASDCP_SUCCESS(result) )
-    {
-      //TODO: Is this necessary?What means ECoffset?Never used in the code? If necessary check if it is set correctly.
-
-      // Index setup
-      Kumu::fpos_t ECoffset = m_File.Tell();
-
-      if(m_BytesPerEditUnit == 0){
-       m_CurrentIndexBodyPartition->SetIndexParamsVBR(&m_HeaderPart.m_Primer, m_EditRate, ECoffset);
-      }
-      else{
-       m_CurrentIndexBodyPartition->SetIndexParamsCBR(&m_HeaderPart.m_Primer, m_BytesPerEditUnit, m_EditRate);
-      }
-    }
-
-  return result;
-}
-
-Result_t AS_02::h__Writer::CompleteIndexBodyPart()
-{
-  Result_t result = RESULT_OK;
-  if ( m_IndexStrategy == AS_02::IS_FOLLOW )
-    {\r
-      m_CurrentIndexBodyPartition->ThisPartition = m_File.Tell();\r
-       m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(m_CurrentIndexBodyPartition->BodySID, m_CurrentIndexBodyPartition->ThisPartition));\r
-         }
-
-  UL BodyUL(m_Dict->ul(MDD_ClosedCompleteBodyPartition));\r
-    ui64_t cur_pos = m_File.Tell();\r
-      m_File.Seek(m_CurrentIndexBodyPartition->ThisPartition);\r
-       result = m_CurrentIndexBodyPartition->WriteToFile(m_File, BodyUL);
-       m_File.Seek(cur_pos);
-       return result;
-}
+AS_02::h__AS02Writer::h__AS02Writer(const ASDCP::Dictionary& d) : ASDCP::MXF::TrackFileWriter<ASDCP::MXF::OP1aHeader>(d) {}
+AS_02::h__AS02Writer::~h__AS02Writer() {}
 
 //
 Result_t
-AS_02::h__Writer::WriteMXFHeader(const std::string& PackageLabel, const UL& WrappingUL,
-                                const std::string& TrackName, const UL& EssenceUL, const UL& DataDefinition,
-                                const ASDCP::MXF::Rational& EditRate, ui32_t TCFrameRate, ui32_t BytesPerEditUnit)
+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)
 {
   InitHeader();
   AddSourceClip(EditRate, TCFrameRate, TrackName, EssenceUL, DataDefinition, PackageLabel);
@@ -515,158 +53,13 @@ AS_02::h__Writer::WriteMXFHeader(const std::string& PackageLabel, const UL& Wrap
   Result_t result = m_HeaderPart.WriteToFile(m_File, m_HeaderSize);
 
   //use the FrameRate for the indexing; initialize the SID counters
-  m_CurrentBodySID = 0;
-  m_CurrentIndexSID = 0;
+  ///  m_CurrentBodySID = 0;
+  ///  m_CurrentIndexSID = 0;
   m_PartitionSpace = m_PartitionSpace * TCFrameRate; ///// TODO ????
 
-  if ( KM_SUCCESS(result) )
-    result = CreateBodyPart(EditRate, BytesPerEditUnit);
-
-  return result;
-}
-
-
-// standard method of writing a plaintext or encrypted frame
-Result_t
-AS_02::h__Writer::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf, const byte_t* EssenceUL,
-                                 AESEncContext* Ctx, HMACContext* HMAC)
-{
-  Result_t result = RESULT_OK;
-  IntegrityPack IntPack;
-
-  byte_t overhead[128];
-  Kumu::MemIOWriter Overhead(overhead, 128);
-  assert(m_Dict);
-
-  if ( FrameBuf.Size() == 0 )
-    {
-      DefaultLogSink().Error("Cannot write empty frame buffer\n");
-      return RESULT_EMPTY_FB;
-    }
-
-  if ( m_Info.EncryptedEssence )
-    {
-      if ( ! Ctx )
-       return RESULT_CRYPT_CTX;
-
-      if ( m_Info.UsesHMAC && ! HMAC )
-       return RESULT_HMAC_CTX;
-
-      if ( FrameBuf.PlaintextOffset() > FrameBuf.Size() )
-       return RESULT_LARGE_PTO;
-
-      // encrypt the essence data (create encrypted source value)
-      result = EncryptFrameBuffer(FrameBuf, m_CtFrameBuf, Ctx);
-
-      // create HMAC
-      if ( ASDCP_SUCCESS(result) && m_Info.UsesHMAC )
-       result = IntPack.CalcValues(m_CtFrameBuf, m_Info.AssetUUID, m_FramesWritten + 1, HMAC);
-
-      if ( ASDCP_SUCCESS(result) )
-       { // write UL
-         Overhead.WriteRaw(m_Dict->ul(MDD_CryptEssence), SMPTE_UL_LENGTH);
-
-         // construct encrypted triplet header
-         ui32_t ETLength = klv_cryptinfo_size + m_CtFrameBuf.Size();
-         ui32_t BER_length = MXF_BER_LENGTH;
-
-         if ( m_Info.UsesHMAC )
-           ETLength += klv_intpack_size;
-         else
-           ETLength += (MXF_BER_LENGTH * 3); // for empty intpack
-
-         if ( ETLength > 0x00ffffff ) // Need BER integer longer than MXF_BER_LENGTH bytes
-           {
-             BER_length = Kumu::get_BER_length_for_value(ETLength);
-
-             // the packet is longer by the difference in expected vs. actual BER length
-             ETLength += BER_length - MXF_BER_LENGTH;
-
-             if ( BER_length == 0 )
-               result = RESULT_KLV_CODING;
-           }
-
-         if ( ASDCP_SUCCESS(result) )
-           {
-             if ( ! ( Overhead.WriteBER(ETLength, BER_length)                 // write encrypted triplet length
-                      && Overhead.WriteBER(UUIDlen, MXF_BER_LENGTH)                // write ContextID length
-                      && Overhead.WriteRaw(m_Info.ContextID, UUIDlen)              // write ContextID
-                      && Overhead.WriteBER(sizeof(ui64_t), MXF_BER_LENGTH)         // write PlaintextOffset length
-                      && Overhead.WriteUi64BE(FrameBuf.PlaintextOffset())          // write PlaintextOffset
-                      && Overhead.WriteBER(SMPTE_UL_LENGTH, MXF_BER_LENGTH)        // write essence UL length
-                      && Overhead.WriteRaw((byte_t*)EssenceUL, SMPTE_UL_LENGTH)    // write the essence UL
-                      && Overhead.WriteBER(sizeof(ui64_t), MXF_BER_LENGTH)         // write SourceLength length
-                      && Overhead.WriteUi64BE(FrameBuf.Size())                     // write SourceLength
-                      && Overhead.WriteBER(m_CtFrameBuf.Size(), BER_length) ) )    // write ESV length
-               {
-                 result = RESULT_KLV_CODING;
-               }
-           }
-
-         if ( ASDCP_SUCCESS(result) )
-           result = m_File.Writev(Overhead.Data(), Overhead.Length());
-       }
-
-      if ( ASDCP_SUCCESS(result) )
-       {
-         m_StreamOffset += Overhead.Length();
-         // write encrypted source value
-         result = m_File.Writev((byte_t*)m_CtFrameBuf.RoData(), m_CtFrameBuf.Size());
-       }
-
-      if ( ASDCP_SUCCESS(result) )
-       {
-         m_StreamOffset += m_CtFrameBuf.Size();
-
-         byte_t hmoverhead[512];
-         Kumu::MemIOWriter HMACOverhead(hmoverhead, 512);
-
-         // write the HMAC
-         if ( m_Info.UsesHMAC )
-           {
-             HMACOverhead.WriteRaw(IntPack.Data, klv_intpack_size);
-           }
-         else
-           { // we still need the var-pack length values if the intpack is empty
-             for ( ui32_t i = 0; i < 3 ; i++ )
-               HMACOverhead.WriteBER(0, MXF_BER_LENGTH);
-           }
-
-         // write HMAC
-         result = m_File.Writev(HMACOverhead.Data(), HMACOverhead.Length());
-         m_StreamOffset += HMACOverhead.Length();
-       }
-    }
-  else
-    {
-      ui32_t BER_length = MXF_BER_LENGTH;
-
-      if ( FrameBuf.Size() > 0x00ffffff ) // Need BER integer longer than MXF_BER_LENGTH bytes
-       {
-         BER_length = Kumu::get_BER_length_for_value(FrameBuf.Size());
-
-         if ( BER_length == 0 )
-           result = RESULT_KLV_CODING;
-       }
-
-      Overhead.WriteRaw((byte_t*)EssenceUL, SMPTE_UL_LENGTH);
-      Overhead.WriteBER(FrameBuf.Size(), BER_length);
-
-      if ( ASDCP_SUCCESS(result) )
-       result = m_File.Writev(Overhead.Data(), Overhead.Length());
-
-      if ( ASDCP_SUCCESS(result) )
-       result = m_File.Writev((byte_t*)FrameBuf.RoData(), FrameBuf.Size());
-
-      if ( ASDCP_SUCCESS(result) )
-       m_StreamOffset += Overhead.Length() + FrameBuf.Size();
-    }
-
-  if ( ASDCP_SUCCESS(result) )
-    result = m_File.Writev();
-
   return result;
 }
+    
 
 //
 // end h__02_Writer.cpp
index 77d732f9f2aaae9536691767f8163fd5d7d65c18..1ba43232f0cf3dada21ece244a032f4f5f4f657f 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
@@ -51,8 +51,9 @@ ASDCP::default_md_object_init()
       if ( ! sg_DefaultMDTypesInit )
        {
          sg_dict = &DefaultSMPTEDict();
-         g_OPAtomHeader = new ASDCP::MXF::OPAtomHeader(sg_dict);
+         g_OP1aHeader = new ASDCP::MXF::OP1aHeader(sg_dict);
          g_OPAtomIndexFooter = new ASDCP::MXF::OPAtomIndexFooter(sg_dict);
+         g_RIP = new ASDCP::MXF::RIP(sg_dict);
          sg_DefaultMDTypesInit = true;
        }
     }
@@ -63,7 +64,7 @@ ASDCP::default_md_object_init()
 //
 
 //
-ASDCP::h__ASDCPReader::h__ASDCPReader(const Dictionary& d) : MXF::TrackFileReader<OPAtomHeader, OPAtomIndexFooter>(d), m_BodyPart(m_Dict) {}
+ASDCP::h__ASDCPReader::h__ASDCPReader(const Dictionary& d) : MXF::TrackFileReader<OP1aHeader, OPAtomIndexFooter>(d), m_BodyPart(m_Dict) {}
 ASDCP::h__ASDCPReader::~h__ASDCPReader() {}
 
 
@@ -71,87 +72,94 @@ ASDCP::h__ASDCPReader::~h__ASDCPReader() {}
 Result_t
 ASDCP::h__ASDCPReader::OpenMXFRead(const char* filename)
 {
-  Result_t result = ASDCP::MXF::TrackFileReader<OPAtomHeader, OPAtomIndexFooter>::OpenMXFRead(filename);
+  Result_t result = ASDCP::MXF::TrackFileReader<OP1aHeader, OPAtomIndexFooter>::OpenMXFRead(filename);
 
   if ( KM_SUCCESS(result) )
-    {
-        // if this is a three partition file, go to the body
-        // partition and read the partition pack
-        if ( m_HeaderPart.m_RIP.PairArray.size() > 2 )
-        {
-            Array<RIP::Pair>::iterator r_i = m_HeaderPart.m_RIP.PairArray.begin();
-            r_i++;
-            m_File.Seek((*r_i).ByteOffset);
-            result = m_BodyPart.InitFromFile(m_File);
-            if( !ASDCP_SUCCESS(result) )
-            {
-                DefaultLogSink().Error("ASDCP::h__Reader::OpenMXFRead, m_BodyPart.InitFromFile failed\n");
-            }
-        }
-    }
-    else
-      DefaultLogSink().Error("ASDCP::h__Reader::OpenMXFRead, TrackFileReader::OpenMXFRead failed\n");
-
-
-  if ( KM_SUCCESS(result) )
-      m_HeaderPart.BodyOffset = m_File.Tell();
-
-  return result;
-}
-
-//
-Result_t
-ASDCP::h__ASDCPReader::InitInfo()
-{
-  Result_t result = ASDCP::MXF::TrackFileReader<OPAtomHeader, OPAtomIndexFooter>::InitInfo();
+    result = ASDCP::MXF::TrackFileReader<OP1aHeader, OPAtomIndexFooter>::InitInfo();
 
   if( KM_SUCCESS(result) )
     {
+      //
       InterchangeObject* Object;
 
       m_Info.LabelSetType = LS_MXF_UNKNOWN;
 
       if ( m_HeaderPart.OperationalPattern.ExactMatch(MXFInterop_OPAtom_Entry().ul) )
        {
-       m_Info.LabelSetType = LS_MXF_INTEROP;
+         m_Info.LabelSetType = LS_MXF_INTEROP;
        }
       else if ( m_HeaderPart.OperationalPattern.ExactMatch(SMPTE_390_OPAtom_Entry().ul) )
        {
          m_Info.LabelSetType = LS_MXF_SMPTE;
        }
-    }
-
-  return result;
-}
+      else
+       {
+         char strbuf[IdentBufferLen];
+         const MDDEntry* Entry = m_Dict->FindUL(m_HeaderPart.OperationalPattern.Value());
 
-// AS-DCP method of populating the in-memory index
-Result_t
-ASDCP::h__ASDCPReader::InitMXFIndex()
-{
-  if ( ! m_File.IsOpen() )
-    return RESULT_INIT;
+         if ( Entry == 0 )
+           {
+             DefaultLogSink().Warn("Operational pattern is not OP-Atom: %s\n",
+                                   m_HeaderPart.OperationalPattern.EncodeString(strbuf, IdentBufferLen));
+           }
+         else
+           {
+             DefaultLogSink().Warn("Operational pattern is not OP-Atom: %s\n", Entry->name);
+           }
+       }
 
-  Result_t result = m_File.Seek(m_HeaderPart.FooterPartition);
+      //
+      if ( m_RIP.PairArray.size() < 2 )
+       {
+         // OP-Atom states that there will be either two or three partitions:
+         // one closed header and one closed footer with an optional body
+         // SMPTE 429-5 files may have many partitions, see SMPTE ST 410.
+         DefaultLogSink().Warn("RIP entry count is less than 2: %u\n", m_RIP.PairArray.size());
+       }
+      else if ( m_RIP.PairArray.size() > 2 )
+        {
+         // if this is a three partition file, go to the body
+         // partition and read the partition pack
+         Array<RIP::Pair>::iterator r_i = m_RIP.PairArray.begin();
+         r_i++;
+         m_File.Seek((*r_i).ByteOffset);
+         result = m_BodyPart.InitFromFile(m_File);
+
+         if( ASDCP_FAILURE(result) )
+            {
+             DefaultLogSink().Error("ASDCP::h__ASDCPReader::OpenMXFRead, m_BodyPart.InitFromFile failed\n");
+            }
+        }
+      else if ( m_RIP.PairArray.front().ByteOffset != 0 )
+       {
+         DefaultLogSink().Error("First Partition in RIP is not at offset 0.\n");
+         result = RESULT_FORMAT;
+       }
+    }
 
-  if ( ASDCP_SUCCESS(result) )
+  if ( KM_SUCCESS(result) )
     {
-      m_FooterPart.m_Lookup = &m_HeaderPart.m_Primer;
-      result = m_FooterPart.InitFromFile(m_File);
-    }
+      m_HeaderPart.BodyOffset = m_File.Tell();
+
+      result = m_File.Seek(m_HeaderPart.FooterPartition);
 
-  if ( ASDCP_SUCCESS(result) )
-    m_File.Seek(m_HeaderPart.BodyOffset);
+      if ( ASDCP_SUCCESS(result) )
+       {
+         m_IndexAccess.m_Lookup = &m_HeaderPart.m_Primer;
+         result = m_IndexAccess.InitFromFile(m_File);
+       }
+    }
 
+  m_File.Seek(m_HeaderPart.BodyOffset);
   return result;
 }
 
-
 // AS-DCP method of reading a plaintext or encrypted frame
 Result_t
 ASDCP::h__ASDCPReader::ReadEKLVFrame(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
                                     const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC)
 {
-  return ASDCP::MXF::TrackFileReader<OPAtomHeader, OPAtomIndexFooter>::ReadEKLVFrame(m_HeaderPart, FrameNum, FrameBuf,
+  return ASDCP::MXF::TrackFileReader<OP1aHeader, OPAtomIndexFooter>::ReadEKLVFrame(m_HeaderPart, FrameNum, FrameBuf,
                                                                                     EssenceUL, Ctx, HMAC);
 }
 
@@ -159,7 +167,7 @@ Result_t
 ASDCP::h__ASDCPReader::LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset,
                            i8_t& temporalOffset, i8_t& keyFrameOffset)
 {
-  return ASDCP::MXF::TrackFileReader<OPAtomHeader, OPAtomIndexFooter>::LocateFrame(m_HeaderPart, FrameNum,
+  return ASDCP::MXF::TrackFileReader<OP1aHeader, OPAtomIndexFooter>::LocateFrame(m_HeaderPart, FrameNum,
                                                                                    streamOffset, temporalOffset, keyFrameOffset);
 }
 
@@ -225,7 +233,7 @@ ASDCP::KLReader::ReadKLFromFile(Kumu::FileReader& Reader)
 
 // base subroutine for reading a KLV packet, assumes file position is at the first byte of the packet
 Result_t
-ASDCP::Read_EKLV_Packet(Kumu::FileReader& File, const ASDCP::Dictionary& Dict, const MXF::OPAtomHeader& HeaderPart,
+ASDCP::Read_EKLV_Packet(Kumu::FileReader& File, const ASDCP::Dictionary& Dict, const MXF::OP1aHeader& HeaderPart,
                        const ASDCP::WriterInfo& Info, Kumu::fpos_t& LastPosition, ASDCP::FrameBuffer& CtFrameBuf,
                        ui32_t FrameNum, ui32_t SequenceNum, ASDCP::FrameBuffer& FrameBuf,
                        const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC)
@@ -296,12 +304,19 @@ ASDCP::Read_EKLV_Packet(Kumu::FileReader& File, const ASDCP::Dictionary& Dict, c
        {
          char strbuf[IntBufferLen];
          const MDDEntry* Entry = Dict.FindUL(Key.Value());
+
          if ( Entry == 0 )
-           DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Key.EncodeString(strbuf, IntBufferLen));
+           {
+             DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Key.EncodeString(strbuf, IntBufferLen));
+           }
          else
-           DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Entry->name);
+           {
+             DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Entry->name);
+           }
+
          return RESULT_FORMAT;
        }
+
       ess_p += SMPTE_UL_LENGTH;
 
       // read SourceLength length
@@ -408,10 +423,15 @@ ASDCP::Read_EKLV_Packet(Kumu::FileReader& File, const ASDCP::Dictionary& Dict, c
     {
       char strbuf[IntBufferLen];
       const MDDEntry* Entry = Dict.FindUL(Key.Value());
+
       if ( Entry == 0 )
-        DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Key.EncodeString(strbuf, IntBufferLen));
+       {
+         DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Key.EncodeString(strbuf, IntBufferLen));
+       }
       else
-        DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Entry->name);
+       {
+         DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Entry->name);
+       }
 
       return RESULT_FORMAT;
     }
index 48b348647ad65a0a80e1c8ec8976cc55d9f43176..4290974d675bf13c23a4cbe24c0b664fc1dbea84 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
@@ -35,26 +35,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 using namespace ASDCP;
 using namespace ASDCP::MXF;
 
-// a magic number identifying asdcplib
-#ifndef ASDCP_BUILD_NUMBER
-#define ASDCP_BUILD_NUMBER 0x6A68
-#endif
-
-
-
-//
-ASDCP::h__Writer::h__Writer(const Dictionary& d) :
-  m_HeaderPart(m_Dict), m_BodyPart(m_Dict), m_FooterPart(m_Dict), m_Dict(&d),
-  m_HeaderSize(0), m_EssenceStart(0),
-  m_EssenceDescriptor(0), m_FramesWritten(0), m_StreamOffset(0)
-{
-  default_md_object_init();
-}
-
-ASDCP::h__Writer::~h__Writer()
-{
-}
-
 //
 // add DMS CryptographicFramework entry to source package
 void
@@ -94,326 +74,18 @@ ASDCP::AddDMScrypt(Partition& HeaderPart, SourcePackage& Package,
   Context->CryptographicKeyID.Set(Descr.CryptographicKeyID);
 }
 
-//
-void
-ASDCP::h__Writer::InitHeader()
-{
-  assert(m_Dict);
-  assert(m_EssenceDescriptor);
-
-  m_HeaderPart.m_Primer.ClearTagList();
-  m_HeaderPart.m_Preface = new Preface(m_Dict);
-  m_HeaderPart.AddChildObject(m_HeaderPart.m_Preface);
-
-  // Set the Operational Pattern label -- we're just starting and have no RIP or index,
-  // so we tell the world by using OP1a
-  m_HeaderPart.m_Preface->OperationalPattern = UL(m_Dict->ul(MDD_OP1a));
-  m_HeaderPart.OperationalPattern = m_HeaderPart.m_Preface->OperationalPattern;
-
-  // First RIP Entry
-  if ( m_Info.LabelSetType == LS_MXF_SMPTE )
-    m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(0, 0)); // 3-part, no essence in header
-  else
-    m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(1, 0)); // 2-part, essence in header
-
-  //
-  // Identification
-  //
-  Identification* Ident = new Identification(m_Dict);
-  m_HeaderPart.AddChildObject(Ident);
-  m_HeaderPart.m_Preface->Identifications.push_back(Ident->InstanceUID);
-
-  Kumu::GenRandomValue(Ident->ThisGenerationUID);
-  Ident->CompanyName = m_Info.CompanyName.c_str();
-  Ident->ProductName = m_Info.ProductName.c_str();
-  Ident->VersionString = m_Info.ProductVersion.c_str();
-  Ident->ProductUID.Set(m_Info.ProductUUID);
-  Ident->Platform = ASDCP_PLATFORM;
-
-  std::vector<int> version = version_split(Version());
-
-  Ident->ToolkitVersion.Major = version[0];
-  Ident->ToolkitVersion.Minor = version[1];
-  Ident->ToolkitVersion.Patch = version[2];
-  Ident->ToolkitVersion.Build = ASDCP_BUILD_NUMBER;
-  Ident->ToolkitVersion.Release = VersionType::RL_RELEASE;
-}
-
-//
-template <class ClipT>
-struct TrackSet
-{
-  MXF::Track*    Track;
-  MXF::Sequence* Sequence;
-  ClipT*         Clip;
-
-  TrackSet() : Track(0), Sequence(0), Clip(0) {}
-};
-
-//
-template <class PackageT, class ClipT>
-TrackSet<ClipT>
-CreateTrackAndSequence(OPAtomHeader& Header, PackageT& Package, const std::string TrackName,
-                      const MXF::Rational& EditRate, const UL& Definition, ui32_t TrackID, const Dictionary*& Dict)
-{
-  TrackSet<ClipT> NewTrack;
-
-  NewTrack.Track = new Track(Dict);
-  Header.AddChildObject(NewTrack.Track);
-  NewTrack.Track->EditRate = EditRate;
-  Package.Tracks.push_back(NewTrack.Track->InstanceUID);
-  NewTrack.Track->TrackID = TrackID;
-  NewTrack.Track->TrackName = TrackName.c_str();
-
-  NewTrack.Sequence = new Sequence(Dict);
-  Header.AddChildObject(NewTrack.Sequence);
-  NewTrack.Track->Sequence = NewTrack.Sequence->InstanceUID;
-  NewTrack.Sequence->DataDefinition = Definition;
-
-  return NewTrack;
-}
-
-//
-template <class PackageT>
-TrackSet<TimecodeComponent>
-CreateTimecodeTrack(OPAtomHeader& Header, PackageT& Package,
-                   const MXF::Rational& EditRate, ui32_t TCFrameRate, ui64_t TCStart, const Dictionary*& Dict)
-{
-  assert(Dict);
-  UL TCUL(Dict->ul(MDD_TimecodeDataDef));
-
-  TrackSet<TimecodeComponent> NewTrack = CreateTrackAndSequence<PackageT, TimecodeComponent>(Header, Package, "Timecode Track", EditRate, TCUL, 1, Dict);
-
-  NewTrack.Clip = new TimecodeComponent(Dict);
-  Header.AddChildObject(NewTrack.Clip);
-  NewTrack.Sequence->StructuralComponents.push_back(NewTrack.Clip->InstanceUID);
-  NewTrack.Clip->RoundedTimecodeBase = TCFrameRate;
-  NewTrack.Clip->StartTimecode = TCStart;
-  NewTrack.Clip->DataDefinition = TCUL;
-
-  return NewTrack;
-}
-
-
-//
-void
-ASDCP::h__Writer::AddSourceClip(const MXF::Rational& EditRate, ui32_t TCFrameRate,
-                               const std::string& TrackName, const UL& EssenceUL,
-                               const UL& DataDefinition, const std::string& PackageLabel)
-{
-  //
-  ContentStorage* Storage = new ContentStorage(m_Dict);
-  m_HeaderPart.AddChildObject(Storage);
-  m_HeaderPart.m_Preface->ContentStorage = Storage->InstanceUID;
-
-  EssenceContainerData* ECD = new EssenceContainerData(m_Dict);
-  m_HeaderPart.AddChildObject(ECD);
-  Storage->EssenceContainerData.push_back(ECD->InstanceUID);
-  ECD->IndexSID = 129;
-  ECD->BodySID = 1;
-
-  UUID assetUUID(m_Info.AssetUUID);
-  UMID SourcePackageUMID, MaterialPackageUMID;
-  SourcePackageUMID.MakeUMID(0x0f, assetUUID);
-  MaterialPackageUMID.MakeUMID(0x0f); // unidentified essence
-
-  //
-  // Material Package
-  //
-  m_MaterialPackage = new MaterialPackage(m_Dict);
-  m_MaterialPackage->Name = "AS-DCP Material Package";
-  m_MaterialPackage->PackageUID = MaterialPackageUMID;
-  m_HeaderPart.AddChildObject(m_MaterialPackage);
-  Storage->Packages.push_back(m_MaterialPackage->InstanceUID);
-
-  TrackSet<TimecodeComponent> MPTCTrack =
-    CreateTimecodeTrack<MaterialPackage>(m_HeaderPart, *m_MaterialPackage,
-                                        EditRate, TCFrameRate, 0, m_Dict);
-  m_DurationUpdateList.push_back(&(MPTCTrack.Sequence->Duration));
-  m_DurationUpdateList.push_back(&(MPTCTrack.Clip->Duration));
-
-  TrackSet<SourceClip> MPTrack =
-    CreateTrackAndSequence<MaterialPackage, SourceClip>(m_HeaderPart, *m_MaterialPackage,
-                                                       TrackName, EditRate, DataDefinition,
-                                                       2, m_Dict);
-  m_DurationUpdateList.push_back(&(MPTrack.Sequence->Duration));
-
-  MPTrack.Clip = new SourceClip(m_Dict);
-  m_HeaderPart.AddChildObject(MPTrack.Clip);
-  MPTrack.Sequence->StructuralComponents.push_back(MPTrack.Clip->InstanceUID);
-  MPTrack.Clip->DataDefinition = DataDefinition;
-  MPTrack.Clip->SourcePackageID = SourcePackageUMID;
-  MPTrack.Clip->SourceTrackID = 2;
-  m_DurationUpdateList.push_back(&(MPTrack.Clip->Duration));
 
-  
-  //
-  // File (Source) Package
-  //
-  m_FilePackage = new SourcePackage(m_Dict);
-  m_FilePackage->Name = PackageLabel.c_str();
-  m_FilePackage->PackageUID = SourcePackageUMID;
-  ECD->LinkedPackageUID = SourcePackageUMID;
-
-  m_HeaderPart.AddChildObject(m_FilePackage);
-  Storage->Packages.push_back(m_FilePackage->InstanceUID);
-
-  TrackSet<TimecodeComponent> FPTCTrack =
-    CreateTimecodeTrack<SourcePackage>(m_HeaderPart, *m_FilePackage,
-                                      EditRate, TCFrameRate,
-                                      ui64_C(3600) * TCFrameRate, m_Dict);
-  m_DurationUpdateList.push_back(&(FPTCTrack.Sequence->Duration));
-  m_DurationUpdateList.push_back(&(FPTCTrack.Clip->Duration));
-  TrackSet<SourceClip> FPTrack =
-    CreateTrackAndSequence<SourcePackage, SourceClip>(m_HeaderPart, *m_FilePackage,
-                                                     TrackName, EditRate, DataDefinition,
-                                                     2, m_Dict);
-  m_DurationUpdateList.push_back(&(FPTrack.Sequence->Duration));
-
-  // Consult ST 379:2004 Sec. 6.3, "Element to track relationship" to see where "12" comes from.
-  FPTrack.Track->TrackNumber = KM_i32_BE(Kumu::cp2i<ui32_t>((EssenceUL.Value() + 12)));
-
-  FPTrack.Clip = new SourceClip(m_Dict);
-  m_HeaderPart.AddChildObject(FPTrack.Clip);
-  FPTrack.Sequence->StructuralComponents.push_back(FPTrack.Clip->InstanceUID);
-  FPTrack.Clip->DataDefinition = DataDefinition;
-
-  // for now we do not allow setting this value, so all files will be 'original'
-  FPTrack.Clip->SourceTrackID = 0;
-  FPTrack.Clip->SourcePackageID = NilUMID;
-  m_DurationUpdateList.push_back(&(FPTrack.Clip->Duration));
-
-  m_EssenceDescriptor->LinkedTrackID = FPTrack.Track->TrackID;
-}
 
 //
-void
-ASDCP::h__Writer::AddDMSegment(const MXF::Rational& EditRate, ui32_t TCFrameRate,
-                              const std::string& TrackName, const UL& DataDefinition,
-                              const std::string& PackageLabel)
-{
-  //
-  ContentStorage* Storage = new ContentStorage(m_Dict);
-  m_HeaderPart.AddChildObject(Storage);
-  m_HeaderPart.m_Preface->ContentStorage = Storage->InstanceUID;
-
-  EssenceContainerData* ECD = new EssenceContainerData(m_Dict);
-  m_HeaderPart.AddChildObject(ECD);
-  Storage->EssenceContainerData.push_back(ECD->InstanceUID);
-  ECD->IndexSID = 129;
-  ECD->BodySID = 1;
-
-  UUID assetUUID(m_Info.AssetUUID);
-  UMID SourcePackageUMID, MaterialPackageUMID;
-  SourcePackageUMID.MakeUMID(0x0f, assetUUID);
-  MaterialPackageUMID.MakeUMID(0x0f); // unidentified essence
-
-  //
-  // Material Package
-  //
-  m_MaterialPackage = new MaterialPackage(m_Dict);
-  m_MaterialPackage->Name = "AS-DCP Material Package";
-  m_MaterialPackage->PackageUID = MaterialPackageUMID;
-  m_HeaderPart.AddChildObject(m_MaterialPackage);
-  Storage->Packages.push_back(m_MaterialPackage->InstanceUID);
-
-  TrackSet<TimecodeComponent> MPTCTrack =
-    CreateTimecodeTrack<MaterialPackage>(m_HeaderPart, *m_MaterialPackage,
-                                        EditRate, TCFrameRate, 0, m_Dict);
-  m_DurationUpdateList.push_back(&(MPTCTrack.Sequence->Duration));
-  m_DurationUpdateList.push_back(&(MPTCTrack.Clip->Duration));
-
-  TrackSet<DMSegment> MPTrack =
-    CreateTrackAndSequence<MaterialPackage, DMSegment>(m_HeaderPart, *m_MaterialPackage,
-                                                      TrackName, EditRate, DataDefinition,
-                                                      2, m_Dict);
-  m_DurationUpdateList.push_back(&(MPTrack.Sequence->Duration));
-
-  MPTrack.Clip = new DMSegment(m_Dict);
-  m_HeaderPart.AddChildObject(MPTrack.Clip);
-  MPTrack.Sequence->StructuralComponents.push_back(MPTrack.Clip->InstanceUID);
-  MPTrack.Clip->DataDefinition = DataDefinition;
-  //  MPTrack.Clip->SourcePackageID = SourcePackageUMID;
-  //  MPTrack.Clip->SourceTrackID = 2;
-  m_DurationUpdateList.push_back(&(MPTrack.Clip->Duration));
+ASDCP::h__ASDCPWriter::h__ASDCPWriter(const Dictionary& d) :
+  MXF::TrackFileWriter<OP1aHeader>(d), m_BodyPart(m_Dict), m_FooterPart(m_Dict) {}
 
-  
-  //
-  // File (Source) Package
-  //
-  m_FilePackage = new SourcePackage(m_Dict);
-  m_FilePackage->Name = PackageLabel.c_str();
-  m_FilePackage->PackageUID = SourcePackageUMID;
-  ECD->LinkedPackageUID = SourcePackageUMID;
-
-  m_HeaderPart.AddChildObject(m_FilePackage);
-  Storage->Packages.push_back(m_FilePackage->InstanceUID);
-
-  TrackSet<TimecodeComponent> FPTCTrack =
-    CreateTimecodeTrack<SourcePackage>(m_HeaderPart, *m_FilePackage,
-                                      EditRate, TCFrameRate,
-                                      ui64_C(3600) * TCFrameRate, m_Dict);
-  m_DurationUpdateList.push_back(&(FPTCTrack.Sequence->Duration));
-  m_DurationUpdateList.push_back(&(FPTCTrack.Clip->Duration));
-
-  TrackSet<DMSegment> FPTrack =
-    CreateTrackAndSequence<SourcePackage, DMSegment>(m_HeaderPart, *m_FilePackage,
-                                                    TrackName, EditRate, DataDefinition,
-                                                    2, m_Dict);
-  m_DurationUpdateList.push_back(&(FPTrack.Sequence->Duration));
-
-  FPTrack.Clip = new DMSegment(m_Dict);
-  m_HeaderPart.AddChildObject(FPTrack.Clip);
-  FPTrack.Sequence->StructuralComponents.push_back(FPTrack.Clip->InstanceUID);
-  FPTrack.Clip->DataDefinition = DataDefinition;
-  FPTrack.Clip->EventComment = "D-Cinema Timed Text";
-
-  m_DurationUpdateList.push_back(&(FPTrack.Clip->Duration));
-  m_EssenceDescriptor->LinkedTrackID = FPTrack.Track->TrackID;
-}
+ASDCP::h__ASDCPWriter::~h__ASDCPWriter() {}
 
-//
-void
-ASDCP::h__Writer::AddEssenceDescriptor(const UL& WrappingUL)
-{
-  //
-  // Essence Descriptor
-  //
-  m_EssenceDescriptor->EssenceContainer = WrappingUL;
-  m_HeaderPart.m_Preface->PrimaryPackage = m_FilePackage->InstanceUID;
-
-  //
-  // Essence Descriptors
-  //
-  assert(m_Dict);
-  UL GenericContainerUL(m_Dict->ul(MDD_GCMulti));
-  m_HeaderPart.EssenceContainers.push_back(GenericContainerUL);
-
-  if ( m_Info.EncryptedEssence )
-    {
-      UL CryptEssenceUL(m_Dict->ul(MDD_EncryptedContainerLabel));
-      m_HeaderPart.EssenceContainers.push_back(CryptEssenceUL);
-      m_HeaderPart.m_Preface->DMSchemes.push_back(UL(m_Dict->ul(MDD_CryptographicFrameworkLabel)));
-      AddDMScrypt(m_HeaderPart, *m_FilePackage, m_Info, WrappingUL, m_Dict);
-    }
-  else
-    {
-      m_HeaderPart.EssenceContainers.push_back(WrappingUL);
-    }
-
-  m_HeaderPart.m_Preface->EssenceContainers = m_HeaderPart.EssenceContainers;
-  m_HeaderPart.AddChildObject(m_EssenceDescriptor);
-
-  std::list<InterchangeObject*>::iterator sdli = m_EssenceSubDescriptorList.begin();
-  for ( ; sdli != m_EssenceSubDescriptorList.end(); sdli++ )
-      m_HeaderPart.AddChildObject(*sdli);
-
-  m_FilePackage->Descriptor = m_EssenceDescriptor->InstanceUID;
-}
 
 //
 Result_t
-ASDCP::h__Writer::CreateBodyPart(const MXF::Rational& EditRate, ui32_t BytesPerEditUnit)
+ASDCP::h__ASDCPWriter::CreateBodyPart(const MXF::Rational& EditRate, ui32_t BytesPerEditUnit)
 {
   assert(m_Dict);
   Result_t result = RESULT_OK;
@@ -427,7 +99,7 @@ ASDCP::h__Writer::CreateBodyPart(const MXF::Rational& EditRate, ui32_t BytesPerE
       m_BodyPart.BodySID = 1;
       UL OPAtomUL(m_Dict->ul(MDD_OPAtom));
       m_BodyPart.OperationalPattern = OPAtomUL;
-      m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(1, m_BodyPart.ThisPartition)); // Second RIP Entry
+      m_RIP.PairArray.push_back(RIP::Pair(1, m_BodyPart.ThisPartition)); // Second RIP Entry
       
       UL BodyUL(m_Dict->ul(MDD_ClosedCompleteBodyPartition));
       result = m_BodyPart.WriteToFile(m_File, BodyUL);
@@ -444,9 +116,13 @@ ASDCP::h__Writer::CreateBodyPart(const MXF::Rational& EditRate, ui32_t BytesPerE
       m_FooterPart.IndexSID = 129;
 
       if ( BytesPerEditUnit == 0 )
-       m_FooterPart.SetIndexParamsVBR(&m_HeaderPart.m_Primer, EditRate, ECoffset);
+       {
+         m_FooterPart.SetIndexParamsVBR(&m_HeaderPart.m_Primer, EditRate, ECoffset);
+       }
       else
-       m_FooterPart.SetIndexParamsCBR(&m_HeaderPart.m_Primer, BytesPerEditUnit, EditRate);
+       {
+         m_FooterPart.SetIndexParamsCBR(&m_HeaderPart.m_Primer, BytesPerEditUnit, EditRate);
+       }
     }
 
   return result;
@@ -454,11 +130,22 @@ ASDCP::h__Writer::CreateBodyPart(const MXF::Rational& EditRate, ui32_t BytesPerE
 
 //
 Result_t
-ASDCP::h__Writer::WriteMXFHeader(const std::string& PackageLabel, const UL& WrappingUL,
-                                const std::string& TrackName, const UL& EssenceUL, const UL& DataDefinition,
-                                const MXF::Rational& EditRate, ui32_t TCFrameRate, ui32_t BytesPerEditUnit)
+ASDCP::h__ASDCPWriter::WriteASDCPHeader(const std::string& PackageLabel, const UL& WrappingUL,
+                                       const std::string& TrackName, const UL& EssenceUL, const UL& DataDefinition,
+                                       const MXF::Rational& EditRate, ui32_t TCFrameRate, ui32_t BytesPerEditUnit)
 {
   InitHeader();
+
+  // First RIP Entry
+  if ( m_Info.LabelSetType == LS_MXF_SMPTE )  // ERK
+    {
+      m_RIP.PairArray.push_back(RIP::Pair(0, 0)); // 3-part, no essence in header
+    }
+  else
+    {
+      m_RIP.PairArray.push_back(RIP::Pair(1, 0)); // 2-part, essence in header
+    }
+
   AddSourceClip(EditRate, TCFrameRate, TrackName, EssenceUL, DataDefinition, PackageLabel);
   AddEssenceDescriptor(WrappingUL);
 
@@ -471,17 +158,70 @@ ASDCP::h__Writer::WriteMXFHeader(const std::string& PackageLabel, const UL& Wrap
 }
 
 
+
+// standard method of writing the header and footer of a completed MXF file
+//
+Result_t
+ASDCP::h__ASDCPWriter::WriteASDCPFooter()
+{
+  // update all Duration properties
+  DurationElementList_t::iterator dli = m_DurationUpdateList.begin();
+
+  for (; dli != m_DurationUpdateList.end(); ++dli )
+    {
+      **dli = m_FramesWritten;
+    }
+
+  m_EssenceDescriptor->ContainerDuration = m_FramesWritten;
+  m_FooterPart.PreviousPartition = m_RIP.PairArray.back().ByteOffset;
+
+  Kumu::fpos_t here = m_File.Tell();
+  m_RIP.PairArray.push_back(RIP::Pair(0, here)); // Last RIP Entry
+  m_HeaderPart.FooterPartition = here;
+
+  assert(m_Dict);
+  // re-label the header partition, set the footer
+  UL OPAtomUL(m_Dict->ul(MDD_OPAtom));
+  m_HeaderPart.OperationalPattern = OPAtomUL;
+  m_HeaderPart.m_Preface->OperationalPattern = OPAtomUL;
+  m_FooterPart.OperationalPattern = OPAtomUL;
+
+  m_FooterPart.EssenceContainers = m_HeaderPart.EssenceContainers;
+  m_FooterPart.FooterPartition = here;
+  m_FooterPart.ThisPartition = here;
+
+  Result_t result = m_FooterPart.WriteToFile(m_File, m_FramesWritten);
+
+  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);
+
+  m_File.Close();
+  return result;
+}
+
+
+//------------------------------------------------------------------------------------------
+//
+
+
 // standard method of writing a plaintext or encrypted frame
 Result_t
-ASDCP::h__Writer::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf, const byte_t* EssenceUL,
-                                 AESEncContext* Ctx, HMACContext* HMAC)
+ASDCP::Write_EKLV_Packet(Kumu::FileWriter& File, const ASDCP::Dictionary& Dict, const MXF::OP1aHeader& HeaderPart,
+                        const ASDCP::WriterInfo& Info, ASDCP::FrameBuffer& CtFrameBuf, ui32_t& FramesWritten,
+                        ui64_t & StreamOffset, const ASDCP::FrameBuffer& FrameBuf, const byte_t* EssenceUL,
+                        AESEncContext* Ctx, HMACContext* HMAC)
 {
   Result_t result = RESULT_OK;
   IntegrityPack IntPack;
 
   byte_t overhead[128];
   Kumu::MemIOWriter Overhead(overhead, 128);
-  assert(m_Dict);
 
   if ( FrameBuf.Size() == 0 )
     {
@@ -489,33 +229,33 @@ ASDCP::h__Writer::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf, const byte
       return RESULT_EMPTY_FB;
     }
 
-  if ( m_Info.EncryptedEssence )
+  if ( Info.EncryptedEssence )
     {
       if ( ! Ctx )
        return RESULT_CRYPT_CTX;
 
-      if ( m_Info.UsesHMAC && ! HMAC )
+      if ( Info.UsesHMAC && ! HMAC )
        return RESULT_HMAC_CTX;
 
       if ( FrameBuf.PlaintextOffset() > FrameBuf.Size() )
        return RESULT_LARGE_PTO;
 
       // encrypt the essence data (create encrypted source value)
-      result = EncryptFrameBuffer(FrameBuf, m_CtFrameBuf, Ctx);
+      result = EncryptFrameBuffer(FrameBuf, CtFrameBuf, Ctx);
 
       // create HMAC
-      if ( ASDCP_SUCCESS(result) && m_Info.UsesHMAC )
-       result = IntPack.CalcValues(m_CtFrameBuf, m_Info.AssetUUID, m_FramesWritten + 1, HMAC);
+      if ( ASDCP_SUCCESS(result) && Info.UsesHMAC )
+       result = IntPack.CalcValues(CtFrameBuf, Info.AssetUUID, FramesWritten + 1, HMAC);
 
       if ( ASDCP_SUCCESS(result) )
        { // write UL
-         Overhead.WriteRaw(m_Dict->ul(MDD_CryptEssence), SMPTE_UL_LENGTH);
+         Overhead.WriteRaw(Dict.ul(MDD_CryptEssence), SMPTE_UL_LENGTH);
 
          // construct encrypted triplet header
-         ui32_t ETLength = klv_cryptinfo_size + m_CtFrameBuf.Size();
+         ui32_t ETLength = klv_cryptinfo_size + CtFrameBuf.Size();
          ui32_t BER_length = MXF_BER_LENGTH;
 
-         if ( m_Info.UsesHMAC )
+         if ( Info.UsesHMAC )
            ETLength += klv_intpack_size;
          else
            ETLength += (MXF_BER_LENGTH * 3); // for empty intpack
@@ -535,39 +275,39 @@ ASDCP::h__Writer::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf, const byte
            {
              if ( ! ( Overhead.WriteBER(ETLength, BER_length)                      // write encrypted triplet length
                       && Overhead.WriteBER(UUIDlen, MXF_BER_LENGTH)                // write ContextID length
-                      && Overhead.WriteRaw(m_Info.ContextID, UUIDlen)              // write ContextID
+                      && Overhead.WriteRaw(Info.ContextID, UUIDlen)              // write ContextID
                       && Overhead.WriteBER(sizeof(ui64_t), MXF_BER_LENGTH)         // write PlaintextOffset length
                       && Overhead.WriteUi64BE(FrameBuf.PlaintextOffset())          // write PlaintextOffset
                       && Overhead.WriteBER(SMPTE_UL_LENGTH, MXF_BER_LENGTH)        // write essence UL length
                       && Overhead.WriteRaw((byte_t*)EssenceUL, SMPTE_UL_LENGTH)    // write the essence UL
                       && Overhead.WriteBER(sizeof(ui64_t), MXF_BER_LENGTH)         // write SourceLength length
                       && Overhead.WriteUi64BE(FrameBuf.Size())                     // write SourceLength
-                      && Overhead.WriteBER(m_CtFrameBuf.Size(), BER_length) ) )    // write ESV length
+                      && Overhead.WriteBER(CtFrameBuf.Size(), BER_length) ) )    // write ESV length
                {
                  result = RESULT_KLV_CODING;
                }
            }
 
          if ( ASDCP_SUCCESS(result) )
-           result = m_File.Writev(Overhead.Data(), Overhead.Length());
+           result = File.Writev(Overhead.Data(), Overhead.Length());
        }
 
       if ( ASDCP_SUCCESS(result) )
        {
-         m_StreamOffset += Overhead.Length();
+         StreamOffset += Overhead.Length();
          // write encrypted source value
-         result = m_File.Writev((byte_t*)m_CtFrameBuf.RoData(), m_CtFrameBuf.Size());
+         result = File.Writev((byte_t*)CtFrameBuf.RoData(), CtFrameBuf.Size());
        }
 
       if ( ASDCP_SUCCESS(result) )
        {
-         m_StreamOffset += m_CtFrameBuf.Size();
+         StreamOffset += CtFrameBuf.Size();
 
          byte_t hmoverhead[512];
          Kumu::MemIOWriter HMACOverhead(hmoverhead, 512);
 
          // write the HMAC
-         if ( m_Info.UsesHMAC )
+         if ( Info.UsesHMAC )
            {
              HMACOverhead.WriteRaw(IntPack.Data, klv_intpack_size);
            }
@@ -578,8 +318,8 @@ ASDCP::h__Writer::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf, const byte
            }
 
          // write HMAC
-         result = m_File.Writev(HMACOverhead.Data(), HMACOverhead.Length());
-         m_StreamOffset += HMACOverhead.Length();
+         result = File.Writev(HMACOverhead.Data(), HMACOverhead.Length());
+         StreamOffset += HMACOverhead.Length();
        }
     }
   else
@@ -598,67 +338,18 @@ ASDCP::h__Writer::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf, const byte
       Overhead.WriteBER(FrameBuf.Size(), BER_length);
 
       if ( ASDCP_SUCCESS(result) )
-       result = m_File.Writev(Overhead.Data(), Overhead.Length());
+       result = File.Writev(Overhead.Data(), Overhead.Length());
  
       if ( ASDCP_SUCCESS(result) )
-       result = m_File.Writev((byte_t*)FrameBuf.RoData(), FrameBuf.Size());
+       result = File.Writev((byte_t*)FrameBuf.RoData(), FrameBuf.Size());
 
       if ( ASDCP_SUCCESS(result) )
-       m_StreamOffset += Overhead.Length() + FrameBuf.Size();
+       StreamOffset += Overhead.Length() + FrameBuf.Size();
     }
 
   if ( ASDCP_SUCCESS(result) )
-    result = m_File.Writev();
-
-  return result;
-}
-
-
-// standard method of writing the header and footer of a completed MXF file
-//
-Result_t
-ASDCP::h__Writer::WriteMXFFooter()
-{
-  // Set top-level file package correctly for OP-Atom
-
-  //  m_MPTCSequence->Duration = m_MPTimecode->Duration = m_MPClSequence->Duration = m_MPClip->Duration = 
-  //    m_FPTCSequence->Duration = m_FPTimecode->Duration = m_FPClSequence->Duration = m_FPClip->Duration = 
-
-  DurationElementList_t::iterator dli = m_DurationUpdateList.begin();
-
-  for (; dli != m_DurationUpdateList.end(); dli++ )
-    **dli = m_FramesWritten;
-
-  m_EssenceDescriptor->ContainerDuration = m_FramesWritten;
-  m_FooterPart.PreviousPartition = m_HeaderPart.m_RIP.PairArray.back().ByteOffset;
-
-  Kumu::fpos_t here = m_File.Tell();
-  m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(0, here)); // Last RIP Entry
-  m_HeaderPart.FooterPartition = here;
+    result = File.Writev();
 
-  assert(m_Dict);
-  // re-label the partition
-  UL OPAtomUL(m_Dict->ul(MDD_OPAtom));
-  m_HeaderPart.OperationalPattern = OPAtomUL;
-  m_HeaderPart.m_Preface->OperationalPattern = m_HeaderPart.OperationalPattern;
-
-  m_FooterPart.OperationalPattern = m_HeaderPart.OperationalPattern;
-  m_FooterPart.EssenceContainers = m_HeaderPart.EssenceContainers;
-  m_FooterPart.FooterPartition = here;
-  m_FooterPart.ThisPartition = here;
-
-  Result_t result = m_FooterPart.WriteToFile(m_File, m_FramesWritten);
-
-  if ( ASDCP_SUCCESS(result) )
-    result = m_HeaderPart.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);
-
-  m_File.Close();
   return result;
 }
 
index 92e7a3fbc5fd6877e301e85b6c6061bc032cb7d6..f87d2c50f662c1f696c5e6e453e0cf95182022e9 100755 (executable)
@@ -194,21 +194,47 @@ main(int argc, const char** argv)
        {
          Kumu::FileReader        Reader;
          const Dictionary* Dict = &DefaultCompositeDict();
-         ASDCP::MXF::OPAtomHeader Header(Dict);
+         ASDCP::MXF::OP1aHeader Header(Dict);
+         ASDCP::MXF::RIP RIP(Dict);
          
          result = Reader.OpenRead((*fi).c_str());
          
+         if ( ASDCP_SUCCESS(result) )
+           result = MXF::SeekToRIP(Reader);
+
+         if ( ASDCP_SUCCESS(result) )
+           {
+             result = RIP.InitFromFile(Reader);
+             ui32_t test_s = RIP.PairArray.size();
+
+             if ( ASDCP_FAILURE(result) )
+               {
+                 DefaultLogSink().Error("File contains no RIP\n");
+                 result = RESULT_OK;
+               }
+             else if ( RIP.PairArray.empty() )
+               {
+                 DefaultLogSink().Error("RIP contains no Pairs.\n");
+               }
+
+             Reader.Seek(0);
+           }
+         else
+           {
+             DefaultLogSink().Error("ASDCP::h__Reader::OpenMXFRead, SeekToRIP failed\n");
+           }
+
          if ( ASDCP_SUCCESS(result) )
            result = Header.InitFromFile(Reader);
          
          if ( ASDCP_SUCCESS(result) )
            Header.Dump(stdout);
          
-         if ( ASDCP_SUCCESS(result) && Header.m_RIP.PairArray.size() > 2 )
+         if ( ASDCP_SUCCESS(result) && RIP.PairArray.size() > 2 )
            {
-             MXF::Array<MXF::RIP::Pair>::const_iterator pi = Header.m_RIP.PairArray.begin();
+             MXF::Array<MXF::RIP::Pair>::const_iterator pi = RIP.PairArray.begin();
 
-             for ( pi++; pi != Header.m_RIP.PairArray.end() && ASDCP_SUCCESS(result); pi++ )
+             for ( pi++; pi != RIP.PairArray.end() && ASDCP_SUCCESS(result); pi++ )
                {
                  result = Reader.Seek((*pi).ByteOffset);
 
@@ -239,7 +265,7 @@ main(int argc, const char** argv)
            }
 
          if ( ASDCP_SUCCESS(result) )
-           Header.m_RIP.Dump(stdout);
+           RIP.Dump(stdout);
        }
       else // dump klv
        {