diff options
| author | Thomas Richter <thomas.richter@iis.fraunhofer.de> | 2022-01-28 09:30:55 +0100 |
|---|---|---|
| committer | Thomas Richter <thomas.richter@iis.fraunhofer.de> | 2022-01-28 09:30:55 +0100 |
| commit | 7081231eba80044c0f97d4da5998d65681b94528 (patch) | |
| tree | 550d0ecc45d301663b93cfd34e6c958fa6c5b4c0 /src | |
| parent | d96e461dd7ba5f81ce40979a79bfad105be352de (diff) | |
| parent | 94e66805feeba15e6dd80ec290f04706a1c9dbdc (diff) | |
Merge branch 'master' of github.com:thorfdbg/asdcplib
Diffstat (limited to 'src')
70 files changed, 1465 insertions, 978 deletions
diff --git a/src/ACES_Sequence_Parser.cpp b/src/ACES_Sequence_Parser.cpp index 655da1f..95887a0 100644 --- a/src/ACES_Sequence_Parser.cpp +++ b/src/ACES_Sequence_Parser.cpp @@ -32,57 +32,57 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <assert.h> #include <KM_log.h> - using Kumu::DefaultLogSink; +namespace { + class FileList : public std::list<std::string> + { + std::string m_DirName; -class FileList : public std::list<std::string> -{ - std::string m_DirName; - -public: - FileList() {} - ~FileList() {} + public: + FileList() {} + ~FileList() {} - const FileList& operator=(const std::list<std::string>& pathlist) - { - std::list<std::string>::const_iterator i; - for(i = pathlist.begin(); i != pathlist.end(); i++) - push_back(*i); - return *this; - } + const FileList& operator=(const std::list<std::string>& pathlist) + { + std::list<std::string>::const_iterator i; + for(i = pathlist.begin(); i != pathlist.end(); i++) + push_back(*i); + return *this; + } - // - ASDCP::Result_t InitFromDirectory(const std::string& path) - { - char next_file[Kumu::MaxFilePath]; - Kumu::DirScanner Scanner; + // + ASDCP::Result_t InitFromDirectory(const std::string& path) + { + char next_file[Kumu::MaxFilePath]; + Kumu::DirScanner Scanner; - ASDCP::Result_t result = Scanner.Open(path); + ASDCP::Result_t result = Scanner.Open(path); - if(ASDCP_SUCCESS(result)) - { - m_DirName = path; + if(ASDCP_SUCCESS(result)) + { + m_DirName = path; - while(ASDCP_SUCCESS(Scanner.GetNext(next_file))) - { - if(next_file[0] == '.') // no hidden files or internal links - continue; + while(ASDCP_SUCCESS(Scanner.GetNext(next_file))) + { + if(next_file[0] == '.') // no hidden files or internal links + continue; - std::string Str(m_DirName); - Str += "/"; - Str += next_file; + std::string Str(m_DirName); + Str += "/"; + Str += next_file; - if(!Kumu::PathIsDirectory(Str)) - push_back(Str); - } + if(!Kumu::PathIsDirectory(Str)) + push_back(Str); + } - sort(); - } + sort(); + } - return result; - } -}; + return result; + } + }; +} class AS_02::ACES::SequenceParser::h__SequenceParser diff --git a/src/AS_02.h b/src/AS_02.h index ab58f31..8a31d8f 100644 --- a/src/AS_02.h +++ b/src/AS_02.h @@ -87,7 +87,7 @@ namespace AS_02 AS02IndexReader(const ASDCP::Dictionary*); virtual ~AS02IndexReader(); - Result_t InitFromFile(const Kumu::FileReader& reader, const ASDCP::MXF::RIP& rip, const bool has_header_essence); + Result_t InitFromFile(const Kumu::IFileReader& reader, const ASDCP::MXF::RIP& rip, const bool has_header_essence); ui32_t GetDuration() const; void Dump(FILE* = 0); Result_t GetMDObjectByID(const Kumu::UUID&, ASDCP::MXF::InterchangeObject** = 0); @@ -196,7 +196,7 @@ namespace AS_02 ASDCP_NO_COPY_CONSTRUCT(MXFReader); public: - MXFReader(); + MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory); virtual ~MXFReader(); // Warning: direct manipulation of MXF structures can interfere @@ -289,7 +289,7 @@ namespace AS_02 ASDCP_NO_COPY_CONSTRUCT(MXFReader); public: - MXFReader(); + MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory); virtual ~MXFReader(); // Warning: direct manipulation of MXF structures can interfere @@ -443,8 +443,8 @@ namespace AS_02 ASDCP::mem_ptr<h__Reader> m_Reader; ASDCP_NO_COPY_CONSTRUCT(MXFReader); - public: - MXFReader(); + public: + MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory); virtual ~MXFReader(); // Warning: direct manipulation of MXF structures can interfere @@ -547,7 +547,7 @@ namespace AS_02 ASDCP_NO_COPY_CONSTRUCT(MXFReader); public: - MXFReader(); + MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory); virtual ~MXFReader(); // Warning: direct manipulation of MXF structures can interfere diff --git a/src/AS_02_ACES.cpp b/src/AS_02_ACES.cpp index 0d3105a..1eda2d0 100644 --- a/src/AS_02_ACES.cpp +++ b/src/AS_02_ACES.cpp @@ -290,8 +290,8 @@ class AS_02::ACES::MXFReader::h__Reader : public AS_02::h__AS02Reader ASDCP::MXF::RGBAEssenceDescriptor *m_EssenceDescriptor; public: - h__Reader(const Dictionary *d) : - AS_02::h__AS02Reader(d), m_EssenceDescriptor(NULL) {} + h__Reader(const Dictionary *d, const Kumu::IFileReaderFactory& fileReaderFactory) : + AS_02::h__AS02Reader(d, fileReaderFactory), m_EssenceDescriptor(NULL) {} AS_02::ACES::ResourceList_t m_Anc_Resources; @@ -343,7 +343,7 @@ Result_t AS_02::ACES::MXFReader::h__Reader::OpenRead(const std::string& filename Result_t AS_02::ACES::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, AS_02::ACES::FrameBuffer& FrameBuf, ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC) { - if(!m_File.IsOpen()) return RESULT_INIT; + if(!m_File->IsOpen()) return RESULT_INIT; assert(m_Dict); return ReadEKLVFrame(FrameNum, FrameBuf, m_Dict->ul(MDD_ACESFrameWrappedEssence), Ctx, HMAC); //PB:new UL @@ -395,12 +395,12 @@ AS_02::Result_t AS_02::ACES::MXFReader::h__Reader::ReadAncillaryResource(const K if((Kumu::fpos_t)TmpPair.ByteOffset != m_LastPosition) { m_LastPosition = TmpPair.ByteOffset; - result = m_File.Seek(TmpPair.ByteOffset); + result = m_File->Seek(TmpPair.ByteOffset); } // read the partition header ASDCP::MXF::Partition GSPart(m_Dict); - result = GSPart.InitFromFile(m_File); + result = GSPart.InitFromFile(*m_File); if(ASDCP_SUCCESS(result)) { @@ -473,7 +473,7 @@ AS_02::Result_t AS_02::ACES::MXFReader::h__Reader::FillAncillaryResourceDescript void AS_02::ACES::MXFReader::DumpHeaderMetadata(FILE* stream) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { m_Reader->m_HeaderPart.Dump(stream); } @@ -484,7 +484,7 @@ AS_02::ACES::MXFReader::DumpHeaderMetadata(FILE* stream) const void AS_02::ACES::MXFReader::DumpIndex(FILE* stream) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { m_Reader->m_IndexAccess.Dump(stream); } @@ -672,7 +672,7 @@ AS_02::Result_t AS_02::ACES::MXFWriter::h__Writer::WriteAncillaryResource(const return RESULT_STATE; } - Kumu::fpos_t here = m_File.Tell(); + Kumu::fpos_t here = m_File.TellPosition(); assert(m_Dict); // create generic stream partition header @@ -782,10 +782,9 @@ AS_02::Result_t AS_02::ACES::MXFWriter::WriteAncillaryResource(const AS_02::ACES } -AS_02::ACES::MXFReader::MXFReader() +AS_02::ACES::MXFReader::MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory) { - - m_Reader = new h__Reader(&DefaultCompositeDict()); + m_Reader = new h__Reader(&DefaultCompositeDict(), fileReaderFactory); } AS_02::ACES::MXFReader::~MXFReader() @@ -841,7 +840,7 @@ AS_02::Result_t AS_02::ACES::MXFReader::OpenRead(const std::string& filename) co AS_02::Result_t AS_02::ACES::MXFReader::Close() const { - if(m_Reader && m_Reader->m_File.IsOpen()) + if(m_Reader && m_Reader->m_File->IsOpen()) { m_Reader->Close(); return RESULT_OK; @@ -852,7 +851,7 @@ AS_02::Result_t AS_02::ACES::MXFReader::Close() const AS_02::Result_t AS_02::ACES::MXFReader::FillWriterInfo(ASDCP::WriterInfo& Info) const { - if(m_Reader && m_Reader->m_File.IsOpen()) + if(m_Reader && m_Reader->m_File->IsOpen()) { Info = m_Reader->m_Info; return RESULT_OK; @@ -863,7 +862,7 @@ AS_02::Result_t AS_02::ACES::MXFReader::FillWriterInfo(ASDCP::WriterInfo& Info) AS_02::Result_t AS_02::ACES::MXFReader::ReadFrame(ui32_t FrameNum, AS_02::ACES::FrameBuffer &FrameBuf, ASDCP::AESDecContext *Ctx /*= 0*/, ASDCP::HMACContext *HMAC /*= 0*/) const { - if(m_Reader && m_Reader->m_File.IsOpen()) + if(m_Reader && m_Reader->m_File->IsOpen()) return m_Reader->ReadFrame(FrameNum, FrameBuf, Ctx, HMAC); return RESULT_INIT; @@ -872,7 +871,7 @@ AS_02::Result_t AS_02::ACES::MXFReader::ReadFrame(ui32_t FrameNum, AS_02::ACES:: AS_02::Result_t AS_02::ACES::MXFReader::ReadAncillaryResource(const Kumu::UUID &uuid, AS_02::ACES::FrameBuffer &FrameBuf, ASDCP::AESDecContext *Ctx , ASDCP::HMACContext *HMAC ) const { - if(m_Reader && m_Reader->m_File.IsOpen()) + if(m_Reader && m_Reader->m_File->IsOpen()) return m_Reader->ReadAncillaryResource(uuid, FrameBuf, Ctx, HMAC); return RESULT_INIT; @@ -881,7 +880,7 @@ AS_02::Result_t AS_02::ACES::MXFReader::ReadAncillaryResource(const Kumu::UUID & AS_02::Result_t AS_02::ACES::MXFReader::FillAncillaryResourceList(AS_02::ACES::ResourceList_t &ancillary_resources) const { - if(m_Reader && m_Reader->m_File.IsOpen()) + if(m_Reader && m_Reader->m_File->IsOpen()) { ancillary_resources = m_Reader->m_Anc_Resources; return RESULT_OK; diff --git a/src/AS_02_ACES.h b/src/AS_02_ACES.h index dd53904..faa06c4 100644 --- a/src/AS_02_ACES.h +++ b/src/AS_02_ACES.h @@ -442,7 +442,7 @@ class MXFReader ASDCP_NO_COPY_CONSTRUCT(MXFReader); public: - MXFReader(); + MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory); virtual ~MXFReader(); // Warning: direct manipulation of MXF structures can interfere diff --git a/src/AS_02_IAB.cpp b/src/AS_02_IAB.cpp index aa551d9..5d1876b 100644 --- a/src/AS_02_IAB.cpp +++ b/src/AS_02_IAB.cpp @@ -33,6 +33,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <iostream> #include <iomanip> #include <stdexcept> +#include "AS_02_internal.h" namespace Kumu { class RuntimeError : public std::runtime_error { @@ -45,6 +46,31 @@ namespace Kumu { }; } +// +class AS_02::IAB::MXFWriter::h__Writer : public h__AS02Writer<AS_02::MXF::AS02IndexWriterVBR> +{ + ASDCP_NO_COPY_CONSTRUCT(h__Writer); + h__Writer(); +public: + WriterState_t m_State; + + h__Writer(const Dictionary *d) : h__AS02Writer(d), m_State(ST_BEGIN) {} + virtual ~h__Writer(){} +}; + +// +class AS_02::IAB::MXFReader::h__Reader : public h__AS02Reader +{ + ASDCP_NO_COPY_CONSTRUCT(h__Reader); + h__Reader(); +public: + ReaderState_t m_State; + + h__Reader(const Dictionary *d, const Kumu::IFileReaderFactory& fileReaderFactory) : + h__AS02Reader(d, fileReaderFactory), m_State(ST_READER_BEGIN) {} + virtual ~h__Reader(){} +}; + //------------------------------------------------------------------------------------------ /* Size of the BER Length of the clip */ @@ -54,14 +80,14 @@ static const int CLIP_BER_LENGTH_SIZE = 8; static const int RESERVED_KL_SIZE = ASDCP::SMPTE_UL_LENGTH + CLIP_BER_LENGTH_SIZE; -AS_02::IAB::MXFWriter::MXFWriter() : m_ClipStart(0), m_State(ST_BEGIN) { +AS_02::IAB::MXFWriter::MXFWriter() : m_ClipStart(0), m_Writer(0) { } AS_02::IAB::MXFWriter::~MXFWriter() {} const ASDCP::MXF::OP1aHeader& AS_02::IAB::MXFWriter::OP1aHeader() const { - if (this->m_State == ST_BEGIN) { + if (this->m_Writer->m_State == ST_BEGIN) { throw Kumu::RuntimeError(Kumu::RESULT_INIT); } @@ -70,7 +96,7 @@ AS_02::IAB::MXFWriter::OP1aHeader() const { const ASDCP::MXF::RIP& AS_02::IAB::MXFWriter::RIP() const { - if (this->m_State == ST_BEGIN) { + if (this->m_Writer->m_State == ST_BEGIN) { throw Kumu::RuntimeError(Kumu::RESULT_INIT); } @@ -88,7 +114,8 @@ AS_02::IAB::MXFWriter::OpenWrite( /* are we already running */ - if (this->m_State != ST_BEGIN) { + if ( this->m_Writer && this->m_Writer->m_State != ST_BEGIN ) { + KM_RESULT_STATE_HERE(); return Kumu::RESULT_STATE; } @@ -177,7 +204,7 @@ AS_02::IAB::MXFWriter::OpenWrite( /* start the clip */ - this->m_ClipStart = this->m_Writer->m_File.Tell(); + this->m_ClipStart = this->m_Writer->m_File.TellPosition(); /* reserve space for the KL of the KLV, which will be written later during finalization */ @@ -197,7 +224,7 @@ AS_02::IAB::MXFWriter::OpenWrite( this->m_Writer->m_StreamOffset = RESERVED_KL_SIZE; - this->m_State = ST_READY; + this->m_Writer->m_State = ST_READY; } catch (Kumu::RuntimeError e) { @@ -213,54 +240,63 @@ 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) { + if (this->m_Writer->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++; + if (result.Failure()) { + this->Reset(); + return result; + } - /* increment stream offset */ + /* increment the frame counter */ - this->m_Writer->m_StreamOffset += sz; + this->m_Writer->m_FramesWritten++; - /* we are running now */ + /* increment stream offset */ - this->m_State = ST_RUNNING; + this->m_Writer->m_StreamOffset += sz; - } catch (Kumu::RuntimeError e) { + /* we are running now */ - this->Reset(); + this->m_Writer->m_State = ST_RUNNING; - return e.GetResult(); + return result; +} - } +Result_t AS_02::IAB::MXFWriter::WriteFrame(const ASDCP::FrameBuffer& frame) { + return WriteFrame(frame.RoData(), frame.Size()); +} - return result; +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) +{ + if ( m_Writer.empty() ) + return RESULT_INIT; + + m_Writer->FlushIndexPartition(); + return m_Writer->AddDmsGenericPartUtf8Text(FrameBuf, Ctx, HMAC, trackDescription, dataDescription); } Result_t @@ -268,9 +304,14 @@ AS_02::IAB::MXFWriter::Finalize() { /* are we running */ - if (this->m_State == ST_BEGIN) { + if (this->m_Writer->m_State == ST_BEGIN) { return Kumu::RESULT_INIT; } + if (this->m_Writer->m_State != ST_RUNNING) { + KM_RESULT_STATE_HERE(); + return RESULT_STATE; + } + Result_t result = RESULT_OK; @@ -278,7 +319,7 @@ AS_02::IAB::MXFWriter::Finalize() { /* write clip length */ - ui64_t current_position = this->m_Writer->m_File.Tell(); + ui64_t current_position = this->m_Writer->m_File.TellPosition(); result = this->m_Writer->m_File.Seek(m_ClipStart + ASDCP::SMPTE_UL_LENGTH); @@ -329,21 +370,25 @@ AS_02::IAB::MXFWriter::Finalize() { void AS_02::IAB::MXFWriter::Reset() { - this->m_Writer.set(NULL); - this->m_State = ST_BEGIN; + this->m_Writer.set(0); } //------------------------------------------------------------------------------------------ -AS_02::IAB::MXFReader::MXFReader() : m_State(ST_READER_BEGIN) {} +AS_02::IAB::MXFReader::MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory) : + m_FileReaderFactory(fileReaderFactory), m_Reader(0) {} -AS_02::IAB::MXFReader::~MXFReader() {} +AS_02::IAB::MXFReader::~MXFReader() { + if ( m_Reader && m_Reader->m_File->IsOpen()) { + m_Reader->Close(); + } +} ASDCP::MXF::OP1aHeader& AS_02::IAB::MXFReader::OP1aHeader() const { - if (this->m_State == ST_READER_BEGIN) { + if (this->m_Reader->m_State == ST_READER_BEGIN) { throw Kumu::RuntimeError(Kumu::RESULT_INIT); } @@ -352,7 +397,7 @@ AS_02::IAB::MXFReader::OP1aHeader() const { const ASDCP::MXF::RIP& AS_02::IAB::MXFReader::RIP() const { - if (this->m_State == ST_READER_BEGIN) { + if (this->m_Reader->m_State == ST_READER_BEGIN) { throw Kumu::RuntimeError(Kumu::RESULT_INIT); } @@ -364,7 +409,8 @@ AS_02::IAB::MXFReader::OpenRead(const std::string& filename) { /* are we already running */ - if (this->m_State != ST_READER_BEGIN) { + if ( this->m_Reader && this->m_Reader->m_State != ST_READER_BEGIN ) { + KM_RESULT_STATE_HERE(); return Kumu::RESULT_STATE; } @@ -372,24 +418,23 @@ AS_02::IAB::MXFReader::OpenRead(const std::string& filename) { /* initialize the writer */ - this->m_Reader = new h__Reader(&DefaultCompositeDict()); + this->m_Reader = new h__Reader(&DefaultCompositeDict(), m_FileReaderFactory); 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 ( ASDCP_SUCCESS(result)){ + this->m_Reader->m_HeaderPart.GetMDObjectByType( + this->m_Reader->m_Dict->Type(MDD_IABEssenceDescriptor).ul, + &tmp_iobj ); + } if (!tmp_iobj) { + DefaultLogSink().Error("IABEssenceDescriptor object not found in IMF/IAB MXF file.\n"); throw Kumu::RuntimeError(Kumu::RESULT_FAIL); } @@ -399,6 +444,7 @@ AS_02::IAB::MXFReader::OpenRead(const std::string& filename) { ); if (!tmp_iobj) { + DefaultLogSink().Error("IABSoundfieldLabelSubDescriptor object not found.\n"); throw Kumu::RuntimeError(Kumu::RESULT_FAIL); } @@ -415,11 +461,9 @@ 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; + this->m_Reader->m_State = ST_READER_READY; } catch (Kumu::RuntimeError e) { @@ -437,7 +481,7 @@ AS_02::IAB::MXFReader::Close() { /* are we already running */ - if (this->m_State == ST_READER_BEGIN) { + if (this->m_Reader->m_State == ST_READER_BEGIN) { return Kumu::RESULT_INIT; } @@ -451,7 +495,7 @@ Result_t AS_02::IAB::MXFReader::GetFrameCount(ui32_t& frameCount) const { /* are we already running */ - if (this->m_State == ST_READER_BEGIN) { + if (this->m_Reader->m_State == ST_READER_BEGIN) { return Kumu::RESULT_INIT; } @@ -460,141 +504,168 @@ 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) { +/* 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; - - /* have we already read the frame */ - - if (frame_number != this->m_CurrentFrameIndex) { + Result_t + ReadFrameImpl(ui32_t frame_number, ASDCP::FrameBuffer& frame, ReaderState_t& reader_state, AS_02::h__AS02Reader *reader, bool reallocate_if_needed) { + assert(reader); + /* are we already running */ - try { - - // look up frame index node - IndexTableSegment::IndexEntry index_entry; + if (reader_state == ST_READER_BEGIN) { + return Kumu::RESULT_INIT; + } - result = this->m_Reader->m_IndexAccess.Lookup(frame_number, index_entry); + Result_t result = RESULT_OK; - if (result.Failure()) { - DefaultLogSink().Error("Frame value out of range: %u\n", frame_number); - throw Kumu::RuntimeError(result); - } + // look up frame index node + IndexTableSegment::IndexEntry index_entry; - result = this->m_Reader->m_File.Seek(index_entry.StreamOffset); + result = reader->m_IndexAccess.Lookup(frame_number, index_entry); - if (result.Failure()) { - DefaultLogSink().Error("Cannot seek to stream offset: %u\n", index_entry.StreamOffset); - throw Kumu::RuntimeError(result); - } + if (result.Failure()) { + DefaultLogSink().Error("Frame value out of range: %u\n", frame_number); + return result; + } - /* read the preamble info */ + result = reader->m_File->Seek(index_entry.StreamOffset); - const int preambleTLLen = 5; - const int frameTLLen = 5; + if (result.Failure()) { + DefaultLogSink().Error("Cannot seek to stream offset: %u\n", index_entry.StreamOffset); + return result; + } - ui32_t buffer_offset = 0; + /* read the preamble info */ - this->m_CurrentFrameBuffer.resize(preambleTLLen); + const int preambleTLLen = 5; + const int frameTLLen = 5; - result = this->m_Reader->m_File.Read(&this->m_CurrentFrameBuffer[buffer_offset], preambleTLLen); + ui32_t buffer_offset = 0; - if (result.Failure()) { - DefaultLogSink().Error("Error reading IA Frame preamble\n", index_entry.StreamOffset); - throw Kumu::RuntimeError(result); - } + if (!checkFrameCapacity(frame, preambleTLLen, reallocate_if_needed)) { + return RESULT_SMALLBUF; + } - 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 = reader->m_File->Read(&frame.Data()[buffer_offset], preambleTLLen); - buffer_offset += preambleTLLen; + if (result.Failure()) { + DefaultLogSink().Error("Error reading IA Frame preamble\n", index_entry.StreamOffset); + return result; + } - /* read the preamble*/ + 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 (preambleLen > 0) { + buffer_offset += preambleTLLen; - this->m_CurrentFrameBuffer.resize(preambleTLLen + preambleLen); + /* read the preamble*/ - result = this->m_Reader->m_File.Read(&this->m_CurrentFrameBuffer[buffer_offset], preambleLen); + if (preambleLen > 0) { - if (result.Failure()) { - DefaultLogSink().Error("Error reading IA Frame preamble\n", index_entry.StreamOffset); - throw Kumu::RuntimeError(result); - } + if (!checkFrameCapacity(frame, preambleTLLen + preambleLen, reallocate_if_needed)) { + return RESULT_SMALLBUF; + } - buffer_offset += preambleLen; + result = reader->m_File->Read(&frame.Data()[buffer_offset], preambleLen); + if (result.Failure()) { + DefaultLogSink().Error("Error reading IA Frame preamble\n", index_entry.StreamOffset); + return result; } - /* read the IA Frame info */ + buffer_offset += preambleLen; - this->m_CurrentFrameBuffer.resize(preambleTLLen + preambleLen + frameTLLen); + } - result = this->m_Reader->m_File.Read(&this->m_CurrentFrameBuffer[buffer_offset], frameTLLen); + /* read the IA Frame info */ - if (result.Failure()) { - DefaultLogSink().Error("Error reading IA Frame data\n", index_entry.StreamOffset); - throw Kumu::RuntimeError(result); - } + if (!checkFrameCapacity(frame, preambleTLLen + preambleLen + frameTLLen, reallocate_if_needed)) { + 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 = reader->m_File->Read(&frame.Data()[buffer_offset], frameTLLen); - buffer_offset += frameTLLen; + if (result.Failure()) { + DefaultLogSink().Error("Error reading IA Frame data\n", index_entry.StreamOffset); + return result; + } - /* read the IA Frame */ + 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 (frameLen > 0) { + buffer_offset += frameTLLen; - this->m_CurrentFrameBuffer.resize(preambleTLLen + preambleLen + frameTLLen + frameLen); + /* read the IA Frame */ - result = this->m_Reader->m_File.Read(&this->m_CurrentFrameBuffer[buffer_offset], frameLen); + if (frameLen > 0) { - if (result.Failure()) { - DefaultLogSink().Error("Error reading IA Frame data\n", index_entry.StreamOffset); - throw Kumu::RuntimeError(result); - } + if (!checkFrameCapacity(frame, preambleTLLen + preambleLen + frameTLLen + frameLen, reallocate_if_needed)) { + return RESULT_SMALLBUF; + } + frame.Size(preambleTLLen + preambleLen + frameTLLen + frameLen); - buffer_offset += 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; } + } - /* update current frame */ + reader_state = ST_READER_RUNNING; - this->m_CurrentFrameIndex = frame_number; + return result; + } +} // namespace - } catch (Kumu::RuntimeError e) { +Result_t AS_02::IAB::MXFReader::ReadFrame(ui32_t frame_number, + AS_02::IAB::MXFReader::Frame &frame) { + assert(!this->m_Reader.empty()); + Result_t result = ReadFrameImpl(frame_number, this->m_FrameBuffer, + this->m_Reader->m_State, this->m_Reader, true); - this->Reset(); + frame = std::pair<size_t, const ui8_t *>(this->m_FrameBuffer.Size(), + this->m_FrameBuffer.Data()); + return result; +} - return e.GetResult(); +Result_t AS_02::IAB::MXFReader::ReadFrame(ui32_t frame_number, + ASDCP::FrameBuffer &frame) { + return ReadFrameImpl(frame_number, frame, this->m_Reader->m_State, this->m_Reader, + false); +} +Result_t +AS_02::IAB::MXFReader::ReadGenericStreamPartitionPayload(const ui32_t SID, ASDCP::FrameBuffer& frame_buf) +{ + if ( m_Reader && m_Reader->m_File->IsOpen() ) + { + return m_Reader->ReadGenericStreamPartitionPayload(SID, frame_buf, 0, 0 /*no encryption*/); } - } - - frame = std::pair<size_t, const ui8_t*>(this->m_CurrentFrameBuffer.size(), &this->m_CurrentFrameBuffer[0]); - - this->m_State = ST_READER_RUNNING; - - return result; + return RESULT_INIT; } Result_t AS_02::IAB::MXFReader::FillWriterInfo(WriterInfo& Info) const { /* are we already running */ - if (this->m_State == ST_READER_BEGIN) { + if (this->m_Reader->m_State == ST_READER_BEGIN) { return Kumu::RESULT_FAIL; } @@ -605,7 +676,7 @@ AS_02::IAB::MXFReader::FillWriterInfo(WriterInfo& Info) const { void AS_02::IAB::MXFReader::DumpHeaderMetadata(FILE* stream) const { - if (this->m_State != ST_READER_BEGIN) { + if (this->m_Reader->m_State != ST_READER_BEGIN) { this->m_Reader->m_HeaderPart.Dump(stream); } } @@ -613,15 +684,18 @@ AS_02::IAB::MXFReader::DumpHeaderMetadata(FILE* stream) const { void AS_02::IAB::MXFReader::DumpIndex(FILE* stream) const { - if (this->m_State != ST_READER_BEGIN) { + if (this->m_Reader->m_State != ST_READER_BEGIN) { this->m_Reader->m_IndexAccess.Dump(stream); } } void AS_02::IAB::MXFReader::Reset() { - this->m_Reader.set(NULL); - this->m_State = ST_READER_BEGIN; + if ( m_Reader && m_Reader->m_File->IsOpen()) { + m_Reader->Close(); + } + + this->m_Reader.set(0); } // diff --git a/src/AS_02_IAB.h b/src/AS_02_IAB.h index 57fb77e..dc7f564 100644 --- a/src/AS_02_IAB.h +++ b/src/AS_02_IAB.h @@ -37,7 +37,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define AS_02_IAB_h__ #include "AS_02.h" -#include "AS_02_internal.h" #include "Metadata.h" namespace AS_02 { @@ -49,12 +48,9 @@ namespace AS_02 { * */ class MXFWriter { - - typedef h__AS02Writer<AS_02::MXF::AS02IndexWriterVBR> h__Writer; - + class h__Writer; ASDCP::mem_ptr<h__Writer> m_Writer; ui64_t m_ClipStart; - WriterState_t m_State; void Reset(); @@ -116,8 +112,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 +122,27 @@ 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 + * operating system error occurs. + */ + Result_t AddDmsGenericPartUtf8Text(const ASDCP::FrameBuffer& frame_buffer, ASDCP::AESEncContext* enc = 0, ASDCP::HMACContext* hmac = 0, + const std::string& trackDescription = "Descriptive Track", const std::string& dataDescription = ""); + + /** * Writes the Track File footer and closes the file. * * Must be preceded by a succesful OpenWrite() call followed by zero or more WriteFrame() calls @@ -140,14 +158,12 @@ namespace AS_02 { * */ class MXFReader { - - typedef h__AS02Reader h__Reader; - + class h__Reader; ASDCP::mem_ptr<h__Reader> m_Reader; - i64_t m_CurrentFrameIndex; - std::vector<ui8_t> m_CurrentFrameBuffer; - ReaderState_t m_State; + ASDCP::FrameBuffer m_FrameBuffer; + + const Kumu::IFileReaderFactory& m_FileReaderFactory; void Reset(); @@ -161,7 +177,16 @@ namespace AS_02 { /* methods */ - MXFReader(); + /** + * Construct MXF Reader + * . + * @param fileReaderFactory Abstract interface that allows + * to override asdcplib's file read access by a user implementation. + * Notice that the factory object reference needs to remain valid + * when performing OpenRead operation. + */ + MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory); + virtual ~MXFReader(); /** @@ -220,6 +245,23 @@ 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 + * actual partition at ByteOffset does not have a matching BodySID value. + * Encryption is not currently supported. + */ + Result_t ReadGenericStreamPartitionPayload(ui32_t SID, ASDCP::FrameBuffer& FrameBuf); + + /** * Returns the number of IA Frame in the Track File. * * @param frameCount Number of IA Frames diff --git a/src/AS_02_ISXD.cpp b/src/AS_02_ISXD.cpp index f7165a3..fe6f037 100644 --- a/src/AS_02_ISXD.cpp +++ b/src/AS_02_ISXD.cpp @@ -54,8 +54,8 @@ class AS_02::ISXD::MXFReader::h__Reader : public AS_02::h__AS02Reader ASDCP_NO_COPY_CONSTRUCT(h__Reader); public: - h__Reader(const Dictionary *d) : - AS_02::h__AS02Reader(d) {} + h__Reader(const Dictionary* d, const Kumu::IFileReaderFactory& fileReaderFactory) : + AS_02::h__AS02Reader(d, fileReaderFactory) {} virtual ~h__Reader() {} @@ -101,7 +101,7 @@ Result_t AS_02::ISXD::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf, ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC) { - if ( ! m_File.IsOpen() ) + if ( ! m_File->IsOpen() ) return RESULT_INIT; assert(m_Dict); @@ -113,9 +113,9 @@ AS_02::ISXD::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, ASDCP::FrameBuffer //------------------------------------------------------------------------------------------ // -AS_02::ISXD::MXFReader::MXFReader() +AS_02::ISXD::MXFReader::MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory) { - m_Reader = new h__Reader(&DefaultCompositeDict()); + m_Reader = new h__Reader(&DefaultCompositeDict(), fileReaderFactory); } @@ -181,7 +181,7 @@ AS_02::ISXD::MXFReader::OpenRead(const std::string& filename) const Result_t AS_02::ISXD::MXFReader::Close() const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { m_Reader->Close(); return RESULT_OK; @@ -195,7 +195,7 @@ Result_t AS_02::ISXD::MXFReader::ReadFrame(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf, ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { return m_Reader->ReadFrame(FrameNum, FrameBuf, Ctx, HMAC); } @@ -207,7 +207,7 @@ AS_02::ISXD::MXFReader::ReadFrame(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf, Result_t AS_02::ISXD::MXFReader::ReadGenericStreamPartitionPayload(const ui32_t SID, ASDCP::FrameBuffer& frame_buf) { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { return m_Reader->ReadGenericStreamPartitionPayload(SID, frame_buf, 0, 0 /*no encryption*/); } @@ -220,7 +220,7 @@ AS_02::ISXD::MXFReader::ReadGenericStreamPartitionPayload(const ui32_t SID, ASDC Result_t AS_02::ISXD::MXFReader::FillWriterInfo(WriterInfo& Info) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { Info = m_Reader->m_Info; return RESULT_OK; @@ -233,7 +233,7 @@ AS_02::ISXD::MXFReader::FillWriterInfo(WriterInfo& Info) const void AS_02::ISXD::MXFReader::DumpHeaderMetadata(FILE* stream) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { m_Reader->m_HeaderPart.Dump(stream); } @@ -244,7 +244,7 @@ AS_02::ISXD::MXFReader::DumpHeaderMetadata(FILE* stream) const void AS_02::ISXD::MXFReader::DumpIndex(FILE* stream) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { m_Reader->m_IndexAccess.Dump(stream); } diff --git a/src/AS_02_JP2K.cpp b/src/AS_02_JP2K.cpp index 4817f21..88131b9 100644 --- a/src/AS_02_JP2K.cpp +++ b/src/AS_02_JP2K.cpp @@ -55,8 +55,8 @@ class AS_02::JP2K::MXFReader::h__Reader : public AS_02::h__AS02Reader ASDCP_NO_COPY_CONSTRUCT(h__Reader); public: - h__Reader(const Dictionary *d) : - AS_02::h__AS02Reader(d) {} + h__Reader(const Dictionary* d, const Kumu::IFileReaderFactory& fileReaderFactory) : + AS_02::h__AS02Reader(d, fileReaderFactory) {} virtual ~h__Reader() {} @@ -112,7 +112,7 @@ Result_t AS_02::JP2K::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, ASDCP::JP2K::FrameBuffer& FrameBuf, ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC) { - if ( ! m_File.IsOpen() ) + if ( ! m_File->IsOpen() ) return RESULT_INIT; assert(m_Dict); @@ -122,9 +122,9 @@ AS_02::JP2K::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, ASDCP::JP2K::Frame //------------------------------------------------------------------------------------------ // -AS_02::JP2K::MXFReader::MXFReader() +AS_02::JP2K::MXFReader::MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory) { - m_Reader = new h__Reader(&DefaultCompositeDict()); + m_Reader = new h__Reader(&DefaultCompositeDict(), fileReaderFactory); } @@ -189,7 +189,7 @@ AS_02::JP2K::MXFReader::OpenRead(const std::string& filename) const Result_t AS_02::JP2K::MXFReader::Close() const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { m_Reader->Close(); return RESULT_OK; @@ -203,7 +203,7 @@ Result_t 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() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) return m_Reader->ReadFrame(FrameNum, FrameBuf, Ctx, HMAC); return RESULT_INIT; @@ -214,7 +214,7 @@ AS_02::JP2K::MXFReader::ReadFrame(ui32_t FrameNum, ASDCP::JP2K::FrameBuffer& Fra Result_t AS_02::JP2K::MXFReader::FillWriterInfo(WriterInfo& Info) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { Info = m_Reader->m_Info; return RESULT_OK; @@ -227,7 +227,7 @@ AS_02::JP2K::MXFReader::FillWriterInfo(WriterInfo& Info) const void AS_02::JP2K::MXFReader::DumpHeaderMetadata(FILE* stream) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { m_Reader->m_HeaderPart.Dump(stream); } @@ -238,7 +238,7 @@ AS_02::JP2K::MXFReader::DumpHeaderMetadata(FILE* stream) const void AS_02::JP2K::MXFReader::DumpIndex(FILE* stream) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { m_Reader->m_IndexAccess.Dump(stream); } diff --git a/src/AS_02_JXS.cpp b/src/AS_02_JXS.cpp index 53a1e01..f8af21f 100644 --- a/src/AS_02_JXS.cpp +++ b/src/AS_02_JXS.cpp @@ -57,8 +57,8 @@ class AS_02::JXS::MXFReader::h__Reader : public AS_02::h__AS02Reader ASDCP_NO_COPY_CONSTRUCT(h__Reader); public: - h__Reader(const Dictionary *d) : - AS_02::h__AS02Reader(d) {} + h__Reader(const Dictionary* d, const Kumu::IFileReaderFactory& fileReaderFactory) : + AS_02::h__AS02Reader(d, fileReaderFactory) {} virtual ~h__Reader() {} @@ -73,7 +73,7 @@ AS_02::JXS::MXFReader::h__Reader::CalcFrameBufferSize(ui64_t &size) { IndexTableSegment::IndexEntry TmpEntry; - if ( ! m_File.IsOpen() ) + if ( ! m_File->IsOpen() ) return RESULT_INIT; if ( KM_FAILURE(m_IndexAccess.Lookup(0, TmpEntry)) ) { @@ -87,7 +87,7 @@ AS_02::JXS::MXFReader::h__Reader::CalcFrameBufferSize(ui64_t &size) if ( FilePosition != m_LastPosition ) { m_LastPosition = FilePosition; - result = m_File.Seek(FilePosition); + result = m_File->Seek(FilePosition); } if ( KM_SUCCESS(result) ) { @@ -97,7 +97,7 @@ AS_02::JXS::MXFReader::h__Reader::CalcFrameBufferSize(ui64_t &size) // // Return the file to where it was m_LastPosition = old; - m_File.Seek(old); + m_File->Seek(old); return result; } @@ -150,7 +150,7 @@ Result_t AS_02::JXS::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, ASDCP::JXS::FrameBuffer& FrameBuf, ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC) { - if ( ! m_File.IsOpen() ) + if ( ! m_File->IsOpen() ) return RESULT_INIT; assert(m_Dict); @@ -160,9 +160,9 @@ AS_02::JXS::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, ASDCP::JXS::FrameBu //------------------------------------------------------------------------------------------ // -AS_02::JXS::MXFReader::MXFReader() +AS_02::JXS::MXFReader::MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory) { - m_Reader = new h__Reader(&DefaultCompositeDict()); + m_Reader = new h__Reader(&DefaultSMPTEDict(), fileReaderFactory); } @@ -227,7 +227,7 @@ AS_02::JXS::MXFReader::OpenRead(const std::string& filename) const Result_t AS_02::JXS::MXFReader::Close() const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { m_Reader->Close(); return RESULT_OK; @@ -241,7 +241,7 @@ Result_t AS_02::JXS::MXFReader::ReadFrame(ui32_t FrameNum, ASDCP::JXS::FrameBuffer& FrameBuf, ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) return m_Reader->ReadFrame(FrameNum, FrameBuf, Ctx, HMAC); return RESULT_INIT; @@ -252,7 +252,7 @@ AS_02::JXS::MXFReader::ReadFrame(ui32_t FrameNum, ASDCP::JXS::FrameBuffer& Frame Result_t AS_02::JXS::MXFReader::CalcFrameBufferSize(ui64_t &size) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) return m_Reader->CalcFrameBufferSize(size); return RESULT_INIT; @@ -263,7 +263,7 @@ AS_02::JXS::MXFReader::CalcFrameBufferSize(ui64_t &size) const Result_t AS_02::JXS::MXFReader::FillWriterInfo(WriterInfo& Info) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { Info = m_Reader->m_Info; return RESULT_OK; @@ -276,7 +276,7 @@ AS_02::JXS::MXFReader::FillWriterInfo(WriterInfo& Info) const void AS_02::JXS::MXFReader::DumpHeaderMetadata(FILE* stream) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { m_Reader->m_HeaderPart.Dump(stream); } @@ -287,7 +287,7 @@ AS_02::JXS::MXFReader::DumpHeaderMetadata(FILE* stream) const void AS_02::JXS::MXFReader::DumpIndex(FILE* stream) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { m_Reader->m_IndexAccess.Dump(stream); } diff --git a/src/AS_02_JXS.h b/src/AS_02_JXS.h index 06b4145..864110a 100644 --- a/src/AS_02_JXS.h +++ b/src/AS_02_JXS.h @@ -100,7 +100,7 @@ namespace AS_02 ASDCP_NO_COPY_CONSTRUCT(MXFReader); public: - MXFReader(); + MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory); virtual ~MXFReader(); // Warning: direct manipulation of MXF structures can interfere diff --git a/src/AS_02_PCM.cpp b/src/AS_02_PCM.cpp index d034ffb..28d2f4b 100644 --- a/src/AS_02_PCM.cpp +++ b/src/AS_02_PCM.cpp @@ -56,7 +56,7 @@ class AS_02::PCM::MXFReader::h__Reader : public AS_02::h__AS02Reader h__Reader(); public: - h__Reader(const Dictionary *d) : AS_02::h__AS02Reader(d), m_ClipEssenceBegin(0), m_ClipSize(0), + h__Reader(const Dictionary* d, const Kumu::IFileReaderFactory& fileReaderFactory) : AS_02::h__AS02Reader(d, fileReaderFactory), m_ClipEssenceBegin(0), m_ClipSize(0), m_ClipDurationFrames(0) {} virtual ~h__Reader() {} @@ -94,13 +94,13 @@ AS_02::PCM::MXFReader::h__Reader::OpenRead(const std::string& filename, const AS result = m_IndexAccess.Lookup(0, tmp_entry); if ( KM_SUCCESS(result) ) - result = m_File.Seek(tmp_entry.StreamOffset); + result = m_File->Seek(tmp_entry.StreamOffset); if ( KM_SUCCESS(result) ) { assert(wave_descriptor); KLReader reader; - result = reader.ReadKLFromFile(m_File); + result = reader.ReadKLFromFile(*m_File); if ( KM_SUCCESS(result) ) { @@ -133,7 +133,7 @@ AS_02::PCM::MXFReader::h__Reader::OpenRead(const std::string& filename, const AS return RESULT_AS02_FORMAT; } - m_ClipEssenceBegin = m_File.Tell(); + m_ClipEssenceBegin = m_File->TellPosition(); m_ClipSize = reader.Length(); m_BytesPerFrame = AS_02::MXF::CalcFrameBufferSize(*wave_descriptor, edit_rate); m_ClipDurationFrames = m_ClipSize / m_BytesPerFrame; @@ -153,7 +153,7 @@ ASDCP::Result_t AS_02::PCM::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, ASDCP::PCM::FrameBuffer& FrameBuf, ASDCP::AESDecContext*, ASDCP::HMACContext*) { - if ( ! m_File.IsOpen() ) + if ( ! m_File->IsOpen() ) { return RESULT_INIT; } @@ -168,16 +168,16 @@ AS_02::PCM::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, ASDCP::PCM::FrameBu ui64_t position = m_ClipEssenceBegin + offset; Result_t result = RESULT_OK; - if ( m_File.Tell() != static_cast<Kumu::fpos_t>(position) ) + if ( m_File->TellPosition() != static_cast<Kumu::fpos_t>(position) ) { - result = m_File.Seek(position); + result = m_File->Seek(position); } if ( KM_SUCCESS(result) ) { ui64_t remainder = m_ClipSize - offset; ui32_t read_size = ( remainder < m_BytesPerFrame ) ? remainder : m_BytesPerFrame; - result = m_File.Read(FrameBuf.Data(), read_size); + result = m_File->Read(FrameBuf.Data(), read_size); if ( KM_SUCCESS(result) ) { @@ -198,9 +198,9 @@ AS_02::PCM::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, ASDCP::PCM::FrameBu // -AS_02::PCM::MXFReader::MXFReader() +AS_02::PCM::MXFReader::MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory) { - m_Reader = new h__Reader(&DefaultCompositeDict()); + m_Reader = new h__Reader(&DefaultCompositeDict(), fileReaderFactory); } AS_02::PCM::MXFReader::~MXFReader() @@ -264,7 +264,7 @@ AS_02::PCM::MXFReader::OpenRead(const std::string& filename, const ASDCP::Ration Result_t AS_02::PCM::MXFReader::Close() const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { m_Reader->Close(); return RESULT_OK; @@ -281,7 +281,7 @@ ASDCP::Result_t AS_02::PCM::MXFReader::ReadFrame(ui32_t FrameNum, ASDCP::PCM::FrameBuffer& FrameBuf, ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) return m_Reader->ReadFrame(FrameNum, FrameBuf, Ctx, HMAC); return RESULT_INIT; @@ -293,7 +293,7 @@ AS_02::PCM::MXFReader::ReadFrame(ui32_t FrameNum, ASDCP::PCM::FrameBuffer& Frame ASDCP::Result_t AS_02::PCM::MXFReader::FillWriterInfo(WriterInfo& Info) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { Info = m_Reader->m_Info; return RESULT_OK; @@ -306,7 +306,7 @@ AS_02::PCM::MXFReader::FillWriterInfo(WriterInfo& Info) const void AS_02::PCM::MXFReader::DumpHeaderMetadata(FILE* stream) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { m_Reader->m_HeaderPart.Dump(stream); } @@ -316,7 +316,7 @@ AS_02::PCM::MXFReader::DumpHeaderMetadata(FILE* stream) const void AS_02::PCM::MXFReader::DumpIndex(FILE* stream) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { m_Reader->m_IndexAccess.Dump(stream); } @@ -326,7 +326,7 @@ AS_02::PCM::MXFReader::DumpIndex(FILE* stream) const //------------------------------------------------------------------------------------------ // -class AS_02::PCM::MXFWriter::h__Writer : public AS_02::h__AS02WriterClip +class AS_02::PCM::MXFWriter::h__Writer : public AS_02::h__AS02WriterClip<AS_02::MXF::AS02IndexWriterCBR> { ASDCP_NO_COPY_CONSTRUCT(h__Writer); h__Writer(); @@ -335,8 +335,8 @@ public: ASDCP::MXF::WaveAudioDescriptor *m_WaveAudioDescriptor; byte_t m_EssenceUL[SMPTE_UL_LENGTH]; ui32_t m_BytesPerSample; - - h__Writer(const Dictionary *d) : AS_02::h__AS02WriterClip(d), m_WaveAudioDescriptor(0), m_BytesPerSample(0) + + h__Writer(const Dictionary *d) : AS_02::h__AS02WriterClip<AS_02::MXF::AS02IndexWriterCBR>(d), m_WaveAudioDescriptor(0), m_BytesPerSample(0) { memset(m_EssenceUL, 0, SMPTE_UL_LENGTH); } diff --git a/src/AS_02_PHDR.cpp b/src/AS_02_PHDR.cpp index d08c823..71f6b64 100644 --- a/src/AS_02_PHDR.cpp +++ b/src/AS_02_PHDR.cpp @@ -76,8 +76,8 @@ class AS_02::PHDR::MXFReader::h__Reader : public AS_02::h__AS02Reader ASDCP_NO_COPY_CONSTRUCT(h__Reader); public: - h__Reader(const Dictionary *d) : - AS_02::h__AS02Reader(d) {} + h__Reader(const Dictionary *d, const Kumu::IFileReaderFactory& fileReaderFactory) : + AS_02::h__AS02Reader(d, fileReaderFactory) {} virtual ~h__Reader() {} @@ -167,12 +167,12 @@ AS_02::PHDR::MXFReader::h__Reader::OpenRead(const std::string& filename, std::st if ( (Kumu::fpos_t)TmpPair.ByteOffset != m_LastPosition ) { m_LastPosition = TmpPair.ByteOffset; - result = m_File.Seek(TmpPair.ByteOffset); + result = m_File->Seek(TmpPair.ByteOffset); } // read the partition header ASDCP::MXF::Partition GSPart(m_Dict); - result = GSPart.InitFromFile(m_File); + result = GSPart.InitFromFile(*m_File); if ( KM_SUCCESS(result) ) { @@ -182,7 +182,7 @@ AS_02::PHDR::MXFReader::h__Reader::OpenRead(const std::string& filename, std::st ASDCP::FrameBuffer tmp_buf; tmp_buf.Capacity(Kumu::Megabyte); - result = Read_EKLV_Packet(m_File, *m_Dict, m_Info, m_LastPosition, m_CtFrameBuf, + result = Read_EKLV_Packet(*m_File, *m_Dict, m_Info, m_LastPosition, m_CtFrameBuf, 0, 0, tmp_buf, m_Dict->ul(MDD_GenericStream_DataElement), 0, 0); if ( KM_SUCCESS(result) ) @@ -202,7 +202,7 @@ Result_t AS_02::PHDR::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, AS_02::PHDR::FrameBuffer& FrameBuf, ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC) { - if ( ! m_File.IsOpen() ) + if ( ! m_File->IsOpen() ) return RESULT_INIT; assert(m_Dict); @@ -213,7 +213,7 @@ AS_02::PHDR::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, AS_02::PHDR::Frame ASDCP::FrameBuffer tmp_metadata_buffer; tmp_metadata_buffer.Capacity(8192); - result = Read_EKLV_Packet(m_File, *m_Dict, m_Info, m_LastPosition, m_CtFrameBuf, + result = Read_EKLV_Packet(*m_File, *m_Dict, m_Info, m_LastPosition, m_CtFrameBuf, FrameNum, FrameNum + 1, tmp_metadata_buffer, m_Dict->ul(MDD_PHDRImageMetadataItem), Ctx, HMAC); if ( KM_SUCCESS(result) ) @@ -233,9 +233,9 @@ AS_02::PHDR::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, AS_02::PHDR::Frame //------------------------------------------------------------------------------------------ // -AS_02::PHDR::MXFReader::MXFReader() +AS_02::PHDR::MXFReader::MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory) { - m_Reader = new h__Reader(&DefaultCompositeDict()); + m_Reader = new h__Reader(&DefaultCompositeDict(), fileReaderFactory); } @@ -300,7 +300,7 @@ AS_02::PHDR::MXFReader::OpenRead(const std::string& filename, std::string& PHDR_ Result_t AS_02::PHDR::MXFReader::Close() const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { m_Reader->Close(); return RESULT_OK; @@ -314,7 +314,7 @@ Result_t AS_02::PHDR::MXFReader::ReadFrame(ui32_t FrameNum, AS_02::PHDR::FrameBuffer& FrameBuf, ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) return m_Reader->ReadFrame(FrameNum, FrameBuf, Ctx, HMAC); return RESULT_INIT; @@ -325,7 +325,7 @@ AS_02::PHDR::MXFReader::ReadFrame(ui32_t FrameNum, AS_02::PHDR::FrameBuffer& Fra Result_t AS_02::PHDR::MXFReader::FillWriterInfo(WriterInfo& Info) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { Info = m_Reader->m_Info; return RESULT_OK; @@ -492,7 +492,7 @@ AS_02::PHDR::MXFWriter::h__Writer::WritePHDRHeader(const std::string& PackageLab if ( KM_SUCCESS(result) ) { m_PartitionSpace *= floor( EditRate.Quotient() + 0.5 ); // convert seconds to edit units - m_ECStart = m_File.Tell(); + m_ECStart = m_File.TellPosition(); m_IndexWriter.IndexSID = 129; UL body_ul(m_Dict->ul(MDD_ClosedCompleteBodyPartition)); @@ -603,7 +603,7 @@ AS_02::PHDR::MXFWriter::h__Writer::WriteFrame(const AS_02::PHDR::FrameBuffer& Fr body_part.MinorVersion = m_HeaderPart.MinorVersion; body_part.OperationalPattern = m_HeaderPart.OperationalPattern; body_part.EssenceContainers = m_HeaderPart.EssenceContainers; - body_part.ThisPartition = m_File.Tell(); + body_part.ThisPartition = m_File.TellPosition(); body_part.BodyOffset = m_StreamOffset; result = body_part.WriteToFile(m_File, body_ul); @@ -639,7 +639,7 @@ AS_02::PHDR::MXFWriter::h__Writer::Finalize(const std::string& PHDR_master_metad if ( ! PHDR_master_metadata.empty() ) { // write PHDRSimplePayload - Kumu::fpos_t here = m_File.Tell(); + Kumu::fpos_t here = m_File.TellPosition(); // create generic stream partition header static UL GenericStream_DataElement(m_Dict->ul(MDD_GenericStream_DataElement)); diff --git a/src/AS_02_PHDR.h b/src/AS_02_PHDR.h index 754247d..1635c01 100644 --- a/src/AS_02_PHDR.h +++ b/src/AS_02_PHDR.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2011-2018, John Hurst +Copyright (c) 2011-2021, John Hurst All rights reserved. @@ -145,7 +145,7 @@ namespace AS_02 ASDCP_NO_COPY_CONSTRUCT(MXFReader); public: - MXFReader(); + MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory); virtual ~MXFReader(); // Warning: direct manipulation of MXF structures can interfere diff --git a/src/AS_02_TimedText.cpp b/src/AS_02_TimedText.cpp index aa593a1..afbf441 100644 --- a/src/AS_02_TimedText.cpp +++ b/src/AS_02_TimedText.cpp @@ -32,6 +32,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "AS_02_internal.h" #include "KM_xml.h" +#include "KM_fileio.h" #include <iostream> #include <iomanip> @@ -67,9 +68,9 @@ class AS_02::TimedText::MXFReader::h__Reader : public AS_02::h__AS02Reader ASDCP_NO_COPY_CONSTRUCT(h__Reader); public: - TimedTextDescriptor m_TDesc; + TimedTextDescriptor m_TDesc; - h__Reader(const Dictionary *d) : AS_02::h__AS02Reader(d), m_EssenceDescriptor(0) { + h__Reader(const Dictionary* d, const Kumu::IFileReaderFactory& fileReaderFactory) : AS_02::h__AS02Reader(d, fileReaderFactory), m_EssenceDescriptor(0) { memset(&m_TDesc.AssetID, 0, UUIDlen); } @@ -169,7 +170,7 @@ ASDCP::Result_t AS_02::TimedText::MXFReader::h__Reader::ReadTimedTextResource(ASDCP::TimedText::FrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC) { - if ( ! m_File.IsOpen() ) + if ( ! m_File->IsOpen() ) { return RESULT_INIT; } @@ -223,9 +224,9 @@ AS_02::TimedText::MXFReader::h__Reader::ReadAncillaryResource(const Kumu::UUID& //------------------------------------------------------------------------------------------ -AS_02::TimedText::MXFReader::MXFReader() +AS_02::TimedText::MXFReader::MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory) { - m_Reader = new h__Reader(&DefaultSMPTEDict()); + m_Reader = new h__Reader(&DefaultSMPTEDict(), fileReaderFactory); } @@ -291,7 +292,7 @@ AS_02::TimedText::MXFReader::OpenRead(const std::string& filename) const ASDCP::Result_t AS_02::TimedText::MXFReader::FillTimedTextDescriptor(TimedText::TimedTextDescriptor& TDesc) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { TDesc = m_Reader->m_TDesc; return RESULT_OK; @@ -305,7 +306,7 @@ AS_02::TimedText::MXFReader::FillTimedTextDescriptor(TimedText::TimedTextDescrip ASDCP::Result_t AS_02::TimedText::MXFReader::FillWriterInfo(WriterInfo& Info) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { Info = m_Reader->m_Info; return RESULT_OK; @@ -333,7 +334,7 @@ ASDCP::Result_t AS_02::TimedText::MXFReader::ReadTimedTextResource(ASDCP::TimedText::FrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) return m_Reader->ReadTimedTextResource(FrameBuf, Ctx, HMAC); return RESULT_INIT; @@ -344,7 +345,7 @@ ASDCP::Result_t AS_02::TimedText::MXFReader::ReadAncillaryResource(const Kumu::UUID& uuid, ASDCP::TimedText::FrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) return m_Reader->ReadAncillaryResource(uuid, FrameBuf, Ctx, HMAC); return RESULT_INIT; @@ -355,7 +356,7 @@ AS_02::TimedText::MXFReader::ReadAncillaryResource(const Kumu::UUID& uuid, ASDCP void AS_02::TimedText::MXFReader::DumpHeaderMetadata(FILE* stream) const { - if ( m_Reader->m_File.IsOpen() ) + if ( m_Reader->m_File->IsOpen() ) m_Reader->m_HeaderPart.Dump(stream); } @@ -364,7 +365,7 @@ AS_02::TimedText::MXFReader::DumpHeaderMetadata(FILE* stream) const void AS_02::TimedText::MXFReader::DumpIndex(FILE* stream) const { - if ( m_Reader->m_File.IsOpen() ) + if ( m_Reader->m_File->IsOpen() ) m_Reader->m_IndexAccess.Dump(stream); } @@ -372,7 +373,7 @@ AS_02::TimedText::MXFReader::DumpIndex(FILE* stream) const ASDCP::Result_t AS_02::TimedText::MXFReader::Close() const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { m_Reader->Close(); return RESULT_OK; @@ -386,7 +387,7 @@ AS_02::TimedText::MXFReader::Close() const // -class AS_02::TimedText::MXFWriter::h__Writer : public AS_02::h__AS02WriterClip +class AS_02::TimedText::MXFWriter::h__Writer : public AS_02::h__AS02WriterClip<AS_02::MXF::AS02IndexWriterCBR> { ASDCP_NO_COPY_CONSTRUCT(h__Writer); h__Writer(); @@ -397,7 +398,7 @@ public: ui32_t m_EssenceStreamID; ASDCP::Rational m_EditRate; - h__Writer(const Dictionary *d) : AS_02::h__AS02WriterClip(d), m_EssenceStreamID(10) + h__Writer(const Dictionary *d) : AS_02::h__AS02WriterClip<AS_02::MXF::AS02IndexWriterCBR>(d), m_EssenceStreamID(10) { memset(m_EssenceUL, 0, SMPTE_UL_LENGTH); } @@ -554,7 +555,7 @@ AS_02::TimedText::MXFWriter::h__Writer::WriteTimedTextResource(const std::string if ( KM_SUCCESS(result) ) { // create an index partition header - Kumu::fpos_t here = m_File.Tell(); + Kumu::fpos_t here = m_File.TellPosition(); assert(m_Dict); ASDCP::MXF::Partition partition(m_Dict); @@ -601,7 +602,7 @@ AS_02::TimedText::MXFWriter::h__Writer::WriteAncillaryResource(const ASDCP::Time return RESULT_STATE; } - Kumu::fpos_t here = m_File.Tell(); + Kumu::fpos_t here = m_File.TellPosition(); assert(m_Dict); // create generic stream partition header diff --git a/src/AS_02_internal.h b/src/AS_02_internal.h index ba7c33d..c7fbd2f 100644 --- a/src/AS_02_internal.h +++ b/src/AS_02_internal.h @@ -41,15 +41,14 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using Kumu::DefaultLogSink; -#ifdef DEFAULT_02_MD_DECL -AS_02::MXF::AS02IndexReader *g_AS02IndexReader; -#else -extern AS_02::MXF::AS02IndexReader *g_AS02IndexReader; -#endif - - namespace AS_02 { + + #ifdef DEFAULT_02_MD_DECL + AS_02::MXF::AS02IndexReader *g_AS02IndexReader; + #else + extern AS_02::MXF::AS02IndexReader *g_AS02IndexReader; + #endif void default_md_object_init(); @@ -61,7 +60,8 @@ namespace AS_02 h__AS02Reader(); public: - h__AS02Reader(const ASDCP::Dictionary*); + h__AS02Reader(const ASDCP::Dictionary*, const Kumu::IFileReaderFactory& fileReaderFactory); + virtual ~h__AS02Reader(); Result_t OpenMXFRead(const std::string& filename); @@ -191,7 +191,7 @@ namespace AS_02 if ( KM_SUCCESS(result) ) { this->m_PartitionSpace *= (ui32_t)floor( EditRate.Quotient() + 0.5 ); // convert seconds to edit units - this->m_ECStart = this->m_File.Tell(); + this->m_ECStart = this->m_File.TellPosition(); this->m_IndexWriter.IndexSID = 129; UL body_ul(this->m_Dict->ul(MDD_ClosedCompleteBodyPartition)); @@ -209,21 +209,23 @@ namespace AS_02 return result; } - void FlushIndexPartition() + Result_t FlushIndexPartition() { - if ( this->m_IndexWriter.GetDuration() > 0 ) - { - this->m_IndexWriter.ThisPartition = this->m_File.Tell(); - this->m_IndexWriter.WriteToFile(this->m_File); + Result_t result = RESULT_OK; + if ( this->m_IndexWriter.GetDuration() > 0 ) + { + this->m_IndexWriter.ThisPartition = this->m_File.TellPosition(); + result = this->m_IndexWriter.WriteToFile(this->m_File); this->m_RIP.PairArray.push_back(RIP::PartitionPair(0, this->m_IndexWriter.ThisPartition)); - } + } + return result; } // standard method of writing the header and footer of a completed AS-02 file // Result_t WriteAS02Footer() { - this->FlushIndexPartition(); + Result_t result = this->FlushIndexPartition(); // update all Duration properties ASDCP::MXF::Partition footer_part(this->m_Dict); @@ -237,7 +239,7 @@ namespace AS_02 this->m_EssenceDescriptor->ContainerDuration = this->m_FramesWritten; footer_part.PreviousPartition = this->m_RIP.PairArray.back().ByteOffset; - Kumu::fpos_t here = this->m_File.Tell(); + Kumu::fpos_t here = this->m_File.TellPosition(); this->m_RIP.PairArray.push_back(RIP::PartitionPair(0, here)); // Last RIP Entry this->m_HeaderPart.FooterPartition = here; @@ -249,8 +251,11 @@ namespace AS_02 footer_part.FooterPartition = here; footer_part.ThisPartition = here; - UL footer_ul(this->m_Dict->ul(MDD_CompleteFooter)); - Result_t result = footer_part.WriteToFile(this->m_File, footer_ul); + if (KM_SUCCESS(result)) + { + UL footer_ul(this->m_Dict->ul(MDD_CompleteFooter)); + result = footer_part.WriteToFile(this->m_File, footer_ul); + } if ( KM_SUCCESS(result) ) result = this->m_RIP.WriteToFile(this->m_File); @@ -314,23 +319,112 @@ namespace AS_02 }; // - class h__AS02WriterClip : public h__AS02Writer<AS_02::MXF::AS02IndexWriterCBR> + template <typename IndexWriterType> + class h__AS02WriterClip : public h__AS02Writer<IndexWriterType> { ASDCP_NO_COPY_CONSTRUCT(h__AS02WriterClip); - h__AS02WriterClip(); + h__AS02WriterClip() {} public: - ui64_t m_ECStart; // offset of the first essence element - ui64_t m_ClipStart; // state variable for clip-wrap-in-progress - IndexStrategy_t m_IndexStrategy; // per SMPTE ST 2067-5 - - h__AS02WriterClip(const Dictionary*); - virtual ~h__AS02WriterClip(); - - bool HasOpenClip() const; - Result_t StartClip(const byte_t* EssenceUL, AESEncContext* Ctx, HMACContext* HMAC); - Result_t WriteClipBlock(const ASDCP::FrameBuffer& FrameBuf); - Result_t FinalizeClip(ui32_t bytes_per_frame); + ui64_t m_ECStart; // offset of the first essence element + ui64_t m_ClipStart; // state variable for clip-wrap-in-progress + IndexStrategy_t m_IndexStrategy; // per SMPTE ST 2067-5 + + h__AS02WriterClip(const Dictionary* d) : + h__AS02Writer<IndexWriterType>(d), + m_ECStart(0), m_ClipStart(0), m_IndexStrategy(AS_02::IS_FOLLOW) + {} + virtual ~h__AS02WriterClip() + {} + + bool HasOpenClip() const { return m_ClipStart != 0; } + Result_t StartClip(const byte_t* EssenceUL, AESEncContext* Ctx, HMACContext* HMAC) + { + if (Ctx != 0) + { + DefaultLogSink().Error("Encryption not yet supported for PCM clip-wrap.\n"); + return RESULT_STATE; + } + + if (m_ClipStart != 0) + { + DefaultLogSink().Error("Cannot open clip, clip already open.\n"); + return RESULT_STATE; + } + + m_ClipStart = h__AS02Writer<IndexWriterType>::m_File.TellPosition(); + byte_t clip_buffer[24] = { 0 }; + memcpy(clip_buffer, EssenceUL, 16); + bool check = Kumu::write_BER(clip_buffer + 16, 0, 8); + assert(check); + return h__AS02Writer<IndexWriterType>::m_File.Write(clip_buffer, 24); + } + Result_t WriteClipBlock(const ASDCP::FrameBuffer& FrameBuf) + { + if (m_ClipStart == 0) + { + DefaultLogSink().Error("Cannot write clip block, no clip open.\n"); + return RESULT_STATE; + } + + return h__AS02Writer<IndexWriterType>::m_File.Write(FrameBuf.RoData(), FrameBuf.Size()); + } + Result_t FinalizeClip(ui32_t bytes_per_frame) + { + if (m_ClipStart == 0) + { + DefaultLogSink().Error("Cannot close clip, clip not open.\n"); + return RESULT_STATE; + } + + ui64_t current_position = h__AS02Writer<IndexWriterType>::m_File.TellPosition(); + Result_t result = h__AS02Writer<IndexWriterType>::m_File.Seek(m_ClipStart + 16); + + if (KM_SUCCESS(result)) + { + byte_t clip_buffer[8] = { 0 }; + ui64_t size = static_cast<ui64_t>(h__AS02Writer<IndexWriterType>::m_FramesWritten) * bytes_per_frame; + bool check = Kumu::write_BER(clip_buffer, size, 8); + assert(check); + result = h__AS02Writer<IndexWriterType>::m_File.Write(clip_buffer, 8); + } + + if (KM_SUCCESS(result)) + { + result = h__AS02Writer<IndexWriterType>::m_File.Seek(current_position); + m_ClipStart = 0; + } + + return result; + } + Result_t FinalizeClip(ui64_t total_bytes_written) + { + if (m_ClipStart == 0) + { + DefaultLogSink().Error("Cannot close clip, clip not open.\n"); + return RESULT_STATE; + } + + ui64_t current_position = h__AS02Writer<IndexWriterType>::m_File.TellPosition(); + Result_t result = h__AS02Writer<IndexWriterType>::m_File.Seek(m_ClipStart + 16); + + if (KM_SUCCESS(result)) + { + byte_t clip_buffer[8] = { 0 }; + bool check = Kumu::write_BER(clip_buffer, total_bytes_written, 8); + assert(check); + result = h__AS02Writer<IndexWriterType>::m_File.Write(clip_buffer, 8); + } + + if (KM_SUCCESS(result)) + { + result = h__AS02Writer<IndexWriterType>::m_File.Seek(current_position); + m_ClipStart = 0; + } + + return result; + + } }; } // namespace AS_02 diff --git a/src/AS_DCP.h b/src/AS_DCP.h index ef38f7d..aab7f77 100755 --- a/src/AS_DCP.h +++ b/src/AS_DCP.h @@ -234,7 +234,7 @@ namespace ASDCP { // Determine the type of essence contained in the given MXF file. RESULT_OK // is returned if the file is successfully opened and contains a valid MXF // stream. If there is an error, the result code will indicate the reason. - Result_t EssenceType(const std::string& filename, EssenceType_t& type); + Result_t EssenceType(const std::string& filename, EssenceType_t& type, const Kumu::IFileReaderFactory& fileReaderFactory); // Determine the type of essence contained in the given raw file. RESULT_OK // is returned if the file is successfully opened and contains a known @@ -795,7 +795,7 @@ namespace ASDCP { ASDCP_NO_COPY_CONSTRUCT(MXFReader); public: - MXFReader(); + MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory); virtual ~MXFReader(); // Warning: direct manipulation of MXF structures can interfere @@ -1006,7 +1006,7 @@ namespace ASDCP { ASDCP_NO_COPY_CONSTRUCT(MXFReader); public: - MXFReader(); + MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory); virtual ~MXFReader(); // Warning: direct manipulation of MXF structures can interfere @@ -1284,7 +1284,7 @@ namespace ASDCP { ASDCP_NO_COPY_CONSTRUCT(MXFReader); public: - MXFReader(); + MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory); virtual ~MXFReader(); // Warning: direct manipulation of MXF structures can interfere @@ -1399,7 +1399,7 @@ namespace ASDCP { ASDCP_NO_COPY_CONSTRUCT(MXFSReader); public: - MXFSReader(); + MXFSReader(const Kumu::IFileReaderFactory& fileReaderFactory); virtual ~MXFSReader(); // Warning: direct manipulation of MXF structures can interfere @@ -1624,7 +1624,7 @@ namespace ASDCP { ASDCP_NO_COPY_CONSTRUCT(MXFReader); public: - MXFReader(); + MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory); virtual ~MXFReader(); // Warning: direct manipulation of MXF structures can interfere @@ -1810,7 +1810,7 @@ namespace ASDCP { ASDCP_NO_COPY_CONSTRUCT(MXFReader); public: - MXFReader(); + MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory); virtual ~MXFReader(); // Warning: direct manipulation of MXF structures can interfere @@ -1918,7 +1918,7 @@ namespace ASDCP { ASDCP_NO_COPY_CONSTRUCT(MXFReader); public: - MXFReader(); + MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory); virtual ~MXFReader(); // Warning: direct manipulation of MXF structures can interfere diff --git a/src/AS_DCP_ATMOS.cpp b/src/AS_DCP_ATMOS.cpp index d476e20..396f359 100644 --- a/src/AS_DCP_ATMOS.cpp +++ b/src/AS_DCP_ATMOS.cpp @@ -117,8 +117,9 @@ class ASDCP::ATMOS::MXFReader::h__Reader : public ASDCP::h__ASDCPReader ASDCP::DCData::DCDataDescriptor m_DDesc; AtmosDescriptor m_ADesc; - h__Reader(const Dictionary *d) : - ASDCP::h__ASDCPReader(d), m_EssenceDescriptor(0), m_EssenceSubDescriptor(0) {} + h__Reader(const Dictionary* d, const Kumu::IFileReaderFactory& fileReaderFactory) : + ASDCP::h__ASDCPReader(d, fileReaderFactory), m_EssenceDescriptor(0), m_EssenceSubDescriptor(0) {} + virtual ~h__Reader() {} Result_t OpenRead(const std::string&); Result_t ReadFrame(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*); @@ -239,7 +240,7 @@ ASDCP::Result_t ASDCP::ATMOS::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, FrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC) { - if ( ! m_File.IsOpen() ) + if ( ! m_File->IsOpen() ) return RESULT_INIT; assert(m_Dict); @@ -249,15 +250,15 @@ ASDCP::ATMOS::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, FrameBuffer& Fram //------------------------------------------------------------------------------------------ -ASDCP::ATMOS::MXFReader::MXFReader() +ASDCP::ATMOS::MXFReader::MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory) { - m_Reader = new h__Reader(&AtmosSMPTEDict()); + m_Reader = new h__Reader(&AtmosSMPTEDict(), fileReaderFactory); } ASDCP::ATMOS::MXFReader::~MXFReader() { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) m_Reader->Close(); } @@ -319,7 +320,7 @@ ASDCP::Result_t ASDCP::ATMOS::MXFReader::ReadFrame(ui32_t FrameNum, DCData::FrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) return m_Reader->ReadFrame(FrameNum, FrameBuf, Ctx, HMAC); return RESULT_INIT; @@ -337,7 +338,7 @@ ASDCP::ATMOS::MXFReader::LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset ASDCP::Result_t ASDCP::ATMOS::MXFReader::FillAtmosDescriptor(AtmosDescriptor& ADesc) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { ADesc = m_Reader->m_ADesc; return RESULT_OK; @@ -352,7 +353,7 @@ ASDCP::ATMOS::MXFReader::FillAtmosDescriptor(AtmosDescriptor& ADesc) const ASDCP::Result_t ASDCP::ATMOS::MXFReader::FillWriterInfo(WriterInfo& Info) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { Info = m_Reader->m_Info; return RESULT_OK; @@ -365,7 +366,7 @@ ASDCP::ATMOS::MXFReader::FillWriterInfo(WriterInfo& Info) const void ASDCP::ATMOS::MXFReader::DumpHeaderMetadata(FILE* stream) const { - if ( m_Reader->m_File.IsOpen() ) + if ( m_Reader->m_File->IsOpen() ) m_Reader->m_HeaderPart.Dump(stream); } @@ -373,7 +374,7 @@ ASDCP::ATMOS::MXFReader::DumpHeaderMetadata(FILE* stream) const void ASDCP::ATMOS::MXFReader::DumpIndex(FILE* stream) const { - if ( m_Reader->m_File.IsOpen() ) + if ( m_Reader->m_File->IsOpen() ) m_Reader->m_IndexAccess.Dump(stream); } @@ -381,7 +382,7 @@ ASDCP::ATMOS::MXFReader::DumpIndex(FILE* stream) const ASDCP::Result_t ASDCP::ATMOS::MXFReader::Close() const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { m_Reader->Close(); return RESULT_OK; diff --git a/src/AS_DCP_DCData.cpp b/src/AS_DCP_DCData.cpp index fee3ff8..f73ca9f 100644 --- a/src/AS_DCP_DCData.cpp +++ b/src/AS_DCP_DCData.cpp @@ -85,7 +85,7 @@ class ASDCP::DCData::MXFReader::h__Reader : public ASDCP::h__ASDCPReader public: DCDataDescriptor m_DDesc; - h__Reader(const Dictionary *d) : ASDCP::h__ASDCPReader(d), m_PrivateLabelCompatibilityMode(false), m_DDesc() {} + h__Reader(const Dictionary* d, const Kumu::IFileReaderFactory& fileReaderFactory) : ASDCP::h__ASDCPReader(d, fileReaderFactory), m_PrivateLabelCompatibilityMode(false), m_DDesc() {} ~h__Reader() {} Result_t OpenRead(const std::string&); Result_t ReadFrame(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*); @@ -191,7 +191,7 @@ ASDCP::Result_t ASDCP::DCData::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, FrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC) { - if ( ! m_File.IsOpen() ) + if ( ! m_File->IsOpen() ) return RESULT_INIT; assert(m_Dict); @@ -224,15 +224,15 @@ ASDCP::DCData::FrameBuffer::Dump(FILE* stream, ui32_t dump_len) const //------------------------------------------------------------------------------------------ -ASDCP::DCData::MXFReader::MXFReader() +ASDCP::DCData::MXFReader::MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory) { - m_Reader = new h__Reader(&DefaultSMPTEDict()); + m_Reader = new h__Reader(&DefaultSMPTEDict(), fileReaderFactory); } ASDCP::DCData::MXFReader::~MXFReader() { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) m_Reader->Close(); } @@ -294,7 +294,7 @@ ASDCP::Result_t ASDCP::DCData::MXFReader::ReadFrame(ui32_t FrameNum, FrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) return m_Reader->ReadFrame(FrameNum, FrameBuf, Ctx, HMAC); return RESULT_INIT; @@ -312,7 +312,7 @@ ASDCP::DCData::MXFReader::LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffse ASDCP::Result_t ASDCP::DCData::MXFReader::FillDCDataDescriptor(DCDataDescriptor& DDesc) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { DDesc = m_Reader->m_DDesc; return RESULT_OK; @@ -327,7 +327,7 @@ ASDCP::DCData::MXFReader::FillDCDataDescriptor(DCDataDescriptor& DDesc) const ASDCP::Result_t ASDCP::DCData::MXFReader::FillWriterInfo(WriterInfo& Info) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { Info = m_Reader->m_Info; return RESULT_OK; @@ -340,7 +340,7 @@ ASDCP::DCData::MXFReader::FillWriterInfo(WriterInfo& Info) const void ASDCP::DCData::MXFReader::DumpHeaderMetadata(FILE* stream) const { - if ( m_Reader->m_File.IsOpen() ) + if ( m_Reader->m_File->IsOpen() ) m_Reader->m_HeaderPart.Dump(stream); } @@ -349,7 +349,7 @@ ASDCP::DCData::MXFReader::DumpHeaderMetadata(FILE* stream) const void ASDCP::DCData::MXFReader::DumpIndex(FILE* stream) const { - if ( m_Reader->m_File.IsOpen() ) + if ( m_Reader->m_File->IsOpen() ) m_Reader->m_IndexAccess.Dump(stream); } @@ -357,7 +357,7 @@ ASDCP::DCData::MXFReader::DumpIndex(FILE* stream) const ASDCP::Result_t ASDCP::DCData::MXFReader::Close() const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { m_Reader->Close(); return RESULT_OK; diff --git a/src/AS_DCP_DCData_internal.h b/src/AS_DCP_DCData_internal.h index b3f95f6..167e566 100644 --- a/src/AS_DCP_DCData_internal.h +++ b/src/AS_DCP_DCData_internal.h @@ -57,8 +57,8 @@ namespace DCData public: DCDataDescriptor m_DDesc; - h__Reader(const Dictionary *d) : ASDCP::h__ASDCPReader(d), m_EssenceDescriptor(0), - m_DDesc() {} + h__Reader(const Dictionary *d, Kumu::IFileReaderFactory& f) : + ASDCP::h__ASDCPReader(d, f), m_EssenceDescriptor(0), m_DDesc() {} ~h__Reader() {} Result_t OpenRead(const std::string&); Result_t ReadFrame(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*); diff --git a/src/AS_DCP_JP2K.cpp b/src/AS_DCP_JP2K.cpp index 39aaa2a..06f86cd 100755 --- a/src/AS_DCP_JP2K.cpp +++ b/src/AS_DCP_JP2K.cpp @@ -513,7 +513,10 @@ ASDCP::MD_to_JP2K_PDesc(const ASDCP::MXF::GenericPictureEssenceDescriptor& Esse // // hidden, internal implementation of JPEG 2000 reader +namespace ASDCP { +namespace JP2K +{ class lh__Reader : public ASDCP::h__ASDCPReader { RGBAEssenceDescriptor* m_EssenceDescriptor; @@ -527,14 +530,16 @@ class lh__Reader : public ASDCP::h__ASDCPReader 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) {} + lh__Reader(const Dictionary *d, const Kumu::IFileReaderFactory& fileReaderFactory) : + ASDCP::h__ASDCPReader(d, fileReaderFactory), m_EssenceDescriptor(0), m_EssenceSubDescriptor(0), m_Format(ESS_UNKNOWN) {} virtual ~lh__Reader() {} Result_t OpenRead(const std::string&, EssenceType_t); Result_t ReadFrame(ui32_t, JP2K::FrameBuffer&, AESDecContext*, HMACContext*); }; +} // namespace JP2K +} // namespace asdcp // @@ -701,7 +706,7 @@ ASDCP::Result_t lh__Reader::ReadFrame(ui32_t FrameNum, JP2K::FrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC) { - if ( ! m_File.IsOpen() ) + if ( ! m_File->IsOpen() ) return RESULT_INIT; assert(m_Dict); @@ -716,7 +721,7 @@ class ASDCP::JP2K::MXFReader::h__Reader : public lh__Reader h__Reader(); public: - h__Reader(const Dictionary *d) : lh__Reader(d) {} + h__Reader(const Dictionary *d, const Kumu::IFileReaderFactory& fileReaderFactory) : lh__Reader(d, fileReaderFactory) {} }; @@ -742,15 +747,15 @@ ASDCP::JP2K::FrameBuffer::Dump(FILE* stream, ui32_t dump_len) const //------------------------------------------------------------------------------------------ -ASDCP::JP2K::MXFReader::MXFReader() +ASDCP::JP2K::MXFReader::MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory) { - m_Reader = new h__Reader(&DefaultCompositeDict()); + m_Reader = new h__Reader(&DefaultCompositeDict(), fileReaderFactory); } ASDCP::JP2K::MXFReader::~MXFReader() { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) m_Reader->Close(); } @@ -812,7 +817,7 @@ ASDCP::Result_t ASDCP::JP2K::MXFReader::ReadFrame(ui32_t FrameNum, FrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) return m_Reader->ReadFrame(FrameNum, FrameBuf, Ctx, HMAC); return RESULT_INIT; @@ -830,7 +835,7 @@ ASDCP::JP2K::MXFReader::LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, ASDCP::Result_t ASDCP::JP2K::MXFReader::FillPictureDescriptor(PictureDescriptor& PDesc) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { PDesc = m_Reader->m_PDesc; return RESULT_OK; @@ -845,7 +850,7 @@ ASDCP::JP2K::MXFReader::FillPictureDescriptor(PictureDescriptor& PDesc) const ASDCP::Result_t ASDCP::JP2K::MXFReader::FillWriterInfo(WriterInfo& Info) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { Info = m_Reader->m_Info; return RESULT_OK; @@ -858,7 +863,7 @@ ASDCP::JP2K::MXFReader::FillWriterInfo(WriterInfo& Info) const void ASDCP::JP2K::MXFReader::DumpHeaderMetadata(FILE* stream) const { - if ( m_Reader->m_File.IsOpen() ) + if ( m_Reader->m_File->IsOpen() ) m_Reader->m_HeaderPart.Dump(stream); } @@ -867,7 +872,7 @@ ASDCP::JP2K::MXFReader::DumpHeaderMetadata(FILE* stream) const void ASDCP::JP2K::MXFReader::DumpIndex(FILE* stream) const { - if ( m_Reader->m_File.IsOpen() ) + if ( m_Reader->m_File->IsOpen() ) m_Reader->m_IndexAccess.Dump(stream); } @@ -875,7 +880,7 @@ ASDCP::JP2K::MXFReader::DumpIndex(FILE* stream) const ASDCP::Result_t ASDCP::JP2K::MXFReader::Close() const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { m_Reader->Close(); return RESULT_OK; @@ -893,7 +898,7 @@ class ASDCP::JP2K::MXFSReader::h__SReader : public lh__Reader ui32_t m_StereoFrameReady; public: - h__SReader(const Dictionary *d) : lh__Reader(d), m_StereoFrameReady(0xffffffff) {} + h__SReader(const Dictionary *d, const Kumu::IFileReaderFactory& fileReaderFactory) : lh__Reader(d, fileReaderFactory), m_StereoFrameReady(0xffffffff) {} // Result_t ReadFrame(ui32_t FrameNum, StereoscopicPhase_t phase, FrameBuffer& FrameBuf, @@ -916,7 +921,7 @@ public: if ( FilePosition != m_LastPosition ) { m_LastPosition = FilePosition; - result = m_File.Seek(FilePosition); + result = m_File->Seek(FilePosition); } // the call to ReadEKLVPacket() will leave the file on an R frame @@ -931,17 +936,17 @@ public: if ( FilePosition != m_LastPosition ) { m_LastPosition = FilePosition; - result = m_File.Seek(FilePosition); + result = m_File->Seek(FilePosition); } KLReader Reader; - result = Reader.ReadKLFromFile(m_File); + result = Reader.ReadKLFromFile(*m_File); if ( ASDCP_SUCCESS(result) ) { // skip over the companion SP_LEFT frame Kumu::fpos_t new_pos = FilePosition + SMPTE_UL_LENGTH + Reader.KLLength() + Reader.Length(); - result = m_File.Seek(new_pos); + result = m_File->Seek(new_pos); } } @@ -968,15 +973,15 @@ public: -ASDCP::JP2K::MXFSReader::MXFSReader() +ASDCP::JP2K::MXFSReader::MXFSReader(const Kumu::IFileReaderFactory& fileReaderFactory) { - m_Reader = new h__SReader(&DefaultCompositeDict()); + m_Reader = new h__SReader(&DefaultCompositeDict(), fileReaderFactory); } ASDCP::JP2K::MXFSReader::~MXFSReader() { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) m_Reader->Close(); } @@ -1039,7 +1044,7 @@ ASDCP::JP2K::MXFSReader::ReadFrame(ui32_t FrameNum, SFrameBuffer& FrameBuf, AESD { Result_t result = RESULT_INIT; - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { result = m_Reader->ReadFrame(FrameNum, SP_LEFT, FrameBuf.Left, Ctx, HMAC); @@ -1055,7 +1060,7 @@ ASDCP::Result_t ASDCP::JP2K::MXFSReader::ReadFrame(ui32_t FrameNum, StereoscopicPhase_t phase, FrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) return m_Reader->ReadFrame(FrameNum, phase, FrameBuf, Ctx, HMAC); return RESULT_INIT; @@ -1072,7 +1077,7 @@ ASDCP::JP2K::MXFSReader::LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset ASDCP::Result_t ASDCP::JP2K::MXFSReader::FillPictureDescriptor(PictureDescriptor& PDesc) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { PDesc = m_Reader->m_PDesc; return RESULT_OK; @@ -1087,7 +1092,7 @@ ASDCP::JP2K::MXFSReader::FillPictureDescriptor(PictureDescriptor& PDesc) const ASDCP::Result_t ASDCP::JP2K::MXFSReader::FillWriterInfo(WriterInfo& Info) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { Info = m_Reader->m_Info; return RESULT_OK; @@ -1100,7 +1105,7 @@ ASDCP::JP2K::MXFSReader::FillWriterInfo(WriterInfo& Info) const void ASDCP::JP2K::MXFSReader::DumpHeaderMetadata(FILE* stream) const { - if ( m_Reader->m_File.IsOpen() ) + if ( m_Reader->m_File->IsOpen() ) m_Reader->m_HeaderPart.Dump(stream); } @@ -1109,7 +1114,7 @@ ASDCP::JP2K::MXFSReader::DumpHeaderMetadata(FILE* stream) const void ASDCP::JP2K::MXFSReader::DumpIndex(FILE* stream) const { - if ( m_Reader->m_File.IsOpen() ) + if ( m_Reader->m_File->IsOpen() ) m_Reader->m_IndexAccess.Dump(stream); } @@ -1117,7 +1122,7 @@ ASDCP::JP2K::MXFSReader::DumpIndex(FILE* stream) const ASDCP::Result_t ASDCP::JP2K::MXFSReader::Close() const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { m_Reader->Close(); return RESULT_OK; @@ -1131,6 +1136,10 @@ ASDCP::JP2K::MXFSReader::Close() const // +namespace ASDCP { + +namespace JP2K +{ class lh__Writer : public ASDCP::h__ASDCPWriter { ASDCP_NO_COPY_CONSTRUCT(lh__Writer); @@ -1154,6 +1163,8 @@ public: Result_t WriteFrame(const JP2K::FrameBuffer&, bool add_index, AESEncContext*, HMACContext*); Result_t Finalize(); }; +} // namespace JP2K +} // namespace asdcp // Open the file for writing. The file must not exist. Returns error if // the operation cannot be completed. diff --git a/src/AS_DCP_JXS.cpp b/src/AS_DCP_JXS.cpp index 5fec863..c873dfb 100644 --- a/src/AS_DCP_JXS.cpp +++ b/src/AS_DCP_JXS.cpp @@ -62,8 +62,8 @@ class ih__Reader : public ASDCP::h__ASDCPReader public: - ih__Reader(const Dictionary *d) : - ASDCP::h__ASDCPReader(d), m_EssenceDescriptor(0), m_EssenceSubDescriptor(0), m_Format(ESS_UNKNOWN) {} + ih__Reader(const Dictionary *d, const Kumu::IFileReaderFactory& fileReaderFactory) : + ASDCP::h__ASDCPReader(d, fileReaderFactory), m_EssenceDescriptor(0), m_EssenceSubDescriptor(0), m_Format(ESS_UNKNOWN) {} virtual ~ih__Reader() {} @@ -243,7 +243,7 @@ ASDCP::Result_t ih__Reader::ReadFrame(ui32_t FrameNum, JXS::FrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC) { - if ( ! m_File.IsOpen() ) + if ( ! m_File->IsOpen() ) return RESULT_INIT; assert(m_Dict); @@ -253,7 +253,7 @@ ih__Reader::ReadFrame(ui32_t FrameNum, JXS::FrameBuffer& FrameBuf, // Result_t ih__Reader::CalcFrameBufferSize(ui64_t &size) { - if ( ! m_File.IsOpen() ) + if ( ! m_File->IsOpen() ) return RESULT_INIT; assert(m_Dict); @@ -267,21 +267,21 @@ class ASDCP::JXS::MXFReader::h__Reader : public ih__Reader h__Reader(); public: - h__Reader(const Dictionary *d) : ih__Reader(d) {} + h__Reader(const Dictionary *d, const Kumu::IFileReaderFactory& fileReaderFactory) : ih__Reader(d, fileReaderFactory) {} }; //------------------------------------------------------------------------------------------ -ASDCP::JXS::MXFReader::MXFReader() +ASDCP::JXS::MXFReader::MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory) { - m_Reader = new h__Reader(&DefaultCompositeDict()); + m_Reader = new h__Reader(&DefaultCompositeDict(), fileReaderFactory); } ASDCP::JXS::MXFReader::~MXFReader() { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) m_Reader->Close(); } @@ -343,7 +343,7 @@ ASDCP::Result_t ASDCP::JXS::MXFReader::ReadFrame(ui32_t FrameNum, FrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) return m_Reader->ReadFrame(FrameNum, FrameBuf, Ctx, HMAC); return RESULT_INIT; @@ -353,7 +353,7 @@ ASDCP::JXS::MXFReader::ReadFrame(ui32_t FrameNum, FrameBuffer& FrameBuf, ASDCP::Result_t ASDCP::JXS::MXFReader::CalcFrameBufferSize(ui64_t &size) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) return m_Reader->CalcFrameBufferSize(size); return RESULT_INIT; @@ -371,7 +371,7 @@ ASDCP::JXS::MXFReader::LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, ASDCP::Result_t ASDCP::JXS::MXFReader::FillWriterInfo(WriterInfo& Info) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { Info = m_Reader->m_Info; return RESULT_OK; @@ -384,7 +384,7 @@ ASDCP::JXS::MXFReader::FillWriterInfo(WriterInfo& Info) const void ASDCP::JXS::MXFReader::DumpHeaderMetadata(FILE* stream) const { - if ( m_Reader->m_File.IsOpen() ) + if ( m_Reader->m_File->IsOpen() ) m_Reader->m_HeaderPart.Dump(stream); } @@ -393,7 +393,7 @@ ASDCP::JXS::MXFReader::DumpHeaderMetadata(FILE* stream) const void ASDCP::JXS::MXFReader::DumpIndex(FILE* stream) const { - if ( m_Reader->m_File.IsOpen() ) + if ( m_Reader->m_File->IsOpen() ) m_Reader->m_IndexAccess.Dump(stream); } @@ -401,7 +401,7 @@ ASDCP::JXS::MXFReader::DumpIndex(FILE* stream) const ASDCP::Result_t ASDCP::JXS::MXFReader::Close() const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { m_Reader->Close(); return RESULT_OK; diff --git a/src/AS_DCP_JXS.h b/src/AS_DCP_JXS.h index fd334df..c60bebe 100644 --- a/src/AS_DCP_JXS.h +++ b/src/AS_DCP_JXS.h @@ -137,7 +137,7 @@ namespace ASDCP { ASDCP_NO_COPY_CONSTRUCT(MXFReader); public: - MXFReader(); + MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory); virtual ~MXFReader(); // Warning: direct manipulation of MXF structures can interfere diff --git a/src/AS_DCP_MPEG2.cpp b/src/AS_DCP_MPEG2.cpp index 0608abd..807e58b 100755 --- a/src/AS_DCP_MPEG2.cpp +++ b/src/AS_DCP_MPEG2.cpp @@ -39,6 +39,10 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. static std::string MPEG_PACKAGE_LABEL = "File Package: SMPTE 381M frame wrapping of MPEG2 video elementary stream"; static std::string PICT_DEF_LABEL = "Picture Track"; +namespace ASDCP { + +namespace MPEG2 +{ // ASDCP::Result_t MD_to_MPEG2_VDesc(MXF::MPEG2VideoDescriptor* VDescObj, MPEG2::VideoDescriptor& VDesc) @@ -111,6 +115,8 @@ MPEG2_VDesc_to_MD(MPEG2::VideoDescriptor& VDesc, MXF::MPEG2VideoDescriptor* VDes VDescObj->ProfileAndLevel = VDesc.ProfileAndLevel; return RESULT_OK; } +} // namespace MPEG2 +} // namespace asdcp // std::ostream& @@ -185,7 +191,7 @@ class ASDCP::MPEG2::MXFReader::h__Reader : public ASDCP::h__ASDCPReader public: VideoDescriptor m_VDesc; // video parameter list - h__Reader(const Dictionary *d) : ASDCP::h__ASDCPReader(d) {} + h__Reader(const Dictionary *d, const Kumu::IFileReaderFactory& fileReaderFactory) : ASDCP::h__ASDCPReader(d, fileReaderFactory) {} virtual ~h__Reader() {} Result_t OpenRead(const std::string&); Result_t ReadFrame(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*); @@ -246,7 +252,7 @@ ASDCP::MPEG2::MXFReader::h__Reader::FindFrameGOPStart(ui32_t FrameNum, ui32_t& K { KeyFrameNum = 0; - if ( ! m_File.IsOpen() ) + if ( ! m_File->IsOpen() ) return RESULT_INIT; // look up frame index node @@ -266,7 +272,7 @@ ASDCP::MPEG2::MXFReader::h__Reader::FindFrameGOPStart(ui32_t FrameNum, ui32_t& K ASDCP::Result_t ASDCP::MPEG2::MXFReader::h__Reader::FrameType(ui32_t FrameNum, FrameType_t& type) { - if ( ! m_File.IsOpen() ) + if ( ! m_File->IsOpen() ) return RESULT_INIT; // look up frame index node @@ -289,7 +295,7 @@ ASDCP::MPEG2::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, FrameBuffer& Fram AESDecContext* Ctx, HMACContext* HMAC) { assert(m_Dict); - if ( ! m_File.IsOpen() ) + if ( ! m_File->IsOpen() ) return RESULT_INIT; Result_t result = ReadEKLVFrame(FrameNum, FrameBuf, m_Dict->ul(MDD_MPEG2Essence), Ctx, HMAC); @@ -340,15 +346,15 @@ ASDCP::MPEG2::FrameBuffer::Dump(FILE* stream, ui32_t dump_len) const //------------------------------------------------------------------------------------------ -ASDCP::MPEG2::MXFReader::MXFReader() +ASDCP::MPEG2::MXFReader::MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory) { - m_Reader = new h__Reader(&DefaultCompositeDict()); + m_Reader = new h__Reader(&DefaultCompositeDict(), fileReaderFactory); } ASDCP::MPEG2::MXFReader::~MXFReader() { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) m_Reader->Close(); } @@ -410,7 +416,7 @@ ASDCP::Result_t ASDCP::MPEG2::MXFReader::ReadFrame(ui32_t FrameNum, FrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) return m_Reader->ReadFrame(FrameNum, FrameBuf, Ctx, HMAC); return RESULT_INIT; @@ -429,7 +435,7 @@ ASDCP::Result_t ASDCP::MPEG2::MXFReader::ReadFrameGOPStart(ui32_t FrameNum, FrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) return m_Reader->ReadFrameGOPStart(FrameNum, FrameBuf, Ctx, HMAC); return RESULT_INIT; @@ -440,7 +446,7 @@ ASDCP::MPEG2::MXFReader::ReadFrameGOPStart(ui32_t FrameNum, FrameBuffer& FrameBu ASDCP::Result_t ASDCP::MPEG2::MXFReader::FindFrameGOPStart(ui32_t FrameNum, ui32_t& KeyFrameNum) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) return m_Reader->FindFrameGOPStart(FrameNum, KeyFrameNum); return RESULT_INIT; @@ -452,7 +458,7 @@ ASDCP::MPEG2::MXFReader::FindFrameGOPStart(ui32_t FrameNum, ui32_t& KeyFrameNum) ASDCP::Result_t ASDCP::MPEG2::MXFReader::FillVideoDescriptor(VideoDescriptor& VDesc) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { VDesc = m_Reader->m_VDesc; return RESULT_OK; @@ -467,7 +473,7 @@ ASDCP::MPEG2::MXFReader::FillVideoDescriptor(VideoDescriptor& VDesc) const ASDCP::Result_t ASDCP::MPEG2::MXFReader::FillWriterInfo(WriterInfo& Info) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { Info = m_Reader->m_Info; return RESULT_OK; @@ -480,7 +486,7 @@ ASDCP::MPEG2::MXFReader::FillWriterInfo(WriterInfo& Info) const void ASDCP::MPEG2::MXFReader::DumpHeaderMetadata(FILE* stream) const { - if ( m_Reader->m_File.IsOpen() ) + if ( m_Reader->m_File->IsOpen() ) m_Reader->m_HeaderPart.Dump(stream); } @@ -489,7 +495,7 @@ ASDCP::MPEG2::MXFReader::DumpHeaderMetadata(FILE* stream) const void ASDCP::MPEG2::MXFReader::DumpIndex(FILE* stream) const { - if ( m_Reader->m_File.IsOpen() ) + if ( m_Reader->m_File->IsOpen() ) m_Reader->m_IndexAccess.Dump(stream); } @@ -497,7 +503,7 @@ ASDCP::MPEG2::MXFReader::DumpIndex(FILE* stream) const ASDCP::Result_t ASDCP::MPEG2::MXFReader::Close() const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { m_Reader->Close(); return RESULT_OK; diff --git a/src/AS_DCP_MXF.cpp b/src/AS_DCP_MXF.cpp index 9cb4c15..129edf1 100755 --- a/src/AS_DCP_MXF.cpp +++ b/src/AS_DCP_MXF.cpp @@ -163,19 +163,19 @@ ASDCP::MD_to_CryptoInfo(CryptographicContext* InfoObj, WriterInfo& Info, const D // // ASDCP::Result_t -ASDCP::EssenceType(const std::string& filename, EssenceType_t& type) +ASDCP::EssenceType(const std::string& filename, EssenceType_t& type, const Kumu::IFileReaderFactory& fileReaderFactory) { const Dictionary* m_Dict = &DefaultCompositeDict(); InterchangeObject* md_object = 0; assert(m_Dict); - Kumu::FileReader Reader; + ASDCP::mem_ptr<Kumu::IFileReader> Reader(fileReaderFactory.CreateFileReader()); OP1aHeader TestHeader(m_Dict); - Result_t result = Reader.OpenRead(filename); + Result_t result = Reader->OpenRead(filename); if ( ASDCP_SUCCESS(result) ) - result = TestHeader.InitFromFile(Reader); // test UL and OP + result = TestHeader.InitFromFile(*Reader); // test UL and OP if ( ASDCP_SUCCESS(result) ) { @@ -312,7 +312,6 @@ ASDCP::RawEssenceType(const std::string& filename, EssenceType_t& type) ASDCP::Wav::SimpleWaveHeader WavHeader; ASDCP::RF64::SimpleRF64Header RF64Header; ASDCP::AIFF::SimpleAIFFHeader AIFFHeader; - Kumu::XMLElement TmpElement("Tmp"); ui32_t data_offset; ui32_t read_count; @@ -466,6 +465,8 @@ ASDCP::RawEssenceType(const std::string& filename, EssenceType_t& type) return result; } +#ifdef HAVE_OPENSSL + // Result_t ASDCP::EncryptFrameBuffer(const ASDCP::FrameBuffer& FBin, ASDCP::FrameBuffer& FBout, AESEncContext* Ctx) @@ -721,6 +722,8 @@ ASDCP::IntegrityPack::TestValues(const ASDCP::FrameBuffer& FB, const byte_t* Ass return result; } +#endif //HAVE_OPENSSL + // // end AS_DCP_MXF.cpp // diff --git a/src/AS_DCP_PCM.cpp b/src/AS_DCP_PCM.cpp index 4cca5d5..fb11e19 100755 --- a/src/AS_DCP_PCM.cpp +++ b/src/AS_DCP_PCM.cpp @@ -254,7 +254,7 @@ class ASDCP::PCM::MXFReader::h__Reader : public ASDCP::h__ASDCPReader public: AudioDescriptor m_ADesc; - h__Reader(const Dictionary *d) : ASDCP::h__ASDCPReader(d) {} + h__Reader(const Dictionary *d, const Kumu::IFileReaderFactory& fileReaderFactory) : ASDCP::h__ASDCPReader(d, fileReaderFactory) {} virtual ~h__Reader() {} Result_t OpenRead(const std::string&); Result_t ReadFrame(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*); @@ -339,7 +339,7 @@ ASDCP::Result_t ASDCP::PCM::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, FrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC) { - if ( ! m_File.IsOpen() ) + if ( ! m_File->IsOpen() ) return RESULT_INIT; if ( (FrameNum+1) > m_ADesc.ContainerDuration ) @@ -370,15 +370,15 @@ ASDCP::PCM::FrameBuffer::Dump(FILE* stream, ui32_t dump_len) const //------------------------------------------------------------------------------------------ -ASDCP::PCM::MXFReader::MXFReader() +ASDCP::PCM::MXFReader::MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory) { - m_Reader = new h__Reader(&DefaultCompositeDict()); + m_Reader = new h__Reader(&DefaultCompositeDict(), fileReaderFactory); } ASDCP::PCM::MXFReader::~MXFReader() { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) m_Reader->Close(); } @@ -443,7 +443,7 @@ ASDCP::Result_t ASDCP::PCM::MXFReader::ReadFrame(ui32_t FrameNum, FrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) return m_Reader->ReadFrame(FrameNum, FrameBuf, Ctx, HMAC); return RESULT_INIT; @@ -461,7 +461,7 @@ ASDCP::PCM::MXFReader::LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, ASDCP::Result_t ASDCP::PCM::MXFReader::FillAudioDescriptor(AudioDescriptor& ADesc) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { ADesc = m_Reader->m_ADesc; return RESULT_OK; @@ -475,7 +475,7 @@ ASDCP::PCM::MXFReader::FillAudioDescriptor(AudioDescriptor& ADesc) const ASDCP::Result_t ASDCP::PCM::MXFReader::FillWriterInfo(WriterInfo& Info) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { Info = m_Reader->m_Info; return RESULT_OK; @@ -488,7 +488,7 @@ ASDCP::PCM::MXFReader::FillWriterInfo(WriterInfo& Info) const void ASDCP::PCM::MXFReader::DumpHeaderMetadata(FILE* stream) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) m_Reader->m_HeaderPart.Dump(stream); } @@ -497,7 +497,7 @@ ASDCP::PCM::MXFReader::DumpHeaderMetadata(FILE* stream) const void ASDCP::PCM::MXFReader::DumpIndex(FILE* stream) const { - if ( m_Reader->m_File.IsOpen() ) + if ( m_Reader->m_File->IsOpen() ) m_Reader->m_IndexAccess.Dump(stream); } @@ -505,7 +505,7 @@ ASDCP::PCM::MXFReader::DumpIndex(FILE* stream) const ASDCP::Result_t ASDCP::PCM::MXFReader::Close() const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { m_Reader->Close(); return RESULT_OK; diff --git a/src/AS_DCP_TimedText.cpp b/src/AS_DCP_TimedText.cpp index f04c7d8..9a3e336 100644 --- a/src/AS_DCP_TimedText.cpp +++ b/src/AS_DCP_TimedText.cpp @@ -132,9 +132,9 @@ class ASDCP::TimedText::MXFReader::h__Reader : public ASDCP::h__ASDCPReader ASDCP_NO_COPY_CONSTRUCT(h__Reader); public: - TimedTextDescriptor m_TDesc; + TimedTextDescriptor m_TDesc; - h__Reader(const Dictionary *d) : ASDCP::h__ASDCPReader(d), m_EssenceDescriptor(0) { + h__Reader(const Dictionary *d, const Kumu::IFileReaderFactory& fileReaderFactory) : ASDCP::h__ASDCPReader(d, fileReaderFactory), m_EssenceDescriptor(0) { memset(&m_TDesc.AssetID, 0, UUIDlen); } @@ -231,7 +231,7 @@ ASDCP::Result_t ASDCP::TimedText::MXFReader::h__Reader::ReadTimedTextResource(FrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC) { - if ( ! m_File.IsOpen() ) + if ( ! m_File->IsOpen() ) return RESULT_INIT; assert(m_Dict); @@ -285,9 +285,9 @@ ASDCP::TimedText::MXFReader::h__Reader::ReadAncillaryResource(const byte_t* uuid //------------------------------------------------------------------------------------------ -ASDCP::TimedText::MXFReader::MXFReader() +ASDCP::TimedText::MXFReader::MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory) { - m_Reader = new h__Reader(&DefaultSMPTEDict()); + m_Reader = new h__Reader(&DefaultSMPTEDict(), fileReaderFactory); } @@ -353,7 +353,7 @@ ASDCP::TimedText::MXFReader::OpenRead(const std::string& filename) const ASDCP::Result_t ASDCP::TimedText::MXFReader::FillTimedTextDescriptor(TimedText::TimedTextDescriptor& TDesc) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { TDesc = m_Reader->m_TDesc; return RESULT_OK; @@ -367,7 +367,7 @@ ASDCP::TimedText::MXFReader::FillTimedTextDescriptor(TimedText::TimedTextDescrip ASDCP::Result_t ASDCP::TimedText::MXFReader::FillWriterInfo(WriterInfo& Info) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { Info = m_Reader->m_Info; return RESULT_OK; @@ -395,7 +395,7 @@ ASDCP::Result_t ASDCP::TimedText::MXFReader::ReadTimedTextResource(FrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) return m_Reader->ReadTimedTextResource(FrameBuf, Ctx, HMAC); return RESULT_INIT; @@ -406,7 +406,7 @@ ASDCP::Result_t ASDCP::TimedText::MXFReader::ReadAncillaryResource(const byte_t* uuid, FrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC) const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) return m_Reader->ReadAncillaryResource(uuid, FrameBuf, Ctx, HMAC); return RESULT_INIT; @@ -417,7 +417,7 @@ ASDCP::TimedText::MXFReader::ReadAncillaryResource(const byte_t* uuid, FrameBuff void ASDCP::TimedText::MXFReader::DumpHeaderMetadata(FILE* stream) const { - if ( m_Reader->m_File.IsOpen() ) + if ( m_Reader->m_File->IsOpen() ) m_Reader->m_HeaderPart.Dump(stream); } @@ -426,7 +426,7 @@ ASDCP::TimedText::MXFReader::DumpHeaderMetadata(FILE* stream) const void ASDCP::TimedText::MXFReader::DumpIndex(FILE* stream) const { - if ( m_Reader->m_File.IsOpen() ) + if ( m_Reader->m_File->IsOpen() ) m_Reader->m_IndexAccess.Dump(stream); } @@ -434,7 +434,7 @@ ASDCP::TimedText::MXFReader::DumpIndex(FILE* stream) const ASDCP::Result_t ASDCP::TimedText::MXFReader::Close() const { - if ( m_Reader && m_Reader->m_File.IsOpen() ) + if ( m_Reader && m_Reader->m_File->IsOpen() ) { m_Reader->Close(); return RESULT_OK; @@ -689,7 +689,7 @@ ASDCP::TimedText::MXFWriter::h__Writer::WriteAncillaryResource(const ASDCP::Time if ( ! m_State.Test_RUNNING() ) return RESULT_STATE; - Kumu::fpos_t here = m_File.Tell(); + Kumu::fpos_t here = m_File.TellPosition(); assert(m_Dict); // create generic stream partition header diff --git a/src/AS_DCP_internal.h b/src/AS_DCP_internal.h index 5626058..6d8688f 100755 --- a/src/AS_DCP_internal.h +++ b/src/AS_DCP_internal.h @@ -47,6 +47,8 @@ using namespace ASDCP::MXF; #endif +namespace ASDCP { + // uncomment to remove MXFGCGenericEssenceMultipleMappings from your AS-02 files // #define ASDCP_GCMULTI_PATCH @@ -61,10 +63,6 @@ extern MXF::OPAtomIndexFooter *g_OPAtomIndexFooter; extern MXF::RIP *g_RIP; #endif - -namespace ASDCP -{ - // static std::vector<int> version_split(const char* str) @@ -170,12 +168,13 @@ namespace ASDCP WriterInfo& Descr, const UL& WrappingUL, const Dictionary *Dict); Result_t AddDmsTrackGenericPartUtf8Text(Kumu::FileWriter&, ASDCP::MXF::OP1aHeader&, SourcePackage&, - ASDCP::MXF::RIP&, const Dictionary*); + ASDCP::MXF::RIP&, const Dictionary*, const std::string&, const std::string&, std::list<ui64_t*>&); + // Result_t WriteGenericStreamPartition(Kumu::FileWriter&, ASDCP::MXF::OP1aHeader&, ASDCP::MXF::RIP&, const Dictionary*, const ASDCP::FrameBuffer&, ASDCP::AESEncContext* = 0, ASDCP::HMACContext* = 0); - Result_t Read_EKLV_Packet(Kumu::FileReader& File, const ASDCP::Dictionary& Dict, + Result_t Read_EKLV_Packet(Kumu::IFileReader& File, const ASDCP::Dictionary& Dict, const ASDCP::WriterInfo& Info, Kumu::fpos_t& LastPosition, ASDCP::FrameBuffer& CtFrameBuf, ui32_t FrameNum, ui32_t SequenceNum, ASDCP::FrameBuffer& FrameBuf, const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC); @@ -200,7 +199,7 @@ namespace ASDCP inline ui64_t Length() { return m_ValueLength; } inline ui64_t KLLength() { return m_KLLength; } - Result_t ReadKLFromFile(Kumu::FileReader& Reader); + Result_t ReadKLFromFile(Kumu::IFileReader& Reader); }; namespace MXF @@ -218,7 +217,7 @@ namespace ASDCP public: const Dictionary *m_Dict; - Kumu::FileReader m_File; + Kumu::IFileReader* m_File; HeaderType m_HeaderPart; IndexAccessType m_IndexAccess; RIP m_RIP; @@ -226,14 +225,16 @@ namespace ASDCP ASDCP::FrameBuffer m_CtFrameBuf; Kumu::fpos_t m_LastPosition; - TrackFileReader(const Dictionary *d) : - m_HeaderPart(d), m_IndexAccess(d), m_RIP(d), m_Dict(d) + TrackFileReader(const Dictionary* d, const Kumu::IFileReaderFactory& fileReaderFactory) : + m_HeaderPart(m_Dict), m_IndexAccess(m_Dict), m_RIP(m_Dict), m_Dict(d) { default_md_object_init(); + m_File = fileReaderFactory.CreateFileReader(); } virtual ~TrackFileReader() { Close(); + delete m_File; } const MXF::RIP& GetRIP() const { return m_RIP; } @@ -242,14 +243,14 @@ namespace ASDCP Result_t OpenMXFRead(const std::string& filename) { m_LastPosition = 0; - Result_t result = m_File.OpenRead(filename); + Result_t result = m_File->OpenRead(filename); if ( ASDCP_SUCCESS(result) ) - result = SeekToRIP(m_File); + result = SeekToRIP(*m_File); if ( ASDCP_SUCCESS(result) ) { - result = m_RIP.InitFromFile(m_File); + result = m_RIP.InitFromFile(*m_File); if ( ASDCP_FAILURE(result) ) { @@ -265,8 +266,8 @@ namespace ASDCP DefaultLogSink().Error("TrackFileReader::OpenMXFRead, SeekToRIP failed\n"); } - m_File.Seek(0); - result = m_HeaderPart.InitFromFile(m_File); + m_File->Seek(0); + result = m_HeaderPart.InitFromFile(*m_File); if ( KM_FAILURE(result) ) { @@ -332,7 +333,7 @@ namespace ASDCP if ( FilePosition != m_LastPosition ) { m_LastPosition = FilePosition; - result = m_File.Seek(FilePosition); + result = m_File->Seek(FilePosition); } if ( KM_SUCCESS(result) ) @@ -361,7 +362,7 @@ namespace ASDCP if ( static_cast<Kumu::fpos_t>(TmpEntry.StreamOffset) != m_LastPosition ) { m_LastPosition = TmpEntry.StreamOffset; - result = m_File.Seek(TmpEntry.StreamOffset); + result = m_File->Seek(TmpEntry.StreamOffset); } if ( KM_SUCCESS(result) ) @@ -375,7 +376,7 @@ namespace ASDCP const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC) { assert(m_Dict); - return Read_EKLV_Packet(m_File, *m_Dict, m_Info, m_LastPosition, m_CtFrameBuf, + return Read_EKLV_Packet(*m_File, *m_Dict, m_Info, m_LastPosition, m_CtFrameBuf, FrameNum, SequenceNum, FrameBuf, EssenceUL, Ctx, HMAC); } @@ -384,7 +385,7 @@ namespace ASDCP Result_t CalcFrameBufferSize(ui64_t &PacketLength) { KLReader Reader; - Result_t result = Reader.ReadKLFromFile(m_File); + Result_t result = Reader.ReadKLFromFile(*m_File); if ( KM_FAILURE(result) ) return result; @@ -455,7 +456,7 @@ namespace ASDCP } // Read the Partition header and then read the payload. - Result_t result = m_File.Seek(start_offset); + Result_t result = m_File->Seek(start_offset); if ( KM_SUCCESS(result) ) { @@ -466,7 +467,7 @@ namespace ASDCP { // read the partition header ASDCP::MXF::Partition GSPart(m_Dict); - result = GSPart.InitFromFile(m_File); + result = GSPart.InitFromFile(*m_File); if ( KM_SUCCESS(result) ) { @@ -489,7 +490,7 @@ namespace ASDCP // void Close() { - m_File.Close(); + m_File->Close(); } }; @@ -733,6 +734,7 @@ namespace ASDCP m_HeaderPart.AddChildObject(m_MaterialPackage); m_ContentStorage->Packages.push_back(m_MaterialPackage->InstanceUID); + ui32_t trackID = 1; if ( tc_frame_rate ) { TrackSet<TimecodeComponent> MPTCTrack = @@ -743,12 +745,13 @@ namespace ASDCP m_DurationUpdateList.push_back(&(MPTCTrack.Sequence->Duration.get())); MPTCTrack.Clip->Duration.set_has_value(); m_DurationUpdateList.push_back(&(MPTCTrack.Clip->Duration.get())); + trackID++; } TrackSet<SourceClip> MPTrack = CreateTrackAndSequence<MaterialPackage, SourceClip>(m_HeaderPart, *m_MaterialPackage, TrackName, clip_edit_rate, DataDefinition, - 2, m_Dict); + trackID, m_Dict); MPTrack.Sequence->Duration.set_has_value(); m_DurationUpdateList.push_back(&(MPTrack.Sequence->Duration.get())); @@ -757,7 +760,7 @@ namespace ASDCP MPTrack.Sequence->StructuralComponents.push_back(MPTrack.Clip->InstanceUID); MPTrack.Clip->DataDefinition = DataDefinition; MPTrack.Clip->SourcePackageID = SourcePackageUMID; - MPTrack.Clip->SourceTrackID = 2; + MPTrack.Clip->SourceTrackID = trackID; MPTrack.Clip->Duration.set_has_value(); m_DurationUpdateList.push_back(&(MPTrack.Clip->Duration.get())); @@ -774,6 +777,7 @@ namespace ASDCP m_HeaderPart.AddChildObject(m_FilePackage); m_ContentStorage->Packages.push_back(m_FilePackage->InstanceUID); + trackID = 1; if ( tc_frame_rate ) { TrackSet<TimecodeComponent> FPTCTrack = @@ -784,12 +788,13 @@ namespace ASDCP m_DurationUpdateList.push_back(&(FPTCTrack.Sequence->Duration.get())); FPTCTrack.Clip->Duration.set_has_value(); m_DurationUpdateList.push_back(&(FPTCTrack.Clip->Duration.get())); + trackID++; } TrackSet<SourceClip> FPTrack = CreateTrackAndSequence<SourcePackage, SourceClip>(m_HeaderPart, *m_FilePackage, TrackName, clip_edit_rate, DataDefinition, - 2, m_Dict); + trackID, m_Dict); FPTrack.Sequence->Duration.set_has_value(); m_DurationUpdateList.push_back(&(FPTrack.Sequence->Duration.get())); @@ -854,16 +859,19 @@ namespace ASDCP } Result_t AddDmsGenericPartUtf8Text(const ASDCP::FrameBuffer& frame_buffer, - ASDCP::AESEncContext* enc = 0, ASDCP::HMACContext* hmac = 0) + ASDCP::AESEncContext* enc = 0, ASDCP::HMACContext* hmac = 0, + const std::string& trackDescription = "Descriptive Track", + const std::string& dataDescription = "") { Kumu::fpos_t previous_partition_offset = m_RIP.PairArray.back().ByteOffset; - Result_t result = AddDmsTrackGenericPartUtf8Text(m_File, m_HeaderPart, *m_FilePackage, m_RIP, m_Dict); + + Result_t result = AddDmsTrackGenericPartUtf8Text(m_File, m_HeaderPart, *m_FilePackage, m_RIP, m_Dict, trackDescription, dataDescription, m_DurationUpdateList); if ( KM_SUCCESS(result) ) { // m_RIP now contains an entry (at the back) for the new generic stream // (this entry was created during the call to AddDmsTrackGenericPartUtf8Text()) - if ( m_File.Tell() != m_RIP.PairArray.back().ByteOffset ) + if ( m_File.TellPosition() != m_RIP.PairArray.back().ByteOffset ) { DefaultLogSink().Error("File offset has moved since RIP modification. Unrecoverable error.\n"); return RESULT_FAIL; @@ -886,8 +894,9 @@ namespace ASDCP if ( KM_SUCCESS(result) ) { + ui64_t streamOffset = m_StreamOffset; result = Write_EKLV_Packet(m_File, *m_Dict, m_HeaderPart, m_Info, m_CtFrameBuf, m_FramesWritten, - m_StreamOffset, frame_buffer, GenericStream_DataElement.Value(), + streamOffset, frame_buffer, GenericStream_DataElement.Value(), MXF_BER_LENGTH, enc, hmac); } } @@ -924,7 +933,7 @@ namespace ASDCP public: Partition m_BodyPart; - h__ASDCPReader(const Dictionary*); + h__ASDCPReader(const Dictionary*, const Kumu::IFileReaderFactory& fileReaderFactory); virtual ~h__ASDCPReader(); Result_t OpenMXFRead(const std::string& filename); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 26b0d89..57b8d84 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -41,6 +41,7 @@ else() endif()
# ----------libkumu----------
+
# source
set(kumu_src KM_fileio.cpp KM_log.cpp KM_util.cpp KM_tai.cpp KM_prng.cpp KM_aes.cpp KM_xml.cpp KM_sha1.cpp)
@@ -48,6 +49,7 @@ set(kumu_src KM_fileio.cpp KM_log.cpp KM_util.cpp KM_tai.cpp KM_prng.cpp KM_aes. set(kumu_src ${kumu_src} KM_fileio.h KM_log.h KM_prng.h KM_util.h KM_tai.h KM_error.h KM_memio.h KM_mutex.h KM_platform.h dirent_win.h KM_aes.h KM_xml.h KM_sha1.h)
# ----------libasdcp----------
+
# source
set(asdcp_src MPEG2_Parser.cpp MPEG.cpp JP2K_Codestream_Parser.cpp
JP2K_Sequence_Parser.cpp JP2K.cpp PCM_Parser.cpp Wav.cpp
@@ -55,7 +57,7 @@ set(asdcp_src MPEG2_Parser.cpp MPEG.cpp JP2K_Codestream_Parser.cpp h__Reader.cpp h__Writer.cpp AS_DCP_MPEG2.cpp AS_DCP_JP2K.cpp
AS_DCP_PCM.cpp AS_DCP_TimedText.cpp PCMParserList.cpp MDD.cpp
AS_DCP_ATMOS.cpp AS_DCP_DCData.cpp DCData_ByteStream_Parser.cpp DCData_Sequence_Parser.cpp AtmosSyncChannel_Generator.cpp
- AtmosSyncChannel_Mixer.cpp PCMDataProviders.cpp SyncEncoder.c CRC16.c UUIDInformation.c
+ AtmosSyncChannel_Mixer.cpp PCMDataProviders.cpp SyncEncoder.cpp CRC16.cpp UUIDInformation.cpp
)
if (HAVE_OPENSSL)
@@ -67,7 +69,11 @@ if (USE_ASDCP_JXS) endif()
# header for deployment (install target)
-set(asdcp_deploy_header AS_DCP.h AS_DCP_JXS.h PCMParserList.h AS_DCP_internal.h KM_error.h KM_fileio.h KM_util.h KM_memio.h KM_tai.h KM_platform.h KM_log.h KM_mutex.h dirent_win.h)
+
+set(asdcp_deploy_header AS_DCP.h AS_DCP_JXS.h PCMParserList.h AS_DCP_internal.h KM_error.h KM_fileio.h KM_util.h KM_memio.h KM_tai.h KM_platform.h KM_log.h KM_mutex.h)
+if (WIN32)
+ list(APPEND asdcp_deploy_header dirent_win.h)
+endif()
# header
set(asdcp_src ${asdcp_src} Wav.h WavFileWriter.h MXF.h Metadata.h JP2K.h
@@ -77,6 +83,7 @@ JXS.h AS_DCP.h AS_DCP_JXS.h AS_DCP_internal.h KLV.h MPEG.h MXFTypes.h MDD.h )
# ----------as02----------
+
# source
set(as02_src h__02_Reader.cpp h__02_Writer.cpp AS_02_ISXD.cpp AS_02_JP2K.cpp
AS_02_JXS.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 ST2052_TextParser.cpp)
@@ -85,8 +92,7 @@ AS_02_JXS.cpp AS_02_PCM.cpp ST2052_TextParser.cpp AS_02_TimedText.cpp AS_02_ACES set(as02_deploy_header AS_02.h AS_02_JXS.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_JXS.h AS_02_internal.h AS_02_ACES.h ACES.h AS_02_IAB.h)
-
+set(as02_src ${as02_src} AS_02.h AS_02_JXS.h AS_02_internal.h AS_02_ACES.h ACES.h AS_02_IAB.h AS_02_PHDR.h)
include_directories("${CMAKE_CURRENT_SOURCE_DIR}")
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
@@ -230,4 +236,4 @@ set(install_targets blackwave wavesplit klvwalk asdcp-test asdcp-wrap asdcp-unwr install(TARGETS ${install_targets} RUNTIME DESTINATION bin)
install(FILES ${as02_deploy_header} ${asdcp_deploy_header} DESTINATION include)
-install(EXPORT asdcplibtargets DESTINATION targets)
+install(EXPORT asdcplibtargets DESTINATION targets)
\ No newline at end of file diff --git a/src/CRC16.c b/src/CRC16.cpp index 3e2f09e..302953d 100644 --- a/src/CRC16.c +++ b/src/CRC16.cpp @@ -31,6 +31,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "CRC16.h" +namespace ASDCP { + static const unsigned short g_aushCRC16tab[256]= { 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7, 0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef, @@ -84,3 +86,5 @@ unsigned short CRC16(const void *pData, int ilength) return ushCRC; } + +} // namespace asdcp diff --git a/src/CRC16.h b/src/CRC16.h index 6d3beb3..150afc1 100644 --- a/src/CRC16.h +++ b/src/CRC16.h @@ -32,14 +32,10 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef _CRC_16_H_ #define _CRC_16_H_ -#ifdef __cplusplus -extern "C" { -#endif +namespace ASDCP { unsigned short CRC16(const void *pData, int ilength); -#ifdef __cplusplus -} /* extern "C" */ -#endif +} // namespace asdcp #endif diff --git a/src/Index.cpp b/src/Index.cpp index 0815f25..5adc7e2 100755 --- a/src/Index.cpp +++ b/src/Index.cpp @@ -30,9 +30,11 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "MXF.h" -const ui32_t kl_length = ASDCP::SMPTE_UL_LENGTH + ASDCP::MXF_BER_LENGTH; +#include "KM_log.h" +const ui32_t kl_length = ASDCP::SMPTE_UL_LENGTH + ASDCP::MXF_BER_LENGTH; +using Kumu::DefaultLogSink; // ASDCP::MXF::IndexTableSegment::IndexTableSegment(const Dictionary* d) : InterchangeObject(d), RtFileOffset(0), RtEntryOffset(0), @@ -118,10 +120,15 @@ ASDCP::MXF::IndexTableSegment::InitFromTLVSet(TLVReader& TLVSet) if ( decoder_item_size < item_size ) { - TLVSet.SkipOffset(item_size - decoder_item_size); + rc = TLVSet.SkipOffset(item_size - decoder_item_size); } } } + if (IndexEntryArray.size() != item_count) + { + DefaultLogSink().Error("Malformed index table segment, could not decode all IndexEntries.\n"); + return RESULT_KLV_CODING; + } } } } @@ -196,7 +203,7 @@ ASDCP::MXF::IndexTableSegment::Dump(FILE* stream) } else { - fprintf(stream, " IndexEntryArray: %zu entries\n", IndexEntryArray.size()); + fprintf(stream, " IndexEntryArray: %lu entries\n", IndexEntryArray.size()); } } diff --git a/src/JP2K_Sequence_Parser.cpp b/src/JP2K_Sequence_Parser.cpp index a8de925..ad8f0e9 100755 --- a/src/JP2K_Sequence_Parser.cpp +++ b/src/JP2K_Sequence_Parser.cpp @@ -42,7 +42,9 @@ using namespace ASDCP; //------------------------------------------------------------------------------------------ - + +namespace ASDCP { + class FileList : public std::list<std::string> { std::string m_DirName; @@ -89,6 +91,7 @@ public: return result; } }; +} // namespace asdcp //------------------------------------------------------------------------------------------ @@ -191,6 +194,8 @@ ASDCP::JP2K::SequenceParser::h__SequenceParser::OpenRead(const std::list<std::st } +namespace ASDCP { + // bool operator==(const ASDCP::JP2K::ImageComponent_t& lhs, const ASDCP::JP2K::ImageComponent_t& rhs) @@ -334,6 +339,7 @@ operator==(const ASDCP::JP2K::PictureDescriptor& lhs, const ASDCP::JP2K::Picture return true; } +} // namespace asdcp // ASDCP::Result_t diff --git a/src/KLV.cpp b/src/KLV.cpp index 303a672..681a834 100755 --- a/src/KLV.cpp +++ b/src/KLV.cpp @@ -189,7 +189,7 @@ ASDCP::KLVPacket::Dump(FILE* stream, const Dictionary& Dict, bool show_value) // ASDCP::Result_t -ASDCP::KLVFilePacket::InitFromFile(const Kumu::FileReader& Reader, const UL& label) +ASDCP::KLVFilePacket::InitFromFile(const Kumu::IFileReader& Reader, const UL& label) { Result_t result = KLVFilePacket::InitFromFile(Reader); @@ -201,7 +201,7 @@ ASDCP::KLVFilePacket::InitFromFile(const Kumu::FileReader& Reader, const UL& lab // TODO: refactor to use InitFromBuffer ASDCP::Result_t -ASDCP::KLVFilePacket::InitFromFile(const Kumu::FileReader& Reader) +ASDCP::KLVFilePacket::InitFromFile(const Kumu::IFileReader& Reader) { ui32_t read_count; byte_t tmp_data[tmp_read_size]; @@ -266,7 +266,7 @@ ASDCP::KLVFilePacket::InitFromFile(const Kumu::FileReader& Reader) if ( (remainder = read_count - packet_length) != 0 ) { DefaultLogSink().Warn("Repositioning pointer for short packet\n"); - Kumu::fpos_t pos = Reader.Tell(); + Kumu::fpos_t pos = Reader.TellPosition(); assert(pos > remainder); result = Reader.Seek(pos - remainder); } @@ -249,8 +249,8 @@ inline const char* ui64sz(ui64_t i, char* buf) KLVFilePacket() {} virtual ~KLVFilePacket() {} - virtual Result_t InitFromFile(const Kumu::FileReader&); - virtual Result_t InitFromFile(const Kumu::FileReader&, const UL& label); + virtual Result_t InitFromFile(const Kumu::IFileReader&); + virtual Result_t InitFromFile(const Kumu::IFileReader&, const UL& label); virtual Result_t WriteKLToFile(Kumu::FileWriter& Writer, const UL& label, ui32_t length); }; diff --git a/src/KM_error.h b/src/KM_error.h index 8270cc0..ad94f6c 100755 --- a/src/KM_error.h +++ b/src/KM_error.h @@ -36,7 +36,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <string> -#define KM_DECLARE_RESULT(sym, i, l) const Result_t RESULT_##sym = Result_t(i, #sym, l); +#define KM_DECLARE_RESULT(sym, i, l) const Result_t RESULT_##sym = Result_t(i, #sym, l) namespace Kumu { diff --git a/src/KM_fileio.cpp b/src/KM_fileio.cpp index b24c7db..4d50722 100644 --- a/src/KM_fileio.cpp +++ b/src/KM_fileio.cpp @@ -762,6 +762,16 @@ Kumu::FileWriter::Writev(const byte_t* buf, ui32_t buf_len) return RESULT_OK; } +Kumu::FileReader::FileReader() +{ + m_Handle = INVALID_HANDLE_VALUE; + assert(sizeof(off_t) <= sizeof(int64_t)); +} + +Kumu::FileReader::~FileReader() +{ + Kumu::FileReader::Close(); +} #ifdef KM_WIN32 #ifdef KM_WIN32_UTF8 @@ -1066,6 +1076,7 @@ Kumu::FileWriter::Write(const byte_t* buf, ui32_t buf_len, ui32_t* bytes_written // POSIX // + Kumu::Result_t Kumu::FileReader::OpenRead(const std::string& filename) const { @@ -1140,7 +1151,6 @@ Kumu::FileReader::Read(byte_t* buf, ui32_t buf_len, ui32_t* read_count) const return (tmp_count == 0 ? RESULT_ENDOFFILE : RESULT_OK); } - //------------------------------------------------------------------------------------------ // @@ -1233,6 +1243,11 @@ Kumu::FileWriter::Write(const byte_t* buf, ui32_t buf_len, ui32_t* bytes_written //------------------------------------------------------------------------------------------ +// +IFileReader* FileReaderFactory::CreateFileReader() const +{ + return new FileReader(); +} // Kumu::Result_t @@ -1690,6 +1705,9 @@ Kumu::DeleteFile(const std::string& filename) return RESULT_FAIL; } +namespace Kumu +{ + // Result_t h__DeletePath(const std::string& pathname) @@ -1751,6 +1769,8 @@ h__DeletePath(const std::string& pathname) return result; } +} // namespace KUMU + // Result_t Kumu::DeletePath(const std::string& pathname) diff --git a/src/KM_fileio.h b/src/KM_fileio.h index 60e1e6a..1ef5e75 100755 --- a/src/KM_fileio.h +++ b/src/KM_fileio.h @@ -84,7 +84,7 @@ namespace Kumu KM_NO_COPY_CONSTRUCT(DirScannerEx); public: - + DirScannerEx(); ~DirScannerEx() { Close(); } @@ -313,37 +313,65 @@ namespace Kumu //------------------------------------------------------------------------------------------ // File I/O //------------------------------------------------------------------------------------------ + // + class IFileReader + { + public: + virtual ~IFileReader(){} + + virtual Result_t OpenRead(const std::string&) const = 0; // open the file for reading + virtual Result_t Close() const = 0; // close the file + virtual int64_t Size() const = 0; // returns the file's current size + virtual Result_t Seek(Kumu::fpos_t = 0, SeekPos_t = SP_BEGIN) const = 0; // move the file pointer + virtual Result_t Tell(Kumu::fpos_t* pos) const = 0; // report the file pointer's location + virtual Result_t Read(byte_t*, ui32_t, ui32_t* = 0) const = 0; // read a buffer of data + virtual bool IsOpen() const = 0; // returns true if the file is open + + inline int64_t TellPosition() const // report the file pointer's location + { + int64_t tmp_pos; + Tell(&tmp_pos); + return tmp_pos; + } + }; // - class FileReader - { - KM_NO_COPY_CONSTRUCT(FileReader); + class FileReader : public IFileReader + { + KM_NO_COPY_CONSTRUCT(FileReader); + + public: + FileReader(); + ~FileReader(); + virtual Result_t OpenRead(const std::string&) const; // open the file for reading + virtual Result_t Close() const; // close the file + virtual int64_t Size() const; // returns the file's current size + virtual Result_t Seek(Kumu::fpos_t = 0, SeekPos_t = SP_BEGIN) const; // move the file pointer + virtual Result_t Tell(Kumu::fpos_t* pos) const; // report the file pointer's location + virtual Result_t Read(byte_t*, ui32_t, ui32_t* = 0) const; // read a buffer of data + + inline virtual bool IsOpen() const // returns true if the file is open + { + return (m_Handle != INVALID_HANDLE_VALUE); + } protected: std::string m_Filename; FileHandle m_Handle; + }; + // + class IFileReaderFactory + { public: - FileReader() : m_Handle(INVALID_HANDLE_VALUE) {} - virtual ~FileReader() { Close(); } - - Result_t OpenRead(const std::string&) const; // open the file for reading - Result_t Close() const; // close the file - fsize_t Size() const; // returns the file's current size - Result_t Seek(Kumu::fpos_t = 0, SeekPos_t = SP_BEGIN) const; // move the file pointer - Result_t Tell(Kumu::fpos_t* pos) const; // report the file pointer's location - Result_t Read(byte_t*, ui32_t, ui32_t* = 0) const; // read a buffer of data - - inline Kumu::fpos_t Tell() const // report the file pointer's location - { - Kumu::fpos_t tmp_pos; - Tell(&tmp_pos); - return tmp_pos; - } - - inline bool IsOpen() { // returns true if the file is open - return (m_Handle != INVALID_HANDLE_VALUE); - } + virtual IFileReader* CreateFileReader() const = 0; + virtual ~IFileReaderFactory(){} + }; + + class FileReaderFactory : public IFileReaderFactory + { + public: + virtual IFileReader* CreateFileReader() const; }; // diff --git a/src/KM_platform.h b/src/KM_platform.h index 3e50e54..747f6fc 100644 --- a/src/KM_platform.h +++ b/src/KM_platform.h @@ -52,8 +52,12 @@ typedef unsigned __int64 ui64_t; typedef __int64 i64_t; # define i64_C(c) (i64_t)(c) # define ui64_C(c) (ui64_t)(c) +# if !defined snprintf && defined _snprintf # define snprintf _snprintf +# endif +# if !defined vsnprintf && defined _vsnprintf # define vsnprintf _vsnprintf +# endif # else // KM_WIN32 typedef unsigned long long ui64_t; diff --git a/src/KM_prng.cpp b/src/KM_prng.cpp index f40d846..f9ec0c0 100755 --- a/src/KM_prng.cpp +++ b/src/KM_prng.cpp @@ -50,7 +50,7 @@ using namespace Kumu; # include <wincrypt.h> #else // KM_WIN32 # include <KM_fileio.h> -const char* DEV_URANDOM = "/dev/urandom"; +static const char* DEV_URANDOM = "/dev/urandom"; #endif // KM_WIN32 @@ -59,94 +59,95 @@ const ui32_t RNG_KEY_SIZE_BITS = 256UL; const ui32_t RNG_BLOCK_SIZE = AES_BLOCKLEN; const ui32_t MAX_SEQUENCE_LEN = 0x00040000UL; +namespace{ + // internal implementation class + class h__RNG + { + KM_NO_COPY_CONSTRUCT(h__RNG); -// internal implementation class -class h__RNG -{ - KM_NO_COPY_CONSTRUCT(h__RNG); - -public: - AES_ctx m_Context; - byte_t m_ctr_buf[RNG_BLOCK_SIZE]; - Mutex m_Lock; + public: + AES_ctx m_Context; + byte_t m_ctr_buf[RNG_BLOCK_SIZE]; + Mutex m_Lock; - h__RNG() - { - memset(m_ctr_buf, 0, RNG_BLOCK_SIZE); - byte_t rng_key[RNG_KEY_SIZE]; + h__RNG() + { + memset(m_ctr_buf, 0, RNG_BLOCK_SIZE); + byte_t rng_key[RNG_KEY_SIZE]; - { // this block scopes the following AutoMutex so that it will be - // released before the call to set_key() below. - AutoMutex Lock(m_Lock); + { // this block scopes the following AutoMutex so that it will be + // released before the call to set_key() below. + AutoMutex Lock(m_Lock); -#ifdef KM_WIN32 - HCRYPTPROV hProvider = 0; - CryptAcquireContext(&hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); - CryptGenRandom(hProvider, RNG_KEY_SIZE, rng_key); -#else // KM_WIN32 - // on POSIX systems we simply read some seed from /dev/urandom - FileReader URandom; + #ifdef KM_WIN32 + HCRYPTPROV hProvider = 0; + CryptAcquireContext(&hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); + CryptGenRandom(hProvider, RNG_KEY_SIZE, rng_key); + #else // KM_WIN32 + // on POSIX systems we simply read some seed from /dev/urandom + FileReader URandom; - Result_t result = URandom.OpenRead(DEV_URANDOM); + Result_t result = URandom.OpenRead(DEV_URANDOM); - if ( KM_SUCCESS(result) ) - { - ui32_t read_count; - result = URandom.Read(rng_key, RNG_KEY_SIZE, &read_count); - } + if ( KM_SUCCESS(result) ) + { + ui32_t read_count; + result = URandom.Read(rng_key, RNG_KEY_SIZE, &read_count); + } - if ( KM_FAILURE(result) ) - DefaultLogSink().Error("Error opening random device: %s\n", DEV_URANDOM); + if ( KM_FAILURE(result) ) + DefaultLogSink().Error("Error opening random device: %s\n", DEV_URANDOM); -#endif // KM_WIN32 - } // end AutoMutex context + #endif // KM_WIN32 + } // end AutoMutex context - set_key(rng_key); - } - - // - void - set_key(const byte_t* key_fodder) - { - assert(key_fodder); - byte_t sha_buf[20]; - SHA1_CTX SHA; - SHA1_Init(&SHA); - - SHA1_Update(&SHA, (byte_t*)&m_Context, sizeof(m_Context)); - SHA1_Update(&SHA, key_fodder, RNG_KEY_SIZE); - SHA1_Final(sha_buf, &SHA); - - AutoMutex Lock(m_Lock); - AES_init_ctx(&m_Context, sha_buf); - *(ui32_t*)(m_ctr_buf + 12) = 1; - } - - // - void - fill_rand(byte_t* buf, ui32_t len) - { - assert(len <= MAX_SEQUENCE_LEN); - ui32_t gen_count = 0; - AutoMutex Lock(m_Lock); - - while ( gen_count + RNG_BLOCK_SIZE <= len ) + set_key(rng_key); + } + + // + void + set_key(const byte_t* key_fodder) { - memcpy(buf + gen_count, m_ctr_buf, RNG_BLOCK_SIZE); - AES_encrypt(&m_Context, buf + gen_count); - *(ui32_t*)(m_ctr_buf + 12) += 1; - gen_count += RNG_BLOCK_SIZE; + assert(key_fodder); + byte_t sha_buf[20]; + SHA1_CTX SHA; + SHA1_Init(&SHA); + + SHA1_Update(&SHA, (byte_t*)&m_Context, sizeof(m_Context)); + SHA1_Update(&SHA, key_fodder, RNG_KEY_SIZE); + SHA1_Final(sha_buf, &SHA); + + AutoMutex Lock(m_Lock); + AES_init_ctx(&m_Context, sha_buf); + *(ui32_t*)(m_ctr_buf + 12) = 1; } - - if ( len != gen_count ) // partial count needed? + + // + void + fill_rand(byte_t* buf, ui32_t len) { - byte_t tmp[RNG_BLOCK_SIZE]; - memcpy(tmp, m_ctr_buf, RNG_BLOCK_SIZE); - AES_encrypt(&m_Context, tmp); - memcpy(buf + gen_count, tmp, len - gen_count); + assert(len <= MAX_SEQUENCE_LEN); + ui32_t gen_count = 0; + AutoMutex Lock(m_Lock); + + while ( gen_count + RNG_BLOCK_SIZE <= len ) + { + memcpy(buf + gen_count, m_ctr_buf, RNG_BLOCK_SIZE); + AES_encrypt(&m_Context, buf + gen_count); + *(ui32_t*)(m_ctr_buf + 12) += 1; + gen_count += RNG_BLOCK_SIZE; + } + + if ( len != gen_count ) // partial count needed? + { + byte_t tmp[RNG_BLOCK_SIZE]; + memcpy(tmp, m_ctr_buf, RNG_BLOCK_SIZE); + AES_encrypt(&m_Context, tmp); + memcpy(buf + gen_count, tmp, len - gen_count); + } } - } -}; + }; +} static h__RNG* s_RNG = 0; diff --git a/src/KM_tai.cpp b/src/KM_tai.cpp index 00a1231..47039e6 100644 --- a/src/KM_tai.cpp +++ b/src/KM_tai.cpp @@ -55,6 +55,10 @@ The libtai source code is in the public domain. #include <sys/time.h> #endif +namespace Kumu +{ + + // void caldate_frommjd(Kumu::TAI::caldate* cd, i32_t day) @@ -216,6 +220,7 @@ Kumu::TAI::caltime::operator=(const Kumu::TAI::tai& rhs) return *this; } +} // namespace Kumu // // end KM_tai.cpp diff --git a/src/KM_util.cpp b/src/KM_util.cpp index da8d732..4c59c78 100755 --- a/src/KM_util.cpp +++ b/src/KM_util.cpp @@ -244,6 +244,9 @@ Kumu::DTrace_t::~DTrace_t() //------------------------------------------------------------------------------------------ +namespace Kumu +{ + const char fill = '='; const char* base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; @@ -283,6 +286,7 @@ const byte_t decode_map[] = 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; +} // namespace Kumu // Convert a binary string to NULL-terminated UTF-8 hexadecimal, returns the buffer // if the binary buffer was large enough to hold the result. If the output buffer diff --git a/src/KM_xml.cpp b/src/KM_xml.cpp index 5037391..9c45cde 100644 --- a/src/KM_xml.cpp +++ b/src/KM_xml.cpp @@ -74,20 +74,21 @@ extern "C" using namespace Kumu; - -class ns_map : public std::map<std::string, XMLNamespace*> -{ -public: - ~ns_map() +namespace{ + class ns_map : public std::map<std::string, XMLNamespace*> { - while ( ! empty() ) - { - ns_map::iterator ni = begin(); - delete ni->second; - erase(ni); - } - } -}; + public: + ~ns_map() + { + while ( ! empty() ) + { + ns_map::iterator ni = begin(); + delete ni->second; + erase(ni); + } + } + }; +} Kumu::XMLElement::XMLElement(const char* name) : m_Namespace(0), m_NamespaceOwner(0) @@ -612,6 +613,9 @@ Kumu::XMLElement::ParseFirstFromString(const char* document, ui32_t doc_len) if ( ! XML_Parse(Parser, document, doc_len, 1) ) { + DefaultLogSink().Error("XML Parse error on line %d: %s\n", + XML_GetCurrentLineNumber(Parser), + XML_ErrorString(XML_GetErrorCode(Parser))); XML_ParserFree(Parser); return false; } @@ -1022,8 +1026,23 @@ Kumu::XMLElement::ParseFirstFromString(const char* document, ui32_t doc_len) ++errorCount; } } + catch (const XMLException& e) + { + char* message = XMLString::transcode(e.getMessage()); + DefaultLogSink().Error("Parser error: %s\n", message); + XMLString::release(&message); + errorCount++; + } + catch (const SAXParseException& e) + { + char* message = XMLString::transcode(e.getMessage()); + DefaultLogSink().Error("Parser error: %s at line %d\n", message, e.getLineNumber()); + XMLString::release(&message); + errorCount++; + } catch (...) { + DefaultLogSink().Error("Unexpected XML parser error\n"); errorCount++; } diff --git a/src/MDD.cpp b/src/MDD.cpp index 4584a48..c513f3b 100644 --- a/src/MDD.cpp +++ b/src/MDD.cpp @@ -1702,7 +1702,7 @@ static const ASDCP::MDDEntry s_MDD_Table[] = { { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, 0x04, 0x01, 0x02, 0x02, 0x03, 0x08, 0x09, 0x00 }, {0}, false, "JPEGXSHigh4444_12Profile" }, // 549 - { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x7f, 0x01, 0x01, + { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x81, 0x02 }, {0}, false, "JPEGXSSubDescriptor" }, // 550 { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0e, diff --git a/src/MPEG2_Parser.cpp b/src/MPEG2_Parser.cpp index 8b79d51..3eefc96 100755 --- a/src/MPEG2_Parser.cpp +++ b/src/MPEG2_Parser.cpp @@ -44,6 +44,11 @@ const ui32_t VESReadSize = 4 * Kumu::Kilobyte; //------------------------------------------------------------------------------------------ +namespace ASDCP { + +namespace MPEG2 +{ + // enum ParserState_t { ST_INIT, @@ -365,7 +370,7 @@ public: // - any frame that begins with a picture header is either an I, B or P frame // and is assumed to contain a complete picture header and picture data -class ASDCP::MPEG2::Parser::h__Parser +class Parser::h__Parser { StreamParams m_ParamsDelegate; FrameParser m_ParserDelegate; @@ -388,6 +393,8 @@ public: Result_t FillVideoDescriptor(VideoDescriptor&); }; +} // namespace MPEG2 +} // namespace asdcp // Result_t diff --git a/src/MXF.cpp b/src/MXF.cpp index 3566c70..c961727 100755 --- a/src/MXF.cpp +++ b/src/MXF.cpp @@ -45,7 +45,7 @@ const ui32_t CBRIndexEntriesPerSegment = 5000; // ASDCP::Result_t -ASDCP::MXF::SeekToRIP(const Kumu::FileReader& Reader) +ASDCP::MXF::SeekToRIP(const Kumu::IFileReader& Reader) { Kumu::fpos_t end_pos; @@ -118,7 +118,7 @@ ASDCP::MXF::RIP::GetPairBySID(ui32_t SID, PartitionPair& outPair) const // ASDCP::Result_t -ASDCP::MXF::RIP::InitFromFile(const Kumu::FileReader& Reader) +ASDCP::MXF::RIP::InitFromFile(const Kumu::IFileReader& Reader) { assert(m_Dict); Result_t result = KLVFilePacket::InitFromFile(Reader, m_Dict->ul(MDD_RandomIndexMetadata)); @@ -291,7 +291,7 @@ ASDCP::MXF::Partition::AddChildObject(InterchangeObject* Object) // ASDCP::Result_t -ASDCP::MXF::Partition::InitFromFile(const Kumu::FileReader& Reader) +ASDCP::MXF::Partition::InitFromFile(const Kumu::IFileReader& Reader) { Result_t result = KLVFilePacket::InitFromFile(Reader); // test the UL @@ -552,8 +552,8 @@ ASDCP::MXF::Primer::InsertTag(const MDDEntry& Entry, ASDCP::TagValue& Tag) ASDCP::Result_t ASDCP::MXF::Primer::TagForKey(const ASDCP::UL& Key, ASDCP::TagValue& Tag) { - assert(m_Lookup); - if ( m_Lookup.empty() ) + + if ( !m_Lookup || m_Lookup.empty() ) { DefaultLogSink().Error("Primer lookup is empty\n"); return RESULT_FAIL; @@ -750,7 +750,7 @@ ASDCP::MXF::OP1aHeader::~OP1aHeader() {} // ASDCP::Result_t -ASDCP::MXF::OP1aHeader::InitFromFile(const Kumu::FileReader& Reader) +ASDCP::MXF::OP1aHeader::InitFromFile(const Kumu::IFileReader& Reader) { Result_t result = Partition::InitFromFile(Reader); @@ -986,7 +986,7 @@ ASDCP::MXF::OP1aHeader::WriteToFile(Kumu::FileWriter& Writer, ui32_t HeaderSize) // KLV Fill if ( ASDCP_SUCCESS(result) ) { - Kumu::fpos_t pos = Writer.Tell(); + Kumu::fpos_t pos = Writer.TellPosition(); if ( pos > (Kumu::fpos_t)HeaderByteCount ) { @@ -1058,7 +1058,7 @@ ASDCP::MXF::OPAtomIndexFooter::~OPAtomIndexFooter() {} // ASDCP::Result_t -ASDCP::MXF::OPAtomIndexFooter::InitFromFile(const Kumu::FileReader& Reader) +ASDCP::MXF::OPAtomIndexFooter::InitFromFile(const Kumu::IFileReader& Reader) { Result_t result = Partition::InitFromFile(Reader); // test UL and OP @@ -1509,26 +1509,35 @@ ASDCP::MXF::InterchangeObject::IsA(const byte_t* label) //------------------------------------------------------------------------------------------ -struct FactoryCompareUL +namespace ASDCP { +namespace MXF { - bool operator()(const ASDCP::UL& lhs, const ASDCP::UL& rhs) const + struct FactoryCompareUL { - ui32_t test_size = lhs.Size() < rhs.Size() ? lhs.Size() : rhs.Size(); - - for (ui32_t i = 0; i < test_size; i++) + bool operator()(const ASDCP::UL& lhs, const ASDCP::UL& rhs) const { - if (i == 7) continue; // skip version to be symmetrical with UL::operator== - if (lhs.Value()[i] != rhs.Value()[i]) - return lhs.Value()[i] < rhs.Value()[i]; - } + ui32_t test_size = lhs.Size() < rhs.Size() ? lhs.Size() : rhs.Size(); - return false; - } -}; + for (ui32_t i = 0; i < test_size; i++) + { + if (i == 7) continue; // skip version to be symmetrical with UL::operator== + if (lhs.Value()[i] != rhs.Value()[i]) + return lhs.Value()[i] < rhs.Value()[i]; + } -typedef std::map<ASDCP::UL, ASDCP::MXF::MXFObjectFactory_t, FactoryCompareUL>FactoryMap_t; + return false; + } + }; +} +} // namespace asdcp + +typedef std::map<ASDCP::UL, ASDCP::MXF::MXFObjectFactory_t, ASDCP::MXF::FactoryCompareUL>FactoryMap_t; typedef FactoryMap_t::iterator FLi_t; +namespace ASDCP { + +namespace MXF +{ // class FactoryList : public FactoryMap_t { @@ -1559,8 +1568,11 @@ public: } }; +} // namespace MXF +} // namespace asdcp + // -static FactoryList s_FactoryList; +static ASDCP::MXF::FactoryList s_FactoryList; static Kumu::Mutex s_InitLock; static bool s_TypesInit = false; @@ -54,7 +54,7 @@ namespace ASDCP // seek an open file handle to the start of the RIP KLV packet - Result_t SeekToRIP(const Kumu::FileReader&); + Result_t SeekToRIP(const Kumu::IFileReader &); // class RIP : public ASDCP::KLVFilePacket @@ -107,7 +107,7 @@ namespace ASDCP RIP(const Dictionary* d) : m_Dict(d) {} virtual ~RIP() {} - virtual Result_t InitFromFile(const Kumu::FileReader& Reader); + virtual Result_t InitFromFile(const Kumu::IFileReader& Reader); virtual Result_t WriteToFile(Kumu::FileWriter& Writer); virtual bool GetPairBySID(ui32_t, PartitionPair&) const; virtual void Dump(FILE* = 0); @@ -156,7 +156,7 @@ namespace ASDCP Partition(const Dictionary*); virtual ~Partition(); virtual void AddChildObject(InterchangeObject*); // takes ownership - virtual Result_t InitFromFile(const Kumu::FileReader& Reader); + virtual Result_t InitFromFile(const Kumu::IFileReader& Reader); virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l); virtual Result_t WriteToFile(Kumu::FileWriter& Writer, UL& PartitionLabel); virtual ui32_t ArchiveSize(); // returns the size of the archived structure @@ -443,7 +443,7 @@ namespace ASDCP OP1aHeader(const Dictionary*); virtual ~OP1aHeader(); - virtual Result_t InitFromFile(const Kumu::FileReader& Reader); + virtual Result_t InitFromFile(const Kumu::IFileReader& 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, ui32_t HeaderLength = 16384); @@ -478,7 +478,7 @@ namespace ASDCP OPAtomIndexFooter(const Dictionary*); virtual ~OPAtomIndexFooter(); - virtual Result_t InitFromFile(const Kumu::FileReader& Reader); + virtual Result_t InitFromFile(const Kumu::IFileReader& 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); diff --git a/src/MXFTypes.h b/src/MXFTypes.h index 0f38e9d..50cc286 100755 --- a/src/MXFTypes.h +++ b/src/MXFTypes.h @@ -624,8 +624,12 @@ namespace ASDCP size_t const RGBAValueLength = 16; + byte_t const RGBAValue_RGB_16[RGBAValueLength] = { 'R', 16, 'G', 16, 'B', 16, 0, 0 }; + byte_t const RGBAValue_RGB_12[RGBAValueLength] = { 'R', 12, 'G', 12, 'B', 12, 0, 0 }; byte_t const RGBAValue_RGB_10[RGBAValueLength] = { 'R', 10, 'G', 10, 'B', 10, 0, 0 }; byte_t const RGBAValue_RGB_8[RGBAValueLength] = { 'R', 8, 'G', 8, 'B', 8, 0, 0 }; + byte_t const RGBAValue_YUV_16[RGBAValueLength] = { 'Y', 16, 'U', 16, 'V', 16, 0, 0 }; + byte_t const RGBAValue_YUV_12[RGBAValueLength] = { 'Y', 12, 'U', 12, 'V', 12, 0, 0 }; byte_t const RGBAValue_YUV_10[RGBAValueLength] = { 'Y', 10, 'U', 10, 'V', 10, 0, 0 }; byte_t const RGBAValue_YUV_8[RGBAValueLength] = { 'Y', 8, 'U', 8, 'V', 8, 0, 0 }; byte_t const RGBAValue_DCDM[RGBAValueLength] = { 0xd8, 10, 0xd9, 10, 0xda, 10, 0, 0 }; diff --git a/src/Makefile.am b/src/Makefile.am index 5a7f9ed..3ea5cbd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -134,8 +134,8 @@ libasdcp_la_SOURCES = MPEG2_Parser.cpp MPEG.cpp JP2K_Codestream_Parser.cpp \ AtmosSyncChannel_Generator.cpp AtmosSyncChannel_Generator.h \ AtmosSyncChannel_Mixer.cpp AtmosSyncChannel_Mixer.h \ PCMDataProviders.cpp PCMDataProviders.h \ - SyncEncoder.c SyncEncoder.h SyncCommon.h CRC16.c CRC16.h \ - UUIDInformation.c UUIDInformation.h \ + SyncEncoder.cpp SyncEncoder.h SyncCommon.h CRC16.cpp CRC16.h \ + UUIDInformation.cpp UUIDInformation.h \ ST2095_PinkNoise.cpp if HAVE_OPENSSL diff --git a/src/PCM_Parser.cpp b/src/PCM_Parser.cpp index 072c235..b8dea71 100755 --- a/src/PCM_Parser.cpp +++ b/src/PCM_Parser.cpp @@ -45,14 +45,14 @@ using namespace ASDCP::RF64; // class ASDCP::PCM::WAVParser::h__WAVParser { - Kumu::FileReader m_FileReader; - bool m_EOF; - ui32_t m_DataStart; - ui64_t m_DataLength; - ui64_t m_ReadCount; - ui32_t m_FrameBufferSize; - ui32_t m_FramesRead; - Rational m_PictureRate; + Kumu::FileReader m_FileReader; + bool m_EOF; + ui32_t m_DataStart; + ui64_t m_DataLength; + ui64_t m_ReadCount; + ui32_t m_FrameBufferSize; + ui32_t m_FramesRead; + Rational m_PictureRate; ASDCP_NO_COPY_CONSTRUCT(h__WAVParser); @@ -118,7 +118,7 @@ ASDCP::PCM::WAVParser::h__WAVParser::OpenRead(const std::string& filename, const ASDCP::AIFF::SimpleAIFFHeader AIFFHeader; m_FileReader.Seek(0); - result = AIFFHeader.ReadFromFile(m_FileReader, &m_DataStart); + result = AIFFHeader.ReadFromFile(m_FileReader, &m_DataStart); if ( ASDCP_SUCCESS(result) ) { @@ -133,7 +133,7 @@ ASDCP::PCM::WAVParser::h__WAVParser::OpenRead(const std::string& filename, const { SimpleRF64Header RF64Header; m_FileReader.Seek(0); - result = RF64Header.ReadFromFile(m_FileReader, &m_DataStart); + result = RF64Header.ReadFromFile(m_FileReader, &m_DataStart); if ( ASDCP_SUCCESS(result) ) { diff --git a/src/ST2052_TextParser.cpp b/src/ST2052_TextParser.cpp index 75c0e86..9dabfb7 100644 --- a/src/ST2052_TextParser.cpp +++ b/src/ST2052_TextParser.cpp @@ -38,7 +38,7 @@ using namespace ASDCP; using Kumu::DefaultLogSink; -const char* c_tt_namespace_name = "http://www.smpte-ra.org/schemas/2052-1/2010/smpte-tt"; +static const char* c_tt_namespace_name = "http://www.smpte-ra.org/schemas/2052-1/2010/smpte-tt"; //------------------------------------------------------------------------------------------ diff --git a/src/SyncEncoder.c b/src/SyncEncoder.cpp index c553509..11c74ed 100644 --- a/src/SyncEncoder.c +++ b/src/SyncEncoder.cpp @@ -34,9 +34,13 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <memory.h> +using namespace ASDCP; + +static void ConstructFrame(LPSYNCENCODER pSyncEncoder, INT iFrameIndex); +static FLOAT SEWriteBits( INT iSampleRate, /* In: Sample rate of signal */ FLOAT *pfAudioBuffer, /* Out: Audio buffer containing signal */ INT iBits, /* In: Number of bits to write */ @@ -45,7 +49,7 @@ FLOAT SEWriteBits( INT iSampleRate, /* In: Sample rate of signal */ -INT SyncEncoderInit(LPSYNCENCODER pSyncEncoder, /* Out: SYNCENCODER structure to be initialized */ +INT ASDCP::SyncEncoderInit(LPSYNCENCODER pSyncEncoder, /* Out: SYNCENCODER structure to be initialized */ INT iSampleRate, /* In: Signal sample rate */ INT iFrameRate, /* In: frame rate */ LPUUIDINFORMATION pUUID) /* In: UUID */ @@ -142,7 +146,7 @@ INT SyncEncoderInit(LPSYNCENCODER pSyncEncoder, /* Out: SYNCENCODER structure t return pSyncEncoder->iError; } -INT GetSyncEncoderAudioBufferLength(LPSYNCENCODER pSyncEncoder) /* In: Sync encoder structure */ +INT ASDCP::GetSyncEncoderAudioBufferLength(LPSYNCENCODER pSyncEncoder) /* In: Sync encoder structure */ { if(pSyncEncoder->iError != SYNC_ENCODER_ERROR_NONE){ return pSyncEncoder->iError; @@ -153,7 +157,7 @@ INT GetSyncEncoderAudioBufferLength(LPSYNCENCODER pSyncEncoder) /* In: Sync enco -INT EncodeSync( LPSYNCENCODER pSyncEncoder, /* In: Sync encoder structure */ +INT ASDCP::EncodeSync( LPSYNCENCODER pSyncEncoder, /* In: Sync encoder structure */ INT iBufferLength, /* In: Length of audio buffer */ FLOAT *pfAudioBuffer, /* Out: Audio buffer with signal */ INT iFrameIndex) /* In: Frame Index */ diff --git a/src/SyncEncoder.h b/src/SyncEncoder.h index 4b97f5a..fc84ebf 100644 --- a/src/SyncEncoder.h +++ b/src/SyncEncoder.h @@ -35,9 +35,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "SyncCommon.h" #include "UUIDInformation.h" -#ifdef __cplusplus -extern "C" { -#endif +namespace ASDCP { + typedef struct SyncEncoder{ INT iSampleRate; /* Signal sample rate */ @@ -78,9 +77,7 @@ INT EncodeSync( LPSYNCENCODER pSyncEncoder, /* In: Sync encoder structure */ FLOAT *pfAudioBuffer, /* Out: Audio buffer with signal */ INT iFrameIndex); /* In: Frame Index */ -#ifdef __cplusplus -} /* extern "C" */ -#endif +} // namespace asdcp #endif diff --git a/src/TimedText_Parser.cpp b/src/TimedText_Parser.cpp index 020baf3..d3eca72 100644 --- a/src/TimedText_Parser.cpp +++ b/src/TimedText_Parser.cpp @@ -39,7 +39,7 @@ using namespace ASDCP; using Kumu::DefaultLogSink; -const char* c_dcst_namespace_name = "http://www.smpte-ra.org/schemas/428-7/2007/DCST"; +static const char* c_dcst_namespace_name = "http://www.smpte-ra.org/schemas/428-7/2007/DCST"; //------------------------------------------------------------------------------------------ @@ -144,36 +144,37 @@ public: Result_t OpenRead(const std::string& xml_doc, const std::string& filename); Result_t ReadAncillaryResource(const byte_t* uuid, FrameBuffer& FrameBuf, const IResourceResolver& Resolver) const; }; +namespace { + // + bool + get_UUID_from_element(XMLElement* Element, UUID& ID) + { + assert(Element); + const char* p = Element->GetBody().c_str(); -// -bool -get_UUID_from_element(XMLElement* Element, UUID& ID) -{ - assert(Element); - const char* p = Element->GetBody().c_str(); + if ( strncmp(p, "urn:uuid:", 9) == 0 ) + { + p += 9; + } + + return ID.DecodeHex(p); + } - if ( strncmp(p, "urn:uuid:", 9) == 0 ) + // + bool + get_UUID_from_child_element(const char* name, XMLElement* Parent, UUID& outID) { - p += 9; - } - - return ID.DecodeHex(p); -} + assert(name); + assert(Parent); + XMLElement* Child = Parent->GetChildWithName(name); -// -bool -get_UUID_from_child_element(const char* name, XMLElement* Parent, UUID& outID) -{ - assert(name); - assert(Parent); - XMLElement* Child = Parent->GetChildWithName(name); + if ( Child == 0 ) + { + return false; + } - if ( Child == 0 ) - { - return false; + return get_UUID_from_element(Child, outID); } - - return get_UUID_from_element(Child, outID); } // diff --git a/src/UUIDInformation.c b/src/UUIDInformation.cpp index 4c5eec9..335e532 100644 --- a/src/UUIDInformation.c +++ b/src/UUIDInformation.cpp @@ -32,8 +32,9 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "UUIDInformation.h" #include <stdlib.h> +using namespace ASDCP; -void UUIDSynthesize(LPUUIDINFORMATION pUUID) +void ASDCP::UUIDSynthesize(LPUUIDINFORMATION pUUID) { INT n; @@ -48,8 +49,8 @@ void UUIDSynthesize(LPUUIDINFORMATION pUUID) pUUID->abyUUIDBytes[8] |= 0xA0; } -void UUIDPrint( FILE *pFilePtr, - LPUUIDINFORMATION pUUID) +void ASDCP::UUIDPrint( FILE *pFilePtr, + LPUUIDINFORMATION pUUID) { if(pFilePtr != NULL){ INT n; @@ -67,8 +68,8 @@ void UUIDPrint( FILE *pFilePtr, } } -void UUIDPrintFormated( FILE *pFilePtr, - LPUUIDINFORMATION pUUID) +void ASDCP::UUIDPrintFormated( FILE *pFilePtr, + LPUUIDINFORMATION pUUID) { if(pFilePtr != NULL){ INT n; diff --git a/src/UUIDInformation.h b/src/UUIDInformation.h index 4bd0ff4..804104b 100644 --- a/src/UUIDInformation.h +++ b/src/UUIDInformation.h @@ -35,9 +35,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "SyncCommon.h" #include <stdio.h> -#ifdef __cplusplus -extern "C" { -#endif +namespace ASDCP { typedef struct UUIInformation{ BYTE abyUUIDBytes[16]; @@ -51,8 +49,6 @@ void UUIDPrint( FILE *pFilePtr, void UUIDPrintFormated( FILE *pFilePtr, LPUUIDINFORMATION pUUID); -#ifdef __cplusplus -} /* extern "C" */ -#endif +} // namespace asdcp #endif diff --git a/src/Wav.cpp b/src/Wav.cpp index 8f510eb..73a216c 100755 --- a/src/Wav.cpp +++ b/src/Wav.cpp @@ -108,7 +108,7 @@ ASDCP::Wav::SimpleWaveHeader::WriteToFile(Kumu::FileWriter& OutFile) const // ASDCP::Result_t -ASDCP::Wav::SimpleWaveHeader::ReadFromFile(const Kumu::FileReader& InFile, ui32_t* data_start) +ASDCP::Wav::SimpleWaveHeader::ReadFromFile(const Kumu::IFileReader& InFile, ui32_t* data_start) { ui32_t read_count = 0; ui32_t local_data_start = 0; @@ -206,6 +206,9 @@ ASDCP::Wav::SimpleWaveHeader::ReadFromBuffer(const byte_t* buf, ui32_t buf_len, //------------------------------------------------------------------------------------------ // conversion algorithms from http://www.borg.com/~jglatt/tech/aiff.htm +namespace ASDCP { + + // void Rat_to_extended(ASDCP::Rational rate, byte_t* buf) @@ -256,6 +259,8 @@ extended_to_Rat(const byte_t* buf) return ASDCP::Rational(mantissa, 1); } +} // namespace asdcp + // void ASDCP::AIFF::SimpleAIFFHeader::FillADesc(ASDCP::PCM::AudioDescriptor& ADesc, ASDCP::Rational PictureRate) const @@ -274,7 +279,7 @@ ASDCP::AIFF::SimpleAIFFHeader::FillADesc(ASDCP::PCM::AudioDescriptor& ADesc, ASD // ASDCP::Result_t -ASDCP::AIFF::SimpleAIFFHeader::ReadFromFile(const Kumu::FileReader& InFile, ui32_t* data_start) +ASDCP::AIFF::SimpleAIFFHeader::ReadFromFile(const Kumu::IFileReader& InFile, ui32_t* data_start) { ui32_t read_count = 0; ui32_t local_data_start = 0; @@ -483,7 +488,7 @@ ASDCP::RF64::SimpleRF64Header::WriteToFile(Kumu::FileWriter& OutFile) const // ASDCP::Result_t -ASDCP::RF64::SimpleRF64Header::ReadFromFile(const Kumu::FileReader& InFile, ui32_t* data_start) +ASDCP::RF64::SimpleRF64Header::ReadFromFile(const Kumu::IFileReader& InFile, ui32_t* data_start) { ui32_t read_count = 0; ui32_t local_data_start = 0; @@ -74,7 +74,7 @@ namespace ASDCP } Result_t ReadFromBuffer(const byte_t* buf, ui32_t buf_len, ui32_t* data_start); - Result_t ReadFromFile(const Kumu::FileReader& InFile, ui32_t* data_start); + Result_t ReadFromFile(const Kumu::IFileReader& InFile, ui32_t* data_start); void FillADesc(ASDCP::PCM::AudioDescriptor& ADesc, Rational PictureRate) const; }; @@ -112,7 +112,7 @@ namespace ASDCP SimpleWaveHeader(ASDCP::PCM::AudioDescriptor& ADesc); Result_t ReadFromBuffer(const byte_t* buf, ui32_t buf_len, ui32_t* data_start); - Result_t ReadFromFile(const Kumu::FileReader& InFile, ui32_t* data_start); + Result_t ReadFromFile(const Kumu::IFileReader& InFile, ui32_t* data_start); Result_t WriteToFile(Kumu::FileWriter& OutFile) const; void FillADesc(ASDCP::PCM::AudioDescriptor& ADesc, Rational PictureRate) const; }; @@ -148,7 +148,7 @@ namespace ASDCP SimpleRF64Header(ASDCP::PCM::AudioDescriptor& ADesc); Result_t ReadFromBuffer(const byte_t* buf, ui32_t buf_len, ui32_t* data_start); - Result_t ReadFromFile(const Kumu::FileReader& InFile, ui32_t* data_start); + Result_t ReadFromFile(const Kumu::IFileReader& InFile, ui32_t* data_start); Result_t WriteToFile(Kumu::FileWriter& OutFile) const; void FillADesc(ASDCP::PCM::AudioDescriptor& ADesc, Rational PictureRate) const; diff --git a/src/as-02-info.cpp b/src/as-02-info.cpp index dd769a8..79fe41b 100644 --- a/src/as-02-info.cpp +++ b/src/as-02-info.cpp @@ -39,6 +39,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <KM_log.h> #include <AS_DCP.h> #include <AS_02.h> +#include <AS_02_IAB.h> #include <JP2K.h> #include <AS_02_ACES.h> #include <ACES.h> @@ -631,15 +632,22 @@ class FileInfoWrapper Result_t OpenRead(const T& m, const CommandOptions& Options) { return m.OpenRead(Options.filenames.front().c_str()); - }; + } + + Result_t OpenRead(AS_02::IAB::MXFReader& m, const CommandOptions& Options) + { + // OpenRead method is not const + return m.OpenRead(Options.filenames.front().c_str()); + } + Result_t OpenRead(const AS_02::PCM::MXFReader& m, const CommandOptions& Options) { return m.OpenRead(Options.filenames.front().c_str(), EditRate_24); //Result_t OpenRead(const std::string& filename, const ASDCP::Rational& EditRate); - }; + } public: - FileInfoWrapper() : m_MaxBitrate(0.0), m_AvgBitrate(0.0) {} + FileInfoWrapper(const IFileReaderFactory& fileReaderFactory) : m_MaxBitrate(0.0), m_AvgBitrate(0.0), m_Reader(fileReaderFactory) {} virtual ~FileInfoWrapper() {} Result_t @@ -662,7 +670,7 @@ public: fprintf(stdout, "%s file essence type is %s, (%d edit unit%s).\n", ( m_WriterInfo.LabelSetType == LS_MXF_SMPTE ? "SMPTE 2067-5" : "Unknown" ), type_string, - (m_Desc.ContainerDuration != 0 ? m_Desc.ContainerDuration : m_Reader.AS02IndexReader().GetDuration()), + m_Desc.ContainerDuration, (m_Desc.ContainerDuration == (ui64_t)1 ? "":"s")); if ( Options.showheader_flag ) @@ -855,17 +863,17 @@ public: // Read header metadata from an ASDCP file // Result_t -show_file_info(CommandOptions& Options) +show_file_info(CommandOptions& Options, const Kumu::IFileReaderFactory& fileReaderFactory) { EssenceType_t EssenceType; - Result_t result = ASDCP::EssenceType(Options.filenames.front().c_str(), EssenceType); + Result_t result = ASDCP::EssenceType(Options.filenames.front().c_str(), EssenceType, fileReaderFactory); if ( ASDCP_FAILURE(result) ) return result; if ( EssenceType == ESS_AS02_JPEG_2000 ) { - FileInfoWrapper<AS_02::JP2K::MXFReader, MyPictureDescriptor> wrapper; + FileInfoWrapper<AS_02::JP2K::MXFReader, MyPictureDescriptor> wrapper(fileReaderFactory); result = wrapper.file_info(Options, "JPEG 2000 pictures"); if ( KM_SUCCESS(result) ) @@ -889,7 +897,7 @@ show_file_info(CommandOptions& Options) else if ( EssenceType == ESS_AS02_ACES ) { - FileInfoWrapper<AS_02::ACES::MXFReader, MyACESPictureDescriptor> wrapper; + FileInfoWrapper<AS_02::ACES::MXFReader, MyACESPictureDescriptor> wrapper(fileReaderFactory); result = wrapper.file_info(Options, "ACES pictures"); if ( KM_SUCCESS(result) ) @@ -913,7 +921,7 @@ show_file_info(CommandOptions& Options) else if ( EssenceType == ESS_AS02_PCM_24b_48k || EssenceType == ESS_AS02_PCM_24b_96k ) { - FileInfoWrapper<AS_02::PCM::MXFReader, MyAudioDescriptor> wrapper; + FileInfoWrapper<AS_02::PCM::MXFReader, MyAudioDescriptor> wrapper(fileReaderFactory); result = wrapper.file_info(Options, "PCM audio"); if ( ASDCP_SUCCESS(result) && Options.showcoding_flag ) @@ -922,14 +930,14 @@ show_file_info(CommandOptions& Options) else { fprintf(stderr, "Unknown/unsupported essence type: %s\n", Options.filenames.front().c_str()); - Kumu::FileReader Reader; + ASDCP::mem_ptr<Kumu::IFileReader> Reader(fileReaderFactory.CreateFileReader()); const Dictionary* Dict = &DefaultCompositeDict(); MXF::OP1aHeader TestHeader(Dict); - result = Reader.OpenRead(Options.filenames.front().c_str()); + result = Reader->OpenRead(Options.filenames.front().c_str()); if ( ASDCP_SUCCESS(result) ) - result = TestHeader.InitFromFile(Reader); // test UL and OP + result = TestHeader.InitFromFile(*Reader); // test UL and OP if ( ASDCP_SUCCESS(result) ) { @@ -949,8 +957,7 @@ show_file_info(CommandOptions& Options) { fputs("File is not MXF.\n", stdout); } - } - + } return result; } @@ -977,10 +984,10 @@ main(int argc, const char** argv) } init_rate_info(); - + Kumu::FileReaderFactory defaultFactory; while ( ! Options.filenames.empty() && ASDCP_SUCCESS(result) ) { - result = show_file_info(Options); + result = show_file_info(Options, defaultFactory); Options.filenames.pop_front(); } diff --git a/src/as-02-unwrap.cpp b/src/as-02-unwrap.cpp index 64a399a..614a624 100755 --- a/src/as-02-unwrap.cpp +++ b/src/as-02-unwrap.cpp @@ -38,12 +38,13 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <KM_fileio.h> #include <AS_02.h> +#include <AS_02_IAB.h> #include "AS_02_ACES.h" #include <WavFileWriter.h> namespace ASDCP { Result_t MD_to_PCM_ADesc(ASDCP::MXF::WaveAudioDescriptor* ADescObj, ASDCP::PCM::AudioDescriptor& ADesc); -} +} // namespace asdcp using namespace ASDCP; @@ -140,7 +141,7 @@ public: bool j2c_pedantic; // passed to JP2K::SequenceParser::OpenRead ui32_t picture_rate; // fps of picture when wrapping PCM ui32_t fb_size; // size of picture frame buffer - Rational edit_rate; // frame buffer size for reading clip-wrapped PCM + ASDCP::Rational edit_rate; // frame buffer size for reading clip-wrapped PCM const char* file_prefix; // filename pre for files written by the extract mode byte_t key_value[KeyLen]; // value of given encryption key (when key_flag is true) byte_t key_id_value[UUIDlen];// value of given key ID (when key_id_flag is true) @@ -289,13 +290,13 @@ public: // Read one or more ciphertext JPEG 2000 codestreams from a ciphertext ASDCP file // Result_t -read_JP2K_file(CommandOptions& Options) +read_JP2K_file(CommandOptions& Options, const Kumu::IFileReaderFactory& fileReaderFactory) { - AESDecContext* Context = 0; - HMACContext* HMAC = 0; - AS_02::JP2K::MXFReader Reader; - JP2K::FrameBuffer FrameBuffer(Options.fb_size); - ui32_t frame_count = 0; + AESDecContext* Context = 0; + HMACContext* HMAC = 0; + AS_02::JP2K::MXFReader Reader(fileReaderFactory); + JP2K::FrameBuffer FrameBuffer(Options.fb_size); + ui32_t frame_count = 0; Result_t result = Reader.OpenRead(Options.input_filename); @@ -435,11 +436,11 @@ read_JP2K_file(CommandOptions& Options) // Result_t -read_ACES_file(CommandOptions& Options) +read_ACES_file(CommandOptions& Options, const Kumu::IFileReaderFactory& fileReaderFactory) { AESDecContext* Context = 0; HMACContext* HMAC = 0; - AS_02::ACES::MXFReader Reader; + AS_02::ACES::MXFReader Reader(fileReaderFactory); AS_02::ACES::FrameBuffer FrameBuffer(Options.fb_size); ui64_t frame_count = 0; AS_02::ACES::ResourceList_t resource_list_t; @@ -625,17 +626,17 @@ read_ACES_file(CommandOptions& Options) // Read one or more ciphertext PCM audio streams from a ciphertext ASDCP file // Result_t -read_PCM_file(CommandOptions& Options) +read_PCM_file(CommandOptions& Options, const Kumu::IFileReaderFactory& fileReaderFactory) { AESDecContext* Context = 0; HMACContext* HMAC = 0; - AS_02::PCM::MXFReader Reader; + AS_02::PCM::MXFReader Reader(fileReaderFactory); PCM::FrameBuffer FrameBuffer; WavFileWriter OutWave; ui32_t last_frame = 0; ASDCP::MXF::WaveAudioDescriptor *wave_descriptor = 0; - if ( Options.edit_rate == Rational(0,0) ) // todo, make this available to the CLI + if ( Options.edit_rate == ASDCP::Rational(0,0) ) // todo, make this available to the CLI { Options.edit_rate = EditRate_24; } @@ -797,11 +798,11 @@ read_PCM_file(CommandOptions& Options) // Read one or more timed text streams from a plaintext AS-02 file // Result_t -read_timed_text_file(CommandOptions& Options) +read_timed_text_file(CommandOptions& Options, const Kumu::IFileReaderFactory& fileReaderFactory) { AESDecContext* Context = 0; HMACContext* HMAC = 0; - AS_02::TimedText::MXFReader Reader; + AS_02::TimedText::MXFReader Reader(fileReaderFactory); TimedText::FrameBuffer FrameBuffer(Options.fb_size); //ASDCP::TimedText::FrameBuffer FrameBuffer(Options.fb_size); AS_02::TimedText::TimedTextDescriptor TDesc; @@ -874,11 +875,11 @@ read_timed_text_file(CommandOptions& Options) // Result_t -read_isxd_file(CommandOptions& Options) +read_isxd_file(CommandOptions& Options, const Kumu::IFileReaderFactory& fileReaderFactory) { AESDecContext* Context = 0; HMACContext* HMAC = 0; - AS_02::ISXD::MXFReader Reader; + AS_02::ISXD::MXFReader Reader(fileReaderFactory); ASDCP::FrameBuffer FrameBuffer; ui32_t frame_count = 0; @@ -959,10 +960,10 @@ read_isxd_file(CommandOptions& Options) } Result_t -extract_generic_stream_partition_payload(const std::string& in_filename, const ui32_t sid, const std::string& out_filename) +extract_generic_stream_partition_payload(const std::string& in_filename, const ui32_t sid, const std::string& out_filename, const Kumu::IFileReaderFactory& fileReaderFactory) { ASDCP::FrameBuffer payload; - AS_02::ISXD::MXFReader reader; + AS_02::ISXD::MXFReader reader(fileReaderFactory); Result_t result = reader.OpenRead(in_filename); @@ -986,6 +987,119 @@ extract_generic_stream_partition_payload(const std::string& in_filename, const u return result; } +Result_t read_iab_file(CommandOptions& Options, const Kumu::IFileReaderFactory& fileReaderFactory) +{ + AESDecContext* Context = 0; + HMACContext* HMAC = 0; + AS_02::IAB::MXFReader Reader(fileReaderFactory); + ASDCP::FrameBuffer FrameBuffer; + + ui32_t last_frame = 0; + ASDCP::MXF::IABEssenceDescriptor *iab_descriptor = 0; + + Result_t result = Reader.OpenRead(Options.input_filename); + + if ( KM_SUCCESS(result) ) + { + if ( Options.verbose_flag ) + { + fprintf(stderr, "Frame Buffer size: %u\n", Options.fb_size); + } + + ASDCP::MXF::InterchangeObject* tmp_obj = 0; + + result = Reader.OP1aHeader().GetMDObjectByType(DefaultCompositeDict().ul(MDD_IABEssenceDescriptor), &tmp_obj); + + if ( KM_SUCCESS(result) ) + { + iab_descriptor = dynamic_cast<ASDCP::MXF::IABEssenceDescriptor*>(tmp_obj); + + if ( iab_descriptor == 0 ) + { + fprintf(stderr, "File does not contain an essence descriptor.\n"); + return RESULT_FAIL; + } + + if ( Options.verbose_flag ) + { + iab_descriptor->Dump(); + } + + if ( iab_descriptor->ContainerDuration.get() == 0 ) + { + fprintf(stderr, "ContainerDuration not set in file descriptor, attempting to use index duration.\n"); + Reader.GetFrameCount(last_frame); + } + else + { + last_frame = (ui32_t)iab_descriptor->ContainerDuration; + } + + if ( last_frame == 0 ) + { + fprintf(stderr, "ContainerDuration not set in index, attempting to use Duration from SourceClip.\n"); + result = Reader.OP1aHeader().GetMDObjectByType(DefaultCompositeDict().ul(MDD_SourceClip), &tmp_obj); + if ( KM_SUCCESS(result)) + { + ASDCP::MXF::SourceClip *sourceClip = dynamic_cast<ASDCP::MXF::SourceClip*>(tmp_obj); + if ( ! sourceClip->Duration.empty() ) + { + last_frame = (ui32_t)sourceClip->Duration; + } + } + } + + if ( last_frame == 0 ) + { + fprintf(stderr, "Unable to determine file duration.\n"); + return RESULT_FAIL; + } + + assert(iab_descriptor); + FrameBuffer.Capacity(24000); // TODO what size? + last_frame = (ui32_t)iab_descriptor->ContainerDuration; + } + } + + if ( ASDCP_SUCCESS(result) ) + { + if ( Options.duration > 0 && Options.duration < last_frame ) + last_frame = Options.duration; + + if ( Options.start_frame > 0 ) + { + if ( Options.start_frame > last_frame ) + { + fprintf(stderr, "Start value greater than file duration.\n"); + return RESULT_FAIL; + } + + last_frame = Kumu::xmin(Options.start_frame + last_frame, last_frame); + } + + last_frame = last_frame - Options.start_frame; + + + } + + for ( ui32_t i = Options.start_frame; ASDCP_SUCCESS(result) && i < last_frame; i++ ) + { + result = Reader.ReadFrame(i, FrameBuffer); + + if ( ASDCP_SUCCESS(result) ) + { + if ( Options.verbose_flag ) + { + FrameBuffer.FrameNumber(i); + fprintf(stdout, "Frame(%d):\n", i); + Kumu::hexdump(FrameBuffer.RoData(), Kumu::xmin(FrameBuffer.Size(), (ui32_t)Options.fb_dump_size), stdout); + } + } + } + + return result; +} + // int @@ -1009,39 +1123,44 @@ main(int argc, const char** argv) } EssenceType_t EssenceType; - Result_t result = ASDCP::EssenceType(Options.input_filename, EssenceType); + Kumu::FileReaderFactory defaultFactory; + Result_t result = ASDCP::EssenceType(Options.input_filename, EssenceType, defaultFactory); if ( ASDCP_SUCCESS(result) ) { switch ( EssenceType ) { case ESS_AS02_JPEG_2000: - result = read_JP2K_file(Options); + result = read_JP2K_file(Options, defaultFactory); break; //PB case ESS_AS02_ACES: - result = read_ACES_file(Options); + result = read_ACES_file(Options, defaultFactory); break; //-- case ESS_AS02_PCM_24b_48k: case ESS_AS02_PCM_24b_96k: - result = read_PCM_file(Options); + result = read_PCM_file(Options, defaultFactory); break; case ESS_AS02_TIMED_TEXT: - result = read_timed_text_file(Options); + result = read_timed_text_file(Options, defaultFactory); + break; + + case ESS_AS02_IAB: + result = read_iab_file(Options, defaultFactory); break; case ESS_AS02_ISXD: if ( Options.g_stream_sid == 0 ) { - result = read_isxd_file(Options); + result = read_isxd_file(Options, defaultFactory); } else { result = extract_generic_stream_partition_payload(Options.input_filename, Options.g_stream_sid, - Options.file_prefix); + Options.file_prefix, defaultFactory); } break; diff --git a/src/as-02-wrap.cpp b/src/as-02-wrap.cpp index 387d07d..8dba4ce 100755 --- a/src/as-02-wrap.cpp +++ b/src/as-02-wrap.cpp @@ -143,7 +143,7 @@ Options:\n\ All color system values assume YCbCr; also use -R for RGB\n\ -C <ul> - Set ChannelAssignment UL value\n\ -d <duration> - Number of frames to process, default all\n\ - -D <depth> - Component depth for YCbCr images (default: 10)\n\ + -D <depth> - Component depth for YCbCr or RGB images (default: 10)\n\ -e - Encrypt JP2K headers (default)\n\ -E - Do not encrypt JP2K headers\n\ -F (0|1) - Set field dominance for interlaced image (default: 0)\n\ @@ -155,6 +155,7 @@ Options:\n\ Stream. May be issued multiple times.\n\ -i - Indicates input essence is interlaced fields (forces -Y)\n\ -j <key-id-str> - Write key ID instead of creating a random value\n\ + -J - Write J2CLayout\n\ -k <key-string> - Use key for ciphertext operations\n\ -l <first>,<second>\n\ - Integer values that set the VideoLineMap\n\ @@ -273,6 +274,7 @@ public: bool help_flag; // true if the help display option was selected ui32_t duration; // number of frames to be processed bool j2c_pedantic; // passed to JP2K::SequenceParser::OpenRead + bool write_j2clayout; // true if a J2CLayout field should be written bool use_cdci_descriptor; // Rational edit_rate; // edit rate of JP2K sequence ui32_t fb_size; // size of picture frame buffer @@ -512,7 +514,7 @@ public: error_flag(true), key_flag(false), key_id_flag(false), asset_id_flag(false), encrypt_header_flag(true), write_hmac(true), verbose_flag(false), fb_dump_size(0), no_write_flag(false), version_flag(false), help_flag(false), - duration(0xffffffff), j2c_pedantic(true), use_cdci_descriptor(false), + duration(0xffffffff), j2c_pedantic(true), write_j2clayout(false), use_cdci_descriptor(false), edit_rate(24,1), fb_size(FRAME_BUFFER_SIZE), show_ul_values_flag(false), index_strategy(AS_02::IS_FOLLOW), partition_space(60), mca_config(g_dict), rgba_MaxRef(1023), rgba_MinRef(0), @@ -734,6 +736,8 @@ public: } break; + case 'J': write_j2clayout = true; break; + case 'k': key_flag = true; TEST_EXTRA_ARG(i, 'k'); { @@ -995,6 +999,7 @@ write_JP2K_file(CommandOptions& Options) JP2K::SequenceParser Parser; ASDCP::MXF::FileDescriptor *essence_descriptor = 0; ASDCP::MXF::InterchangeObject_list_t essence_sub_descriptors; + ASDCP::MXF::JPEG2000PictureSubDescriptor *jp2k_sub_descriptor = NULL; // set up essence parser Result_t result = Parser.OpenRead(Options.filenames.front().c_str(), Options.j2c_pedantic); @@ -1053,6 +1058,31 @@ write_JP2K_file(CommandOptions& Options) } essence_descriptor = static_cast<ASDCP::MXF::FileDescriptor*>(tmp_dscr); + + if (Options.write_j2clayout) + { + jp2k_sub_descriptor = static_cast<ASDCP::MXF::JPEG2000PictureSubDescriptor*>(essence_sub_descriptors.back()); + if (Options.component_depth == 16) + { + jp2k_sub_descriptor->J2CLayout = ASDCP::MXF::RGBALayout(ASDCP::MXF::RGBAValue_YUV_16); + } + else if (Options.component_depth == 12) + { + jp2k_sub_descriptor->J2CLayout = ASDCP::MXF::RGBALayout(ASDCP::MXF::RGBAValue_YUV_12); + } + else if (Options.component_depth == 10) + { + jp2k_sub_descriptor->J2CLayout = ASDCP::MXF::RGBALayout(ASDCP::MXF::RGBAValue_YUV_10); + } + else if (Options.component_depth == 8) + { + jp2k_sub_descriptor->J2CLayout = ASDCP::MXF::RGBALayout(ASDCP::MXF::RGBAValue_YUV_8); + } + else + { + fprintf(stderr, "Warning: could not determine J2CLayout to write.\n"); + } + } } } else @@ -1088,6 +1118,31 @@ write_JP2K_file(CommandOptions& Options) } essence_descriptor = static_cast<ASDCP::MXF::FileDescriptor*>(tmp_dscr); + + if (Options.write_j2clayout) + { + jp2k_sub_descriptor = static_cast<ASDCP::MXF::JPEG2000PictureSubDescriptor*>(essence_sub_descriptors.back()); + if (Options.component_depth == 16) + { + jp2k_sub_descriptor->J2CLayout = ASDCP::MXF::RGBALayout(ASDCP::MXF::RGBAValue_RGB_16); + } + else if (Options.component_depth == 12) + { + jp2k_sub_descriptor->J2CLayout = ASDCP::MXF::RGBALayout(ASDCP::MXF::RGBAValue_RGB_12); + } + else if (Options.component_depth == 10) + { + jp2k_sub_descriptor->J2CLayout = ASDCP::MXF::RGBALayout(ASDCP::MXF::RGBAValue_RGB_10); + } + else if (Options.component_depth == 8) + { + jp2k_sub_descriptor->J2CLayout = ASDCP::MXF::RGBALayout(ASDCP::MXF::RGBAValue_RGB_8); + } + else + { + fprintf(stderr, "Warning: could not determine J2CLayout to write.\n"); + } + } } } } @@ -1953,7 +2008,6 @@ int main(int argc, const char** argv) { Result_t result = RESULT_OK; - char str_buf[64]; g_dict = &ASDCP::DefaultSMPTEDict(); assert(g_dict); diff --git a/src/asdcp-info.cpp b/src/asdcp-info.cpp index b8876fe..f8a301c 100755 --- a/src/asdcp-info.cpp +++ b/src/asdcp-info.cpp @@ -309,7 +309,7 @@ class FileInfoWrapper KM_NO_COPY_CONSTRUCT(FileInfoWrapper); public: - FileInfoWrapper() : m_MaxBitrate(0.0), m_AvgBitrate(0.0) {} + FileInfoWrapper(const Kumu::IFileReaderFactory& fileReaderFactory) : m_MaxBitrate(0.0), m_AvgBitrate(0.0), m_Reader(fileReaderFactory) {} virtual ~FileInfoWrapper() {} Result_t @@ -532,17 +532,17 @@ public: // Read header metadata from an ASDCP file // Result_t -show_file_info(CommandOptions& Options) +show_file_info(CommandOptions& Options, const Kumu::IFileReaderFactory& fileReaderFactory) { EssenceType_t EssenceType; - Result_t result = ASDCP::EssenceType(Options.filenames.front().c_str(), EssenceType); + Result_t result = ASDCP::EssenceType(Options.filenames.front().c_str(), EssenceType, fileReaderFactory); if ( ASDCP_FAILURE(result) ) return result; if ( EssenceType == ESS_MPEG2_VES ) { - FileInfoWrapper<ASDCP::MPEG2::MXFReader, MyVideoDescriptor> wrapper; + FileInfoWrapper<ASDCP::MPEG2::MXFReader, MyVideoDescriptor> wrapper(fileReaderFactory); result = wrapper.file_info(Options, "MPEG2 video"); if ( ASDCP_SUCCESS(result) && Options.showrate_flag ) @@ -550,7 +550,7 @@ show_file_info(CommandOptions& Options) } else if ( EssenceType == ESS_PCM_24b_48k || EssenceType == ESS_PCM_24b_96k ) { - FileInfoWrapper<ASDCP::PCM::MXFReader, MyAudioDescriptor> wrapper; + FileInfoWrapper<ASDCP::PCM::MXFReader, MyAudioDescriptor> wrapper(fileReaderFactory); result = wrapper.file_info(Options, "PCM audio"); if ( ASDCP_SUCCESS(result) && Options.showcoding_flag ) @@ -560,7 +560,7 @@ show_file_info(CommandOptions& Options) { if ( Options.stereo_image_flag ) { - FileInfoWrapper<ASDCP::JP2K::MXFSReader, MyStereoPictureDescriptor> wrapper; + FileInfoWrapper<ASDCP::JP2K::MXFSReader, MyStereoPictureDescriptor> wrapper(fileReaderFactory); result = wrapper.file_info(Options, "JPEG 2000 stereoscopic pictures"); if ( KM_SUCCESS(result) ) @@ -579,7 +579,7 @@ show_file_info(CommandOptions& Options) } else { - FileInfoWrapper<ASDCP::JP2K::MXFReader, MyPictureDescriptor>wrapper; + FileInfoWrapper<ASDCP::JP2K::MXFReader, MyPictureDescriptor>wrapper(fileReaderFactory); result = wrapper.file_info(Options, "JPEG 2000 pictures"); if ( KM_SUCCESS(result) ) @@ -599,7 +599,7 @@ show_file_info(CommandOptions& Options) } else if ( EssenceType == ESS_JPEG_2000_S ) { - FileInfoWrapper<ASDCP::JP2K::MXFSReader, MyStereoPictureDescriptor>wrapper; + FileInfoWrapper<ASDCP::JP2K::MXFSReader, MyStereoPictureDescriptor>wrapper(fileReaderFactory); result = wrapper.file_info(Options, "JPEG 2000 stereoscopic pictures"); if ( KM_SUCCESS(result) ) @@ -618,17 +618,17 @@ show_file_info(CommandOptions& Options) } else if ( EssenceType == ESS_TIMED_TEXT ) { - FileInfoWrapper<ASDCP::TimedText::MXFReader, MyTextDescriptor>wrapper; + FileInfoWrapper<ASDCP::TimedText::MXFReader, MyTextDescriptor>wrapper(fileReaderFactory); result = wrapper.file_info(Options, "Timed Text"); } else if ( EssenceType == ESS_DCDATA_UNKNOWN ) { - FileInfoWrapper<ASDCP::DCData::MXFReader, MyDCDataDescriptor> wrapper; + FileInfoWrapper<ASDCP::DCData::MXFReader, MyDCDataDescriptor> wrapper(fileReaderFactory); result = wrapper.file_info(Options, "D-Cinema Generic Data"); } else if ( EssenceType == ESS_DCDATA_DOLBY_ATMOS ) { - FileInfoWrapper<ASDCP::ATMOS::MXFReader, MyAtmosDescriptor> wrapper; + FileInfoWrapper<ASDCP::ATMOS::MXFReader, MyAtmosDescriptor> wrapper(fileReaderFactory); result = wrapper.file_info(Options, "Dolby ATMOS"); } else if ( EssenceType == ESS_AS02_PCM_24b_48k @@ -641,14 +641,14 @@ show_file_info(CommandOptions& Options) else { fprintf(stderr, "File is not AS-DCP: %s\n", Options.filenames.front().c_str()); - Kumu::FileReader Reader; + Kumu::IFileReader* Reader = fileReaderFactory.CreateFileReader(); const Dictionary* Dict = &DefaultCompositeDict(); MXF::OP1aHeader TestHeader(Dict); - result = Reader.OpenRead(Options.filenames.front().c_str()); + result = Reader->OpenRead(Options.filenames.front().c_str()); if ( ASDCP_SUCCESS(result) ) - result = TestHeader.InitFromFile(Reader); // test UL and OP + result = TestHeader.InitFromFile(*Reader); // test UL and OP if ( ASDCP_SUCCESS(result) ) { @@ -668,6 +668,7 @@ show_file_info(CommandOptions& Options) { fputs("File is not MXF.\n", stdout); } + delete Reader; } return result; @@ -696,9 +697,10 @@ main(int argc, const char** argv) return 3; } + Kumu::FileReaderFactory defaultFactory; while ( ! Options.filenames.empty() && ASDCP_SUCCESS(result) ) { - result = show_file_info(Options); + result = show_file_info(Options, defaultFactory); Options.filenames.pop_front(); } diff --git a/src/asdcp-test.cpp b/src/asdcp-test.cpp index ecf6f21..3b25d88 100755 --- a/src/asdcp-test.cpp +++ b/src/asdcp-test.cpp @@ -670,11 +670,11 @@ write_MPEG2_file(CommandOptions& Options) // Read a ciphertext MPEG2 Video Elementary Stream from a ciphertext ASDCP file // Result_t -read_MPEG2_file(CommandOptions& Options) +read_MPEG2_file(CommandOptions& Options, const Kumu::IFileReaderFactory& fileReaderFactory) { AESDecContext* Context = 0; HMACContext* HMAC = 0; - MPEG2::MXFReader Reader; + MPEG2::MXFReader Reader(fileReaderFactory); MPEG2::FrameBuffer FrameBuffer(Options.fb_size); Kumu::FileWriter OutFile; ui32_t frame_count = 0; @@ -749,11 +749,11 @@ read_MPEG2_file(CommandOptions& Options) // Result_t -gop_start_test(CommandOptions& Options) +gop_start_test(CommandOptions& Options, const Kumu::IFileReaderFactory& fileReaderFactory) { using namespace ASDCP::MPEG2; - MXFReader Reader; + MXFReader Reader(fileReaderFactory); MPEG2::FrameBuffer FrameBuffer(Options.fb_size); ui32_t frame_count = 0; @@ -937,11 +937,11 @@ write_JP2K_S_file(CommandOptions& Options) // Read one or more plaintext JPEG 2000 stereoscopic codestream pairs from a ciphertext ASDCP file // Read one or more ciphertext JPEG 2000 stereoscopic codestream pairs from a ciphertext ASDCP file Result_t -read_JP2K_S_file(CommandOptions& Options) +read_JP2K_S_file(CommandOptions& Options, const Kumu::IFileReaderFactory& fileReaderFactory) { AESDecContext* Context = 0; HMACContext* HMAC = 0; - JP2K::MXFSReader Reader; + JP2K::MXFSReader Reader(fileReaderFactory); JP2K::FrameBuffer FrameBuffer(Options.fb_size); ui32_t frame_count = 0; @@ -1160,11 +1160,11 @@ write_JP2K_file(CommandOptions& Options) // Read one or more ciphertext JPEG 2000 codestreams from a ciphertext ASDCP file // Result_t -read_JP2K_file(CommandOptions& Options) +read_JP2K_file(CommandOptions& Options, const Kumu::IFileReaderFactory& fileReaderFactory) { AESDecContext* Context = 0; HMACContext* HMAC = 0; - JP2K::MXFReader Reader; + JP2K::MXFReader Reader(fileReaderFactory); JP2K::FrameBuffer FrameBuffer(Options.fb_size); ui32_t frame_count = 0; @@ -1382,11 +1382,11 @@ write_PCM_file(CommandOptions& Options) // Read one or more ciphertext PCM audio streams from a ciphertext ASDCP file // Result_t -read_PCM_file(CommandOptions& Options) +read_PCM_file(CommandOptions& Options, const Kumu::IFileReaderFactory& fileReaderFactory) { AESDecContext* Context = 0; HMACContext* HMAC = 0; - PCM::MXFReader Reader; + PCM::MXFReader Reader(fileReaderFactory); PCM::FrameBuffer FrameBuffer; WavFileWriter OutWave; PCM::AudioDescriptor ADesc; @@ -1607,11 +1607,11 @@ write_timed_text_file(CommandOptions& Options) // Read one or more timed text streams from a ciphertext ASDCP file // Result_t -read_timed_text_file(CommandOptions& Options) +read_timed_text_file(CommandOptions& Options, const Kumu::IFileReaderFactory& fileReaderFactory) { AESDecContext* Context = 0; HMACContext* HMAC = 0; - TimedText::MXFReader Reader; + TimedText::MXFReader Reader(fileReaderFactory); TimedText::FrameBuffer FrameBuffer; TimedText::TimedTextDescriptor TDesc; @@ -1766,7 +1766,7 @@ class FileInfoWrapper { public: static Result_t - file_info(CommandOptions& Options, const char* type_string, FILE* stream = 0) + file_info(CommandOptions& Options, const char* type_string, const Kumu::IFileReaderFactory& fileReaderFactory, FILE* stream = 0) { assert(type_string); if ( stream == 0 ) @@ -1776,7 +1776,7 @@ public: if ( Options.verbose_flag || Options.showheader_flag ) { - ReaderT Reader; + ReaderT Reader(fileReaderFactory); result = Reader.OpenRead(Options.filenames[0]); if ( ASDCP_SUCCESS(result) ) @@ -1810,26 +1810,26 @@ public: // Read header metadata from an ASDCP file // Result_t -show_file_info(CommandOptions& Options) +show_file_info(CommandOptions& Options, const Kumu::IFileReaderFactory& fileReaderFactory) { EssenceType_t EssenceType; - Result_t result = ASDCP::EssenceType(Options.filenames[0], EssenceType); + Result_t result = ASDCP::EssenceType(Options.filenames[0], EssenceType, fileReaderFactory); if ( ASDCP_FAILURE(result) ) return result; if ( EssenceType == ESS_MPEG2_VES ) { - result = FileInfoWrapper<ASDCP::MPEG2::MXFReader, MyVideoDescriptor>::file_info(Options, "MPEG2 video"); + result = FileInfoWrapper<ASDCP::MPEG2::MXFReader, MyVideoDescriptor>::file_info(Options, "MPEG2 video", fileReaderFactory); } else if ( EssenceType == ESS_PCM_24b_48k || EssenceType == ESS_PCM_24b_96k ) { - result = FileInfoWrapper<ASDCP::PCM::MXFReader, MyAudioDescriptor>::file_info(Options, "PCM audio"); + result = FileInfoWrapper<ASDCP::PCM::MXFReader, MyAudioDescriptor>::file_info(Options, "PCM audio", fileReaderFactory); if ( ASDCP_SUCCESS(result) ) { const Dictionary* Dict = &DefaultCompositeDict(); - PCM::MXFReader Reader; + PCM::MXFReader Reader(fileReaderFactory); MXF::OP1aHeader Header(Dict); MXF::WaveAudioDescriptor *descriptor = 0; @@ -1850,34 +1850,34 @@ show_file_info(CommandOptions& Options) if ( Options.stereo_image_flag ) { result = FileInfoWrapper<ASDCP::JP2K::MXFSReader, - MyStereoPictureDescriptor>::file_info(Options, "JPEG 2000 stereoscopic pictures"); + MyStereoPictureDescriptor>::file_info(Options, "JPEG 2000 stereoscopic pictures", fileReaderFactory); } else { result = FileInfoWrapper<ASDCP::JP2K::MXFReader, - MyPictureDescriptor>::file_info(Options, "JPEG 2000 pictures"); + MyPictureDescriptor>::file_info(Options, "JPEG 2000 pictures", fileReaderFactory); } } else if ( EssenceType == ESS_JPEG_2000_S ) { result = FileInfoWrapper<ASDCP::JP2K::MXFSReader, - MyStereoPictureDescriptor>::file_info(Options, "JPEG 2000 stereoscopic pictures"); + MyStereoPictureDescriptor>::file_info(Options, "JPEG 2000 stereoscopic pictures", fileReaderFactory); } else if ( EssenceType == ESS_TIMED_TEXT ) { - result = FileInfoWrapper<ASDCP::TimedText::MXFReader, MyTextDescriptor>::file_info(Options, "Timed Text"); + result = FileInfoWrapper<ASDCP::TimedText::MXFReader, MyTextDescriptor>::file_info(Options, "Timed Text", fileReaderFactory); } else { - fprintf(stderr, "File is not AS-DCP: %s\n", Options.filenames[0]); - Kumu::FileReader Reader; + fprintf(stderr, "File is not AS-DCP: %s\n", Options.filenames[0]); + ASDCP::mem_ptr<Kumu::IFileReader> Reader(fileReaderFactory.CreateFileReader()); const Dictionary* Dict = &DefaultCompositeDict(); MXF::OP1aHeader TestHeader(Dict); - result = Reader.OpenRead(Options.filenames[0]); + result = Reader->OpenRead(Options.filenames[0]); if ( ASDCP_SUCCESS(result) ) - result = TestHeader.InitFromFile(Reader); // test UL and OP + result = TestHeader.InitFromFile(*Reader); // test UL and OP if ( ASDCP_SUCCESS(result) ) { @@ -1967,19 +1967,21 @@ main(int argc, const char** argv) return 3; } + Kumu::FileReaderFactory defaultFactory; + if ( Options.mode == MMT_INFO ) { - result = show_file_info(Options); + result = show_file_info(Options, defaultFactory); for ( int i = 1; ASDCP_SUCCESS(result) && i < Options.file_count; ++i ) { Options.filenames[0] = Options.filenames[i]; // oh-so hackish - result = show_file_info(Options); + result = show_file_info(Options, defaultFactory); } } else if ( Options.mode == MMT_GOP_START ) { - result = gop_start_test(Options); + result = gop_start_test(Options, defaultFactory); } else if ( Options.mode == MMT_GEN_KEY ) { @@ -2008,37 +2010,37 @@ main(int argc, const char** argv) else if ( Options.mode == MMT_EXTRACT ) { EssenceType_t EssenceType; - result = ASDCP::EssenceType(Options.filenames[0], EssenceType); + result = ASDCP::EssenceType(Options.filenames[0], EssenceType, defaultFactory); if ( ASDCP_SUCCESS(result) ) { switch ( EssenceType ) { case ESS_MPEG2_VES: - result = read_MPEG2_file(Options); + result = read_MPEG2_file(Options, defaultFactory); break; case ESS_JPEG_2000: if ( Options.stereo_image_flag ) - result = read_JP2K_S_file(Options); + result = read_JP2K_S_file(Options, defaultFactory); else - result = read_JP2K_file(Options); + result = read_JP2K_file(Options, defaultFactory); break; case ESS_JPEG_2000_S: - result = read_JP2K_S_file(Options); + result = read_JP2K_S_file(Options, defaultFactory); break; case ESS_PCM_24b_48k: case ESS_PCM_24b_96k: - result = read_PCM_file(Options); + result = read_PCM_file(Options, defaultFactory); break; case ESS_TIMED_TEXT: - result = read_timed_text_file(Options); + result = read_timed_text_file(Options, defaultFactory); break; - default: + default: fprintf(stderr, "%s: Unknown file type, not ASDCP essence.\n", Options.filenames[0]); return 5; } diff --git a/src/asdcp-unwrap.cpp b/src/asdcp-unwrap.cpp index 7b607d9..bddc4ee 100755 --- a/src/asdcp-unwrap.cpp +++ b/src/asdcp-unwrap.cpp @@ -325,11 +325,11 @@ public: // Read a ciphertext MPEG2 Video Elementary Stream from a ciphertext ASDCP file // Result_t -read_MPEG2_file(CommandOptions& Options) +read_MPEG2_file(CommandOptions& Options, const Kumu::IFileReaderFactory& fileReaderFactory) { AESDecContext* Context = 0; HMACContext* HMAC = 0; - MPEG2::MXFReader Reader; + MPEG2::MXFReader Reader(fileReaderFactory); MPEG2::FrameBuffer FrameBuffer(Options.fb_size); Kumu::FileWriter OutFile; ui32_t frame_count = 0; @@ -407,11 +407,11 @@ read_MPEG2_file(CommandOptions& Options) // Result_t -gop_start_test(CommandOptions& Options) +gop_start_test(CommandOptions& Options, const Kumu::IFileReaderFactory& fileReaderFactory) { using namespace ASDCP::MPEG2; - MXFReader Reader; + MXFReader Reader(fileReaderFactory); MPEG2::FrameBuffer FrameBuffer(Options.fb_size); ui32_t frame_count = 0; @@ -461,11 +461,11 @@ gop_start_test(CommandOptions& Options) // Read one or more plaintext JPEG 2000 stereoscopic codestream pairs from a ciphertext ASDCP file // Read one or more ciphertext JPEG 2000 stereoscopic codestream pairs from a ciphertext ASDCP file Result_t -read_JP2K_S_file(CommandOptions& Options) +read_JP2K_S_file(CommandOptions& Options, const Kumu::IFileReaderFactory& fileReaderFactory) { AESDecContext* Context = 0; HMACContext* HMAC = 0; - JP2K::MXFSReader Reader; + JP2K::MXFSReader Reader(fileReaderFactory); JP2K::FrameBuffer FrameBuffer(Options.fb_size); ui32_t frame_count = 0; @@ -569,11 +569,11 @@ read_JP2K_S_file(CommandOptions& Options) // Read one or more ciphertext JPEG 2000 codestreams from a ciphertext ASDCP file // Result_t -read_JP2K_file(CommandOptions& Options) +read_JP2K_file(CommandOptions& Options, const Kumu::IFileReaderFactory& fileReaderFactory) { AESDecContext* Context = 0; HMACContext* HMAC = 0; - JP2K::MXFReader Reader; + JP2K::MXFReader Reader(fileReaderFactory); JP2K::FrameBuffer FrameBuffer(Options.fb_size); ui32_t frame_count = 0; @@ -658,11 +658,11 @@ read_JP2K_file(CommandOptions& Options) // Read one or more ciphertext PCM audio streams from a ciphertext ASDCP file // Result_t -read_PCM_file(CommandOptions& Options) +read_PCM_file(CommandOptions& Options, const Kumu::IFileReaderFactory& fileReaderFactory) { AESDecContext* Context = 0; HMACContext* HMAC = 0; - PCM::MXFReader Reader; + PCM::MXFReader Reader(fileReaderFactory); PCM::FrameBuffer FrameBuffer; WavFileWriter OutWave; PCM::AudioDescriptor ADesc; @@ -779,11 +779,11 @@ read_PCM_file(CommandOptions& Options) // Read one or more timed text streams from a ciphertext ASDCP file // Result_t -read_timed_text_file(CommandOptions& Options) +read_timed_text_file(CommandOptions& Options, const Kumu::IFileReaderFactory& fileReaderFactory) { AESDecContext* Context = 0; HMACContext* HMAC = 0; - TimedText::MXFReader Reader; + TimedText::MXFReader Reader(fileReaderFactory); TimedText::FrameBuffer FrameBuffer; TimedText::TimedTextDescriptor TDesc; @@ -867,11 +867,11 @@ read_timed_text_file(CommandOptions& Options) // Read one or more ciphertext DCData byestreams from a ciphertext ASDCP file // Result_t -read_DCData_file(CommandOptions& Options) +read_DCData_file(CommandOptions& Options, const Kumu::IFileReaderFactory& fileReaderFactory) { AESDecContext* Context = 0; HMACContext* HMAC = 0; - DCData::MXFReader Reader; + DCData::MXFReader Reader(fileReaderFactory); DCData::FrameBuffer FrameBuffer(Options.fb_size); ui32_t frame_count = 0; @@ -953,7 +953,6 @@ int main(int argc, const char** argv) { Result_t result = RESULT_OK; - char str_buf[64]; CommandOptions Options(argc, argv); if ( Options.version_flag ) @@ -971,50 +970,52 @@ main(int argc, const char** argv) return 3; } + Kumu::FileReaderFactory defaultFactory; + if ( Options.mode == MMT_GOP_START ) { - result = gop_start_test(Options); + result = gop_start_test(Options, defaultFactory); } else if ( Options.mode == MMT_EXTRACT ) { EssenceType_t EssenceType; - result = ASDCP::EssenceType(Options.input_filename, EssenceType); + result = ASDCP::EssenceType(Options.input_filename, EssenceType, defaultFactory); if ( ASDCP_SUCCESS(result) ) { switch ( EssenceType ) { case ESS_MPEG2_VES: - result = read_MPEG2_file(Options); + result = read_MPEG2_file(Options, defaultFactory); break; case ESS_JPEG_2000: if ( Options.stereo_image_flag ) - result = read_JP2K_S_file(Options); + result = read_JP2K_S_file(Options, defaultFactory); else - result = read_JP2K_file(Options); + result = read_JP2K_file(Options, defaultFactory); break; case ESS_JPEG_2000_S: - result = read_JP2K_S_file(Options); + result = read_JP2K_S_file(Options, defaultFactory); break; case ESS_PCM_24b_48k: case ESS_PCM_24b_96k: - result = read_PCM_file(Options); + result = read_PCM_file(Options, defaultFactory); break; case ESS_TIMED_TEXT: - result = read_timed_text_file(Options); + result = read_timed_text_file(Options, defaultFactory); break; case ESS_DCDATA_UNKNOWN: - result = read_DCData_file(Options); + result = read_DCData_file(Options, defaultFactory); break; case ESS_DCDATA_DOLBY_ATMOS: Options.extension = "atmos"; - result = read_DCData_file(Options); + result = read_DCData_file(Options, defaultFactory); break; default: diff --git a/src/h__02_Reader.cpp b/src/h__02_Reader.cpp index ff4af7c..17c5871 100644 --- a/src/h__02_Reader.cpp +++ b/src/h__02_Reader.cpp @@ -72,7 +72,7 @@ AS_02::MXF::AS02IndexReader::~AS02IndexReader() {} // Result_t -AS_02::MXF::AS02IndexReader::InitFromFile(const Kumu::FileReader& reader, const ASDCP::MXF::RIP& rip, const bool has_header_essence) +AS_02::MXF::AS02IndexReader::InitFromFile(const Kumu::IFileReader& reader, const ASDCP::MXF::RIP& rip, const bool has_header_essence) { typedef std::list<Kumu::mem_ptr<ASDCP::MXF::Partition> > body_part_array_t; body_part_array_t body_part_array; @@ -395,8 +395,7 @@ AS_02::MXF::AS02IndexReader::Lookup(ui32_t frame_num, ASDCP::MXF::IndexTableSegm // -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(const ASDCP::Dictionary *d, const Kumu::IFileReaderFactory& fileReaderFactory) : ASDCP::MXF::TrackFileReader<ASDCP::MXF::OP1aHeader, AS_02::MXF::AS02IndexReader>(d, fileReaderFactory) {} AS_02::h__AS02Reader::~h__AS02Reader() {} @@ -478,7 +477,7 @@ AS_02::h__AS02Reader::OpenMXFRead(const std::string& filename) if ( KM_SUCCESS(result) ) { m_IndexAccess.m_Lookup = &m_HeaderPart.m_Primer; - result = m_IndexAccess.InitFromFile(m_File, m_RIP, has_header_essence); + result = m_IndexAccess.InitFromFile(*m_File, m_RIP, has_header_essence); } return result; diff --git a/src/h__02_Writer.cpp b/src/h__02_Writer.cpp index e35727e..07d4ec2 100644 --- a/src/h__02_Writer.cpp +++ b/src/h__02_Writer.cpp @@ -221,7 +221,7 @@ AS_02::h__AS02WriterFrame::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf,co body_part.BodySID = 1; body_part.OperationalPattern = m_HeaderPart.OperationalPattern; body_part.EssenceContainers = m_HeaderPart.EssenceContainers; - body_part.ThisPartition = m_File.Tell(); + body_part.ThisPartition = m_File.TellPosition(); body_part.BodyOffset = m_StreamOffset; result = body_part.WriteToFile(m_File, body_ul); @@ -309,89 +309,3 @@ AS_02::MXF::AS02IndexWriterCBR::SetEditRate(const ASDCP::Rational& edit_rate, co //------------------------------------------------------------------------------------------ // - -// -AS_02::h__AS02WriterClip::h__AS02WriterClip(const ASDCP::Dictionary* d) : - h__AS02Writer<AS_02::MXF::AS02IndexWriterCBR>(d), - m_ECStart(0), m_ClipStart(0), m_IndexStrategy(AS_02::IS_FOLLOW) {} - -AS_02::h__AS02WriterClip::~h__AS02WriterClip() {} - -// -bool -AS_02::h__AS02WriterClip::HasOpenClip() const -{ - return m_ClipStart != 0; -} - -// -Result_t -AS_02::h__AS02WriterClip::StartClip(const byte_t* EssenceUL, AESEncContext* Ctx, HMACContext*) -{ - if ( Ctx != 0 ) - { - DefaultLogSink().Error("Encryption not yet supported for PCM clip-wrap.\n"); - return RESULT_STATE; - } - - if ( m_ClipStart != 0 ) - { - DefaultLogSink().Error("Cannot open clip, clip already open.\n"); - return RESULT_STATE; - } - - m_ClipStart = m_File.Tell(); - byte_t clip_buffer[24] = {0}; - memcpy(clip_buffer, EssenceUL, 16); - bool check = Kumu::write_BER(clip_buffer+16, 0, 8); - assert(check); - return m_File.Write(clip_buffer, 24); -} - -// -Result_t -AS_02::h__AS02WriterClip::WriteClipBlock(const ASDCP::FrameBuffer& FrameBuf) -{ - if ( m_ClipStart == 0 ) - { - DefaultLogSink().Error("Cannot write clip block, no clip open.\n"); - return RESULT_STATE; - } - - return m_File.Write(FrameBuf.RoData(), FrameBuf.Size()); -} - -// -Result_t -AS_02::h__AS02WriterClip::FinalizeClip(ui32_t bytes_per_frame) -{ - if ( m_ClipStart == 0 ) - { - DefaultLogSink().Error("Cannot close clip, clip not open.\n"); - return RESULT_STATE; - } - - ui64_t current_position = m_File.Tell(); - Result_t result = m_File.Seek(m_ClipStart+16); - - if ( KM_SUCCESS(result) ) - { - byte_t clip_buffer[8] = {0}; - ui64_t size = static_cast<ui64_t>(m_FramesWritten) * bytes_per_frame; - bool check = Kumu::write_BER(clip_buffer, size, 8); - assert(check); - result = m_File.Write(clip_buffer, 8); - } - - if ( KM_SUCCESS(result) ) - { - result = m_File.Seek(current_position); - m_ClipStart = 0; - } - - return result; -} - -// -// end h__02_Writer.cpp -// diff --git a/src/h__Reader.cpp b/src/h__Reader.cpp index ce2abf6..26ceb4a 100755 --- a/src/h__Reader.cpp +++ b/src/h__Reader.cpp @@ -64,8 +64,7 @@ ASDCP::default_md_object_init() // // -ASDCP::h__ASDCPReader::h__ASDCPReader(const Dictionary *d) : - MXF::TrackFileReader<OP1aHeader, OPAtomIndexFooter>(d), m_BodyPart(d) {} +ASDCP::h__ASDCPReader::h__ASDCPReader(const Dictionary *d, const Kumu::IFileReaderFactory& fileReaderFactory) : MXF::TrackFileReader<OP1aHeader, OPAtomIndexFooter>(d, fileReaderFactory), m_BodyPart(m_Dict) {} ASDCP::h__ASDCPReader::~h__ASDCPReader() {} @@ -127,8 +126,8 @@ ASDCP::h__ASDCPReader::OpenMXFRead(const std::string& filename) // partition and read the partition pack RIP::const_pair_iterator r_i = m_RIP.PairArray.begin(); r_i++; - m_File.Seek((*r_i).ByteOffset); - result = m_BodyPart.InitFromFile(m_File); + m_File->Seek((*r_i).ByteOffset); + result = m_BodyPart.InitFromFile(*m_File); if( ASDCP_FAILURE(result) ) { @@ -142,18 +141,18 @@ ASDCP::h__ASDCPReader::OpenMXFRead(const std::string& filename) // this position will be at either // a) the spot in the header partition where essence units appear, or // b) right after the body partition header (where essence units appear) - m_HeaderPart.BodyOffset = m_File.Tell(); + m_HeaderPart.BodyOffset = m_File->TellPosition(); - result = m_File.Seek(m_HeaderPart.FooterPartition); + 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); + result = m_IndexAccess.InitFromFile(*m_File); } } - m_File.Seek(m_HeaderPart.BodyOffset); + m_File->Seek(m_HeaderPart.BodyOffset); return result; } @@ -181,7 +180,7 @@ ASDCP::h__ASDCPReader::LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, // Result_t -ASDCP::KLReader::ReadKLFromFile(Kumu::FileReader& Reader) +ASDCP::KLReader::ReadKLFromFile(Kumu::IFileReader& Reader) { ui32_t read_count; ui32_t header_length = SMPTE_UL_LENGTH + MXF_BER_LENGTH; @@ -241,7 +240,7 @@ ASDCP::KLReader::ReadKLFromFile(Kumu::FileReader& Reader) // base subroutine for reading a KLV packet, assumes file position is at the first byte of the packet Result_t -ASDCP::Read_EKLV_Packet(Kumu::FileReader& File, const ASDCP::Dictionary& Dict, +ASDCP::Read_EKLV_Packet(Kumu::IFileReader& File, const ASDCP::Dictionary& Dict, const ASDCP::WriterInfo& Info, Kumu::fpos_t& LastPosition, ASDCP::FrameBuffer& CtFrameBuf, ui32_t FrameNum, ui32_t SequenceNum, ASDCP::FrameBuffer& FrameBuf, const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC) @@ -358,6 +357,7 @@ ASDCP::Read_EKLV_Packet(Kumu::FileReader& File, const ASDCP::Dictionary& Dict, return RESULT_FORMAT; } +#ifdef HAVE_OPENSSL if ( Ctx ) { // wrap the pointer and length as a FrameBuffer for use by @@ -379,7 +379,8 @@ ASDCP::Read_EKLV_Packet(Kumu::FileReader& File, const ASDCP::Dictionary& Dict, } } else // return ciphertext to caller - { +#endif //HAVE_OPENSSL + { if ( FrameBuf.Capacity() < tmp_len ) { char intbuf[IntBufferLen]; diff --git a/src/h__Writer.cpp b/src/h__Writer.cpp index 5f836fe..b36af64 100755 --- a/src/h__Writer.cpp +++ b/src/h__Writer.cpp @@ -102,7 +102,9 @@ id_batch_contains(const Array<Kumu::UUID>& batch, const Kumu::UUID& value) // Result_t ASDCP::AddDmsTrackGenericPartUtf8Text(Kumu::FileWriter& file_writer, MXF::OP1aHeader& header_part, - SourcePackage& source_package, MXF::RIP& rip, const Dictionary* Dict) + SourcePackage& source_package, MXF::RIP& rip, const Dictionary* Dict, + const std::string& trackDescription, const std::string& dataDescription, + std::list<ui64_t*>& durationUpdateList) { Sequence* Sequence_obj = 0; InterchangeObject* tmp_iobj = 0; @@ -121,6 +123,8 @@ ASDCP::AddDmsTrackGenericPartUtf8Text(Kumu::FileWriter& file_writer, MXF::OP1aHe StaticTrack *StaticTrack_obj = 0; header_part.GetMDObjectsByType(Dict->ul(MDD_StaticTrack), object_list); std::list<InterchangeObject*>::iterator j; + // start with 2 because there one other track in Material Package: Audio Essence track + ui32_t newTrackId = 2; for ( j = object_list.begin(); j != object_list.end(); ++j ) { StaticTrack_obj = dynamic_cast<StaticTrack*>(*j); @@ -128,8 +132,13 @@ ASDCP::AddDmsTrackGenericPartUtf8Text(Kumu::FileWriter& file_writer, MXF::OP1aHe if ( id_batch_contains(SourcePackage_obj->Tracks, StaticTrack_obj->InstanceUID) && StaticTrack_obj->TrackName.get() == rp2057_static_track_label ) { - break; + newTrackId = StaticTrack_obj->TrackID; + break; } + if (StaticTrack_obj->TrackID >= newTrackId) + { + newTrackId = StaticTrack_obj->TrackID + 1; + } StaticTrack_obj = 0; } @@ -157,13 +166,15 @@ ASDCP::AddDmsTrackGenericPartUtf8Text(Kumu::FileWriter& file_writer, MXF::OP1aHe StaticTrack* static_track = new StaticTrack(Dict); header_part.AddChildObject(static_track); source_package.Tracks.push_back(static_track->InstanceUID); - static_track->TrackName = "Descriptive Track"; - static_track->TrackID = 4; + static_track->TrackName = trackDescription; + static_track->TrackID = newTrackId; Sequence_obj = new Sequence(Dict); header_part.AddChildObject(Sequence_obj); static_track->Sequence = Sequence_obj->InstanceUID; Sequence_obj->DataDefinition = UL(Dict->ul(MDD_DescriptiveMetaDataDef)); + Sequence_obj->Duration.set_has_value(); + durationUpdateList.push_back(&Sequence_obj->Duration.get()); header_part.m_Preface->DMSchemes.push_back(UL(Dict->ul(MDD_MXFTextBasedFramework))); } @@ -174,6 +185,11 @@ ASDCP::AddDmsTrackGenericPartUtf8Text(Kumu::FileWriter& file_writer, MXF::OP1aHe Sequence_obj->StructuralComponents.push_back(Segment->InstanceUID); Segment->EventComment = rp2057_static_track_label; Segment->DataDefinition = UL(Dict->ul(MDD_DescriptiveMetaDataDef)); + if (!Segment->Duration.empty()) + { + durationUpdateList.push_back(&Segment->Duration.get()); + } + // TextBasedDMFramework *dmf_obj = new TextBasedDMFramework(Dict); @@ -200,7 +216,7 @@ ASDCP::AddDmsTrackGenericPartUtf8Text(Kumu::FileWriter& file_writer, MXF::OP1aHe return RESULT_FORMAT; } - rip.PairArray.push_back(RIP::PartitionPair(max_sid + 1, file_writer.Tell())); + rip.PairArray.push_back(RIP::PartitionPair(max_sid + 1, file_writer.TellPosition())); // Add new GSTBS linked to DMF GenericStreamTextBasedSet *gst_obj = new GenericStreamTextBasedSet(Dict); @@ -208,6 +224,7 @@ ASDCP::AddDmsTrackGenericPartUtf8Text(Kumu::FileWriter& file_writer, MXF::OP1aHe gst_obj->InstanceUID = dmf_obj->ObjectRef; gst_obj->GenericStreamSID = max_sid + 1; gst_obj->PayloadSchemeID = UL(Dict->ul(MDD_MXFTextBasedFramework)); + gst_obj->TextDataDescription = dataDescription; return RESULT_OK; } @@ -231,7 +248,7 @@ ASDCP::h__ASDCPWriter::CreateBodyPart(const MXF::Rational& EditRate, ui32_t Byte { // Body Partition m_BodyPart.EssenceContainers = m_HeaderPart.EssenceContainers; - m_BodyPart.ThisPartition = m_File.Tell(); + m_BodyPart.ThisPartition = m_File.TellPosition(); m_BodyPart.BodySID = 1; UL OPAtomUL(m_Dict->ul(MDD_OPAtom)); m_BodyPart.OperationalPattern = OPAtomUL; @@ -248,7 +265,7 @@ ASDCP::h__ASDCPWriter::CreateBodyPart(const MXF::Rational& EditRate, ui32_t Byte if ( ASDCP_SUCCESS(result) ) { // Index setup - Kumu::fpos_t ECoffset = m_File.Tell(); + Kumu::fpos_t ECoffset = m_File.TellPosition(); m_FooterPart.IndexSID = 129; if ( BytesPerEditUnit == 0 ) @@ -326,7 +343,7 @@ ASDCP::h__ASDCPWriter::WriteASDCPFooter() m_EssenceDescriptor->ContainerDuration = m_FramesWritten; m_FooterPart.PreviousPartition = m_RIP.PairArray.back().ByteOffset; - Kumu::fpos_t here = m_File.Tell(); + Kumu::fpos_t here = m_File.TellPosition(); m_RIP.PairArray.push_back(RIP::PartitionPair(0, here)); // Last RIP Entry m_HeaderPart.FooterPartition = here; @@ -392,6 +409,9 @@ ASDCP::Write_EKLV_Packet(Kumu::FileWriter& File, const ASDCP::Dictionary& Dict, if ( Info.EncryptedEssence ) { + #ifndef HAVE_OPENSSL + return RESULT_CRYPT_CTX; + #else if ( ! Ctx ) return RESULT_CRYPT_CTX; @@ -479,6 +499,7 @@ ASDCP::Write_EKLV_Packet(Kumu::FileWriter& File, const ASDCP::Dictionary& Dict, result = File.Writev(HMACOverhead.Data(), HMACOverhead.Length()); StreamOffset += HMACOverhead.Length(); } +#endif //HAVE_OPENSSL } else { diff --git a/src/klvwalk.cpp b/src/klvwalk.cpp index 90b719b..1ba9908 100755 --- a/src/klvwalk.cpp +++ b/src/klvwalk.cpp @@ -188,28 +188,29 @@ main(int argc, const char** argv) FileList_t::iterator fi; Result_t result = RESULT_OK; + Kumu::FileReaderFactory defaultFactory; for ( fi = Options.inFileList.begin(); ASDCP_SUCCESS(result) && fi != Options.inFileList.end(); fi++ ) { + ASDCP::mem_ptr<Kumu::IFileReader> Reader(defaultFactory.CreateFileReader()); if (Options.verbose_flag) fprintf(stderr, "Opening file %s\n", ((*fi).c_str())); if ( Options.read_mxf_flag ) // dump MXF - { - Kumu::FileReader Reader; + { const Dictionary* Dict = &DefaultCompositeDict(); ASDCP::MXF::OP1aHeader Header(Dict); ASDCP::MXF::RIP RIP(Dict); - result = Reader.OpenRead(*fi); + result = Reader->OpenRead(*fi); if ( ASDCP_SUCCESS(result) ) { - result = MXF::SeekToRIP(Reader); + result = MXF::SeekToRIP(*Reader); if ( ASDCP_SUCCESS(result) ) { - result = RIP.InitFromFile(Reader); + result = RIP.InitFromFile(*Reader); ui32_t test_s = RIP.PairArray.size(); if ( ASDCP_FAILURE(result) ) @@ -222,7 +223,7 @@ main(int argc, const char** argv) DefaultLogSink().Error("RIP contains no Pairs.\n"); } - Reader.Seek(0); + Reader->Seek(0); } else { @@ -231,7 +232,7 @@ main(int argc, const char** argv) } if ( ASDCP_SUCCESS(result) ) - result = Header.InitFromFile(Reader); + result = Header.InitFromFile(*Reader); if ( ASDCP_SUCCESS(result) ) Header.Dump(stdout); @@ -242,12 +243,12 @@ main(int argc, const char** argv) for ( pi++; pi != RIP.PairArray.end() && ASDCP_SUCCESS(result); pi++ ) { - result = Reader.Seek((*pi).ByteOffset); + result = Reader->Seek((*pi).ByteOffset); if ( ASDCP_SUCCESS(result) ) { MXF::Partition TmpPart(Dict); - result = TmpPart.InitFromFile(Reader); + result = TmpPart.InitFromFile(*Reader); if ( ASDCP_SUCCESS(result) && TmpPart.BodySID > 0 ) TmpPart.Dump(stdout); @@ -258,12 +259,12 @@ main(int argc, const char** argv) if ( ASDCP_SUCCESS(result) ) { ASDCP::MXF::OPAtomIndexFooter Index(Dict); - result = Reader.Seek(Header.FooterPartition); + result = Reader->Seek(Header.FooterPartition); if ( ASDCP_SUCCESS(result) ) { Index.m_Lookup = &Header.m_Primer; - result = Index.InitFromFile(Reader); + result = Index.InitFromFile(*Reader); } if ( ASDCP_SUCCESS(result) ) @@ -275,19 +276,18 @@ main(int argc, const char** argv) } else if ( Options.walk_parts_flag ) { - Kumu::FileReader Reader; const Dictionary* Dict = &DefaultCompositeDict(); ASDCP::MXF::OP1aHeader Header(Dict); ASDCP::MXF::RIP RIP(Dict); - result = Reader.OpenRead((*fi).c_str()); + result = Reader->OpenRead((*fi).c_str()); if ( ASDCP_SUCCESS(result) ) - result = MXF::SeekToRIP(Reader); + result = MXF::SeekToRIP(*Reader); if ( ASDCP_SUCCESS(result) ) { - result = RIP.InitFromFile(Reader); + result = RIP.InitFromFile(*Reader); ui32_t test_s = RIP.PairArray.size(); if ( ASDCP_FAILURE(result) ) @@ -300,7 +300,7 @@ main(int argc, const char** argv) DefaultLogSink().Error("RIP contains no Pairs.\n"); } - Reader.Seek(0); + Reader->Seek(0); } else { @@ -314,9 +314,9 @@ main(int argc, const char** argv) MXF::RIP::const_pair_iterator i; for ( i = RIP.PairArray.begin(); i != RIP.PairArray.end(); ++i ) { - Reader.Seek(i->ByteOffset); + Reader->Seek(i->ByteOffset); MXF::Partition plain_part(Dict); - plain_part.InitFromFile(Reader); + plain_part.InitFromFile(*Reader); if ( plain_part.ThisPartition != i->ByteOffset ) { @@ -329,22 +329,21 @@ main(int argc, const char** argv) } } else // dump klv - { - Kumu::FileReader Reader; + { KLVFilePacket KP; ui64_t pos = 0; - result = Reader.OpenRead((*fi).c_str()); + result = Reader->OpenRead((*fi).c_str()); if ( ASDCP_SUCCESS(result) ) - result = KP.InitFromFile(Reader); + result = KP.InitFromFile(*Reader); while ( ASDCP_SUCCESS(result) ) { fprintf(stdout, "@0x%08llx: ", pos); KP.Dump(stdout, DefaultCompositeDict(), true); - pos = Reader.Tell(); - result = KP.InitFromFile(Reader); + pos = Reader->TellPosition(); + result = KP.InitFromFile(*Reader); } if( result == RESULT_ENDOFFILE ) diff --git a/src/phdr-unwrap.cpp b/src/phdr-unwrap.cpp index be62110..25ce9d0 100755 --- a/src/phdr-unwrap.cpp +++ b/src/phdr-unwrap.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2011-2018, John Hurst +Copyright (c) 2011-2021, John Hurst All rights reserved. @@ -43,7 +43,7 @@ const ui32_t FRAME_BUFFER_SIZE = 4 * Kumu::Megabyte; // // command line option parser class -static const char* PROGRAM_NAME = "as-02-unwrap"; // program name for messages +static const char* PROGRAM_NAME = "phdr-unwrap"; // program name for messages // Increment the iterator, test for an additional non-option command line argument. // Causes the caller to return if there are no remaining arguments or if the next @@ -60,7 +60,7 @@ banner(FILE* stream = stdout) { fprintf(stream, "\n\ %s (asdcplib %s)\n\n\ -Copyright (c) 2011-2018, John Hurst\n\n\ +Copyright (c) 2011-2021, John Hurst\n\n\ asdcplib may be copied only under the terms of the license found at\n\ the top of every file in the asdcplib distribution kit.\n\n\ Specify the -h (help) option for further information about %s\n\n", @@ -252,11 +252,11 @@ public: // Read one or more ciphertext JPEG 2000 codestreams from a ciphertext P-HDR file // Result_t -read_JP2K_file(CommandOptions& Options) +read_JP2K_file(CommandOptions& Options, const Kumu::IFileReaderFactory& fileReaderFactory) { AESDecContext* Context = 0; HMACContext* HMAC = 0; - AS_02::PHDR::MXFReader Reader; + AS_02::PHDR::MXFReader Reader(fileReaderFactory); AS_02::PHDR::FrameBuffer FrameBuffer(Options.fb_size); ui32_t frame_count = 0; @@ -418,14 +418,15 @@ main(int argc, const char** argv) } EssenceType_t EssenceType; - Result_t result = ASDCP::EssenceType(Options.input_filename, EssenceType); + Kumu::FileReaderFactory defaultFactory; + Result_t result = ASDCP::EssenceType(Options.input_filename, EssenceType, defaultFactory); if ( ASDCP_SUCCESS(result) ) { switch ( EssenceType ) { case ESS_AS02_JPEG_2000: - result = read_JP2K_file(Options); + result = read_JP2K_file(Options, defaultFactory); break; default: diff --git a/src/phdr-wrap.cpp b/src/phdr-wrap.cpp index 1632508..6880c92 100755 --- a/src/phdr-wrap.cpp +++ b/src/phdr-wrap.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2011-2018, John Hurst +Copyright (c) 2011-2021, John Hurst All rights reserved. @@ -55,7 +55,7 @@ RationalToString(const ASDCP::Rational& r, char* buf, const ui32_t& len) // // command line option parser class -static const char* PROGRAM_NAME = "as-02-wrap"; // program name for messages +static const char* PROGRAM_NAME = "phdr-wrap"; // program name for messages // local program identification info written to file headers class MyInfo : public WriterInfo @@ -100,7 +100,7 @@ banner(FILE* stream = stdout) { fprintf(stream, "\n\ %s (asdcplib %s)\n\n\ -Copyright (c) 2011-2018, John Hurst\n\n\ +Copyright (c) 2011-2021, John Hurst\n\n\ asdcplib may be copied only under the terms of the license found at\n\ the top of every file in the asdcplib distribution kit.\n\n\ Specify the -h (help) option for further information about %s\n\n", |
