Implemented J2K desc to/from MD
[asdcplib.git] / src / asdcp-info.cpp
index 05e2c79a353a93c9928bf764256cf6ccd7d1dc01..b8876fed903326fb417d3fb478a8f121eddd935b 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
@@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 /*! \file    asdcp-info.cpp
-    \version $Id$       
+    \version $Id$
     \brief   AS-DCP file metadata utility
 
   This program provides metadata information about an AS-DCP file.
@@ -35,6 +35,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include <KM_fileio.h>
 #include <AS_DCP.h>
+#include <AS_02.h>
 #include <MXF.h>
 #include <Metadata.h>
 
@@ -75,7 +76,7 @@ banner(FILE* stream = stdout)
 {
   fprintf(stream, "\n\
 %s (asdcplib %s)\n\n\
-Copyright (c) 2003-2012 John Hurst\n\n\
+Copyright (c) 2003-2015 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",
@@ -93,7 +94,7 @@ USAGE:%s [-h|-help] [-V]\n\
 \n\
 Options:\n\
   -3          - Force stereoscopic interpretation of a JP2K file\n\
-  -C          - Do not show essence coding UL\n\
+  -c          - Show essence coding UL\n\
   -d          - Show essence descriptor info\n\
   -h | -help  - Show help\n\
   -H          - Show MXF header metadata\n\
@@ -125,7 +126,7 @@ public:
   bool   stereo_image_flag; // if true, expect stereoscopic JP2K input (left eye first)
   bool   showid_flag;          // if true, show file identity info (the WriterInfo struct)
   bool   showdescriptor_flag;  // if true, show the essence descriptor
-  bool   showcoding_flag;      // if true, show the coding UL 
+  bool   showcoding_flag;      // if true, show the coding UL
   bool   showrate_flag;        // if true and is image file, show bit rate
   bool   max_bitrate_flag;     // true if -t option given
   double max_bitrate;          // if true and is image file, max bit rate for rate test
@@ -145,7 +146,7 @@ public:
            help_flag = true;
            continue;
          }
-         
+
        if ( argv[i][0] == '-'
             && ( isalpha(argv[i][1]) || isdigit(argv[i][1]) )
             && argv[i][2] == 0 )
@@ -163,7 +164,7 @@ public:
 
              case 't':
                TEST_EXTRA_ARG(i, 't');
-               max_bitrate = abs(atoi(argv[i]));
+               max_bitrate = Kumu::xabs(strtol(argv[i], 0, 10));
                max_bitrate_flag = true;
                break;
 
@@ -191,7 +192,7 @@ public:
 
     if ( help_flag || version_flag )
       return;
-    
+
     if ( filenames.empty() )
       {
        fputs("At least one filename argument is required.\n", stderr);
@@ -270,6 +271,30 @@ class MyTextDescriptor : public TimedText::TimedTextDescriptor
   }
 };
 
+class MyDCDataDescriptor : public DCData::DCDataDescriptor
+{
+ public:
+  void FillDescriptor(DCData::MXFReader& Reader) {
+    Reader.FillDCDataDescriptor(*this);
+  }
+
+  void Dump(FILE* stream) {
+      DCData::DCDataDescriptorDump(*this, stream);
+  }
+};
+
+class MyAtmosDescriptor : public ATMOS::AtmosDescriptor
+{
+ public:
+  void FillDescriptor(ATMOS::MXFReader& Reader) {
+    Reader.FillAtmosDescriptor(*this);
+  }
+
+  void Dump(FILE* stream) {
+      ATMOS::AtmosDescriptorDump(*this, stream);
+  }
+};
+
 //
 //
 template<class ReaderT, class DescriptorT>
@@ -302,7 +327,8 @@ public:
        m_Desc.FillDescriptor(m_Reader);
        m_Reader.FillWriterInfo(m_WriterInfo);
 
-       fprintf(stdout, "File essence type is %s, (%d edit unit%s).\n",
+       fprintf(stdout, "%s file essence type is %s, (%d edit unit%s).\n",
+               ( m_WriterInfo.LabelSetType == LS_MXF_SMPTE ? "SMPTE 429" : LS_MXF_INTEROP ? "Interop" : "Unknown" ),
                type_string, m_Desc.ContainerDuration, (m_Desc.ContainerDuration==1?"":"s"));
 
        if ( Options.showheader_flag )
@@ -331,9 +357,9 @@ public:
     const Dictionary& Dict = DefaultCompositeDict();
     MXF::RGBAEssenceDescriptor *descriptor = 0;
 
-    Result_t result = m_Reader.OPAtomHeader().GetMDObjectByType(DefaultCompositeDict().ul(MDD_RGBAEssenceDescriptor),
-                                                               reinterpret_cast<MXF::InterchangeObject**>(&descriptor));
-    
+    Result_t result = m_Reader.OP1aHeader().GetMDObjectByType(DefaultCompositeDict().ul(MDD_RGBAEssenceDescriptor),
+                                                             reinterpret_cast<MXF::InterchangeObject**>(&descriptor));
+
     if ( KM_SUCCESS(result) )
       m_PictureEssenceCoding = descriptor->PictureEssenceCoding;
   }
@@ -452,7 +478,7 @@ public:
          {
            if ( last_stream_offset != 0 )
              {
-               ui64_t this_frame_size = entry.StreamOffset - last_stream_offset;
+               ui64_t this_frame_size = entry.StreamOffset - last_stream_offset - 20; // do not count the bytes that represent the KLV wrapping 
                total_frame_bytes += this_frame_size;
 
                if ( this_frame_size > largest_frame )
@@ -463,14 +489,17 @@ public:
          }
       }
 
-    // scale bytes to megabits
-    static const double mega_const = 1 / ( 1024.0 * 1024.0 / 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();
+      }
   }
 
   //
@@ -487,13 +516,13 @@ public:
     const Dictionary& Dict = DefaultCompositeDict();
     MXF::WaveAudioDescriptor *descriptor = 0;
 
-    Result_t result = m_Reader.OPAtomHeader().GetMDObjectByType(DefaultCompositeDict().ul(MDD_WaveAudioDescriptor),
-                                                               reinterpret_cast<MXF::InterchangeObject**>(&descriptor));
-    
+    Result_t result = m_Reader.OP1aHeader().GetMDObjectByType(DefaultCompositeDict().ul(MDD_WaveAudioDescriptor),
+                                                             reinterpret_cast<MXF::InterchangeObject**>(&descriptor));
+
     if ( KM_SUCCESS(result) )
       {
        char buf[64];
-       fprintf(stream, "ChannelAssignment: %s\n", descriptor->ChannelAssignment.EncodeString(buf, 64));
+       fprintf(stream, "ChannelAssignment: %s\n", descriptor->ChannelAssignment.const_get().EncodeString(buf, 64));
       }
   }
 
@@ -572,7 +601,7 @@ show_file_info(CommandOptions& Options)
     {
       FileInfoWrapper<ASDCP::JP2K::MXFSReader, MyStereoPictureDescriptor>wrapper;
       result = wrapper.file_info(Options, "JPEG 2000 stereoscopic pictures");
-      
+
       if ( KM_SUCCESS(result) )
        {
          wrapper.get_PictureEssenceCoding();
@@ -592,12 +621,29 @@ show_file_info(CommandOptions& Options)
       FileInfoWrapper<ASDCP::TimedText::MXFReader, MyTextDescriptor>wrapper;
       result = wrapper.file_info(Options, "Timed Text");
     }
+  else if ( EssenceType == ESS_DCDATA_UNKNOWN )
+    {
+      FileInfoWrapper<ASDCP::DCData::MXFReader, MyDCDataDescriptor> wrapper;
+      result = wrapper.file_info(Options, "D-Cinema Generic Data");
+    }
+  else if ( EssenceType == ESS_DCDATA_DOLBY_ATMOS )
+    {
+      FileInfoWrapper<ASDCP::ATMOS::MXFReader, MyAtmosDescriptor> wrapper;
+      result = wrapper.file_info(Options, "Dolby ATMOS");
+    }
+  else if ( EssenceType == ESS_AS02_PCM_24b_48k
+           || EssenceType == ESS_AS02_PCM_24b_96k
+           || EssenceType == ESS_AS02_JPEG_2000
+           || EssenceType == ESS_AS02_TIMED_TEXT )
+    {
+      fprintf(stderr, "File is AS-02. Inspection in not supported by this command.\n");
+    }
   else
     {
       fprintf(stderr, "File is not AS-DCP: %s\n", Options.filenames.front().c_str());
       Kumu::FileReader   Reader;
       const Dictionary* Dict = &DefaultCompositeDict();
-      MXF::OPAtomHeader TestHeader(Dict);
+      MXF::OP1aHeader TestHeader(Dict);
 
       result = Reader.OpenRead(Options.filenames.front().c_str());