working j2c as-02
authorjhurst <jhurst@cinecert.com>
Tue, 4 Jun 2013 05:22:27 +0000 (05:22 +0000)
committerjhurst <>
Tue, 4 Jun 2013 05:22:27 +0000 (05:22 +0000)
18 files changed:
src/AS_02.h
src/AS_02_JP2K.cpp
src/AS_02_PCM.cpp
src/AS_02_internal.h
src/AS_DCP_ATMOS.cpp
src/AS_DCP_DCData.cpp
src/AS_DCP_JP2K.cpp
src/AS_DCP_MPEG2.cpp
src/AS_DCP_MXF.cpp
src/AS_DCP_PCM.cpp
src/AS_DCP_internal.h
src/Index.cpp
src/MXF.cpp
src/as-02-unwrap.cpp
src/as-02-wrap.cpp
src/h__02_Reader.cpp
src/h__02_Writer.cpp
src/klvwalk.cpp

index dc6fc612e8ef91b9a1f162e1b4ffa77f61235dff..e4be1b872b450d979100971fa6b57e54b566adff 100644 (file)
@@ -68,107 +68,34 @@ namespace AS_02
   using Kumu::Result_t;
 
   namespace MXF {
-#if 0
     //
-    class OP1aIndexBodyPartion : public ASDCP::MXF::Partition
+    class AS02IndexReader : public ASDCP::MXF::Partition
     {
-      ASDCP::MXF::IndexTableSegment*  m_CurrentSegment;
-      ASDCP::FrameBuffer  m_Buffer;
-      ASDCP::MXF::Rational m_EditRate;
-      ui32_t                           klv_fill_size;
+      Kumu::ByteString m_IndexSegmentData;
+      ui32_t m_Duration;
 
-      ASDCP_NO_COPY_CONSTRUCT(OP1aIndexBodyPartion);
+      //      ui32_t              m_BytesPerEditUnit;
 
-    public:
-      const ASDCP::Dictionary*&  m_Dict;
-      Kumu::fpos_t        m_ECOffset;
-      ASDCP::IPrimerLookup*      m_Lookup;
-
-      ui32_t             m_BytesPerEditUnit;
-      ui32_t             m_FramesWritten;
-      
-      OP1aIndexBodyPartion(const ASDCP::Dictionary*&);
-      virtual ~OP1aIndexBodyPartion();
-      virtual Result_t InitFromFile(const Kumu::FileReader& Reader);
-      virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l);
-      virtual Result_t WriteToFile(Kumu::FileWriter& Writer, ASDCP::UL& PartitionLabel);
-      virtual void     Dump(FILE* = 0);
-
-      virtual bool Lookup(ui32_t frame_num, ASDCP::MXF::IndexTableSegment::IndexEntry&,ui32_t&) const;
-      virtual void PushIndexEntry(const ASDCP::MXF::IndexTableSegment::IndexEntry&);
-      virtual void SetIndexParamsCBR(ASDCP::IPrimerLookup* lookup, ui32_t size, const ASDCP::MXF::Rational& Rate);
-      virtual void SetIndexParamsVBR(ASDCP::IPrimerLookup* lookup, const ASDCP::MXF::Rational& Rate, Kumu::fpos_t offset);
-
-      //new
-      virtual ui64_t Duration();
-      virtual Result_t FillWriteToFile(Kumu::FileWriter& Writer, ui32_t numberOfIndexEntries);
-
-      //new for PCM
-      virtual void PCMSetIndexParamsCBR(ui32_t sizeFirst, ui32_t sizeOthers);
-      virtual void PCMIndexLookup(ui32_t frame_num, ASDCP::MXF::IndexTableSegment::IndexEntry& Entry) const;
-      
-    };
-
-    //
-    class OP1aIndexFooter : public ASDCP::MXF::Partition
-    {
-      ASDCP::MXF::IndexTableSegment*  m_CurrentSegment;
-      ASDCP::FrameBuffer  m_Buffer;
-      ui32_t              m_BytesPerEditUnit;
-      ASDCP::MXF::Rational m_EditRate;
-      ui32_t              m_BodySID;
-      ASDCP_NO_COPY_CONSTRUCT(OP1aIndexFooter);
-      OP1aIndexFooter();
-
-    public:
-      const ASDCP::Dictionary*&   m_Dict;
-      Kumu::fpos_t        m_ECOffset;
-      ASDCP::IPrimerLookup*      m_Lookup;
-
-      OP1aIndexFooter(const ASDCP::Dictionary*&);
-      virtual ~OP1aIndexFooter();
-      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);
-      virtual Result_t WriteToFile(Kumu::FileWriter& Writer, ui64_t duration);
-      virtual void     Dump(FILE* = 0);
-
-      virtual Result_t Lookup(ui32_t frame_num, ASDCP::MXF::IndexTableSegment::IndexEntry&) const;
-      virtual void     PushIndexEntry(const ASDCP::MXF::IndexTableSegment::IndexEntry&);
-      virtual void     SetIndexParamsCBR(ASDCP::IPrimerLookup* lookup, ui32_t size, const ASDCP::MXF::Rational& Rate);
-      virtual void     SetIndexParamsVBR(ASDCP::IPrimerLookup* lookup, const ASDCP::MXF::Rational& Rate, Kumu::fpos_t offset);
-    };
-
-#endif
-
-    //
-    class AS02IndexReader
-    {
-      ASDCP::MXF::IndexTableSegment*  m_CurrentSegment;
-      ASDCP::FrameBuffer  m_Buffer;
-      ui32_t              m_BytesPerEditUnit;
-      ASDCP::Rational     m_EditRate;
-      ui32_t              m_BodySID;
+      Result_t InitFromBuffer(const byte_t* p, ui32_t l);
 
       ASDCP_NO_COPY_CONSTRUCT(AS02IndexReader);
       AS02IndexReader();
          
     public:
       const ASDCP::Dictionary*&   m_Dict;
-      Kumu::fpos_t        m_ECOffset;
+      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;
+      Result_t InitFromFile(const Kumu::FileReader& reader, const ASDCP::MXF::RIP& rip);
+      ui32_t GetDuration() const;
+      void     Dump(FILE* = 0);
+      Result_t GetMDObjectByID(const Kumu::UUID&, ASDCP::MXF::InterchangeObject** = 0);
+      Result_t GetMDObjectByType(const byte_t*, ASDCP::MXF::InterchangeObject** = 0);
+      Result_t GetMDObjectsByType(const byte_t* ObjectID, std::list<ASDCP::MXF::InterchangeObject*>& ObjectList);
+      Result_t Lookup(ui32_t frame_num, ASDCP::MXF::IndexTableSegment::IndexEntry&) const;
     };
 
   } // namespace MXF
