/// <summary>
        ///  Calculates dropped frame statistics based on the difference in
        ///  timestamps between two consecutive headers.
        /// </summary>
        /// <param name="stream">
        ///  The KStudioSeekableEventStream object of the video stream
        /// </param>
        /// <param name="frameTime">The number of milliseconds per frame</param>
        /// <returns>
        ///  FrameAnalysis object with collected frame statistics.
        /// </returns>
        public override FrameAnalysis CountDroppedFrames()
        {
            double        prevFrameTime  = 0;
            double        cumulativeTime = 0;
            int           eventIndex     = 0;
            FrameAnalysis result         = new FrameAnalysis();

            KStudioSeekableEventStream stream = (KStudioSeekableEventStream)_stream;

            prevFrameTime = stream.StartRelativeTime.TotalMilliseconds;

            foreach (KStudioEventHeader header in stream.EventHeaders)
            {
                double currentFrameTime = header.RelativeTime.TotalMilliseconds;
                double deltaTime        = currentFrameTime - prevFrameTime;

                cumulativeTime += deltaTime - FrameTime;

                result.FrameCount++;
                result.FrameMap.Add(eventIndex);

                while (cumulativeTime > FrameTime)
                {
                    result.DroppedFrames++;
                    cumulativeTime -= FrameTime;
                    result.FrameMap.Add(eventIndex);
                    result.DroppedIndices.Add(result.FrameCount++);
                }

                eventIndex++;
                prevFrameTime = currentFrameTime;
            }

            return(result);
        }
Beispiel #2
0
        public override void Extract(string outputPath)
        {
            KStudioSeekableEventStream stream = (KStudioSeekableEventStream)_stream;

            int frameCount = (int)stream.EventCount;

            double[] irTiming = new double[frameCount];
            var      values   = Enumerable.Range(0, frameCount);

            Parallel.ForEach(values, (value, pls, index) => {
                //var currEvent = stream.ReadEvent((uint) index);
                var currEvent   = stream.EventHeaders[(int)index];
                irTiming[index] = currEvent.RelativeTime.TotalMilliseconds;

                // Update progress
                OnProgressUpdated(new KinectFileProgressChangedEventArgs {
                    Progress   = (int)((float)(index + 1) / frameCount * 100),
                    StatusName = Name
                });
            });

            // Write timings
            string filepath = outputPath + "/Kinect_Output";

            Utils.WriteTimingToFile(filepath + "/IR_timing.txt", irTiming);
        }
        public bool UpdateTime(TimeSpan time, out uint foundIndex)
        {
            DebugHelper.AssertUIThread();

            LoadEvents();

            bool result = false;

            foundIndex = 0;

            EventData newSelectedNode = null;

            if (this.events != null)
            {
                KStudioSeekableEventStream seekableStream = this.stream as KStudioSeekableEventStream;
                if (seekableStream != null)
                {
                    TimeSpan foundTime;

                    if (seekableStream.FindEvent(time, out foundIndex, out foundTime))
                    {
                        if ((foundIndex >= 0) && (foundIndex < this.events.Length))
                        {
                            newSelectedNode = this.events[(int)foundIndex];
                            result          = true;
                        }
                    }
                }
            }

            this.UpdateSelection(newSelectedNode);

            return(result);
        }
