From dd03f3ae2c71df2c4eb89804293e621777a050cf Mon Sep 17 00:00:00 2001 From: mikey Date: Tue, 29 Apr 2014 15:31:21 +0000 Subject: [PATCH] added a note about AS-02 support. --- src/AS_02.h | 7 +- src/AS_DCP_AES.cpp | 8 +- src/AtmosSyncChannel_Mixer.cpp | 39 ++++++++++ src/AtmosSyncChannel_Mixer.h | 3 + src/KM_error.h | 18 ++++- src/KM_fileio.cpp | 104 ++++++++++++++++++++++++++ src/KM_fileio.h | 41 +++++++++- src/KM_memio.h | 15 ++-- src/KM_util.h | 2 +- src/MDD.cpp | 12 ++- src/MDD.h | 2 + src/MXF.cpp | 133 ++++++++++++++++++--------------- src/MXF.h | 15 +++- src/MXFTypes.cpp | 2 +- src/Makefile.am | 8 +- src/as-02-unwrap.cpp | 4 +- src/asdcp-info.cpp | 19 +++-- src/asdcp-test.cpp | 7 +- src/asdcp-unwrap.cpp | 4 +- src/asdcp-wrap.cpp | 9 +-- 20 files changed, 353 insertions(+), 99 deletions(-) diff --git a/src/AS_02.h b/src/AS_02.h index 6b34c77..02efb9f 100644 --- a/src/AS_02.h +++ b/src/AS_02.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2011-2013, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, +Copyright (c) 2011-2014, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst All rights reserved. @@ -128,6 +128,11 @@ namespace AS_02 } // namespace MXF + + // IMF App 2 edit rates not already exposed in namespace ASDCP + const ASDCP::Rational EditRate_29_97 = ASDCP::Rational(30000, 1001); + const ASDCP::Rational EditRate_59_94 = ASDCP::Rational(60000, 1001); + //--------------------------------------------------------------------------------- // Accessors in the MXFReader and MXFWriter classes below return these types to // provide direct access to MXF metadata structures declared in MXF.h and Metadata.h diff --git a/src/AS_DCP_AES.cpp b/src/AS_DCP_AES.cpp index 51955f6..379e8ab 100755 --- a/src/AS_DCP_AES.cpp +++ b/src/AS_DCP_AES.cpp @@ -58,6 +58,7 @@ print_ssl_error() class ASDCP::AESEncContext::h__AESContext : public AES_KEY { public: + Kumu::SymmetricKey m_KeyBuf; byte_t m_IVec[CBC_BLOCK_SIZE]; }; @@ -76,8 +77,9 @@ ASDCP::AESEncContext::InitKey(const byte_t* key) return RESULT_INIT; m_Context = new h__AESContext; + m_Context->m_KeyBuf.Set(key); - if ( AES_set_encrypt_key(key, KEY_SIZE_BITS, m_Context) ) + if ( AES_set_encrypt_key(m_Context->m_KeyBuf.Value(), KEY_SIZE_BITS, m_Context) ) { print_ssl_error(); return RESULT_CRYPT_INIT; @@ -159,6 +161,7 @@ ASDCP::AESEncContext::EncryptBlock(const byte_t* pt_buf, byte_t* ct_buf, ui32_t class ASDCP::AESDecContext::h__AESContext : public AES_KEY { public: + Kumu::SymmetricKey m_KeyBuf; byte_t m_IVec[CBC_BLOCK_SIZE]; }; @@ -177,8 +180,9 @@ ASDCP::AESDecContext::InitKey(const byte_t* key) return RESULT_INIT; m_Context = new h__AESContext; + m_Context->m_KeyBuf.Set(key); - if ( AES_set_decrypt_key(key, KEY_SIZE_BITS, m_Context) ) + if ( AES_set_decrypt_key(m_Context->m_KeyBuf.Value(), KEY_SIZE_BITS, m_Context) ) { print_ssl_error(); return RESULT_CRYPT_INIT; diff --git a/src/AtmosSyncChannel_Mixer.cpp b/src/AtmosSyncChannel_Mixer.cpp index 70cfbfd..a58b3cd 100644 --- a/src/AtmosSyncChannel_Mixer.cpp +++ b/src/AtmosSyncChannel_Mixer.cpp @@ -252,6 +252,45 @@ ASDCP::AtmosSyncChannelMixer::MixInAtmosSyncChannel() 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 diff --git a/src/AtmosSyncChannel_Mixer.h b/src/AtmosSyncChannel_Mixer.h index c6a27a3..27c3b9f 100644 --- a/src/AtmosSyncChannel_Mixer.h +++ b/src/AtmosSyncChannel_Mixer.h @@ -76,8 +76,11 @@ namespace ASDCP 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); diff --git a/src/KM_error.h b/src/KM_error.h index c0305e8..0d05174 100755 --- a/src/KM_error.h +++ b/src/KM_error.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2004-2011, John Hurst +Copyright (c) 2004-2014, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -135,6 +135,22 @@ namespace Kumu return Kumu::RESULT_NULL_STR; \ } +// RESULT_STATE is ambiguous. Use these everywhere it is assigned to provide some context +#define KM_RESULT_STATE_TEST_IMPLICIT() \ + if ( result == Kumu::RESULT_STATE ) { \ + Kumu::DefaultLogSink().Error("RESULT_STATE RETURNED at %s (%d)\n", __FILE__, __LINE__); \ + } + +#define KM_RESULT_STATE_TEST_THIS(_this__r_) \ + if ( _this__r_ == Kumu::RESULT_STATE ) { \ + Kumu::DefaultLogSink().Error("RESULT_STATE RETURNED at %s (%d)\n", __FILE__, __LINE__); \ + } + +#define KM_RESULT_STATE_HERE() \ + Kumu::DefaultLogSink().Error("RESULT_STATE RETURNED at %s (%d)\n", __FILE__, __LINE__); + + + namespace Kumu { // simple tracing mechanism diff --git a/src/KM_fileio.cpp b/src/KM_fileio.cpp index 0866acd..417b17e 100644 --- a/src/KM_fileio.cpp +++ b/src/KM_fileio.cpp @@ -1415,6 +1415,110 @@ Kumu::DirScanner::GetNext(char* filename) } +// +Kumu::DirScannerEx::DirScannerEx() : m_Handle(0) {} + +// +Result_t +Kumu::DirScannerEx::Open(const std::string& dirname) +{ + Result_t result = RESULT_OK; + + if ( ( m_Handle = opendir(dirname.c_str()) ) == 0 ) + { + switch ( errno ) + { + case ENOENT: + case ENOTDIR: + result = RESULT_NOTAFILE; + case EACCES: + result = RESULT_NO_PERM; + case ELOOP: + case ENAMETOOLONG: + result = RESULT_PARAM; + case EMFILE: + case ENFILE: + result = RESULT_STATE; + default: + DefaultLogSink().Error("DirScanner::Open(%s): %s\n", dirname.c_str(), strerror(errno)); + result = RESULT_FAIL; + } + } + + if ( KM_SUCCESS(result) ) + m_Dirname = dirname; + + KM_RESULT_STATE_TEST_IMPLICIT(); + return result; +} + +// +Result_t +Kumu::DirScannerEx::Close() +{ + if ( m_Handle == NULL ) + return RESULT_FILEOPEN; + + if ( closedir(m_Handle) == -1 ) + { + switch ( errno ) + { + case EBADF: + case EINTR: + KM_RESULT_STATE_HERE(); + return RESULT_STATE; + + default: + DefaultLogSink().Error("DirScanner::Close(): %s\n", strerror(errno)); + return RESULT_FAIL; + } + } + + m_Handle = 0; + return RESULT_OK; +} + +// +Result_t +Kumu::DirScannerEx::GetNext(std::string& next_item_name, DirectoryEntryType_t& next_item_type) +{ + if ( m_Handle == 0 ) + return RESULT_FILEOPEN; + + struct dirent* entry; + + for (;;) + { + if ( ( entry = readdir(m_Handle) ) == 0 ) + return RESULT_ENDOFFILE; + + break; + } + + next_item_name.assign(entry->d_name, strlen(entry->d_name)); + + switch ( entry->d_type ) + { + case DT_DIR: + next_item_type = DET_DIR; + break; + + case DT_REG: + next_item_type = DET_FILE; + break; + + case DT_LNK: + next_item_type = DET_LINK; + break; + + default: + next_item_type = DET_DEV; + } + + return RESULT_OK; +} + + #endif // KM_WIN32 diff --git a/src/KM_fileio.h b/src/KM_fileio.h index 46e2000..1bf2822 100755 --- a/src/KM_fileio.h +++ b/src/KM_fileio.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2004-2009, John Hurst +Copyright (c) 2004-2014, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -70,6 +70,45 @@ namespace Kumu Result_t GetNext(char*); }; + + // + enum DirectoryEntryType_t { + DET_FILE, + DET_DIR, + DET_DEV, + DET_LINK + }; + + // + class DirScannerEx + { + std::string m_Dirname; +#ifdef KM_WIN32 + __int64 m_Handle; + struct _finddatai64_t m_FileInfo; +#else + DIR* m_Handle; +#endif + + KM_NO_COPY_CONSTRUCT(DirScannerEx); + + public: + + DirScannerEx(); + ~DirScannerEx() { Close(); } + + Result_t Open(const std::string& dirname); + Result_t Close(); + + + inline Result_t GetNext(std::string& next_item_name) { + DirectoryEntryType_t ft; + return GetNext(next_item_name, ft); + } + + Result_t GetNext(std::string& next_item_name, DirectoryEntryType_t& next_item_type); + }; + #ifdef KM_WIN32 typedef __int64 fsize_t; typedef __int64 fpos_t; diff --git a/src/KM_memio.h b/src/KM_memio.h index defea5e..caf4fc0 100755 --- a/src/KM_memio.h +++ b/src/KM_memio.h @@ -128,7 +128,7 @@ namespace Kumu if ( ! WriteRaw((const byte_t*)str.c_str(), len) ) return false; return true; } - }; + }; // class MemIOReader @@ -217,11 +217,16 @@ namespace Kumu inline bool ReadString(std::string& str) { - ui32_t str_length; + ui32_t str_length = 0; if ( ! ReadUi32BE(&str_length) ) return false; - if ( ( m_size + str_length ) > m_capacity ) return false; - str.assign((const char*)CurrentData(), str_length); - if ( ! SkipOffset(str_length) ) return false; + + if ( str_length > 0 ) + { + if ( ( m_size + str_length ) > m_capacity ) return false; + str.assign((const char*)CurrentData(), str_length); + if ( ! SkipOffset(str_length) ) return false; + } + return true; } }; diff --git a/src/KM_util.h b/src/KM_util.h index 1c54860..3e99bbf 100755 --- a/src/KM_util.h +++ b/src/KM_util.h @@ -510,7 +510,7 @@ namespace Kumu inline virtual bool HasValue() const { return m_Length > 0; } - inline virtual ui32_t ArchiveLength() const { return m_Length; } + inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t) + m_Length; } inline virtual bool Archive(MemIOWriter* Writer) const { assert(Writer); diff --git a/src/MDD.cpp b/src/MDD.cpp index a15956c..6da1c91 100644 --- a/src/MDD.cpp +++ b/src/MDD.cpp @@ -911,10 +911,10 @@ static const ASDCP::MDDEntry s_MDD_Table[] = { { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0d, // 291 0x03, 0x01, 0x01, 0x02, 0x03, 0x15, 0x00, 0x00 }, {0}, false, "MCALabelSubDescriptor_RFC5646SpokenLanguage" }, - { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0d, // 292 - 0x01, 0x03, 0x07, 0x01, 0x03, 0x00, 0x00, 0x00 }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0e, // 292 + 0x01, 0x03, 0x07, 0x01, 0x06, 0x00, 0x00, 0x00 }, {0}, false, "AudioChannelLabelSubDescriptor_SoundfieldGroupLinkID" }, - { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0d, // 293 + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0e, // 293 0x01, 0x03, 0x07, 0x01, 0x04, 0x00, 0x00, 0x00 }, {0}, false, "SoundfieldGroupLabelSubDescriptor_GroupOfSoundfieldGroupsLinkID" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x05, // 294 @@ -1148,6 +1148,12 @@ static const ASDCP::MDDEntry s_MDD_Table[] = { { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, // 370 0x0d, 0x01, 0x03, 0x01, 0x02, 0x06, 0x02, 0x00 }, {0}, false, "WAVWrappingClip" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 371 + 0x0e, 0x16, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01 }, + {0}, false, "DBOXMotionCodePrimaryStream" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 372 + 0x0e, 0x16, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02 }, + {0}, false, "DBOXMotionCodeSecondaryStream" }, { {0}, {0}, false, 0 } }; diff --git a/src/MDD.h b/src/MDD.h index e622c6a..83def7b 100755 --- a/src/MDD.h +++ b/src/MDD.h @@ -406,6 +406,8 @@ namespace ASDCP { MDD_AlternativeCenterCuts_4x3, // 368 MDD_AlternativeCenterCuts_14x9, // 369 MDD_WAVWrappingClip, // 370 + MDD_DBOXMotionCodePrimaryStream, // 371 + MDD_DBOXMotionCodeSecondaryStream, // 372 MDD_Max }; // enum MDD_t diff --git a/src/MXF.cpp b/src/MXF.cpp index ac4bb1d..f113444 100755 --- a/src/MXF.cpp +++ b/src/MXF.cpp @@ -1504,7 +1504,7 @@ ASDCP::MXF::decode_mca_string(const std::string& s, const mca_label_map_t& label return false; } - if ( i->second.Value()[10] != 2 ) // magic depends on UL "Essence Facet" byte (see ST 428-12) + if ( i->second.ul.Value()[10] != 2 ) // magic depends on UL "Essence Facet" byte (see ST 428-12) { DefaultLogSink().Error("Not a soundfield group symbol: '%s'\n", symbol_buf.c_str()); return false; @@ -1514,10 +1514,10 @@ ASDCP::MXF::decode_mca_string(const std::string& s, const mca_label_map_t& label GenRandomValue(current_soundfield->InstanceUID); GenRandomValue(current_soundfield->MCALinkID); - current_soundfield->MCATagSymbol = "sg" + i->first; - current_soundfield->MCATagName = i->first; + current_soundfield->MCATagSymbol = (i->second.requires_prefix ? "sg" : "") + i->first; + current_soundfield->MCATagName = i->second.tag_name; current_soundfield->RFC5646SpokenLanguage = language; - current_soundfield->MCALabelDictionaryID = i->second; + current_soundfield->MCALabelDictionaryID = i->second.ul; descriptor_list.push_back(reinterpret_cast(current_soundfield)); symbol_buf.clear(); } @@ -1547,20 +1547,26 @@ ASDCP::MXF::decode_mca_string(const std::string& s, const mca_label_map_t& label new ASDCP::MXF::AudioChannelLabelSubDescriptor(dict); GenRandomValue(channel_descr->InstanceUID); + GenRandomValue(channel_descr->MCALinkID); assert(current_soundfield); channel_descr->SoundfieldGroupLinkID = current_soundfield->MCALinkID; - channel_descr->MCAChannelID = channel_count++; - channel_descr->MCATagSymbol = "ch" + i->first; - channel_descr->MCATagName = i->first; + channel_descr->MCAChannelID = channel_count++ + 1; + channel_descr->MCATagSymbol = (i->second.requires_prefix ? "ch" : "") + i->first; + channel_descr->MCATagName = i->second.tag_name; channel_descr->RFC5646SpokenLanguage = language; - channel_descr->MCALabelDictionaryID = i->second; + channel_descr->MCALabelDictionaryID = i->second.ul; descriptor_list.push_back(reinterpret_cast(channel_descr)); symbol_buf.clear(); current_soundfield = 0; } else if ( *i == ',' ) { - if ( ! symbol_buf.empty() ) + if ( ! symbol_buf.empty() && ! symbol_buf.compare("-") ) + { + channel_count++; + symbol_buf.clear(); + } + else if ( ! symbol_buf.empty() ) { mca_label_map_t::const_iterator i = labels.find(symbol_buf); @@ -1570,7 +1576,7 @@ ASDCP::MXF::decode_mca_string(const std::string& s, const mca_label_map_t& label return false; } - if ( i->second.Value()[10] != 1 ) // magic depends on UL "Essence Facet" byte (see ST 428-12) + if ( i->second.ul.Value()[10] != 1 ) // magic depends on UL "Essence Facet" byte (see ST 428-12) { DefaultLogSink().Error("Not a channel symbol: '%s'\n", symbol_buf.c_str()); return false; @@ -1586,16 +1592,16 @@ ASDCP::MXF::decode_mca_string(const std::string& s, const mca_label_map_t& label channel_descr->SoundfieldGroupLinkID = current_soundfield->MCALinkID; } - channel_descr->MCAChannelID = channel_count++; - channel_descr->MCATagSymbol = "ch" + i->first; - channel_descr->MCATagName = i->first; + channel_descr->MCAChannelID = channel_count++ + 1; + channel_descr->MCATagSymbol = (i->second.requires_prefix ? "ch" : "") + i->first; + channel_descr->MCATagName = i->second.tag_name; channel_descr->RFC5646SpokenLanguage = language; - channel_descr->MCALabelDictionaryID = i->second; + channel_descr->MCALabelDictionaryID = i->second.ul; descriptor_list.push_back(reinterpret_cast(channel_descr)); symbol_buf.clear(); } } - else if ( isalnum(*i) ) + else if ( *i == '-' || isalnum(*i) ) { symbol_buf += *i; } @@ -1606,7 +1612,11 @@ ASDCP::MXF::decode_mca_string(const std::string& s, const mca_label_map_t& label } } - if ( ! symbol_buf.empty() ) + if ( ! symbol_buf.empty() && ! symbol_buf.compare("-") ) + { + channel_count++; + } + else if ( ! symbol_buf.empty() ) { mca_label_map_t::const_iterator i = labels.find(symbol_buf); @@ -1620,17 +1630,18 @@ ASDCP::MXF::decode_mca_string(const std::string& s, const mca_label_map_t& label new ASDCP::MXF::AudioChannelLabelSubDescriptor(dict); GenRandomValue(channel_descr->InstanceUID); + GenRandomValue(channel_descr->MCALinkID); if ( current_soundfield != 0 ) { channel_descr->SoundfieldGroupLinkID = current_soundfield->MCALinkID; } - channel_descr->MCAChannelID = channel_count++; - channel_descr->MCATagSymbol = "ch" + i->first; - channel_descr->MCATagName = i->first; + channel_descr->MCAChannelID = channel_count++ + 1; + channel_descr->MCATagSymbol = (i->second.requires_prefix ? "ch" : "") + i->first; + channel_descr->MCATagName = i->second.tag_name; channel_descr->RFC5646SpokenLanguage = language; - channel_descr->MCALabelDictionaryID = i->second; + channel_descr->MCALabelDictionaryID = i->second.ul; descriptor_list.push_back(reinterpret_cast(channel_descr)); } @@ -1640,26 +1651,29 @@ ASDCP::MXF::decode_mca_string(const std::string& s, const mca_label_map_t& label // ASDCP::MXF::ASDCP_MCAConfigParser::ASDCP_MCAConfigParser(const Dictionary*& d) : m_Dict(d), m_ChannelCount(0) { - m_LabelMap.insert(mca_label_map_t::value_type("L", m_Dict->ul(MDD_DCAudioChannel_L))); - m_LabelMap.insert(mca_label_map_t::value_type("R", m_Dict->ul(MDD_DCAudioChannel_R))); - m_LabelMap.insert(mca_label_map_t::value_type("C", m_Dict->ul(MDD_DCAudioChannel_C))); - m_LabelMap.insert(mca_label_map_t::value_type("LFE", m_Dict->ul(MDD_DCAudioChannel_LFE))); - m_LabelMap.insert(mca_label_map_t::value_type("Ls", m_Dict->ul(MDD_DCAudioChannel_Ls))); - m_LabelMap.insert(mca_label_map_t::value_type("Rs", m_Dict->ul(MDD_DCAudioChannel_Rs))); - m_LabelMap.insert(mca_label_map_t::value_type("Lss", m_Dict->ul(MDD_DCAudioChannel_Lss))); - m_LabelMap.insert(mca_label_map_t::value_type("Rss", m_Dict->ul(MDD_DCAudioChannel_Rss))); - m_LabelMap.insert(mca_label_map_t::value_type("Lrs", m_Dict->ul(MDD_DCAudioChannel_Lrs))); - m_LabelMap.insert(mca_label_map_t::value_type("Rrs", m_Dict->ul(MDD_DCAudioChannel_Rrs))); - m_LabelMap.insert(mca_label_map_t::value_type("Lc", m_Dict->ul(MDD_DCAudioChannel_Lc))); - m_LabelMap.insert(mca_label_map_t::value_type("Rc", m_Dict->ul(MDD_DCAudioChannel_Rc))); - m_LabelMap.insert(mca_label_map_t::value_type("Cs", m_Dict->ul(MDD_DCAudioChannel_Cs))); - m_LabelMap.insert(mca_label_map_t::value_type("HI", m_Dict->ul(MDD_DCAudioChannel_HI))); - m_LabelMap.insert(mca_label_map_t::value_type("VIN", m_Dict->ul(MDD_DCAudioChannel_VIN))); - m_LabelMap.insert(mca_label_map_t::value_type("51", m_Dict->ul(MDD_DCAudioSoundfield_51))); - m_LabelMap.insert(mca_label_map_t::value_type("71", m_Dict->ul(MDD_DCAudioSoundfield_71))); - m_LabelMap.insert(mca_label_map_t::value_type("SDS", m_Dict->ul(MDD_DCAudioSoundfield_SDS))); - m_LabelMap.insert(mca_label_map_t::value_type("61", m_Dict->ul(MDD_DCAudioSoundfield_61))); - m_LabelMap.insert(mca_label_map_t::value_type("M", m_Dict->ul(MDD_DCAudioSoundfield_M))); + typedef mca_label_map_t::value_type pair; + m_LabelMap.insert(pair("L", label_traits("Left" , true, m_Dict->ul(MDD_DCAudioChannel_L)))); + m_LabelMap.insert(pair("R", label_traits("Right" , true, m_Dict->ul(MDD_DCAudioChannel_R)))); + m_LabelMap.insert(pair("C", label_traits("Center" , true, m_Dict->ul(MDD_DCAudioChannel_C)))); + m_LabelMap.insert(pair("LFE", label_traits("LFE" , true, m_Dict->ul(MDD_DCAudioChannel_LFE)))); + m_LabelMap.insert(pair("Ls", label_traits("Left Surround" , true, m_Dict->ul(MDD_DCAudioChannel_Ls)))); + m_LabelMap.insert(pair("Rs", label_traits("Right Surround" , true, m_Dict->ul(MDD_DCAudioChannel_Rs)))); + m_LabelMap.insert(pair("Lss", label_traits("Left Side Surround" , true, m_Dict->ul(MDD_DCAudioChannel_Lss)))); + m_LabelMap.insert(pair("Rss", label_traits("Right Side Surround" , true, m_Dict->ul(MDD_DCAudioChannel_Rss)))); + m_LabelMap.insert(pair("Lrs", label_traits("Left Rear Surround" , true, m_Dict->ul(MDD_DCAudioChannel_Lrs)))); + m_LabelMap.insert(pair("Rrs", label_traits("Right Rear Surround" , true, m_Dict->ul(MDD_DCAudioChannel_Rrs)))); + m_LabelMap.insert(pair("Lc", label_traits("Left Center" , true, m_Dict->ul(MDD_DCAudioChannel_Lc)))); + m_LabelMap.insert(pair("Rc", label_traits("Right Center" , true, m_Dict->ul(MDD_DCAudioChannel_Rc)))); + m_LabelMap.insert(pair("Cs", label_traits("Center Surround" , true, m_Dict->ul(MDD_DCAudioChannel_Cs)))); + m_LabelMap.insert(pair("HI", label_traits("Hearing Impaired" , true, m_Dict->ul(MDD_DCAudioChannel_HI)))); + m_LabelMap.insert(pair("VIN", label_traits("Visually Impaired-Narrative" , true, m_Dict->ul(MDD_DCAudioChannel_VIN)))); + m_LabelMap.insert(pair("51", label_traits("5.1" , true, m_Dict->ul(MDD_DCAudioSoundfield_51)))); + m_LabelMap.insert(pair("71", label_traits("7.1DS" , true, m_Dict->ul(MDD_DCAudioSoundfield_71)))); + m_LabelMap.insert(pair("SDS", label_traits("7.1SDS" , true, m_Dict->ul(MDD_DCAudioSoundfield_SDS)))); + m_LabelMap.insert(pair("61", label_traits("6.1" , true, m_Dict->ul(MDD_DCAudioSoundfield_61)))); + m_LabelMap.insert(pair("M", label_traits("1.0 Monaural" , true, m_Dict->ul(MDD_DCAudioSoundfield_M)))); + m_LabelMap.insert(pair("DBOX", label_traits("D-BOX Motion Code Primary Stream" , false, m_Dict->ul(MDD_DBOXMotionCodePrimaryStream)))); + m_LabelMap.insert(pair("DBOX2", label_traits("D-BOX Motion Code Secondary Stream", false, m_Dict->ul(MDD_DBOXMotionCodeSecondaryStream)))); } // @@ -1680,25 +1694,26 @@ ASDCP::MXF::ASDCP_MCAConfigParser::DecodeString(const std::string& s, const std: ASDCP::MXF::AS02_MCAConfigParser::AS02_MCAConfigParser(const Dictionary*& d) : ASDCP::MXF::ASDCP_MCAConfigParser(d) { - m_LabelMap.insert(mca_label_map_t::value_type("M1", m_Dict->ul(MDD_IMFAudioChannel_M1))); - m_LabelMap.insert(mca_label_map_t::value_type("M2", m_Dict->ul(MDD_IMFAudioChannel_M2))); - m_LabelMap.insert(mca_label_map_t::value_type("Lt", m_Dict->ul(MDD_IMFAudioChannel_Lt))); - m_LabelMap.insert(mca_label_map_t::value_type("Rt", m_Dict->ul(MDD_IMFAudioChannel_Rt))); - m_LabelMap.insert(mca_label_map_t::value_type("Lst", m_Dict->ul(MDD_IMFAudioChannel_Lst))); - m_LabelMap.insert(mca_label_map_t::value_type("Rst", m_Dict->ul(MDD_IMFAudioChannel_Rst))); - m_LabelMap.insert(mca_label_map_t::value_type("S", m_Dict->ul(MDD_IMFAudioChannel_S))); - m_LabelMap.insert(mca_label_map_t::value_type("ST", m_Dict->ul(MDD_IMFAudioSoundfield_ST))); - m_LabelMap.insert(mca_label_map_t::value_type("DM", m_Dict->ul(MDD_IMFAudioSoundfield_DM))); - m_LabelMap.insert(mca_label_map_t::value_type("DNS", m_Dict->ul(MDD_IMFAudioSoundfield_DNS))); - m_LabelMap.insert(mca_label_map_t::value_type("30", m_Dict->ul(MDD_IMFAudioSoundfield_30))); - m_LabelMap.insert(mca_label_map_t::value_type("40", m_Dict->ul(MDD_IMFAudioSoundfield_40))); - m_LabelMap.insert(mca_label_map_t::value_type("50", m_Dict->ul(MDD_IMFAudioSoundfield_50))); - m_LabelMap.insert(mca_label_map_t::value_type("60", m_Dict->ul(MDD_IMFAudioSoundfield_60))); - m_LabelMap.insert(mca_label_map_t::value_type("70", m_Dict->ul(MDD_IMFAudioSoundfield_70))); - m_LabelMap.insert(mca_label_map_t::value_type("LtRt", m_Dict->ul(MDD_IMFAudioSoundfield_LtRt))); - m_LabelMap.insert(mca_label_map_t::value_type("51Ex", m_Dict->ul(MDD_IMFAudioSoundfield_51Ex))); - m_LabelMap.insert(mca_label_map_t::value_type("HI", m_Dict->ul(MDD_IMFAudioSoundfield_HI))); - m_LabelMap.insert(mca_label_map_t::value_type("VIN", m_Dict->ul(MDD_IMFAudioSoundfield_VIN))); + typedef mca_label_map_t::value_type pair; + m_LabelMap.insert(pair("M1", label_traits("M1", true, m_Dict->ul(MDD_IMFAudioChannel_M1)))); + m_LabelMap.insert(pair("M2", label_traits("M2", true, m_Dict->ul(MDD_IMFAudioChannel_M2)))); + m_LabelMap.insert(pair("Lt", label_traits("Lt", true, m_Dict->ul(MDD_IMFAudioChannel_Lt)))); + m_LabelMap.insert(pair("Rt", label_traits("Rt", true, m_Dict->ul(MDD_IMFAudioChannel_Rt)))); + m_LabelMap.insert(pair("Lst", label_traits("Lst", true, m_Dict->ul(MDD_IMFAudioChannel_Lst)))); + m_LabelMap.insert(pair("Rst", label_traits("Rst", true, m_Dict->ul(MDD_IMFAudioChannel_Rst)))); + m_LabelMap.insert(pair("S", label_traits("S", true, m_Dict->ul(MDD_IMFAudioChannel_S)))); + m_LabelMap.insert(pair("ST", label_traits("ST", true, m_Dict->ul(MDD_IMFAudioSoundfield_ST)))); + m_LabelMap.insert(pair("DM", label_traits("DM", true, m_Dict->ul(MDD_IMFAudioSoundfield_DM)))); + m_LabelMap.insert(pair("DNS", label_traits("DNS", true, m_Dict->ul(MDD_IMFAudioSoundfield_DNS)))); + m_LabelMap.insert(pair("30", label_traits("30", true, m_Dict->ul(MDD_IMFAudioSoundfield_30)))); + m_LabelMap.insert(pair("40", label_traits("40", true, m_Dict->ul(MDD_IMFAudioSoundfield_40)))); + m_LabelMap.insert(pair("50", label_traits("50", true, m_Dict->ul(MDD_IMFAudioSoundfield_50)))); + m_LabelMap.insert(pair("60", label_traits("60", true, m_Dict->ul(MDD_IMFAudioSoundfield_60)))); + m_LabelMap.insert(pair("70", label_traits("70", true, m_Dict->ul(MDD_IMFAudioSoundfield_70)))); + m_LabelMap.insert(pair("LtRt", label_traits("LtRt",true, m_Dict->ul(MDD_IMFAudioSoundfield_LtRt)))); + m_LabelMap.insert(pair("51Ex", label_traits("51Ex",true, m_Dict->ul(MDD_IMFAudioSoundfield_51Ex)))); + m_LabelMap.insert(pair("HI", label_traits("HI", true, m_Dict->ul(MDD_IMFAudioSoundfield_HI)))); + m_LabelMap.insert(pair("VIN", label_traits("VIN", true, m_Dict->ul(MDD_IMFAudioSoundfield_VIN)))); } // diff --git a/src/MXF.h b/src/MXF.h index 6e6a47a..88fc0af 100755 --- a/src/MXF.h +++ b/src/MXF.h @@ -459,7 +459,18 @@ namespace ASDCP } }; - typedef std::map mca_label_map_t; + struct label_traits + { + const std::string tag_name; + const bool requires_prefix; + const UL ul; + + label_traits(const std::string& tag_name, const bool requires_prefix, const UL ul) : + tag_name(tag_name), requires_prefix(requires_prefix), ul(ul) { } + }; + + typedef std::map mca_label_map_t; + bool decode_mca_string(const std::string& s, const mca_label_map_t& labels, const Dictionary*& dict, const std::string& language, InterchangeObject_list_t&, ui32_t&); @@ -477,7 +488,7 @@ namespace ASDCP public: ASDCP_MCAConfigParser(const Dictionary*&); - bool DecodeString(const std::string& s, const std::string& language = "en"); + bool DecodeString(const std::string& s, const std::string& language = "en-US"); // Valid only after a successful call to DecodeString ui32_t ChannelCount() const; diff --git a/src/MXFTypes.cpp b/src/MXFTypes.cpp index 58c6fb7..483eb70 100755 --- a/src/MXFTypes.cpp +++ b/src/MXFTypes.cpp @@ -410,7 +410,7 @@ ASDCP::MXF::ISO8String::Archive(Kumu::MemIOWriter* Writer) const return false; } - return Writer->WriteString(*this); + return Writer->WriteRaw((const byte_t*)c_str(), size()); } //------------------------------------------------------------------------------------------ diff --git a/src/Makefile.am b/src/Makefile.am index d9c981e..d72ba34 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -64,7 +64,13 @@ include_HEADERS += \ MXF.h \ Wav.h \ PCMParserList.h \ - AtmosSyncChannel_Generator.h + AtmosSyncChannel_Mixer.h \ + AtmosSyncChannel_Generator.h \ + PCMDataProviders.h \ + SyncCommon.h \ + SyncEncoder.h \ + UUIDInformation.h + nodist_include_HEADERS = TimedText_Transform.h endif diff --git a/src/as-02-unwrap.cpp b/src/as-02-unwrap.cpp index ae66df7..b8f69a0 100755 --- a/src/as-02-unwrap.cpp +++ b/src/as-02-unwrap.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2011-2013, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, +Copyright (c) 2011-2014, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst All rights reserved. @@ -69,7 +69,7 @@ banner(FILE* stream = stdout) { fprintf(stream, "\n\ %s (asdcplib %s)\n\n\ -Copyright (c) 2011-2013, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst\n\n\ +Copyright (c) 2011-2014, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst\n\n\ asdcplib may be copied only under the terms of the license found at\n\ the top of every file in the asdcplib distribution kit.\n\n\ Specify the -h (help) option for further information about %s\n\n", diff --git a/src/asdcp-info.cpp b/src/asdcp-info.cpp index df69d2b..65edd09 100755 --- a/src/asdcp-info.cpp +++ b/src/asdcp-info.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2003-2012, John Hurst +Copyright (c) 2003-2014, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -75,7 +75,7 @@ banner(FILE* stream = stdout) { fprintf(stream, "\n\ %s (asdcplib %s)\n\n\ -Copyright (c) 2003-2012 John Hurst\n\n\ +Copyright (c) 2003-2014 John Hurst\n\n\ asdcplib may be copied only under the terms of the license found at\n\ the top of every file in the asdcplib distribution kit.\n\n\ Specify the -h (help) option for further information about %s\n\n", @@ -488,14 +488,17 @@ public: } } - // scale bytes to megabits - static const double mega_const = 1.0 / ( 1000000 / 8.0 ); + if ( KM_SUCCESS(result) ) + { + // scale bytes to megabits + static const double mega_const = 1.0 / ( 1000000 / 8.0 ); - // we did not accumulate the first or last frame, so duration -= 2 - double avg_bytes_frame = total_frame_bytes / ( m_Desc.ContainerDuration - 2 ); + // we did not accumulate the first or last frame, so duration -= 2 + double avg_bytes_frame = total_frame_bytes / ( m_Desc.ContainerDuration - 2 ); - m_MaxBitrate = largest_frame * mega_const * m_Desc.EditRate.Quotient(); - m_AvgBitrate = avg_bytes_frame * mega_const * m_Desc.EditRate.Quotient(); + m_MaxBitrate = largest_frame * mega_const * m_Desc.EditRate.Quotient(); + m_AvgBitrate = avg_bytes_frame * mega_const * m_Desc.EditRate.Quotient(); + } } // diff --git a/src/asdcp-test.cpp b/src/asdcp-test.cpp index a35770a..dc50706 100755 --- a/src/asdcp-test.cpp +++ b/src/asdcp-test.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2003-2012, John Hurst +Copyright (c) 2003-2014, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -103,7 +103,7 @@ banner(FILE* stream = stdout) { fprintf(stream, "\n\ %s (asdcplib %s)\n\n\ -Copyright (c) 2003-2012 John Hurst\n\n\ +Copyright (c) 2003-2014 John Hurst\n\n\ asdcplib may be copied only under the terms of the license found at\n\ the top of every file in the asdcplib distribution kit.\n\n\ Specify the -h (help) option for further information about %s\n\n", @@ -241,9 +241,6 @@ decode_channel_fmt(const std::string& label_name) else if ( label_name == "7.1DS" ) return PCM::CF_CFG_5; - else if ( label_name == "MCA" ) - return PCM::CF_CFG_6; - fprintf(stderr, "Error decoding channel format string: %s\n", label_name.c_str()); fprintf(stderr, "Expecting '5.1', '6.1', '7.1', '7.1DS' or 'WTF'\n"); return PCM::CF_NONE; diff --git a/src/asdcp-unwrap.cpp b/src/asdcp-unwrap.cpp index 7b8654b..e3572f6 100755 --- a/src/asdcp-unwrap.cpp +++ b/src/asdcp-unwrap.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2003-2012, John Hurst +Copyright (c) 2003-2014, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -61,7 +61,7 @@ banner(FILE* stream = stdout) { fprintf(stream, "\n\ %s (asdcplib %s)\n\n\ -Copyright (c) 2003-2012 John Hurst\n\n\ +Copyright (c) 2003-2014 John Hurst\n\n\ asdcplib may be copied only under the terms of the license found at\n\ the top of every file in the asdcplib distribution kit.\n\n\ Specify the -h (help) option for further information about %s\n\n", diff --git a/src/asdcp-wrap.cpp b/src/asdcp-wrap.cpp index fd4a6d9..b87e4c7 100755 --- a/src/asdcp-wrap.cpp +++ b/src/asdcp-wrap.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2003-2013, John Hurst +Copyright (c) 2003-2014, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -104,7 +104,7 @@ banner(FILE* stream = stdout) { fprintf(stream, "\n\ %s (asdcplib %s)\n\n\ -Copyright (c) 2003-2012 John Hurst\n\n\ +Copyright (c) 2003-2014 John Hurst\n\n\ asdcplib may be copied only under the terms of the license found at\n\ the top of every file in the asdcplib distribution kit.\n\n\ Specify the -h (help) option for further information about %s\n\n", @@ -139,6 +139,8 @@ Options:\n\ -M - Do not create HMAC values when writing\n\ -m - Write MCA labels using . Example:\n\ 51(L,R,C,LFE,Ls,Rs,),HI,VIN\n\ + Note: The symbol '-' may be used for an unlabeled\n\ + channel, but not within a soundfield.\n\ -a - Specify the Asset ID of the file\n\ -b - Specify size in bytes of picture frame buffer\n\ Defaults to 4,194,304 (4MB)\n\ @@ -187,9 +189,6 @@ decode_channel_fmt(const std::string& label_name) else if ( label_name == "7.1DS" ) return PCM::CF_CFG_5; - else if ( label_name == "MCA" ) - return PCM::CF_CFG_6; - fprintf(stderr, "Error decoding channel format string: %s\n", label_name.c_str()); fprintf(stderr, "Expecting '5.1', '6.1', '7.1', '7.1DS' or 'WTF'\n"); return PCM::CF_NONE; -- 2.30.2