index 38b2e55aac44bd6e302f1df7f30739804e9b4404..aeb6dbc6550aea4a27596ba20bdfb29971bc298a 100644 (file)
@@ -50,7 +50,8 @@ static std::string PICT_DEF_LABEL = "Image Track";
 
 class AS_02::JP2K::MXFReader::h__Reader : public AS_02::h__AS02Reader
 {
-  RGBAEssenceDescriptor*        m_EssenceDescriptor;
+  RGBAEssenceDescriptor*        m_RGBAEssenceDescriptor;
+  CDCIEssenceDescriptor*        m_CDCIEssenceDescriptor;
   JPEG2000PictureSubDescriptor* m_EssenceSubDescriptor;
   ASDCP::Rational               m_EditRate;
   ASDCP::Rational               m_SampleRate;
@@ -62,29 +63,49 @@ public:
   PictureDescriptor m_PDesc;        // codestream parameter list
 
   h__Reader(const Dictionary& d) :
-    AS_02::h__AS02Reader(d), m_EssenceDescriptor(0), m_EssenceSubDescriptor(0), m_Format(ESS_UNKNOWN) {}
+    AS_02::h__AS02Reader(d), m_RGBAEssenceDescriptor(0), m_CDCIEssenceDescriptor(0),
+    m_EssenceSubDescriptor(0), m_Format(ESS_UNKNOWN) {}
 
   virtual ~h__Reader() {}
 
-  Result_t    OpenRead(const char*, EssenceType_t);
+  Result_t    OpenRead(const char*);
   Result_t    ReadFrame(ui32_t, ASDCP::JP2K::FrameBuffer&, AESDecContext*, HMACContext*);
 };
 
 //
 Result_t
-AS_02::JP2K::MXFReader::h__Reader::OpenRead(const char* filename, ASDCP::EssenceType_t type)
+AS_02::JP2K::MXFReader::h__Reader::OpenRead(const char* filename)
 {
   Result_t result = OpenMXFRead(filename);
 
   if( ASDCP_SUCCESS(result) )
     {
       InterchangeObject* tmp_iobj = 0;
-      m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(RGBAEssenceDescriptor), &tmp_iobj);
-      m_EssenceDescriptor = static_cast<RGBAEssenceDescriptor*>(tmp_iobj);
+
+      m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(CDCIEssenceDescriptor), &tmp_iobj);
+      m_CDCIEssenceDescriptor = static_cast<CDCIEssenceDescriptor*>(tmp_iobj);
+
+      if ( m_CDCIEssenceDescriptor == 0 )
+       {
+         m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(RGBAEssenceDescriptor), &tmp_iobj);
+         m_RGBAEssenceDescriptor = static_cast<RGBAEssenceDescriptor*>(tmp_iobj);
+       }
+
+      if ( m_CDCIEssenceDescriptor == 0 && m_RGBAEssenceDescriptor == 0 )
+       {
+         DefaultLogSink().Error("RGBAEssenceDescriptor nor CDCIEssenceDescriptor found.\n");
+         return RESULT_FORMAT;
+       }
 
       m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(JPEG2000PictureSubDescriptor), &tmp_iobj);
       m_EssenceSubDescriptor = static_cast<JPEG2000PictureSubDescriptor*>(tmp_iobj);
 
+      if ( m_EssenceSubDescriptor == 0 )
+       {
+         DefaultLogSink().Error("JPEG2000PictureSubDescriptor not found.\n");
+         return RESULT_FORMAT;
+       }
+
       std::list<InterchangeObject*> ObjectList;
       m_HeaderPart.GetMDObjectsByType(OBJ_TYPE_ARGS(Track), ObjectList);
 
@@ -94,34 +115,23 @@ AS_02::JP2K::MXFReader::h__Reader::OpenRead(const char* filename, ASDCP::Essence
          return RESULT_FORMAT;
        }
 
-      m_EditRate = ((Track*)ObjectList.front())->EditRate;
-      m_SampleRate = m_EssenceDescriptor->SampleRate;
-
-      if ( type == ASDCP::ESS_JPEG_2000 )
+      if ( m_CDCIEssenceDescriptor != 0 )
        {
-         if ( m_EditRate != m_SampleRate )
-           {
-             DefaultLogSink().Warn("EditRate and SampleRate do not match (%.03f, %.03f).\n",
-                                   m_EditRate.Quotient(), m_SampleRate.Quotient());
-
-             if ( m_EditRate == EditRate_24 && m_SampleRate == EditRate_48 )
-               {
-                 DefaultLogSink().Debug("File may contain JPEG Interop stereoscopic images.\n");
-                 return RESULT_SFORMAT;
-               }
-
-             return RESULT_FORMAT;
-           }
+         m_EditRate = ((Track*)ObjectList.front())->EditRate;
+         m_SampleRate = m_CDCIEssenceDescriptor->SampleRate;
+         result = MD_to_JP2K_PDesc(*m_CDCIEssenceDescriptor, *m_EssenceSubDescriptor, m_EditRate, m_SampleRate, m_PDesc);
        }
-      else
+      else if ( m_RGBAEssenceDescriptor != 0 )
        {
-         DefaultLogSink().Error("'type' argument unexpected: %x\n", type);
-         return RESULT_STATE;
+         m_EditRate = ((Track*)ObjectList.front())->EditRate;
+         m_SampleRate = m_RGBAEssenceDescriptor->SampleRate;
+         result = MD_to_JP2K_PDesc(*m_RGBAEssenceDescriptor, *m_EssenceSubDescriptor, m_EditRate, m_SampleRate, m_PDesc);
        }
 
-      assert(m_EssenceDescriptor);
-      assert(m_EssenceSubDescriptor);
-      result = MD_to_JP2K_PDesc(*m_EssenceDescriptor, *m_EssenceSubDescriptor, m_EditRate, m_SampleRate, m_PDesc);
+      if ( m_PDesc.ContainerDuration == 0 )
+       {
+         m_PDesc.ContainerDuration = m_IndexAccess.GetDuration();
+       }
     }
 
   return result;
@@ -203,7 +213,7 @@ AS_02::JP2K::MXFReader::RIP()
 Result_t
 AS_02::JP2K::MXFReader::OpenRead(const char* filename) const
 {
-  return m_Reader->OpenRead(filename, ASDCP::ESS_JPEG_2000);
+  return m_Reader->OpenRead(filename);
 }
 
 //
