diff options
| author | jhurst <jhurst@cinecert.com> | 2020-07-15 12:32:17 -0700 |
|---|---|---|
| committer | jhurst <jhurst@cinecert.com> | 2020-07-15 12:32:17 -0700 |
| commit | 7a3145b65af7181903206c5c152da6f648e91d7d (patch) | |
| tree | eafe1a217881896b8c296d387448705fc6621196 | |
| parent | e8f0a84fedafbe3c2e1c283bef9e93afeefa7157 (diff) | |
| parent | 1b64c426f5bb727217984d353c5c3671f9bc4eed (diff) | |
Merge branch 'master' of https://github.com/cinecert/asdcplib
| -rwxr-xr-x | README.md | 4 | ||||
| -rw-r--r-- | m4/ax_lib_openssl.m4 | 4 | ||||
| -rw-r--r-- | src/AS_02_IAB.cpp | 625 | ||||
| -rw-r--r-- | src/AS_02_IAB.h | 239 | ||||
| -rw-r--r-- | src/AS_02_internal.h | 5 | ||||
| -rwxr-xr-x | src/AS_DCP.h | 1 | ||||
| -rwxr-xr-x | src/AS_DCP_MXF.cpp | 4 | ||||
| -rwxr-xr-x | src/AS_DCP_internal.h | 21 | ||||
| -rw-r--r-- | src/CMakeLists.txt | 6 | ||||
| -rw-r--r-- | src/KM_fileio.cpp | 4 | ||||
| -rw-r--r-- | src/MDD.cpp | 21 | ||||
| -rwxr-xr-x | src/MDD.h | 7 | ||||
| -rw-r--r-- | src/Makefile.am | 2 | ||||
| -rwxr-xr-x | src/Metadata.cpp | 146 | ||||
| -rwxr-xr-x | src/Metadata.h | 44 | ||||
| -rwxr-xr-x | win32/Makefile.common (renamed from win32/Makefile.wmk) | 17 | ||||
| -rw-r--r-- | win32/Makefile32.wmk | 28 | ||||
| -rw-r--r-- | win32/Makefile64.wmk | 28 | ||||
| -rwxr-xr-x | win32/README.txt | 24 |
19 files changed, 1196 insertions, 34 deletions
@@ -56,9 +56,9 @@ auto-tooled version by untarring the distribution and running ```sh autoreconf -if -./configure --enable-freedist --enable-as-02 +./configure --enable-as-02 make -make dist +make install ``` ## Libraries diff --git a/m4/ax_lib_openssl.m4 b/m4/ax_lib_openssl.m4 index 8a70f99..a7f69f0 100644 --- a/m4/ax_lib_openssl.m4 +++ b/m4/ax_lib_openssl.m4 @@ -237,7 +237,7 @@ SSLeay(); if test -f "$openssl_include_dir/openssl/opensslv.h"; then OPENSSL_VERSION=`grep OPENSSL_VERSION_TEXT $openssl_include_dir/openssl/opensslv.h \ - | grep -v fips | grep -v PTEXT | cut -f 2 | tr -d \"` + | grep -v fips | grep -v PTEXT | sed -e 's/[ ][ ][ ]*/\t/g' | cut -f 2 | tr -d \"` AC_SUBST([OPENSSL_VERSION]) dnl Decompose required version string and calculate numerical representation @@ -259,7 +259,7 @@ SSLeay(); \+ $((0xf))` dnl Calculate numerical representation of detected version - openssl_version_number=`expr $(($(grep OPENSSL_VERSION_NUMBER $openssl_include_dir/openssl/opensslv.h | cut -f 2 | tr -d L)))` + openssl_version_number=`expr $(($(grep OPENSSL_VERSION_NUMBER $openssl_include_dir/openssl/opensslv.h | sed -e 's/[ ][ ][ ]*/\t/g' | cut -f 2 | tr -d L)))` openssl_version_check=`expr $openssl_version_number \>\= $openssl_version_req_number` if test "$openssl_version_check" = "1"; then diff --git a/src/AS_02_IAB.cpp b/src/AS_02_IAB.cpp new file mode 100644 index 0000000..b058515 --- /dev/null +++ b/src/AS_02_IAB.cpp @@ -0,0 +1,625 @@ +/* +Copyright (c) 2011-2020, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, +John Hurst, Pierre-Anthony Lemieux + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "AS_02_internal.h" +#include "AS_02_IAB.h" + +#include <iostream> +#include <iomanip> +#include <stdexcept> + +namespace Kumu { + class RuntimeError : public std::runtime_error { + Kumu::Result_t m_Result; + RuntimeError(); + public: + RuntimeError(const Kumu::Result_t& result) : std::runtime_error(result.Message()), m_Result(result) {} + Kumu::Result_t GetResult() { return this->m_Result; } + ~RuntimeError() throw() {} + }; +} + +//------------------------------------------------------------------------------------------ + +/* Size of the BER Length of the clip */ +static const int CLIP_BER_LENGTH_SIZE = 8; + +/* Combined size of the Key and Length of the clip */ +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() {} + +const ASDCP::MXF::OP1aHeader& +AS_02::IAB::MXFWriter::OP1aHeader() const { + if (this->m_State == ST_BEGIN) { + throw Kumu::RuntimeError(Kumu::RESULT_INIT); + } + + return this->m_Writer->m_HeaderPart; +} + +const ASDCP::MXF::RIP& +AS_02::IAB::MXFWriter::RIP() const { + if (this->m_State == ST_BEGIN) { + throw Kumu::RuntimeError(Kumu::RESULT_INIT); + } + + return this->m_Writer->m_RIP; +} + +Kumu::Result_t +AS_02::IAB::MXFWriter::OpenWrite( + const std::string& filename, + const ASDCP::WriterInfo& Info, + const ASDCP::MXF::IABSoundfieldLabelSubDescriptor& sub, + const std::vector<ASDCP::UL>& conformsToSpecs, + const ASDCP::Rational& edit_rate, + const ASDCP::Rational& sample_rate) { + + /* are we already running */ + + if (this->m_State != ST_BEGIN) { + return Kumu::RESULT_STATE; + } + + Result_t result = Kumu::RESULT_OK; + + /* initialize the writer */ + + this->m_Writer = new AS_02::IAB::MXFWriter::h__Writer(DefaultSMPTEDict()); + + this->m_Writer->m_Info = Info; + + this->m_Writer->m_HeaderSize = 16 * 1024; + + try { + + /* open the file */ + + result = this->m_Writer->m_File.OpenWrite(filename.c_str()); + + if (result.Failure()) { + throw Kumu::RuntimeError(result); + } + + /* initialize IAB descriptor */ + + ASDCP::MXF::IABEssenceDescriptor* desc = new ASDCP::MXF::IABEssenceDescriptor(this->m_Writer->m_Dict); + + GenRandomValue(desc->InstanceUID); /* TODO: remove */ + desc->SampleRate = edit_rate; + desc->AudioSamplingRate = sample_rate; + desc->ChannelCount = 0; + desc->SoundEssenceCoding = this->m_Writer->m_Dict->ul(MDD_ImmersiveAudioCoding); + desc->QuantizationBits = 24; + + this->m_Writer->m_EssenceDescriptor = desc; + + /* copy and add the IAB subdescriptor */ + + ASDCP::MXF::IABSoundfieldLabelSubDescriptor* subdesc = new ASDCP::MXF::IABSoundfieldLabelSubDescriptor(sub); + + GenRandomValue(subdesc->InstanceUID); /* TODO: remove */ + subdesc->MCATagName = "IAB"; + subdesc->MCATagSymbol = "IAB"; + subdesc->MCALabelDictionaryID = this->m_Writer->m_Dict->ul(MDD_IABSoundfield); + GenRandomValue(subdesc->MCALinkID); + + this->m_Writer->m_EssenceSubDescriptorList.push_back(subdesc); + this->m_Writer->m_EssenceDescriptor->SubDescriptors.push_back(subdesc->InstanceUID); + + /* initialize the index write */ + + this->m_Writer->m_IndexWriter.SetEditRate(edit_rate); + + /* Essence Element UL */ + + byte_t element_ul_bytes[ASDCP::SMPTE_UL_LENGTH]; + + const ASDCP::MDDEntry& element_ul_entry = this->m_Writer->m_Dict->Type(MDD_IMF_IABEssenceClipWrappedElement); + + std::copy(element_ul_entry.ul, element_ul_entry.ul + ASDCP::SMPTE_UL_LENGTH, element_ul_bytes); + + /* only a single track */ + + element_ul_bytes[15] = 1; + + /* write the file header*/ + /* WriteAS02Header() takes ownership of desc and subdesc */ + + result = this->m_Writer->WriteAS02Header( + "Clip wrapping of IA bitstreams as specified in SMPTE ST 2067-201", + UL(this->m_Writer->m_Dict->ul(MDD_IMF_IABEssenceClipWrappedContainer)), + "IA Bitstream", + UL(element_ul_bytes), + UL(this->m_Writer->m_Dict->ul(MDD_SoundDataDef)), + edit_rate, + &conformsToSpecs + ); + + if (result.Failure()) { + throw Kumu::RuntimeError(result); + } + + /* start the clip */ + + this->m_ClipStart = this->m_Writer->m_File.Tell(); + + /* reserve space for the KL of the KLV, which will be written later during finalization */ + + byte_t clip_buffer[RESERVED_KL_SIZE] = { 0 }; + + memcpy(clip_buffer, this->m_Writer->m_Dict->ul(MDD_IMF_IABEssenceClipWrappedElement), ASDCP::SMPTE_UL_LENGTH); + + if (!Kumu::write_BER(clip_buffer + ASDCP::SMPTE_UL_LENGTH, 0, CLIP_BER_LENGTH_SIZE)) { + throw Kumu::RuntimeError(Kumu::RESULT_FAIL); + } + + result = this->m_Writer->m_File.Write(clip_buffer, RESERVED_KL_SIZE); + + if (result.Failure()) { + throw Kumu::RuntimeError(result); + } + + this->m_Writer->m_StreamOffset = RESERVED_KL_SIZE; + + this->m_State = ST_READY; + + } catch (Kumu::RuntimeError e) { + + this->Reset(); + + return e.GetResult(); + + } + + return result; + +} + +Result_t +AS_02::IAB::MXFWriter::WriteFrame(const ui8_t* frame, ui32_t sz) { + + /* are we running */ + + if (this->m_State == ST_BEGIN) { + return Kumu::RESULT_INIT; + } + + Result_t result = Kumu::RESULT_OK; + + /* update the index */ + + IndexTableSegment::IndexEntry Entry; + + Entry.StreamOffset = this->m_Writer->m_StreamOffset; + + this->m_Writer->m_IndexWriter.PushIndexEntry(Entry); + + try { + + /* write the frame */ + + result = this->m_Writer->m_File.Write(frame, sz); + + if (result.Failure()) { + throw Kumu::RuntimeError(result); + } + + /* increment the frame counter */ + + this->m_Writer->m_FramesWritten++; + + /* increment stream offset */ + + this->m_Writer->m_StreamOffset += sz; + + /* we are running now */ + + this->m_State = ST_RUNNING; + + } catch (Kumu::RuntimeError e) { + + this->Reset(); + + return e.GetResult(); + + } + + return result; +} + +Result_t +AS_02::IAB::MXFWriter::Finalize() { + + /* are we running */ + + if (this->m_State == ST_BEGIN) { + return Kumu::RESULT_INIT; + } + + Result_t result = RESULT_OK; + + try { + + /* write clip length */ + + ui64_t current_position = this->m_Writer->m_File.Tell(); + + result = this->m_Writer->m_File.Seek(m_ClipStart + ASDCP::SMPTE_UL_LENGTH); + + byte_t clip_buffer[CLIP_BER_LENGTH_SIZE] = { 0 }; + + ui64_t size = static_cast<ui64_t>(this->m_Writer->m_StreamOffset) /* total size of the KLV */ - RESERVED_KL_SIZE; + + bool check = Kumu::write_BER(clip_buffer, size, CLIP_BER_LENGTH_SIZE); + + if (!check) { + throw Kumu::RuntimeError(Kumu::RESULT_FAIL); + } + + result = this->m_Writer->m_File.Write(clip_buffer, CLIP_BER_LENGTH_SIZE); + + if (result.Failure()) { + throw Kumu::RuntimeError(result); + } + + result = this->m_Writer->m_File.Seek(current_position); + + if (result.Failure()) { + throw Kumu::RuntimeError(result); + } + + /* write footer */ + + result = this->m_Writer->WriteAS02Footer(); + + if (result.Failure()) { + throw Kumu::RuntimeError(result); + } + + } catch (Kumu::RuntimeError e) { + + /* nothing to do since we are about to reset */ + + result = e.GetResult(); + + } + + /* we are ready to start again */ + + this->Reset(); + + return result; +} + +void +AS_02::IAB::MXFWriter::Reset() { + this->m_Writer.set(NULL); + this->m_State = ST_BEGIN; +} + + +//------------------------------------------------------------------------------------------ + + +AS_02::IAB::MXFReader::MXFReader() : m_State(ST_READER_BEGIN) {} + +AS_02::IAB::MXFReader::~MXFReader() {} + +ASDCP::MXF::OP1aHeader& +AS_02::IAB::MXFReader::OP1aHeader() const { + if (this->m_State == ST_READER_BEGIN) { + throw Kumu::RuntimeError(Kumu::RESULT_INIT); + } + + return this->m_Reader->m_HeaderPart; +} + +const ASDCP::MXF::RIP& +AS_02::IAB::MXFReader::RIP() const { + if (this->m_State == ST_READER_BEGIN) { + throw Kumu::RuntimeError(Kumu::RESULT_INIT); + } + + return this->m_Reader->m_RIP; +} + +Result_t +AS_02::IAB::MXFReader::OpenRead(const std::string& filename) { + + /* are we already running */ + + if (this->m_State != ST_READER_BEGIN) { + return Kumu::RESULT_STATE; + } + + Result_t result = Kumu::RESULT_OK; + + /* initialize the writer */ + + this->m_Reader = new h__Reader(DefaultCompositeDict()); + + try { + + result = this->m_Reader->OpenMXFRead(filename); + + if (result.Failure()) { + throw Kumu::RuntimeError(result); + } + + InterchangeObject* tmp_iobj = 0; + + this->m_Reader->m_HeaderPart.GetMDObjectByType( + this->m_Reader->m_Dict->Type(MDD_IABEssenceDescriptor).ul, + &tmp_iobj + ); + + if (!tmp_iobj) { + throw Kumu::RuntimeError(Kumu::RESULT_FAIL); + } + + this->m_Reader->m_HeaderPart.GetMDObjectByType( + this->m_Reader->m_Dict->Type(MDD_IABSoundfieldLabelSubDescriptor).ul, + &tmp_iobj + ); + + if (!tmp_iobj) { + throw Kumu::RuntimeError(Kumu::RESULT_FAIL); + } + + std::list<InterchangeObject*> ObjectList; + + this->m_Reader->m_HeaderPart.GetMDObjectsByType( + this->m_Reader->m_Dict->Type(MDD_Track).ul, + ObjectList + ); + + if (ObjectList.empty()) { + throw Kumu::RuntimeError(Kumu::RESULT_FAIL); + } + + /* invalidate current frame */ + + this->m_CurrentFrameIndex = -1; + + /* we are ready */ + + this->m_State = ST_READER_READY; + + } catch (Kumu::RuntimeError e) { + + this->Reset(); + + return e.GetResult(); + } + + return RESULT_OK; +} + + +Result_t +AS_02::IAB::MXFReader::Close() { + + /* are we already running */ + + if (this->m_State == ST_READER_BEGIN) { + return Kumu::RESULT_INIT; + } + + this->Reset(); + + return Kumu::RESULT_OK; +} + + +Result_t AS_02::IAB::MXFReader::GetFrameCount(ui32_t& frameCount) const { + + /* are we already running */ + + if (this->m_State == ST_READER_BEGIN) { + return Kumu::RESULT_INIT; + } + + frameCount = m_Reader->m_IndexAccess.GetDuration(); + + return Kumu::RESULT_OK; +} + +Result_t +AS_02::IAB::MXFReader::ReadFrame(ui32_t frame_number, AS_02::IAB::MXFReader::Frame& frame) { + + /* are we already running */ + + if (this->m_State == ST_READER_BEGIN) { + return Kumu::RESULT_INIT; + } + + Result_t result = RESULT_OK; + + /* have we already read the frame */ + + if (frame_number != this->m_CurrentFrameIndex) { + + try { + + // look up frame index node + IndexTableSegment::IndexEntry index_entry; + + result = this->m_Reader->m_IndexAccess.Lookup(frame_number, index_entry); + + if (result.Failure()) { + DefaultLogSink().Error("Frame value out of range: %u\n", frame_number); + throw Kumu::RuntimeError(result); + } + + result = this->m_Reader->m_File.Seek(index_entry.StreamOffset); + + if (result.Failure()) { + DefaultLogSink().Error("Cannot seek to stream offset: %u\n", index_entry.StreamOffset); + throw Kumu::RuntimeError(result); + } + + /* read the preamble info */ + + const int preambleTLLen = 5; + const int frameTLLen = 5; + + ui32_t buffer_offset = 0; + + this->m_CurrentFrameBuffer.resize(preambleTLLen); + + result = this->m_Reader->m_File.Read(&this->m_CurrentFrameBuffer[buffer_offset], preambleTLLen); + + if (result.Failure()) { + DefaultLogSink().Error("Error reading IA Frame preamble\n", index_entry.StreamOffset); + throw Kumu::RuntimeError(result); + } + + ui32_t preambleLen = ((ui32_t)this->m_CurrentFrameBuffer[1 + buffer_offset] << 24) + + ((ui32_t)this->m_CurrentFrameBuffer[2 + buffer_offset] << 16) + + ((ui32_t)this->m_CurrentFrameBuffer[3 + buffer_offset] << 8) + + (ui32_t)this->m_CurrentFrameBuffer[4 + buffer_offset]; + + buffer_offset += preambleTLLen; + + /* read the preamble*/ + + if (preambleLen > 0) { + + this->m_CurrentFrameBuffer.resize(preambleTLLen + preambleLen); + + result = this->m_Reader->m_File.Read(&this->m_CurrentFrameBuffer[buffer_offset], preambleLen); + + if (result.Failure()) { + DefaultLogSink().Error("Error reading IA Frame preamble\n", index_entry.StreamOffset); + throw Kumu::RuntimeError(result); + } + + buffer_offset += preambleLen; + + } + + /* read the IA Frame info */ + + this->m_CurrentFrameBuffer.resize(preambleTLLen + preambleLen + frameTLLen); + + result = this->m_Reader->m_File.Read(&this->m_CurrentFrameBuffer[buffer_offset], frameTLLen); + + if (result.Failure()) { + DefaultLogSink().Error("Error reading IA Frame data\n", index_entry.StreamOffset); + throw Kumu::RuntimeError(result); + } + + ui32_t frameLen = ((ui32_t)this->m_CurrentFrameBuffer[buffer_offset + 1] << 24) + + ((ui32_t)this->m_CurrentFrameBuffer[buffer_offset + 2] << 16) + + ((ui32_t)this->m_CurrentFrameBuffer[buffer_offset + 3] << 8) + + (ui32_t)this->m_CurrentFrameBuffer[buffer_offset + 4]; + + buffer_offset += frameTLLen; + + /* read the IA Frame */ + + if (frameLen > 0) { + + this->m_CurrentFrameBuffer.resize(preambleTLLen + preambleLen + frameTLLen + frameLen); + + result = this->m_Reader->m_File.Read(&this->m_CurrentFrameBuffer[buffer_offset], frameLen); + + if (result.Failure()) { + DefaultLogSink().Error("Error reading IA Frame data\n", index_entry.StreamOffset); + throw Kumu::RuntimeError(result); + } + + buffer_offset += frameLen; + + } + + /* update current frame */ + + this->m_CurrentFrameIndex = frame_number; + + } catch (Kumu::RuntimeError e) { + + this->Reset(); + + return e.GetResult(); + + } + + } + + frame = std::pair<size_t, const ui8_t*>(this->m_CurrentFrameBuffer.size(), &this->m_CurrentFrameBuffer[0]); + + this->m_State = ST_READER_RUNNING; + + return result; +} + +Result_t +AS_02::IAB::MXFReader::FillWriterInfo(WriterInfo& Info) const { + /* are we already running */ + + if (this->m_State == ST_READER_BEGIN) { + return Kumu::RESULT_FAIL; + } + + Info = m_Reader->m_Info; + + return Kumu::RESULT_OK; +} + +void +AS_02::IAB::MXFReader::DumpHeaderMetadata(FILE* stream) const { + if (this->m_State != ST_READER_BEGIN) { + this->m_Reader->m_HeaderPart.Dump(stream); + } +} + + +void +AS_02::IAB::MXFReader::DumpIndex(FILE* stream) const { + if (this->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; +} + +// +// end AS_02_IAB.cpp +// diff --git a/src/AS_02_IAB.h b/src/AS_02_IAB.h new file mode 100644 index 0000000..57fb77e --- /dev/null +++ b/src/AS_02_IAB.h @@ -0,0 +1,239 @@ +/* +Copyright (c), Bjoern Stresing, Patrick Bichiou, Wolfgang Ruppel, +John Hurst, Pierre-Anthony Lemieux + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products +derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/** + * Reader and writer classes for IAB Track Files, as defined in SMPTE ST 2067-201 + * + * @file + */ + +#ifndef AS_02_IAB_h__ +#define AS_02_IAB_h__ + +#include "AS_02.h" +#include "AS_02_internal.h" +#include "Metadata.h" + +namespace AS_02 { + + namespace IAB { + + /** + * Writes IAB Track Files as specified in ST SMPTE 2067-201 + * + */ + class MXFWriter { + + typedef h__AS02Writer<AS_02::MXF::AS02IndexWriterVBR> h__Writer; + + ASDCP::mem_ptr<h__Writer> m_Writer; + ui64_t m_ClipStart; + WriterState_t m_State; + + void Reset(); + + ASDCP_NO_COPY_CONSTRUCT(MXFWriter); + + public: + MXFWriter(); + virtual ~MXFWriter(); + + /** + * Must be preceded by a succesful OpenWrite() call followed by zero or more WriteFrame() calls + * + * Warning: direct manipulation of MXF structures can interfere + * with the normal operation of the wrapper. Caveat emptor! + * + * @return Header of the Track File + * + * @throws std::runtime_error if the Track File is not open + */ + virtual const ASDCP::MXF::OP1aHeader& OP1aHeader() const; + + /** + * Must be preceded by a succesful OpenWrite() call followed by zero or more WriteFrame() calls + * + * Warning: direct manipulation of MXF structures can interfere + * with the normal operation of the wrapper. Caveat emptor! + * + * @return RIP of the Track File + * + * @throws std::runtime_error if the Track File is not open + */ + virtual const ASDCP::MXF::RIP& RIP() const; + + /** + * Creates and prepares an IAB Track File for writing. + * + * Must be called following instantiation or after Finalize() call + * + * @param filename Path to the file. The file must no exist. + * @param Info MXF file metadata to be written. + * @param sub IAB Soundfield Subdescritor items to be written. MCATagName, MCATagSymbol, MCALabelDictionaryID, MCALinkID are ignored. + * @param conformsToSpecs Value of the ConformsToSpecifications preface item + * @param edit_rate Frame rate of the IA Bitstream + * @param sampling_rate Sampling rate of the audio essence within the IA Bitstream + * + * @return RESULT_OK indicates that frames are ready to be written, + * otherwise the reader is reset and the file is left is an undermined state. + */ + Result_t OpenWrite( + const std::string& filename, + const ASDCP::WriterInfo& Info, + const ASDCP::MXF::IABSoundfieldLabelSubDescriptor& sub, + const std::vector<ASDCP::UL>& conformsToSpecs, + const ASDCP::Rational& edit_rate, + const ASDCP::Rational& sampling_rate = ASDCP::SampleRate_48k + ); + + /** + * Writes a single frame. + * + * Must be preceded by a succesful OpenWrite() call followed by zero or more WriteFrame() calls + * + * @param frame Pointer to a complete IA Frame + * @param sz Size in bytes of the IA Frame + * @return RESULT_OK indicates that the frame is written and additional frames can be written, + * otherwise the reader is reset and the file is left is an undermined state. + */ + Result_t WriteFrame(const ui8_t* frame, ui32_t sz); + + /** + * Writes the Track File footer and closes the file. + * + * Must be preceded by a succesful OpenWrite() call followed by zero or more WriteFrame() calls + * + * @return RESULT_OK indicates that the frame is written and additional frames can be written, + * otherwise the reader is reset and the file is left is an undermined state. + */ + Result_t Finalize(); + }; + + /** + * Reads IAB Track Files as specified in ST SMPTE 2067-201 + * + */ + class MXFReader { + + typedef h__AS02Reader h__Reader; + + ASDCP::mem_ptr<h__Reader> m_Reader; + + i64_t m_CurrentFrameIndex; + std::vector<ui8_t> m_CurrentFrameBuffer; + ReaderState_t m_State; + + void Reset(); + + ASDCP_NO_COPY_CONSTRUCT(MXFReader); + + public: + + /* typedefs*/ + + typedef std::pair<size_t, const ui8_t*> Frame; + + /* methods */ + + MXFReader(); + virtual ~MXFReader(); + + /** + * Warning: direct manipulation of MXF structures can interfere + * with the normal operation of the wrapper. Caveat emptor! + * + * @return Header of the Track File + * + * @throws std::runtime_error if the Track File is not open + */ + virtual ASDCP::MXF::OP1aHeader& OP1aHeader() const; + + /** + * Warning: direct manipulation of MXF structures can interfere + * with the normal operation of the wrapper. Caveat emptor! + * + * @return RIP of the Track File + * + * @throws std::runtime_error if the Track File is not open + */ + virtual const ASDCP::MXF::RIP& RIP() const; + + /** + * Creates and prepares an IAB Track File for reading. + * + * @param filename Path to the file. The file must no exist. + * + * @return RESULT_OK indicates that frames are ready to be read, + * otherwise the reader is reset + */ + Result_t OpenRead(const std::string& filename); + + /** + * Closes the IAB Track File. + * + * @return RESULT_OK indicates that the Track File was successfully closed. + */ + Result_t Close(); + + /** + * Fill a WriterInfo struct with the values from the Track File's header. + * + * @param writer_info Struct to be filled + * @return RESULT_OK indicates that writer_info was successfully filled. + */ + Result_t FillWriterInfo(ASDCP::WriterInfo& writer_info) const; + + /** + * Reads an IA Frame. + * + * @param frame_number Index of the frame to be read. Must be in the range [0, GetFrameCount()). + * @param frame Frame data. Must not be modified. Remains valid until the next call to ReadFrame(). + * @return RESULT_OK indicates that more frames are ready to be read, + * otherwise the file is closed and the reader reset + */ + Result_t ReadFrame(ui32_t frame_number, Frame& frame); + + /** + * Returns the number of IA Frame in the Track File. + * + * @param frameCount Number of IA Frames + * @return RESULT_OK unless the file is not open + */ + Result_t GetFrameCount(ui32_t& frameCount) const; + + // Print debugging information to stream + void DumpHeaderMetadata(FILE* = 0) const; + void DumpIndex(FILE* = 0) const; + }; + + } //namespace IAB + +} // namespace AS_02 + +#endif // AS_02_IAB_h__ diff --git a/src/AS_02_internal.h b/src/AS_02_internal.h index e6038c3..b5d8282 100644 --- a/src/AS_02_internal.h +++ b/src/AS_02_internal.h @@ -164,7 +164,8 @@ namespace AS_02 // all the above for a single source clip Result_t WriteAS02Header(const std::string& PackageLabel, const ASDCP::UL& WrappingUL, const std::string& TrackName, const ASDCP::UL& EssenceUL, - const ASDCP::UL& DataDefinition, const ASDCP::Rational& EditRate) + const ASDCP::UL& DataDefinition, const ASDCP::Rational& EditRate, + const std::vector<ASDCP::UL>* conformsToSpecifications = NULL) { if ( EditRate.Numerator == 0 || EditRate.Denominator == 0 ) { @@ -172,7 +173,7 @@ namespace AS_02 return RESULT_PARAM; } - InitHeader(MXFVersion_2011); + InitHeader(MXFVersion_2011, conformsToSpecifications); AddSourceClip(EditRate, EditRate/*TODO: for a moment*/, 0 /*no timecode track*/, TrackName, EssenceUL, DataDefinition, PackageLabel); AddEssenceDescriptor(WrappingUL); diff --git a/src/AS_DCP.h b/src/AS_DCP.h index f39c9c8..f089f06 100755 --- a/src/AS_DCP.h +++ b/src/AS_DCP.h @@ -223,6 +223,7 @@ namespace ASDCP { ESS_AS02_TIMED_TEXT, // the file contains a TTML document and zero or more resources ESS_AS02_ISXD, // the file contains an ISXD document stream (per SMPTE RDD 47) ESS_AS02_ACES, // the file contains two or more ACES codestreams (per SMPTE ST 2067-50) + ESS_AS02_IAB, // the file contains an IAB stream (per SMPTE ST 2067-201) ESS_MAX }; diff --git a/src/AS_DCP_MXF.cpp b/src/AS_DCP_MXF.cpp index d3606fe..c478f2f 100755 --- a/src/AS_DCP_MXF.cpp +++ b/src/AS_DCP_MXF.cpp @@ -277,6 +277,10 @@ ASDCP::EssenceType(const std::string& filename, EssenceType_t& type) { type = ESS_AS02_ACES; } + else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(IABEssenceDescriptor))) ) + { + type = ESS_AS02_IAB; + } } } else diff --git a/src/AS_DCP_internal.h b/src/AS_DCP_internal.h index a684ba5..7162368 100755 --- a/src/AS_DCP_internal.h +++ b/src/AS_DCP_internal.h @@ -624,7 +624,7 @@ namespace ASDCP const MXF::RIP& GetRIP() const { return m_RIP; } - void InitHeader(const MXFVersion& mxf_ver) + void InitHeader(const MXFVersion& mxf_ver, const std::vector<ASDCP::UL>* conformsToSpecifications = NULL) { assert(m_Dict); assert(m_EssenceDescriptor); @@ -633,6 +633,18 @@ namespace ASDCP m_HeaderPart.m_Preface = new Preface(m_Dict); m_HeaderPart.AddChildObject(m_HeaderPart.m_Preface); + // add conformsToSpecifications, if it exists + + if (conformsToSpecifications && conformsToSpecifications->size() > 0) { + + m_HeaderPart.m_Preface->ConformsToSpecifications.set_has_value(); + + m_HeaderPart.m_Preface->ConformsToSpecifications.get().insert( + conformsToSpecifications->begin(), + conformsToSpecifications->end() + ); + } + // Set the Operational Pattern label -- we're just starting and have no RIP or index, // so we tell the world by using OP1a m_HeaderPart.m_Preface->OperationalPattern = UL(m_Dict->ul(MDD_OP1a)); @@ -881,6 +893,13 @@ namespace ASDCP //------------------------------------------------------------------------------------------ // +// state machine for mxf reader + enum ReaderState_t { + ST_READER_BEGIN, // waiting for Open() + ST_READER_READY, // ready to read frames + ST_READER_RUNNING, // one or more frames read + }; + // class h__ASDCPReader : public MXF::TrackFileReader<OP1aHeader, OPAtomIndexFooter> { diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 842f44a..2787e46 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -37,13 +37,13 @@ set(asdcp_src ${asdcp_src} Wav.h WavFileWriter.h MXF.h Metadata.h JP2K.h AS_DCP. # ----------as02----------
# source
-set(as02_src h__02_Reader.cpp h__02_Writer.cpp AS_02_ISXD.cpp AS_02_JP2K.cpp AS_02_PCM.cpp ST2052_TextParser.cpp AS_02_TimedText.cpp AS_02_ACES.cpp ACES_Codestream_Parser.cpp ACES_Sequence_Parser.cpp ACES.cpp)
+set(as02_src h__02_Reader.cpp h__02_Writer.cpp AS_02_ISXD.cpp AS_02_JP2K.cpp AS_02_PCM.cpp ST2052_TextParser.cpp AS_02_TimedText.cpp AS_02_ACES.cpp ACES_Codestream_Parser.cpp ACES_Sequence_Parser.cpp ACES.cpp AS_02_IAB.cpp)
# header for deployment (install target)
-set(as02_deploy_header AS_02.h Metadata.h MXF.h MXFTypes.h KLV.h MDD.h AS_02_ACES.h ACES.h)
+set(as02_deploy_header AS_02.h Metadata.h MXF.h MXFTypes.h KLV.h MDD.h AS_02_ACES.h ACES.h AS_02_IAB.h AS_02_internal.h)
# header
-set(as02_src ${as02_src} AS_02.h AS_02_internal.h AS_02_ACES.h ACES.h)
+set(as02_src ${as02_src} AS_02.h AS_02_internal.h AS_02_ACES.h ACES.h AS_02_IAB.h)
include_directories("${PROJECT_SOURCE_DIR}/src" "${OpenSSLLib_include_DIR}" "${XercescppLib_include_DIR}")
diff --git a/src/KM_fileio.cpp b/src/KM_fileio.cpp index 27a5bfa..4ee73c2 100644 --- a/src/KM_fileio.cpp +++ b/src/KM_fileio.cpp @@ -719,7 +719,9 @@ Kumu::fsize_t Kumu::FileReader::Size() const { #ifdef KM_WIN32 - return FileSize(m_Filename.c_str()); + LARGE_INTEGER size; + GetFileSizeEx(m_Handle, &size); + return size.QuadPart; #else fstat_t info; diff --git a/src/MDD.cpp b/src/MDD.cpp index 6db1bec..772b96d 100644 --- a/src/MDD.cpp +++ b/src/MDD.cpp @@ -1639,6 +1639,27 @@ static const ASDCP::MDDEntry s_MDD_Table[] = { { { 0x06, 0x0e, 0x2b, 0x34, 01, 0x01, 0x01, 0x0e, 06, 0x01, 0x01, 0x02, 06, 0x00, 0x00, 0x00 }, {0}, false, "TimedTextDescriptor_ZPositionInUse" }, // 528 + { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 529 + 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x7b, 0x00 }, + {0}, false, "IABEssenceDescriptor" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 530 + 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x7c, 0x00 }, + {0}, false, "IABSoundfieldLabelSubDescriptor" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 531 + 0x01, 0x01, 0x02, 0x01, 0x02, 0x00, 0x00, 0x00 }, + {0}, false, "IMF_IABTrackFileLevel0" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 532 + 0x0d, 0x01, 0x03, 0x01, 0x02, 0x1d, 0x01, 0x01 }, + {0}, false, "IMF_IABEssenceClipWrappedContainer" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 533 + 0x03, 0x02, 0x02, 0x21, 0x00, 0x00, 0x00, 0x00 }, + {0}, false, "IABSoundfield" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x02, 0x01, 0x01, // 534 + 0x0d, 0x01, 0x03, 0x01, 0x16, 0x7f, 0x0d, 0x7f }, + {0}, false, "IMF_IABEssenceClipWrappedElement" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x05, // 535 + 0x0e, 0x09, 0x06, 0x04, 0x00, 0x00, 0x00, 0x00 }, + {0}, false, "ImmersiveAudioCoding" }, { {0}, {0}, false, 0 }, }; @@ -564,6 +564,13 @@ namespace ASDCP { MDD_TimedTextDescriptor_DisplayType, // 526 MDD_TimedTextDescriptor_IntrinsicPictureResolution, // 527 MDD_TimedTextDescriptor_ZPositionInUse, // 528 + MDD_IABEssenceDescriptor, // 529 + MDD_IABSoundfieldLabelSubDescriptor, // 530 + MDD_IMF_IABTrackFileLevel0, // 531 + MDD_IMF_IABEssenceClipWrappedContainer, // 532 + MDD_IABSoundfield, // 533 + MDD_IMF_IABEssenceClipWrappedElement, // 534 + MDD_ImmersiveAudioCoding, // 535 MDD_Max }; // enum MDD_t diff --git a/src/Makefile.am b/src/Makefile.am index 74c0b11..7768b39 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -143,6 +143,7 @@ libas02_la_SOURCES = \ AS_02_internal.h \ ACES.h \ AS_02_ACES.h \ + AS_02_IAB.h \ h__02_Reader.cpp \ h__02_Writer.cpp \ AS_02_JP2K.cpp \ @@ -151,6 +152,7 @@ libas02_la_SOURCES = \ ST2052_TextParser.cpp \ AS_02_TimedText.cpp \ ACES.cpp \ + AS_02_IAB.cpp \ ACES_Codestream_Parser.cpp \ ACES_Sequence_Parser.cpp \ AS_02_ACES.cpp diff --git a/src/Metadata.cpp b/src/Metadata.cpp index adaac11..9ca3d66 100755 --- a/src/Metadata.cpp +++ b/src/Metadata.cpp @@ -87,6 +87,8 @@ static InterchangeObject* GenericStreamTextBasedSet_Factory(const Dictionary*& D static InterchangeObject* ISXDDataEssenceDescriptor_Factory(const Dictionary*& Dict) { return new ISXDDataEssenceDescriptor(Dict); } static InterchangeObject* PHDRMetadataTrackSubDescriptor_Factory(const Dictionary*& Dict) { return new PHDRMetadataTrackSubDescriptor(Dict); } static InterchangeObject* PIMFDynamicMetadataDescriptor_Factory(const Dictionary*& Dict) { return new PIMFDynamicMetadataDescriptor(Dict); } +static InterchangeObject* IABEssenceDescriptor_Factory(const Dictionary*& Dict) { return new IABEssenceDescriptor(Dict); } +static InterchangeObject* IABSoundfieldLabelSubDescriptor_Factory(const Dictionary*& Dict) { return new IABSoundfieldLabelSubDescriptor(Dict); } void @@ -140,6 +142,8 @@ ASDCP::MXF::Metadata_InitTypes(const Dictionary*& Dict) SetObjectFactory(Dict->ul(MDD_ISXDDataEssenceDescriptor), ISXDDataEssenceDescriptor_Factory); SetObjectFactory(Dict->ul(MDD_PHDRMetadataTrackSubDescriptor), PHDRMetadataTrackSubDescriptor_Factory); SetObjectFactory(Dict->ul(MDD_PIMFDynamicMetadataDescriptor), PIMFDynamicMetadataDescriptor_Factory); + SetObjectFactory(Dict->ul(MDD_IABEssenceDescriptor), IABEssenceDescriptor_Factory); + SetObjectFactory(Dict->ul(MDD_IABSoundfieldLabelSubDescriptor), IABSoundfieldLabelSubDescriptor_Factory); } //------------------------------------------------------------------------------------------ @@ -4851,6 +4855,148 @@ PIMFDynamicMetadataDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer) return InterchangeObject::WriteToBuffer(Buffer); } +//------------------------------------------------------------------------------------------ +// IABEssenceDescriptor + +// + +IABEssenceDescriptor::IABEssenceDescriptor(const Dictionary*& d) : GenericSoundEssenceDescriptor(d), m_Dict(d) +{ + assert(m_Dict); + m_UL = m_Dict->ul(MDD_IABEssenceDescriptor); +} + +IABEssenceDescriptor::IABEssenceDescriptor(const IABEssenceDescriptor& rhs) : GenericSoundEssenceDescriptor(rhs.m_Dict), m_Dict(rhs.m_Dict) +{ + assert(m_Dict); + m_UL = m_Dict->ul(MDD_IABEssenceDescriptor); + Copy(rhs); +} + + +// +ASDCP::Result_t +IABEssenceDescriptor::InitFromTLVSet(TLVReader& TLVSet) +{ + assert(m_Dict); + Result_t result = GenericSoundEssenceDescriptor::InitFromTLVSet(TLVSet); + return result; +} + +// +ASDCP::Result_t +IABEssenceDescriptor::WriteToTLVSet(TLVWriter& TLVSet) +{ + assert(m_Dict); + Result_t result = GenericSoundEssenceDescriptor::WriteToTLVSet(TLVSet); + return result; +} + +// +void +IABEssenceDescriptor::Copy(const IABEssenceDescriptor& rhs) +{ + GenericSoundEssenceDescriptor::Copy(rhs); +} + +// +void +IABEssenceDescriptor::Dump(FILE* stream) +{ + char identbuf[IdentBufferLen]; + *identbuf = 0; + + if ( stream == 0 ) + stream = stderr; + + GenericSoundEssenceDescriptor::Dump(stream); +} + +// +ASDCP::Result_t +IABEssenceDescriptor::InitFromBuffer(const byte_t* p, ui32_t l) +{ + return InterchangeObject::InitFromBuffer(p, l); +} + +// +ASDCP::Result_t +IABEssenceDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer) +{ + return InterchangeObject::WriteToBuffer(Buffer); +} + +//------------------------------------------------------------------------------------------ +// IABSoundfieldLabelSubDescriptor + +// + +IABSoundfieldLabelSubDescriptor::IABSoundfieldLabelSubDescriptor(const Dictionary*& d) : MCALabelSubDescriptor(d), m_Dict(d) +{ + assert(m_Dict); + m_UL = m_Dict->ul(MDD_IABSoundfieldLabelSubDescriptor); +} + +IABSoundfieldLabelSubDescriptor::IABSoundfieldLabelSubDescriptor(const IABSoundfieldLabelSubDescriptor& rhs) : MCALabelSubDescriptor(rhs.m_Dict), m_Dict(rhs.m_Dict) +{ + assert(m_Dict); + m_UL = m_Dict->ul(MDD_IABSoundfieldLabelSubDescriptor); + Copy(rhs); +} + + +// +ASDCP::Result_t +IABSoundfieldLabelSubDescriptor::InitFromTLVSet(TLVReader& TLVSet) +{ + assert(m_Dict); + Result_t result = MCALabelSubDescriptor::InitFromTLVSet(TLVSet); + return result; +} + +// +ASDCP::Result_t +IABSoundfieldLabelSubDescriptor::WriteToTLVSet(TLVWriter& TLVSet) +{ + assert(m_Dict); + Result_t result = MCALabelSubDescriptor::WriteToTLVSet(TLVSet); + return result; +} + +// +void +IABSoundfieldLabelSubDescriptor::Copy(const IABSoundfieldLabelSubDescriptor& rhs) +{ + MCALabelSubDescriptor::Copy(rhs); +} + +// +void +IABSoundfieldLabelSubDescriptor::Dump(FILE* stream) +{ + char identbuf[IdentBufferLen]; + *identbuf = 0; + + if ( stream == 0 ) + stream = stderr; + + MCALabelSubDescriptor::Dump(stream); +} + +// +ASDCP::Result_t +IABSoundfieldLabelSubDescriptor::InitFromBuffer(const byte_t* p, ui32_t l) +{ + return InterchangeObject::InitFromBuffer(p, l); +} + +// +ASDCP::Result_t +IABSoundfieldLabelSubDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer) +{ + return InterchangeObject::WriteToBuffer(Buffer); +} + // // end Metadata.cpp // diff --git a/src/Metadata.h b/src/Metadata.h index c624784..ab11034 100755 --- a/src/Metadata.h +++ b/src/Metadata.h @@ -1297,6 +1297,50 @@ namespace ASDCP virtual Result_t WriteToBuffer(ASDCP::FrameBuffer&); }; + // + class IABEssenceDescriptor : public GenericSoundEssenceDescriptor + { + IABEssenceDescriptor(); + + public: + const Dictionary*& m_Dict; + + IABEssenceDescriptor(const Dictionary*& d); + IABEssenceDescriptor(const IABEssenceDescriptor& rhs); + virtual ~IABEssenceDescriptor() {} + + const IABEssenceDescriptor& operator=(const IABEssenceDescriptor& rhs) { Copy(rhs); return *this; } + virtual void Copy(const IABEssenceDescriptor& rhs); + virtual const char* HasName() { return "IABEssenceDescriptor"; } + virtual Result_t InitFromTLVSet(TLVReader& TLVSet); + virtual Result_t WriteToTLVSet(TLVWriter& TLVSet); + virtual void Dump(FILE* = 0); + virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l); + virtual Result_t WriteToBuffer(ASDCP::FrameBuffer&); + }; + + // + class IABSoundfieldLabelSubDescriptor : public MCALabelSubDescriptor + { + IABSoundfieldLabelSubDescriptor(); + + public: + const Dictionary*& m_Dict; + + IABSoundfieldLabelSubDescriptor(const Dictionary*& d); + IABSoundfieldLabelSubDescriptor(const IABSoundfieldLabelSubDescriptor& rhs); + virtual ~IABSoundfieldLabelSubDescriptor() {} + + const IABSoundfieldLabelSubDescriptor& operator=(const IABSoundfieldLabelSubDescriptor& rhs) { Copy(rhs); return *this; } + virtual void Copy(const IABSoundfieldLabelSubDescriptor& rhs); + virtual const char* HasName() { return "IABSoundfieldLabelSubDescriptor"; } + virtual Result_t InitFromTLVSet(TLVReader& TLVSet); + virtual Result_t WriteToTLVSet(TLVWriter& TLVSet); + virtual void Dump(FILE* = 0); + virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l); + virtual Result_t WriteToBuffer(ASDCP::FrameBuffer&); + }; + } // namespace MXF } // namespace ASDCP diff --git a/win32/Makefile.wmk b/win32/Makefile.common index 1a0956d..5f90bc7 100755 --- a/win32/Makefile.wmk +++ b/win32/Makefile.common @@ -1,5 +1,5 @@ # $Id$
-# Copyright (c) 2007-2012 John Hurst. All rights reserved.
+# Copyright (c) 2007-2020 John Hurst. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -34,17 +34,16 @@ OBJDIR = . !ifdef ENABLE_RANDOM_UUID
CXXFLAGS1 = /nologo /W3 /GR /EHsc /DWIN32 /DKM_WIN32 /D_CONSOLE /I. /I$(SRCDIR) /DASDCP_PLATFORM=\"win32\" \
/D_CRT_SECURE_NO_WARNINGS /D_CRT_NONSTDC_NO_WARNINGS /DPACKAGE_VERSION=\"@PACKAGE_VERSION@\" \
- /I"$(WITH_OPENSSL)"\inc32 /DCONFIG_RANDOM_UUID=1
+ /I"$(WITH_OPENSSL)"\include /DCONFIG_RANDOM_UUID=1
!else
CXXFLAGS1 = /nologo /W3 /GR /EHsc /DWIN32 /DKM_WIN32 /D_CONSOLE /I. /I$(SRCDIR) /DASDCP_PLATFORM=\"win32\" \
/D_CRT_SECURE_NO_WARNINGS /D_CRT_NONSTDC_NO_WARNINGS /DPACKAGE_VERSION=\"@PACKAGE_VERSION@\" \
- /I"$(WITH_OPENSSL)"\inc32
+ /I"$(WITH_OPENSSL)"\include
!endif
LIB_EXE = lib.exe
-LIBFLAGS1 = /NOLOGO /LIBPATH:"$(WITH_OPENSSL)"\out32dll
+LIBFLAGS1 = /NOLOGO /LIBPATH:"$(WITH_OPENSSL)"\lib
LINK = link.exe
-LINKFLAGS1 = /NOLOGO /SUBSYSTEM:console /MACHINE:I386 /LIBPATH:. /DEBUG
!ifdef DEBUG
@@ -110,14 +109,14 @@ clean: libkumu.lib : $(KUMU_OBJS)
!IFDEF WITH_XERCES
!IFDEF DEBUG
- $(LIB_EXE) $(LIBFLAGS) /OUT:libkumu.lib $** libeay32.lib xerces-c_2D.lib
+ $(LIB_EXE) $(LIBFLAGS) /OUT:libkumu.lib $** libcrypto.lib xerces-c_3D.lib
!ELSE
- $(LIB_EXE) $(LIBFLAGS) /OUT:libkumu.lib $** libeay32.lib xerces-c_2.lib
+ $(LIB_EXE) $(LIBFLAGS) /OUT:libkumu.lib $** libcrypto.lib xerces-c_3.lib
!ENDIF
!ELSEIFDEF WITH_XML_PARSER
- $(LIB_EXE) $(LIBFLAGS) /OUT:libkumu.lib $** libeay32.lib libexpatMT.lib
+ $(LIB_EXE) $(LIBFLAGS) /OUT:libkumu.lib $** libcrypto.lib libexpatMT.lib
!ELSE
- $(LIB_EXE) $(LIBFLAGS) /OUT:libkumu.lib $** libeay32.lib
+ $(LIB_EXE) $(LIBFLAGS) /OUT:libkumu.lib $** libcrypto.lib
!ENDIF
libasdcp.lib: libkumu.lib $(ASDCP_OBJS)
diff --git a/win32/Makefile32.wmk b/win32/Makefile32.wmk new file mode 100644 index 0000000..5fc0887 --- /dev/null +++ b/win32/Makefile32.wmk @@ -0,0 +1,28 @@ +# $Id$ +# Copyright (c) 2007-2020 John Hurst. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +LINKFLAGS1 = /NOLOGO /SUBSYSTEM:console /MACHINE:I386 /LIBPATH:. /DEBUG + +include Makefile.common diff --git a/win32/Makefile64.wmk b/win32/Makefile64.wmk new file mode 100644 index 0000000..c1ad4a5 --- /dev/null +++ b/win32/Makefile64.wmk @@ -0,0 +1,28 @@ +# $Id$ +# Copyright (c) 2007-2020 John Hurst. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +LINKFLAGS1 = /NOLOGO /SUBSYSTEM:console /MACHINE:X64 /LIBPATH:. /DEBUG + +include Makefile.common diff --git a/win32/README.txt b/win32/README.txt index 76e76c7..4dbdd14 100755 --- a/win32/README.txt +++ b/win32/README.txt @@ -35,29 +35,25 @@ variable KM_USE_RANDOM_UUID is set during runtime. Open a command prompt in which the VS build tools are available on the command line (e.g., the
"Visual Studio command prompt"). The nmake invocation follows this form:
C:\>nmake WITH_OPENSSL=<OpenSSL directory> [WITH_XERCES=<Xerces directory>|
- WITH_XML_PARSER=<Expat directory>] [ENABLE_RANDOM_UUID=1] /f Makefile.mak
+ WITH_XML_PARSER=<Expat directory>] [ENABLE_RANDOM_UUID=1] /f Makefile32.wmk
On our Windows development machine, the invocation with XML parsing by Xerces-C++ is as such:
-C:\Program Files\asdcplib\win32>nmake WITH_OPENSSL="c:\Program Files\openssl-0.9.8j"
- WITH_XERCES="C:\Program Files\xerces-c_2_8_0-x86-windows-vc_8_0" /f Makefile.mak
+C:\Program Files (x86)\asdcplib\win32>nmake WITH_OPENSSL="C:\Program Files (x86)\openssl"
+ WITH_XERCES="C:\Program Files (x86)\xerces-c" /f Makefile32.wmk
With XML parsing by Expat and random UUID generation enabled:
-C:\Program Files\asdcplib\win32>nmake WITH_OPENSSL="c:\Program Files\openssl-0.9.8j"
- WITH_XML_PARSER="C:\Program Files\Expat 2.0.1" ENABLE_RANDOM_UUID=1 /f Makefile.mak
+C:\Program Files (x86)\asdcplib\win32>nmake WITH_OPENSSL="C:\Program Files (x86)\openssl"
+ WITH_XML_PARSER="C:\Program Files (x86)\Expat 2.0.1" ENABLE_RANDOM_UUID=1 /f Makefile32.wmk
Without XML parsing:
-C:\Program Files\asdcplib\win32>nmake WITH_OPENSSL="c:\Program Files\openssl-0.9.8j"
- /f Makefile.mak
+C:\Program Files (x86)\asdcplib\win32>nmake WITH_OPENSSL="C:\Program Files (x86)\openssl"
+ /f Makefile32.wmk
Without XML parsing but with the AS-02 library and executables:
-C:\Program Files\asdcplib\win32>nmake WITH_OPENSSL="c:\Program Files\openssl-0.9.8j"
- USE_AS_02=1 /f Makefile.mak
-
-Want a 64-bit build? Change the following line in Makefile.mak:
- LINKFLAGS1 = /NOLOGO /SUBSYSTEM:console /MACHINE:I386 /LIBPATH:. /DEBUG
-to
- LINKFLAGS1 = /NOLOGO /SUBSYSTEM:console /MACHINE:X64 /LIBPATH:. /DEBUG
+C:\Program Files (x86)\asdcplib\win32>nmake WITH_OPENSSL="C:\Program Files (x86)\openssl"
+ USE_AS_02=1 /f Makefile32.wmk
+Want a 64-bit build? Use Makefile64.wmk and specify 64-bit library locations.
IV. CONCLUSION
==============
|
