added a note about AS-02 support.
authormikey <mikey@cinecert.com>
Tue, 29 Apr 2014 15:31:21 +0000 (15:31 +0000)
committermikey <>
Tue, 29 Apr 2014 15:31:21 +0000 (15:31 +0000)
20 files changed:
src/AS_02.h
src/AS_DCP_AES.cpp
src/AtmosSyncChannel_Mixer.cpp
src/AtmosSyncChannel_Mixer.h
src/KM_error.h
src/KM_fileio.cpp
src/KM_fileio.h
src/KM_memio.h
src/KM_util.h
src/MDD.cpp
src/MDD.h
src/MXF.cpp
src/MXF.h
src/MXFTypes.cpp
src/Makefile.am
src/as-02-unwrap.cpp
src/asdcp-info.cpp
src/asdcp-test.cpp
src/asdcp-unwrap.cpp
src/asdcp-wrap.cpp

index 6b34c777134ad595e3b552c9eb43d8a7b03819cb..02efb9fdeb417626c6579ded815ba2a94db48b35 100644 (file)
@@ -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
index 51955f6680c422235d566b154bb9747be651bbb7..379e8abe9e42deead11e1726f7603ecf3d3ccaf9 100755 (executable)
@@ -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;
index 70cfbfdc93260e43ba1e5b6d7fe19087801dfa3e..a58b3cd39dc3a37d667d0e9d8ec5a6ea716d6090 100644 (file)
@@ -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<SilenceDataProvider> 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
index c6a27a3deee511f32d4fa0c455bbacfa0d67fd1f..27c3b9f87a669b47cf032d8235160e8a115ae823 100644 (file)
@@ -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);
index c0305e88db1f839d1493ee38f0f59a3d42100de2..0d051746c888835f0a4a179920f9823f5458bb2d 100755 (executable)
@@ -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
index 0866acd9e0ab8adf3f6702fe7550b0397dcf1204..417b17e60074038fc8e1e9df7c6e45a95e6b40f8 100644 (file)
@@ -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
 
 
index 46e200086b8fe0b0694487f777831ceaef7e09c0..1bf2822077c416b9af998a93645ea3daa8f1e881 100755 (executable)
@@ -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;
index defea5ed89a151a97a886930e71ea2cbca9e73b8..caf4fc0aca0f48a1517a8a6bbd1c93822baa0c90 100755 (executable)
@@ -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;
       }
     };
index 1c54860faa1471b53d7a089adfd8256b2f326b75..3e99bbfccb8f6d61403909806c5705f996644d95 100755 (executable)
@@ -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);
index a15956cca5789ff343e02349a07c59619b625187..6da1c9137c1c1403f6add8e3b314039ade164472 100644 (file)
@@ -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 }
 };
index e622c6a2ae07f86e4a53844aa67ee33db1a669ad..83def7bcda26634d91a42b96ef1cef185ca6788b 100755 (executable)
--- 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
 
index ac4bb1d2da2d89da2d39b9bffbcbe8cd7cbbef56..f113444b4654a124b46ab183def9f8ba6475630d 100755 (executable)
@@ -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<ASDCP::MXF::InterchangeObject*>(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<ASDCP::MXF::InterchangeObject*>(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<ASDCP::MXF::InterchangeObject*>(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<ASDCP::MXF::InterchangeObject*>(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))));
 }
 
 //
index 6e6a47afd154e4326661e51888a2d60f0ee9efbd..88fc0af69776bf83cb4eaa1f104ab7c4339d4161 100755 (executable)
--- a/src/MXF.h
+++ b/src/MXF.h
@@ -459,7 +459,18 @@ namespace ASDCP
        }
       };
 
-      typedef std::map<const std::string, const UL, ci_comp> 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<const std::string, const label_traits, ci_comp> 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;
index 58c6fb703ab68dbed1bbbbc0b450d1f9ffbcd21c..483eb7048150762b031e4ed0919b3d71f4bcf752 100755 (executable)
@@ -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());
 }
 
 //------------------------------------------------------------------------------------------
index d9c981e42be6d319d4d9a4eb7221de0cb41da90f..d72ba347267305721b9e49d5d8fec92102dde6af 100644 (file)
@@ -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
index ae66df7eea6463e22ab385472531448c576a8080..b8f69a0a169bf0946f7a8ca20659a62153cef869 100755 (executable)
@@ -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",
index df69d2b83c711b195210a5f65239b348a451bb93..65edd097cc8ea17068c557933c0b298b0e6a4213 100755 (executable)
@@ -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();
+      }
   }
 
   //
index a35770a3e7bc1b76bcac3dd0805c248066d07668..dc507066eeaef0d7a212aac004c0cf38be02e989 100755 (executable)
@@ -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;
index 7b8654bbda68c7ff4b6c9cdb8ea29d90578e80a2..e3572f695f3c7d862151d2b8a11bdf735a1b613f 100755 (executable)
@@ -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",
index fd4a6d931b5d7bf2594eaf68a99e8968dd3404c2..b87e4c7392902c95f62fe5132ee96f4eaf45d119 100755 (executable)
@@ -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 <expr>         - Write MCA labels using <expr>.  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 <UUID>         - Specify the Asset ID of the file\n\
   -b <buffer-size>  - 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;