@@ -359,14 +369,13 @@ AS_02::JP2K::MXFWriter::h__Writer::SetSourceStream(const PictureDescriptor& PDes
 Result_t
 AS_02::JP2K::MXFWriter::h__Writer::WriteFrame(const ASDCP::JP2K::FrameBuffer& FrameBuf,
                       AESEncContext* Ctx, HMACContext* HMAC)
-#if 1
 {
   Result_t result = RESULT_OK;
 
   if ( m_State.Test_READY() )
     result = m_State.Goto_RUNNING(); // first time through
  
-  ui64_t StreamOffset = m_StreamOffset;
+  ui64_t StreamOffset = m_StreamOffset; // m_StreamOffset will be changed by the call to WriteEKLVPacket
 
   if ( ASDCP_SUCCESS(result) )
     result = WriteEKLVPacket(FrameBuf, m_EssenceUL, Ctx, HMAC);
@@ -381,46 +390,6 @@ AS_02::JP2K::MXFWriter::h__Writer::WriteFrame(const ASDCP::JP2K::FrameBuffer& Fr
   m_FramesWritten++;
   return result;
 }
-#else
-{
-  Result_t result = RESULT_OK;
-
-  if ( m_State.Test_READY() ){
-    result = m_State.Goto_RUNNING(); // first time through
-  }
-  ui64_t StreamOffset = m_StreamOffset;
-
-  if ( ASDCP_SUCCESS(result) )
-    result = WriteEKLVPacket(FrameBuf, m_EssenceUL, Ctx, HMAC);
-
-  if ( ASDCP_SUCCESS(result) && add_index )
-    {
-      //create new Index and add it to the IndexTableSegment in the IndexPartition
-      IndexTableSegment::IndexEntry Entry;
-      Entry.StreamOffset = StreamOffset;
-      m_CurrentIndexBodyPartition->m_FramesWritten = m_FramesWritten;
-      m_CurrentIndexBodyPartition->PushIndexEntry(Entry);
-
-      //here we must check if the number of frames per partition are reached 
-      if(m_FramesWritten!=0 &&((m_FramesWritten+1) % m_PartitionSpace) == 0){
-       this->m_BodyOffset += m_StreamOffset;
-       //StreamOffset - Offset in bytes from the start of the Essence\r
-       //Container of first Essence Element in this Edit Unit of\r
-       //stored Essence within the Essence Container Stream
-       //this->m_StreamOffset = 0; ???
-
-       //Complete the Index-BodyPartion
-       result = CompleteIndexBodyPart();\r
-         //Create new BodyPartions for Essence and Index
-         result = CreateBodyPartPair();                 
-      }
-      //else do nothing, we must only insert the current frame
-      //else{}
-    }
-  m_FramesWritten++;
-  return result;
-}
-#endif
 
 // Closes the MXF file, writing the index and other closing information.
 //
index b82e1f062fd72c8f8e8100da270b5f8639fd0417..9c52591199486d88164ade4bacdbd1714630a27c 100644 (file)
@@ -106,10 +106,15 @@ AS_02::PCM::MXFReader::h__Reader::OpenRead(const char* filename)
 
   if( ASDCP_SUCCESS(result) )
     {
-      InterchangeObject* Object;
+      InterchangeObject* Object = 0;
       if ( ASDCP_SUCCESS(m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(WaveAudioDescriptor), &Object)) )
        {
-         assert(Object);
+         if ( Object == 0 )
+           {
+             DefaultLogSink().Error("WaveAudioDescriptor object not found.\n");
+             return RESULT_FORMAT;
+           }
+
          result = MD_to_PCM_ADesc((ASDCP::MXF::WaveAudioDescriptor*)Object, m_ADesc);
        }
     }
index 87e8451a8492fa98127febd9de4ece2999b91a72..cf9c3681fdda8415e48d05d01d79b59f69c86595 100644 (file)
@@ -50,26 +50,6 @@ namespace AS_02
 
   void default_md_object_init();
 
-  static void CalculateIndexPartitionSize(ui32_t& size,ui32_t numberOfIndexEntries)
-  {
-    if(numberOfIndexEntries){
-      //Partition::ArchiveSize(); HeaderSize = 124 bytes
-      //KLV-Item = 20 bytes
-      //ItemSize IndexEntry = 11 bytes
-      //number of IndexEntries - parameter
-      //IndexEntryArray = 12 bytes
-      //size for other Elements(PosTableCount etc.) = 108 bytes
-      //see Index.cpp ASDCP::MXF::IndexTableSegment::WriteToTLVSet(TLVWriter& TLVSet) how this is computed 
-      size = 124 + 20 + 11 * numberOfIndexEntries + 12 +108;
-      size += 20;//because maybe we must fill the last partition, minimum required space for KLV-Item
-    }
-    else{
-      //Partition HeaderSize = 124 bytes
-      //KLV-Item = 20 bytes
-      //244 for 2 IndexTableSegments
-      size = 124 + 20 + 244;
-    }
-  }
 
   //
   class AS02IndexWriter : public ASDCP::MXF::Partition
@@ -110,8 +90,6 @@ namespace AS_02
       //      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();
index 63b55577f4bda85c67d73905e541ffbfdd7efb3d..e8a2a8a21665d4a3a1dd383c5f1f64d7970487b6 100644 (file)
@@ -147,20 +147,26 @@ ASDCP::ATMOS::MXFReader::h__Reader::OpenRead(const char* filename)
   Result_t result = DCData::h__Reader::OpenRead(filename);
 
   if( ASDCP_SUCCESS(result) )
-  {
-
-    if (NULL == m_EssenceSubDescriptor)
-    {
-      InterchangeObject* iObj = NULL;
-      result = m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(DolbyAtmosSubDescriptor), &iObj);
-      m_EssenceSubDescriptor = static_cast<MXF::DolbyAtmosSubDescriptor*>(iObj);
-    }
-
-    if ( ASDCP_SUCCESS(result) )
     {
-      result = MD_to_Atmos_ADesc(m_ADesc);
+      
+      if (NULL == m_EssenceSubDescriptor)
+       {
+         InterchangeObject* iObj = NULL;
+         result = m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(DolbyAtmosSubDescriptor), &iObj);
+         m_EssenceSubDescriptor = static_cast<MXF::DolbyAtmosSubDescriptor*>(iObj);
+         
+         if ( iObj == 0 )
+           {
+             DefaultLogSink().Error("DolbyAtmosSubDescriptor object not found.\n");
+             return RESULT_FORMAT;
+           }
+       }
+
+      if ( ASDCP_SUCCESS(result) )
+       {
+         result = MD_to_Atmos_ADesc(m_ADesc);
+       }
     }
-  }
 
   return result;
 }
index 6ee1098d46ca95f07fdcfa63ff5bad0956fdec64..faa02a03d8bf87a5f1cea44717f381f42b65c652 100644 (file)
@@ -96,20 +96,26 @@ ASDCP::DCData::h__Reader::OpenRead(const char* filename)
   Result_t result = OpenMXFRead(filename);
 
   if( ASDCP_SUCCESS(result) )
-  {
-    if (NULL == m_EssenceDescriptor)
     {
-      InterchangeObject* iObj = NULL;
-      result = m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(DCDataDescriptor), &iObj);
-      m_EssenceDescriptor = static_cast<MXF::DCDataDescriptor*>(iObj);
+      if (NULL == m_EssenceDescriptor)
+       {
+         InterchangeObject* iObj = NULL;
+         result = m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(DCDataDescriptor), &iObj);
+         m_EssenceDescriptor = static_cast<MXF::DCDataDescriptor*>(iObj);
+
+         if ( m_EssenceDescriptor == 0 )
+           {
+             DefaultLogSink().Error("DCDataDescriptor object not found.\n");
+             return RESULT_FORMAT;
+           }
+       }
+
+      if ( ASDCP_SUCCESS(result) )
+       {
+         result = MD_to_DCData_DDesc(m_DDesc);
+       }
     }
 