Beispiel #4
0
        /// <summary>
        /// Initializes a new instance of the StreamData class and sets all properties based on the KStudioEventStream provided
        /// </summary>
        /// <param name="stream">KStudioEventStream to get data from</param>
        public StreamData(KStudioEventStream stream)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            this.EventStream      = stream;
            this.PublicMetadata   = stream.GetMetadata(KStudioMetadataType.Public);
            this.PersonalMetadata = stream.GetMetadata(KStudioMetadataType.PersonallyIdentifiableInformation);
            this.EventHeaders     = new ObservableCollection <KStudioEventHeader>();

            KStudioSeekableEventStream seekStream = stream as KStudioSeekableEventStream;

            if (seekStream != null)
            {
                this.StartTime = seekStream.StartRelativeTime;
                this.EndTime   = seekStream.EndRelativeTime;

                List <KStudioEventHeader> headers = seekStream.EventHeaders.ToList();
                foreach (KStudioEventHeader header in headers)
                {
                    this.EventHeaders.Add(header);
                }
            }
        }
        public override void Extract(string outputPath)
        {
            KStudioSeekableEventStream stream = (KStudioSeekableEventStream)_stream;
            int frameCount = _frameAnalysis.FrameCount;

            double[] colorTiming = new double[frameCount];
            var      values      = Enumerable.Range(0, frameCount);

            Parallel.ForEach(values, new ParallelOptions {
                MaxDegreeOfParallelism = 8
            },
                             (value, pls, index) => {
                WriteableBitmap colorBitmap = new WriteableBitmap(ColorWidth, ColorHeight, 96.0, 96.0,
                                                                  PixelFormats.Bgr32,
                                                                  null);
                byte[] colorData = new byte[ColorWidth * ColorHeight * 2];

                // Determine if this frame was a dropped frame
                int frameIndex = _frameAnalysis.FrameMap[(int)index];

                var currEvent = stream.ReadEvent((uint)frameIndex);
                currEvent.CopyEventDataToArray(colorData, 0);

                NativeMethods.YUY2ToBGR(colorData, 1920 * 1080 / 2, colorBitmap.BackBuffer, 1920 * 1080 * 4);
                colorBitmap.WritePixels(new Int32Rect(0, 0, 1920, 1080), colorBitmap.BackBuffer, 1920 * 1080 * 4, colorBitmap.BackBufferStride);

                // create a png bitmap encoder which knows how to save a .png file
                //BitmapEncoder encoder = new PngBitmapEncoder();
                BitmapEncoder encoder = new BmpBitmapEncoder();

                // create frame from the writable bitmap and add to encoder
                encoder.Frames.Add(BitmapFrame.Create(colorBitmap));

                string filePath = outputPath + "/Kinect_Output/Color/";
                Directory.CreateDirectory(filePath);
                string path = Path.Combine(filePath, "ColorFrame_" + index + ".bmp");

                // write the new file to disk
                try {
                    using (FileStream fs = new FileStream(path, FileMode.Create)) {
                        encoder.Save(fs);
                    }
                }
                catch (IOException) { }

                colorTiming[frameIndex] = currEvent.RelativeTime.TotalMilliseconds;

                // Update progress
                OnProgressUpdated(new KinectFileProgressChangedEventArgs {
                    Progress   = (int)((float)((int)index + 1) / frameCount * 100),
                    StatusName = Name
                });
            });

            // Write timings
            string filepath = outputPath + "/Kinect_Output";

            Utils.WriteTimingToFile(filepath + "/color_timing.txt", colorTiming);
        }
Beispiel #6
0
        public override void Extract(string outputPath)
        {
            KStudioSeekableEventStream stream = (KStudioSeekableEventStream)_stream;

            string filePath = outputPath + "\\Kinect_Output\\Depth\\";

            Utils.ExistOrCreateDirectory(filePath);

            int frameCount = (int)stream.EventCount;

            double[] depthTiming = new double[frameCount];

            var values = Enumerable.Range(0, frameCount);

            Parallel.ForEach(values, (value, pls, index) => {
                WriteableBitmap depthBitmap = new WriteableBitmap(DepthWidth, DepthHeight, 96.0, 96.0,
                                                                  PixelFormats.Gray16, null);
                var currEvent = stream.ReadEvent((uint)index);
                IntPtr buffer = Marshal.AllocHGlobal((int)currEvent.EventDataSize);

                currEvent.CopyEventDataToBuffer(currEvent.EventDataSize, buffer);
                depthBitmap.WritePixels(new System.Windows.Int32Rect(0, 0, DepthWidth, DepthHeight), buffer, (int)currEvent.EventDataSize, depthBitmap.BackBufferStride);

                // create a png bitmap encoder which knows how to save a .png file
                BitmapEncoder encoder = new PngBitmapEncoder();

                // create frame from the writable bitmap and add to encoder
                encoder.Frames.Add(BitmapFrame.Create(depthBitmap));

                string path = Path.Combine(filePath, "DepthFrame_" + index + ".png");

                // write the new file to disk
                try {
                    using (FileStream fs = new FileStream(path, FileMode.Create)) {
                        encoder.Save(fs);
                    }
                }
                catch (IOException ex)
                {
                    Console.WriteLine(ex.StackTrace);
                }

                depthTiming[index] = currEvent.RelativeTime.TotalMilliseconds;

                // Update progress
                OnProgressUpdated(new KinectFileProgressChangedEventArgs {
                    Progress   = (int)((float)(index + 1) / frameCount * 100),
                    StatusName = Name
                });
            });

            // Write timings
            string filepath = outputPath + "\\Kinect_Output";

            Utils.WriteTimingToFile(filepath + "\\depth_timing.txt", depthTiming);
        }
