From c7bf747462f303a7173693cacc4479df72037fb4 Mon Sep 17 00:00:00 2001 From: milla Date: Wed, 26 May 2021 13:30:01 +0200 Subject: Writeframe and Readframe in line with other APIs (they now use framebuffer) --- src/AS_02_IAB.cpp | 190 ++++++++++++++++++++++++------------------------------ src/AS_02_IAB.h | 47 +++++++------- 2 files changed, 107 insertions(+), 130 deletions(-) (limited to 'src') diff --git a/src/AS_02_IAB.cpp b/src/AS_02_IAB.cpp index 696a68d..c228a39 100644 --- a/src/AS_02_IAB.cpp +++ b/src/AS_02_IAB.cpp @@ -213,53 +213,47 @@ AS_02::IAB::MXFWriter::OpenWrite( } Result_t -AS_02::IAB::MXFWriter::WriteFrame(const ui8_t* frame, ui32_t sz) { - +AS_02::IAB::MXFWriter::WriteFrame(const ASDCP::FrameBuffer& frame) { /* are we running */ if (this->m_State == ST_BEGIN) { return Kumu::RESULT_INIT; } + if (frame.Size() == 0) { + DefaultLogSink().Error("The frame buffer size is zero.\n"); + return RESULT_PARAM; + } + 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 */ + /* write the frame */ - this->m_Writer->m_FramesWritten++; + result = this->m_Writer->m_File.Write(frame.RoData(), frame.Size()); - /* increment stream offset */ + if (result.Failure()) { + this->Reset(); + return result; + } - this->m_Writer->m_StreamOffset += sz; + /* increment the frame counter */ - /* we are running now */ + this->m_Writer->m_FramesWritten++; - this->m_State = ST_RUNNING; + /* increment stream offset */ - } catch (Kumu::RuntimeError e) { + this->m_Writer->m_StreamOffset += frame.Size(); - this->Reset(); + /* we are running now */ - return e.GetResult(); - - } + this->m_State = ST_RUNNING; return result; } @@ -483,7 +477,7 @@ Result_t AS_02::IAB::MXFReader::GetFrameCount(ui32_t& frameCount) const { } Result_t -AS_02::IAB::MXFReader::ReadFrame(ui32_t frame_number, AS_02::IAB::MXFReader::Frame& frame) { +AS_02::IAB::MXFReader::ReadFrame(ui32_t frame_number, ASDCP::FrameBuffer& frame) { /* are we already running */ @@ -493,120 +487,104 @@ AS_02::IAB::MXFReader::ReadFrame(ui32_t frame_number, AS_02::IAB::MXFReader::Fra 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; + // look up frame index node + IndexTableSegment::IndexEntry index_entry; - result = this->m_Reader->m_IndexAccess.Lookup(frame_number, 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); - } + if (result.Failure()) { + DefaultLogSink().Error("Frame value out of range: %u\n", frame_number); + return 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]; + result = this->m_Reader->m_File->Seek(index_entry.StreamOffset); - buffer_offset += preambleTLLen; + if (result.Failure()) { + DefaultLogSink().Error("Cannot seek to stream offset: %u\n", index_entry.StreamOffset); + return result; + } - /* read the preamble*/ + /* read the preamble info */ - if (preambleLen > 0) { + const int preambleTLLen = 5; + const int frameTLLen = 5; - this->m_CurrentFrameBuffer.resize(preambleTLLen + preambleLen); + ui32_t buffer_offset = 0; - result = this->m_Reader->m_File.Read(&this->m_CurrentFrameBuffer[buffer_offset], preambleLen); + if (frame.Capacity() < preambleTLLen) { + return RESULT_SMALLBUF; + } - if (result.Failure()) { - DefaultLogSink().Error("Error reading IA Frame preamble\n", index_entry.StreamOffset); - throw Kumu::RuntimeError(result); - } + result = this->m_Reader->m_File->Read(&frame.Data()[buffer_offset], preambleTLLen); - buffer_offset += preambleLen; + if (result.Failure()) { + DefaultLogSink().Error("Error reading IA Frame preamble\n", index_entry.StreamOffset); + return result; + } - } + ui32_t preambleLen = ((ui32_t)frame.Data()[1 + buffer_offset] << 24) + + ((ui32_t)frame.Data()[2 + buffer_offset] << 16) + + ((ui32_t)frame.Data()[3 + buffer_offset] << 8) + + (ui32_t)frame.Data()[4 + buffer_offset]; - /* read the IA Frame info */ + buffer_offset += preambleTLLen; - this->m_CurrentFrameBuffer.resize(preambleTLLen + preambleLen + frameTLLen); + /* read the preamble*/ - result = this->m_Reader->m_File.Read(&this->m_CurrentFrameBuffer[buffer_offset], frameTLLen); + if (preambleLen > 0) { - if (result.Failure()) { - DefaultLogSink().Error("Error reading IA Frame data\n", index_entry.StreamOffset); - throw Kumu::RuntimeError(result); - } + if (frame.Capacity() < preambleTLLen + preambleLen) { + return RESULT_SMALLBUF; + } - 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]; + result = this->m_Reader->m_File->Read(&frame.Data()[buffer_offset], preambleLen); - buffer_offset += frameTLLen; + if (result.Failure()) { + DefaultLogSink().Error("Error reading IA Frame preamble\n", index_entry.StreamOffset); + return result; + } - /* read the IA Frame */ + buffer_offset += preambleLen; - if (frameLen > 0) { + } - this->m_CurrentFrameBuffer.resize(preambleTLLen + preambleLen + frameTLLen + frameLen); + /* read the IA Frame info */ - result = this->m_Reader->m_File.Read(&this->m_CurrentFrameBuffer[buffer_offset], frameLen); + if (frame.Capacity() < preambleTLLen + preambleLen + frameTLLen) { + return RESULT_SMALLBUF; + } - if (result.Failure()) { - DefaultLogSink().Error("Error reading IA Frame data\n", index_entry.StreamOffset); - throw Kumu::RuntimeError(result); - } + result = this->m_Reader->m_File->Read(&frame.Data()[buffer_offset], frameTLLen); - buffer_offset += frameLen; + if (result.Failure()) { + DefaultLogSink().Error("Error reading IA Frame data\n", index_entry.StreamOffset); + return result; + } - } + ui32_t frameLen = ((ui32_t)frame.Data()[buffer_offset + 1] << 24) + + ((ui32_t)frame.Data()[buffer_offset + 2] << 16) + + ((ui32_t)frame.Data()[buffer_offset + 3] << 8) + + (ui32_t)frame.Data()[buffer_offset + 4]; - /* update current frame */ + buffer_offset += frameTLLen; - this->m_CurrentFrameIndex = frame_number; + /* read the IA Frame */ - } catch (Kumu::RuntimeError e) { + if (frameLen > 0) { - this->Reset(); + if (frame.Capacity() < preambleTLLen + preambleLen + frameTLLen + frameLen) { + return RESULT_SMALLBUF; + } + frame.Size(preambleTLLen + preambleLen + frameTLLen + frameLen); - return e.GetResult(); + result = this->m_Reader->m_File->Read(&frame.Data()[buffer_offset], frameLen); + if (result.Failure()) { + DefaultLogSink().Error("Error reading IA Frame data\n", index_entry.StreamOffset); + return result; } - } - frame = std::pair(this->m_CurrentFrameBuffer.size(), &this->m_CurrentFrameBuffer[0]); - this->m_State = ST_READER_RUNNING; return result; diff --git a/src/AS_02_IAB.h b/src/AS_02_IAB.h index 7e489e6..100f967 100644 --- a/src/AS_02_IAB.h +++ b/src/AS_02_IAB.h @@ -112,17 +112,17 @@ namespace AS_02 { const ASDCP::Rational& sampling_rate = ASDCP::SampleRate_48k ); - /** - * Writes a single frame. - * - * Must be preceded by a succesful OpenWrite() call followed by zero or more WriteFrame() calls - * - * @param frame Pointer to a complete IA Frame - * @param sz Size in bytes of the IA Frame - * @return RESULT_OK indicates that the frame is written and additional frames can be written, - * otherwise the reader is reset and the file is left is an undermined state. - */ - Result_t WriteFrame(const ui8_t* frame, ui32_t sz); + /** + * Writes a single frame. + * + * Must be preceded by a succesful OpenWrite() call followed by zero or more WriteFrame() calls + * + * @param frame a complete IA Frame + * @return RESULT_OK indicates that the frame is written and additional frames can be written, + * otherwise the reader is reset and the file is left is an undermined state. + */ + Result_t WriteFrame(const ASDCP::FrameBuffer& frame); + /** * Writes an XML text document to the MXF file as per RP 2057. If the @@ -135,10 +135,10 @@ namespace AS_02 { /** * Writes the Track File footer and closes the file. - * + * * Must be preceded by a succesful OpenWrite() call followed by zero or more WriteFrame() calls - * - * @return RESULT_OK indicates that the frame is written and additional frames can be written, + * + * @return RESULT_OK indicates that the frame is written and additional frames can be written, * otherwise the reader is reset and the file is left is an undermined state. */ Result_t Finalize(); @@ -229,16 +229,15 @@ namespace AS_02 { */ Result_t FillWriterInfo(ASDCP::WriterInfo& writer_info) const; - /** - * Reads an IA Frame. - * - * @param frame_number Index of the frame to be read. Must be in the range [0, GetFrameCount()). - * @param frame Frame data. Must not be modified. Remains valid until the next call to ReadFrame(). - * @return RESULT_OK indicates that more frames are ready to be read, - * otherwise the file is closed and the reader reset - */ - Result_t ReadFrame(ui32_t frame_number, Frame& frame); - + /** + * Reads an IA Frame. + * + * @param frame_number Index of the frame to be read. Must be in the range [0, GetFrameCount()). + * @param frame Frame data. Must not be modified. Remains valid until the next call to ReadFrame(). + * @return RESULT_OK indicates that more frames are ready to be read, + * otherwise the file is closed and the reader reset + */ + Result_t ReadFrame(ui32_t frame_number, ASDCP::FrameBuffer& frame); /** Reads a Generic Stream Partition payload. Returns RESULT_INIT if the file is * not open, or RESULT_FORMAT if the SID is not present in the RIP, or if the -- cgit v1.2.3 From 35ceab95d3ad46db13d2e0f979f1ef9102be86f0 Mon Sep 17 00:00:00 2001 From: milla Date: Wed, 9 Jun 2021 13:43:55 +0200 Subject: Fix indentation --- src/AS_02_IAB.h | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/AS_02_IAB.h b/src/AS_02_IAB.h index 100f967..710a322 100644 --- a/src/AS_02_IAB.h +++ b/src/AS_02_IAB.h @@ -112,18 +112,17 @@ namespace AS_02 { const ASDCP::Rational& sampling_rate = ASDCP::SampleRate_48k ); - /** - * Writes a single frame. - * - * Must be preceded by a succesful OpenWrite() call followed by zero or more WriteFrame() calls - * - * @param frame a complete IA Frame - * @return RESULT_OK indicates that the frame is written and additional frames can be written, - * otherwise the reader is reset and the file is left is an undermined state. - */ + /** + * Writes a single frame. + * + * Must be preceded by a succesful OpenWrite() call followed by zero or more WriteFrame() calls + * + * @param frame a complete IA Frame + * @return RESULT_OK indicates that the frame is written and additional frames can be written, + * otherwise the reader is reset and the file is left is an undermined state. + */ Result_t WriteFrame(const ASDCP::FrameBuffer& frame); - /** * Writes an XML text document to the MXF file as per RP 2057. If the * optional AESEncContext argument is present, the document is encrypted @@ -135,10 +134,10 @@ namespace AS_02 { /** * Writes the Track File footer and closes the file. - * + * * Must be preceded by a succesful OpenWrite() call followed by zero or more WriteFrame() calls - * - * @return RESULT_OK indicates that the frame is written and additional frames can be written, + * + * @return RESULT_OK indicates that the frame is written and additional frames can be written, * otherwise the reader is reset and the file is left is an undermined state. */ Result_t Finalize(); @@ -229,14 +228,14 @@ namespace AS_02 { */ Result_t FillWriterInfo(ASDCP::WriterInfo& writer_info) const; - /** - * Reads an IA Frame. - * - * @param frame_number Index of the frame to be read. Must be in the range [0, GetFrameCount()). - * @param frame Frame data. Must not be modified. Remains valid until the next call to ReadFrame(). - * @return RESULT_OK indicates that more frames are ready to be read, - * otherwise the file is closed and the reader reset - */ + /** + * Reads an IA Frame. + * + * @param frame_number Index of the frame to be read. Must be in the range [0, GetFrameCount()). + * @param frame Frame data. Must not be modified. Remains valid until the next call to ReadFrame(). + * @return RESULT_OK indicates that more frames are ready to be read, + * otherwise the file is closed and the reader reset + */ Result_t ReadFrame(ui32_t frame_number, ASDCP::FrameBuffer& frame); /** Reads a Generic Stream Partition payload. Returns RESULT_INIT if the file is -- cgit v1.2.3 From 7af443a806f8c8a2a3cef7ec0b0602b1872987c6 Mon Sep 17 00:00:00 2001 From: nolaiz Date: Wed, 8 Sep 2021 13:55:26 +0200 Subject: Re-implement previous {Read,Write}Frame API --- src/AS_02_IAB.cpp | 180 ++++++++++++++++++++++++++++++++---------------------- src/AS_02_IAB.h | 28 ++++++++- 2 files changed, 133 insertions(+), 75 deletions(-) (limited to 'src') diff --git a/src/AS_02_IAB.cpp b/src/AS_02_IAB.cpp index c228a39..536efbd 100644 --- a/src/AS_02_IAB.cpp +++ b/src/AS_02_IAB.cpp @@ -213,14 +213,14 @@ AS_02::IAB::MXFWriter::OpenWrite( } Result_t -AS_02::IAB::MXFWriter::WriteFrame(const ASDCP::FrameBuffer& frame) { +AS_02::IAB::MXFWriter::WriteFrame(const ui8_t* frame, ui32_t sz) { /* are we running */ if (this->m_State == ST_BEGIN) { return Kumu::RESULT_INIT; } - if (frame.Size() == 0) { + if (sz == 0) { DefaultLogSink().Error("The frame buffer size is zero.\n"); return RESULT_PARAM; } @@ -236,7 +236,7 @@ AS_02::IAB::MXFWriter::WriteFrame(const ASDCP::FrameBuffer& frame) { /* write the frame */ - result = this->m_Writer->m_File.Write(frame.RoData(), frame.Size()); + result = this->m_Writer->m_File.Write(frame, sz); if (result.Failure()) { this->Reset(); @@ -249,7 +249,7 @@ AS_02::IAB::MXFWriter::WriteFrame(const ASDCP::FrameBuffer& frame) { /* increment stream offset */ - this->m_Writer->m_StreamOffset += frame.Size(); + this->m_Writer->m_StreamOffset += sz; /* we are running now */ @@ -258,6 +258,10 @@ AS_02::IAB::MXFWriter::WriteFrame(const ASDCP::FrameBuffer& frame) { return result; } +Result_t AS_02::IAB::MXFWriter::WriteFrame(const ASDCP::FrameBuffer& frame) { + return WriteFrame(frame.RoData(), frame.Size()); +} + Result_t AS_02::IAB::MXFWriter::AddDmsGenericPartUtf8Text(const ASDCP::FrameBuffer& FrameBuf, ASDCP::AESEncContext* Ctx, ASDCP::HMACContext* HMAC, const std::string& trackDescription, const std::string& dataDescription) @@ -431,8 +435,6 @@ AS_02::IAB::MXFReader::OpenRead(const std::string& filename) { /* invalidate current frame */ - this->m_CurrentFrameIndex = -1; - /* we are ready */ this->m_State = ST_READER_READY; @@ -476,120 +478,152 @@ Result_t AS_02::IAB::MXFReader::GetFrameCount(ui32_t& frameCount) const { return Kumu::RESULT_OK; } -Result_t -AS_02::IAB::MXFReader::ReadFrame(ui32_t frame_number, ASDCP::FrameBuffer& frame) { +/* Anonymous namespace with ReadFrame helpers */ +namespace { + bool checkFrameCapacity(ASDCP::FrameBuffer& frame, size_t size, bool reallocate_if_needed) { - /* are we already running */ - - if (this->m_State == ST_READER_BEGIN) { - return Kumu::RESULT_INIT; + if (frame.Capacity() < size) { + if (!reallocate_if_needed) { + return false; + } + Result_t result = frame.Capacity(size); + return result == RESULT_OK; + } + return true; } - Result_t result = RESULT_OK; - - // look up frame index node - IndexTableSegment::IndexEntry index_entry; + Result_t + ReadFrameImpl(ui32_t frame_number, ASDCP::FrameBuffer& frame, ReaderState_t& reader_state, ASDCP::mem_ptr& reader, bool reallocate_if_needed) { - result = this->m_Reader->m_IndexAccess.Lookup(frame_number, index_entry); + /* are we already running */ - if (result.Failure()) { - DefaultLogSink().Error("Frame value out of range: %u\n", frame_number); - return 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); - return result; - } + if (reader_state == ST_READER_BEGIN) { + return Kumu::RESULT_INIT; + } - /* read the preamble info */ + Result_t result = RESULT_OK; - const int preambleTLLen = 5; - const int frameTLLen = 5; + // look up frame index node + IndexTableSegment::IndexEntry index_entry; - ui32_t buffer_offset = 0; + result = reader->m_IndexAccess.Lookup(frame_number, index_entry); - if (frame.Capacity() < preambleTLLen) { - return RESULT_SMALLBUF; - } + if (result.Failure()) { + DefaultLogSink().Error("Frame value out of range: %u\n", frame_number); + return result; + } - result = this->m_Reader->m_File->Read(&frame.Data()[buffer_offset], preambleTLLen); + result = reader->m_File->Seek(index_entry.StreamOffset); - if (result.Failure()) { - DefaultLogSink().Error("Error reading IA Frame preamble\n", index_entry.StreamOffset); - return result; - } - - ui32_t preambleLen = ((ui32_t)frame.Data()[1 + buffer_offset] << 24) + - ((ui32_t)frame.Data()[2 + buffer_offset] << 16) + - ((ui32_t)frame.Data()[3 + buffer_offset] << 8) + - (ui32_t)frame.Data()[4 + buffer_offset]; + if (result.Failure()) { + DefaultLogSink().Error("Cannot seek to stream offset: %u\n", index_entry.StreamOffset); + return result; + } - buffer_offset += preambleTLLen; + /* read the preamble info */ - /* read the preamble*/ + const int preambleTLLen = 5; + const int frameTLLen = 5; - if (preambleLen > 0) { + ui32_t buffer_offset = 0; - if (frame.Capacity() < preambleTLLen + preambleLen) { - return RESULT_SMALLBUF; + if (!checkFrameCapacity(frame, preambleTLLen, reallocate_if_needed)) { + return RESULT_SMALLBUF; } - result = this->m_Reader->m_File->Read(&frame.Data()[buffer_offset], preambleLen); + result = reader->m_File->Read(&frame.Data()[buffer_offset], preambleTLLen); if (result.Failure()) { DefaultLogSink().Error("Error reading IA Frame preamble\n", index_entry.StreamOffset); return result; } - buffer_offset += preambleLen; + ui32_t preambleLen = ((ui32_t)frame.Data()[1 + buffer_offset] << 24) + + ((ui32_t)frame.Data()[2 + buffer_offset] << 16) + + ((ui32_t)frame.Data()[3 + buffer_offset] << 8) + + (ui32_t)frame.Data()[4 + buffer_offset]; - } + buffer_offset += preambleTLLen; - /* read the IA Frame info */ + /* read the preamble*/ - if (frame.Capacity() < preambleTLLen + preambleLen + frameTLLen) { - return RESULT_SMALLBUF; - } + if (preambleLen > 0) { - result = this->m_Reader->m_File->Read(&frame.Data()[buffer_offset], frameTLLen); + if (!checkFrameCapacity(frame, preambleTLLen + preambleLen, reallocate_if_needed)) { + return RESULT_SMALLBUF; + } - if (result.Failure()) { - DefaultLogSink().Error("Error reading IA Frame data\n", index_entry.StreamOffset); - return result; - } + result = reader->m_File->Read(&frame.Data()[buffer_offset], preambleLen); - ui32_t frameLen = ((ui32_t)frame.Data()[buffer_offset + 1] << 24) + - ((ui32_t)frame.Data()[buffer_offset + 2] << 16) + - ((ui32_t)frame.Data()[buffer_offset + 3] << 8) + - (ui32_t)frame.Data()[buffer_offset + 4]; + if (result.Failure()) { + DefaultLogSink().Error("Error reading IA Frame preamble\n", index_entry.StreamOffset); + return result; + } - buffer_offset += frameTLLen; + buffer_offset += preambleLen; - /* read the IA Frame */ + } - if (frameLen > 0) { + /* read the IA Frame info */ - if (frame.Capacity() < preambleTLLen + preambleLen + frameTLLen + frameLen) { + if (!checkFrameCapacity(frame, preambleTLLen + preambleLen + frameTLLen, reallocate_if_needed)) { return RESULT_SMALLBUF; } - frame.Size(preambleTLLen + preambleLen + frameTLLen + frameLen); - result = this->m_Reader->m_File->Read(&frame.Data()[buffer_offset], frameLen); + result = reader->m_File->Read(&frame.Data()[buffer_offset], frameTLLen); if (result.Failure()) { DefaultLogSink().Error("Error reading IA Frame data\n", index_entry.StreamOffset); return result; } + + ui32_t frameLen = ((ui32_t)frame.Data()[buffer_offset + 1] << 24) + + ((ui32_t)frame.Data()[buffer_offset + 2] << 16) + + ((ui32_t)frame.Data()[buffer_offset + 3] << 8) + + (ui32_t)frame.Data()[buffer_offset + 4]; + + buffer_offset += frameTLLen; + + /* read the IA Frame */ + + if (frameLen > 0) { + + if (!checkFrameCapacity(frame, preambleTLLen + preambleLen + frameTLLen + frameLen, reallocate_if_needed)) { + return RESULT_SMALLBUF; + } + frame.Size(preambleTLLen + preambleLen + frameTLLen + frameLen); + + result = reader->m_File->Read(&frame.Data()[buffer_offset], frameLen); + + if (result.Failure()) { + DefaultLogSink().Error("Error reading IA Frame data\n", index_entry.StreamOffset); + return result; + } + } + + reader_state = ST_READER_RUNNING; + + return result; } +} // namespace - this->m_State = ST_READER_RUNNING; +Result_t AS_02::IAB::MXFReader::ReadFrame(ui32_t frame_number, + AS_02::IAB::MXFReader::Frame &frame) { + Result_t result = ReadFrameImpl(frame_number, this->m_FrameBuffer, + this->m_State, this->m_Reader, true); + + frame = std::pair(this->m_FrameBuffer.Size(), + this->m_FrameBuffer.Data()); return result; } +Result_t AS_02::IAB::MXFReader::ReadFrame(ui32_t frame_number, + ASDCP::FrameBuffer &frame) { + return ReadFrameImpl(frame_number, frame, this->m_State, this->m_Reader, + false); +} + Result_t AS_02::IAB::MXFReader::ReadGenericStreamPartitionPayload(const ui32_t SID, ASDCP::FrameBuffer& frame_buf) { diff --git a/src/AS_02_IAB.h b/src/AS_02_IAB.h index 710a322..d33c749 100644 --- a/src/AS_02_IAB.h +++ b/src/AS_02_IAB.h @@ -116,7 +116,21 @@ namespace AS_02 { * Writes a single frame. * * Must be preceded by a succesful OpenWrite() call followed by zero or more WriteFrame() calls + * + * + * @param frame Pointer to a complete IA Frame + * @param sz Size in bytes of the IA Frame + * @return RESULT_OK indicates that the frame is written and additional frames can be written, + * otherwise the reader is reset and the file is left is an undermined state. + */ + Result_t WriteFrame(const ui8_t* frame, ui32_t sz); + + /** + * Writes a single frame. * + * Must be preceded by a succesful OpenWrite() call followed by zero or more WriteFrame() calls + * + * * @param frame a complete IA Frame * @return RESULT_OK indicates that the frame is written and additional frames can be written, * otherwise the reader is reset and the file is left is an undermined state. @@ -153,8 +167,8 @@ namespace AS_02 { ASDCP::mem_ptr m_Reader; - i64_t m_CurrentFrameIndex; - std::vector m_CurrentFrameBuffer; + ASDCP::FrameBuffer m_FrameBuffer; + ReaderState_t m_State; const Kumu::IFileReaderFactory& m_FileReaderFactory; @@ -236,6 +250,16 @@ namespace AS_02 { * @return RESULT_OK indicates that more frames are ready to be read, * otherwise the file is closed and the reader reset */ + Result_t ReadFrame(ui32_t frame_number, Frame& frame); + + /** + * Reads an IA Frame. + * + * @param frame_number Index of the frame to be read. Must be in the range [0, GetFrameCount()). + * @param frame Frame data. Must not be modified. Remains valid until the next call to ReadFrame(). + * @return RESULT_OK indicates that more frames are ready to be read, + * otherwise the file is closed and the reader reset + */ Result_t ReadFrame(ui32_t frame_number, ASDCP::FrameBuffer& frame); /** Reads a Generic Stream Partition payload. Returns RESULT_INIT if the file is -- cgit v1.2.3