-    if ( ASDCP_SUCCESS(result) )
-    {
-      result = MD_to_DCData_DDesc(m_DDesc);
-    }
-  }
-
   // check for sample/frame rate sanity
   if ( ASDCP_SUCCESS(result)
                 && m_DDesc.EditRate != EditRate_24
index df4f6a27b2db89d088d2a4a79fdffe6b32c8d266..1aec48eb0ba990a69960c014e674a20603de7214 100755 (executable)
@@ -279,36 +279,140 @@ ASDCP::JP2K_PDesc_to_MD(const JP2K::PictureDescriptor& PDesc,
 }
 
 
-//------------------------------------------------------------------------------------------
 //
-// hidden, internal implementation of JPEG 2000 reader
+ASDCP::Result_t
+ASDCP::MD_to_JP2K_PDesc(const ASDCP::MXF::RGBAEssenceDescriptor&  EssenceDescriptor,
+                       const ASDCP::MXF::JPEG2000PictureSubDescriptor& EssenceSubDescriptor,
+                       const ASDCP::Rational& EditRate, const ASDCP::Rational& SampleRate,
+                       ASDCP::JP2K::PictureDescriptor& PDesc)
+{
+  memset(&PDesc, 0, sizeof(PDesc));
 
+  PDesc.EditRate           = EditRate;
+  PDesc.SampleRate         = SampleRate;
+  assert(EssenceDescriptor.ContainerDuration <= 0xFFFFFFFFL);
+  PDesc.ContainerDuration  = (ui32_t) EssenceDescriptor.ContainerDuration;
+  PDesc.StoredWidth        = EssenceDescriptor.StoredWidth;
+  PDesc.StoredHeight       = EssenceDescriptor.StoredHeight;
+  PDesc.AspectRatio        = EssenceDescriptor.AspectRatio;
 
-class lh__Reader : public ASDCP::h__ASDCPReader
+  PDesc.Rsize   = EssenceSubDescriptor.Rsize;
+  PDesc.Xsize   = EssenceSubDescriptor.Xsize;
+  PDesc.Ysize   = EssenceSubDescriptor.Ysize;
+  PDesc.XOsize  = EssenceSubDescriptor.XOsize;
+  PDesc.YOsize  = EssenceSubDescriptor.YOsize;
+  PDesc.XTsize  = EssenceSubDescriptor.XTsize;
+  PDesc.YTsize  = EssenceSubDescriptor.YTsize;
+  PDesc.XTOsize = EssenceSubDescriptor.XTOsize;
+  PDesc.YTOsize = EssenceSubDescriptor.YTOsize;
+  PDesc.Csize   = EssenceSubDescriptor.Csize;
+
+  // PictureComponentSizing
+  ui32_t tmp_size = EssenceSubDescriptor.PictureComponentSizing.Length();
+
+  if ( tmp_size == 17 ) // ( 2 * sizeof(ui32_t) ) + 3 components * 3 byte each
+    {
+      memcpy(&PDesc.ImageComponents, EssenceSubDescriptor.PictureComponentSizing.RoData() + 8, tmp_size - 8);
+    }
+  else
+    {
+      DefaultLogSink().Error("Unexpected PictureComponentSizing size: %u, should be 17\n", tmp_size);
+    }
+
+  // CodingStyleDefault
+  memset(&PDesc.CodingStyleDefault, 0, sizeof(CodingStyleDefault_t));
+  memcpy(&PDesc.CodingStyleDefault,
+        EssenceSubDescriptor.CodingStyleDefault.RoData(),
+        EssenceSubDescriptor.CodingStyleDefault.Length());
+
+  // QuantizationDefault
+  memset(&PDesc.QuantizationDefault, 0, sizeof(QuantizationDefault_t));
+  memcpy(&PDesc.QuantizationDefault,
+        EssenceSubDescriptor.QuantizationDefault.RoData(),
+        EssenceSubDescriptor.QuantizationDefault.Length());
+  
+  PDesc.QuantizationDefault.SPqcdLength = EssenceSubDescriptor.QuantizationDefault.Length() - 1;
+  return RESULT_OK;
+}
+
+//
+ASDCP::Result_t
+ASDCP::JP2K_PDesc_to_MD(const JP2K::PictureDescriptor& PDesc,
+                       const ASDCP::Dictionary& dict,
+                       ASDCP::MXF::CDCIEssenceDescriptor *EssenceDescriptor,
+                       ASDCP::MXF::JPEG2000PictureSubDescriptor *EssenceSubDescriptor)
 {
-  RGBAEssenceDescriptor*        m_EssenceDescriptor;
-  JPEG2000PictureSubDescriptor* m_EssenceSubDescriptor;
-  ASDCP::Rational               m_EditRate;
-  ASDCP::Rational               m_SampleRate;
-  EssenceType_t                 m_Format;
+  if ( EssenceDescriptor == 0 || EssenceSubDescriptor == 0 )
+    return RESULT_PTR;
 
-  ASDCP_NO_COPY_CONSTRUCT(lh__Reader);
+  EssenceDescriptor->ContainerDuration = PDesc.ContainerDuration;
+  EssenceDescriptor->SampleRate = PDesc.EditRate;
+  EssenceDescriptor->FrameLayout = 0;
+  EssenceDescriptor->StoredWidth = PDesc.StoredWidth;
+  EssenceDescriptor->StoredHeight = PDesc.StoredHeight;
+  EssenceDescriptor->AspectRatio = PDesc.AspectRatio;
 
-public:
-  PictureDescriptor m_PDesc;        // codestream parameter list
+  //  if ( m_Info.LabelSetType == LS_MXF_SMPTE )
+  //    {
+  // PictureEssenceCoding UL = 
+  // Video Line Map       ui32_t[VideoLineMapSize] = { 2, 4, 0, 0 }
+  // CaptureGamma         UL = 
+  // ComponentMaxRef      ui32_t = 4095
+  // ComponentMinRef      ui32_t = 0
+  // PixelLayout          byte_t[PixelLayoutSize] = s_PixelLayoutXYZ
+  //    }
 
-  lh__Reader(const Dictionary& d) :
-    ASDCP::h__ASDCPReader(d), m_EssenceDescriptor(0), m_EssenceSubDescriptor(0), m_Format(ESS_UNKNOWN) {}
+  if ( PDesc.StoredWidth < 2049 )
+    {
+      EssenceDescriptor->PictureEssenceCoding.Set(dict.ul(MDD_JP2KEssenceCompression_2K));
+      EssenceSubDescriptor->Rsize = 3;
+    }
+  else
+    {
+      EssenceDescriptor->PictureEssenceCoding.Set(dict.ul(MDD_JP2KEssenceCompression_4K));
+      EssenceSubDescriptor->Rsize = 4;
+    }
 
-  virtual ~lh__Reader() {}
+  EssenceSubDescriptor->Xsize = PDesc.Xsize;
+  EssenceSubDescriptor->Ysize = PDesc.Ysize;
+  EssenceSubDescriptor->XOsize = PDesc.XOsize;
+  EssenceSubDescriptor->YOsize = PDesc.YOsize;
+  EssenceSubDescriptor->XTsize = PDesc.XTsize;
+  EssenceSubDescriptor->YTsize = PDesc.YTsize;
+  EssenceSubDescriptor->XTOsize = PDesc.XTOsize;
+  EssenceSubDescriptor->YTOsize = PDesc.YTOsize;
+  EssenceSubDescriptor->Csize = PDesc.Csize;
+
+  const ui32_t tmp_buffer_len = 1024;
+  byte_t tmp_buffer[tmp_buffer_len];
+
+  *(ui32_t*)tmp_buffer = KM_i32_BE(MaxComponents); // three components
+  *(ui32_t*)(tmp_buffer+4) = KM_i32_BE(sizeof(ASDCP::JP2K::ImageComponent_t));
+  memcpy(tmp_buffer + 8, &PDesc.ImageComponents, sizeof(ASDCP::JP2K::ImageComponent_t) * MaxComponents);
+
+  const ui32_t pcomp_size = (sizeof(int) * 2) + (sizeof(ASDCP::JP2K::ImageComponent_t) * MaxComponents);
+  memcpy(EssenceSubDescriptor->PictureComponentSizing.Data(), tmp_buffer, pcomp_size);
+  EssenceSubDescriptor->PictureComponentSizing.Length(pcomp_size);
+
+  ui32_t precinct_set_size = 0, i;
+  for ( i = 0; PDesc.CodingStyleDefault.SPcod.PrecinctSize[i] != 0 && i < MaxPrecincts; i++ )
+    precinct_set_size++;
+
+  ui32_t csd_size = sizeof(CodingStyleDefault_t) - MaxPrecincts + precinct_set_size;
+  memcpy(EssenceSubDescriptor->CodingStyleDefault.Data(), &PDesc.CodingStyleDefault, csd_size);
+  EssenceSubDescriptor->CodingStyleDefault.Length(csd_size);
+
+  ui32_t qdflt_size = PDesc.QuantizationDefault.SPqcdLength + 1;
+  memcpy(EssenceSubDescriptor->QuantizationDefault.Data(), &PDesc.QuantizationDefault, qdflt_size);
+  EssenceSubDescriptor->QuantizationDefault.Length(qdflt_size);
+
+  return RESULT_OK;
+}
 
-  Result_t    OpenRead(const char*, EssenceType_t);
-  Result_t    ReadFrame(ui32_t, JP2K::FrameBuffer&, AESDecContext*, HMACContext*);
-};
 
 //
 ASDCP::Result_t
