From 46139166ca33b761fe6482a3486610edbbad0b82 Mon Sep 17 00:00:00 2001
From: kidjan <kidjan@6e6572fa-98a6-11dd-ad9f-f77439c74b79>
Date: Mon, 21 May 2012 04:48:23 +0000
Subject: [PATCH 01/21] Fixes for issue #132--configure.ac should be treating
 something as string, but it was using %d instead.  Also, fix for time_t on
 mingw.

---
 configure.ac                 | 2 +-
 libplatform/platform_win32.h | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index 7c514eb..83e9dce 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,7 +20,7 @@ m4_define([PRJ_version_hex],m4_format([0x%04x%02x%02x],PRJ_version_major,PRJ_ver
 
 m4_define([PRJ_version],ifelse(
     PRJ_repo_type,[stable],m4_format([%s],PRJ_repo_branch),
-    m4_format([%s-r%d],PRJ_repo_branch,PRJ_repo_rev)))
+    m4_format([%s-r%s],PRJ_repo_branch,PRJ_repo_rev)))
 
 ###############################################################################
 # initialization
diff --git a/libplatform/platform_win32.h b/libplatform/platform_win32.h
index 7e8685a..2be4952 100644
--- a/libplatform/platform_win32.h
+++ b/libplatform/platform_win32.h
@@ -7,6 +7,8 @@
 #ifdef __MINGW32__
 #   undef  __MSVCRT_VERSION__
 #   define __MSVCRT_VERSION__ 0x800
+// JAN: see http://code.google.com/p/mp4v2/issues/detail?id=132
+#   define _USE_32BIT_TIME_T
 #endif
 
 // set minimum win32 API requirement to Windows 2000 or higher

From 6f8e89194586aef75da5153975fa045dbad33a6c Mon Sep 17 00:00:00 2001
From: kidjan <kidjan@gmail.com>
Date: Mon, 1 Oct 2012 14:28:58 +0000
Subject: [PATCH 02/21] fix for issue 141, missing break statement.  thanks to
 pneumanlsd for the fix.

---
 util/mp4tags.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/util/mp4tags.cpp b/util/mp4tags.cpp
index 1b9e866..80e89d4 100644
--- a/util/mp4tags.cpp
+++ b/util/mp4tags.cpp
@@ -539,6 +539,7 @@ extern "C" int
                         else {
                             fprintf( stderr, "Art file %s not found\n", tags[i] );
                         }
+                        break;
                     }
                     case OPT_ALBUM_ARTIST:
                         MP4TagsSetAlbumArtist( mdata, tags[i] );

From a4163745881802fb77825498f702854cce0a8736 Mon Sep 17 00:00:00 2001
From: kidjan <kidjan@gmail.com>
Date: Sun, 18 Nov 2012 17:55:00 +0000
Subject: [PATCH 03/21] Fix for issue #149 = crash in mp4info.  Added some var
 initialization as well (do not like uninitialized pointers, even if the API
 purportedly guarantees to set it to NULL).  Something about
 MP4GetTrackmediaDataOriginalFormat seems odd, but some other day.

---
 src/mp4info.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/mp4info.cpp b/src/mp4info.cpp
