diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/AS_02.h | 99 | ||||
| -rw-r--r-- | src/AS_02_JP2K.cpp | 113 | ||||
| -rw-r--r-- | src/AS_02_PCM.cpp | 9 | ||||
| -rw-r--r-- | src/AS_02_internal.h | 22 | ||||
| -rw-r--r-- | src/AS_DCP_ATMOS.cpp | 30 | ||||
| -rw-r--r-- | src/AS_DCP_DCData.cpp | 28 | ||||
| -rwxr-xr-x | src/AS_DCP_JP2K.cpp | 184 | ||||
| -rwxr-xr-x | src/AS_DCP_MPEG2.cpp | 10 | ||||
| -rwxr-xr-x | src/AS_DCP_MXF.cpp | 46 | ||||
| -rwxr-xr-x | src/AS_DCP_PCM.cpp | 10 | ||||
| -rwxr-xr-x | src/AS_DCP_internal.h | 15 | ||||
| -rwxr-xr-x | src/Index.cpp | 2 | ||||
| -rwxr-xr-x | src/MXF.cpp | 2 | ||||
| -rwxr-xr-x | src/as-02-unwrap.cpp | 4 | ||||
| -rwxr-xr-x | src/as-02-wrap.cpp | 2 | ||||
| -rw-r--r-- | src/h__02_Reader.cpp | 198 | ||||
| -rw-r--r-- | src/h__02_Writer.cpp | 18 | ||||
| -rwxr-xr-x | src/klvwalk.cpp | 6 |
18 files changed, 530 insertions, 268 deletions
diff --git a/src/AS_02.h b/src/AS_02.h index dc6fc61..e4be1b8 100644 --- a/src/AS_02.h +++ b/src/AS_02.h @@ -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 diff --git a/src/AS_02_JP2K.cpp b/src/AS_02_JP2K.cpp index 38b2e55..aeb6dbc 100644 --- a/src/AS_02_JP2K.cpp +++ b/src/AS_02_JP2K.cpp @@ -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
- //Container of first Essence Element in this Edit Unit of
- //stored Essence within the Essence Container Stream - //this->m_StreamOffset = 0; ??? - - //Complete the Index-BodyPartion - result = CompleteIndexBodyPart();
- //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. // diff --git a/src/AS_02_PCM.cpp b/src/AS_02_PCM.cpp index b82e1f0..9c52591 100644 --- a/src/AS_02_PCM.cpp +++ b/src/AS_02_PCM.cpp @@ -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); } } diff --git a/src/AS_02_internal.h b/src/AS_02_internal.h index 87e8451..cf9c368 100644 --- a/src/AS_02_internal.h +++ b/src/AS_02_internal.h @@ -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(); diff --git a/src/AS_DCP_ATMOS.cpp b/src/AS_DCP_ATMOS.cpp index 63b5557..e8a2a8a 100644 --- a/src/AS_DCP_ATMOS.cpp +++ b/src/AS_DCP_ATMOS.cpp @@ -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; } diff --git a/src/AS_DCP_DCData.cpp b/src/AS_DCP_DCData.cpp index 6ee1098..faa02a0 100644 --- a/src/AS_DCP_DCData.cpp +++ b/src/AS_DCP_DCData.cpp @@ -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 diff --git a/src/AS_DCP_JP2K.cpp b/src/AS_DCP_JP2K.cpp index df4f6a2..1aec48e 100755 --- a/src/AS_DCP_JP2K.cpp +++ b/src/AS_DCP_JP2K.cpp @@ -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); } diff --git a/src/AS_DCP_MPEG2.cpp b/src/AS_DCP_MPEG2.cpp index 0ddfa45..6dc34f2 100755 --- a/src/AS_DCP_MPEG2.cpp +++ b/src/AS_DCP_MPEG2.cpp @@ -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); } } diff --git a/src/AS_DCP_MXF.cpp b/src/AS_DCP_MXF.cpp index a9ff152..f3ad310 100755 --- a/src/AS_DCP_MXF.cpp +++ b/src/AS_DCP_MXF.cpp @@ -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; diff --git a/src/AS_DCP_PCM.cpp b/src/AS_DCP_PCM.cpp index 2109999..c126f25 100755 --- a/src/AS_DCP_PCM.cpp +++ b/src/AS_DCP_PCM.cpp @@ -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); } } diff --git a/src/AS_DCP_internal.h b/src/AS_DCP_internal.h index 8188943..6fa4fa1 100755 --- a/src/AS_DCP_internal.h +++ b/src/AS_DCP_internal.h @@ -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(); diff --git a/src/Index.cpp b/src/Index.cpp index f377585..42bdce0 100755 --- a/src/Index.cpp +++ b/src/Index.cpp @@ -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); diff --git a/src/MXF.cpp b/src/MXF.cpp index babbec7..ad34095 100755 --- a/src/MXF.cpp +++ b/src/MXF.cpp @@ -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; } diff --git a/src/as-02-unwrap.cpp b/src/as-02-unwrap.cpp index 6cb90e2..6e68507 100755 --- a/src/as-02-unwrap.cpp +++ b/src/as-02-unwrap.cpp @@ -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; diff --git a/src/as-02-wrap.cpp b/src/as-02-wrap.cpp index a879cab..6f79012 100755 --- a/src/as-02-wrap.cpp +++ b/src/as-02-wrap.cpp @@ -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]; diff --git a/src/h__02_Reader.cpp b/src/h__02_Reader.cpp index d470838..77f0cdb 100644 --- a/src/h__02_Reader.cpp +++ b/src/h__02_Reader.cpp @@ -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); diff --git a/src/h__02_Writer.cpp b/src/h__02_Writer.cpp index 8a4b073..598431b 100644 --- a/src/h__02_Writer.cpp +++ b/src/h__02_Writer.cpp @@ -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; diff --git a/src/klvwalk.cpp b/src/klvwalk.cpp index 6ef0474..b7550e6 100755 --- a/src/klvwalk.cpp +++ b/src/klvwalk.cpp @@ -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 ) { |