-ASDCP::MD_to_JP2K_PDesc(const ASDCP::MXF::RGBAEssenceDescriptor&  EssenceDescriptor,
+ASDCP::MD_to_JP2K_PDesc(const ASDCP::MXF::CDCIEssenceDescriptor&  EssenceDescriptor,
                        const ASDCP::MXF::JPEG2000PictureSubDescriptor& EssenceSubDescriptor,
                        const ASDCP::Rational& EditRate, const ASDCP::Rational& SampleRate,
                        ASDCP::JP2K::PictureDescriptor& PDesc)
@@ -378,6 +482,35 @@ epsilon_compare(const ASDCP::Rational& left, const ASDCP::Rational& right, doubl
 }
 // end DOLBY
 
+
+//------------------------------------------------------------------------------------------
+//
+// hidden, internal implementation of JPEG 2000 reader
+
+
+class lh__Reader : public ASDCP::h__ASDCPReader
+{
+  RGBAEssenceDescriptor*        m_EssenceDescriptor;
+  JPEG2000PictureSubDescriptor* m_EssenceSubDescriptor;
+  ASDCP::Rational               m_EditRate;
+  ASDCP::Rational               m_SampleRate;
+  EssenceType_t                 m_Format;
+
+  ASDCP_NO_COPY_CONSTRUCT(lh__Reader);
+
+public:
+  PictureDescriptor m_PDesc;        // codestream parameter list
+
+  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*);
+};
+
+
 //
 //
 ASDCP::Result_t
@@ -391,9 +524,22 @@ lh__Reader::OpenRead(const char* filename, EssenceType_t type)
       m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(RGBAEssenceDescriptor), &tmp_iobj);
       m_EssenceDescriptor = static_cast<RGBAEssenceDescriptor*>(tmp_iobj);
 
+      if ( m_EssenceDescriptor == 0 )
+       {
+         DefaultLogSink().Error("RGBAEssenceDescriptor object not found.\n");
+         return RESULT_FORMAT;
+       }
+
       m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(JPEG2000PictureSubDescriptor), &tmp_iobj);
       m_EssenceSubDescriptor = static_cast<JPEG2000PictureSubDescriptor*>(tmp_iobj);
 
+      if ( m_EssenceSubDescriptor == 0 )
+       {
+         m_EssenceDescriptor = 0;
+         DefaultLogSink().Error("JPEG2000PictureSubDescriptor object not found.\n");
+         return RESULT_FORMAT;
+       }
+
       std::list<InterchangeObject*> ObjectList;
       m_HeaderPart.GetMDObjectsByType(OBJ_TYPE_ARGS(Track), ObjectList);
 
@@ -490,8 +636,6 @@ lh__Reader::OpenRead(const char* filename, EssenceType_t type)
          return RESULT_STATE;
        }
 
-      assert(m_EssenceDescriptor);
-      assert(m_EssenceSubDescriptor);
       result = MD_to_JP2K_PDesc(*m_EssenceDescriptor, *m_EssenceSubDescriptor, m_EditRate, m_SampleRate, m_PDesc);
     }
 
index 0ddfa45e6b1eba804daaf231f3e36a2db979cfb7..6dc34f2f9ac5594d81f22d26b71279dafbf6a4dc 100755 (executable)
@@ -187,10 +187,16 @@ ASDCP::MPEG2::MXFReader::h__Reader::OpenRead(const char* filename)
 
   if( ASDCP_SUCCESS(result) )
     {
-      InterchangeObject* Object;
+      InterchangeObject* Object = 0;
+
       if ( ASDCP_SUCCESS(m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(MPEG2VideoDescriptor), &Object)) )
        {
-         assert(Object);
+         if ( Object == 0 )
+           {
+             DefaultLogSink().Error("MPEG2VideoDescriptor object not found.\n");
+             return RESULT_FORMAT;
+           }
+
          result = MD_to_MPEG2_VDesc((MXF::MPEG2VideoDescriptor*)Object, m_VDesc);
        }
     }
index a9ff152730ebc931c430e68ad9e9fb38b2ebd437..f3ad310ed2bde3effb793e13f11a7b62213ee12b 100755 (executable)
@@ -164,6 +164,8 @@ ASDCP::Result_t
 ASDCP::EssenceType(const char* filename, EssenceType_t& type)
 {
   const Dictionary* m_Dict = &DefaultCompositeDict();
+  InterchangeObject* md_object = 0;
+
   assert(m_Dict);
 
   ASDCP_TEST_NULL_STR(filename);
@@ -178,26 +180,48 @@ ASDCP::EssenceType(const char* filename, EssenceType_t& type)
   if ( ASDCP_SUCCESS(result) )
     {
       type = ESS_UNKNOWN;
-      if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(RGBAEssenceDescriptor))) )
+      if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(JPEG2000PictureSubDescriptor))) )
        {
          if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(StereoscopicPictureSubDescriptor))) )
-           type = ESS_JPEG_2000_S;
+           {
+             type = ESS_JPEG_2000_S;
+           }
          else
