fix #6208, negative broadcast timestamps
authorRobin Gareus <robin@gareus.org>
Sun, 22 Mar 2015 15:01:40 +0000 (16:01 +0100)
committerRobin Gareus <robin@gareus.org>
Sun, 22 Mar 2015 15:12:40 +0000 (16:12 +0100)
libs/ardour/sndfileimportable.cc
libs/audiographer/src/general/broadcast_info.cc

index ceb88eddc9f80c4ae61a87b41e9c1b092a59dad3..2c5588650276ce08024fc010009494e165c1ff6a 100644 (file)
@@ -1,8 +1,10 @@
-#include "ardour/sndfileimportable.h"
 #include <sndfile.h>
 #include <iostream>
 #include <cstring>
 
+#include "pbd/error.h"
+#include "ardour/sndfileimportable.h"
+
 using namespace ARDOUR;
 using namespace std;
 
@@ -15,10 +17,32 @@ SndFileImportableSource::get_timecode_info (SNDFILE* sf, SF_BROADCAST_INFO* binf
                return 0;
        }
 
+       /* see http://tracker.ardour.org/view.php?id=6208
+        * 0xffffffff 0xfffc5680
+        * seems to be a bug in Presonus Capture (which generated the file)
+        *
+        * still since framepos_t is a signed int, ignore files that could
+        * lead to negative timestamps for now.
+        */
+
+       if (binfo->time_reference_high & 0x80000000) {
+               char tmp[64];
+               snprintf(tmp, sizeof(tmp), "%x%08x", binfo->time_reference_high, binfo->time_reference_low);
+               PBD::warning << "Invalid Timestamp " << tmp << endmsg;
+               exists = false;
+               return 0;
+       }
+
        exists = true;
-       int64_t ret = (uint32_t) binfo->time_reference_high;
+       /* libsndfile reads eactly 4 bytes for high and low, but
+        * uses "unsigned int" which may or may not be 32 bit little
+        * endian.
+        */
+       int64_t ret = (uint32_t) (binfo->time_reference_high & 0x7fffffff);
        ret <<= 32;
-       ret |= (uint32_t) binfo->time_reference_low;
+       ret |= (uint32_t) (binfo->time_reference_low & 0xffffffff);
+
+       assert(ret >= 0);
        return ret;
 }
 
index df69ac9c79df618a07f4891f0193824b1e67b98f..5daee9b2ec263b1fd18f1ba3bf2336c930d3bb37 100644 (file)
@@ -110,9 +110,13 @@ BroadcastInfo::get_time_reference () const
                return 0;
        }
 
-       int64_t ret = (uint32_t) info->time_reference_high;
+       if (info->time_reference_high & 0x80000000) {
+               return 0;
+       }
+
+       int64_t ret = (uint32_t) (info->time_reference_high & 0x7fffffff);
        ret <<= 32;
-       ret |= (uint32_t) info->time_reference_low;
+       ret |= (uint32_t) (info->time_reference_low & 0xffffffff);
        return ret;
 }