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");
            }
        }
Пример #4
0
        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);
            });
        }