-           type = ESS_JPEG_2000;
+           {
+             type = ESS_JPEG_2000;
+           }
+       }
+      else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(WaveAudioDescriptor), &md_object)) )
+       {
+         assert(md_object);
+         if ( static_cast<ASDCP::MXF::WaveAudioDescriptor*>(md_object)->AudioSamplingRate == SampleRate_96k )
+           {
+             type = ESS_PCM_24b_96k;
+           }
+         else
+           {
+             type = ESS_PCM_24b_48k;
+           }
        }
-      else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(WaveAudioDescriptor))) )
-       type = ESS_PCM_24b_48k;
       else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(MPEG2VideoDescriptor))) )
+       {
        type = ESS_MPEG2_VES;
+       }
       else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(TimedTextDescriptor))) )
+       {
        type = ESS_TIMED_TEXT;
+       }
       else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(DCDataDescriptor))) )
-      {
-        if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(DolbyAtmosSubDescriptor))) )
-          type = ESS_DCDATA_DOLBY_ATMOS;
-        else
-          type = ESS_DCDATA_UNKNOWN;
-      }
+       {
+         if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(DolbyAtmosSubDescriptor))) )
+           {
+             type = ESS_DCDATA_DOLBY_ATMOS;
+           }
+         else
+           {
+             type = ESS_DCDATA_UNKNOWN;
+           }
+       }
     }
 
   return result;
index 2109999df868a4ea253b63152e7baf6dcaed14c6..c126f2515878482cd8801f983c72923fb3564f50 100755 (executable)
@@ -251,10 +251,16 @@ ASDCP::PCM::MXFReader::h__Reader::OpenRead(const char* filename)
 
   if( ASDCP_SUCCESS(result) )
     {
-      InterchangeObject* Object;
+      InterchangeObject* Object = 0
+;
       if ( ASDCP_SUCCESS(m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(WaveAudioDescriptor), &Object)) )
        {
-         assert(Object);
+         if ( Object == 0 )
+           {
+             DefaultLogSink().Error("WaveAudioDescriptor object not found.\n");
+             return RESULT_FORMAT;
+           }
+
          result = MD_to_PCM_ADesc((MXF::WaveAudioDescriptor*)Object, m_ADesc);
        }
     }
index 81889433baee7f370beb18f5be815be4bdf44cc4..6fa4fa19b58901de33943cc18e6584849becac63 100755 (executable)
@@ -142,6 +142,16 @@ namespace ASDCP
                            ASDCP::MXF::RGBAEssenceDescriptor *EssenceDescriptor,
                            ASDCP::MXF::JPEG2000PictureSubDescriptor *EssenceSubDescriptor);
 
+  Result_t MD_to_JP2K_PDesc(const ASDCP::MXF::CDCIEssenceDescriptor&  EssenceDescriptor,
+                           const ASDCP::MXF::JPEG2000PictureSubDescriptor& EssenceSubDescriptor,
+                           const ASDCP::Rational& EditRate, const ASDCP::Rational& SampleRate,
+                           ASDCP::JP2K::PictureDescriptor& PDesc);
+
+  Result_t JP2K_PDesc_to_MD(const JP2K::PictureDescriptor& PDesc,
+                           const ASDCP::Dictionary& dict,
+                           ASDCP::MXF::CDCIEssenceDescriptor *EssenceDescriptor,
+                           ASDCP::MXF::JPEG2000PictureSubDescriptor *EssenceSubDescriptor);
+
   Result_t PCM_ADesc_to_MD(PCM::AudioDescriptor& ADesc, ASDCP::MXF::WaveAudioDescriptor* ADescObj);
   Result_t MD_to_PCM_ADesc(ASDCP::MXF::WaveAudioDescriptor* ADescObj, PCM::AudioDescriptor& ADesc);
 
@@ -308,7 +318,7 @@ namespace ASDCP
              result = m_File.Seek(FilePosition);
            }
 
-         if( KM_SUCCESS(result) )
+         if ( KM_SUCCESS(result) )
            result = ReadEKLVPacket(FrameNum, FrameNum + 1, FrameBuf, EssenceUL, Ctx, HMAC);
 
          return result;
@@ -464,7 +474,6 @@ namespace ASDCP
        ui32_t             m_HeaderSize;
        HeaderType         m_HeaderPart;
        RIP                m_RIP;
-       ui64_t             m_EssenceStart;
 
        MaterialPackage*   m_MaterialPackage;
        SourcePackage*     m_FilePackage;
