From c93f726df76687de551b8b9258305975d56ff102 Mon Sep 17 00:00:00 2001 From: Pierre-Anthony Lemieux Date: Tue, 10 Mar 2020 20:47:33 -0700 Subject: Replaced ATMOS with IAB terminology --- src/AS_DCP.h | 28 +- src/AS_DCP_ATMOS.cpp | 693 ------------------------------------- src/AS_DCP_DCData.cpp | 10 +- src/AS_DCP_IAB.cpp | 693 +++++++++++++++++++++++++++++++++++++ src/AS_DCP_MXF.cpp | 14 +- src/AtmosSyncChannel_Generator.cpp | 149 -------- src/AtmosSyncChannel_Generator.h | 151 -------- src/AtmosSyncChannel_Mixer.cpp | 368 -------------------- src/AtmosSyncChannel_Mixer.h | 94 ----- src/CMakeLists.txt | 6 +- src/Dict.cpp | 30 +- src/FSKSyncChannel_Generator.cpp | 149 ++++++++ src/FSKSyncChannel_Generator.h | 151 ++++++++ src/FSKSyncChannel_Mixer.cpp | 368 ++++++++++++++++++++ src/FSKSyncChannel_Mixer.h | 94 +++++ src/KLV.h | 2 +- src/MDD.cpp | 22 +- src/MDD.h | 18 +- src/Makefile.am | 10 +- src/Metadata.cpp | 80 ++--- src/Metadata.h | 36 +- src/PCMDataProviders.cpp | 14 +- src/PCMDataProviders.h | 17 +- src/SyncCommon.h | 2 +- src/SyncEncoder.c | 2 +- src/SyncEncoder.h | 2 +- src/UUIDInformation.c | 2 +- src/UUIDInformation.h | 2 +- src/asdcp-info.cpp | 14 +- src/asdcp-unwrap.cpp | 2 +- src/asdcp-wrap.cpp | 56 +-- win32/Makefile.wmk | 4 +- 32 files changed, 1640 insertions(+), 1643 deletions(-) delete mode 100644 src/AS_DCP_ATMOS.cpp create mode 100644 src/AS_DCP_IAB.cpp delete mode 100644 src/AtmosSyncChannel_Generator.cpp delete mode 100644 src/AtmosSyncChannel_Generator.h delete mode 100644 src/AtmosSyncChannel_Mixer.cpp delete mode 100644 src/AtmosSyncChannel_Mixer.h create mode 100644 src/FSKSyncChannel_Generator.cpp create mode 100644 src/FSKSyncChannel_Generator.h create mode 100644 src/FSKSyncChannel_Mixer.cpp create mode 100644 src/FSKSyncChannel_Mixer.h diff --git a/src/AS_DCP.h b/src/AS_DCP.h index 74991f6..89ab776 100755 --- a/src/AS_DCP.h +++ b/src/AS_DCP.h @@ -214,7 +214,7 @@ namespace ASDCP { ESS_TIMED_TEXT, // the file contains an XML timed text document and one or more resources ESS_JPEG_2000_S, // the file contains one or more JPEG 2000 codestream pairs (stereoscopic) ESS_DCDATA_UNKNOWN, // the file contains one or more D-Cinema Data bytestreams - ESS_DCDATA_DOLBY_ATMOS, // the file contains one or more DolbyATMOS bytestreams + ESS_DCDATA_IAB, // the file contains one or more IAB bytestreams // IMF essence types ESS_AS02_JPEG_2000, // the file contains one or more JPEG 2000 codestreams @@ -1848,23 +1848,23 @@ namespace ASDCP { //--------------------------------------------------------------------------------- // - namespace ATMOS + namespace IAB { - struct AtmosDescriptor : public DCData::DCDataDescriptor + struct IABDescriptor : public DCData::DCDataDescriptor { ui32_t FirstFrame; // Frame number of the frame to align with the FFOA of the picture track ui16_t MaxChannelCount; // Max number of channels in bitstream ui16_t MaxObjectCount; // Max number of objects in bitstream - byte_t AtmosID[UUIDlen]; // UUID of Atmos Project - ui8_t AtmosVersion; // ATMOS Coder Version used to create bitstream + byte_t ImmersiveAudioID[UUIDlen]; // UUID of IAB Project + ui8_t ImmersiveAudioVersion; // IAB Coder Version used to create bitstream }; - // Print AtmosDescriptor to std::ostream - std::ostream& operator << (std::ostream& strm, const AtmosDescriptor& adesc); + // Print IABDescriptor to std::ostream + std::ostream& operator << (std::ostream& strm, const IABDescriptor& adesc); // Print debugging information to stream (stderr default) - void AtmosDescriptorDump(const AtmosDescriptor&, FILE* = 0); - // Determine if a file is a raw atmos file - bool IsDolbyAtmos(const std::string& filename); + void IADataEssenceSubDescriptorDump(const IABDescriptor&, FILE* = 0); + // Determine if a file is a raw IAB file + bool IsIAB(const std::string& filename); // class MXFWriter @@ -1888,7 +1888,7 @@ namespace ASDCP { // the operation cannot be completed or if nonsensical data is discovered // in the essence descriptor. Result_t OpenWrite(const std::string& filename, const WriterInfo&, - const AtmosDescriptor&, ui32_t HeaderSize = 16384); + const IABDescriptor&, ui32_t HeaderSize = 16384); // Writes a frame of essence to the MXF file. If the optional AESEncContext // argument is present, the essence is encrypted prior to writing. @@ -1924,9 +1924,9 @@ namespace ASDCP { // Returns RESULT_INIT if the file is not open. Result_t Close() const; - // Fill an AtmosDescriptor struct with the values from the file's header. + // Fill an IABDescriptor struct with the values from the file's header. // Returns RESULT_INIT if the file is not open. - Result_t FillAtmosDescriptor(AtmosDescriptor&) const; + Result_t FillIABDescriptor(IABDescriptor&) const; // Fill a WriterInfo struct with the values from the file's header. // Returns RESULT_INIT if the file is not open. @@ -1952,7 +1952,7 @@ namespace ASDCP { void DumpIndex(FILE* = 0) const; }; - } // namespace ATMOS + } // namespace IAB diff --git a/src/AS_DCP_ATMOS.cpp b/src/AS_DCP_ATMOS.cpp deleted file mode 100644 index 2fc7d56..0000000 --- a/src/AS_DCP_ATMOS.cpp +++ /dev/null @@ -1,693 +0,0 @@ -/* -Copyright (c) 2004-2016, 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. -*/ -/*! \file AS_DCP_ATMOS.cpp - \version $Id$ - \brief AS-DCP library, Dolby Atmos essence reader and writer implementation -*/ - - -#include - -#include "AS_DCP.h" -#include "AS_DCP_internal.h" - -namespace ASDCP -{ -namespace ATMOS -{ - static std::string ATMOS_PACKAGE_LABEL = "File Package: SMPTE-GC frame wrapping of Dolby ATMOS data"; - static std::string ATMOS_DEF_LABEL = "Dolby ATMOS Data Track"; - static byte_t ATMOS_ESSENCE_CODING[SMPTE_UL_LENGTH] = { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x05, - 0x0e, 0x09, 0x06, 0x04, 0x00, 0x00, 0x00, 0x00 }; -} // namespace ATMOS -} // namespace ASDCP - -// -std::ostream& -ASDCP::ATMOS::operator << (std::ostream& strm, const AtmosDescriptor& ADesc) -{ - char str_buf[40]; - strm << " EditRate: " << ADesc.EditRate.Numerator << "/" << ADesc.EditRate.Denominator << std::endl; - strm << " ContainerDuration: " << (unsigned) ADesc.ContainerDuration << std::endl; - strm << " DataEssenceCoding: " << UL(ADesc.DataEssenceCoding).EncodeString(str_buf, 40) << std::endl; - strm << " AtmosVersion: " << (unsigned) ADesc.AtmosVersion << std::endl; - strm << " MaxChannelCount: " << (unsigned) ADesc.MaxChannelCount << std::endl; - strm << " MaxObjectCount: " << (unsigned) ADesc.MaxObjectCount << std::endl; - strm << " AtmosID: " << UUID(ADesc.AtmosID).EncodeString(str_buf, 40) << std::endl; - strm << " FirstFrame: " << (unsigned) ADesc.FirstFrame << std::endl; - return strm; -} - -// -void -ASDCP::ATMOS::AtmosDescriptorDump(const AtmosDescriptor& ADesc, FILE* stream) -{ - char str_buf[40]; - char atmosID_buf[40]; - if ( stream == 0 ) - stream = stderr; - - fprintf(stream, "\ - EditRate: %d/%d\n\ - ContainerDuration: %u\n\ - DataEssenceCoding: %s\n\ - AtmosVersion: %u\n\ - MaxChannelCount: %u\n\ - MaxObjectCount: %u\n\ - AtmosID: %s\n\ - FirsFrame: %u\n", - ADesc.EditRate.Numerator, ADesc.EditRate.Denominator, - ADesc.ContainerDuration, - UL(ADesc.DataEssenceCoding).EncodeString(str_buf, 40), - ADesc.AtmosVersion, - ADesc.MaxChannelCount, - ADesc.MaxObjectCount, - UUID(ADesc.AtmosID).EncodeString(atmosID_buf, 40), - ADesc.FirstFrame); -} - -// -bool -ASDCP::ATMOS::IsDolbyAtmos(const std::string& filename) -{ - // TODO - // For now use an atmos extension - bool result = ( 0 == (std::string("atmos").compare(Kumu::PathGetExtension(filename))) ); - return result; -} - - -//------------------------------------------------------------------------------------------ - -typedef std::list SubDescriptorList_t; - -class ASDCP::ATMOS::MXFReader::h__Reader : public ASDCP::h__ASDCPReader -{ - MXF::PrivateDCDataDescriptor* m_EssenceDescriptor; - MXF::DolbyAtmosSubDescriptor* m_EssenceSubDescriptor; - - KM_NO_COPY_CONSTRUCT(h__Reader); - h__Reader(); - - public: - ASDCP::DCData::DCDataDescriptor m_DDesc; - AtmosDescriptor m_ADesc; - - h__Reader(const Dictionary& d) : - ASDCP::h__ASDCPReader(d), m_EssenceDescriptor(0), m_EssenceSubDescriptor(0) {} - virtual ~h__Reader() {} - Result_t OpenRead(const std::string&); - Result_t ReadFrame(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*); - Result_t MD_to_DCData_DDesc(ASDCP::DCData::DCDataDescriptor& DDesc); - Result_t MD_to_Atmos_ADesc(ATMOS::AtmosDescriptor& ADesc); -}; - -ASDCP::Result_t -ASDCP::ATMOS::MXFReader::h__Reader::MD_to_DCData_DDesc(ASDCP::DCData::DCDataDescriptor& DDesc) -{ - ASDCP_TEST_NULL(m_EssenceDescriptor); - MXF::PrivateDCDataDescriptor* DDescObj = m_EssenceDescriptor; - DDesc.EditRate = DDescObj->SampleRate; - assert(DDescObj->ContainerDuration <= 0xFFFFFFFFL); - DDesc.ContainerDuration = static_cast(DDescObj->ContainerDuration); - memcpy(DDesc.DataEssenceCoding, DDescObj->DataEssenceCoding.Value(), SMPTE_UL_LENGTH); - return RESULT_OK; -} - -ASDCP::Result_t -ASDCP::ATMOS::MXFReader::h__Reader::MD_to_Atmos_ADesc(ATMOS::AtmosDescriptor& ADesc) -{ - ASDCP_TEST_NULL(m_EssenceSubDescriptor); - Result_t result = MD_to_DCData_DDesc(ADesc); - if( ASDCP_SUCCESS(result) ) - { - MXF::DolbyAtmosSubDescriptor* ADescObj = m_EssenceSubDescriptor; - ADesc.MaxChannelCount = ADescObj->MaxChannelCount; - ADesc.MaxObjectCount = ADescObj->MaxObjectCount; - ::memcpy(ADesc.AtmosID, ADescObj->AtmosID.Value(), UUIDlen); - ADesc.AtmosVersion = ADescObj->AtmosVersion; - ADesc.FirstFrame = ADescObj->FirstFrame; - } - return result; -} - -// -// -ASDCP::Result_t -ASDCP::ATMOS::MXFReader::h__Reader::OpenRead(const std::string& filename) -{ - Result_t result = OpenMXFRead(filename); - m_EssenceDescriptor = 0; - - if ( KM_SUCCESS(result) ) - { - InterchangeObject* iObj = 0; - result = m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(PrivateDCDataDescriptor), &iObj); - - if ( KM_SUCCESS(result) ) - { - m_EssenceDescriptor = static_cast(iObj); - } - } - - if ( m_EssenceDescriptor == 0 ) - { - DefaultLogSink().Error("DCDataDescriptor object not found in Atmos file.\n"); - result = RESULT_FORMAT; - } - - if ( KM_SUCCESS(result) ) - { - result = MD_to_DCData_DDesc(m_DDesc); - } - - // check for sample/frame rate sanity - if ( ASDCP_SUCCESS(result) - && m_DDesc.EditRate != EditRate_24 - && m_DDesc.EditRate != EditRate_25 - && m_DDesc.EditRate != EditRate_30 - && m_DDesc.EditRate != EditRate_48 - && m_DDesc.EditRate != EditRate_50 - && m_DDesc.EditRate != EditRate_60 - && m_DDesc.EditRate != EditRate_96 - && m_DDesc.EditRate != EditRate_100 - && m_DDesc.EditRate != EditRate_120 - && m_DDesc.EditRate != EditRate_192 - && m_DDesc.EditRate != EditRate_200 - && m_DDesc.EditRate != EditRate_240 ) - { - DefaultLogSink().Error("DC Data file EditRate is not a supported value: %d/%d\n", // lu - m_DDesc.EditRate.Numerator, m_DDesc.EditRate.Denominator); - - return RESULT_FORMAT; - } - - if( ASDCP_SUCCESS(result) ) - { - - if (NULL == m_EssenceSubDescriptor) - { - InterchangeObject* iObj = NULL; - result = m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(DolbyAtmosSubDescriptor), &iObj); - m_EssenceSubDescriptor = static_cast(iObj); - - if ( iObj == 0 ) - { - DefaultLogSink().Error("DolbyAtmosSubDescriptor object not found.\n"); - return RESULT_FORMAT; - } - } - - if ( ASDCP_SUCCESS(result) ) - { - result = MD_to_Atmos_ADesc(m_ADesc); - } - } - - return result; -} - -// -ASDCP::Result_t -ASDCP::ATMOS::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, FrameBuffer& FrameBuf, - AESDecContext* Ctx, HMACContext* HMAC) -{ - if ( ! m_File.IsOpen() ) - return RESULT_INIT; - - assert(m_Dict); - return ReadEKLVFrame(FrameNum, FrameBuf, m_Dict->ul(MDD_PrivateDCDataEssence), Ctx, HMAC); -} - - -//------------------------------------------------------------------------------------------ - -ASDCP::ATMOS::MXFReader::MXFReader() -{ - m_Reader = new h__Reader(AtmosSMPTEDict()); -} - - -ASDCP::ATMOS::MXFReader::~MXFReader() -{ - if ( m_Reader && m_Reader->m_File.IsOpen() ) - m_Reader->Close(); -} - -// Warning: direct manipulation of MXF structures can interfere -// with the normal operation of the wrapper. Caveat emptor! -// -ASDCP::MXF::OP1aHeader& -ASDCP::ATMOS::MXFReader::OP1aHeader() -{ - if ( m_Reader.empty() ) - { - assert(g_OP1aHeader); - return *g_OP1aHeader; - } - - return m_Reader->m_HeaderPart; -} - -// Warning: direct manipulation of MXF structures can interfere -// with the normal operation of the wrapper. Caveat emptor! -// -ASDCP::MXF::OPAtomIndexFooter& -ASDCP::ATMOS::MXFReader::OPAtomIndexFooter() -{ - if ( m_Reader.empty() ) - { - assert(g_OPAtomIndexFooter); - return *g_OPAtomIndexFooter; - } - - return m_Reader->m_IndexAccess; -} - -// Warning: direct manipulation of MXF structures can interfere -// with the normal operation of the wrapper. Caveat emptor! -// -ASDCP::MXF::RIP& -ASDCP::ATMOS::MXFReader::RIP() -{ - if ( m_Reader.empty() ) - { - assert(g_RIP); - return *g_RIP; - } - - return m_Reader->m_RIP; -} - -// Open the file for reading. The file must exist. Returns error if the -// operation cannot be completed. -ASDCP::Result_t -ASDCP::ATMOS::MXFReader::OpenRead(const std::string& filename) const -{ - return m_Reader->OpenRead(filename); -} - -// -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() ) - return m_Reader->ReadFrame(FrameNum, FrameBuf, Ctx, HMAC); - - return RESULT_INIT; -} - -ASDCP::Result_t -ASDCP::ATMOS::MXFReader::LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const -{ - return m_Reader->LocateFrame(FrameNum, streamOffset, temporalOffset, keyFrameOffset); -} - - -// Fill the struct with the values from the file's header. -// Returns RESULT_INIT if the file is not open. -ASDCP::Result_t -ASDCP::ATMOS::MXFReader::FillAtmosDescriptor(AtmosDescriptor& ADesc) const -{ - if ( m_Reader && m_Reader->m_File.IsOpen() ) - { - ADesc = m_Reader->m_ADesc; - return RESULT_OK; - } - - return RESULT_INIT; -} - - -// Fill the struct with the values from the file's header. -// Returns RESULT_INIT if the file is not open. -ASDCP::Result_t -ASDCP::ATMOS::MXFReader::FillWriterInfo(WriterInfo& Info) const -{ - if ( m_Reader && m_Reader->m_File.IsOpen() ) - { - Info = m_Reader->m_Info; - return RESULT_OK; - } - - return RESULT_INIT; -} - -// -void -ASDCP::ATMOS::MXFReader::DumpHeaderMetadata(FILE* stream) const -{ - if ( m_Reader->m_File.IsOpen() ) - m_Reader->m_HeaderPart.Dump(stream); -} - -// -void -ASDCP::ATMOS::MXFReader::DumpIndex(FILE* stream) const -{ - if ( m_Reader->m_File.IsOpen() ) - m_Reader->m_IndexAccess.Dump(stream); -} - -// -ASDCP::Result_t -ASDCP::ATMOS::MXFReader::Close() const -{ - if ( m_Reader && m_Reader->m_File.IsOpen() ) - { - m_Reader->Close(); - return RESULT_OK; - } - - return RESULT_INIT; -} - - -//------------------------------------------------------------------------------------------ - -// -class ASDCP::ATMOS::MXFWriter::h__Writer : public ASDCP::h__ASDCPWriter -{ - ASDCP::DCData::DCDataDescriptor m_DDesc; - byte_t m_EssenceUL[SMPTE_UL_LENGTH]; - MXF::DolbyAtmosSubDescriptor* m_EssenceSubDescriptor; - - ASDCP_NO_COPY_CONSTRUCT(h__Writer); - h__Writer(); - - public: - AtmosDescriptor m_ADesc; - - h__Writer(const Dictionary& d) : ASDCP::h__ASDCPWriter(d), - m_EssenceSubDescriptor(0), m_ADesc() { - memset(m_EssenceUL, 0, SMPTE_UL_LENGTH); - } - - virtual ~h__Writer(){} - - Result_t OpenWrite(const std::string&, ui32_t HeaderSize, const AtmosDescriptor& ADesc); - Result_t SetSourceStream(const DCData::DCDataDescriptor&, const byte_t*, const std::string&, const std::string&); - Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0); - Result_t Finalize(); - Result_t DCData_DDesc_to_MD(ASDCP::DCData::DCDataDescriptor& DDesc); - Result_t Atmos_ADesc_to_MD(const AtmosDescriptor& ADesc); -}; - -// -ASDCP::Result_t -ASDCP::ATMOS::MXFWriter::h__Writer::DCData_DDesc_to_MD(ASDCP::DCData::DCDataDescriptor& DDesc) -{ - ASDCP_TEST_NULL(m_EssenceDescriptor); - MXF::PrivateDCDataDescriptor* DDescObj = static_cast(m_EssenceDescriptor); - - DDescObj->SampleRate = DDesc.EditRate; - DDescObj->ContainerDuration = DDesc.ContainerDuration; - DDescObj->DataEssenceCoding.Set(DDesc.DataEssenceCoding); - return RESULT_OK; -} - -// -ASDCP::Result_t -ASDCP::ATMOS::MXFWriter::h__Writer::Atmos_ADesc_to_MD(const AtmosDescriptor& ADesc) -{ - ASDCP_TEST_NULL(m_EssenceDescriptor); - ASDCP_TEST_NULL(m_EssenceSubDescriptor); - MXF::DolbyAtmosSubDescriptor * ADescObj = m_EssenceSubDescriptor; - ADescObj->MaxChannelCount = ADesc.MaxChannelCount; - ADescObj->MaxObjectCount = ADesc.MaxObjectCount; - ADescObj->AtmosID.Set(ADesc.AtmosID); - ADescObj->AtmosVersion = ADesc.AtmosVersion; - ADescObj->FirstFrame = ADesc.FirstFrame; - return RESULT_OK; -} - -// -ASDCP::Result_t -ASDCP::ATMOS::MXFWriter::h__Writer::OpenWrite(const std::string& filename, ui32_t HeaderSize, const AtmosDescriptor& ADesc) -{ - if ( ! m_State.Test_BEGIN() ) - return RESULT_STATE; - - Result_t result = m_File.OpenWrite(filename); - - if ( ASDCP_SUCCESS(result) ) - { - m_HeaderSize = HeaderSize; - m_EssenceDescriptor = new MXF::PrivateDCDataDescriptor(m_Dict); - m_EssenceSubDescriptor = new DolbyAtmosSubDescriptor(m_Dict); - SubDescriptorList_t subDescriptors; - subDescriptors.push_back(m_EssenceSubDescriptor); - - SubDescriptorList_t::const_iterator sDObj; - SubDescriptorList_t::const_iterator lastDescriptor = subDescriptors.end(); - for (sDObj = subDescriptors.begin(); sDObj != lastDescriptor; ++sDObj) - { - m_EssenceSubDescriptorList.push_back(*sDObj); - GenRandomValue((*sDObj)->InstanceUID); - m_EssenceDescriptor->SubDescriptors.push_back((*sDObj)->InstanceUID); - } - result = m_State.Goto_INIT(); - } - - if ( ASDCP_FAILURE(result) ) - delete m_EssenceSubDescriptor; - - if ( ASDCP_SUCCESS(result) ) - { - m_ADesc = ADesc; - memcpy(m_ADesc.DataEssenceCoding, ATMOS_ESSENCE_CODING, SMPTE_UL_LENGTH); - result = Atmos_ADesc_to_MD(m_ADesc); - } - - return result; -} - -// -ASDCP::Result_t -ASDCP::ATMOS::MXFWriter::h__Writer::SetSourceStream(ASDCP::DCData::DCDataDescriptor const& DDesc, - const byte_t * essenceCoding, - const std::string& packageLabel, - const std::string& defLabel) -{ - if ( ! m_State.Test_INIT() ) - return RESULT_STATE; - - if ( DDesc.EditRate != EditRate_24 - && DDesc.EditRate != EditRate_25 - && DDesc.EditRate != EditRate_30 - && DDesc.EditRate != EditRate_48 - && DDesc.EditRate != EditRate_50 - && DDesc.EditRate != EditRate_60 - && DDesc.EditRate != EditRate_96 - && DDesc.EditRate != EditRate_100 - && DDesc.EditRate != EditRate_120 - && DDesc.EditRate != EditRate_192 - && DDesc.EditRate != EditRate_200 - && DDesc.EditRate != EditRate_240 ) - { - DefaultLogSink().Error("DCDataDescriptor.EditRate is not a supported value: %d/%d\n", - DDesc.EditRate.Numerator, DDesc.EditRate.Denominator); - return RESULT_RAW_FORMAT; - } - - assert(m_Dict); - m_DDesc = DDesc; - if (NULL != essenceCoding) - memcpy(m_DDesc.DataEssenceCoding, essenceCoding, SMPTE_UL_LENGTH); - Result_t result = DCData_DDesc_to_MD(m_DDesc); - - if ( ASDCP_SUCCESS(result) ) - { - memcpy(m_EssenceUL, m_Dict->ul(MDD_PrivateDCDataEssence), SMPTE_UL_LENGTH); - m_EssenceUL[SMPTE_UL_LENGTH-1] = 1; // first (and only) essence container - result = m_State.Goto_READY(); - } - - if ( ASDCP_SUCCESS(result) ) - { - ui32_t TCFrameRate = m_DDesc.EditRate.Numerator; - - result = WriteASDCPHeader(packageLabel, UL(m_Dict->ul(MDD_PrivateDCDataWrappingFrame)), - defLabel, UL(m_EssenceUL), UL(m_Dict->ul(MDD_DataDataDef)), - m_DDesc.EditRate, TCFrameRate); - } - - return result; -} - -// -ASDCP::Result_t -ASDCP::ATMOS::MXFWriter::h__Writer::WriteFrame(const FrameBuffer& FrameBuf, - ASDCP::AESEncContext* Ctx, ASDCP::HMACContext* HMAC) -{ - Result_t result = RESULT_OK; - - if ( m_State.Test_READY() ) - result = m_State.Goto_RUNNING(); // first time through - - ui64_t StreamOffset = m_StreamOffset; - - if ( ASDCP_SUCCESS(result) ) - result = WriteEKLVPacket(FrameBuf, m_EssenceUL, MXF_BER_LENGTH, Ctx, HMAC); - - if ( ASDCP_SUCCESS(result) ) - { - IndexTableSegment::IndexEntry Entry; - Entry.StreamOffset = StreamOffset; - m_FooterPart.PushIndexEntry(Entry); - m_FramesWritten++; - } - return result; -} - -// Closes the MXF file, writing the index and other closing information. -// -ASDCP::Result_t -ASDCP::ATMOS::MXFWriter::h__Writer::Finalize() -{ - if ( ! m_State.Test_RUNNING() ) - return RESULT_STATE; - - m_State.Goto_FINAL(); - - return WriteASDCPFooter(); -} - - - -//------------------------------------------------------------------------------------------ - -ASDCP::ATMOS::MXFWriter::MXFWriter() -{ -} - -ASDCP::ATMOS::MXFWriter::~MXFWriter() -{ -} - -// Warning: direct manipulation of MXF structures can interfere -// with the normal operation of the wrapper. Caveat emptor! -// -ASDCP::MXF::OP1aHeader& -ASDCP::ATMOS::MXFWriter::OP1aHeader() -{ - if ( m_Writer.empty() ) - { - assert(g_OP1aHeader); - return *g_OP1aHeader; - } - - return m_Writer->m_HeaderPart; -} - -// Warning: direct manipulation of MXF structures can interfere -// with the normal operation of the wrapper. Caveat emptor! -// -ASDCP::MXF::OPAtomIndexFooter& -ASDCP::ATMOS::MXFWriter::OPAtomIndexFooter() -{ - if ( m_Writer.empty() ) - { - assert(g_OPAtomIndexFooter); - return *g_OPAtomIndexFooter; - } - - return m_Writer->m_FooterPart; -} - -// Warning: direct manipulation of MXF structures can interfere -// with the normal operation of the wrapper. Caveat emptor! -// -ASDCP::MXF::RIP& -ASDCP::ATMOS::MXFWriter::RIP() -{ - if ( m_Writer.empty() ) - { - assert(g_RIP); - return *g_RIP; - } - - return m_Writer->m_RIP; -} - -// Open the file for writing. The file must not exist. Returns error if -// the operation cannot be completed. -ASDCP::Result_t -ASDCP::ATMOS::MXFWriter::OpenWrite(const std::string& filename, const WriterInfo& Info, - const AtmosDescriptor& ADesc, ui32_t HeaderSize) -{ - if ( Info.LabelSetType != LS_MXF_SMPTE ) - { - DefaultLogSink().Error("Atmos support requires LS_MXF_SMPTE\n"); - return RESULT_FORMAT; - } - - m_Writer = new h__Writer(AtmosSMPTEDict()); - m_Writer->m_Info = Info; - - Result_t result = m_Writer->OpenWrite(filename, HeaderSize, ADesc); - - if ( ASDCP_SUCCESS(result) ) - result = m_Writer->SetSourceStream(ADesc, ATMOS_ESSENCE_CODING, ATMOS_PACKAGE_LABEL, - ATMOS_DEF_LABEL); - - if ( ASDCP_FAILURE(result) ) - m_Writer.release(); - - return result; -} - -// Writes a frame of essence to the MXF file. If the optional AESEncContext -// argument is present, the essence is encrypted prior to writing. -// Fails if the file is not open, is finalized, or an operating system -// error occurs. -ASDCP::Result_t -ASDCP::ATMOS::MXFWriter::WriteFrame(const DCData::FrameBuffer& FrameBuf, AESEncContext* Ctx, HMACContext* HMAC) -{ - if ( m_Writer.empty() ) - return RESULT_INIT; - - return m_Writer->WriteFrame(FrameBuf, Ctx, HMAC); -} - -// Closes the MXF file, writing the index and other closing information. -ASDCP::Result_t -ASDCP::ATMOS::MXFWriter::Finalize() -{ - if ( m_Writer.empty() ) - return RESULT_INIT; - - return m_Writer->Finalize(); -} - - -// -// end AS_DCP_ATMOS.cpp -// - - diff --git a/src/AS_DCP_DCData.cpp b/src/AS_DCP_DCData.cpp index 245b46b..7641f1b 100644 --- a/src/AS_DCP_DCData.cpp +++ b/src/AS_DCP_DCData.cpp @@ -90,7 +90,7 @@ class ASDCP::DCData::MXFReader::h__Reader : public ASDCP::h__ASDCPReader Result_t OpenRead(const std::string&); Result_t ReadFrame(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*); Result_t MD_to_DCData_DDesc(const MXF::DCDataDescriptor& descriptor_object, DCData::DCDataDescriptor& DDesc); - Result_t MD_to_DCData_DDesc(const MXF::PrivateDCDataDescriptor& descriptor_object, DCData::DCDataDescriptor& DDesc); + Result_t MD_to_DCData_DDesc(const MXF::IADataEssenceDescriptor& descriptor_object, DCData::DCDataDescriptor& DDesc); }; // @@ -107,7 +107,7 @@ ASDCP::DCData::MXFReader::h__Reader::MD_to_DCData_DDesc(const MXF::DCDataDescrip // ASDCP::Result_t -ASDCP::DCData::MXFReader::h__Reader::MD_to_DCData_DDesc(const MXF::PrivateDCDataDescriptor& descriptor_object, +ASDCP::DCData::MXFReader::h__Reader::MD_to_DCData_DDesc(const MXF::IADataEssenceDescriptor& descriptor_object, DCData::DCDataDescriptor& DDesc) { DDesc.EditRate = descriptor_object.SampleRate; @@ -137,12 +137,12 @@ ASDCP::DCData::MXFReader::h__Reader::OpenRead(const std::string& filename) } else { - result = m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(PrivateDCDataDescriptor), &iObj); + result = m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(IADataEssenceDescriptor), &iObj); if ( KM_SUCCESS(result) ) { m_PrivateLabelCompatibilityMode = true; - const MXF::PrivateDCDataDescriptor* p = dynamic_cast(iObj); + const MXF::IADataEssenceDescriptor* p = dynamic_cast(iObj); assert(p); result = MD_to_DCData_DDesc(*p, m_DDesc); } @@ -191,7 +191,7 @@ ASDCP::DCData::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, FrameBuffer& Fra assert(m_Dict); if ( m_PrivateLabelCompatibilityMode ) { - return ReadEKLVFrame(FrameNum, FrameBuf, m_Dict->ul(MDD_PrivateDCDataEssence), Ctx, HMAC); + return ReadEKLVFrame(FrameNum, FrameBuf, m_Dict->ul(MDD_IADataElement), Ctx, HMAC); } return ReadEKLVFrame(FrameNum, FrameBuf, m_Dict->ul(MDD_DCDataEssence), Ctx, HMAC); diff --git a/src/AS_DCP_IAB.cpp b/src/AS_DCP_IAB.cpp new file mode 100644 index 0000000..9b27923 --- /dev/null +++ b/src/AS_DCP_IAB.cpp @@ -0,0 +1,693 @@ +/* +Copyright (c) 2004-2016, 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. +*/ +/*! \file AS_DCP_IAB.cpp + \version $Id$ + \brief AS-DCP library, IAB essence reader and writer implementation +*/ + + +#include + +#include "AS_DCP.h" +#include "AS_DCP_internal.h" + +namespace ASDCP +{ +namespace IAB +{ + static std::string IAB_PACKAGE_LABEL = "File Package: SMPTE-GC frame wrapping of IAB data"; + static std::string IAB_DEF_LABEL = "IAB Data Track"; + static byte_t IAB_ESSENCE_CODING[SMPTE_UL_LENGTH] = { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x05, + 0x0e, 0x09, 0x06, 0x04, 0x00, 0x00, 0x00, 0x00 }; +} // namespace IAB +} // namespace ASDCP + +// +std::ostream& +ASDCP::IAB::operator << (std::ostream& strm, const IABDescriptor& ADesc) +{ + char str_buf[40]; + strm << " EditRate: " << ADesc.EditRate.Numerator << "/" << ADesc.EditRate.Denominator << std::endl; + strm << " ContainerDuration: " << (unsigned) ADesc.ContainerDuration << std::endl; + strm << " DataEssenceCoding: " << UL(ADesc.DataEssenceCoding).EncodeString(str_buf, 40) << std::endl; + strm << " ImmersiveAudioVersion: " << (unsigned) ADesc.ImmersiveAudioVersion << std::endl; + strm << " MaxChannelCount: " << (unsigned) ADesc.MaxChannelCount << std::endl; + strm << " MaxObjectCount: " << (unsigned) ADesc.MaxObjectCount << std::endl; + strm << " ImmersiveAudioID: " << UUID(ADesc.ImmersiveAudioID).EncodeString(str_buf, 40) << std::endl; + strm << " FirstFrame: " << (unsigned) ADesc.FirstFrame << std::endl; + return strm; +} + +// +void +ASDCP::IAB::IADataEssenceSubDescriptorDump(const IABDescriptor& ADesc, FILE* stream) +{ + char str_buf[40]; + char ImmersiveAudioID_buf[40]; + if ( stream == 0 ) + stream = stderr; + + fprintf(stream, "\ + EditRate: %d/%d\n\ + ContainerDuration: %u\n\ + DataEssenceCoding: %s\n\ + ImmersiveAudioVersion: %u\n\ + MaxChannelCount: %u\n\ + MaxObjectCount: %u\n\ + ImmersiveAudioID: %s\n\ + FirsFrame: %u\n", + ADesc.EditRate.Numerator, ADesc.EditRate.Denominator, + ADesc.ContainerDuration, + UL(ADesc.DataEssenceCoding).EncodeString(str_buf, 40), + ADesc.ImmersiveAudioVersion, + ADesc.MaxChannelCount, + ADesc.MaxObjectCount, + UUID(ADesc.ImmersiveAudioID).EncodeString(ImmersiveAudioID_buf, 40), + ADesc.FirstFrame); +} + +// +bool +ASDCP::IAB::IsIAB(const std::string& filename) +{ + // TODO + // For now use an IAB extension + bool result = ( 0 == (std::string("atmos").compare(Kumu::PathGetExtension(filename))) ); + return result; +} + + +//------------------------------------------------------------------------------------------ + +typedef std::list SubDescriptorList_t; + +class ASDCP::IAB::MXFReader::h__Reader : public ASDCP::h__ASDCPReader +{ + MXF::IADataEssenceDescriptor* m_EssenceDescriptor; + MXF::IADataEssenceSubDescriptor* m_EssenceSubDescriptor; + + KM_NO_COPY_CONSTRUCT(h__Reader); + h__Reader(); + + public: + ASDCP::DCData::DCDataDescriptor m_DDesc; + IABDescriptor m_ADesc; + + h__Reader(const Dictionary& d) : + ASDCP::h__ASDCPReader(d), m_EssenceDescriptor(0), m_EssenceSubDescriptor(0) {} + virtual ~h__Reader() {} + Result_t OpenRead(const std::string&); + Result_t ReadFrame(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*); + Result_t MD_to_DCData_DDesc(ASDCP::DCData::DCDataDescriptor& DDesc); + Result_t MD_to_IAB_ADesc(IAB::IABDescriptor& ADesc); +}; + +ASDCP::Result_t +ASDCP::IAB::MXFReader::h__Reader::MD_to_DCData_DDesc(ASDCP::DCData::DCDataDescriptor& DDesc) +{ + ASDCP_TEST_NULL(m_EssenceDescriptor); + MXF::IADataEssenceDescriptor* DDescObj = m_EssenceDescriptor; + DDesc.EditRate = DDescObj->SampleRate; + assert(DDescObj->ContainerDuration <= 0xFFFFFFFFL); + DDesc.ContainerDuration = static_cast(DDescObj->ContainerDuration); + memcpy(DDesc.DataEssenceCoding, DDescObj->DataEssenceCoding.Value(), SMPTE_UL_LENGTH); + return RESULT_OK; +} + +ASDCP::Result_t +ASDCP::IAB::MXFReader::h__Reader::MD_to_IAB_ADesc(IAB::IABDescriptor& ADesc) +{ + ASDCP_TEST_NULL(m_EssenceSubDescriptor); + Result_t result = MD_to_DCData_DDesc(ADesc); + if( ASDCP_SUCCESS(result) ) + { + MXF::IADataEssenceSubDescriptor* ADescObj = m_EssenceSubDescriptor; + ADesc.MaxChannelCount = ADescObj->MaxChannelCount; + ADesc.MaxObjectCount = ADescObj->MaxObjectCount; + ::memcpy(ADesc.ImmersiveAudioID, ADescObj->ImmersiveAudioID.Value(), UUIDlen); + ADesc.ImmersiveAudioVersion = ADescObj->ImmersiveAudioVersion; + ADesc.FirstFrame = ADescObj->FirstFrame; + } + return result; +} + +// +// +ASDCP::Result_t +ASDCP::IAB::MXFReader::h__Reader::OpenRead(const std::string& filename) +{ + Result_t result = OpenMXFRead(filename); + m_EssenceDescriptor = 0; + + if ( KM_SUCCESS(result) ) + { + InterchangeObject* iObj = 0; + result = m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(IADataEssenceDescriptor), &iObj); + + if ( KM_SUCCESS(result) ) + { + m_EssenceDescriptor = static_cast(iObj); + } + } + + if ( m_EssenceDescriptor == 0 ) + { + DefaultLogSink().Error("DCDataDescriptor object not found in IAB file.\n"); + result = RESULT_FORMAT; + } + + if ( KM_SUCCESS(result) ) + { + result = MD_to_DCData_DDesc(m_DDesc); + } + + // check for sample/frame rate sanity + if ( ASDCP_SUCCESS(result) + && m_DDesc.EditRate != EditRate_24 + && m_DDesc.EditRate != EditRate_25 + && m_DDesc.EditRate != EditRate_30 + && m_DDesc.EditRate != EditRate_48 + && m_DDesc.EditRate != EditRate_50 + && m_DDesc.EditRate != EditRate_60 + && m_DDesc.EditRate != EditRate_96 + && m_DDesc.EditRate != EditRate_100 + && m_DDesc.EditRate != EditRate_120 + && m_DDesc.EditRate != EditRate_192 + && m_DDesc.EditRate != EditRate_200 + && m_DDesc.EditRate != EditRate_240 ) + { + DefaultLogSink().Error("DC Data file EditRate is not a supported value: %d/%d\n", // lu + m_DDesc.EditRate.Numerator, m_DDesc.EditRate.Denominator); + + return RESULT_FORMAT; + } + + if( ASDCP_SUCCESS(result) ) + { + + if (NULL == m_EssenceSubDescriptor) + { + InterchangeObject* iObj = NULL; + result = m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(IADataEssenceSubDescriptor), &iObj); + m_EssenceSubDescriptor = static_cast(iObj); + + if ( iObj == 0 ) + { + DefaultLogSink().Error("IADataEssenceSubDescriptor object not found.\n"); + return RESULT_FORMAT; + } + } + + if ( ASDCP_SUCCESS(result) ) + { + result = MD_to_IAB_ADesc(m_ADesc); + } + } + + return result; +} + +// +ASDCP::Result_t +ASDCP::IAB::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, FrameBuffer& FrameBuf, + AESDecContext* Ctx, HMACContext* HMAC) +{ + if ( ! m_File.IsOpen() ) + return RESULT_INIT; + + assert(m_Dict); + return ReadEKLVFrame(FrameNum, FrameBuf, m_Dict->ul(MDD_IADataElement), Ctx, HMAC); +} + + +//------------------------------------------------------------------------------------------ + +ASDCP::IAB::MXFReader::MXFReader() +{ + m_Reader = new h__Reader(IABSMPTEDict()); +} + + +ASDCP::IAB::MXFReader::~MXFReader() +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + m_Reader->Close(); +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::OP1aHeader& +ASDCP::IAB::MXFReader::OP1aHeader() +{ + if ( m_Reader.empty() ) + { + assert(g_OP1aHeader); + return *g_OP1aHeader; + } + + return m_Reader->m_HeaderPart; +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::OPAtomIndexFooter& +ASDCP::IAB::MXFReader::OPAtomIndexFooter() +{ + if ( m_Reader.empty() ) + { + assert(g_OPAtomIndexFooter); + return *g_OPAtomIndexFooter; + } + + return m_Reader->m_IndexAccess; +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::RIP& +ASDCP::IAB::MXFReader::RIP() +{ + if ( m_Reader.empty() ) + { + assert(g_RIP); + return *g_RIP; + } + + return m_Reader->m_RIP; +} + +// Open the file for reading. The file must exist. Returns error if the +// operation cannot be completed. +ASDCP::Result_t +ASDCP::IAB::MXFReader::OpenRead(const std::string& filename) const +{ + return m_Reader->OpenRead(filename); +} + +// +ASDCP::Result_t +ASDCP::IAB::MXFReader::ReadFrame(ui32_t FrameNum, DCData::FrameBuffer& FrameBuf, + AESDecContext* Ctx, HMACContext* HMAC) const +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + return m_Reader->ReadFrame(FrameNum, FrameBuf, Ctx, HMAC); + + return RESULT_INIT; +} + +ASDCP::Result_t +ASDCP::IAB::MXFReader::LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const +{ + return m_Reader->LocateFrame(FrameNum, streamOffset, temporalOffset, keyFrameOffset); +} + + +// Fill the struct with the values from the file's header. +// Returns RESULT_INIT if the file is not open. +ASDCP::Result_t +ASDCP::IAB::MXFReader::FillIABDescriptor(IABDescriptor& ADesc) const +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + { + ADesc = m_Reader->m_ADesc; + return RESULT_OK; + } + + return RESULT_INIT; +} + + +// Fill the struct with the values from the file's header. +// Returns RESULT_INIT if the file is not open. +ASDCP::Result_t +ASDCP::IAB::MXFReader::FillWriterInfo(WriterInfo& Info) const +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + { + Info = m_Reader->m_Info; + return RESULT_OK; + } + + return RESULT_INIT; +} + +// +void +ASDCP::IAB::MXFReader::DumpHeaderMetadata(FILE* stream) const +{ + if ( m_Reader->m_File.IsOpen() ) + m_Reader->m_HeaderPart.Dump(stream); +} + +// +void +ASDCP::IAB::MXFReader::DumpIndex(FILE* stream) const +{ + if ( m_Reader->m_File.IsOpen() ) + m_Reader->m_IndexAccess.Dump(stream); +} + +// +ASDCP::Result_t +ASDCP::IAB::MXFReader::Close() const +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + { + m_Reader->Close(); + return RESULT_OK; + } + + return RESULT_INIT; +} + + +//------------------------------------------------------------------------------------------ + +// +class ASDCP::IAB::MXFWriter::h__Writer : public ASDCP::h__ASDCPWriter +{ + ASDCP::DCData::DCDataDescriptor m_DDesc; + byte_t m_EssenceUL[SMPTE_UL_LENGTH]; + MXF::IADataEssenceSubDescriptor* m_EssenceSubDescriptor; + + ASDCP_NO_COPY_CONSTRUCT(h__Writer); + h__Writer(); + + public: + IABDescriptor m_ADesc; + + h__Writer(const Dictionary& d) : ASDCP::h__ASDCPWriter(d), + m_EssenceSubDescriptor(0), m_ADesc() { + memset(m_EssenceUL, 0, SMPTE_UL_LENGTH); + } + + virtual ~h__Writer(){} + + Result_t OpenWrite(const std::string&, ui32_t HeaderSize, const IABDescriptor& ADesc); + Result_t SetSourceStream(const DCData::DCDataDescriptor&, const byte_t*, const std::string&, const std::string&); + Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0); + Result_t Finalize(); + Result_t DCData_DDesc_to_MD(ASDCP::DCData::DCDataDescriptor& DDesc); + Result_t IAB_ADesc_to_MD(const IABDescriptor& ADesc); +}; + +// +ASDCP::Result_t +ASDCP::IAB::MXFWriter::h__Writer::DCData_DDesc_to_MD(ASDCP::DCData::DCDataDescriptor& DDesc) +{ + ASDCP_TEST_NULL(m_EssenceDescriptor); + MXF::IADataEssenceDescriptor* DDescObj = static_cast(m_EssenceDescriptor); + + DDescObj->SampleRate = DDesc.EditRate; + DDescObj->ContainerDuration = DDesc.ContainerDuration; + DDescObj->DataEssenceCoding.Set(DDesc.DataEssenceCoding); + return RESULT_OK; +} + +// +ASDCP::Result_t +ASDCP::IAB::MXFWriter::h__Writer::IAB_ADesc_to_MD(const IABDescriptor& ADesc) +{ + ASDCP_TEST_NULL(m_EssenceDescriptor); + ASDCP_TEST_NULL(m_EssenceSubDescriptor); + MXF::IADataEssenceSubDescriptor * ADescObj = m_EssenceSubDescriptor; + ADescObj->MaxChannelCount = ADesc.MaxChannelCount; + ADescObj->MaxObjectCount = ADesc.MaxObjectCount; + ADescObj->ImmersiveAudioID.Set(ADesc.ImmersiveAudioID); + ADescObj->ImmersiveAudioVersion = ADesc.ImmersiveAudioVersion; + ADescObj->FirstFrame = ADesc.FirstFrame; + return RESULT_OK; +} + +// +ASDCP::Result_t +ASDCP::IAB::MXFWriter::h__Writer::OpenWrite(const std::string& filename, ui32_t HeaderSize, const IABDescriptor& ADesc) +{ + if ( ! m_State.Test_BEGIN() ) + return RESULT_STATE; + + Result_t result = m_File.OpenWrite(filename); + + if ( ASDCP_SUCCESS(result) ) + { + m_HeaderSize = HeaderSize; + m_EssenceDescriptor = new MXF::IADataEssenceDescriptor(m_Dict); + m_EssenceSubDescriptor = new IADataEssenceSubDescriptor(m_Dict); + SubDescriptorList_t subDescriptors; + subDescriptors.push_back(m_EssenceSubDescriptor); + + SubDescriptorList_t::const_iterator sDObj; + SubDescriptorList_t::const_iterator lastDescriptor = subDescriptors.end(); + for (sDObj = subDescriptors.begin(); sDObj != lastDescriptor; ++sDObj) + { + m_EssenceSubDescriptorList.push_back(*sDObj); + GenRandomValue((*sDObj)->InstanceUID); + m_EssenceDescriptor->SubDescriptors.push_back((*sDObj)->InstanceUID); + } + result = m_State.Goto_INIT(); + } + + if ( ASDCP_FAILURE(result) ) + delete m_EssenceSubDescriptor; + + if ( ASDCP_SUCCESS(result) ) + { + m_ADesc = ADesc; + memcpy(m_ADesc.DataEssenceCoding, IAB_ESSENCE_CODING, SMPTE_UL_LENGTH); + result = IAB_ADesc_to_MD(m_ADesc); + } + + return result; +} + +// +ASDCP::Result_t +ASDCP::IAB::MXFWriter::h__Writer::SetSourceStream(ASDCP::DCData::DCDataDescriptor const& DDesc, + const byte_t * essenceCoding, + const std::string& packageLabel, + const std::string& defLabel) +{ + if ( ! m_State.Test_INIT() ) + return RESULT_STATE; + + if ( DDesc.EditRate != EditRate_24 + && DDesc.EditRate != EditRate_25 + && DDesc.EditRate != EditRate_30 + && DDesc.EditRate != EditRate_48 + && DDesc.EditRate != EditRate_50 + && DDesc.EditRate != EditRate_60 + && DDesc.EditRate != EditRate_96 + && DDesc.EditRate != EditRate_100 + && DDesc.EditRate != EditRate_120 + && DDesc.EditRate != EditRate_192 + && DDesc.EditRate != EditRate_200 + && DDesc.EditRate != EditRate_240 ) + { + DefaultLogSink().Error("DCDataDescriptor.EditRate is not a supported value: %d/%d\n", + DDesc.EditRate.Numerator, DDesc.EditRate.Denominator); + return RESULT_RAW_FORMAT; + } + + assert(m_Dict); + m_DDesc = DDesc; + if (NULL != essenceCoding) + memcpy(m_DDesc.DataEssenceCoding, essenceCoding, SMPTE_UL_LENGTH); + Result_t result = DCData_DDesc_to_MD(m_DDesc); + + if ( ASDCP_SUCCESS(result) ) + { + memcpy(m_EssenceUL, m_Dict->ul(MDD_IADataElement), SMPTE_UL_LENGTH); + m_EssenceUL[SMPTE_UL_LENGTH-1] = 1; // first (and only) essence container + result = m_State.Goto_READY(); + } + + if ( ASDCP_SUCCESS(result) ) + { + ui32_t TCFrameRate = m_DDesc.EditRate.Numerator; + + result = WriteASDCPHeader(packageLabel, UL(m_Dict->ul(MDD_MXF_GC_IAData_Frame_Wrapped)), + defLabel, UL(m_EssenceUL), UL(m_Dict->ul(MDD_DataDataDef)), + m_DDesc.EditRate, TCFrameRate); + } + + return result; +} + +// +ASDCP::Result_t +ASDCP::IAB::MXFWriter::h__Writer::WriteFrame(const FrameBuffer& FrameBuf, + ASDCP::AESEncContext* Ctx, ASDCP::HMACContext* HMAC) +{ + Result_t result = RESULT_OK; + + if ( m_State.Test_READY() ) + result = m_State.Goto_RUNNING(); // first time through + + ui64_t StreamOffset = m_StreamOffset; + + if ( ASDCP_SUCCESS(result) ) + result = WriteEKLVPacket(FrameBuf, m_EssenceUL, MXF_BER_LENGTH, Ctx, HMAC); + + if ( ASDCP_SUCCESS(result) ) + { + IndexTableSegment::IndexEntry Entry; + Entry.StreamOffset = StreamOffset; + m_FooterPart.PushIndexEntry(Entry); + m_FramesWritten++; + } + return result; +} + +// Closes the MXF file, writing the index and other closing information. +// +ASDCP::Result_t +ASDCP::IAB::MXFWriter::h__Writer::Finalize() +{ + if ( ! m_State.Test_RUNNING() ) + return RESULT_STATE; + + m_State.Goto_FINAL(); + + return WriteASDCPFooter(); +} + + + +//------------------------------------------------------------------------------------------ + +ASDCP::IAB::MXFWriter::MXFWriter() +{ +} + +ASDCP::IAB::MXFWriter::~MXFWriter() +{ +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::OP1aHeader& +ASDCP::IAB::MXFWriter::OP1aHeader() +{ + if ( m_Writer.empty() ) + { + assert(g_OP1aHeader); + return *g_OP1aHeader; + } + + return m_Writer->m_HeaderPart; +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::OPAtomIndexFooter& +ASDCP::IAB::MXFWriter::OPAtomIndexFooter() +{ + if ( m_Writer.empty() ) + { + assert(g_OPAtomIndexFooter); + return *g_OPAtomIndexFooter; + } + + return m_Writer->m_FooterPart; +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::RIP& +ASDCP::IAB::MXFWriter::RIP() +{ + if ( m_Writer.empty() ) + { + assert(g_RIP); + return *g_RIP; + } + + return m_Writer->m_RIP; +} + +// Open the file for writing. The file must not exist. Returns error if +// the operation cannot be completed. +ASDCP::Result_t +ASDCP::IAB::MXFWriter::OpenWrite(const std::string& filename, const WriterInfo& Info, + const IABDescriptor& ADesc, ui32_t HeaderSize) +{ + if ( Info.LabelSetType != LS_MXF_SMPTE ) + { + DefaultLogSink().Error("IAB support requires LS_MXF_SMPTE\n"); + return RESULT_FORMAT; + } + + m_Writer = new h__Writer(IABSMPTEDict()); + m_Writer->m_Info = Info; + + Result_t result = m_Writer->OpenWrite(filename, HeaderSize, ADesc); + + if ( ASDCP_SUCCESS(result) ) + result = m_Writer->SetSourceStream(ADesc, IAB_ESSENCE_CODING, IAB_PACKAGE_LABEL, + IAB_DEF_LABEL); + + if ( ASDCP_FAILURE(result) ) + m_Writer.release(); + + return result; +} + +// Writes a frame of essence to the MXF file. If the optional AESEncContext +// argument is present, the essence is encrypted prior to writing. +// Fails if the file is not open, is finalized, or an operating system +// error occurs. +ASDCP::Result_t +ASDCP::IAB::MXFWriter::WriteFrame(const DCData::FrameBuffer& FrameBuf, AESEncContext* Ctx, HMACContext* HMAC) +{ + if ( m_Writer.empty() ) + return RESULT_INIT; + + return m_Writer->WriteFrame(FrameBuf, Ctx, HMAC); +} + +// Closes the MXF file, writing the index and other closing information. +ASDCP::Result_t +ASDCP::IAB::MXFWriter::Finalize() +{ + if ( m_Writer.empty() ) + return RESULT_INIT; + + return m_Writer->Finalize(); +} + + +// +// end AS_DCP_IAB.cpp +// + + diff --git a/src/AS_DCP_MXF.cpp b/src/AS_DCP_MXF.cpp index d3606fe..8dc25f9 100755 --- a/src/AS_DCP_MXF.cpp +++ b/src/AS_DCP_MXF.cpp @@ -216,11 +216,11 @@ ASDCP::EssenceType(const std::string& filename, EssenceType_t& type) type = ESS_TIMED_TEXT; } else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(DCDataDescriptor))) - || ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(PrivateDCDataDescriptor))) ) + || ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(IADataEssenceDescriptor))) ) { - if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(DolbyAtmosSubDescriptor))) ) + if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(IADataEssenceSubDescriptor))) ) { - type = ESS_DCDATA_DOLBY_ATMOS; + type = ESS_DCDATA_IAB; } else { @@ -388,9 +388,9 @@ ASDCP::RawEssenceType(const std::string& filename, EssenceType_t& type) { type = ESS_TIMED_TEXT; } - else if ( ASDCP::ATMOS::IsDolbyAtmos(filename) ) + else if ( ASDCP::IAB::IsIAB(filename) ) { - type = ESS_DCDATA_DOLBY_ATMOS; + type = ESS_DCDATA_IAB; } } } @@ -445,9 +445,9 @@ ASDCP::RawEssenceType(const std::string& filename, EssenceType_t& type) return RESULT_FORMAT; } } - else if ( ASDCP::ATMOS::IsDolbyAtmos(Kumu::PathJoin(filename, next_file)) ) + else if ( ASDCP::IAB::IsIAB(Kumu::PathJoin(filename, next_file)) ) { - type = ESS_DCDATA_DOLBY_ATMOS; + type = ESS_DCDATA_IAB; } else { diff --git a/src/AtmosSyncChannel_Generator.cpp b/src/AtmosSyncChannel_Generator.cpp deleted file mode 100644 index b9b8c44..0000000 --- a/src/AtmosSyncChannel_Generator.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/* -Copyright (c) 2013-2013, 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. -*/ -/*! \file AtmosSyncChannel_Generator.cpp - \version $Id$ - \brief Dolby Atmos sync channel generator implementation -*/ - -#include - -#include - -using namespace ASDCP; - -// -ASDCP::PCM::AtmosSyncChannelGenerator::AtmosSyncChannelGenerator(ui16_t bitsPerSample, ui32_t sampleRate, - const ASDCP::Rational& editRate, const byte_t* uuid) - : m_syncEncoder(), - m_audioTrackUUID(), - m_ADesc(), - m_syncSignalBuffer(NULL), - m_numSamplesPerFrame(0), - m_currentFrameNumber(0), - m_numBytesPerFrame(0), - m_isSyncEncoderInitialized(false) -{ - - m_ADesc.EditRate = editRate; - m_ADesc.ChannelCount = 1; - m_ADesc.QuantizationBits = bitsPerSample; - m_ADesc.AudioSamplingRate = Rational(sampleRate, 1); - m_ADesc.BlockAlign = ((bitsPerSample + 7) / 8); - m_ADesc.AvgBps = (sampleRate * m_ADesc.BlockAlign); - - memcpy(&m_audioTrackUUID.abyUUIDBytes[0], uuid, UUIDlen); - m_numSamplesPerFrame = (editRate.Denominator * sampleRate) / editRate.Numerator; - m_numBytesPerFrame = m_numSamplesPerFrame * m_ADesc.BlockAlign; - - if (bitsPerSample == 24) - { - ui32_t frameRate = editRate.Numerator/editRate.Denominator; // intentionally allowing for imprecise cast to int - m_isSyncEncoderInitialized = (SyncEncoderInit(&m_syncEncoder, sampleRate, frameRate, &m_audioTrackUUID) == SYNC_ENCODER_ERROR_NONE); - m_syncSignalBuffer = new float[m_numSamplesPerFrame]; - } - else - { - m_isSyncEncoderInitialized = false; - } -} - -ASDCP::PCM::AtmosSyncChannelGenerator::~AtmosSyncChannelGenerator() -{ - delete [] m_syncSignalBuffer; -} - -ASDCP::Result_t -ASDCP::PCM::AtmosSyncChannelGenerator::ReadFrame(FrameBuffer& OutFB) -{ - if (OutFB.Capacity() < m_numBytesPerFrame) - { - return RESULT_SMALLBUF; - } - - /** - * Update frame number and size. - */ - OutFB.FrameNumber(m_currentFrameNumber); - OutFB.Size(m_numBytesPerFrame); - - /** - * Get pointer to frame essence. - */ - byte_t* frameEssence = OutFB.Data(); - - if (m_isSyncEncoderInitialized) - { - /** - * Generate sync signal frame. - */ - int ret = EncodeSync(&m_syncEncoder, m_numSamplesPerFrame, m_syncSignalBuffer, m_currentFrameNumber); - if (ret == SYNC_ENCODER_ERROR_NONE) - { - for (unsigned int i = 0; i < m_numSamplesPerFrame; ++i) - { - /** - * Convert each encoded float sample to a signed 24 bit integer and - * copy into the essence buffer. - */ - i32_t sample = convertSampleFloatToInt24(m_syncSignalBuffer[i]); - memcpy(frameEssence, ((byte_t*)(&sample))+1, NUM_BYTES_PER_INT24); - frameEssence += NUM_BYTES_PER_INT24; - } - } - else - { - /** - * Encoding error, zero out the frame. - */ - memset(frameEssence, 0, m_numBytesPerFrame); - } - } - else - { - /** - * Sync encoder not initialize, zero out the frame. - */ - memset(frameEssence, 0, m_numBytesPerFrame); - } - ++m_currentFrameNumber; - return RESULT_OK; -} - -ASDCP::Result_t -ASDCP::PCM::AtmosSyncChannelGenerator::Reset() -{ - m_currentFrameNumber = 0; - return RESULT_OK; -} - -Result_t -ASDCP::PCM::AtmosSyncChannelGenerator::FillAudioDescriptor(AudioDescriptor& ADesc) const -{ - ADesc = m_ADesc; - return RESULT_OK; -} - diff --git a/src/AtmosSyncChannel_Generator.h b/src/AtmosSyncChannel_Generator.h deleted file mode 100644 index d7f4219..0000000 --- a/src/AtmosSyncChannel_Generator.h +++ /dev/null @@ -1,151 +0,0 @@ -/* -Copyright (c) 2013-2013, 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. -*/ -/*! \file AtmosSyncChannel_Generator.h - \version $Id$ - \brief Dolby Atmos sync channel generator -*/ - -#ifndef _ATMOSSYNCCHANNEL_GENERATOR_H_ -#define _ATMOSSYNCCHANNEL_GENERATOR_H_ - -#include -#include "SyncEncoder.h" -#include "UUIDInformation.h" - -#define INT24_MAX 8388607.0 -#define INT24_MIN -8388608.0 - -namespace ASDCP -{ - namespace ATMOS - { - static const ui32_t SYNC_CHANNEL = 14; - } - - namespace PCM - { - - static const ui16_t NUM_BYTES_PER_INT24 = 3; - - class AtmosSyncChannelGenerator - { - SYNCENCODER m_syncEncoder; - UUIDINFORMATION m_audioTrackUUID; - AudioDescriptor m_ADesc; - float *m_syncSignalBuffer; - ui32_t m_numSamplesPerFrame; - ui32_t m_currentFrameNumber; - ui32_t m_numBytesPerFrame; - bool m_isSyncEncoderInitialized; - - ASDCP_NO_COPY_CONSTRUCT(AtmosSyncChannelGenerator); - - public: - /** - * Constructor - * - * @param bitsPerSample the number of bits in each sample of pcm data - * @param sampleRate the sampling rate - * @param editRate the edit rate of the associated picture track. - * @param atmosUUID the UUID of the associated ATMOS track file. - * - */ - AtmosSyncChannelGenerator(ui16_t bitsPerSample, ui32_t sampleRate, - const ASDCP::Rational& editRate, const byte_t* uuid); - ~AtmosSyncChannelGenerator(); - - /** - * Set the frame number when seeking - * Use override the default starting frame number for a new track or - * to set the frame number when doing random access. - * - * @param frameNumber - * - */ - void setFrameNumber(ui32_t frameNumber) { m_currentFrameNumber = frameNumber; }; - - /** - * Get the number of bytes per frame. - * - * @return Number of bytes per frame - * - */ - ui32_t getBytesPerFrame() { return m_numBytesPerFrame; } - - /** - * Generates the next frame of sync data. - * Generates the next frame of sync data and places it - * the frame buffer. Fails if the buffer is too small. - * **Automatically increments the frame number.** - * - * @param buf the buffer that the generated frame data will be written to. - * - * @return Kumu::RESULT_OK if the buffer is succesfully filled with sync - * data for the next frame. - */ - Result_t ReadFrame(FrameBuffer& buf); - - /** - * Reset the frame count. - * - * @return Kumu::RESULT_OK - */ - Result_t Reset(); - - /** - * Fill the AudioDescriptor with the relevant information. - * - * @return Kumu::RESULT_OK - */ - Result_t FillAudioDescriptor(PCM::AudioDescriptor& ADesc) const; - - /** - * Converts a sample float into - * 24-bit PCM data. - * - */ - static inline i32_t convertSampleFloatToInt24(float sample) - { - if (sample >= 0.0) - { - return (static_cast(sample * INT24_MAX) << 8); - } - else - { - return (static_cast(-sample * INT24_MIN) << 8); - } - } - }; - - } // namespace PCM -} // namespace ASDCP - -#endif // _ATMOSSYNCCHANNEL_GENERATOR_H_ - -// -// end AtmosSyncChannel_Generator.h -// diff --git a/src/AtmosSyncChannel_Mixer.cpp b/src/AtmosSyncChannel_Mixer.cpp deleted file mode 100644 index b035341..0000000 --- a/src/AtmosSyncChannel_Mixer.cpp +++ /dev/null @@ -1,368 +0,0 @@ -/* -Copyright (c) 2013-2014, 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. -*/ -/*! \file AtmosSyncChannel_Mixer.cpp - \version $Id$ - \brief Read WAV files(s), multiplex multiple PCM frame buffers including Atmos Sync into one -*/ - -#include - -#include - -#include -#include -#include - -using namespace ASDCP; -using namespace Kumu; - -// -ASDCP::AtmosSyncChannelMixer::AtmosSyncChannelMixer(const byte_t * trackUUID) - : m_inputs(), m_outputs(), m_trackUUID(), m_ADesc(), m_ChannelCount(0), m_FramesRead(0) -{ - ::memcpy(m_trackUUID, trackUUID, UUIDlen); -} - -ASDCP::AtmosSyncChannelMixer::~AtmosSyncChannelMixer() -{ - clear(); -} - -void -ASDCP::AtmosSyncChannelMixer::clear() -{ - m_outputs.clear(); - std::for_each(m_inputs.begin(), m_inputs.end(), delete_input()); - m_inputs.clear(); -} - -// -Result_t -ASDCP::AtmosSyncChannelMixer::OpenRead(ui32_t argc, const char** argv, const Rational& PictureRate) -{ - ASDCP_TEST_NULL(argv); - PathList_t TmpFileList; - - for ( ui32_t i = 0; i < argc; ++i ) - { - ASDCP_TEST_NULL_STR(argv[i]); - TmpFileList.push_back(argv[i]); - } - - return OpenRead(TmpFileList, PictureRate); -} - -// -Result_t -ASDCP::AtmosSyncChannelMixer::OpenRead(const Kumu::PathList_t& argv, const Rational& PictureRate) -{ - Result_t result = RESULT_OK; - PathList_t::iterator fi; - Kumu::PathList_t file_list; - PCM::AudioDescriptor tmpDesc; - - if ( argv.size() == 1 && PathIsDirectory(argv.front()) ) - { - DirScanner Dir; - char name_buf[MaxFilePath]; - result = Dir.Open(argv.front().c_str()); - - if ( KM_SUCCESS(result) ) - result = Dir.GetNext(name_buf); - - while ( KM_SUCCESS(result) ) - { - if ( name_buf[0] != '.' ) // no hidden files - { - std::string tmp_path = argv.front() + "/" + name_buf; - file_list.push_back(tmp_path); - } - - result = Dir.GetNext(name_buf); - } - - if ( result == RESULT_ENDOFFILE ) - { - result = RESULT_OK; - file_list.sort(); - } - } - else - { - file_list = argv; - } - - for ( fi = file_list.begin(); KM_SUCCESS(result) && fi != file_list.end(); ++fi ) - { - result = OpenRead(*fi, PictureRate); - } - - if ( ASDCP_SUCCESS(result) && (m_ChannelCount < ATMOS::SYNC_CHANNEL)) - { - // atmos sync channel has not been added - result = MixInSilenceChannels(); - if ( ASDCP_SUCCESS(result) ) - result = MixInAtmosSyncChannel(); - } - - if ( ASDCP_SUCCESS(result) ) - { - m_ADesc.ChannelCount = m_ChannelCount; - m_ADesc.AvgBps = (ui32_t)(ceil(m_ADesc.AudioSamplingRate.Quotient()) * m_ADesc.BlockAlign); - } - else - { - clear(); - } - - return result; -} - -// -Result_t -ASDCP::AtmosSyncChannelMixer::OpenRead(const std::string& file, const Rational& PictureRate) -{ - Result_t result = RESULT_OK; - PCM::AudioDescriptor tmpDesc; - ui32_t numChannels = 0; - mem_ptr I = new WAVDataProvider; - result = I->OpenRead(file.c_str(), PictureRate); - - if ( ASDCP_SUCCESS(result)) - { - result = I->FillAudioDescriptor(tmpDesc); - } - - if ( ASDCP_SUCCESS(result) ) - { - - if ( m_ChannelCount == 0 ) - { - m_ADesc = tmpDesc; - } - else - { - - if ( tmpDesc.AudioSamplingRate != m_ADesc.AudioSamplingRate ) - { - DefaultLogSink().Error("AudioSamplingRate mismatch in PCM parser list."); - return RESULT_FORMAT; - } - - if ( tmpDesc.QuantizationBits != m_ADesc.QuantizationBits ) - { - DefaultLogSink().Error("QuantizationBits mismatch in PCM parser list."); - return RESULT_FORMAT; - } - - if ( tmpDesc.ContainerDuration < m_ADesc.ContainerDuration ) - m_ADesc.ContainerDuration = tmpDesc.ContainerDuration; - - m_ADesc.BlockAlign += tmpDesc.BlockAlign; - } - } - - - if ( ASDCP_SUCCESS(result) ) - { - numChannels = tmpDesc.ChannelCount; // default to all channels - if ((m_ChannelCount < ATMOS::SYNC_CHANNEL) && (m_ChannelCount + numChannels) > (ATMOS::SYNC_CHANNEL - 1)) - { - // need to insert an atmos channel between the channels of this file. - numChannels = ATMOS::SYNC_CHANNEL - m_ChannelCount - 1; - m_outputs.push_back(std::make_pair(numChannels, I.get())); - m_ChannelCount += numChannels; - MixInAtmosSyncChannel(); - numChannels = tmpDesc.ChannelCount - numChannels; - } - m_outputs.push_back(std::make_pair(numChannels, I.get())); - m_inputs.push_back(I); - I.release(); - m_ChannelCount += numChannels; - } - return result; -} - -Result_t -ASDCP::AtmosSyncChannelMixer::MixInSilenceChannels() -{ - Result_t result = RESULT_OK; - PCM::AudioDescriptor tmpDesc; - ui32_t numSilenceChannels = ATMOS::SYNC_CHANNEL - m_ChannelCount - 1; - if (numSilenceChannels > 0) - { - mem_ptr I = new SilenceDataProvider(numSilenceChannels, - m_ADesc.QuantizationBits, - m_ADesc.AudioSamplingRate.Numerator, - m_ADesc.EditRate); - result = I->FillAudioDescriptor(tmpDesc); - if ( ASDCP_SUCCESS(result) ) - { - m_ADesc.BlockAlign += tmpDesc.BlockAlign; - m_ChannelCount += tmpDesc.ChannelCount; - m_outputs.push_back(std::make_pair(numSilenceChannels, I.get())); - m_inputs.push_back(I); - I.release(); - assert(m_ChannelCount == (ATMOS::SYNC_CHANNEL - 1)); - } - } - return result; -} - -// -Result_t -ASDCP::AtmosSyncChannelMixer::MixInAtmosSyncChannel() -{ - Result_t result = RESULT_OK; - PCM::AudioDescriptor tmpDesc; - mem_ptr I = new AtmosSyncDataProvider(m_ADesc.QuantizationBits, - m_ADesc.AudioSamplingRate.Numerator, - m_ADesc.EditRate, m_trackUUID); - result = I->FillAudioDescriptor(tmpDesc); - if ( ASDCP_SUCCESS(result) ) - { - m_ADesc.BlockAlign += tmpDesc.BlockAlign; - m_ChannelCount += tmpDesc.ChannelCount; - m_outputs.push_back(std::make_pair(tmpDesc.ChannelCount, I.get())); - m_inputs.push_back(I); - I.release(); - assert(m_ChannelCount == ATMOS::SYNC_CHANNEL); - } - return result; -} - -// -Result_t -ASDCP::AtmosSyncChannelMixer::AppendSilenceChannels(const ui32_t& channel_count) -{ - if ( m_ADesc.QuantizationBits == 0 ) - { - DefaultLogSink().Error("Mixer object contains no channels, call OpenRead() first.\n"); - return RESULT_PARAM; - } - - Result_t result = RESULT_OK; - PCM::AudioDescriptor tmpDesc; - - if ( channel_count > 0 ) - { - Kumu::mem_ptr I = - new SilenceDataProvider(channel_count, - m_ADesc.QuantizationBits, - m_ADesc.AudioSamplingRate.Numerator, - m_ADesc.EditRate); - - result = I->FillAudioDescriptor(tmpDesc); - - if ( ASDCP_SUCCESS(result) ) - { - m_ADesc.BlockAlign += tmpDesc.BlockAlign; - m_ChannelCount += tmpDesc.ChannelCount; - m_ADesc.ChannelCount = m_ChannelCount; - m_ADesc.AvgBps = (ui32_t)(ceil(m_ADesc.AudioSamplingRate.Quotient()) * m_ADesc.BlockAlign); - - m_outputs.push_back(std::make_pair(channel_count, I.get())); - m_inputs.push_back(I); - I.release(); - } - } - - return result; -} - -// -Result_t -ASDCP::AtmosSyncChannelMixer::FillAudioDescriptor(PCM::AudioDescriptor& ADesc) const -{ - ADesc = m_ADesc; - return RESULT_OK; -} - -// -Result_t -ASDCP::AtmosSyncChannelMixer::Reset() -{ - Result_t result = RESULT_OK; - SourceList::iterator it; - SourceList::iterator lastInput = m_inputs.end(); - - for ( it = m_inputs.begin(); it != lastInput && ASDCP_SUCCESS(result) ; ++it ) - result = (*it)->Reset(); - - return result; -} - - -//2 -Result_t -ASDCP::AtmosSyncChannelMixer::ReadFrame(PCM::FrameBuffer& OutFB) -{ - - - Result_t result = RESULT_OK; - SourceList::iterator iter; - SourceList::iterator lastInput = m_inputs.end(); - ui32_t bufSize = PCM::CalcFrameBufferSize(m_ADesc); - assert( bufSize <= OutFB.Capacity()); - - for ( iter = m_inputs.begin(); iter != lastInput && ASDCP_SUCCESS(result) ; ++iter ) - result = (*iter)->ReadFrame(); - - if ( ASDCP_SUCCESS(result) ) - { - OutFB.Size(bufSize); - byte_t* Out_p = OutFB.Data(); - byte_t* End_p = Out_p + OutFB.Size(); - ui32_t bytesWritten = 0; - OutputList::iterator iter; - OutputList::iterator lastOutput = m_outputs.end(); - - while ( Out_p < End_p && ASDCP_SUCCESS(result) ) - { - iter = m_outputs.begin(); - while ( iter != lastOutput && ASDCP_SUCCESS(result) ) - { - result = ((*iter).second)->PutSample((*iter).first, Out_p, &bytesWritten); - Out_p += bytesWritten; - ++iter; - } - } - - if ( ASDCP_SUCCESS(result) ) - { - assert(Out_p == End_p); - OutFB.FrameNumber(m_FramesRead++); - } - } - - return result; -} - - -// -// end AtmosSyncChannel_Mixer.cpp -// diff --git a/src/AtmosSyncChannel_Mixer.h b/src/AtmosSyncChannel_Mixer.h deleted file mode 100644 index 27c3b9f..0000000 --- a/src/AtmosSyncChannel_Mixer.h +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright (c) 2013-2013, 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. -*/ -/*! \file AtmosSyncChannel_Mixer.h - \version $Id$ - \brief Read WAV files(s), multiplex multiple PCM frame buffers including Atmos Sync into one -*/ - -#ifndef _ATMOSSYNCCHANNEL_MIXER_H_ -#define _ATMOSSYNCCHANNEL_MIXER_H_ - -#include -#include -#include -#include - -namespace ASDCP -{ - - // - class AtmosSyncChannelMixer - { - typedef std::pair InputBus; - typedef std::vector OutputList; - typedef std::vector SourceList; - - SourceList m_inputs; - OutputList m_outputs; - byte_t m_trackUUID[ASDCP::UUIDlen]; - - Result_t OpenRead(const std::string& file, const Rational& PictureRate); - Result_t MixInSilenceChannels(); - Result_t MixInAtmosSyncChannel(); - void clear(); - - // functor for deleting - struct delete_input - { - void operator()(PCMDataProviderInterface* i) - { - delete i; - } - }; - - ASDCP_NO_COPY_CONSTRUCT(AtmosSyncChannelMixer); - - protected: - PCM::AudioDescriptor m_ADesc; - ui32_t m_ChannelCount; - ui32_t m_FramesRead; - - public: - AtmosSyncChannelMixer(const byte_t * trackUUID); - virtual ~AtmosSyncChannelMixer(); - - const ui32_t& ChannelCount() const { return m_ChannelCount; } - - Result_t OpenRead(ui32_t argc, const char** argv, const Rational& PictureRate); - Result_t OpenRead(const Kumu::PathList_t& argv, const Rational& PictureRate); - Result_t AppendSilenceChannels(const ui32_t& channel_count); - Result_t FillAudioDescriptor(PCM::AudioDescriptor& ADesc) const; - Result_t Reset(); - Result_t ReadFrame(PCM::FrameBuffer& OutFB); - }; -} // namespace ASDCP - -#endif // _ATMOSSYNCCHANNEL_MIXER_H_ - -// -// end AtmosSyncChannel_Mixer.h -// diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 842f44a..da670c4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -22,8 +22,8 @@ set(kumu_src ${kumu_src} KM_fileio.h KM_log.h KM_prng.h KM_util.h KM_xml.h KM_ta set(asdcp_src MPEG2_Parser.cpp MPEG.cpp JP2K_Codestream_Parser.cpp JP2K_Sequence_Parser.cpp JP2K.cpp PCM_Parser.cpp Wav.cpp TimedText_Parser.cpp KLV.cpp Dict.cpp MXFTypes.cpp MXF.cpp Index.cpp Metadata.cpp AS_DCP.cpp AS_DCP_MXF.cpp AS_DCP_AES.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 + AS_DCP_IAB.cpp AS_DCP_DCData.cpp DCData_ByteStream_Parser.cpp DCData_Sequence_Parser.cpp FSKSyncChannel_Generator.cpp + FSKSyncChannel_Mixer.cpp PCMDataProviders.cpp SyncEncoder.c CRC16.c UUIDInformation.c ) # header for deployment (install target) @@ -31,7 +31,7 @@ set(asdcp_deploy_header AS_DCP.h PCMParserList.h AS_DCP_internal.h KM_error.h KM # header set(asdcp_src ${asdcp_src} Wav.h WavFileWriter.h MXF.h Metadata.h JP2K.h AS_DCP.h AS_DCP_internal.h KLV.h MPEG.h MXFTypes.h MDD.h - PCMParserList.h S12MTimecode.h AtmosSyncChannel_Generator.h AtmosSyncChannel_Mixer.h PCMDataProviders.h + PCMParserList.h S12MTimecode.h FSKSyncChannel_Generator.h FSKSyncChannel_Mixer.h PCMDataProviders.h SyncEncoder.h SyncCommon.h CRC16.h UUIDInformation.h dirent_win.h ) diff --git a/src/Dict.cpp b/src/Dict.cpp index 752b81a..7100b48 100755 --- a/src/Dict.cpp +++ b/src/Dict.cpp @@ -138,35 +138,35 @@ ASDCP::SMPTE_390_OPAtom_Entry() { // // -static ASDCP::Dictionary s_AtmosSMPTEDict; -static Kumu::Mutex s_AtmosSMPTEDictLock; -static bool s_AtmosSMPTEDictInit = false; +static ASDCP::Dictionary s_IABSMPTEDict; +static Kumu::Mutex s_IABSMPTEDictLock; +static bool s_IABSMPTEDictInit = false; // const ASDCP::Dictionary& -ASDCP::AtmosSMPTEDict() +ASDCP::IABSMPTEDict() { - if ( ! s_AtmosSMPTEDictInit ) + if ( ! s_IABSMPTEDictInit ) { - Kumu::AutoMutex AL(s_AtmosSMPTEDictLock); + Kumu::AutoMutex AL(s_IABSMPTEDictLock); - if ( ! s_AtmosSMPTEDictInit ) + if ( ! s_IABSMPTEDictInit ) { - s_AtmosSMPTEDict.Init(); + s_IABSMPTEDict.Init(); - s_AtmosSMPTEDict.DeleteEntry(MDD_MXFInterop_OPAtom); - s_AtmosSMPTEDict.DeleteEntry(MDD_MXFInterop_CryptEssence); - s_AtmosSMPTEDict.DeleteEntry(MDD_MXFInterop_GenericDescriptor_SubDescriptors); + s_IABSMPTEDict.DeleteEntry(MDD_MXFInterop_OPAtom); + s_IABSMPTEDict.DeleteEntry(MDD_MXFInterop_CryptEssence); + s_IABSMPTEDict.DeleteEntry(MDD_MXFInterop_GenericDescriptor_SubDescriptors); // legacy Atmos files have the wrong version byte - assert(s_AtmosSMPTEDict.Type(MDD_GenericDataEssenceDescriptor_DataEssenceCoding).ul[7] == 0x03); - s_AtmosSMPTEDict.MutableType(MDD_GenericDataEssenceDescriptor_DataEssenceCoding).ul[7] = 0x05; + assert(s_IABSMPTEDict.Type(MDD_GenericDataEssenceDescriptor_DataEssenceCoding).ul[7] == 0x03); + s_IABSMPTEDict.MutableType(MDD_GenericDataEssenceDescriptor_DataEssenceCoding).ul[7] = 0x05; - s_AtmosSMPTEDictInit = true; + s_IABSMPTEDictInit = true; } } - return s_AtmosSMPTEDict; + return s_IABSMPTEDict; } //------------------------------------------------------------------------------------------ diff --git a/src/FSKSyncChannel_Generator.cpp b/src/FSKSyncChannel_Generator.cpp new file mode 100644 index 0000000..5a59b81 --- /dev/null +++ b/src/FSKSyncChannel_Generator.cpp @@ -0,0 +1,149 @@ +/* +Copyright (c) 2013-2013, 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. +*/ +/*! \file FSKSyncChannel_Generator.cpp + \version $Id$ + \brief SMPTE ST 430-12 sync channel generator implementation +*/ + +#include + +#include + +using namespace ASDCP; + +// +ASDCP::PCM::FSKSyncChannelGenerator::FSKSyncChannelGenerator(ui16_t bitsPerSample, ui32_t sampleRate, + const ASDCP::Rational& editRate, const byte_t* uuid) + : m_syncEncoder(), + m_audioTrackUUID(), + m_ADesc(), + m_syncSignalBuffer(NULL), + m_numSamplesPerFrame(0), + m_currentFrameNumber(0), + m_numBytesPerFrame(0), + m_isSyncEncoderInitialized(false) +{ + + m_ADesc.EditRate = editRate; + m_ADesc.ChannelCount = 1; + m_ADesc.QuantizationBits = bitsPerSample; + m_ADesc.AudioSamplingRate = Rational(sampleRate, 1); + m_ADesc.BlockAlign = ((bitsPerSample + 7) / 8); + m_ADesc.AvgBps = (sampleRate * m_ADesc.BlockAlign); + + memcpy(&m_audioTrackUUID.abyUUIDBytes[0], uuid, UUIDlen); + m_numSamplesPerFrame = (editRate.Denominator * sampleRate) / editRate.Numerator; + m_numBytesPerFrame = m_numSamplesPerFrame * m_ADesc.BlockAlign; + + if (bitsPerSample == 24) + { + ui32_t frameRate = editRate.Numerator/editRate.Denominator; // intentionally allowing for imprecise cast to int + m_isSyncEncoderInitialized = (SyncEncoderInit(&m_syncEncoder, sampleRate, frameRate, &m_audioTrackUUID) == SYNC_ENCODER_ERROR_NONE); + m_syncSignalBuffer = new float[m_numSamplesPerFrame]; + } + else + { + m_isSyncEncoderInitialized = false; + } +} + +ASDCP::PCM::FSKSyncChannelGenerator::~FSKSyncChannelGenerator() +{ + delete [] m_syncSignalBuffer; +} + +ASDCP::Result_t +ASDCP::PCM::FSKSyncChannelGenerator::ReadFrame(FrameBuffer& OutFB) +{ + if (OutFB.Capacity() < m_numBytesPerFrame) + { + return RESULT_SMALLBUF; + } + + /** + * Update frame number and size. + */ + OutFB.FrameNumber(m_currentFrameNumber); + OutFB.Size(m_numBytesPerFrame); + + /** + * Get pointer to frame essence. + */ + byte_t* frameEssence = OutFB.Data(); + + if (m_isSyncEncoderInitialized) + { + /** + * Generate sync signal frame. + */ + int ret = EncodeSync(&m_syncEncoder, m_numSamplesPerFrame, m_syncSignalBuffer, m_currentFrameNumber); + if (ret == SYNC_ENCODER_ERROR_NONE) + { + for (unsigned int i = 0; i < m_numSamplesPerFrame; ++i) + { + /** + * Convert each encoded float sample to a signed 24 bit integer and + * copy into the essence buffer. + */ + i32_t sample = convertSampleFloatToInt24(m_syncSignalBuffer[i]); + memcpy(frameEssence, ((byte_t*)(&sample))+1, NUM_BYTES_PER_INT24); + frameEssence += NUM_BYTES_PER_INT24; + } + } + else + { + /** + * Encoding error, zero out the frame. + */ + memset(frameEssence, 0, m_numBytesPerFrame); + } + } + else + { + /** + * Sync encoder not initialize, zero out the frame. + */ + memset(frameEssence, 0, m_numBytesPerFrame); + } + ++m_currentFrameNumber; + return RESULT_OK; +} + +ASDCP::Result_t +ASDCP::PCM::FSKSyncChannelGenerator::Reset() +{ + m_currentFrameNumber = 0; + return RESULT_OK; +} + +Result_t +ASDCP::PCM::FSKSyncChannelGenerator::FillAudioDescriptor(AudioDescriptor& ADesc) const +{ + ADesc = m_ADesc; + return RESULT_OK; +} + diff --git a/src/FSKSyncChannel_Generator.h b/src/FSKSyncChannel_Generator.h new file mode 100644 index 0000000..d038c83 --- /dev/null +++ b/src/FSKSyncChannel_Generator.h @@ -0,0 +1,151 @@ +/* +Copyright (c) 2013-2013, 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. +*/ +/*! \file FSKSyncChannel_Generator.h + \version $Id$ + \brief SMPTE ST 430-12 sync channel generator +*/ + +#ifndef _FSKSyncChannel_GENERATOR_H_ +#define _FSKSyncChannel_GENERATOR_H_ + +#include +#include "SyncEncoder.h" +#include "UUIDInformation.h" + +#define INT24_MAX 8388607.0 +#define INT24_MIN -8388608.0 + +namespace ASDCP +{ + namespace IAB + { + static const ui32_t SYNC_CHANNEL = 14; + } + + namespace PCM + { + + static const ui16_t NUM_BYTES_PER_INT24 = 3; + + class FSKSyncChannelGenerator + { + SYNCENCODER m_syncEncoder; + UUIDINFORMATION m_audioTrackUUID; + AudioDescriptor m_ADesc; + float *m_syncSignalBuffer; + ui32_t m_numSamplesPerFrame; + ui32_t m_currentFrameNumber; + ui32_t m_numBytesPerFrame; + bool m_isSyncEncoderInitialized; + + ASDCP_NO_COPY_CONSTRUCT(FSKSyncChannelGenerator); + + public: + /** + * Constructor + * + * @param bitsPerSample the number of bits in each sample of pcm data + * @param sampleRate the sampling rate + * @param editRate the edit rate of the associated picture track. + * @param uuid the UUID of the associated IAB track file. + * + */ + FSKSyncChannelGenerator(ui16_t bitsPerSample, ui32_t sampleRate, + const ASDCP::Rational& editRate, const byte_t* uuid); + ~FSKSyncChannelGenerator(); + + /** + * Set the frame number when seeking + * Use override the default starting frame number for a new track or + * to set the frame number when doing random access. + * + * @param frameNumber + * + */ + void setFrameNumber(ui32_t frameNumber) { m_currentFrameNumber = frameNumber; }; + + /** + * Get the number of bytes per frame. + * + * @return Number of bytes per frame + * + */ + ui32_t getBytesPerFrame() { return m_numBytesPerFrame; } + + /** + * Generates the next frame of sync data. + * Generates the next frame of sync data and places it + * the frame buffer. Fails if the buffer is too small. + * **Automatically increments the frame number.** + * + * @param buf the buffer that the generated frame data will be written to. + * + * @return Kumu::RESULT_OK if the buffer is succesfully filled with sync + * data for the next frame. + */ + Result_t ReadFrame(FrameBuffer& buf); + + /** + * Reset the frame count. + * + * @return Kumu::RESULT_OK + */ + Result_t Reset(); + + /** + * Fill the AudioDescriptor with the relevant information. + * + * @return Kumu::RESULT_OK + */ + Result_t FillAudioDescriptor(PCM::AudioDescriptor& ADesc) const; + + /** + * Converts a sample float into + * 24-bit PCM data. + * + */ + static inline i32_t convertSampleFloatToInt24(float sample) + { + if (sample >= 0.0) + { + return (static_cast(sample * INT24_MAX) << 8); + } + else + { + return (static_cast(-sample * INT24_MIN) << 8); + } + } + }; + + } // namespace PCM +} // namespace ASDCP + +#endif // _FSKSyncChannel_GENERATOR_H_ + +// +// end FSKSyncChannel_Generator.h +// diff --git a/src/FSKSyncChannel_Mixer.cpp b/src/FSKSyncChannel_Mixer.cpp new file mode 100644 index 0000000..c4e8d87 --- /dev/null +++ b/src/FSKSyncChannel_Mixer.cpp @@ -0,0 +1,368 @@ +/* +Copyright (c) 2013-2014, 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. +*/ +/*! \file FSKSyncChannel_Mixer.cpp + \version $Id$ + \brief Read WAV files(s), multiplex multiple PCM frame buffers including FSK Sync into one +*/ + +#include + +#include + +#include +#include +#include + +using namespace ASDCP; +using namespace Kumu; + +// +ASDCP::FSKSyncChannelMixer::FSKSyncChannelMixer(const byte_t * trackUUID) + : m_inputs(), m_outputs(), m_trackUUID(), m_ADesc(), m_ChannelCount(0), m_FramesRead(0) +{ + ::memcpy(m_trackUUID, trackUUID, UUIDlen); +} + +ASDCP::FSKSyncChannelMixer::~FSKSyncChannelMixer() +{ + clear(); +} + +void +ASDCP::FSKSyncChannelMixer::clear() +{ + m_outputs.clear(); + std::for_each(m_inputs.begin(), m_inputs.end(), delete_input()); + m_inputs.clear(); +} + +// +Result_t +ASDCP::FSKSyncChannelMixer::OpenRead(ui32_t argc, const char** argv, const Rational& PictureRate) +{ + ASDCP_TEST_NULL(argv); + PathList_t TmpFileList; + + for ( ui32_t i = 0; i < argc; ++i ) + { + ASDCP_TEST_NULL_STR(argv[i]); + TmpFileList.push_back(argv[i]); + } + + return OpenRead(TmpFileList, PictureRate); +} + +// +Result_t +ASDCP::FSKSyncChannelMixer::OpenRead(const Kumu::PathList_t& argv, const Rational& PictureRate) +{ + Result_t result = RESULT_OK; + PathList_t::iterator fi; + Kumu::PathList_t file_list; + PCM::AudioDescriptor tmpDesc; + + if ( argv.size() == 1 && PathIsDirectory(argv.front()) ) + { + DirScanner Dir; + char name_buf[MaxFilePath]; + result = Dir.Open(argv.front().c_str()); + + if ( KM_SUCCESS(result) ) + result = Dir.GetNext(name_buf); + + while ( KM_SUCCESS(result) ) + { + if ( name_buf[0] != '.' ) // no hidden files + { + std::string tmp_path = argv.front() + "/" + name_buf; + file_list.push_back(tmp_path); + } + + result = Dir.GetNext(name_buf); + } + + if ( result == RESULT_ENDOFFILE ) + { + result = RESULT_OK; + file_list.sort(); + } + } + else + { + file_list = argv; + } + + for ( fi = file_list.begin(); KM_SUCCESS(result) && fi != file_list.end(); ++fi ) + { + result = OpenRead(*fi, PictureRate); + } + + if ( ASDCP_SUCCESS(result) && (m_ChannelCount < IAB::SYNC_CHANNEL)) + { + // fsk sync channel has not been added + result = MixInSilenceChannels(); + if ( ASDCP_SUCCESS(result) ) + result = MixInFSKSyncChannel(); + } + + if ( ASDCP_SUCCESS(result) ) + { + m_ADesc.ChannelCount = m_ChannelCount; + m_ADesc.AvgBps = (ui32_t)(ceil(m_ADesc.AudioSamplingRate.Quotient()) * m_ADesc.BlockAlign); + } + else + { + clear(); + } + + return result; +} + +// +Result_t +ASDCP::FSKSyncChannelMixer::OpenRead(const std::string& file, const Rational& PictureRate) +{ + Result_t result = RESULT_OK; + PCM::AudioDescriptor tmpDesc; + ui32_t numChannels = 0; + mem_ptr I = new WAVDataProvider; + result = I->OpenRead(file.c_str(), PictureRate); + + if ( ASDCP_SUCCESS(result)) + { + result = I->FillAudioDescriptor(tmpDesc); + } + + if ( ASDCP_SUCCESS(result) ) + { + + if ( m_ChannelCount == 0 ) + { + m_ADesc = tmpDesc; + } + else + { + + if ( tmpDesc.AudioSamplingRate != m_ADesc.AudioSamplingRate ) + { + DefaultLogSink().Error("AudioSamplingRate mismatch in PCM parser list."); + return RESULT_FORMAT; + } + + if ( tmpDesc.QuantizationBits != m_ADesc.QuantizationBits ) + { + DefaultLogSink().Error("QuantizationBits mismatch in PCM parser list."); + return RESULT_FORMAT; + } + + if ( tmpDesc.ContainerDuration < m_ADesc.ContainerDuration ) + m_ADesc.ContainerDuration = tmpDesc.ContainerDuration; + + m_ADesc.BlockAlign += tmpDesc.BlockAlign; + } + } + + + if ( ASDCP_SUCCESS(result) ) + { + numChannels = tmpDesc.ChannelCount; // default to all channels + if ((m_ChannelCount < IAB::SYNC_CHANNEL) && (m_ChannelCount + numChannels) > (IAB::SYNC_CHANNEL - 1)) + { + // need to insert an fsk channel between the channels of this file. + numChannels = IAB::SYNC_CHANNEL - m_ChannelCount - 1; + m_outputs.push_back(std::make_pair(numChannels, I.get())); + m_ChannelCount += numChannels; + MixInFSKSyncChannel(); + numChannels = tmpDesc.ChannelCount - numChannels; + } + m_outputs.push_back(std::make_pair(numChannels, I.get())); + m_inputs.push_back(I); + I.release(); + m_ChannelCount += numChannels; + } + return result; +} + +Result_t +ASDCP::FSKSyncChannelMixer::MixInSilenceChannels() +{ + Result_t result = RESULT_OK; + PCM::AudioDescriptor tmpDesc; + ui32_t numSilenceChannels = IAB::SYNC_CHANNEL - m_ChannelCount - 1; + if (numSilenceChannels > 0) + { + mem_ptr I = new SilenceDataProvider(numSilenceChannels, + m_ADesc.QuantizationBits, + m_ADesc.AudioSamplingRate.Numerator, + m_ADesc.EditRate); + result = I->FillAudioDescriptor(tmpDesc); + if ( ASDCP_SUCCESS(result) ) + { + m_ADesc.BlockAlign += tmpDesc.BlockAlign; + m_ChannelCount += tmpDesc.ChannelCount; + m_outputs.push_back(std::make_pair(numSilenceChannels, I.get())); + m_inputs.push_back(I); + I.release(); + assert(m_ChannelCount == (IAB::SYNC_CHANNEL - 1)); + } + } + return result; +} + +// +Result_t +ASDCP::FSKSyncChannelMixer::MixInFSKSyncChannel() +{ + Result_t result = RESULT_OK; + PCM::AudioDescriptor tmpDesc; + mem_ptr I = new FSKSyncDataProvider(m_ADesc.QuantizationBits, + m_ADesc.AudioSamplingRate.Numerator, + m_ADesc.EditRate, m_trackUUID); + result = I->FillAudioDescriptor(tmpDesc); + if ( ASDCP_SUCCESS(result) ) + { + m_ADesc.BlockAlign += tmpDesc.BlockAlign; + m_ChannelCount += tmpDesc.ChannelCount; + m_outputs.push_back(std::make_pair(tmpDesc.ChannelCount, I.get())); + m_inputs.push_back(I); + I.release(); + assert(m_ChannelCount == IAB::SYNC_CHANNEL); + } + return result; +} + +// +Result_t +ASDCP::FSKSyncChannelMixer::AppendSilenceChannels(const ui32_t& channel_count) +{ + if ( m_ADesc.QuantizationBits == 0 ) + { + DefaultLogSink().Error("Mixer object contains no channels, call OpenRead() first.\n"); + return RESULT_PARAM; + } + + Result_t result = RESULT_OK; + PCM::AudioDescriptor tmpDesc; + + if ( channel_count > 0 ) + { + Kumu::mem_ptr I = + new SilenceDataProvider(channel_count, + m_ADesc.QuantizationBits, + m_ADesc.AudioSamplingRate.Numerator, + m_ADesc.EditRate); + + result = I->FillAudioDescriptor(tmpDesc); + + if ( ASDCP_SUCCESS(result) ) + { + m_ADesc.BlockAlign += tmpDesc.BlockAlign; + m_ChannelCount += tmpDesc.ChannelCount; + m_ADesc.ChannelCount = m_ChannelCount; + m_ADesc.AvgBps = (ui32_t)(ceil(m_ADesc.AudioSamplingRate.Quotient()) * m_ADesc.BlockAlign); + + m_outputs.push_back(std::make_pair(channel_count, I.get())); + m_inputs.push_back(I); + I.release(); + } + } + + return result; +} + +// +Result_t +ASDCP::FSKSyncChannelMixer::FillAudioDescriptor(PCM::AudioDescriptor& ADesc) const +{ + ADesc = m_ADesc; + return RESULT_OK; +} + +// +Result_t +ASDCP::FSKSyncChannelMixer::Reset() +{ + Result_t result = RESULT_OK; + SourceList::iterator it; + SourceList::iterator lastInput = m_inputs.end(); + + for ( it = m_inputs.begin(); it != lastInput && ASDCP_SUCCESS(result) ; ++it ) + result = (*it)->Reset(); + + return result; +} + + +//2 +Result_t +ASDCP::FSKSyncChannelMixer::ReadFrame(PCM::FrameBuffer& OutFB) +{ + + + Result_t result = RESULT_OK; + SourceList::iterator iter; + SourceList::iterator lastInput = m_inputs.end(); + ui32_t bufSize = PCM::CalcFrameBufferSize(m_ADesc); + assert( bufSize <= OutFB.Capacity()); + + for ( iter = m_inputs.begin(); iter != lastInput && ASDCP_SUCCESS(result) ; ++iter ) + result = (*iter)->ReadFrame(); + + if ( ASDCP_SUCCESS(result) ) + { + OutFB.Size(bufSize); + byte_t* Out_p = OutFB.Data(); + byte_t* End_p = Out_p + OutFB.Size(); + ui32_t bytesWritten = 0; + OutputList::iterator iter; + OutputList::iterator lastOutput = m_outputs.end(); + + while ( Out_p < End_p && ASDCP_SUCCESS(result) ) + { + iter = m_outputs.begin(); + while ( iter != lastOutput && ASDCP_SUCCESS(result) ) + { + result = ((*iter).second)->PutSample((*iter).first, Out_p, &bytesWritten); + Out_p += bytesWritten; + ++iter; + } + } + + if ( ASDCP_SUCCESS(result) ) + { + assert(Out_p == End_p); + OutFB.FrameNumber(m_FramesRead++); + } + } + + return result; +} + + +// +// end FSKSyncChannel_Mixer.cpp +// diff --git a/src/FSKSyncChannel_Mixer.h b/src/FSKSyncChannel_Mixer.h new file mode 100644 index 0000000..7d95dc6 --- /dev/null +++ b/src/FSKSyncChannel_Mixer.h @@ -0,0 +1,94 @@ +/* +Copyright (c) 2013-2013, 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. +*/ +/*! \file FSKSyncChannel_Mixer.h + \version $Id$ + \brief Read WAV files(s), multiplex multiple PCM frame buffers including FSK Sync into one +*/ + +#ifndef _FSKSyncChannel_MIXER_H_ +#define _FSKSyncChannel_MIXER_H_ + +#include +#include +#include +#include + +namespace ASDCP +{ + + // + class FSKSyncChannelMixer + { + typedef std::pair InputBus; + typedef std::vector OutputList; + typedef std::vector SourceList; + + SourceList m_inputs; + OutputList m_outputs; + byte_t m_trackUUID[ASDCP::UUIDlen]; + + Result_t OpenRead(const std::string& file, const Rational& PictureRate); + Result_t MixInSilenceChannels(); + Result_t MixInFSKSyncChannel(); + void clear(); + + // functor for deleting + struct delete_input + { + void operator()(PCMDataProviderInterface* i) + { + delete i; + } + }; + + ASDCP_NO_COPY_CONSTRUCT(FSKSyncChannelMixer); + + protected: + PCM::AudioDescriptor m_ADesc; + ui32_t m_ChannelCount; + ui32_t m_FramesRead; + + public: + FSKSyncChannelMixer(const byte_t * trackUUID); + virtual ~FSKSyncChannelMixer(); + + const ui32_t& ChannelCount() const { return m_ChannelCount; } + + Result_t OpenRead(ui32_t argc, const char** argv, const Rational& PictureRate); + Result_t OpenRead(const Kumu::PathList_t& argv, const Rational& PictureRate); + Result_t AppendSilenceChannels(const ui32_t& channel_count); + Result_t FillAudioDescriptor(PCM::AudioDescriptor& ADesc) const; + Result_t Reset(); + Result_t ReadFrame(PCM::FrameBuffer& OutFB); + }; +} // namespace ASDCP + +#endif // _FSKSyncChannel_MIXER_H_ + +// +// end FSKSyncChannel_Mixer.h +// diff --git a/src/KLV.h b/src/KLV.h index f34ebd9..8cffaa4 100755 --- a/src/KLV.h +++ b/src/KLV.h @@ -173,7 +173,7 @@ inline const char* ui64sz(ui64_t i, char* buf) }; - const Dictionary& AtmosSMPTEDict(); + const Dictionary& IABSMPTEDict(); const Dictionary& DefaultSMPTEDict(); const Dictionary& DefaultInteropDict(); const Dictionary& DefaultCompositeDict(); diff --git a/src/MDD.cpp b/src/MDD.cpp index 6db1bec..072f1b5 100644 --- a/src/MDD.cpp +++ b/src/MDD.cpp @@ -928,22 +928,22 @@ static const ASDCP::MDDEntry s_MDD_Table[] = { {0}, false, "DCDataDescriptor" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x05, // 297 0x0e, 0x09, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00 }, - {0}, false, "DolbyAtmosSubDescriptor" }, + {0}, false, "IADataEssenceSubDescriptor" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 298 0x0e, 0x09, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00 }, - {0}, true, "DolbyAtmosSubDescriptor_AtmosVersion" }, + {0}, true, "IADataEssenceSubDescriptor_ImmersiveAudioVersion" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 299 0x0e, 0x09, 0x05, 0x07, 0x00, 0x00, 0x00, 0x00 }, - {0}, true, "DolbyAtmosSubDescriptor_MaxChannelCount" }, + {0}, true, "IADataEssenceSubDescriptor_MaxChannelCount" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 300 0x0e, 0x09, 0x05, 0x08, 0x00, 0x00, 0x00, 0x00 }, - {0}, true, "DolbyAtmosSubDescriptor_MaxObjectCount" }, + {0}, true, "IADataEssenceSubDescriptor_MaxObjectCount" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 301 0x0e, 0x09, 0x05, 0x09, 0x00, 0x00, 0x00, 0x00 }, - {0}, true, "DolbyAtmosSubDescriptor_AtmosID" }, + {0}, true, "IADataEssenceSubDescriptor_ImmersiveAudioID" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 302 0x0e, 0x09, 0x05, 0x0A, 0x00, 0x00, 0x00, 0x00 }, - {0}, true, "DolbyAtmosSubDescriptor_FirstFrame" }, + {0}, true, "IADataEssenceSubDescriptor_FirstFrame" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, // 303 0x01, 0x03, 0x02, 0x02, 0x03, 0x00, 0x00, 0x00 }, {0}, false, "DataDataDef" }, @@ -1185,19 +1185,15 @@ static const ASDCP::MDDEntry s_MDD_Table[] = { { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0e, // 380 0x04, 0x01, 0x06, 0x03, 0x0e, 0x00, 0x00, 0x00 }, {0}, true, "JPEG2000PictureSubDescriptor_J2CLayout" }, - - // Old DCData UL values, needed for continued support of Atmos - // { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x05, // 381 0x0e, 0x09, 0x06, 0x05, 0x00, 0x00, 0x00, 0x00 }, - {0}, false, "PrivateDCDataWrappingFrame" }, + {0}, false, "MXF_GC_IAData_Frame_Wrapped" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x02, 0x01, 0x05, // 382 0x0e, 0x09, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00 }, - {0}, false, "PrivateDCDataEssence" }, + {0}, false, "IADataElement" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x05, // 383 0x0e, 0x09, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00 }, - {0}, false, "PrivateDCDataDescriptor" }, - + {0}, false, "IADataEssenceDescriptor" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0e, // 384 0x01, 0x05, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00 }, {0}, false, "MCALabelSubDescriptor_MCATitle" }, diff --git a/src/MDD.h b/src/MDD.h index 4e3dcaf..1fde577 100755 --- a/src/MDD.h +++ b/src/MDD.h @@ -332,12 +332,12 @@ namespace ASDCP { MDD_DCDataWrappingFrame, // 294 MDD_DCDataEssence, // 295 MDD_DCDataDescriptor, // 296 - MDD_DolbyAtmosSubDescriptor, // 297 - MDD_DolbyAtmosSubDescriptor_AtmosVersion, // 298 - MDD_DolbyAtmosSubDescriptor_MaxChannelCount, // 299 - MDD_DolbyAtmosSubDescriptor_MaxObjectCount, // 300 - MDD_DolbyAtmosSubDescriptor_AtmosID, // 301 - MDD_DolbyAtmosSubDescriptor_FirstFrame, // 302 + MDD_IADataEssenceSubDescriptor, // 297 + MDD_IADataEssenceSubDescriptor_ImmersiveAudioVersion, // 298 + MDD_IADataEssenceSubDescriptor_MaxChannelCount, // 299 + MDD_IADataEssenceSubDescriptor_MaxObjectCount, // 300 + MDD_IADataEssenceSubDescriptor_ImmersiveAudioID, // 301 + MDD_IADataEssenceSubDescriptor_FirstFrame, // 302 MDD_DataDataDef, // 303 MDD_DCAudioChannelCfg_MCA, // 304 MDD_DCAudioChannel_L, // 305 @@ -416,9 +416,9 @@ namespace ASDCP { MDD_PHDRMetadataTrackSubDescriptor_SourceTrackID, // 378 MDD_PHDRMetadataTrackSubDescriptor_SimplePayloadSID, // 379 MDD_JPEG2000PictureSubDescriptor_J2CLayout, // 380 - MDD_PrivateDCDataWrappingFrame, // 381 - MDD_PrivateDCDataEssence, // 382 - MDD_PrivateDCDataDescriptor, // 383 + MDD_MXF_GC_IAData_Frame_Wrapped, // 381 + MDD_IADataElement, // 382 + MDD_IADataEssenceDescriptor, // 383 MDD_MCALabelSubDescriptor_MCATitle, // 384 MDD_MCALabelSubDescriptor_MCATitleVersion, // 385 MDD_MCALabelSubDescriptor_MCATitleSubVersion, // 386 diff --git a/src/Makefile.am b/src/Makefile.am index 74c0b11..cd904e0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -67,8 +67,8 @@ include_HEADERS += \ MXF.h \ Wav.h \ PCMParserList.h \ - AtmosSyncChannel_Mixer.h \ - AtmosSyncChannel_Generator.h \ + FSKSyncChannel_Mixer.h \ + FSKSyncChannel_Generator.h \ PCMDataProviders.h \ SyncCommon.h \ SyncEncoder.h \ @@ -121,10 +121,10 @@ libasdcp_la_SOURCES = MPEG2_Parser.cpp MPEG.cpp JP2K_Codestream_Parser.cpp \ Wav.h WavFileWriter.h MXF.h Metadata.h \ JP2K.h AS_DCP.h AS_DCP_internal.h KLV.h MPEG.h MXFTypes.h MDD.h \ PCMParserList.h S12MTimecode.h MDD.cpp \ - AS_DCP_ATMOS.cpp AS_DCP_DCData.cpp info.in \ + AS_DCP_IAB.cpp AS_DCP_DCData.cpp info.in \ DCData_ByteStream_Parser.cpp DCData_Sequence_Parser.cpp \ - AtmosSyncChannel_Generator.cpp AtmosSyncChannel_Generator.h \ - AtmosSyncChannel_Mixer.cpp AtmosSyncChannel_Mixer.h \ + FSKSyncChannel_Generator.cpp FSKSyncChannel_Generator.h \ + FSKSyncChannel_Mixer.cpp FSKSyncChannel_Mixer.h \ PCMDataProviders.cpp PCMDataProviders.h \ SyncEncoder.c SyncEncoder.h SyncCommon.h CRC16.c CRC16.h \ UUIDInformation.c UUIDInformation.h \ diff --git a/src/Metadata.cpp b/src/Metadata.cpp index adaac11..3160285 100755 --- a/src/Metadata.cpp +++ b/src/Metadata.cpp @@ -77,8 +77,8 @@ static InterchangeObject* AudioChannelLabelSubDescriptor_Factory(const Dictionar static InterchangeObject* SoundfieldGroupLabelSubDescriptor_Factory(const Dictionary*& Dict) { return new SoundfieldGroupLabelSubDescriptor(Dict); } static InterchangeObject* GroupOfSoundfieldGroupsLabelSubDescriptor_Factory(const Dictionary*& Dict) { return new GroupOfSoundfieldGroupsLabelSubDescriptor(Dict); } static InterchangeObject* DCDataDescriptor_Factory(const Dictionary*& Dict) { return new DCDataDescriptor(Dict); } -static InterchangeObject* PrivateDCDataDescriptor_Factory(const Dictionary*& Dict) { return new PrivateDCDataDescriptor(Dict); } -static InterchangeObject* DolbyAtmosSubDescriptor_Factory(const Dictionary*& Dict) { return new DolbyAtmosSubDescriptor(Dict); } +static InterchangeObject* IADataEssenceDescriptor_Factory(const Dictionary*& Dict) { return new IADataEssenceDescriptor(Dict); } +static InterchangeObject* IADataEssenceSubDescriptor_Factory(const Dictionary*& Dict) { return new IADataEssenceSubDescriptor(Dict); } static InterchangeObject* ACESPictureSubDescriptor_Factory(const Dictionary*& Dict) { return new ACESPictureSubDescriptor(Dict); } static InterchangeObject* TargetFrameSubDescriptor_Factory(const Dictionary*& Dict) { return new TargetFrameSubDescriptor(Dict); } static InterchangeObject* TextBasedDMFramework_Factory(const Dictionary*& Dict) { return new TextBasedDMFramework(Dict); } @@ -130,8 +130,8 @@ ASDCP::MXF::Metadata_InitTypes(const Dictionary*& Dict) SetObjectFactory(Dict->ul(MDD_SoundfieldGroupLabelSubDescriptor), SoundfieldGroupLabelSubDescriptor_Factory); SetObjectFactory(Dict->ul(MDD_GroupOfSoundfieldGroupsLabelSubDescriptor), GroupOfSoundfieldGroupsLabelSubDescriptor_Factory); SetObjectFactory(Dict->ul(MDD_DCDataDescriptor), DCDataDescriptor_Factory); - SetObjectFactory(Dict->ul(MDD_PrivateDCDataDescriptor), PrivateDCDataDescriptor_Factory); - SetObjectFactory(Dict->ul(MDD_DolbyAtmosSubDescriptor), DolbyAtmosSubDescriptor_Factory); + SetObjectFactory(Dict->ul(MDD_IADataEssenceDescriptor), IADataEssenceDescriptor_Factory); + SetObjectFactory(Dict->ul(MDD_IADataEssenceSubDescriptor), IADataEssenceSubDescriptor_Factory); SetObjectFactory(Dict->ul(MDD_ACESPictureSubDescriptor), ACESPictureSubDescriptor_Factory); SetObjectFactory(Dict->ul(MDD_TargetFrameSubDescriptor), TargetFrameSubDescriptor_Factory); SetObjectFactory(Dict->ul(MDD_TextBasedDMFramework), TextBasedDMFramework_Factory); @@ -3973,27 +3973,27 @@ DCDataDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer) } //------------------------------------------------------------------------------------------ -// PrivateDCDataDescriptor +// IADataEssenceDescriptor // -PrivateDCDataDescriptor::PrivateDCDataDescriptor(const Dictionary*& d) : GenericDataEssenceDescriptor(d), m_Dict(d) +IADataEssenceDescriptor::IADataEssenceDescriptor(const Dictionary*& d) : GenericDataEssenceDescriptor(d), m_Dict(d) { assert(m_Dict); - m_UL = m_Dict->ul(MDD_PrivateDCDataDescriptor); + m_UL = m_Dict->ul(MDD_IADataEssenceDescriptor); } -PrivateDCDataDescriptor::PrivateDCDataDescriptor(const PrivateDCDataDescriptor& rhs) : GenericDataEssenceDescriptor(rhs.m_Dict), m_Dict(rhs.m_Dict) +IADataEssenceDescriptor::IADataEssenceDescriptor(const IADataEssenceDescriptor& rhs) : GenericDataEssenceDescriptor(rhs.m_Dict), m_Dict(rhs.m_Dict) { assert(m_Dict); - m_UL = m_Dict->ul(MDD_PrivateDCDataDescriptor); + m_UL = m_Dict->ul(MDD_IADataEssenceDescriptor); Copy(rhs); } // ASDCP::Result_t -PrivateDCDataDescriptor::InitFromTLVSet(TLVReader& TLVSet) +IADataEssenceDescriptor::InitFromTLVSet(TLVReader& TLVSet) { assert(m_Dict); Result_t result = GenericDataEssenceDescriptor::InitFromTLVSet(TLVSet); @@ -4002,7 +4002,7 @@ PrivateDCDataDescriptor::InitFromTLVSet(TLVReader& TLVSet) // ASDCP::Result_t -PrivateDCDataDescriptor::WriteToTLVSet(TLVWriter& TLVSet) +IADataEssenceDescriptor::WriteToTLVSet(TLVWriter& TLVSet) { assert(m_Dict); Result_t result = GenericDataEssenceDescriptor::WriteToTLVSet(TLVSet); @@ -4011,14 +4011,14 @@ PrivateDCDataDescriptor::WriteToTLVSet(TLVWriter& TLVSet) // void -PrivateDCDataDescriptor::Copy(const PrivateDCDataDescriptor& rhs) +IADataEssenceDescriptor::Copy(const IADataEssenceDescriptor& rhs) { GenericDataEssenceDescriptor::Copy(rhs); } // void -PrivateDCDataDescriptor::Dump(FILE* stream) +IADataEssenceDescriptor::Dump(FILE* stream) { char identbuf[IdentBufferLen]; *identbuf = 0; @@ -4031,80 +4031,80 @@ PrivateDCDataDescriptor::Dump(FILE* stream) // ASDCP::Result_t -PrivateDCDataDescriptor::InitFromBuffer(const byte_t* p, ui32_t l) +IADataEssenceDescriptor::InitFromBuffer(const byte_t* p, ui32_t l) { return InterchangeObject::InitFromBuffer(p, l); } // ASDCP::Result_t -PrivateDCDataDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer) +IADataEssenceDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer) { return InterchangeObject::WriteToBuffer(Buffer); } //------------------------------------------------------------------------------------------ -// DolbyAtmosSubDescriptor +// IADataEssenceSubDescriptor // -DolbyAtmosSubDescriptor::DolbyAtmosSubDescriptor(const Dictionary*& d) : InterchangeObject(d), m_Dict(d), FirstFrame(0), MaxChannelCount(0), MaxObjectCount(0), AtmosVersion(0) +IADataEssenceSubDescriptor::IADataEssenceSubDescriptor(const Dictionary*& d) : InterchangeObject(d), m_Dict(d), FirstFrame(0), MaxChannelCount(0), MaxObjectCount(0), ImmersiveAudioVersion(0) { assert(m_Dict); - m_UL = m_Dict->ul(MDD_DolbyAtmosSubDescriptor); + m_UL = m_Dict->ul(MDD_IADataEssenceSubDescriptor); } -DolbyAtmosSubDescriptor::DolbyAtmosSubDescriptor(const DolbyAtmosSubDescriptor& rhs) : InterchangeObject(rhs.m_Dict), m_Dict(rhs.m_Dict) +IADataEssenceSubDescriptor::IADataEssenceSubDescriptor(const IADataEssenceSubDescriptor& rhs) : InterchangeObject(rhs.m_Dict), m_Dict(rhs.m_Dict) { assert(m_Dict); - m_UL = m_Dict->ul(MDD_DolbyAtmosSubDescriptor); + m_UL = m_Dict->ul(MDD_IADataEssenceSubDescriptor); Copy(rhs); } // ASDCP::Result_t -DolbyAtmosSubDescriptor::InitFromTLVSet(TLVReader& TLVSet) +IADataEssenceSubDescriptor::InitFromTLVSet(TLVReader& TLVSet) { assert(m_Dict); Result_t result = InterchangeObject::InitFromTLVSet(TLVSet); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(DolbyAtmosSubDescriptor, AtmosID)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(DolbyAtmosSubDescriptor, FirstFrame)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi16(OBJ_READ_ARGS(DolbyAtmosSubDescriptor, MaxChannelCount)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi16(OBJ_READ_ARGS(DolbyAtmosSubDescriptor, MaxObjectCount)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi8(OBJ_READ_ARGS(DolbyAtmosSubDescriptor, AtmosVersion)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(IADataEssenceSubDescriptor, ImmersiveAudioID)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(IADataEssenceSubDescriptor, FirstFrame)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi16(OBJ_READ_ARGS(IADataEssenceSubDescriptor, MaxChannelCount)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi16(OBJ_READ_ARGS(IADataEssenceSubDescriptor, MaxObjectCount)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi8(OBJ_READ_ARGS(IADataEssenceSubDescriptor, ImmersiveAudioVersion)); return result; } // ASDCP::Result_t -DolbyAtmosSubDescriptor::WriteToTLVSet(TLVWriter& TLVSet) +IADataEssenceSubDescriptor::WriteToTLVSet(TLVWriter& TLVSet) { assert(m_Dict); Result_t result = InterchangeObject::WriteToTLVSet(TLVSet); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(DolbyAtmosSubDescriptor, AtmosID)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(DolbyAtmosSubDescriptor, FirstFrame)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi16(OBJ_WRITE_ARGS(DolbyAtmosSubDescriptor, MaxChannelCount)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi16(OBJ_WRITE_ARGS(DolbyAtmosSubDescriptor, MaxObjectCount)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS(DolbyAtmosSubDescriptor, AtmosVersion)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(IADataEssenceSubDescriptor, ImmersiveAudioID)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(IADataEssenceSubDescriptor, FirstFrame)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi16(OBJ_WRITE_ARGS(IADataEssenceSubDescriptor, MaxChannelCount)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi16(OBJ_WRITE_ARGS(IADataEssenceSubDescriptor, MaxObjectCount)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS(IADataEssenceSubDescriptor, ImmersiveAudioVersion)); return result; } // void -DolbyAtmosSubDescriptor::Copy(const DolbyAtmosSubDescriptor& rhs) +IADataEssenceSubDescriptor::Copy(const IADataEssenceSubDescriptor& rhs) { InterchangeObject::Copy(rhs); - AtmosID = rhs.AtmosID; + ImmersiveAudioID = rhs.ImmersiveAudioID; FirstFrame = rhs.FirstFrame; MaxChannelCount = rhs.MaxChannelCount; MaxObjectCount = rhs.MaxObjectCount; - AtmosVersion = rhs.AtmosVersion; + ImmersiveAudioVersion = rhs.ImmersiveAudioVersion; } // void -DolbyAtmosSubDescriptor::Dump(FILE* stream) +IADataEssenceSubDescriptor::Dump(FILE* stream) { char identbuf[IdentBufferLen]; *identbuf = 0; @@ -4113,23 +4113,23 @@ DolbyAtmosSubDescriptor::Dump(FILE* stream) stream = stderr; InterchangeObject::Dump(stream); - fprintf(stream, " %22s = %s\n", "AtmosID", AtmosID.EncodeString(identbuf, IdentBufferLen)); + fprintf(stream, " %22s = %s\n", "ImmersiveAudioID", ImmersiveAudioID.EncodeString(identbuf, IdentBufferLen)); fprintf(stream, " %22s = %d\n", "FirstFrame", FirstFrame); fprintf(stream, " %22s = %d\n", "MaxChannelCount", MaxChannelCount); fprintf(stream, " %22s = %d\n", "MaxObjectCount", MaxObjectCount); - fprintf(stream, " %22s = %d\n", "AtmosVersion", AtmosVersion); + fprintf(stream, " %22s = %d\n", "ImmersiveAudioVersion", ImmersiveAudioVersion); } // ASDCP::Result_t -DolbyAtmosSubDescriptor::InitFromBuffer(const byte_t* p, ui32_t l) +IADataEssenceSubDescriptor::InitFromBuffer(const byte_t* p, ui32_t l) { return InterchangeObject::InitFromBuffer(p, l); } // ASDCP::Result_t -DolbyAtmosSubDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer) +IADataEssenceSubDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer) { return InterchangeObject::WriteToBuffer(Buffer); } diff --git a/src/Metadata.h b/src/Metadata.h index c624784..0fbc40f 100755 --- a/src/Metadata.h +++ b/src/Metadata.h @@ -1047,20 +1047,20 @@ namespace ASDCP }; // - class PrivateDCDataDescriptor : public GenericDataEssenceDescriptor + class IADataEssenceDescriptor : public GenericDataEssenceDescriptor { - PrivateDCDataDescriptor(); + IADataEssenceDescriptor(); public: const Dictionary*& m_Dict; - PrivateDCDataDescriptor(const Dictionary*& d); - PrivateDCDataDescriptor(const PrivateDCDataDescriptor& rhs); - virtual ~PrivateDCDataDescriptor() {} + IADataEssenceDescriptor(const Dictionary*& d); + IADataEssenceDescriptor(const IADataEssenceDescriptor& rhs); + virtual ~IADataEssenceDescriptor() {} - const PrivateDCDataDescriptor& operator=(const PrivateDCDataDescriptor& rhs) { Copy(rhs); return *this; } - virtual void Copy(const PrivateDCDataDescriptor& rhs); - virtual const char* HasName() { return "PrivateDCDataDescriptor"; } + const IADataEssenceDescriptor& operator=(const IADataEssenceDescriptor& rhs) { Copy(rhs); return *this; } + virtual void Copy(const IADataEssenceDescriptor& rhs); + virtual const char* HasName() { return "IADataEssenceDescriptor"; } virtual Result_t InitFromTLVSet(TLVReader& TLVSet); virtual Result_t WriteToTLVSet(TLVWriter& TLVSet); virtual void Dump(FILE* = 0); @@ -1069,25 +1069,25 @@ namespace ASDCP }; // - class DolbyAtmosSubDescriptor : public InterchangeObject + class IADataEssenceSubDescriptor : public InterchangeObject { - DolbyAtmosSubDescriptor(); + IADataEssenceSubDescriptor(); public: const Dictionary*& m_Dict; - UUID AtmosID; + UUID ImmersiveAudioID; ui32_t FirstFrame; ui16_t MaxChannelCount; ui16_t MaxObjectCount; - ui8_t AtmosVersion; + ui8_t ImmersiveAudioVersion; - DolbyAtmosSubDescriptor(const Dictionary*& d); - DolbyAtmosSubDescriptor(const DolbyAtmosSubDescriptor& rhs); - virtual ~DolbyAtmosSubDescriptor() {} + IADataEssenceSubDescriptor(const Dictionary*& d); + IADataEssenceSubDescriptor(const IADataEssenceSubDescriptor& rhs); + virtual ~IADataEssenceSubDescriptor() {} - const DolbyAtmosSubDescriptor& operator=(const DolbyAtmosSubDescriptor& rhs) { Copy(rhs); return *this; } - virtual void Copy(const DolbyAtmosSubDescriptor& rhs); - virtual const char* HasName() { return "DolbyAtmosSubDescriptor"; } + const IADataEssenceSubDescriptor& operator=(const IADataEssenceSubDescriptor& rhs) { Copy(rhs); return *this; } + virtual void Copy(const IADataEssenceSubDescriptor& rhs); + virtual const char* HasName() { return "IADataEssenceSubDescriptor"; } virtual Result_t InitFromTLVSet(TLVReader& TLVSet); virtual Result_t WriteToTLVSet(TLVWriter& TLVSet); virtual void Dump(FILE* = 0); diff --git a/src/PCMDataProviders.cpp b/src/PCMDataProviders.cpp index 7d2c152..7a6045e 100644 --- a/src/PCMDataProviders.cpp +++ b/src/PCMDataProviders.cpp @@ -26,7 +26,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file PCMDataProviders.cpp \version $Id$ - \brief Implementation of PCM sample data providers for WAV, AtmosSync and Silence. + \brief Implementation of PCM sample data providers for WAV, FSK sync and Silence. */ #include @@ -105,7 +105,7 @@ ASDCP::WAVDataProvider::OpenRead(const char* filename, const Rational& PictureRa } // -ASDCP::AtmosSyncDataProvider::AtmosSyncDataProvider(const ui16_t bitsPerSample, const ui32_t sampleRate, +ASDCP::FSKSyncDataProvider::FSKSyncDataProvider(const ui16_t bitsPerSample, const ui32_t sampleRate, const ASDCP::Rational& editRate, const byte_t* uuid) : m_Generator(bitsPerSample, sampleRate, editRate, uuid), m_FB(), m_ADesc(), m_SampleSize() { @@ -114,11 +114,11 @@ ASDCP::AtmosSyncDataProvider::AtmosSyncDataProvider(const ui16_t bitsPerSample, m_FB.Capacity(PCM::CalcFrameBufferSize(m_ADesc)); } -ASDCP::AtmosSyncDataProvider::~AtmosSyncDataProvider() +ASDCP::FSKSyncDataProvider::~FSKSyncDataProvider() {} Result_t -ASDCP::AtmosSyncDataProvider::PutSample(const ui32_t numChannels, byte_t* buf, ui32_t* bytesWritten) +ASDCP::FSKSyncDataProvider::PutSample(const ui32_t numChannels, byte_t* buf, ui32_t* bytesWritten) { ASDCP_TEST_NULL(buf); ASDCP_TEST_NULL(m_ptr); @@ -136,7 +136,7 @@ ASDCP::AtmosSyncDataProvider::PutSample(const ui32_t numChannels, byte_t* buf, u } Result_t -ASDCP::AtmosSyncDataProvider::ReadFrame() +ASDCP::FSKSyncDataProvider::ReadFrame() { Result_t result = m_Generator.ReadFrame(m_FB); m_ptr = ASDCP_SUCCESS(result) ? m_FB.RoData() : NULL; @@ -144,14 +144,14 @@ ASDCP::AtmosSyncDataProvider::ReadFrame() } Result_t -ASDCP::AtmosSyncDataProvider::FillAudioDescriptor(PCM::AudioDescriptor& ADesc) const +ASDCP::FSKSyncDataProvider::FillAudioDescriptor(PCM::AudioDescriptor& ADesc) const { ADesc = m_ADesc; return RESULT_OK; } Result_t -ASDCP::AtmosSyncDataProvider::Reset() +ASDCP::FSKSyncDataProvider::Reset() { return m_Generator.Reset(); } diff --git a/src/PCMDataProviders.h b/src/PCMDataProviders.h index 9241fd3..40e3a2c 100644 --- a/src/PCMDataProviders.h +++ b/src/PCMDataProviders.h @@ -26,14 +26,14 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file PCMDataProviders.h \version $Id$ - \brief PCM sample data providers for WAV, AtmosSync and Silence. + \brief PCM sample data providers for WAV, FSK Sync and Silence. */ #ifndef _PCMDATAPROVIDERS_H_ #define _PCMDATAPROVIDERS_H_ #include -#include +#include namespace ASDCP { @@ -73,20 +73,21 @@ namespace ASDCP }; - // Atmos Sync Channel implementation of the PCM Data Provider Interface - class AtmosSyncDataProvider : public PCMDataProviderInterface + // + //Sync Channel implementation of the PCM Data Provider Interface + class FSKSyncDataProvider : public PCMDataProviderInterface { - ASDCP_NO_COPY_CONSTRUCT(AtmosSyncDataProvider); - PCM::AtmosSyncChannelGenerator m_Generator; + ASDCP_NO_COPY_CONSTRUCT(FSKSyncDataProvider); + PCM::FSKSyncChannelGenerator m_Generator; PCM::FrameBuffer m_FB; PCM::AudioDescriptor m_ADesc; const byte_t* m_ptr; ui32_t m_SampleSize; public: - AtmosSyncDataProvider(const ui16_t bitsPerSample, const ui32_t sampleRate, + FSKSyncDataProvider(const ui16_t bitsPerSample, const ui32_t sampleRate, const ASDCP::Rational& PictureRate, const byte_t* uuid); - virtual ~AtmosSyncDataProvider(); + virtual ~FSKSyncDataProvider(); virtual Result_t PutSample(const ui32_t numChannels, byte_t* buf, ui32_t* bytesWritten); virtual Result_t ReadFrame(); virtual Result_t FillAudioDescriptor(PCM::AudioDescriptor& ADesc) const; diff --git a/src/SyncCommon.h b/src/SyncCommon.h index bc5d498..08c267b 100644 --- a/src/SyncCommon.h +++ b/src/SyncCommon.h @@ -26,7 +26,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file SyncCommon.h \version $Id$ - \brief Common elements for ATMOS Sync Channel generation + \brief Common elements for FSK Sync Channel generation */ #ifndef _SYNC_COMMON_H_ diff --git a/src/SyncEncoder.c b/src/SyncEncoder.c index c553509..6ac52fb 100644 --- a/src/SyncEncoder.c +++ b/src/SyncEncoder.c @@ -26,7 +26,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file SyncEncoder.c \version $Id$ - \brief Implementation of Atmos Sync Frame Encoder + \brief Implementation of FSK Sync Frame Encoder */ #include "SyncEncoder.h" diff --git a/src/SyncEncoder.h b/src/SyncEncoder.h index 4b97f5a..6840dd7 100644 --- a/src/SyncEncoder.h +++ b/src/SyncEncoder.h @@ -26,7 +26,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file SyncEncoder.h \version $Id$ - \brief Declaration of Atmos Sync Frame Encoder + \brief Declaration of FSK Sync Frame Encoder */ #ifndef _SYNC_ENCODER_H_ diff --git a/src/UUIDInformation.c b/src/UUIDInformation.c index 4c5eec9..ed1f228 100644 --- a/src/UUIDInformation.c +++ b/src/UUIDInformation.c @@ -26,7 +26,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file SyncEncoder.h \version $Id$ - \brief Implementation of Atmos Sync UUID + \brief Implementation of FSK Sync UUID */ #include "UUIDInformation.h" diff --git a/src/UUIDInformation.h b/src/UUIDInformation.h index 4bd0ff4..716cef4 100644 --- a/src/UUIDInformation.h +++ b/src/UUIDInformation.h @@ -26,7 +26,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file SyncEncoder.h \version $Id$ - \brief Declaration of Atmos Sync UUID + \brief Declaration of FSK Sync UUID */ #ifndef _UUID_INFORMATION_H_ diff --git a/src/asdcp-info.cpp b/src/asdcp-info.cpp index b8876fe..67131ec 100755 --- a/src/asdcp-info.cpp +++ b/src/asdcp-info.cpp @@ -283,15 +283,15 @@ class MyDCDataDescriptor : public DCData::DCDataDescriptor } }; -class MyAtmosDescriptor : public ATMOS::AtmosDescriptor +class MyIABDescriptor : public IAB::IABDescriptor { public: - void FillDescriptor(ATMOS::MXFReader& Reader) { - Reader.FillAtmosDescriptor(*this); + void FillDescriptor(IAB::MXFReader& Reader) { + Reader.FillIABDescriptor(*this); } void Dump(FILE* stream) { - ATMOS::AtmosDescriptorDump(*this, stream); + IAB::IADataEssenceSubDescriptorDump(*this, stream); } }; @@ -626,10 +626,10 @@ show_file_info(CommandOptions& Options) FileInfoWrapper wrapper; result = wrapper.file_info(Options, "D-Cinema Generic Data"); } - else if ( EssenceType == ESS_DCDATA_DOLBY_ATMOS ) + else if ( EssenceType == ESS_DCDATA_IAB ) { - FileInfoWrapper wrapper; - result = wrapper.file_info(Options, "Dolby ATMOS"); + FileInfoWrapper wrapper; + result = wrapper.file_info(Options, "IAB"); } else if ( EssenceType == ESS_AS02_PCM_24b_48k || EssenceType == ESS_AS02_PCM_24b_96k diff --git a/src/asdcp-unwrap.cpp b/src/asdcp-unwrap.cpp index a24219f..c539771 100755 --- a/src/asdcp-unwrap.cpp +++ b/src/asdcp-unwrap.cpp @@ -1000,7 +1000,7 @@ main(int argc, const char** argv) result = read_DCData_file(Options); break; - case ESS_DCDATA_DOLBY_ATMOS: + case ESS_DCDATA_IAB: Options.extension = "atmos"; result = read_DCData_file(Options); break; diff --git a/src/asdcp-wrap.cpp b/src/asdcp-wrap.cpp index 66f291a..84d8f3d 100755 --- a/src/asdcp-wrap.cpp +++ b/src/asdcp-wrap.cpp @@ -49,7 +49,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include -#include +#include #include #include #include @@ -168,7 +168,7 @@ Options:\n\ -p - fps of picture when wrapping PCM or JP2K:\n\ Use one of [23|24|25|30|48|50|60], 24 is default\n\ -P
    - Set PictureEssenceCoding UL value in a JP2K file\n\ - -s - Insert a Dolby Atmos synchronization channel when\n\ + -s - Insert a SMPTE ST 430-12 synchronization channel when\n\ wrapping PCM. This implies a -L option(SMPTE ULs) and \n\ will overide -C and -l options with Configuration 4 \n\ Channel Assigment and no format label respectively. \n\ @@ -246,10 +246,10 @@ public: UL channel_assignment; UL picture_coding; UL aux_data_coding; - bool dolby_atmos_sync_flag; // if true, insert a Dolby Atmos Synchronization channel. - ui32_t ffoa; // first frame of action for atmos wrapping - ui32_t max_channel_count; // max channel count for atmos wrapping - ui32_t max_object_count; // max object count for atmos wrapping + bool fsk_sync_flag; // if true, insert a SMPTE ST 430-12 Synchronization channel. + ui32_t ffoa; // first frame of action for IAB wrapping + ui32_t max_channel_count; // max channel count for IAB wrapping + ui32_t max_object_count; // max object count for IAB wrapping bool use_interop_sound_wtf; // make true to force WTF assignment label instead of MCA ASDCP::MXF::ASDCP_MCAConfigParser mca_config; std::string mca_language; @@ -310,8 +310,8 @@ public: duration(0xffffffff), use_smpte_labels(false), j2c_pedantic(true), fb_size(FRAME_BUFFER_SIZE), channel_fmt(PCM::CF_NONE), - ffoa(0), max_channel_count(10), max_object_count(118), // hard-coded sample atmos properties - dolby_atmos_sync_flag(false), + ffoa(0), max_channel_count(10), max_object_count(118), // hard-coded sample IAB properties + fsk_sync_flag(false), show_ul_values_flag(false), mca_config(g_dict), use_interop_sound_wtf(false) @@ -454,7 +454,7 @@ public: picture_rate = Kumu::xabs(strtol(argv[i], 0, 10)); break; - case 's': dolby_atmos_sync_flag = true; break; + case 's': fsk_sync_flag = true; break; case 'u': show_ul_values_flag = true; break; case 'V': version_flag = true; break; case 'v': verbose_flag = true; break; @@ -1158,11 +1158,11 @@ write_PCM_file(CommandOptions& Options) return result; } -// Mix one or more plaintext PCM audio streams with a Dolby Atmos Synchronization channel and write them to a plaintext ASDCP file -// Mix one or more plaintext PCM audio streams with a Dolby Atmos Synchronization channel and write them to a ciphertext ASDCP file +// Mix one or more plaintext PCM audio streams with a ST 430-12 Synchronization channel and write them to a plaintext ASDCP file +// Mix one or more plaintext PCM audio streams with a ST 430-12 Synchronization channel and write them to a ciphertext ASDCP file // Result_t -write_PCM_with_ATMOS_sync_file(CommandOptions& Options) +write_PCM_with_FSK_sync_file(CommandOptions& Options) { AESEncContext* Context = 0; HMACContext* HMAC = 0; @@ -1178,7 +1178,7 @@ write_PCM_with_ATMOS_sync_file(CommandOptions& Options) memcpy(Info.AssetUUID, Options.asset_id_value, UUIDlen); else Kumu::GenRandomUUID(Info.AssetUUID); - AtmosSyncChannelMixer Mixer(Info.AssetUUID); + FSKSyncChannelMixer Mixer(Info.AssetUUID); // set up essence parser Result_t result = Mixer.OpenRead(Options.filenames, PictureRate); @@ -1420,17 +1420,17 @@ write_timed_text_file(CommandOptions& Options) return result; } -// Write one or more plaintext Dolby ATMOS bytestreams to a plaintext ASDCP file -// Write one or more plaintext Dolby ATMOS bytestreams to a ciphertext ASDCP file +// Write one or more plaintext IAB bytestreams to a plaintext ASDCP file +// Write one or more plaintext IAB bytestreams to a ciphertext ASDCP file // Result_t -write_dolby_atmos_file(CommandOptions& Options) +write_IAB_file(CommandOptions& Options) { AESEncContext* Context = 0; HMACContext* HMAC = 0; - ATMOS::MXFWriter Writer; + IAB::MXFWriter Writer; DCData::FrameBuffer FrameBuffer(Options.fb_size); - ATMOS::AtmosDescriptor ADesc; + IAB::IABDescriptor ADesc; DCData::SequenceParser Parser; byte_t IV_buf[CBC_BLOCK_SIZE]; Kumu::FortunaRNG RNG; @@ -1443,18 +1443,18 @@ write_dolby_atmos_file(CommandOptions& Options) { Parser.FillDCDataDescriptor(ADesc); ADesc.EditRate = Options.PictureRate(); - // TODO: fill AtmosDescriptor + // TODO: fill IABDescriptor ADesc.FirstFrame = Options.ffoa; ADesc.MaxChannelCount = Options.max_channel_count; ADesc.MaxObjectCount = Options.max_object_count; - Kumu::GenRandomUUID(ADesc.AtmosID); - ADesc.AtmosVersion = 1; + Kumu::GenRandomUUID(ADesc.ImmersiveAudioID); + ADesc.ImmersiveAudioVersion = 1; if ( Options.verbose_flag ) { - fprintf(stderr, "Dolby ATMOS Data\n"); - fputs("AtmosDescriptor:\n", stderr); + fprintf(stderr, "IAB Data\n"); + fputs("IABDescriptor:\n", stderr); fprintf(stderr, "Frame Buffer size: %u\n", Options.fb_size); - ATMOS::AtmosDescriptorDump(ADesc); + IAB::IADataEssenceSubDescriptorDump(ADesc); } } @@ -1716,9 +1716,9 @@ main(int argc, const char** argv) case ESS_PCM_24b_48k: case ESS_PCM_24b_96k: - if ( Options.dolby_atmos_sync_flag ) + if ( Options.fsk_sync_flag ) { - result = write_PCM_with_ATMOS_sync_file(Options); + result = write_PCM_with_FSK_sync_file(Options); } else { @@ -1730,8 +1730,8 @@ main(int argc, const char** argv) result = write_timed_text_file(Options); break; - case ESS_DCDATA_DOLBY_ATMOS: - result = write_dolby_atmos_file(Options); + case ESS_DCDATA_IAB: + result = write_IAB_file(Options); break; case ESS_DCDATA_UNKNOWN: diff --git a/win32/Makefile.wmk b/win32/Makefile.wmk index 1a0956d..31df784 100755 --- a/win32/Makefile.wmk +++ b/win32/Makefile.wmk @@ -83,9 +83,9 @@ ASDCP_OBJS = MPEG2_Parser.obj MPEG.obj JP2K_Codestream_Parser.obj \ Index.obj Metadata.obj AS_DCP.obj AS_DCP_MXF.obj AS_DCP_AES.obj \ h__Reader.obj h__Writer.obj AS_DCP_MPEG2.obj AS_DCP_JP2K.obj \ AS_DCP_PCM.obj AS_DCP_TimedText.obj PCMParserList.obj \ - MDD.obj AS_DCP_ATMOS.obj AS_DCP_DCData.obj \ + MDD.obj AS_DCP_IAB.obj AS_DCP_DCData.obj \ DCData_ByteStream_Parser.obj DCData_Sequence_Parser.obj \ - AtmosSyncChannel_Generator.obj AtmosSyncChannel_Mixer.obj \ + FSKSyncChannel_Generator.obj FSKSyncChannel_Mixer.obj \ PCMDataProviders.obj SyncEncoder.obj CRC16.obj \ UUIDInformation.obj AS02_OBJS = h__02_Reader.obj h__02_Writer.obj AS_02_JP2K.obj \ -- cgit v1.2.3