diff options
| author | jhurst <jhurst@cinecert.com> | 2013-06-17 17:55:54 +0000 |
|---|---|---|
| committer | jhurst <> | 2013-06-17 17:55:54 +0000 |
| commit | ba6e57635ce6482fa9dcd6a824b579edb459b834 (patch) | |
| tree | f354c0297a4233f9cb89396b2fa9fac893ba8140 /src/AS_02_JP2K.cpp | |
| parent | e54f387729bacc2d3e8c93aeb59ee45181d6f714 (diff) | |
tweezes
Diffstat (limited to 'src/AS_02_JP2K.cpp')
| -rw-r--r-- | src/AS_02_JP2K.cpp | 262 |
1 files changed, 125 insertions, 137 deletions
diff --git a/src/AS_02_JP2K.cpp b/src/AS_02_JP2K.cpp index aeb6dbc..79ea382 100644 --- a/src/AS_02_JP2K.cpp +++ b/src/AS_02_JP2K.cpp @@ -1,28 +1,30 @@ /* - 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 - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +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 +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file AS_02_JP2K.cpp \version $Id$ @@ -50,60 +52,47 @@ static std::string PICT_DEF_LABEL = "Image Track"; class AS_02::JP2K::MXFReader::h__Reader : public AS_02::h__AS02Reader { - RGBAEssenceDescriptor* m_RGBAEssenceDescriptor; - CDCIEssenceDescriptor* m_CDCIEssenceDescriptor; - JPEG2000PictureSubDescriptor* m_EssenceSubDescriptor; - ASDCP::Rational m_EditRate; - ASDCP::Rational m_SampleRate; - EssenceType_t m_Format; - ASDCP_NO_COPY_CONSTRUCT(h__Reader); public: PictureDescriptor m_PDesc; // codestream parameter list h__Reader(const Dictionary& d) : - AS_02::h__AS02Reader(d), m_RGBAEssenceDescriptor(0), m_CDCIEssenceDescriptor(0), - m_EssenceSubDescriptor(0), m_Format(ESS_UNKNOWN) {} + AS_02::h__AS02Reader(d) {} virtual ~h__Reader() {} - Result_t OpenRead(const char*); + Result_t OpenRead(const std::string&); Result_t ReadFrame(ui32_t, ASDCP::JP2K::FrameBuffer&, AESDecContext*, HMACContext*); }; // Result_t -AS_02::JP2K::MXFReader::h__Reader::OpenRead(const char* filename) +AS_02::JP2K::MXFReader::h__Reader::OpenRead(const std::string& filename) { - Result_t result = OpenMXFRead(filename); + Result_t result = OpenMXFRead(filename.c_str()); - if( ASDCP_SUCCESS(result) ) + if( KM_SUCCESS(result) ) { InterchangeObject* tmp_iobj = 0; m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(CDCIEssenceDescriptor), &tmp_iobj); - m_CDCIEssenceDescriptor = static_cast<CDCIEssenceDescriptor*>(tmp_iobj); - if ( m_CDCIEssenceDescriptor == 0 ) + if ( tmp_iobj == 0 ) { m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(RGBAEssenceDescriptor), &tmp_iobj); - m_RGBAEssenceDescriptor = static_cast<RGBAEssenceDescriptor*>(tmp_iobj); } - if ( m_CDCIEssenceDescriptor == 0 && m_RGBAEssenceDescriptor == 0 ) + if ( tmp_iobj == 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 ) + if ( tmp_iobj == 0 ) { DefaultLogSink().Error("JPEG2000PictureSubDescriptor not found.\n"); - return RESULT_FORMAT; } std::list<InterchangeObject*> ObjectList; @@ -112,25 +101,7 @@ AS_02::JP2K::MXFReader::h__Reader::OpenRead(const char* filename) if ( ObjectList.empty() ) { DefaultLogSink().Error("MXF Metadata contains no Track Sets.\n"); - return RESULT_FORMAT; - } - - if ( m_CDCIEssenceDescriptor != 0 ) - { - 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 if ( m_RGBAEssenceDescriptor != 0 ) - { - 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); - } - - if ( m_PDesc.ContainerDuration == 0 ) - { - m_PDesc.ContainerDuration = m_IndexAccess.GetDuration(); + return RESULT_AS02_FORMAT; } } @@ -211,38 +182,35 @@ AS_02::JP2K::MXFReader::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 +AS_02::JP2K::MXFReader::OpenRead(const std::string& filename) const { return m_Reader->OpenRead(filename); } // Result_t -AS_02::JP2K::MXFReader::ReadFrame(ui32_t FrameNum, ASDCP::JP2K::FrameBuffer& FrameBuf, - ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC) const +AS_02::JP2K::MXFReader::Close() const { if ( m_Reader && m_Reader->m_File.IsOpen() ) - return m_Reader->ReadFrame(FrameNum, FrameBuf, Ctx, HMAC); + { + m_Reader->Close(); + return RESULT_OK; + } return RESULT_INIT; } - -// Fill the struct with the values from the file's header. -// Returns RESULT_INIT if the file is not open. +// Result_t -AS_02::JP2K::MXFReader::FillPictureDescriptor(PictureDescriptor& PDesc) const +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() ) - { - PDesc = m_Reader->m_PDesc; - return RESULT_OK; - } + return m_Reader->ReadFrame(FrameNum, FrameBuf, Ctx, HMAC); return RESULT_INIT; } - // Fill the struct with the values from the file's header. // Returns RESULT_INIT if the file is not open. Result_t @@ -278,10 +246,11 @@ public: virtual ~h__Writer(){} - Result_t OpenWrite(const char*, EssenceType_t type, const AS_02::IndexStrategy_t& IndexStrategy, + Result_t OpenWrite(const std::string&, ASDCP::MXF::FileDescriptor* essence_descriptor, + ASDCP::MXF::InterchangeObject_list_t& essence_sub_descriptor_list, + 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 SetSourceStream(const std::string& label, const ASDCP::Rational& edit_rate); Result_t WriteFrame(const ASDCP::JP2K::FrameBuffer&, ASDCP::AESEncContext*, ASDCP::HMACContext*); Result_t Finalize(); }; @@ -290,11 +259,16 @@ public: // Open the file for writing. The file must not exist. Returns error if // the operation cannot be completed. Result_t -AS_02::JP2K::MXFWriter::h__Writer::OpenWrite(const char* filename, EssenceType_t type, const AS_02::IndexStrategy_t& IndexStrategy, +AS_02::JP2K::MXFWriter::h__Writer::OpenWrite(const std::string& filename, + ASDCP::MXF::FileDescriptor* essence_descriptor, + ASDCP::MXF::InterchangeObject_list_t& essence_sub_descriptor_list, + const AS_02::IndexStrategy_t& IndexStrategy, const ui32_t& PartitionSpace_sec, const ui32_t& HeaderSize) { if ( ! m_State.Test_BEGIN() ) - return RESULT_STATE; + { + return RESULT_STATE; + } if ( m_IndexStrategy != AS_02::IS_FOLLOW ) { @@ -302,20 +276,39 @@ AS_02::JP2K::MXFWriter::h__Writer::OpenWrite(const char* filename, EssenceType_t return Kumu::RESULT_NOTIMPL; } - Result_t result = m_File.OpenWrite(filename); + Result_t result = m_File.OpenWrite(filename.c_str()); - if ( ASDCP_SUCCESS(result) ) + if ( KM_SUCCESS(result) ) { m_IndexStrategy = IndexStrategy; m_PartitionSpace = PartitionSpace_sec; // later converted to edit units by SetSourceStream() m_HeaderSize = HeaderSize; - m_EssenceDescriptor = new RGBAEssenceDescriptor(m_Dict); - m_EssenceSubDescriptor = new JPEG2000PictureSubDescriptor(m_Dict); - m_EssenceSubDescriptorList.push_back((InterchangeObject*)m_EssenceSubDescriptor); + if ( essence_descriptor->GetUL() != UL(m_Dict->ul(MDD_RGBAEssenceDescriptor)) + && essence_descriptor->GetUL() != UL(m_Dict->ul(MDD_CDCIEssenceDescriptor)) ) + { + DefaultLogSink().Error("Essence descriptor is not a RGBAEssenceDescriptor or CDCIEssenceDescriptor.\n"); + essence_descriptor->Dump(); + return RESULT_AS02_FORMAT; + } + + m_EssenceDescriptor = essence_descriptor; + + ASDCP::MXF::InterchangeObject_list_t::iterator i; + for ( i = essence_sub_descriptor_list.begin(); i != essence_sub_descriptor_list.end(); ++i ) + { + if ( (*i)->GetUL() != UL(m_Dict->ul(MDD_JPEG2000PictureSubDescriptor)) ) + { + DefaultLogSink().Error("Essence sub-descriptor is not a JPEG2000PictureSubDescriptor.\n"); + (*i)->Dump(); + } + + m_EssenceSubDescriptorList.push_back(*i); + GenRandomValue((*i)->InstanceUID); + m_EssenceDescriptor->SubDescriptors.push_back((*i)->InstanceUID); + *i = 0; // parent will only free the ones we don't keep + } - GenRandomValue(m_EssenceSubDescriptor->InstanceUID); - m_EssenceDescriptor->SubDescriptors.push_back(m_EssenceSubDescriptor->InstanceUID); result = m_State.Goto_INIT(); } @@ -324,38 +317,23 @@ AS_02::JP2K::MXFWriter::h__Writer::OpenWrite(const char* filename, EssenceType_t // Automatically sets the MXF file's metadata from the first jpeg codestream stream. Result_t -AS_02::JP2K::MXFWriter::h__Writer::SetSourceStream(const PictureDescriptor& PDesc, const std::string& label, ASDCP::Rational LocalEditRate) +AS_02::JP2K::MXFWriter::h__Writer::SetSourceStream(const std::string& label, const ASDCP::Rational& edit_rate) { assert(m_Dict); if ( ! m_State.Test_INIT() ) - return RESULT_STATE; - - if ( LocalEditRate == ASDCP::Rational(0,0) ) - LocalEditRate = PDesc.EditRate; - - m_PDesc = PDesc; - assert(m_Dict); - Result_t result = JP2K_PDesc_to_MD(m_PDesc, *m_Dict, - static_cast<ASDCP::MXF::RGBAEssenceDescriptor*>(m_EssenceDescriptor), - m_EssenceSubDescriptor); - - static_cast<ASDCP::MXF::RGBAEssenceDescriptor*>(m_EssenceDescriptor)->ComponentMaxRef = 4095; /// TODO: set with magic or some such thing - static_cast<ASDCP::MXF::RGBAEssenceDescriptor*>(m_EssenceDescriptor)->ComponentMinRef = 0; - - if ( ASDCP_SUCCESS(result) ) { - memcpy(m_EssenceUL, m_Dict->ul(MDD_JPEG2000Essence), SMPTE_UL_LENGTH); - m_EssenceUL[SMPTE_UL_LENGTH-1] = 1; // first (and only) essence container - result = m_State.Goto_READY(); + return RESULT_STATE; } - if ( ASDCP_SUCCESS(result) ) - { - ui32_t TCFrameRate = ( m_PDesc.EditRate == EditRate_23_98 ) ? 24 : m_PDesc.EditRate.Numerator; + memcpy(m_EssenceUL, m_Dict->ul(MDD_JPEG2000Essence), SMPTE_UL_LENGTH); + m_EssenceUL[SMPTE_UL_LENGTH-1] = 1; // first (and only) essence container + Result_t result = m_State.Goto_READY(); + if ( KM_SUCCESS(result) ) + { result = WriteAS02Header(label, UL(m_Dict->ul(MDD_JPEG_2000Wrapping)), PICT_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_PictureDataDef)), - LocalEditRate, TCFrameRate); + edit_rate, derive_timecode_rate_from_edit_rate(edit_rate)); } return result; @@ -368,26 +346,27 @@ 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) + AESEncContext* Ctx, HMACContext* HMAC) { + if ( FrameBuf.Size() == 0 ) + { + DefaultLogSink().Error("The frame buffer size is zero.\n"); + return RESULT_PARAM; + } + Result_t result = RESULT_OK; if ( m_State.Test_READY() ) - result = m_State.Goto_RUNNING(); // first time through - - 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); - - if ( ASDCP_SUCCESS(result) ) - { - IndexTableSegment::IndexEntry Entry; - Entry.StreamOffset = StreamOffset; - m_IndexWriter.PushIndexEntry(Entry); + { + result = m_State.Goto_RUNNING(); // first time through + } + + if ( KM_SUCCESS(result) ) + { + result = WriteEKLVPacket(FrameBuf, m_EssenceUL, Ctx, HMAC); + m_FramesWritten++; } - m_FramesWritten++; return result; } @@ -401,8 +380,10 @@ AS_02::JP2K::MXFWriter::h__Writer::Finalize() Result_t result = m_State.Goto_FINAL(); - if ( ASDCP_SUCCESS(result) ) - result = WriteAS02Footer(); + if ( KM_SUCCESS(result) ) + { + result = WriteAS02Footer(); + } return result; } @@ -453,21 +434,28 @@ AS_02::JP2K::MXFWriter::RIP() // Open the file for writing. The file must not exist. Returns error if // the operation cannot be completed. Result_t -AS_02::JP2K::MXFWriter::OpenWrite(const char* filename, const ASDCP::WriterInfo& Info, - const ASDCP::JP2K::PictureDescriptor& PDesc, - const IndexStrategy_t& Strategy, - const ui32_t& PartitionSpace, - const ui32_t& HeaderSize) +AS_02::JP2K::MXFWriter::OpenWrite(const std::string& filename, const ASDCP::WriterInfo& Info, + ASDCP::MXF::FileDescriptor* essence_descriptor, + ASDCP::MXF::InterchangeObject_list_t& essence_sub_descriptor_list, + const ASDCP::Rational& edit_rate, const ui32_t& header_size, + const IndexStrategy_t& strategy, const ui32_t& partition_space) { + if ( essence_descriptor == 0 ) + { + DefaultLogSink().Error("Essence descriptor object required.\n"); + return RESULT_PARAM; + } + m_Writer = new AS_02::JP2K::MXFWriter::h__Writer(DefaultSMPTEDict()); m_Writer->m_Info = Info; - Result_t result = m_Writer->OpenWrite(filename, ASDCP::ESS_JPEG_2000, Strategy, PartitionSpace, HeaderSize); + Result_t result = m_Writer->OpenWrite(filename, essence_descriptor, essence_sub_descriptor_list, + strategy, partition_space, header_size); - if ( ASDCP_SUCCESS(result) ) - result = m_Writer->SetSourceStream(PDesc, JP2K_PACKAGE_LABEL); + if ( KM_SUCCESS(result) ) + result = m_Writer->SetSourceStream(JP2K_PACKAGE_LABEL, edit_rate); - if ( ASDCP_FAILURE(result) ) + if ( KM_FAILURE(result) ) m_Writer.release(); return result; |