Beispiel #7
0
        private void OnSwimLanesSourceChanged(IEnumerable values)
        {
            DebugHelper.AssertUIThread();

            foreach (DataBar dataBar in this.dataBars)
            {
                this.RemoveDataBar(dataBar);
            }

            this.dataBars.Clear();

            if (values != null)
            {
                foreach (object value in values)
                {
                    DataBar          dataBar = null;
                    FrameworkElement sidebar = null;

                    KStudioSeekableEventStream seekableEventStream = value as KStudioSeekableEventStream;
                    if (seekableEventStream != null)
                    {
                        sidebar = new ContentControl()
                        {
                            Content                 = seekableEventStream,
                            ContentTemplate         = this.SidebarTemplate,
                            ContentTemplateSelector = this.SidebarTemplateSelector,
                        };

                        IEventLaneDataSource eventDataSource = seekableEventStream.UserState as IEventLaneDataSource;
                        if (eventDataSource != null)
                        {
                            EventLane2 eventDataBar = new EventLane2(eventDataSource.MinTime, eventDataSource.MaxTime)
                            {
                                DataContext = seekableEventStream,
                                DataSource  = eventDataSource,
                            };

                            dataBar = eventDataBar;
                        }
                    }

                    if (dataBar == null)
                    {
                        dataBar = new DataBar();
                    }

                    this.dataBars.Add(dataBar);

                    this.AddDataBar(dataBar, sidebar, GridLength.Auto);
                }
            }
        }
Beispiel #8
0
        /// <summary>
        ///  Calculates dropped frame statistics based on the difference in
        ///  timestamps between two consecutive headers.
        /// </summary>
        /// <param name="stream">
        ///  The KStudioSeekableEventStream object of the audio stream
        /// </param>
        /// <param name="frameTime">
        ///  The number of milliseconds per audio audio frame. This is not
        ///  necessarily the time per event header as multiple audio samples can
        ///  be stored in a single event.
        /// </param>
        /// <returns>
        ///  FrameAnalysis object with collected frame statistics.
        /// </returns>
        public override FrameAnalysis CountDroppedFrames()
        {
            double        prevFrameTime  = 0;
            double        cumulativeTime = 0;
            int           lastGoodEvent  = 0;
            int           eventIndex     = 0;
            int           eventFrameSize = 14432;
            FrameAnalysis result         = new FrameAnalysis();

            KStudioSeekableEventStream stream = (KStudioSeekableEventStream)_stream;

            foreach (KStudioEventHeader header in stream.EventHeaders)
            {
                double currentFrameTime = header.RelativeTime.TotalMilliseconds;
                double deltaTime        = currentFrameTime - prevFrameTime;

                double missedTime = 0;
                int    j          = 0;

                // Determine if there are missed frames.
                do
                {
                    j          += eventFrameSize - 16;
                    missedTime += FrameTime;
                } while (j <= (int)header.EventDataSize);

                missedTime      = deltaTime - missedTime;
                cumulativeTime += missedTime;

                if (cumulativeTime > FrameTime)
                {
                    while (cumulativeTime > FrameTime)
                    {
                        cumulativeTime -= FrameTime;
                        result.DroppedFrames++;
                        result.FrameMap.Add(lastGoodEvent);
                        result.DroppedIndices.Add(result.FrameCount++);
                    }
                }
                else
                {
                    lastGoodEvent = eventIndex;
                    result.FrameMap.Add(lastGoodEvent);
                    result.FrameCount++;
                }

                eventIndex++;
                prevFrameTime = currentFrameTime;
            }

            return(result);
        }
