From b15f21a0c760bc8b8b28cd2a04491f4963ac0549 Mon Sep 17 00:00:00 2001 From: Pierre-Anthony Lemieux Date: Sun, 12 Apr 2020 13:28:38 -0700 Subject: Add support for IAB Track File reading and writing --- src/AS_02_IAB.cpp | 617 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 617 insertions(+) create mode 100644 src/AS_02_IAB.cpp (limited to 'src/AS_02_IAB.cpp') diff --git a/src/AS_02_IAB.cpp b/src/AS_02_IAB.cpp new file mode 100644 index 0000000..5fc2ea1 --- /dev/null +++ b/src/AS_02_IAB.cpp @@ -0,0 +1,617 @@ +/* +Copyright (c) 2011-2020, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, +John Hurst, Pierre-Anthony Lemieux + +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. +*/ + +#include "AS_02_internal.h" +#include "AS_02_IAB.h" + +#include +#include +#include + +namespace Kumu { + class RuntimeError : public std::runtime_error { + Kumu::Result_t m_Result; + RuntimeError(); /* deleted constructor */ + public: + RuntimeError(const Kumu::Result_t& result) : std::runtime_error(result.Message()), m_Result(result) {} + Kumu::Result_t GetResult() { return this->m_Result; } + }; +} + +//------------------------------------------------------------------------------------------ + + +AS_02::IAB::MXFWriter::MXFWriter() : m_ClipStart(0), m_State(WriterState_t::ST_BEGIN) { +} + +AS_02::IAB::MXFWriter::~MXFWriter() {} + +const ASDCP::MXF::OP1aHeader& +AS_02::IAB::MXFWriter::OP1aHeader() const { + if (this->m_State == WriterState_t::ST_BEGIN) { + throw Kumu::RuntimeError(Kumu::RESULT_INIT); + } + + return this->m_Writer->m_HeaderPart; +} + +const ASDCP::MXF::RIP& +AS_02::IAB::MXFWriter::RIP() const { + if (this->m_State == WriterState_t::ST_BEGIN) { + throw Kumu::RuntimeError(Kumu::RESULT_INIT); + } + + return this->m_Writer->m_RIP; +} + +Kumu::Result_t +AS_02::IAB::MXFWriter::OpenWrite( + const std::string& filename, + const ASDCP::WriterInfo& Info, + const ASDCP::MXF::IABSoundfieldLabelSubDescriptor& sub, + const std::vector& conformsToSpecs, + const ASDCP::Rational& edit_rate, + const ASDCP::Rational& sample_rate) { + + /* are we already running */ + + if (this->m_State != WriterState_t::ST_BEGIN) { + return Kumu::RESULT_STATE; + } + + Result_t result = Kumu::RESULT_OK; + + /* initialize the writer */ + + this->m_Writer = new AS_02::IAB::MXFWriter::h__Writer(DefaultSMPTEDict()); + + this->m_Writer->m_Info = Info; + + this->m_Writer->m_HeaderSize = 16 * 1024; + + try { + + /* open the file */ + + result = this->m_Writer->m_File.OpenWrite(filename.c_str()); + + if (result.Failure()) { + throw Kumu::RuntimeError(result); + } + + /* initialize IAB descriptor */ + + ASDCP::MXF::IABEssenceDescriptor* desc = new ASDCP::MXF::IABEssenceDescriptor(this->m_Writer->m_Dict); + + GenRandomValue(desc->InstanceUID); /* TODO: remove */ + desc->SampleRate = edit_rate; + desc->AudioSamplingRate = sample_rate; + desc->ChannelCount = 0; + desc->SoundEssenceCoding = this->m_Writer->m_Dict->ul(MDD_ImmersiveAudioCoding); + desc->QuantizationBits = 24; + + this->m_Writer->m_EssenceDescriptor = desc; + + /* copy and add the IAB subdescriptor */ + + ASDCP::MXF::IABSoundfieldLabelSubDescriptor* subdesc = new ASDCP::MXF::IABSoundfieldLabelSubDescriptor(sub); + + GenRandomValue(subdesc->InstanceUID); /* TODO: remove */ + subdesc->MCATagName = "IAB"; + subdesc->MCATagSymbol = "IAB"; + subdesc->MCALabelDictionaryID = this->m_Writer->m_Dict->ul(MDD_IABSoundfield); + GenRandomValue(subdesc->MCALinkID); + + this->m_Writer->m_EssenceSubDescriptorList.push_back(subdesc); + this->m_Writer->m_EssenceDescriptor->SubDescriptors.push_back(subdesc->InstanceUID); + + /* initialize the index write */ + + this->m_Writer->m_IndexWriter.SetEditRate(edit_rate); + + /* Essence Element UL */ + + std::array element_ul_bytes; + + const ASDCP::MDDEntry& element_ul_entry = this->m_Writer->m_Dict->Type(MDD_IMF_IABEssenceClipWrappedElement); + + std::copy(std::begin(element_ul_entry.ul), std::end(element_ul_entry.ul), std::begin(element_ul_bytes)); + + /* only a single track */ + + element_ul_bytes[15] = 1; + + /* write the file header*/ + /* WriteAS02Header() takes ownership of desc and subdesc */ + + result = this->m_Writer->WriteAS02Header( + "Clip wrapping of IA bitstreams as specified in SMPTE ST 2067-201", + UL(this->m_Writer->m_Dict->ul(MDD_IMF_IABEssenceClipWrappedContainer)), + "IA Bitstream", + UL(element_ul_bytes.data()), + UL(this->m_Writer->m_Dict->ul(MDD_SoundDataDef)), + edit_rate, + derive_timecode_rate_from_edit_rate(edit_rate), + &conformsToSpecs + ); + + if (result.Failure()) { + throw Kumu::RuntimeError(result); + } + + /* start the clip */ + + this->m_ClipStart = this->m_Writer->m_File.Tell(); + + byte_t clip_buffer[24] = { 0 }; + + memcpy(clip_buffer, this->m_Writer->m_Dict->ul(MDD_IMF_IABEssenceClipWrappedElement), 16); + + if (!Kumu::write_BER(clip_buffer + 16, 0, 8)) { + throw Kumu::RuntimeError(Kumu::RESULT_FAIL); + } + + this->m_Writer->m_StreamOffset = 24; + + result = this->m_Writer->m_File.Write(clip_buffer, 24); + + if (result.Failure()) { + throw Kumu::RuntimeError(result); + } + + this->m_State = WriterState_t::ST_READY; + + } catch (Kumu::RuntimeError e) { + + this->Reset(); + + return e.GetResult(); + + } + + return result; + +} + +Result_t +AS_02::IAB::MXFWriter::WriteFrame(const ui8_t* frame, ui32_t sz) { + + /* are we running */ + + if (this->m_State == WriterState_t::ST_BEGIN) { + return Kumu::RESULT_INIT; + } + + Result_t result = Kumu::RESULT_OK; + + /* update the index */ + + IndexTableSegment::IndexEntry Entry; + + Entry.StreamOffset = this->m_Writer->m_StreamOffset; + + this->m_Writer->m_IndexWriter.PushIndexEntry(Entry); + + try { + + /* write the frame */ + + result = this->m_Writer->m_File.Write(frame, sz); + + if (result.Failure()) { + throw Kumu::RuntimeError(result); + } + + /* increment the frame counter */ + + this->m_Writer->m_FramesWritten++; + + /* increment stream offset */ + + this->m_Writer->m_StreamOffset += sz; + + /* we are running now */ + + this->m_State = WriterState_t::ST_RUNNING; + + } catch (Kumu::RuntimeError e) { + + this->Reset(); + + return e.GetResult(); + + } + + return result; +} + +Result_t +AS_02::IAB::MXFWriter::Finalize() { + + /* are we running */ + + if (this->m_State == WriterState_t::ST_BEGIN) { + return Kumu::RESULT_INIT; + } + + Result_t result = RESULT_OK; + + try { + + /* write clip length */ + + ui64_t current_position = this->m_Writer->m_File.Tell(); + + result = this->m_Writer->m_File.Seek(m_ClipStart + 16); + + byte_t clip_buffer[8] = { 0 }; + + ui64_t size = static_cast(this->m_Writer->m_StreamOffset); + + bool check = Kumu::write_BER(clip_buffer, size, 8); + + if (!check) { + throw Kumu::RuntimeError(Kumu::RESULT_FAIL); + } + + result = this->m_Writer->m_File.Write(clip_buffer, 8); + + if (result.Failure()) { + throw Kumu::RuntimeError(result); + } + + result = this->m_Writer->m_File.Seek(current_position); + + if (result.Failure()) { + throw Kumu::RuntimeError(result); + } + + /* write footer */ + + result = this->m_Writer->WriteAS02Footer(); + + if (result.Failure()) { + throw Kumu::RuntimeError(result); + } + + } catch (Kumu::RuntimeError e) { + + /* nothing to do since we are about to reset */ + + result = e.GetResult(); + + } + + /* we are ready to start again */ + + this->Reset(); + + return result; +} + +void +AS_02::IAB::MXFWriter::Reset() { + this->m_Writer.set(NULL); + this->m_State = WriterState_t::ST_BEGIN; +} + + +//------------------------------------------------------------------------------------------ + + +AS_02::IAB::MXFReader::MXFReader() : m_State(ReaderState_t::ST_BEGIN) {} + +AS_02::IAB::MXFReader::~MXFReader() {} + +const ASDCP::MXF::OP1aHeader& +AS_02::IAB::MXFReader::OP1aHeader() const { + if (this->m_State == ReaderState_t::ST_BEGIN) { + throw Kumu::RuntimeError(Kumu::RESULT_INIT); + } + + return this->m_Reader->m_HeaderPart; +} + +const ASDCP::MXF::RIP& +AS_02::IAB::MXFReader::RIP() const { + if (this->m_State == ReaderState_t::ST_BEGIN) { + throw Kumu::RuntimeError(Kumu::RESULT_INIT); + } + + return this->m_Reader->m_RIP; +} + +Result_t +AS_02::IAB::MXFReader::OpenRead(const std::string& filename) { + + /* are we already running */ + + if (this->m_State != ReaderState_t::ST_BEGIN) { + return Kumu::RESULT_STATE; + } + + Result_t result = Kumu::RESULT_OK; + + /* initialize the writer */ + + this->m_Reader = new h__Reader(DefaultCompositeDict()); + + try { + + result = this->m_Reader->OpenMXFRead(filename); + + if (result.Failure()) { + throw Kumu::RuntimeError(result); + } + + InterchangeObject* tmp_iobj = 0; + + this->m_Reader->m_HeaderPart.GetMDObjectByType( + this->m_Reader->m_Dict->Type(MDD_IABEssenceDescriptor).ul, + &tmp_iobj + ); + + if (!tmp_iobj) { + throw Kumu::RuntimeError(Kumu::RESULT_FAIL); + } + + this->m_Reader->m_HeaderPart.GetMDObjectByType( + this->m_Reader->m_Dict->Type(MDD_IABSoundfieldLabelSubDescriptor).ul, + &tmp_iobj + ); + + if (!tmp_iobj) { + throw Kumu::RuntimeError(Kumu::RESULT_FAIL); + } + + std::list ObjectList; + + this->m_Reader->m_HeaderPart.GetMDObjectsByType( + this->m_Reader->m_Dict->Type(MDD_Track).ul, + ObjectList + ); + + if (ObjectList.empty()) { + throw Kumu::RuntimeError(Kumu::RESULT_FAIL); + } + + /* invalidate current frame */ + + this->m_CurrentFrameIndex = -1; + + /* we are ready */ + + this->m_State = ReaderState_t::ST_READY; + + } catch (Kumu::RuntimeError e) { + + this->Reset(); + + return e.GetResult(); + } + + return RESULT_OK; +} + + +Result_t +AS_02::IAB::MXFReader::Close() { + + /* are we already running */ + + if (this->m_State == ReaderState_t::ST_BEGIN) { + return Kumu::RESULT_INIT; + } + + this->Reset(); + + return Kumu::RESULT_OK; +} + + +Result_t AS_02::IAB::MXFReader::GetFrameCount(ui32_t& frameCount) const { + + /* are we already running */ + + if (this->m_State == ReaderState_t::ST_BEGIN) { + return Kumu::RESULT_INIT; + } + + frameCount = m_Reader->m_IndexAccess.GetDuration(); + + return Kumu::RESULT_OK; +} + +Result_t +AS_02::IAB::MXFReader::ReadFrame(ui32_t frame_number, AS_02::IAB::MXFReader::Frame& frame) { + + /* are we already running */ + + if (this->m_State == ReaderState_t::ST_BEGIN) { + return Kumu::RESULT_INIT; + } + + Result_t result = RESULT_OK; + + /* have we already read the frame */ + + if (frame_number != this->m_CurrentFrameIndex) { + + try { + + // look up frame index node + IndexTableSegment::IndexEntry index_entry; + + result = this->m_Reader->m_IndexAccess.Lookup(frame_number, index_entry); + + if (result.Failure()) { + DefaultLogSink().Error("Frame value out of range: %u\n", frame_number); + throw Kumu::RuntimeError(result); + } + + result = this->m_Reader->m_File.Seek(index_entry.StreamOffset); + + if (result.Failure()) { + DefaultLogSink().Error("Cannot seek to stream offset: %u\n", index_entry.StreamOffset); + throw Kumu::RuntimeError(result); + } + + /* read the preamble info */ + + const int preambleTLLen = 5; + const int frameTLLen = 5; + + ui32_t buffer_offset = 0; + + this->m_CurrentFrameBuffer.resize(preambleTLLen); + + result = this->m_Reader->m_File.Read(&this->m_CurrentFrameBuffer[buffer_offset], preambleTLLen); + + if (result.Failure()) { + DefaultLogSink().Error("Error reading IA Frame preamble\n", index_entry.StreamOffset); + throw Kumu::RuntimeError(result); + } + + ui32_t preambleLen = ((ui32_t)this->m_CurrentFrameBuffer[1 + buffer_offset] << 24) + + ((ui32_t)this->m_CurrentFrameBuffer[2 + buffer_offset] << 16) + + ((ui32_t)this->m_CurrentFrameBuffer[3 + buffer_offset] << 8) + + (ui32_t)this->m_CurrentFrameBuffer[4 + buffer_offset]; + + buffer_offset += preambleTLLen; + + /* read the preamble*/ + + if (preambleLen > 0) { + + this->m_CurrentFrameBuffer.resize(preambleTLLen + preambleLen); + + result = this->m_Reader->m_File.Read(&this->m_CurrentFrameBuffer[buffer_offset], preambleLen); + + if (result.Failure()) { + DefaultLogSink().Error("Error reading IA Frame preamble\n", index_entry.StreamOffset); + throw Kumu::RuntimeError(result); + } + + buffer_offset += preambleLen; + + } + + /* read the IA Frame info */ + + this->m_CurrentFrameBuffer.resize(preambleTLLen + preambleLen + frameTLLen); + + result = this->m_Reader->m_File.Read(&this->m_CurrentFrameBuffer[buffer_offset], frameTLLen); + + if (result.Failure()) { + DefaultLogSink().Error("Error reading IA Frame data\n", index_entry.StreamOffset); + throw Kumu::RuntimeError(result); + } + + ui32_t frameLen = ((ui32_t)this->m_CurrentFrameBuffer[buffer_offset + 1] << 24) + + ((ui32_t)this->m_CurrentFrameBuffer[buffer_offset + 2] << 16) + + ((ui32_t)this->m_CurrentFrameBuffer[buffer_offset + 3] << 8) + + (ui32_t)this->m_CurrentFrameBuffer[buffer_offset + 4]; + + buffer_offset += frameTLLen; + + /* read the IA Frame */ + + if (frameLen > 0) { + + this->m_CurrentFrameBuffer.resize(preambleTLLen + preambleLen + frameTLLen + frameLen); + + result = this->m_Reader->m_File.Read(&this->m_CurrentFrameBuffer[buffer_offset], frameLen); + + if (result.Failure()) { + DefaultLogSink().Error("Error reading IA Frame data\n", index_entry.StreamOffset); + throw Kumu::RuntimeError(result); + } + + buffer_offset += frameLen; + + } + + /* update current frame */ + + this->m_CurrentFrameIndex = frame_number; + + } catch (Kumu::RuntimeError e) { + + this->Reset(); + + return e.GetResult(); + + } + + } + + frame = std::pair(this->m_CurrentFrameBuffer.size(), &this->m_CurrentFrameBuffer[0]); + + this->m_State = ReaderState_t::ST_RUNNING; + + return result; +} + +Result_t +AS_02::IAB::MXFReader::FillWriterInfo(WriterInfo& Info) const { + /* are we already running */ + + if (this->m_State == ReaderState_t::ST_BEGIN) { + return Kumu::RESULT_FAIL; + } + + Info = m_Reader->m_Info; + + return Kumu::RESULT_OK; +} + +void +AS_02::IAB::MXFReader::DumpHeaderMetadata(FILE* stream) const { + if (this->m_State != ReaderState_t::ST_BEGIN) { + this->m_Reader->m_HeaderPart.Dump(stream); + } +} + + +void +AS_02::IAB::MXFReader::DumpIndex(FILE* stream) const { + if (this->m_State != ReaderState_t::ST_BEGIN) { + this->m_Reader->m_IndexAccess.Dump(stream); + } +} + +void +AS_02::IAB::MXFReader::Reset() { + this->m_Reader.set(NULL); + this->m_State = ReaderState_t::ST_BEGIN; +} + +// +// end AS_02_IAB.cpp +// -- cgit v1.2.3 From 8be2ad09b94fbf2f023e24cf1b7eec10c03047b4 Mon Sep 17 00:00:00 2001 From: Pierre-Anthony Lemieux Date: Fri, 17 Apr 2020 09:49:59 -0700 Subject: Removed dependencies on features available beyond C++98 --- src/AS_02_IAB.cpp | 54 +++++++++++++++++++++++++-------------------------- src/AS_DCP_internal.h | 6 +++--- 2 files changed, 30 insertions(+), 30 deletions(-) (limited to 'src/AS_02_IAB.cpp') diff --git a/src/AS_02_IAB.cpp b/src/AS_02_IAB.cpp index 5fc2ea1..3b0aa8c 100644 --- a/src/AS_02_IAB.cpp +++ b/src/AS_02_IAB.cpp @@ -32,29 +32,29 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include -#include namespace Kumu { class RuntimeError : public std::runtime_error { Kumu::Result_t m_Result; - RuntimeError(); /* deleted constructor */ + RuntimeError(); public: RuntimeError(const Kumu::Result_t& result) : std::runtime_error(result.Message()), m_Result(result) {} Kumu::Result_t GetResult() { return this->m_Result; } + ~RuntimeError() throw() {} }; } //------------------------------------------------------------------------------------------ -AS_02::IAB::MXFWriter::MXFWriter() : m_ClipStart(0), m_State(WriterState_t::ST_BEGIN) { +AS_02::IAB::MXFWriter::MXFWriter() : m_ClipStart(0), m_State(ST_BEGIN) { } AS_02::IAB::MXFWriter::~MXFWriter() {} const ASDCP::MXF::OP1aHeader& AS_02::IAB::MXFWriter::OP1aHeader() const { - if (this->m_State == WriterState_t::ST_BEGIN) { + if (this->m_State == ST_BEGIN) { throw Kumu::RuntimeError(Kumu::RESULT_INIT); } @@ -63,7 +63,7 @@ AS_02::IAB::MXFWriter::OP1aHeader() const { const ASDCP::MXF::RIP& AS_02::IAB::MXFWriter::RIP() const { - if (this->m_State == WriterState_t::ST_BEGIN) { + if (this->m_State == ST_BEGIN) { throw Kumu::RuntimeError(Kumu::RESULT_INIT); } @@ -81,7 +81,7 @@ AS_02::IAB::MXFWriter::OpenWrite( /* are we already running */ - if (this->m_State != WriterState_t::ST_BEGIN) { + if (this->m_State != ST_BEGIN) { return Kumu::RESULT_STATE; } @@ -137,11 +137,11 @@ AS_02::IAB::MXFWriter::OpenWrite( /* Essence Element UL */ - std::array element_ul_bytes; + byte_t element_ul_bytes[ASDCP::SMPTE_UL_LENGTH]; const ASDCP::MDDEntry& element_ul_entry = this->m_Writer->m_Dict->Type(MDD_IMF_IABEssenceClipWrappedElement); - std::copy(std::begin(element_ul_entry.ul), std::end(element_ul_entry.ul), std::begin(element_ul_bytes)); + std::copy(element_ul_entry.ul, element_ul_entry.ul + ASDCP::SMPTE_UL_LENGTH, element_ul_bytes); /* only a single track */ @@ -154,7 +154,7 @@ AS_02::IAB::MXFWriter::OpenWrite( "Clip wrapping of IA bitstreams as specified in SMPTE ST 2067-201", UL(this->m_Writer->m_Dict->ul(MDD_IMF_IABEssenceClipWrappedContainer)), "IA Bitstream", - UL(element_ul_bytes.data()), + UL(element_ul_bytes), UL(this->m_Writer->m_Dict->ul(MDD_SoundDataDef)), edit_rate, derive_timecode_rate_from_edit_rate(edit_rate), @@ -185,7 +185,7 @@ AS_02::IAB::MXFWriter::OpenWrite( throw Kumu::RuntimeError(result); } - this->m_State = WriterState_t::ST_READY; + this->m_State = ST_READY; } catch (Kumu::RuntimeError e) { @@ -204,7 +204,7 @@ AS_02::IAB::MXFWriter::WriteFrame(const ui8_t* frame, ui32_t sz) { /* are we running */ - if (this->m_State == WriterState_t::ST_BEGIN) { + if (this->m_State == ST_BEGIN) { return Kumu::RESULT_INIT; } @@ -238,7 +238,7 @@ AS_02::IAB::MXFWriter::WriteFrame(const ui8_t* frame, ui32_t sz) { /* we are running now */ - this->m_State = WriterState_t::ST_RUNNING; + this->m_State = ST_RUNNING; } catch (Kumu::RuntimeError e) { @@ -256,7 +256,7 @@ AS_02::IAB::MXFWriter::Finalize() { /* are we running */ - if (this->m_State == WriterState_t::ST_BEGIN) { + if (this->m_State == ST_BEGIN) { return Kumu::RESULT_INIT; } @@ -318,20 +318,20 @@ AS_02::IAB::MXFWriter::Finalize() { void AS_02::IAB::MXFWriter::Reset() { this->m_Writer.set(NULL); - this->m_State = WriterState_t::ST_BEGIN; + this->m_State = ST_BEGIN; } //------------------------------------------------------------------------------------------ -AS_02::IAB::MXFReader::MXFReader() : m_State(ReaderState_t::ST_BEGIN) {} +AS_02::IAB::MXFReader::MXFReader() : m_State(ST_READER_BEGIN) {} AS_02::IAB::MXFReader::~MXFReader() {} const ASDCP::MXF::OP1aHeader& AS_02::IAB::MXFReader::OP1aHeader() const { - if (this->m_State == ReaderState_t::ST_BEGIN) { + if (this->m_State == ST_READER_BEGIN) { throw Kumu::RuntimeError(Kumu::RESULT_INIT); } @@ -340,7 +340,7 @@ AS_02::IAB::MXFReader::OP1aHeader() const { const ASDCP::MXF::RIP& AS_02::IAB::MXFReader::RIP() const { - if (this->m_State == ReaderState_t::ST_BEGIN) { + if (this->m_State == ST_READER_BEGIN) { throw Kumu::RuntimeError(Kumu::RESULT_INIT); } @@ -352,7 +352,7 @@ AS_02::IAB::MXFReader::OpenRead(const std::string& filename) { /* are we already running */ - if (this->m_State != ReaderState_t::ST_BEGIN) { + if (this->m_State != ST_READER_BEGIN) { return Kumu::RESULT_STATE; } @@ -407,7 +407,7 @@ AS_02::IAB::MXFReader::OpenRead(const std::string& filename) { /* we are ready */ - this->m_State = ReaderState_t::ST_READY; + this->m_State = ST_READER_READY; } catch (Kumu::RuntimeError e) { @@ -425,7 +425,7 @@ AS_02::IAB::MXFReader::Close() { /* are we already running */ - if (this->m_State == ReaderState_t::ST_BEGIN) { + if (this->m_State == ST_READER_BEGIN) { return Kumu::RESULT_INIT; } @@ -439,7 +439,7 @@ Result_t AS_02::IAB::MXFReader::GetFrameCount(ui32_t& frameCount) const { /* are we already running */ - if (this->m_State == ReaderState_t::ST_BEGIN) { + if (this->m_State == ST_READER_BEGIN) { return Kumu::RESULT_INIT; } @@ -453,7 +453,7 @@ AS_02::IAB::MXFReader::ReadFrame(ui32_t frame_number, AS_02::IAB::MXFReader::Fra /* are we already running */ - if (this->m_State == ReaderState_t::ST_BEGIN) { + if (this->m_State == ST_READER_BEGIN) { return Kumu::RESULT_INIT; } @@ -573,7 +573,7 @@ AS_02::IAB::MXFReader::ReadFrame(ui32_t frame_number, AS_02::IAB::MXFReader::Fra frame = std::pair(this->m_CurrentFrameBuffer.size(), &this->m_CurrentFrameBuffer[0]); - this->m_State = ReaderState_t::ST_RUNNING; + this->m_State = ST_READER_RUNNING; return result; } @@ -582,7 +582,7 @@ Result_t AS_02::IAB::MXFReader::FillWriterInfo(WriterInfo& Info) const { /* are we already running */ - if (this->m_State == ReaderState_t::ST_BEGIN) { + if (this->m_State == ST_READER_BEGIN) { return Kumu::RESULT_FAIL; } @@ -593,7 +593,7 @@ AS_02::IAB::MXFReader::FillWriterInfo(WriterInfo& Info) const { void AS_02::IAB::MXFReader::DumpHeaderMetadata(FILE* stream) const { - if (this->m_State != ReaderState_t::ST_BEGIN) { + if (this->m_State != ST_READER_BEGIN) { this->m_Reader->m_HeaderPart.Dump(stream); } } @@ -601,7 +601,7 @@ AS_02::IAB::MXFReader::DumpHeaderMetadata(FILE* stream) const { void AS_02::IAB::MXFReader::DumpIndex(FILE* stream) const { - if (this->m_State != ReaderState_t::ST_BEGIN) { + if (this->m_State != ST_READER_BEGIN) { this->m_Reader->m_IndexAccess.Dump(stream); } } @@ -609,7 +609,7 @@ AS_02::IAB::MXFReader::DumpIndex(FILE* stream) const { void AS_02::IAB::MXFReader::Reset() { this->m_Reader.set(NULL); - this->m_State = ReaderState_t::ST_BEGIN; + this->m_State = ST_READER_BEGIN; } // diff --git a/src/AS_DCP_internal.h b/src/AS_DCP_internal.h index b7712b1..f14bfa0 100755 --- a/src/AS_DCP_internal.h +++ b/src/AS_DCP_internal.h @@ -887,9 +887,9 @@ namespace ASDCP // state machine for mxf reader enum ReaderState_t { - ST_BEGIN, // waiting for Open() - ST_READY, // ready to read frames - ST_RUNNING, // one or more frames read + ST_READER_BEGIN, // waiting for Open() + ST_READER_READY, // ready to read frames + ST_READER_RUNNING, // one or more frames read }; // -- cgit v1.2.3 From da198d2a3a2b772357b3333aae3eb95e96fb6d93 Mon Sep 17 00:00:00 2001 From: Wolfgang Ruppel Date: Wed, 22 Apr 2020 23:40:39 +0200 Subject: * Fixes an error when calling OP1aHeader::GetMDObjectByType() * IAB Essence type detection added * Adding AS_02_internal.h to deploy targets --- src/AS_02_IAB.cpp | 2 +- src/AS_02_IAB.h | 2 +- src/AS_DCP.h | 1 + src/AS_DCP_MXF.cpp | 4 ++++ src/CMakeLists.txt | 2 +- 5 files changed, 8 insertions(+), 3 deletions(-) (limited to 'src/AS_02_IAB.cpp') diff --git a/src/AS_02_IAB.cpp b/src/AS_02_IAB.cpp index 3b0aa8c..319833f 100644 --- a/src/AS_02_IAB.cpp +++ b/src/AS_02_IAB.cpp @@ -329,7 +329,7 @@ AS_02::IAB::MXFReader::MXFReader() : m_State(ST_READER_BEGIN) {} AS_02::IAB::MXFReader::~MXFReader() {} -const ASDCP::MXF::OP1aHeader& +ASDCP::MXF::OP1aHeader& AS_02::IAB::MXFReader::OP1aHeader() const { if (this->m_State == ST_READER_BEGIN) { throw Kumu::RuntimeError(Kumu::RESULT_INIT); diff --git a/src/AS_02_IAB.h b/src/AS_02_IAB.h index aade55d..57fb77e 100644 --- a/src/AS_02_IAB.h +++ b/src/AS_02_IAB.h @@ -172,7 +172,7 @@ namespace AS_02 { * * @throws std::runtime_error if the Track File is not open */ - virtual const ASDCP::MXF::OP1aHeader& OP1aHeader() const; + virtual ASDCP::MXF::OP1aHeader& OP1aHeader() const; /** * Warning: direct manipulation of MXF structures can interfere diff --git a/src/AS_DCP.h b/src/AS_DCP.h index 74991f6..44e60be 100755 --- a/src/AS_DCP.h +++ b/src/AS_DCP.h @@ -223,6 +223,7 @@ namespace ASDCP { ESS_AS02_TIMED_TEXT, // the file contains a TTML document and zero or more resources ESS_AS02_ISXD, // the file contains an ISXD document stream (per SMPTE RDD 47) ESS_AS02_ACES, // the file contains two or more ACES codestreams (per SMPTE ST 2067-50) + ESS_AS02_IAB, // the file contains an IAB stream (per SMPTE ST 2067-201) ESS_MAX }; diff --git a/src/AS_DCP_MXF.cpp b/src/AS_DCP_MXF.cpp index d3606fe..c478f2f 100755 --- a/src/AS_DCP_MXF.cpp +++ b/src/AS_DCP_MXF.cpp @@ -277,6 +277,10 @@ ASDCP::EssenceType(const std::string& filename, EssenceType_t& type) { type = ESS_AS02_ACES; } + else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(IABEssenceDescriptor))) ) + { + type = ESS_AS02_IAB; + } } } else diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f501d1c..2787e46 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -40,7 +40,7 @@ set(asdcp_src ${asdcp_src} Wav.h WavFileWriter.h MXF.h Metadata.h JP2K.h AS_DCP. set(as02_src h__02_Reader.cpp h__02_Writer.cpp AS_02_ISXD.cpp AS_02_JP2K.cpp AS_02_PCM.cpp ST2052_TextParser.cpp AS_02_TimedText.cpp AS_02_ACES.cpp ACES_Codestream_Parser.cpp ACES_Sequence_Parser.cpp ACES.cpp AS_02_IAB.cpp) # header for deployment (install target) -set(as02_deploy_header AS_02.h Metadata.h MXF.h MXFTypes.h KLV.h MDD.h AS_02_ACES.h ACES.h AS_02_IAB.h) +set(as02_deploy_header AS_02.h Metadata.h MXF.h MXFTypes.h KLV.h MDD.h AS_02_ACES.h ACES.h AS_02_IAB.h AS_02_internal.h) # header set(as02_src ${as02_src} AS_02.h AS_02_internal.h AS_02_ACES.h ACES.h AS_02_IAB.h) -- cgit v1.2.3 From 4ca9a065e5e2d7923dc937bb780d996cf4c18adf Mon Sep 17 00:00:00 2001 From: Pierre-Anthony Lemieux Date: Thu, 7 May 2020 11:10:08 -0700 Subject: Address https://github.com/cinecert/asdcplib/pull/33#discussion_r421689866 --- src/AS_02_IAB.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/AS_02_IAB.cpp') diff --git a/src/AS_02_IAB.cpp b/src/AS_02_IAB.cpp index 319833f..cbee6e2 100644 --- a/src/AS_02_IAB.cpp +++ b/src/AS_02_IAB.cpp @@ -32,6 +32,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include +#include namespace Kumu { class RuntimeError : public std::runtime_error { -- cgit v1.2.3