index 44bf45e..676a5be 100644
--- a/src/mp4info.cpp
+++ b/src/mp4info.cpp
@@ -109,7 +109,7 @@ static char* PrintAudioInfo(
     const char* typeName = "Unknown";
     bool foundType = false;
     uint8_t type = 0;
-    const char *media_data_name;
+    const char *media_data_name = NULL;
 
     media_data_name = MP4GetTrackMediaDataName(mp4File, trackId);
 
@@ -306,7 +306,7 @@ static char* PrintVideoInfo(
     bool foundTypeName = false;
     const char* typeName = "Unknown";
 
-    const char *media_data_name;
+    const char *media_data_name = NULL;
     char originalFormat[8];
     char  oformatbuffer[32];
     originalFormat[0] = 0;
@@ -315,7 +315,7 @@ static char* PrintVideoInfo(
 
     media_data_name = MP4GetTrackMediaDataName(mp4File, trackId);
     // encv 264b
-    if (strcasecmp(media_data_name, "encv") == 0) {
+    if (media_data_name != NULL && strcasecmp(media_data_name, "encv") == 0) {
         if (MP4GetTrackMediaDataOriginalFormat(mp4File,
                                                trackId,
                                                originalFormat,

From 4c36a27551dd2f719019678a582465f8fe924aae Mon Sep 17 00:00:00 2001
From: kidjan <kidjan@gmail.com>
Date: Sun, 18 Nov 2012 18:27:46 +0000
Subject: [PATCH 04/21] Fix for issue #142 - off-by-one error on
 MP4File::ReadCountedString.

---
 src/mp4file_io.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/mp4file_io.cpp b/src/mp4file_io.cpp
index 5de2910..d16d87f 100644
--- a/src/mp4file_io.cpp
+++ b/src/mp4file_io.cpp
@@ -387,7 +387,7 @@ char* MP4File::ReadCountedString(uint8_t charSize, bool allowExpandedCount, uint
         charLength = ReadUInt8();
     }
     
-    if (fixedLength && (charLength > fixedLength)) {
+    if (fixedLength && (charLength > fixedLength - 1)) {
         /*
          * The counted length of this string is greater than the
          * maxiumum fixed length, so truncate the string to the
@@ -397,7 +397,7 @@ char* MP4File::ReadCountedString(uint8_t charSize, bool allowExpandedCount, uint
          * a non counted string has been used in the place of a
          * counted string).
          */  
-        WARNING(charLength > fixedLength);
+        WARNING(charLength > fixedLength - 1);
         charLength = fixedLength - 1U;
     }
 

From 75dd26550aae7749905741006896e51302632cce Mon Sep 17 00:00:00 2001
From: kidjan <kidjan@gmail.com>
Date: Fri, 28 Dec 2012 16:45:40 +0000
Subject: [PATCH 05/21] fix for issue 150; mp4v2 incorrectly reports track
 bitrate in the absence of the avgBitrate track property.  thanks to
 ktakata65536 for the patch.

---
 src/mp4.cpp | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/mp4.cpp b/src/mp4.cpp
index 3605298..d69b87e 100644
--- a/src/mp4.cpp
+++ b/src/mp4.cpp
@@ -2402,8 +2402,11 @@ MP4FileHandle MP4ReadProvider( const char* fileName, const MP4FileProvider* file
         if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
             MP4File *pFile = (MP4File *)hFile;
             try {
-                return pFile->GetTrackIntegerProperty(trackId,
+                uint32_t bitrate =  pFile->GetTrackIntegerProperty(trackId,
                                                       "mdia.minf.stbl.stsd.*.esds.decConfigDescr.avgBitrate");
+                if( bitrate != 0 ) {
+                    return bitrate;
+                }
             }
             catch( Exception* x ) {
                 //mp4v2::impl::log.errorf(*x);  we don't really need to print this.

From 54e00597e0e935470754bf33b0ffae93021e4f01 Mon Sep 17 00:00:00 2001
From: kidjan <kidjan@gmail.com>
Date: Mon, 13 May 2013 15:32:53 +0000
Subject: [PATCH 06/21] fix for issue 146: JPEG image type checking is too
 strict.  EXIF and JFIF are close enough that either should be recognized as a
 JPEG

---
 src/itmf/type.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/itmf/type.cpp b/src/itmf/type.cpp
index 44254f8..b85e429 100644
--- a/src/itmf/type.cpp
+++ b/src/itmf/type.cpp
@@ -284,7 +284,7 @@ namespace {
         { BT_BMP,  "\x42\x4d" },
         { BT_GIF,  "GIF87a" },
         { BT_GIF,  "GIF89a" },
-        { BT_JPEG, "\xff\xd8\xff\xe0" },
+        { BT_JPEG, "\xff\xd8\xff" },
         { BT_PNG,  "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a" },
         { BT_UNDEFINED } // must be last
     };

From 91b4e1b7691e89d36c1c060a4d4a5b04e020a7c5 Mon Sep 17 00:00:00 2001
From: kidjan <kidjan@gmail.com>
Date: Mon, 13 May 2013 22:00:14 +0000
Subject: [PATCH 07/21] fix a memory leak identified by static code analysis in
 mp4chaps.cpp; inBuf not free'd in the event of an error

---
 util/mp4chaps.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/util/mp4chaps.cpp b/util/mp4chaps.cpp
index 56aa484..98400f8 100644
--- a/util/mp4chaps.cpp
+++ b/util/mp4chaps.cpp
@@ -856,6 +856,7 @@ ChapterUtility::readChapterFile( const string filename, char** buffer, File::Siz
     if( in.read( inBuf, fileSize, nin ) )
     {
         in.close();
+        free(inBuf);
         return herrf( "reading chapter file '%s' failed: %s\n", filename.c_str(), sys::getLastErrorStr() );
     }
     in.close();

From eb93334b7c44585411a04e77ad4e5e83bfe0bb8f Mon Sep 17 00:00:00 2001
From: kidjan <kidjan@6e6572fa-98a6-11dd-ad9f-f77439c74b79>
Date: Fri, 16 Aug 2013 20:40:27 +0000
Subject: [PATCH 08/21] fix for issue 160 where newever versions of visual
 studio have stdint support; if on those new versions, use the defined support
 instead of redefining

---
 include/mp4v2/platform.h     | 4 ++--
 libplatform/platform_win32.h | 3 +++
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/include/mp4v2/platform.h b/include/mp4v2/platform.h
index d400edf..aea948a 100644
--- a/include/mp4v2/platform.h
+++ b/include/mp4v2/platform.h
@@ -9,9 +9,9 @@
 
 // Thanks, MSFT, for making C99 a total PITA.  Declare this not to define any stdint stuff; this is useful
 // if you're going to be using mp4v2 on windows with some other library that defines its own stdint.
-// TODO msft has finally re-included stdint in vs2010, so maybe at some point in the future this won't be needed.
+// The 1600 version check is for Visual Studio 2010 which has stdint once again.
 #ifndef MP4V2_NO_STDINT_DEFS
-    #if defined( _WIN32 ) && !defined( __MINGW32__ )
+    #if defined( _WIN32 ) && !defined( __MINGW32__ ) && !(defined(_MSC_VER) && _MSC_VER >= 1600)
         typedef char      int8_t;
         typedef short     int16_t;
         typedef int       int32_t;
diff --git a/libplatform/platform_win32.h b/libplatform/platform_win32.h
index 2be4952..28fe800 100644
--- a/libplatform/platform_win32.h
+++ b/libplatform/platform_win32.h
@@ -60,6 +60,8 @@ namespace mp4v2 { namespace platform {
 
 ///////////////////////////////////////////////////////////////////////////////
 
+// If using Visual Studio 2010 or newer these aren't needed since stdint.h is available.
+#if !(defined(_MSC_VER) && _MSC_VER >= 1600)
 // some macros for constant expressions
 #define INT8_C(x)    x
 #define INT16_C(x)   x
@@ -70,6 +72,7 @@ namespace mp4v2 { namespace platform {
 #define UINT16_C(x)  x
 #define UINT32_C(x)  x ## UL
 #define UINT64_C(x)  x ## ULL
+#endif
 
 ///////////////////////////////////////////////////////////////////////////////
 

From 9ff76b479e05aabe08327836bf586dcea6b49bed Mon Sep 17 00:00:00 2001
From: "Nicholas.Salerno" <Nicholas.Salerno@gmail.com>
Date: Thu, 16 Oct 2014 19:57:24 +0000
Subject: [PATCH 09/21] Fix for issue 174: new API function to free memory that
 was allocated by API function MP4GetTrackH264SeqPictHeadres().

---
 include/mp4v2/track_prop.h | 29 +++++++++++++++++++++++++++++
 src/mp4.cpp                | 20 ++++++++++++++++++++
 2 files changed, 49 insertions(+)

diff --git a/include/mp4v2/track_prop.h b/include/mp4v2/track_prop.h
index 37d7643..4b3adf4 100644
--- a/include/mp4v2/track_prop.h
+++ b/include/mp4v2/track_prop.h
@@ -214,6 +214,35 @@ bool MP4SetTrackESConfiguration(
     uint32_t       configSize );
 
 /* h264 information routines */
+
+/** Frees the memory allocated by MP4GetTrackH264SeqPictHeaders.
+ *
+ *  MP4FreeH264SeqPictHeaders frees the memory that was allocated by a
+ *  call to the MP4GetTrackH264SeqPictHeaders function.
+ *
+ *  When a client application wants to extract the H.264 video data from
+ *  an MP4 file it will call MP4GetTrackH264SeqPictHeaders to obtain the
+ *  sequence and picture parameter sets.  These parameter sets are
+ *  required for decoding a sequence of one, or more, coded slices.  When
+ *  the client application is done with the data it must free it.  On the
+ *  Windows platform this cannot be done directly by the client
+ *  application because the C runtime of the client application and the C
+ *  runtime of the mp4v2 DLL may be different, which will result in an
+ *  error at runtime.  This function allows the client application to let
+ *  the mp4v2 DLL free the memory with the appropriate CRT heap manager.
+ *
+ *  @param pSeqHeaders pointer to an array of SPS pointers.
+ *  @param pSeqHeaderSize pointer to array of SPS sizes.
+ *  @param pPictHeader pointer to an array of PPS pointers.
+ *  @param pPictHeaderSize pointer to array of PPS sizes.
+ */
+MP4V2_EXPORT
+void MP4FreeH264SeqPictHeaders(
+    uint8_t** pSeqHeaders,
+    uint32_t* pSeqHeaderSize,
+    uint8_t** pPictHeader,
+    uint32_t* pPictHeaderSize );
+
 MP4V2_EXPORT
 bool MP4GetTrackH264ProfileLevel(
     MP4FileHandle hFile,
diff --git a/src/mp4.cpp b/src/mp4.cpp
index d69b87e..d27ebfa 100644
--- a/src/mp4.cpp
+++ b/src/mp4.cpp
@@ -2535,6 +2535,26 @@ MP4FileHandle MP4ReadProvider( const char* fileName, const MP4FileProvider* file
         return false;
     }
 
+    void MP4FreeH264SeqPictHeaders(uint8_t** pSeqHeaders,
+                                   uint32_t* pSeqHeaderSize,
+                                   uint8_t** pPictHeader,
+                                   uint32_t* pPictHeaderSize )
+    {
+        uint32_t ix;
+
+        for (ix = 0; pSeqHeaderSize[ix] != 0; ++ix) {
+            free(pSeqHeaders[ix]);
+        }
+        free(pSeqHeaders);
+        free(pSeqHeaderSize);
+
+        for (ix = 0; pPictHeaderSize[ix] != 0; ++ix) {
+            free(pPictHeader[ix]);
+        }
+        free(pPictHeader);
+        free(pPictHeaderSize);
+    }
+
     bool MP4GetTrackH264SeqPictHeaders (MP4FileHandle hFile,
                                         MP4TrackId trackId,
                                         uint8_t ***pSeqHeader,

From 3d8f7c925662a229264f599b57a86d57c72a04fd Mon Sep 17 00:00:00 2001
From: "Nicholas.Salerno" <Nicholas.Salerno@gmail.com>
Date: Fri, 17 Oct 2014 22:03:13 +0000
Subject: [PATCH 10/21] Fix for issue 168: modifications to file provider so
 that client can supply memory buffers that behave like files.

---
 include/mp4v2/file.h          | 83 ++++++++++++++++++++++++++++++++---
 libplatform/io/File.cpp       | 18 +++++++-
 libplatform/io/File.h         | 14 ++++++
 libplatform/io/File_posix.cpp | 14 ++++++
 libplatform/io/File_win32.cpp | 21 +++++++++
 src/mp4.cpp                   | 32 ++++++++++++--
 src/mp4file.cpp               | 19 ++++----
 src/mp4file.h                 | 17 +++----
 8 files changed, 192 insertions(+), 26 deletions(-)

diff --git a/include/mp4v2/file.h b/include/mp4v2/file.h
index fc0c5ef..b2124d2 100644
--- a/include/mp4v2/file.h
+++ b/include/mp4v2/file.h
@@ -35,11 +35,12 @@ typedef enum MP4FileMode_e
  */
 typedef struct MP4FileProvider_s
 {
-    void* ( *open  )( const char* name, MP4FileMode mode );
-    int   ( *seek  )( void* handle, int64_t pos );
-    int   ( *read  )( void* handle, void* buffer, int64_t size, int64_t* nin, int64_t maxChunkSize );
-    int   ( *write )( void* handle, const void* buffer, int64_t size, int64_t* nout, int64_t maxChunkSize );
-    int   ( *close )( void* handle );
+    void* ( *open    )( const char* name, MP4FileMode mode );
+    int   ( *seek    )( void* handle, int64_t pos );
+    int   ( *read    )( void* handle, void* buffer, int64_t size, int64_t* nin, int64_t maxChunkSize );
+    int   ( *write   )( void* handle, const void* buffer, int64_t size, int64_t* nout, int64_t maxChunkSize );
+    int   ( *close   )( void* handle );
+    int   ( *getSize )( void* handle, int64_t* nout );
 } MP4FileProvider;
 
 /** Close an mp4 file.
@@ -121,6 +122,78 @@ MP4FileHandle MP4CreateEx(
     char**      compatibleBrands DEFAULT(0),
     uint32_t    compatibleBrandsCount DEFAULT(0) );
 
+/** Create a new mp4 file.
+ *
+ *  MP4CreateProvider is the first call that should be used when you want to
+ *  create a new, empty mp4 file. It is equivalent to opening a file for
+ *  writing, but also involved with creation of necessary mp4 framework
+ *  structures. ie. invoking MP4CreateProvider() followed by MP4Close() will
+ *  result in a file with a non-zero size.
+ *
+ *  @param fileName pathname of the file to be created.
+ *      On Windows, this should be a UTF-8 encoded string.
+ *      On other platforms, it should be an 8-bit encoding that is
+ *      appropriate for the platform, locale, file system, etc.
+ *      (prefer to use UTF-8 when possible).
+ *  @param flags bitmask that allows the user to set 64-bit values for
+ *      data or time atoms. Valid bits may be any combination of:
+ *          @li #MP4_CREATE_64BIT_DATA
+ *          @li #MP4_CREATE_64BIT_TIME
+ *  @param fileProvider custom implementation of file I/O operations.
+ *      All functions in structure must be implemented.
+ *      The structure is immediately copied internally.
+ *
+ *  @return On success a handle of the newly created file for use in
+ *      subsequent calls to the library.
+ *      On error, #MP4_INVALID_FILE_HANDLE.
+ */
+MP4V2_EXPORT
+MP4FileHandle MP4CreateProvider(
+    const char*            fileName,
+    uint32_t               flags DEFAULT(0),
+    const MP4FileProvider* fileProvider DEFAULT(NULL) );
+
+/** Create a new mp4 file with extended options.
+ *
+ *  MP4CreateProviderEx is an extended version of MP4CreateProvider().
+ *
+ *  @param fileName pathname of the file to be created.
+ *      On Windows, this should be a UTF-8 encoded string.
+ *      On other platforms, it should be an 8-bit encoding that is
+ *      appropriate for the platform, locale, file system, etc.
+ *      (prefer to use UTF-8 when possible).
+ *  @param flags bitmask that allows the user to set 64-bit values for
+ *      data or time atoms. Valid bits may be any combination of:
+ *          @li #MP4_CREATE_64BIT_DATA
+ *          @li #MP4_CREATE_64BIT_TIME
+ *  @param fileProvider custom implementation of file I/O operations.
+ *      All functions in structure must be implemented.
+ *      The structure is immediately copied internally.
+ *  @param add_ftyp if true an <b>ftyp</b> atom is automatically created.
+ *  @param add_iods if true an <b>iods</b> atom is automatically created.
+ *  @param majorBrand <b>ftyp</b> brand identifier.
+ *  @param minorVersion <b>ftyp</b> informative integer for the minor version
+ *      of the major brand.
+ *  @param compatibleBrands <b>ftyp</b> list of compatible brands.
+ *  @param compatibleBrandsCount is the count of items specified in
+ *      compatibleBrands.
+ *
+ *  @return On success a handle of the newly created file for use in
+ *      subsequent calls to the library.
+ *      On error, #MP4_INVALID_FILE_HANDLE.
+ */
+MP4V2_EXPORT
+MP4FileHandle MP4CreateProviderEx(
+    const char*            fileName,
+    uint32_t               flags DEFAULT(0),
+    const MP4FileProvider* fileProvider DEFAULT(NULL),
+    int                    add_ftyp DEFAULT(1),
+    int                    add_iods DEFAULT(1),
+    char*                  majorBrand DEFAULT(0),
+    uint32_t               minorVersion DEFAULT(0),
+    char**                 compatibleBrands DEFAULT(0),
+    uint32_t               compatibleBrandsCount DEFAULT(0) );
+
 /** Dump mp4 file contents as ASCII either to stdout or the
  *  log callback (@p see MP4SetLogCallback)
  *
diff --git a/libplatform/io/File.cpp b/libplatform/io/File.cpp
index 893f98c..2ea0e8d 100644
--- a/libplatform/io/File.cpp
+++ b/libplatform/io/File.cpp
@@ -63,7 +63,8 @@ File::open( std::string name_, Mode mode_ )
     if( _provider.open( _name, _mode ))
         return true;
 
-    FileSystem::getFileSize( _name, _size );
+    if( _provider.getSize( _size ))
+        return true;
 
     _isOpen = true;
     return false;
@@ -129,6 +130,15 @@ File::close()
     return false;
 }
 
+bool
+File::getSize( Size& nout )
+{
+    if( !_isOpen )
+        return false;
+
+    return _provider.getSize( nout );
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 CustomFileProvider::CustomFileProvider( const MP4FileProvider& provider )
@@ -180,6 +190,12 @@ CustomFileProvider::close()
     return _call.close( _handle );
 }
 
+bool
+CustomFileProvider::getSize( Size& nout )
+{
+    return _call.getSize( _handle, &nout );
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 }}} // namespace mp4v2::platform::io
diff --git a/libplatform/io/File.h b/libplatform/io/File.h
index 67bb2b6..bf8536c 100644
--- a/libplatform/io/File.h
+++ b/libplatform/io/File.h
@@ -30,6 +30,7 @@ class MP4V2_EXPORT FileProvider
     virtual bool read( void* buffer, Size size, Size& nin, Size maxChunkSize ) = 0;
     virtual bool write( const void* buffer, Size size, Size& nout, Size maxChunkSize ) = 0;
     virtual bool close() = 0;
+    virtual bool getSize( Size& nout ) = 0;
 
 protected:
     FileProvider() { }
@@ -163,6 +164,18 @@ class MP4V2_EXPORT File : public FileProvider
 
     bool write( const void* buffer, Size size, Size& nout, Size maxChunkSize = 0 );
 
+    ///////////////////////////////////////////////////////////////////////////
+    //!
+    //! Get size of file in bytes.
+    //!
+    //! @param nout output indicating the size of the file in bytes.
+    //!
+    //! @return true on failure, false on success.
+    //!
+    ///////////////////////////////////////////////////////////////////////////
+
+    bool getSize( Size& nout );
+
 private:
     std::string   _name;
     bool          _isOpen;
@@ -195,6 +208,7 @@ class CustomFileProvider : public FileProvider
     bool read( void* buffer, Size size, Size& nin, Size maxChunkSize );
     bool write( const void* buffer, Size size, Size& nout, Size maxChunkSize );
     bool close();
+    bool getSize( Size& nout );
 
 private:
     MP4FileProvider _call;
diff --git a/libplatform/io/File_posix.cpp b/libplatform/io/File_posix.cpp
index b6fb214..1c961ab 100644
--- a/libplatform/io/File_posix.cpp
+++ b/libplatform/io/File_posix.cpp
@@ -14,11 +14,13 @@ class StandardFileProvider : public FileProvider
     bool read( void* buffer, Size size, Size& nin, Size maxChunkSize );
     bool write( const void* buffer, Size size, Size& nout, Size maxChunkSize );
     bool close();
+    bool getSize( Size& nout );
 
 private:
     bool         _seekg;
     bool         _seekp;
     std::fstream _fstream;
+    std::string  _name;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -56,6 +58,7 @@ StandardFileProvider::open( std::string name, Mode mode )
     }
 
     _fstream.open( name.c_str(), om );
+    _name = name;
     return _fstream.fail();
 }
 
@@ -96,6 +99,17 @@ StandardFileProvider::close()
     return _fstream.fail();
 }
 
+bool
+StandardFileProvider::getSize( Size& nout )
+{
+    bool retval;
+
+    // getFileSize will log if it fails
+    retval = FileSystem::getFileSize( _name, nout );
+
+    return retval;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 FileProvider&
diff --git a/libplatform/io/File_win32.cpp b/libplatform/io/File_win32.cpp
index d9101ea..e8e259c 100644
--- a/libplatform/io/File_win32.cpp
+++ b/libplatform/io/File_win32.cpp
@@ -37,6 +37,7 @@ class StandardFileProvider : public FileProvider
     bool read( void* buffer, Size size, Size& nin, Size maxChunkSize );
     bool write( const void* buffer, Size size, Size& nout, Size maxChunkSize );
     bool close();
+    bool getSize( Size& nout );
 
 private:
     HANDLE _handle;
@@ -245,6 +246,26 @@ StandardFileProvider::close()
     return !retval;
 }
 
+/**
+ * Get the size of a the file in bytes
+ *
+ * @param nout populated with the size of the file in
+ * bytes if the function succeeds
+ *
+ * @retval false successfully got the file size
+ * @retval true error getting the file size
+ */
+bool
+StandardFileProvider::getSize( Size& nout )
+{
+    BOOL retval;
+
+    // getFileSize will log if it fails
+    retval = FileSystem::getFileSize( _name, nout );
+
+    return retval;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 FileProvider&
diff --git a/src/mp4.cpp b/src/mp4.cpp
index d27ebfa..1016f79 100644
--- a/src/mp4.cpp
+++ b/src/mp4.cpp
@@ -146,9 +146,9 @@ MP4FileHandle MP4ReadProvider( const char* fileName, const MP4FileProvider* file
 ///////////////////////////////////////////////////////////////////////////////
 
     MP4FileHandle MP4Create (const char* fileName,
-                             uint32_t  flags)
+                             uint32_t flags)
     {
-        return MP4CreateEx(fileName, flags);
+        return MP4CreateProviderEx(fileName, flags);
     }
 
     MP4FileHandle MP4CreateEx (const char* fileName,
@@ -159,6 +159,29 @@ MP4FileHandle MP4ReadProvider( const char* fileName, const MP4FileProvider* file
                                uint32_t minorVersion,
                                char** supportedBrands,
                                uint32_t supportedBrandsCount)
+    {
+        return MP4CreateProviderEx(fileName, flags, NULL,
+                                   add_ftyp, add_iods,
+                                   majorBrand, minorVersion,
+                                   supportedBrands, supportedBrandsCount);
+    }
+
+    MP4FileHandle MP4CreateProvider (const char* fileName,
+                                     uint32_t flags,
+                                     const MP4FileProvider* fileProvider)
+    {
+        return MP4CreateProviderEx(fileName, flags, fileProvider);
+    }
+
+    MP4FileHandle MP4CreateProviderEx (const char* fileName,
+                                       uint32_t flags,
+                                       const MP4FileProvider* fileProvider,
+                                       int add_ftyp,
+                                       int add_iods,
+                                       char* majorBrand,
+                                       uint32_t minorVersion,
+                                       char** supportedBrands,
+                                       uint32_t supportedBrandsCount)
     {
         if (!fileName)
             return MP4_INVALID_FILE_HANDLE;
@@ -170,7 +193,8 @@ MP4FileHandle MP4ReadProvider( const char* fileName, const MP4FileProvider* file
         try {
             ASSERT(pFile);
             // LATER useExtensibleFormat, moov first, then mvex's
-            pFile->Create(fileName, flags, add_ftyp, add_iods,
+            pFile->Create(fileName, flags, fileProvider,
+                          add_ftyp, add_iods,
                           majorBrand, minorVersion,
                           supportedBrands, supportedBrandsCount);
             return (MP4FileHandle)pFile;
@@ -189,6 +213,8 @@ MP4FileHandle MP4ReadProvider( const char* fileName, const MP4FileProvider* file
         return MP4_INVALID_FILE_HANDLE;
     }
 
+///////////////////////////////////////////////////////////////////////////////
+
     MP4FileHandle MP4Modify(const char* fileName,
                             uint32_t flags)
     {
diff --git a/src/mp4file.cpp b/src/mp4file.cpp
index 25e241f..86f386b 100644
--- a/src/mp4file.cpp
+++ b/src/mp4file.cpp
@@ -97,17 +97,18 @@ void MP4File::Read( const char* name, const MP4FileProvider* provider )
     CacheProperties();
 }
 
-void MP4File::Create( const char* fileName,
-                      uint32_t    flags,
-                      int         add_ftyp,
-                      int         add_iods,
-                      char*       majorBrand,
-                      uint32_t    minorVersion,
-                      char**      supportedBrands,
-                      uint32_t    supportedBrandsCount )
+void MP4File::Create( const char*            fileName,
+                      uint32_t               flags,
+                      const MP4FileProvider* provider,
+                      int                    add_ftyp,
+                      int                    add_iods,
+                      char*                  majorBrand,
+                      uint32_t               minorVersion,
+                      char**                 supportedBrands,
+                      uint32_t               supportedBrandsCount )
 {
     m_createFlags = flags;
-    Open( fileName, File::MODE_CREATE, NULL );
+    Open( fileName, File::MODE_CREATE, provider );
 
     // generate a skeletal atom tree
     m_pRootAtom = MP4Atom::CreateAtom(*this, NULL, NULL);
diff --git a/src/mp4file.h b/src/mp4file.h
index 813f90f..960505e 100644
--- a/src/mp4file.h
+++ b/src/mp4file.h
@@ -74,14 +74,15 @@ class MP4File
     // file ops
     ///////////////////////////////////////////////////////////////////////////
 
-    void Create( const char* fileName,
-                 uint32_t    flags,
-                 int         add_ftyp = 1,
-                 int         add_iods = 1,
-                 char*       majorBrand = NULL,
-                 uint32_t    minorVersion = 0,
-                 char**      supportedBrands = NULL,
-                 uint32_t    supportedBrandsCount = 0 );
+    void Create( const char*            fileName,
+                 uint32_t               flags,
+                 const MP4FileProvider* provider = NULL,
+                 int                    add_ftyp = 1,
+                 int                    add_iods = 1,
+                 char*                  majorBrand = NULL,
+                 uint32_t               minorVersion = 0,
+                 char**                 supportedBrands = NULL,
+                 uint32_t               supportedBrandsCount = 0 );
 
     const std::string &GetFilename() const;
     void Read( const char* name, const MP4FileProvider* provider );

From cc17ffe84c08f26011e4a2867f6196e62c4258ee Mon Sep 17 00:00:00 2001
From: "Nicholas.Salerno" <Nicholas.Salerno@gmail.com>
Date: Mon, 5 Jan 2015 22:05:43 +0000
Subject: [PATCH 11/21] Fix for r506 commit.

This bug only affects the Windows build.  The patch from revision 506 (addition of file size to file provider API) does not work with absolute path names.  The standard file provider normalizes its UTF-8 path name.  Prior to the r506 patch the platform file class called FileSystem::getFileSize with the argument from the caller.  After the r506 patch the platform class calls the file provider to get the file size.  The standard file provider uses its normalized path name as an argument to FileSystem::getFileSize.  This was a problem if the path was absolute because the normalization added a UNC prefix, which getFileSize does not like.  The standard file provider now passes the original path value that was supplied by the caller.
---
 libplatform/io/File_win32.cpp | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/libplatform/io/File_win32.cpp b/libplatform/io/File_win32.cpp
index e8e259c..0b3ebe8 100644
--- a/libplatform/io/File_win32.cpp
+++ b/libplatform/io/File_win32.cpp
@@ -46,6 +46,11 @@ class StandardFileProvider : public FileProvider
      * The UTF-8 encoded file name
      */
     std::string _name;
+
+    /**
+     * Argument for FileSystem::getFileSize()
+     */
+    std::string _orig_name;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -67,6 +72,8 @@ StandardFileProvider::StandardFileProvider()
 bool
 StandardFileProvider::open( std::string name, Mode mode )
 {
+    _orig_name = name;
+
     DWORD access = 0;
     DWORD share  = 0;
     DWORD crdisp = 0;
@@ -261,7 +268,8 @@ StandardFileProvider::getSize( Size& nout )
     BOOL retval;
 
     // getFileSize will log if it fails
-    retval = FileSystem::getFileSize( _name, nout );
+    // (cannot use _name because it may have UNC prefix)
+    retval = FileSystem::getFileSize( _orig_name, nout );
 
     return retval;
 }

From 60e346211e53257d2fd0b39d4b89ce60c9053409 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9rgio=20M=2E=20Basto?= <sergio@serjux.com>
Date: Wed, 7 Oct 2015 03:59:59 +0100
Subject: [PATCH 12/21] Fix make dist.

Makes fail because make doc fails .
for more information please see :
https://github.com/sergiomb2/libmp4v2/issues/177
---
 configure.ac                          |  1 +
 doc/GNUmakefile.mk                    |  2 +-
 doc/texi/Authors.texi                 |  2 +-
 doc/texi/BuildRepository.texi         | 14 +++++++-------
 doc/texi/BuildSource.texi             | 10 +++++-----
 doc/texi/Documentation.texi           |  2 +-
 doc/texi/ReleaseNotes.texi            |  2 +-
 doc/texi/ToolGuide.texi               |  2 +-
 doc/texi/build/commands.texi          | 14 +++++++-------
 doc/texi/build/process.bootstrap.texi |  2 +-
 doc/texi/build/process.build.texi     |  2 +-
 doc/texi/build/process.checkout.texi  |  2 +-
 doc/texi/build/process.configure.texi |  2 +-
 doc/texi/build/process.dist.texi      |  2 +-
 doc/texi/build/process.extract.texi   |  2 +-
 doc/texi/build/process.install.texi   |  2 +-
 16 files changed, 32 insertions(+), 31 deletions(-)

diff --git a/configure.ac b/configure.ac
index 83e9dce..8316c67 100644
--- a/configure.ac
+++ b/configure.ac
@@ -35,6 +35,7 @@ AC_MSG_NOTICE([
   -->])
 
 AC_CONFIG_AUX_DIR([autoaux])
+AC_CONFIG_MACRO_DIR([m4])
 AM_INIT_AUTOMAKE([1.9.6 foreign -Wall -Wno-portability -Werror subdir-objects nostdinc no-dist-gzip dist-bzip2 dist-zip dejagnu])
 
 AC_CONFIG_SRCDIR([src/mp4.cpp])
diff --git a/doc/GNUmakefile.mk b/doc/GNUmakefile.mk
index 131b03f..dadb234 100644
--- a/doc/GNUmakefile.mk
+++ b/doc/GNUmakefile.mk
@@ -384,4 +384,4 @@ clean-local:
 ###############################################################################
 
 $(sort $(MKDIRS)):
-	$(mkdir_p) $@
+	$(mkdir_p) $(sort $(MKDIRS))
diff --git a/doc/texi/Authors.texi b/doc/texi/Authors.texi
index 9ec4920..74f2cb8 100644
--- a/doc/texi/Authors.texi
+++ b/doc/texi/Authors.texi
@@ -1,4 +1,4 @@
-@input texinfo @c -*- Texinfo -*-
+\input texinfo @c -*- Texinfo -*-
 @c %**start of header
 @setfilename Authors.info
 @include base/article.texi
diff --git a/doc/texi/BuildRepository.texi b/doc/texi/BuildRepository.texi
index dcae56e..f784d69 100644
--- a/doc/texi/BuildRepository.texi
+++ b/doc/texi/BuildRepository.texi
@@ -1,4 +1,4 @@
-@input texinfo @c -*- Texinfo -*-
+\input texinfo @c -*- Texinfo -*-
 @c %**start of header
 @setfilename BuildRepository.info
 @include base/article.texi
@@ -19,12 +19,12 @@ This document describes the recommended process to build @value{PROJECT.name} fr
 This chapter is for the impatient or those just looking for a quick summary of all the commands used in a typical build. You may skip this summary and jump to @ref{Build Process}.
 
 @example
-@COMMAND.checkout{}
-@COMMAND.bootstrap{}
-@COMMAND.configure{}
-@COMMAND.build{}
-@COMMAND.install{}
-@COMMAND.dist{}
+@COMMANDcheckout{}
+@COMMANDbootstrap{}
+@COMMANDconfigure{}
+@COMMANDbuild{}
+@COMMANDinstall{}
+@COMMANDdist{}
 @end example
 
 @anchor{Build Process}
diff --git a/doc/texi/BuildSource.texi b/doc/texi/BuildSource.texi
index 233ecdb..853dd30 100644
--- a/doc/texi/BuildSource.texi
+++ b/doc/texi/BuildSource.texi
@@ -1,4 +1,4 @@
-@input texinfo @c -*- Texinfo -*-
+\input texinfo @c -*- Texinfo -*-
 @c %**start of header
 @setfilename BuildSource.info
 @include base/article.texi
@@ -19,10 +19,10 @@ This document describes the recommended process to build @value{PROJECT.name} fr
 This chapter is for the impatient or those just looking for a quick summary of all the commands used in a typical build. You may skip this summary and jump to @ref{Build Process}.
 
 @example
-@COMMAND.extract{}
-@COMMAND.configure{}
-@COMMAND.build{}
-@COMMAND.install{}
+@COMMANDextract{}
+@COMMANDconfigure{}
+@COMMANDbuild{}
+@COMMANDinstall{}
 @end example
 
 @anchor{Build Process}
diff --git a/doc/texi/Documentation.texi b/doc/texi/Documentation.texi
index 7b85fa1..15554aa 100644
--- a/doc/texi/Documentation.texi
+++ b/doc/texi/Documentation.texi
@@ -1,4 +1,4 @@
-@input texinfo @c -*- Texinfo -*-
+\input texinfo @c -*- Texinfo -*-
 @c %**start of header
 @setfilename Documentation.info
 @include base/article.texi
diff --git a/doc/texi/ReleaseNotes.texi b/doc/texi/ReleaseNotes.texi
index 2e3d189..ac276a4 100644
--- a/doc/texi/ReleaseNotes.texi
+++ b/doc/texi/ReleaseNotes.texi
@@ -1,4 +1,4 @@
-@input texinfo @c -*- Texinfo -*-
+\input texinfo @c -*- Texinfo -*-
 @c %**start of header
 @setfilename ReleaseNotes.info
 @include base/article.texi
diff --git a/doc/texi/ToolGuide.texi b/doc/texi/ToolGuide.texi
index a951f26..7b3398a 100644
--- a/doc/texi/ToolGuide.texi
+++ b/doc/texi/ToolGuide.texi
@@ -1,4 +1,4 @@
-@input texinfo @c -*- Texinfo -*-
+\input texinfo @c -*- Texinfo -*-
 @c %**start of header
 @setfilename ToolGuide.info
 @include base/guide.texi
diff --git a/doc/texi/build/commands.texi b/doc/texi/build/commands.texi
index 8ef9ec9..79e42f7 100644
--- a/doc/texi/build/commands.texi
+++ b/doc/texi/build/commands.texi
@@ -1,33 +1,33 @@
-@macro COMMAND.checkout{}
+@macro COMMANDcheckout{}
 svn checkout @value{PROJECT.repo.url} @value{PROJECT.name.lower}
 cd @value{PROJECT.name.lower}
 @end macro
 
-@macro COMMAND.bootstrap{}
+@macro COMMANDbootstrap{}
 autoreconf -fiv
 @end macro
 
-@macro COMMAND.extract{}
+@macro COMMANDextract{}
 tar xf @value{PROJECT.name.lower}-@value{PROJECT.version}.tar.bz2
 cd @value{PROJECT.name.lower}-@value{PROJECT.version}/
 @end macro
 
-@macro COMMAND.configure{}
+@macro COMMANDconfigure{}
 rm -fr build/
 mkdir build/
 cd build/
 ../configure 
 @end macro
 
-@macro COMMAND.build{}
+@macro COMMANDbuild{}
 make
 @end macro
 
-@macro COMMAND.install{}
+@macro COMMANDinstall{}
 make install
 make install-man
 @end macro
 
-@macro COMMAND.dist{}
+@macro COMMANDdist{}
 make dist
 @end macro
diff --git a/doc/texi/build/process.bootstrap.texi b/doc/texi/build/process.bootstrap.texi
index f8153e9..cb538ac 100644
--- a/doc/texi/build/process.bootstrap.texi
+++ b/doc/texi/build/process.bootstrap.texi
@@ -3,7 +3,7 @@
 The following command causes forces Autotools to regenerate all files and install helper scripts needed at configure-time and to regenerate all files.
 
 @example
-@COMMAND.bootstrap{}
+@COMMANDbootstrap{}
 @end example
 
 If you are a project member and preparing for a release, it is important to note that the versions of Autotools available in your path will directly effect files added to the bundle. At the time of writing, the following versions of Autotools are recommended; in some cases a minimum is hard-coded and warnings will be issued if in violation:
diff --git a/doc/texi/build/process.build.texi b/doc/texi/build/process.build.texi
index 5e9d7a8..cb178df 100644
--- a/doc/texi/build/process.build.texi
+++ b/doc/texi/build/process.build.texi
@@ -3,7 +3,7 @@
 The following command will build @value{PROJECT.name}.
 
 @example
-@COMMAND.build{}
+@COMMANDbuild{}
 @end example
 
 On some platforms @code{make} refers to a BSD-flavor of make which is not compatible with this project. Check if @code{gmake} is installed, and if it is, substitute @code{gmake} wherever you may see @code{make} in this document. Otherwise you will need to install GNU make package version 3.81 or higher. Lower versions might work.
diff --git a/doc/texi/build/process.checkout.texi b/doc/texi/build/process.checkout.texi
index 5bf371a..550fd0f 100644
--- a/doc/texi/build/process.checkout.texi
+++ b/doc/texi/build/process.checkout.texi
@@ -7,7 +7,7 @@ Sources are checked out from either the trunk, release or a branch. This documen
 If you are a project member, then you may add the appropriate login/password information as needed.
 
 @example
-@COMMAND.checkout{}
+@COMMANDcheckout{}
 @end example
 
 It is recommended to use Subversion 1.5.0 or higher.
diff --git a/doc/texi/build/process.configure.texi b/doc/texi/build/process.configure.texi
index 19f427d..6750681 100644
--- a/doc/texi/build/process.configure.texi
+++ b/doc/texi/build/process.configure.texi
@@ -3,7 +3,7 @@
 The following command configures the project for a build.  It is highly recommended that you invoke configure from an empty directory.
 
 @example
-@COMMAND.configure{}
+@COMMANDconfigure{}
 @end example
 
 Please see @file{INSTALL} for details on configure usage, and standard options. Additionally, the following custom options have been added to @file{configure}:
diff --git a/doc/texi/build/process.dist.texi b/doc/texi/build/process.dist.texi
index 2d8b10b..a9d835b 100644
--- a/doc/texi/build/process.dist.texi
+++ b/doc/texi/build/process.dist.texi
@@ -3,7 +3,7 @@
 The following command will create a @value{PROJECT.name} source distribution. It is during this step that shipped documentation is generated.
 
 @example
-@COMMAND.dist{}
+@COMMANDdist{}
 @end example
 
 This step in the build process introduces additional requirements to the host system. While most of the following utilities are generally available, @command{help2man} is used to generate man-pages; however if this command is not available the man-pages will be empty. This is acceptable for non-release builds but for full quality builds this command is required.
diff --git a/doc/texi/build/process.extract.texi b/doc/texi/build/process.extract.texi
index b019cac..efad39e 100644
--- a/doc/texi/build/process.extract.texi
+++ b/doc/texi/build/process.extract.texi
@@ -2,7 +2,7 @@
 Extract sources from a @value{TERM.srcdist} bundle. Releases are available from @url{@value{PROJECT.url.website}} in the @url{@value{PROJECT.url.downloads},downloads} section.
 
 @example
-@COMMAND.extract{}
+@COMMANDextract{}
 @end example
 
 Older versions of @code{tar} may not automatically uncompress the bundle, so you might have to either enter additional flags manually, or first decompress the bundle before extracting. Some possible command variations for uncompressing a @file{bz2} file:
diff --git a/doc/texi/build/process.install.texi b/doc/texi/build/process.install.texi
index 9087853..e3b27dd 100644
--- a/doc/texi/build/process.install.texi
+++ b/doc/texi/build/process.install.texi
@@ -4,5 +4,5 @@
 The following command will install @value{PROJECT.name}.
 
 @example
-@COMMAND.install{}
+@COMMANDinstall{}
 @end example

From fc65e21b1fe12cb3d51a8bc8152efbebedabbd6f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9rgio=20M=2E=20Basto?= <sergio@serjux.com>
Date: Wed, 7 Oct 2015 04:25:20 +0100
Subject: [PATCH 13/21] Install man/man3/, BTW like in libmp4v2-1.5.0.1

And fix 30 annoying warnings "target x given more than once in the same
rule"
---
 GNUmakefile.am     | 73 ++++++++++++++++++++++++++++++++++++++++++++++
 doc/GNUmakefile.mk |  2 +-
 2 files changed, 74 insertions(+), 1 deletion(-)

diff --git a/GNUmakefile.am b/GNUmakefile.am
index 947e6e3..ea45d75 100644
--- a/GNUmakefile.am
+++ b/GNUmakefile.am
@@ -296,6 +296,79 @@ if ADD_MANS
         doc/man/man1/mp4file.1      \
         doc/man/man1/mp4subtitle.1  \
         doc/man/man1/mp4track.1
+    man3_MANS = \
+		doc/MP4.3 \
+		doc/MP4AddRtpESConfigurationPacket.3 \
+		doc/MP4AddRtpHint.3 \
+		doc/MP4AddRtpImmediateData.3 \
+		doc/MP4AddRtpPacket.3 \
+		doc/MP4AddRtpSampleData.3 \
+		doc/MP4AddRtpVideoHint.3 \
+		doc/MP4AddTrackEdit.3 \
+		doc/MP4AppendHintTrackSdp.3 \
+		doc/MP4AppendSessionSdp.3 \
+		doc/MP4BinaryToBase16.3 \
+		doc/MP4BinaryToBase64.3 \
+		doc/MP4CloneTrack.3 \
+		doc/MP4ConvertFromMovieDuration.3 \
+		doc/MP4ConvertFromTrackTimestamp.3 \
+		doc/MP4ConvertToTrackTimestamp.3 \
+		doc/MP4CopyTrack.3 \
+		doc/MP4DeleteTrack.3 \
+		doc/MP4DeleteTrackEdit.3 \
+		doc/MP4FindTrackId.3 \
+		doc/MP4FindTrackIndex.3 \
+		doc/MP4GetAudioProfileLevel.3 \
+		doc/MP4GetDuration.3 \
+		doc/MP4GetGraphicsProfileLevel.3 \
+		doc/MP4GetHintTrackReferenceTrackId.3 \
+		doc/MP4GetHintTrackRtpPayload.3 \
+		doc/MP4GetHintTrackSdp.3 \
+		doc/MP4GetNumberOfTracks.3 \
+		doc/MP4GetODProfileLevel.3 \
+		doc/MP4GetRtpHintNumberOfPackets.3 \
+		doc/MP4GetRtpPacketBFrame.3 \
+		doc/MP4GetRtpPacketTransmitOffset.3 \
+		doc/MP4GetRtpTimestampStart.3 \
+		doc/MP4GetSampleIdFromEditTime.3 \
+		doc/MP4GetSceneProfileLevel.3 \
+		doc/MP4GetSessionSdp.3 \
+		doc/MP4GetTrackAudioMpeg4Type.3 \
+		doc/MP4GetTrackAudioType.3 \
+		doc/MP4GetTrackBitRate.3 \
+		doc/MP4GetTrackDuration.3 \
+		doc/MP4GetTrackEditDuration.3 \
+		doc/MP4GetTrackEditDwell.3 \
+		doc/MP4GetTrackEditMediaStart.3 \
+		doc/MP4GetTrackEditStart.3 \
+		doc/MP4GetTrackEditTotalDuration.3 \
+		doc/MP4GetTrackESConfiguration.3 \
+		doc/MP4GetTrackFixedSampleDuration.3 \
+		doc/MP4GetTrackNumberOfEdits.3 \
+		doc/MP4GetTrackNumberOfSamples.3 \
+		doc/MP4GetTrackVideoFrameRate.3 \
+		doc/MP4GetTrackVideoHeight.3 \
+		doc/MP4GetTrackVideoType.3 \
+		doc/MP4GetTrackVideoWidth.3 \
+		doc/MP4GetVideoProfileLevel.3 \
+		doc/MP4MakeIsmaCompliant.3 \
+		doc/MP4ReadRtpHint.3 \
+		doc/MP4ReadRtpPacket.3 \
+		doc/MP4ReadSampleFromEditTime.3 \
+		doc/MP4SetAudioProfileLevel.3 \
+		doc/MP4SetGraphicsProfileLevel.3 \
+		doc/MP4SetHintTrackRtpPayload.3 \
+		doc/MP4SetHintTrackSdp.3 \
+		doc/MP4SetODProfileLevel.3 \
+		doc/MP4SetRtpTimestampStart.3 \
+		doc/MP4SetSceneProfileLevel.3 \
+		doc/MP4SetSessionSdp.3 \
+		doc/MP4SetTrackEditDuration.3 \
+		doc/MP4SetTrackEditDwell.3 \
+		doc/MP4SetTrackEditMediaStart.3 \
+		doc/MP4SetTrackESConfiguration.3 \
+		doc/MP4SetVideoProfileLevel.3 \
+		doc/MP4WriteRtpHint.3
 endif
 endif
 
diff --git a/doc/GNUmakefile.mk b/doc/GNUmakefile.mk
index dadb234..1e6188e 100644
--- a/doc/GNUmakefile.mk
+++ b/doc/GNUmakefile.mk
@@ -98,7 +98,7 @@ DOC.m4.out = \
 DOC.man.utils = mp4art mp4file mp4subtitle mp4track
 DOC.man.out   = $(DOC.man.utils:%=$(DOC.out/)man/man1/%.1)
 
-DOC.texi.articles = $(wildcard $(DOC.in/)texi/*.texi $(DOC.out/)texi/*.texi)
+DOC.texi.articles = $(wildcard $(DOC.in/)texi/*.texi)
 
 DOC.texi.includes = \
     doc/texi/base/project.texi \

From d7de4350e9fb40c296798f2d0b5197aa760dd417 Mon Sep 17 00:00:00 2001
From: Sam Thursfield <ssssam@gmail.com>
Date: Mon, 6 Feb 2017 06:23:19 +0100
Subject: [PATCH 14/21] Fix out-of-tree builds (#182)

Building with srcdir!=builddir was failing with a "no rule to create
doc/MP4.3" error.
---
 GNUmakefile.am | 144 ++++++++++++++++++++++++-------------------------
 1 file changed, 72 insertions(+), 72 deletions(-)

diff --git a/GNUmakefile.am b/GNUmakefile.am
index ea45d75..4b30ee6 100644
--- a/GNUmakefile.am
+++ b/GNUmakefile.am
@@ -297,78 +297,78 @@ if ADD_MANS
         doc/man/man1/mp4subtitle.1  \
         doc/man/man1/mp4track.1
     man3_MANS = \
-		doc/MP4.3 \
-		doc/MP4AddRtpESConfigurationPacket.3 \
-		doc/MP4AddRtpHint.3 \
-		doc/MP4AddRtpImmediateData.3 \
-		doc/MP4AddRtpPacket.3 \
-		doc/MP4AddRtpSampleData.3 \
-		doc/MP4AddRtpVideoHint.3 \
-		doc/MP4AddTrackEdit.3 \
-		doc/MP4AppendHintTrackSdp.3 \
-		doc/MP4AppendSessionSdp.3 \
-		doc/MP4BinaryToBase16.3 \
-		doc/MP4BinaryToBase64.3 \
-		doc/MP4CloneTrack.3 \
-		doc/MP4ConvertFromMovieDuration.3 \
-		doc/MP4ConvertFromTrackTimestamp.3 \
-		doc/MP4ConvertToTrackTimestamp.3 \
-		doc/MP4CopyTrack.3 \
-		doc/MP4DeleteTrack.3 \
-		doc/MP4DeleteTrackEdit.3 \
-		doc/MP4FindTrackId.3 \
-		doc/MP4FindTrackIndex.3 \
-		doc/MP4GetAudioProfileLevel.3 \
-		doc/MP4GetDuration.3 \
-		doc/MP4GetGraphicsProfileLevel.3 \
-		doc/MP4GetHintTrackReferenceTrackId.3 \
-		doc/MP4GetHintTrackRtpPayload.3 \
-		doc/MP4GetHintTrackSdp.3 \
-		doc/MP4GetNumberOfTracks.3 \
-		doc/MP4GetODProfileLevel.3 \
-		doc/MP4GetRtpHintNumberOfPackets.3 \
-		doc/MP4GetRtpPacketBFrame.3 \
-		doc/MP4GetRtpPacketTransmitOffset.3 \
-		doc/MP4GetRtpTimestampStart.3 \
-		doc/MP4GetSampleIdFromEditTime.3 \
-		doc/MP4GetSceneProfileLevel.3 \
-		doc/MP4GetSessionSdp.3 \
-		doc/MP4GetTrackAudioMpeg4Type.3 \
-		doc/MP4GetTrackAudioType.3 \
-		doc/MP4GetTrackBitRate.3 \
-		doc/MP4GetTrackDuration.3 \
-		doc/MP4GetTrackEditDuration.3 \
-		doc/MP4GetTrackEditDwell.3 \
-		doc/MP4GetTrackEditMediaStart.3 \
-		doc/MP4GetTrackEditStart.3 \
-		doc/MP4GetTrackEditTotalDuration.3 \
-		doc/MP4GetTrackESConfiguration.3 \
-		doc/MP4GetTrackFixedSampleDuration.3 \
-		doc/MP4GetTrackNumberOfEdits.3 \
-		doc/MP4GetTrackNumberOfSamples.3 \
-		doc/MP4GetTrackVideoFrameRate.3 \
-		doc/MP4GetTrackVideoHeight.3 \
-		doc/MP4GetTrackVideoType.3 \
-		doc/MP4GetTrackVideoWidth.3 \
-		doc/MP4GetVideoProfileLevel.3 \
-		doc/MP4MakeIsmaCompliant.3 \
-		doc/MP4ReadRtpHint.3 \
-		doc/MP4ReadRtpPacket.3 \
-		doc/MP4ReadSampleFromEditTime.3 \
-		doc/MP4SetAudioProfileLevel.3 \
-		doc/MP4SetGraphicsProfileLevel.3 \
-		doc/MP4SetHintTrackRtpPayload.3 \
-		doc/MP4SetHintTrackSdp.3 \
-		doc/MP4SetODProfileLevel.3 \
-		doc/MP4SetRtpTimestampStart.3 \
-		doc/MP4SetSceneProfileLevel.3 \
-		doc/MP4SetSessionSdp.3 \
-		doc/MP4SetTrackEditDuration.3 \
-		doc/MP4SetTrackEditDwell.3 \
-		doc/MP4SetTrackEditMediaStart.3 \
-		doc/MP4SetTrackESConfiguration.3 \
-		doc/MP4SetVideoProfileLevel.3 \
-		doc/MP4WriteRtpHint.3
+		$(top_srcdir)/doc/MP4.3 \
+		$(top_srcdir)/doc/MP4AddRtpESConfigurationPacket.3 \
+		$(top_srcdir)/doc/MP4AddRtpHint.3 \
+		$(top_srcdir)/doc/MP4AddRtpImmediateData.3 \
+		$(top_srcdir)/doc/MP4AddRtpPacket.3 \
+		$(top_srcdir)/doc/MP4AddRtpSampleData.3 \
+		$(top_srcdir)/doc/MP4AddRtpVideoHint.3 \
+		$(top_srcdir)/doc/MP4AddTrackEdit.3 \
+		$(top_srcdir)/doc/MP4AppendHintTrackSdp.3 \
+		$(top_srcdir)/doc/MP4AppendSessionSdp.3 \
+		$(top_srcdir)/doc/MP4BinaryToBase16.3 \
+		$(top_srcdir)/doc/MP4BinaryToBase64.3 \
+		$(top_srcdir)/doc/MP4CloneTrack.3 \
+		$(top_srcdir)/doc/MP4ConvertFromMovieDuration.3 \
+		$(top_srcdir)/doc/MP4ConvertFromTrackTimestamp.3 \
+		$(top_srcdir)/doc/MP4ConvertToTrackTimestamp.3 \
+		$(top_srcdir)/doc/MP4CopyTrack.3 \
+		$(top_srcdir)/doc/MP4DeleteTrack.3 \
+		$(top_srcdir)/doc/MP4DeleteTrackEdit.3 \
+		$(top_srcdir)/doc/MP4FindTrackId.3 \
+		$(top_srcdir)/doc/MP4FindTrackIndex.3 \
+		$(top_srcdir)/doc/MP4GetAudioProfileLevel.3 \
+		$(top_srcdir)/doc/MP4GetDuration.3 \
+		$(top_srcdir)/doc/MP4GetGraphicsProfileLevel.3 \
+		$(top_srcdir)/doc/MP4GetHintTrackReferenceTrackId.3 \
+		$(top_srcdir)/doc/MP4GetHintTrackRtpPayload.3 \
+		$(top_srcdir)/doc/MP4GetHintTrackSdp.3 \
+		$(top_srcdir)/doc/MP4GetNumberOfTracks.3 \
+		$(top_srcdir)/doc/MP4GetODProfileLevel.3 \
+		$(top_srcdir)/doc/MP4GetRtpHintNumberOfPackets.3 \
+		$(top_srcdir)/doc/MP4GetRtpPacketBFrame.3 \
+		$(top_srcdir)/doc/MP4GetRtpPacketTransmitOffset.3 \
+		$(top_srcdir)/doc/MP4GetRtpTimestampStart.3 \
+		$(top_srcdir)/doc/MP4GetSampleIdFromEditTime.3 \
+		$(top_srcdir)/doc/MP4GetSceneProfileLevel.3 \
+		$(top_srcdir)/doc/MP4GetSessionSdp.3 \
+		$(top_srcdir)/doc/MP4GetTrackAudioMpeg4Type.3 \
+		$(top_srcdir)/doc/MP4GetTrackAudioType.3 \
+		$(top_srcdir)/doc/MP4GetTrackBitRate.3 \
+		$(top_srcdir)/doc/MP4GetTrackDuration.3 \
+		$(top_srcdir)/doc/MP4GetTrackEditDuration.3 \
+		$(top_srcdir)/doc/MP4GetTrackEditDwell.3 \
+		$(top_srcdir)/doc/MP4GetTrackEditMediaStart.3 \
+		$(top_srcdir)/doc/MP4GetTrackEditStart.3 \
+		$(top_srcdir)/doc/MP4GetTrackEditTotalDuration.3 \
+		$(top_srcdir)/doc/MP4GetTrackESConfiguration.3 \
+		$(top_srcdir)/doc/MP4GetTrackFixedSampleDuration.3 \
+		$(top_srcdir)/doc/MP4GetTrackNumberOfEdits.3 \
+		$(top_srcdir)/doc/MP4GetTrackNumberOfSamples.3 \
+		$(top_srcdir)/doc/MP4GetTrackVideoFrameRate.3 \
+		$(top_srcdir)/doc/MP4GetTrackVideoHeight.3 \
+		$(top_srcdir)/doc/MP4GetTrackVideoType.3 \
+		$(top_srcdir)/doc/MP4GetTrackVideoWidth.3 \
+		$(top_srcdir)/doc/MP4GetVideoProfileLevel.3 \
+		$(top_srcdir)/doc/MP4MakeIsmaCompliant.3 \
+		$(top_srcdir)/doc/MP4ReadRtpHint.3 \
+		$(top_srcdir)/doc/MP4ReadRtpPacket.3 \
+		$(top_srcdir)/doc/MP4ReadSampleFromEditTime.3 \
+		$(top_srcdir)/doc/MP4SetAudioProfileLevel.3 \
+		$(top_srcdir)/doc/MP4SetGraphicsProfileLevel.3 \
+		$(top_srcdir)/doc/MP4SetHintTrackRtpPayload.3 \
+		$(top_srcdir)/doc/MP4SetHintTrackSdp.3 \
+		$(top_srcdir)/doc/MP4SetODProfileLevel.3 \
+		$(top_srcdir)/doc/MP4SetRtpTimestampStart.3 \
+		$(top_srcdir)/doc/MP4SetSceneProfileLevel.3 \
+		$(top_srcdir)/doc/MP4SetSessionSdp.3 \
+		$(top_srcdir)/doc/MP4SetTrackEditDuration.3 \
+		$(top_srcdir)/doc/MP4SetTrackEditDwell.3 \
+		$(top_srcdir)/doc/MP4SetTrackEditMediaStart.3 \
+		$(top_srcdir)/doc/MP4SetTrackESConfiguration.3 \
+		$(top_srcdir)/doc/MP4SetVideoProfileLevel.3 \
+		$(top_srcdir)/doc/MP4WriteRtpHint.3
 endif
 endif
 

From 855e9674232808ff3be7191b697dfb56917db21f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9rgio=20M=2E=20Basto?= <sergio@serjux.com>
Date: Wed, 8 Feb 2017 00:56:32 +0000
Subject: [PATCH 15/21] Fix GCC7 build

if (*pSlash != '\0') {

As it stands the body of that if will always execute and when there are
no encoding parameters ppEncodingParams will be returned as a pointer to
an empty string rather than as a null pointer
---
 src/rtphint.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/rtphint.cpp b/src/rtphint.cpp
index e07309d..1eb01f5 100644
--- a/src/rtphint.cpp
+++ b/src/rtphint.cpp
@@ -339,7 +339,7 @@ void MP4RtpHintTrack::GetPayload(
                 pSlash = strchr(pSlash, '/');
                 if (pSlash != NULL) {
                     pSlash++;
-                    if (pSlash != '\0') {
+                    if (*pSlash != '\0') {
                         length = (uint32_t)strlen(pRtpMap) - (pSlash - pRtpMap);
                         *ppEncodingParams = (char *)MP4Calloc(length + 1);
                         strncpy(*ppEncodingParams, pSlash, length);

From edc4f0ad8f37bb8aeae4e3ea34766dc6cdbb2f15 Mon Sep 17 00:00:00 2001
From: David Carlos Manuelda <StormByte@gmail.com>
Date: Tue, 7 Aug 2018 05:42:28 +0200
Subject: [PATCH 16/21] Fix clang compilation

---
 src/mp4.cpp   | 2 +-
 src/mp4util.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/mp4.cpp b/src/mp4.cpp
index 1016f79..d576103 100644
--- a/src/mp4.cpp
+++ b/src/mp4.cpp
@@ -896,7 +896,7 @@ MP4FileHandle MP4ReadProvider( const char* fileName, const MP4FileProvider* file
         }
 
         catch (...) {
-            return MP4_INVALID_TRACK_ID;
+            return (mp4v2_ismacrypParams *)MP4_INVALID_TRACK_ID;
         }
     }
 
diff --git a/src/mp4util.h b/src/mp4util.h
index 1fbbd81..b33bb44 100644
--- a/src/mp4util.h
+++ b/src/mp4util.h
@@ -33,7 +33,7 @@ namespace mp4v2 { namespace impl {
 #ifndef ASSERT
 #   define ASSERT(expr) \
         if (!(expr)) { \
-            throw new Exception("assert failure: "LIBMPV42_STRINGIFY((expr)), __FILE__, __LINE__, __FUNCTION__ ); \
+            throw new Exception("assert failure: " LIBMPV42_STRINGIFY((expr)), __FILE__, __LINE__, __FUNCTION__ ); \
         }
 #endif
 

From be738b353a48f2db565f5600a8dacdc0e269eaa8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9rgio=20M=2E=20Basto?= <sergio@serjux.com>
Date: Wed, 17 Oct 2018 13:22:34 +0100
Subject: [PATCH 17/21] Update CHANGES.logging (sync with old svn trunk)

---
 CHANGES.logging | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/CHANGES.logging b/CHANGES.logging
index 526a4f0..abe2363 100644
--- a/CHANGES.logging
+++ b/CHANGES.logging
@@ -1,7 +1,7 @@
 change log for logging branch
 
-$Revision$
-$Date$
+$Revision: 453 $
+$Date: 2011-02-03 21:46:27 +0000 (Qui, 03 Fev 2011) $
 
 -------------------
 

From a94a3372c6ef66a2276cc6cd92f7ec07a9c8bb6b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9rgio=20M=2E=20Basto?= <sergio@serjux.com>
Date: Wed, 17 Oct 2018 16:13:06 +0100
Subject: [PATCH 18/21] Fix Out-of-bounds memory access in MP4v2 2.0.0

The bug can be fixed by more checks when doing type comparison.
Reference: https://www.openwall.com/lists/oss-security/2018/07/18/3

Addresses https://nvd.nist.gov/vuln/detail/CVE-2018-14403
---
 src/mp4util.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/mp4util.cpp b/src/mp4util.cpp
index 47bd74e..696dab4 100644
--- a/src/mp4util.cpp
+++ b/src/mp4util.cpp
@@ -46,6 +46,7 @@ bool MP4NameFirstMatches(const char* s1, const char* s2)
         s1++;
         s2++;
     }
+    if(*s2 != '[' && *s2 != '.' && *s2 != '\0') return false;
     return true;
 }
 

From bb920de948c85e3db4a52292ac7250a50e3bfc86 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9rgio=20M=2E=20Basto?= <sergio@serjux.com>
Date: Sat, 2 Nov 2019 04:19:27 +0000
Subject: [PATCH 19/21] Fix v2 Type confusion in MP4v2 2.0.0

The bug is caused by the wrong assumption that the child of an `ilst`
can never be an `ilst`. So we could fix it by simply adding an ASSERT.

Reference: https://www.openwall.com/lists/oss-security/2018/07/17/1
Addresses: https://nvd.nist.gov/vuln/detail/CVE-2018-14379
---
 src/mp4atom.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/mp4atom.cpp b/src/mp4atom.cpp
index 520cbc8..7a0a53f 100644
--- a/src/mp4atom.cpp
+++ b/src/mp4atom.cpp
@@ -778,8 +778,10 @@ MP4Atom::factory( MP4File &file, MP4Atom* parent, const char* type )
         const char* const ptype = parent->GetType();
 
         if( descendsFrom( parent, "ilst" )) {
-            if( ATOMID( ptype ) == ATOMID( "ilst" ))
+            if( ATOMID( ptype ) == ATOMID( "ilst" )) {
+                ASSERT(ATOMID( type ) != ATOMID( "ilst" ));
                 return new MP4ItemAtom( file, type );
+            }
 
             if( ATOMID( type ) == ATOMID( "data" ))
                 return new MP4DataAtom(file);

From 3410bc66fb91f46325ab1d008b6a421dd8240949 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9rgio=20M=2E=20Basto?= <sergio@serjux.com>
Date: Sat, 2 Nov 2019 04:21:17 +0000
Subject: [PATCH 20/21] Null out pointer after free to prevent double free

If an exception occurs (because of a crafted MP4) before the value is reassigned, then a double free can occur.  By setting the pointer to NULL after the first free, we prevent the double free in this case.
Addresses: https://nvd.nist.gov/vuln/detail/CVE-2018-14054

copied form https://github.com/TechSmith/mp4v2/commit/f09cceeee5bd7f783fd31f10e8b3c440ccf4c743
From: Dave O'Rourke
Date: Wed, 20 Mar 2019 08:57:29 -0400
---
 src/mp4property.cpp | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/mp4property.cpp b/src/mp4property.cpp
index 9a5b1e3..1b8e1d2 100644
--- a/src/mp4property.cpp
+++ b/src/mp4property.cpp
@@ -391,8 +391,10 @@ void MP4StringProperty::Read( MP4File& file, uint32_t index )
         char*& value = m_values[i];
 
         // Generally a default atom setting, e.g. see atom_avc1.cpp, "JVT/AVC Coding"; we'll leak this string if
-        // we don't free.  Note that MP4Free checks for null.
-        MP4Free(value); 
+        // we don't free.  Note that this code checks for null before calling free and sets the pointer to null
+        // after freeing it, to prevent a double free in case an exception occurs before the value is reassigned.
+        MP4Free( value );
+        value = NULL;
 
         if( m_useCountedFormat ) {
             value = file.ReadCountedString( (m_useUnicode ? 2 : 1), m_useExpandedCount, m_fixedLength );

From 9084868fd9f86bee118001c23171e832f15009f4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9rgio=20M=2E=20Basto?= <sergio@serjux.com>
Date: Fri, 8 Nov 2019 02:01:32 +0000
Subject: [PATCH 21/21] Fix v3 Integer underflow/overflow in MP4v2 2.0.0

Reference: https://www.openwall.com/lists/oss-security/2018/07/16/1

For the overflow, we could check the result of the integer multiplication:

fix vulnerability where an atom list size is enormous
and calculating the number of bytes needed to hold the list overflows
https://github.com/TechSmith/mp4v2/pull/27/commits/70d823ccd8e2d7d0ed9e62fb7e8983d21e6acbeb

Addresses https://nvd.nist.gov/vuln/detail/CVE-2018-14326 and https://nvd.nist.gov/vuln/detail/CVE-2018-14446

For the underflow, we could check if `dataSize >= hdrSize` satisfies:
Throw exception when invalid atom size would cause integer underflow
The calculation `hdrSize - dataSize` can underflow the 64-bit unsigned int dataSize type, which can lead to incorrect results.  We throw an exception to stop the code from going any further.

Addresses https://nvd.nist.gov/vuln/detail/CVE-2018-14325
Based on https://github.com/TechSmith/mp4v2/commit/e475013c6ef78093055a02b0d035eda0f9f01451
---
 src/mp4array.h  | 2 ++
 src/mp4atom.cpp | 6 ++++++
 2 files changed, 8 insertions(+)

diff --git a/src/mp4array.h b/src/mp4array.h
index c49d59b..69d470a 100644
--- a/src/mp4array.h
+++ b/src/mp4array.h
@@ -102,6 +102,8 @@ class MP4Array {
         void Resize(MP4ArrayIndex newSize) { \
             m_numElements = newSize; \
             m_maxNumElements = newSize; \
+            if ( (uint64_t) m_maxNumElements * sizeof(type) > 0xFFFFFFFF ) \
+               throw new PlatformException("requested array size exceeds 4GB", ERANGE, __FILE__, __LINE__, __FUNCTION__); /* prevent overflow */ \
             m_elements = (type*)MP4Realloc(m_elements, \
                 m_maxNumElements * sizeof(type)); \
         } \
diff --git a/src/mp4atom.cpp b/src/mp4atom.cpp
index 7a0a53f..f5d5dc0 100644
--- a/src/mp4atom.cpp
+++ b/src/mp4atom.cpp
@@ -143,6 +143,12 @@ MP4Atom* MP4Atom::ReadAtom(MP4File& file, MP4Atom* pParentAtom)
         dataSize = file.GetSize() - pos;
     }
 
+    if(dataSize < hdrSize) {
+        ostringstream oss;
+        oss << "Invalid atom size in '" << type << "' atom, dataSize = " << dataSize << " cannot be less than hdrSize = " << static_cast<unsigned>( hdrSize );
+        log.errorf( "%s: \"%s\": %s", __FUNCTION__, file.GetFilename().c_str(), oss.str().c_str() );
+        throw new Exception( oss.str().c_str(), __FILE__, __LINE__, __FUNCTION__ );
+    }
     dataSize -= hdrSize;
 
     log.verbose1f("\"%s\": type = \"%s\" data-size = %" PRIu64 " (0x%" PRIx64 ") hdr %u",