Beispiel #9
0
        private void DirtyWork(object sender, DoWorkEventArgs e)
        {
            outputData = new ushort[WIDTH * HEIGHT];

            var client = KStudio.CreateClient();

            if (string.IsNullOrEmpty(fileName))
            {
                return;
            }
            var file = client.OpenEventFile(fileName);

            foreach (var item in file.EventStreams)
            {
                if (item.DataTypeName.Equals("Nui Depth"))
                {
                    state = "Depth";

                    KStudioSeekableEventStream stream = item as KStudioSeekableEventStream;
                    this.frameCount = (int)stream.EventCount;
                    timing          = new ushort[frameCount];

                    for (uint i = 0; i < frameCount; i++)
                    {
                        b.ReportProgress((int)((float)i / frameCount * 100));

                        Thread.Sleep(100);
                        var curr_event = stream.ReadEvent(i);
                        //unsafe
                        {
                            int    size = outputData.Length * sizeof(ushort);
                            IntPtr ip   = Marshal.AllocHGlobal(size);

                            uint bufferSize = 0;
                            curr_event.AccessUnderlyingEventDataBuffer(out bufferSize, out ip);

                            Copy(ip, outputData, 0, outputData.Length);
                        }
                        this.timing[i] = (ushort)curr_event.RelativeTime.TotalMilliseconds;
                        string filePath = Environment.CurrentDirectory + "/Xef2Mat_Output/DepthFrame" + i.ToString("D4") + ".mat";
                        MATWriter.ToMatFile("Dep" + i.ToString("D4"), filePath, outputData, HEIGHT, WIDTH);
                    }
                }
                if (item.DataTypeName.Equals("Nui IR"))
                {
                    state = "IR";

                    KStudioSeekableEventStream stream = item as KStudioSeekableEventStream;
                    this.frameCount = (int)stream.EventCount;
                    timing          = new ushort[frameCount];

                    for (uint i = 0; i < frameCount; i++)
                    {
                        b.ReportProgress((int)((float)i / frameCount * 100));

                        var curr_event = stream.ReadEvent(i);
                        //unsafe
                        {
                            int    size = outputData.Length * sizeof(ushort);
                            IntPtr ip   = Marshal.AllocHGlobal(size);

                            uint bufferSize = 0;
                            curr_event.AccessUnderlyingEventDataBuffer(out bufferSize, out ip);

                            Copy(ip, outputData, 0, outputData.Length);
                        }
                        this.timing[i] = (ushort)curr_event.RelativeTime.TotalMilliseconds;
                        string filePath = Environment.CurrentDirectory + "/Xef2Mat_Output/IRFrame" + i.ToString("D4") + ".mat";
                        MATWriter.ToMatFile("IR" + i.ToString("D4"), filePath, outputData, HEIGHT, WIDTH);
                    }
                }
            }
            if (frameCount > 0)
            {
                state = "TimeStamp";
                b.ReportProgress(100);
                string filePath = Environment.CurrentDirectory + "/Xef2Mat_Output/TimeStamp.mat";
                MATWriter.ToMatFile("Time", filePath, this.timing, this.timing.Length, 1);
            }
        }
        private void LoadEvents()
        {
            if (this.events == null)
            {
                KStudioSeekableEventStream seekableStream = this.stream as KStudioSeekableEventStream;
                if (seekableStream != null)
                {
                    IReadOnlyList <KStudioEventHeader> eventHeaders = seekableStream.EventHeaders;

                    this.events = new EventData[eventHeaders.Count];

                    bool doFrameNumber = false;

                    if (seekableStream.TagSize >= sizeof(uint))
                    {
                        // At this time, assume if there is at least 4 bytes of tag data that it is a frame number
                        doFrameNumber = true;
                    }

                    int count = eventHeaders.Count;
                    if (count > 0)
                    {
                        ulong tick;
                        uint  eventIndex;

                        {
                            KStudioEventHeader eventHeader = eventHeaders[0];
                            tick       = (ulong)eventHeader.RelativeTime.Ticks * EventStreamState.cTimeSpanTicksToTimelineTicks;
                            eventIndex = eventHeader.EventIndex;
                        }

                        int lastIndex = count - 1;

                        for (int i = 0; i < lastIndex; ++i)
                        {
                            KStudioEventHeader eventHeader = eventHeaders[i + 1];
                            ulong nextTick    = (ulong)eventHeader.RelativeTime.Ticks * EventStreamState.cTimeSpanTicksToTimelineTicks;
                            uint? frameNumber = null;

                            if (doFrameNumber)
                            {
                                uint   bufferSize;
                                IntPtr bufferPtr;
                                eventHeader.AccessUnderlyingTagDataBuffer(out bufferSize, out bufferPtr);

                                Debug.Assert(bufferSize >= sizeof(uint));
                                unsafe
                                {
                                    frameNumber = *((uint *)bufferPtr.ToPointer());
                                }
                            }

                            EventData eventDataNode = new EventData((int)eventIndex, frameNumber, tick, nextTick - tick);
                            tick       = nextTick;
                            eventIndex = eventHeader.EventIndex;

                            this.events[i] = eventDataNode;
                        }

                        {
                            KStudioEventHeader eventHeader = eventHeaders[lastIndex];
                            uint?frameNumber = null;

                            if (doFrameNumber)
                            {
                                uint   bufferSize;
                                IntPtr bufferPtr;
                                eventHeader.AccessUnderlyingTagDataBuffer(out bufferSize, out bufferPtr);

                                Debug.Assert(bufferSize >= sizeof(uint));
                                unsafe
                                {
                                    frameNumber = *((uint *)bufferPtr.ToPointer());
                                }
                            }

                            ulong lastDuration;

                            if (this.duration == 0)
                            {
                                lastDuration = EventStreamState.cLastEventDuration;
                            }
                            else
                            {
                                lastDuration = this.duration - tick;
                            }

                            EventData eventDataNode = new EventData((int)eventIndex, frameNumber, tick, lastDuration);

                            this.events[lastIndex] = eventDataNode;
                        }

#if TODODEB
                        EventHandler handler = this.TimeRangeChanged;
                        if (handler != null)
                        {
                            handler(this, EventArgs.Empty);
                        }
                        handler = this.RenderInvalidated;
                        if (handler != null)
                        {
                            handler(this, EventArgs.Empty);
                        }
#endif
                    }
                }

                this.readOnlyEvents = Array.AsReadOnly(this.events);
            }
        }