@@ -483,7 +492,7 @@ namespace ASDCP
 
       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_HeaderSize(0), m_EssenceDescriptor(0),
          m_FramesWritten(0), m_StreamOffset(0)
          {
            default_md_object_init();
index f37758516411b9969060999217ee04546735bebd..42bdce0d4e984a7282e74096f1b3b0a8f687203f 100755 (executable)
@@ -136,7 +136,7 @@ ASDCP::MXF::IndexTableSegment::Dump(FILE* stream)
 
   fprintf(stream, "  DeltaEntryArray:\n");  DeltaEntryArray.Dump(stream);
 
-  if ( IndexEntryArray.size() < 100 )
+  if ( IndexEntryArray.size() < 1000 )
     {
       fprintf(stream, "  IndexEntryArray:\n");
       IndexEntryArray.Dump(stream);
index babbec74ea98ace1f97bdbb772dd9efe919bc590..ad34095de8a91ffcb144764b383872162abefaf7 100755 (executable)
@@ -58,7 +58,7 @@ ASDCP::MXF::SeekToRIP(const Kumu::FileReader& Reader)
   if ( ASDCP_SUCCESS(result)
        && end_pos < (SMPTE_UL_LENGTH+MXF_BER_LENGTH) )
     {
-      DefaultLogSink().Error("File is smaller than an KLV empty packet.\n");
+      DefaultLogSink().Error("File is smaller than an empty KLV packet.\n");
       result = RESULT_FAIL;
     }
 
index 6cb90e26102dcd434274ba40877c3336936a2bfc..6e6850773a4627a85939200e58e7d0a0eaac9922 100755 (executable)
@@ -273,7 +273,7 @@ read_JP2K_file(CommandOptions& Options)
 {
   AESDecContext*     Context = 0;
   HMACContext*       HMAC = 0;
-  JP2K::MXFReader    Reader;
+  AS_02::JP2K::MXFReader    Reader;
   JP2K::FrameBuffer  FrameBuffer(Options.fb_size);
   ui32_t             frame_count = 0;
 
@@ -357,7 +357,7 @@ read_PCM_file(CommandOptions& Options)
 {
   AESDecContext*     Context = 0;
   HMACContext*       HMAC = 0;
-  PCM::MXFReader     Reader;
+  AS_02::PCM::MXFReader     Reader;
   PCM::FrameBuffer   FrameBuffer;
   WavFileWriter      OutWave;
   PCM::AudioDescriptor ADesc;
index a879caba5a87fbfb5e5c001f23ce5d28abe11f5a..6f7901281fe4f7df339f2f56bf1cdf0b1121b188 100755 (executable)
@@ -460,7 +460,7 @@ write_PCM_file(CommandOptions& Options)
   AESEncContext*    Context = 0;
   HMACContext*      HMAC = 0;
   PCMParserList     Parser;
-  PCM::MXFWriter    Writer;
+  AS_02::PCM::MXFWriter    Writer;
   PCM::FrameBuffer  FrameBuffer;
   PCM::AudioDescriptor ADesc;
   byte_t            IV_buf[CBC_BLOCK_SIZE];
index d4708385ac2d3ebe99cb167cd6b2eb0036c403f4..77f0cdbbcb1c01403fef3ab89301f1415565e341 100644 (file)
@@ -58,13 +58,196 @@ AS_02::default_md_object_init()
 }
 
 
+//---------------------------------------------------------------------------------
+//
+
+    
+AS_02::MXF::AS02IndexReader::AS02IndexReader(const ASDCP::Dictionary*& d) : m_Duration(0), ASDCP::MXF::Partition(m_Dict), m_Dict(d) {}
+AS_02::MXF::AS02IndexReader::~AS02IndexReader() {}
+
+//    
+Result_t
+AS_02::MXF::AS02IndexReader::InitFromFile(const Kumu::FileReader& reader, const ASDCP::MXF::RIP& rip)
+{
+  ASDCP::MXF::Array<ASDCP::MXF::RIP::Pair>::const_iterator i;
+
+  Result_t result = m_IndexSegmentData.Capacity(128*Kumu::Kilobyte);
+
+  for ( i = rip.PairArray.begin(); KM_SUCCESS(result) && i != rip.PairArray.end(); ++i )
+    {
+      reader.Seek(i->ByteOffset);
+      ASDCP::MXF::Partition plain_part(m_Dict);
+      result = plain_part.InitFromFile(reader);
+
+      if ( KM_SUCCESS(result) && plain_part.IndexByteCount > 0 )
+       {
+         // slurp up the remainder of the footer
+         ui32_t read_count = 0;
+
+         assert (plain_part.IndexByteCount <= 0xFFFFFFFFL);
+         ui32_t bytes_this_partition = (ui32_t)plain_part.IndexByteCount;
+
+         result = m_IndexSegmentData.Capacity(m_IndexSegmentData.Length() + bytes_this_partition);
+
+         if ( ASDCP_SUCCESS(result) )
+           result = reader.Read(m_IndexSegmentData.Data() + m_IndexSegmentData.Length(),
+                                bytes_this_partition, &read_count);
+
+         if ( ASDCP_SUCCESS(result) && read_count != bytes_this_partition )
+           {
+             DefaultLogSink().Error("Short read of footer partition: got %u, expecting %u\n",
+                                    read_count, bytes_this_partition);
+             return RESULT_FAIL;
+           }
+
+         if ( ASDCP_SUCCESS(result) )
+           {
+             result = InitFromBuffer(m_IndexSegmentData.RoData() + m_IndexSegmentData.Length(), bytes_this_partition);
+             m_IndexSegmentData.Length(m_IndexSegmentData.Length() + bytes_this_partition);
+           }
+       }
+    }
+
+  return result;
+}
+
+//
+ASDCP::Result_t
+AS_02::MXF::AS02IndexReader::InitFromBuffer(const byte_t* p, ui32_t l)
+{
+  Result_t result = RESULT_OK;
+  const byte_t* end_p = p + l;
+
+  while ( ASDCP_SUCCESS(result) && p < end_p )
+    {
+      // parse the packets and index them by uid, discard KLVFill items
+      InterchangeObject* object = CreateObject(m_Dict, p);
+      assert(object);
+
+      object->m_Lookup = m_Lookup;
+      result = object->InitFromBuffer(p, end_p - p);
+      p += object->PacketLength();
+
+      if ( ASDCP_SUCCESS(result) )
+       {
+         m_PacketList->AddPacket(object); // takes ownership
+       }
+      else
+       {
+         DefaultLogSink().Error("Error initializing packet\n");
+         delete object;
+       }
+    }
+
+  if ( ASDCP_FAILURE(result) )
+    DefaultLogSink().Error("Failed to initialize AS02IndexReader\n");
+
+  std::list<InterchangeObject*>::const_iterator i;
+  
+  for ( i = m_PacketList->m_List.begin(); i != m_PacketList->m_List.end(); ++i )
+    {
+      if ( (*i)->IsA(OBJ_TYPE_ARGS(IndexTableSegment)) )
+       {
+         m_Duration += static_cast<IndexTableSegment*>(*i)->IndexDuration;
+       }
+    }
+
+  return result;
+}
+
+//
+void
+AS_02::MXF::AS02IndexReader::Dump(FILE* stream)
+{
+  if ( stream == 0 )
+    stream = stderr;
+
+  std::list<InterchangeObject*>::iterator i = m_PacketList->m_List.begin();
+  for ( ; i != m_PacketList->m_List.end(); ++i )
+    (*i)->Dump(stream);
+}
+
+//
+Result_t
+AS_02::MXF::AS02IndexReader::GetMDObjectByID(const UUID& object_id, InterchangeObject** Object)
+{
+  return m_PacketList->GetMDObjectByID(object_id, Object);
+}
+
+//
+Result_t
+AS_02::MXF::AS02IndexReader::GetMDObjectByType(const byte_t* type_id, InterchangeObject** Object)
+{
+  InterchangeObject* TmpObject;
+
+  if ( Object == 0 )
+    Object = &TmpObject;
+
+  return m_PacketList->GetMDObjectByType(type_id, Object);
+}
+
+//
+Result_t
+AS_02::MXF::AS02IndexReader::GetMDObjectsByType(const byte_t* ObjectID, std::list<ASDCP::MXF::InterchangeObject*>& ObjectList)
+{
+  return m_PacketList->GetMDObjectsByType(ObjectID, ObjectList);
+}
+
+
+//
+ui32_t
+AS_02::MXF::AS02IndexReader::GetDuration() const
+{
+  return m_Duration;
+}
+   
+
+//
+Result_t
+AS_02::MXF::AS02IndexReader::Lookup(ui32_t frame_num, ASDCP::MXF::IndexTableSegment::IndexEntry& Entry) const
+{
+  std::list<InterchangeObject*>::iterator li;
+  for ( li = m_PacketList->m_List.begin(); li != m_PacketList->m_List.end(); li++ )
+    {
+      if ( (*li)->IsA(OBJ_TYPE_ARGS(IndexTableSegment)) )
+       {
+         IndexTableSegment* Segment = (IndexTableSegment*)(*li);
+         ui64_t start_pos = Segment->IndexStartPosition;
+
+         if ( Segment->EditUnitByteCount > 0 )
+           {
+             if ( m_PacketList->m_List.size() > 1 )
+               DefaultLogSink().Error("Unexpected multiple IndexTableSegment in CBR file\n");
+
+             if ( ! Segment->IndexEntryArray.empty() )
+               DefaultLogSink().Error("Unexpected IndexEntryArray contents in CBR file\n");
+
+             Entry.StreamOffset = (ui64_t)frame_num * Segment->EditUnitByteCount;
+             return RESULT_OK;
+           }
+         else if ( (ui64_t)frame_num >= start_pos
+                   && (ui64_t)frame_num < (start_pos + Segment->IndexDuration) )
+           {
+             ui64_t tmp = frame_num - start_pos;
+             assert(tmp <= 0xFFFFFFFFL);
+             Entry = Segment->IndexEntryArray[(ui32_t) tmp];
+             return RESULT_OK;
+           }
+       }
+    }
+
+  return RESULT_FAIL;
+}
+
+
+//---------------------------------------------------------------------------------
+//
 
 
 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() {}
 
 
-
 // AS-DCP method of opening an MXF file for read
 Result_t
 AS_02::h__AS02Reader::OpenMXFRead(const char* filename)
@@ -77,10 +260,11 @@ AS_02::h__AS02Reader::OpenMXFRead(const char* filename)
   if( KM_SUCCESS(result) )
     {
       //
+      UL OP1a_ul(m_Dict->ul(MDD_OP1a));
       InterchangeObject* Object;
       m_Info.LabelSetType = LS_MXF_SMPTE;
 
-      if ( ! m_HeaderPart.OperationalPattern.ExactMatch(SMPTE_390_OPAtom_Entry().ul) )
+      if ( m_HeaderPart.OperationalPattern != OP1a_ul )
        {
          char strbuf[IdentBufferLen];
          const MDDEntry* Entry = m_Dict->FindUL(m_HeaderPart.OperationalPattern.Value());
@@ -107,14 +291,8 @@ AS_02::h__AS02Reader::OpenMXFRead(const char* filename)
   if ( KM_SUCCESS(result) )
     {
       m_HeaderPart.BodyOffset = m_File.Tell();
-
-      result = m_File.Seek(m_HeaderPart.FooterPartition);
-
-      if ( ASDCP_SUCCESS(result) )
-       {
-         m_IndexAccess.m_Lookup = &m_HeaderPart.m_Primer;
-         result = m_IndexAccess.InitFromFile(m_File);
-       }
+      m_IndexAccess.m_Lookup = &m_HeaderPart.m_Primer;
+      result = m_IndexAccess.InitFromFile(m_File, m_RIP);
     }
 
   m_File.Seek(m_HeaderPart.BodyOffset);
index 8a4b073bdffc0ecb2533f8f84ed919aecf6a6c34..598431b8c833499f92e99d8527c9f8248367a52c 100644 (file)
@@ -251,6 +251,7 @@ AS_02::h__AS02Writer::WriteAS02Header(const std::string& PackageLabel, const ASD
   AddEssenceDescriptor(WrappingUL);
   m_RIP.PairArray.push_back(RIP::Pair(0, 0)); // Header partition RIP entry
   m_IndexWriter.OperationalPattern = m_HeaderPart.OperationalPattern;
+  m_IndexWriter.EssenceContainers = m_HeaderPart.EssenceContainers;
 
   Result_t result = m_HeaderPart.WriteToFile(m_File, m_HeaderSize);
 
@@ -273,10 +274,10 @@ AS_02::h__AS02Writer::WriteAS02Header(const std::string& PackageLabel, const ASD
       Partition body_part(m_Dict);
       body_part.BodySID = 1;
       body_part.OperationalPattern = m_HeaderPart.OperationalPattern;
+      body_part.EssenceContainers = m_HeaderPart.EssenceContainers;
       body_part.ThisPartition = m_File.Tell();
       result = body_part.WriteToFile(m_File, body_ul);
       m_RIP.PairArray.push_back(RIP::Pair(1, body_part.ThisPartition)); // Second RIP Entry
-
     }
 
   return result;
@@ -293,12 +294,13 @@ AS_02::h__AS02Writer::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf,const b
     {
       m_IndexWriter.ThisPartition = m_File.Tell();
       m_IndexWriter.WriteToFile(m_File);
-      m_RIP.PairArray.push_back(RIP::Pair(129, m_IndexWriter.ThisPartition));
+      m_RIP.PairArray.push_back(RIP::Pair(0, m_IndexWriter.ThisPartition));
 
       UL body_ul(m_Dict->ul(MDD_ClosedCompleteBodyPartition));
       Partition body_part(m_Dict);
       body_part.BodySID = 1;
       body_part.OperationalPattern = m_HeaderPart.OperationalPattern;
+      body_part.EssenceContainers = m_HeaderPart.EssenceContainers;
       body_part.ThisPartition = m_File.Tell();
       result = body_part.WriteToFile(m_File, body_ul);
       m_RIP.PairArray.push_back(RIP::Pair(1, body_part.ThisPartition));
@@ -318,7 +320,7 @@ AS_02::h__AS02Writer::WriteAS02Footer()
     {
       m_IndexWriter.ThisPartition = m_File.Tell();
       m_IndexWriter.WriteToFile(m_File);
-      m_RIP.PairArray.push_back(RIP::Pair(129, m_IndexWriter.ThisPartition));
+      m_RIP.PairArray.push_back(RIP::Pair(0, m_IndexWriter.ThisPartition));
     }
 
   // update all Duration properties
@@ -363,15 +365,15 @@ AS_02::h__AS02Writer::WriteAS02Footer()
 
       for ( i = m_RIP.PairArray.begin(); ASDCP_SUCCESS(result) && i != m_RIP.PairArray.end(); ++i )
        {
-         if ( i->BodySID == 0 )
-           continue;
-
+         ASDCP::MXF::Partition plain_part(m_Dict);
          result = m_File.Seek(i->ByteOffset);
 
          if ( ASDCP_SUCCESS(result) )
+           result = plain_part.InitFromFile(m_File);
+      
+         if ( KM_SUCCESS(result)
+              && ( plain_part.IndexSID > 0 || plain_part.BodySID > 0 ) )
            {
-             ASDCP::MXF::Partition plain_part(m_Dict);
-             plain_part.InitFromFile(m_File);
              plain_part.PreviousPartition = previous_partition;
              plain_part.FooterPartition = footer_part.ThisPartition;
              previous_partition = plain_part.ThisPartition;
index 6ef04744b4cdd53e5bb8bbfea77f226d12d42300..b7550e61e71d638e8baf15b240e5321659737c65 100755 (executable)
@@ -225,7 +225,7 @@ main(int argc, const char** argv)
            }
          else
            {
-             DefaultLogSink().Error("ASDCP::h__Reader::OpenMXFRead, SeekToRIP failed\n");
+             DefaultLogSink().Error("read_mxf SeekToRIP failed: %s\n", result.Label());
            }
 
          if ( ASDCP_SUCCESS(result) )
@@ -302,11 +302,13 @@ main(int argc, const char** argv)
            }
          else
            {
-             DefaultLogSink().Error("ASDCP::h__Reader::OpenMXFRead, SeekToRIP failed\n");
+             DefaultLogSink().Error("walk_parts SeekToRIP failed: %s\n", result.Label());
            }
 
          if ( ASDCP_SUCCESS(result) )
            {
+             RIP.Dump();
+
              MXF::Array<MXF::RIP::Pair>::const_iterator i;
              for ( i = RIP.PairArray.begin(); i != RIP.PairArray.end(); ++i )
                {