summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hurst <jhurst@cinecert.com>2021-09-12 12:56:03 -0700
committerGitHub <noreply@github.com>2021-09-12 12:56:03 -0700
commit2cefda0dc78b4e8a1347dcd2ce281fcf6cfeef7a (patch)
tree49dc714119f6c7ccecefd5a8e7ba97b7db6be750
parent3dd7454de034d96faf5571526d935d1d93560e05 (diff)
parent7af443a806f8c8a2a3cef7ec0b0602b1872987c6 (diff)
Merge pull request #5 from DolbyLaboratories/dolby/atmos_storage/asdcplib_integration/readWriteFrame_use_framebuffer
Writeframe and Readframe in line with other APIs (they now use framebuffer)
-rw-r--r--src/AS_02_IAB.cpp224
-rw-r--r--src/AS_02_IAB.h32
2 files changed, 145 insertions, 111 deletions
diff --git a/src/AS_02_IAB.cpp b/src/AS_02_IAB.cpp
index 696a68d..536efbd 100644
--- a/src/AS_02_IAB.cpp
+++ b/src/AS_02_IAB.cpp
@@ -214,56 +214,54 @@ AS_02::IAB::MXFWriter::OpenWrite(
Result_t
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 (sz == 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 */
- /* write the frame */
+ result = this->m_Writer->m_File.Write(frame, sz);
- 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;
+ if (result.Failure()) {
+ this->Reset();
+ return result;
+ }
- /* we are running now */
+ /* increment the frame counter */
- this->m_State = ST_RUNNING;
+ this->m_Writer->m_FramesWritten++;
- } catch (Kumu::RuntimeError e) {
+ /* increment stream offset */
- this->Reset();
+ this->m_Writer->m_StreamOffset += sz;
- return e.GetResult();
+ /* we are running now */
- }
+ this->m_State = ST_RUNNING;
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)
@@ -437,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;
@@ -482,136 +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, AS_02::IAB::MXFReader::Frame& frame) {
-
- /* are we already running */
+/* Anonymous namespace with ReadFrame helpers */
+namespace {
+ bool checkFrameCapacity(ASDCP::FrameBuffer& frame, size_t size, bool reallocate_if_needed) {
- 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;
-
- /* have we already read the frame */
-
- if (frame_number != this->m_CurrentFrameIndex) {
-
- try {
-
- // 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<AS_02::h__AS02Reader>& 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);
- throw Kumu::RuntimeError(result);
- }
+ if (reader_state == ST_READER_BEGIN) {
+ return Kumu::RESULT_INIT;
+ }
- result = this->m_Reader->m_File.Seek(index_entry.StreamOffset);
+ Result_t result = RESULT_OK;
- if (result.Failure()) {
- DefaultLogSink().Error("Cannot seek to stream offset: %u\n", index_entry.StreamOffset);
- throw Kumu::RuntimeError(result);
- }
+ // look up frame index node
+ IndexTableSegment::IndexEntry index_entry;
- /* read the preamble info */
+ result = reader->m_IndexAccess.Lookup(frame_number, index_entry);
- const int preambleTLLen = 5;
- const int frameTLLen = 5;
+ if (result.Failure()) {
+ DefaultLogSink().Error("Frame value out of range: %u\n", frame_number);
+ return result;
+ }
- ui32_t buffer_offset = 0;
+ result = reader->m_File->Seek(index_entry.StreamOffset);
- this->m_CurrentFrameBuffer.resize(preambleTLLen);
+ if (result.Failure()) {
+ DefaultLogSink().Error("Cannot seek to stream offset: %u\n", index_entry.StreamOffset);
+ return result;
+ }
- result = this->m_Reader->m_File.Read(&this->m_CurrentFrameBuffer[buffer_offset], preambleTLLen);
+ /* read the preamble info */
- if (result.Failure()) {
- DefaultLogSink().Error("Error reading IA Frame preamble\n", index_entry.StreamOffset);
- throw Kumu::RuntimeError(result);
- }
+ const int preambleTLLen = 5;
+ const int frameTLLen = 5;
- 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];
+ ui32_t buffer_offset = 0;
- buffer_offset += preambleTLLen;
+ if (!checkFrameCapacity(frame, preambleTLLen, reallocate_if_needed)) {
+ return RESULT_SMALLBUF;
+ }
- /* read the preamble*/
+ result = reader->m_File->Read(&frame.Data()[buffer_offset], preambleTLLen);
- if (preambleLen > 0) {
+ if (result.Failure()) {
+ DefaultLogSink().Error("Error reading IA Frame preamble\n", index_entry.StreamOffset);
+ return result;
+ }
- this->m_CurrentFrameBuffer.resize(preambleTLLen + 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];
- result = this->m_Reader->m_File.Read(&this->m_CurrentFrameBuffer[buffer_offset], preambleLen);
+ buffer_offset += preambleTLLen;
- if (result.Failure()) {
- DefaultLogSink().Error("Error reading IA Frame preamble\n", index_entry.StreamOffset);
- throw Kumu::RuntimeError(result);
- }
+ /* read the preamble*/
- buffer_offset += preambleLen;
+ if (preambleLen > 0) {
+ if (!checkFrameCapacity(frame, preambleTLLen + preambleLen, reallocate_if_needed)) {
+ return RESULT_SMALLBUF;
}
- /* 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);
+ result = reader->m_File->Read(&frame.Data()[buffer_offset], preambleLen);
if (result.Failure()) {
- DefaultLogSink().Error("Error reading IA Frame data\n", index_entry.StreamOffset);
- throw Kumu::RuntimeError(result);
+ DefaultLogSink().Error("Error reading IA Frame preamble\n", index_entry.StreamOffset);
+ return 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 */
+ 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 (!checkFrameCapacity(frame, preambleTLLen + preambleLen + frameTLLen, reallocate_if_needed)) {
+ return RESULT_SMALLBUF;
+ }
- if (result.Failure()) {
- DefaultLogSink().Error("Error reading IA Frame data\n", index_entry.StreamOffset);
- throw Kumu::RuntimeError(result);
- }
+ result = 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 (!checkFrameCapacity(frame, preambleTLLen + preambleLen + frameTLLen + frameLen, reallocate_if_needed)) {
+ return RESULT_SMALLBUF;
+ }
+ frame.Size(preambleTLLen + preambleLen + frameTLLen + frameLen);
- return e.GetResult();
+ 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
- frame = std::pair<size_t, const ui8_t*>(this->m_CurrentFrameBuffer.size(), &this->m_CurrentFrameBuffer[0]);
+Result_t AS_02::IAB::MXFReader::ReadFrame(ui32_t frame_number,
+ AS_02::IAB::MXFReader::Frame &frame) {
- this->m_State = ST_READER_RUNNING;
+ Result_t result = ReadFrameImpl(frame_number, this->m_FrameBuffer,
+ this->m_State, this->m_Reader, true);
+ frame = std::pair<size_t, const ui8_t *>(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 7e489e6..d33c749 100644
--- a/src/AS_02_IAB.h
+++ b/src/AS_02_IAB.h
@@ -116,8 +116,9 @@ 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 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.
@@ -125,6 +126,18 @@ namespace AS_02 {
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
* optional AESEncContext argument is present, the document is encrypted
* prior to writing. Fails if the file is not open, is finalized, or an
@@ -154,8 +167,8 @@ namespace AS_02 {
ASDCP::mem_ptr<h__Reader> m_Reader;
- i64_t m_CurrentFrameIndex;
- std::vector<ui8_t> m_CurrentFrameBuffer;
+ ASDCP::FrameBuffer m_FrameBuffer;
+
ReaderState_t m_State;
const Kumu::IFileReaderFactory& m_FileReaderFactory;
@@ -231,7 +244,7 @@ namespace AS_02 {
/**
* 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,
@@ -239,6 +252,15 @@ namespace AS_02 {
*/
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