private void CheckAdvFileFormat(string fileName, ref AdvFileMetadataInfo fileMetadataInfo, ref GeoLocationInfo geoLocation) { AdvFile advFile = AdvFile.OpenFile(fileName); CheckAdvFileFormatInternal(advFile); fileMetadataInfo.Recorder = advFile.AdvFileTags["RECORDER"]; fileMetadataInfo.Camera = advFile.AdvFileTags["CAMERA-MODEL"]; fileMetadataInfo.Engine = advFile.AdvFileTags["FSTF-TYPE"]; engine = fileMetadataInfo.Engine; if (engine == "ADV") { advFile.AdvFileTags.TryGetValue("ADVR-SOFTWARE-VERSION", out fileMetadataInfo.AdvrVersion); if (string.IsNullOrWhiteSpace(fileMetadataInfo.AdvrVersion)) { advFile.AdvFileTags.TryGetValue("RECORDER-SOFTWARE-VERSION", out fileMetadataInfo.AdvrVersion); } advFile.AdvFileTags.TryGetValue("HTCC-FIRMWARE-VERSION", out fileMetadataInfo.HtccFirmareVersion); fileMetadataInfo.SensorInfo = advFile.AdvFileTags["CAMERA-SENSOR-INFO"]; advFile.AdvFileTags.TryGetValue("OBJNAME", out fileMetadataInfo.ObjectName); advFile.AdvFileTags.TryGetValue("LONGITUDE-WGS84", out geoLocation.Longitude); advFile.AdvFileTags.TryGetValue("LATITUDE-WGS84", out geoLocation.Latitude); advFile.AdvFileTags.TryGetValue("ALTITUDE-MSL", out geoLocation.Altitude); advFile.AdvFileTags.TryGetValue("MSL-WGS84-OFFSET", out geoLocation.MslWgs84Offset); if (!string.IsNullOrEmpty(geoLocation.MslWgs84Offset) && !geoLocation.MslWgs84Offset.StartsWith("-")) { geoLocation.MslWgs84Offset = "+" + geoLocation.MslWgs84Offset; } advFile.AdvFileTags.TryGetValue("GPS-HDOP", out geoLocation.GpsHdop); } else if (engine == "AAV") { advFile.AdvFileTags.TryGetValue("OCR-ENGINE", out OcrEngine); string sCorr; int iCorr; if (advFile.AdvFileTags.TryGetValue("CAPHNTP-TIMING-CORRECTION", out sCorr) && int.TryParse(sCorr, out iCorr)) { fileMetadataInfo.HasNTPTimeStamps = true; } advFile.AdvFileTags.TryGetValue("OBJECT", out fileMetadataInfo.ObjectName); } this.geoLocation = new GeoLocationInfo(geoLocation); }
private void DoConsistencyCheck(AdvFile advFile, ref bool fileIsCorrupted, ref bool isADVFormat, ref int advFormatVersion) { fileIsCorrupted = advFile.IsCorrupted; string fstsTypeStr; if (!advFile.AdvFileTags.TryGetValue("FSTF-TYPE", out fstsTypeStr)) { isADVFormat = false; } else { isADVFormat = fstsTypeStr == "ADV" || fstsTypeStr == "AAV"; } if (fstsTypeStr == "ADV") { string advVersionStr; if (!advFile.AdvFileTags.TryGetValue("ADV-VERSION", out advVersionStr)) { advFormatVersion = -1; } else if (!int.TryParse(advVersionStr, out advFormatVersion)) { advFormatVersion = -1; } } else if (fstsTypeStr == "AAV") { string advVersionStr; if (!advFile.AdvFileTags.TryGetValue("AAV-VERSION", out advVersionStr)) { advFormatVersion = -1; } else if (!int.TryParse(advVersionStr, out advFormatVersion)) { advFormatVersion = -1; } } }
private void CheckAdvFileFormatInternal(AdvFile advFile) { bool fileIsCorrupted = true; bool isADVFormat = false; int advFormatVersion = -1; DoConsistencyCheck(advFile, ref fileIsCorrupted, ref isADVFormat, ref advFormatVersion); if (!isADVFormat) { throw new ADVFormatException("The file is not in ADV/AAV format."); } if (advFormatVersion > 1) { throw new ADVFormatException("The file ADV/AAV version is not supported yet."); } if (fileIsCorrupted) { throw new ADVFormatException("The ADV/AAV file may be corrupted.\r\n\r\nTry to recover it from Tools -> ADV/AAV Tools -> Repair ADV/AAV File"); } }
public void Initialize(Action <int, int> progressCallback) { Task.Run(() => { progressCallback(0, m_Aav.CountFrames); var aavFile = AdvFile.OpenFile(m_Aav.FileName); aavFile.Close(); // This is the system timestamp retrieved by the system when the frame was saved to disk. var SYSTEM_TIME_TAG = aavFile.StatusSection.TagDefinitions.SingleOrDefault(x => x.Name == "SystemTime"); // This is the system timestamp retrieved by the system when the frame was received. var SYSTEM_TIME_FT_TAG = aavFile.StatusSection.TagDefinitions.SingleOrDefault(x => x.Name == "SystemTimeFileTime"); // This is the OCR-ed time with the full precision (0.1 ms for IOTA-VTI) rather than only the 1 ms from the AAVv1 timestamp var OCR_TIME_TAG = aavFile.StatusSection.TagDefinitions.SingleOrDefault(x => x.Name == "OcrTime"); // This is the NTP timestamp retrieved by the system when the frame was received. It has been corrected for the configured 'Calibration Correction' in OccuRec var NTP_TIME_TAG = aavFile.StatusSection.TagDefinitions.SingleOrDefault(x => x.Name == "NTPEndTimestamp"); var NTP_ERROR_TAG = aavFile.StatusSection.TagDefinitions.SingleOrDefault(x => x.Name == "NTPTimestampError"); var OCR_DEBUG_1_TAG = aavFile.StatusSection.TagDefinitions.SingleOrDefault(x => x.Name == "StartFrameTimestamp"); var OCR_DEBUG_2_TAG = aavFile.StatusSection.TagDefinitions.SingleOrDefault(x => x.Name == "EndFrameTimestamp"); var CPU_USAGE_TAG = aavFile.StatusSection.TagDefinitions.SingleOrDefault(x => x.Name == "CpuUtilisation"); var DISK_USAGE_TAG = aavFile.StatusSection.TagDefinitions.SingleOrDefault(x => x.Name == "DisksUtilisation"); var FREE_MEMORY_TAG = aavFile.StatusSection.TagDefinitions.SingleOrDefault(x => x.Name == "FreeMemoryMb"); float maxDeltaSys = 0; float minDeltaSys = 0; float maxDeltaSysF = 0; float minDeltaSysF = 0; float maxDeltaNtp = 0; float minDeltaNtp = 0; float maxNtpError = 0; float minNtpError = 0; float maxFreeMemory = 0; float minFreeMemory = float.MaxValue; float maxDiskUsage = 0; using (FileStream file = new FileStream(m_Aav.FileName, FileMode.Open, FileAccess.Read, FileShare.Read)) using (BinaryReader reader = new BinaryReader(file)) { int i = 0; string tagVal; List <TimeAnalyserEntry> entriesWithNoUtil = new List <TimeAnalyserEntry>(); foreach (var idx in aavFile.Index.Index) { file.Seek(idx.Offset, SeekOrigin.Begin); uint frameDataMagic = reader.ReadUInt32(); Trace.Assert(frameDataMagic == 0xEE0122FF); byte[] data = reader.ReadBytes((int)idx.Length); // Read the timestamp and exposure long frameTimeMsSince2010 = (long)data[0] + (((long)data[1]) << 8) + (((long)data[2]) << 16) + (((long)data[3]) << 24) + (((long)data[4]) << 32) + (((long)data[5]) << 40) + (((long)data[6]) << 48) + (((long)data[7]) << 56); int exposure = data[8] + (data[9] << 8) + (data[10] << 16) + (data[11] << 24); if (frameTimeMsSince2010 == 0) { // First or last AAV frame continue; } var entry = new TimeAnalyserEntry(); int dataOffset = 12; AdvImageData imageData = null; int sectionDataLength = data[dataOffset] + (data[dataOffset + 1] << 8) + (data[dataOffset + 2] << 16) + (data[dataOffset + 3] << 24); if (sectionDataLength > 2) { imageData = (AdvImageData)aavFile.ImageSection.GetDataFromDataBytes(data, null, sectionDataLength, dataOffset + 4); } dataOffset += sectionDataLength + 4; sectionDataLength = data[dataOffset] + (data[dataOffset + 1] << 8) + (data[dataOffset + 2] << 16) + (data[dataOffset + 3] << 24); AdvStatusData statusSection = (AdvStatusData)aavFile.StatusSection.GetDataFromDataBytes(data, null, sectionDataLength, dataOffset + 4); entry.FrameNo = i; entry.ExposureMs = (float)(exposure / 10.0); if (OCR_TIME_TAG != null && statusSection.TagValues.TryGetValue(OCR_TIME_TAG, out tagVal)) { entry.ReferenceTime = new DateTime(long.Parse(tagVal)); } else { entry.ReferenceTime = AdvFile.ADV_ZERO_DATE_REF.AddMilliseconds(frameTimeMsSince2010).AddMilliseconds(-1 * entry.ExposureMs / 2); } long referenceTimeTicks = entry.ReferenceTime.Ticks; if (SYSTEM_TIME_TAG != null && statusSection.TagValues.TryGetValue(SYSTEM_TIME_TAG, out tagVal)) { entry.SystemTime = AdvFile.ADV_ZERO_DATE_REF.AddMilliseconds(long.Parse(tagVal)).AddMilliseconds(m_CorrSystemTimeMs); if (entry.SystemTime.Day + 1 == entry.ReferenceTime.Day) { // Fixing a date-change bug in OccuRec (var 1) entry.ReferenceTime = entry.ReferenceTime.AddDays(-1); referenceTimeTicks = entry.ReferenceTime.Ticks; } if (entry.SystemTime.Day == entry.ReferenceTime.Day && entry.ReferenceTime.Hour - entry.SystemTime.Hour == 23) { // Fixing a date-change bug in OccuRec (var 2) entry.ReferenceTime = entry.ReferenceTime.AddDays(-1); referenceTimeTicks = entry.ReferenceTime.Ticks; } entry.DeltaSystemTimeMs = (float)new TimeSpan(entry.SystemTime.Ticks - referenceTimeTicks).TotalMilliseconds; } if (SYSTEM_TIME_FT_TAG != null && statusSection.TagValues.TryGetValue(SYSTEM_TIME_FT_TAG, out tagVal)) { // SystemTimeAsFileTime has a microsecond precision. However the IOTA-VTI reference time precision is only 0.1 ms // so here we are rounding the SystemTimeAsFileTime value to the nearest 0.1 ms for correctness entry.SystemTimeFileTime = new DateTime(1000 * (long.Parse(tagVal) / 1000)).AddMilliseconds(m_CorrSystemTimeMs); entry.DeltaSystemFileTimeMs = (float)new TimeSpan(entry.SystemTimeFileTime.Ticks - referenceTimeTicks).TotalMilliseconds; } if (NTP_TIME_TAG != null && statusSection.TagValues.TryGetValue(NTP_TIME_TAG, out tagVal)) { entry.NTPTime = AdvFile.ADV_ZERO_DATE_REF.AddMilliseconds(long.Parse(tagVal)).AddMilliseconds(m_CorrNtpTimeMs); entry.DeltaNTPTimeMs = (float)new TimeSpan(entry.NTPTime.Ticks - referenceTimeTicks).TotalMilliseconds; } if (NTP_ERROR_TAG != null && statusSection.TagValues.TryGetValue(NTP_ERROR_TAG, out tagVal)) { entry.NTPErrorMs = 3 * int.Parse(tagVal) / 10.0f; // Value recorded in 0.1MS, converted to MS and then taken as 3-Sigma } Entries.Add(entry); if (imageData != null) { entry.DebugImage = BitmapFilter.ToVideoFields(Pixelmap.ConstructBitmapFromBitmapPixels(imageData.ImageData)); entry.IsOutlier = true; if (OCR_DEBUG_1_TAG != null && statusSection.TagValues.TryGetValue(OCR_DEBUG_1_TAG, out tagVal)) { entry.OrcField1 = tagVal; } if (OCR_DEBUG_2_TAG != null && statusSection.TagValues.TryGetValue(OCR_DEBUG_2_TAG, out tagVal)) { entry.OrcField2 = tagVal; } DebugFrames.Add(entry); } else { int maxOutlier = 2000; int minOutlier = -2000; if (entry.DeltaSystemTimeMs > maxDeltaSys) { if (entry.DeltaSystemTimeMs < maxOutlier) { maxDeltaSys = entry.DeltaSystemTimeMs; } else { entry.IsOutlier = true; Trace.WriteLine("SystemTime Outlier: " + entry.DeltaSystemTimeMs); } } if (entry.DeltaSystemTimeMs < minDeltaSys) { if (entry.DeltaSystemTimeMs > minOutlier) { minDeltaSys = entry.DeltaSystemTimeMs; } else { entry.IsOutlier = true; Trace.WriteLine("SystemTime Outlier: " + entry.DeltaSystemTimeMs); } } if (entry.DeltaSystemFileTimeMs > maxDeltaSysF) { if (entry.DeltaSystemFileTimeMs < maxOutlier) { maxDeltaSysF = entry.DeltaSystemFileTimeMs; } else { entry.IsOutlier = true; Trace.WriteLine("SystemFileTime Outlier: " + entry.DeltaSystemFileTimeMs); } } if (entry.DeltaSystemFileTimeMs < minDeltaSysF) { if (entry.DeltaSystemFileTimeMs > minOutlier) { minDeltaSysF = entry.DeltaSystemFileTimeMs; } else { entry.IsOutlier = true; Trace.WriteLine("SystemFileTime Outlier: " + entry.DeltaSystemFileTimeMs); } } if (entry.DeltaNTPTimeMs > maxDeltaNtp) { if (entry.DeltaNTPTimeMs < maxOutlier) { maxDeltaNtp = entry.DeltaNTPTimeMs; } else { entry.IsOutlier = true; //Trace.WriteLine("NTPTime Outlier: " + entry.DeltaNTPTimeMs); } } if (entry.DeltaNTPTimeMs < minDeltaNtp) { if (entry.DeltaNTPTimeMs > minOutlier) { minDeltaNtp = entry.DeltaNTPTimeMs; } else { entry.IsOutlier = true; //Trace.WriteLine("NTPTime Outlier: " + entry.DeltaNTPTimeMs); } } if (entry.NTPErrorMs > maxNtpError) { if (entry.NTPErrorMs < maxOutlier) { maxNtpError = entry.NTPErrorMs; } else { entry.IsOutlier = true; //Trace.WriteLine("NtpError Outlier: " + entry.NTPErrorMs); } } if (-entry.NTPErrorMs < minNtpError) { if (-entry.NTPErrorMs > minOutlier) { minNtpError = -entry.NTPErrorMs; } else { entry.IsOutlier = true; //Trace.WriteLine("NtpError Outlier: " + -entry.NTPErrorMs); } } } if (CPU_USAGE_TAG != null && statusSection.TagValues.TryGetValue(CPU_USAGE_TAG, out tagVal)) { float cpuUsage = float.Parse(tagVal, CultureInfo.InvariantCulture); float diskUsage = 0; float freeMemory = 0; if (DISK_USAGE_TAG != null && statusSection.TagValues.TryGetValue(DISK_USAGE_TAG, out tagVal)) { diskUsage = float.Parse(tagVal, CultureInfo.InvariantCulture); if (maxDiskUsage < diskUsage) { maxDiskUsage = diskUsage; } } if (FREE_MEMORY_TAG != null && statusSection.TagValues.TryGetValue(FREE_MEMORY_TAG, out tagVal)) { freeMemory = float.Parse(tagVal, CultureInfo.InvariantCulture); if (maxFreeMemory < freeMemory) { maxFreeMemory = freeMemory; } if (minFreeMemory > freeMemory) { minFreeMemory = freeMemory; } } var currUtilisationEntry = new SystemUtilisationEntry() { CpuUtilisation = cpuUsage, DiskUtilisation = diskUsage, FreeMemory = freeMemory }; SystemUtilisation.Add(currUtilisationEntry); entriesWithNoUtil.ForEach(x => x.UtilisationEntry = currUtilisationEntry); entriesWithNoUtil.Clear(); } entriesWithNoUtil.Add(entry); i++; if (i % 100 == 0) { progressCallback(i - m_Aav.FirstFrame, m_Aav.CountFrames); } } } Trace.WriteLine(string.Format("MinDeltaSys: {0:0.0}, MaxDeltaSys: {1:0.0}", minDeltaSys, maxDeltaSys)); Trace.WriteLine(string.Format("MinDeltaSysF: {0:0.0}, MaxDeltaSysF: {1:0.0}", minDeltaSysF, maxDeltaSysF)); Trace.WriteLine(string.Format("MinDeltaNtp: {0:0.0}, MaxDeltaNtp: {1:0.0}", minDeltaNtp, maxDeltaNtp)); MinDeltaNTPMs = minDeltaNtp; MaxDeltaNTPMs = maxDeltaNtp; MinDeltaNTPErrorMs = minNtpError; MaxDeltaNTPErrorMs = maxNtpError; MinDeltaSystemTimeMs = minDeltaSys; MaxDeltaSystemTimeMs = maxDeltaSys; MinDeltaSystemFileTimeMs = minDeltaSysF; MaxDeltaSystemFileTimeMs = maxDeltaSysF; MinFreeMemoryMb = minFreeMemory; MaxFreeMemoryMb = maxFreeMemory; MaxDiskUsage = maxDiskUsage; if (Entries.Count > 0) { FromDateTime = Entries.First().ReferenceTime; ToDateTime = Entries.Last().ReferenceTime; } var logFileName = Path.ChangeExtension(m_Aav.FileName, ".log"); if (File.Exists(logFileName)) { ExtractNTPLogData(logFileName); } var meinbergFileName = Path.GetFullPath(Path.GetDirectoryName(m_Aav.FileName) + @"\ntsmadvlog.txt"); if (File.Exists(meinbergFileName)) { ExtractMeinbergLogData(meinbergFileName); } progressCallback(0, 0); }); }