Beispiel #11
0
        public override void Extract(string outputPath)
        {
            KStudioSeekableEventStream         stream  = (KStudioSeekableEventStream)_stream;
            IReadOnlyList <KStudioEventHeader> headers = stream.EventHeaders;

            int frameCount = (int)stream.EventCount;

            double[]  audioTiming    = new double[frameCount];
            const int eventFrameSize = 14432; // Size for a single audio event frame
            const int frameSize      = 1024;  // The size of the actual audio data in an event frame
            int       dataSize       = 0;
            int       bytePos        = 0;

            // DEBUG
            int                missedFrames   = 0;
            double             cumulativeTime = 0;
            double             lDiff          = 0;
            KStudioEventHeader lHeader        = null;

            // END DEBUG

            // Hacky counting of total data size
            for (int i = 0; i < frameCount; i++)
            {
                KStudioEventHeader header = headers[i];
                int    j          = eventFrameSize;
                double missedTime = 0;
                double diff       = header.RelativeTime.TotalMilliseconds;

                /* DEBUG */
                if (lHeader != null)
                {
                    diff = header.RelativeTime.TotalMilliseconds - lHeader.RelativeTime.TotalMilliseconds;
                    if (diff > lDiff)
                    {
                        lDiff = diff;
                    }
                }

                lHeader = header;
                /* END DEBUG */

                do
                {
                    dataSize   += frameSize;
                    j          += eventFrameSize - 16;
                    missedTime += 16;
                } while (j <= (int)header.EventDataSize);

                missedTime      = diff - missedTime;
                cumulativeTime += missedTime;
                while (cumulativeTime > 16)
                {
                    cumulativeTime -= 16;
                    missedFrames++;
                }
            }

            // Calculate additional bytes needed
            //int numBytes = (int) totalMissedTime / 16 * 1024;
            int numBytes = missedFrames * frameSize;

            if (numBytes > 0)
            {
                dataSize += numBytes;
            }

            // DEBUG
            missedFrames   = 0;
            cumulativeTime = 0;
            KStudioEvent lEvent = null;

            // END DEBUG

            byte[] rawAudio = new byte[dataSize];

            for (uint i = 0; i < frameCount; i++)
            {
                int    j          = eventFrameSize;
                var    currEvent  = stream.ReadEvent(i);
                byte[] rawBuffer  = new byte[currEvent.EventDataSize];
                int    offset     = 96;
                double diff       = currEvent.RelativeTime.TotalMilliseconds;
                double missedTime = 0;

                if (lEvent != null)
                {
                    diff = currEvent.RelativeTime.TotalMilliseconds - lEvent.RelativeTime.TotalMilliseconds;
                    if (diff > lDiff)
                    {
                        lDiff = diff;
                    }
                }

                lEvent = currEvent;

                audioTiming[i] = currEvent.RelativeTime.TotalMilliseconds;
                currEvent.CopyEventDataToArray(rawBuffer, 0);

                do
                {
                    Array.Copy(rawBuffer, offset, rawAudio, bytePos, frameSize);
                    bytePos    += frameSize;
                    j          += eventFrameSize - 16;
                    offset     += eventFrameSize - 16;
                    missedTime += 16;
                } while (j <= (int)currEvent.EventDataSize);

                // If there is any missed time, add it here.
                missedTime      = diff - missedTime;
                cumulativeTime += missedTime;
                while (cumulativeTime > 16)
                {
                    cumulativeTime -= 16;
                    missedFrames++;
                    bytePos += frameSize;
                }

                // Update progress
                OnProgressUpdated(new KinectFileProgressChangedEventArgs {
                    Progress   = (int)((float)(i + 1) / frameCount * 100),
                    StatusName = Name
                });
            }

            string filepath = outputPath + "/Kinect_Output";

            Directory.CreateDirectory(filepath);
            File.WriteAllBytes(filepath + "/raw_audio.wav", rawAudio);

            // Write timings
            Utils.WriteTimingToFile(filepath + "/audio_timing.txt", audioTiming);
        }