Пример #1
0
        private void PrepareSample(SourceReaderFlags flags, long timestamp, Sample sample)
        {
            if (flags.HasFlag(SourceReaderFlags.StreamTick))
            {
                firstTimestamp = timestamp;
            }

            if (sample != null)
            {
                //Console.WriteLine("time " + time + " Timestamp " + timestamp + " Flags " + flags);
                var sampleDuration  = timestamp - prevTimestamp;
                var sampleTimestamp = timestamp - firstTimestamp;

                sample.SampleTime     = sampleTimestamp;
                sample.SampleDuration = sampleDuration;

                ProcessSample(sample);
            }
            prevTimestamp = timestamp;
        }
Пример #2
0
        private void samplerProc()
        {
            try
            {
                long currentSampleTime = 0;
                int  streamRef         = 0;
                SourceReaderFlags sourceReaderFlags = 0;

                int fpsStoreLen = 25;
                var fpsStore    = new Queue <long>();

                Stopwatch sw             = new Stopwatch();
                long      lastSampleTime = -1;
                bool      justUnfreezed  = false;
                double    fps            = double.NaN;

                while (!cancelTokenSource.Token.IsCancellationRequested)
                {
                    bool gonnaFreeze        = WantToFreezeFlag;
                    bool skipBufferedFrames = gonnaFreeze || justUnfreezed;

                    lock (startLocker)
                        if (WantToConfigureReader || reader == null || reader.IsDisposed)
                        {
                            newSourceReader();
                            WantToConfigureReader = false;
                            WantToChangeMediaType = true;
                            fpsStore.Clear();
                        }

                    if (WantToChangeMediaType)
                    {
                        setMediaType();
                        WantToChangeMediaType = false;
                        fpsStore.Clear();
                    }

                    if (skipBufferedFrames)
                    {
                        sw.Restart();
                    }
                    Sample sample = reader.ReadSample(SourceReaderIndex.FirstVideoStream, 0, out streamRef, out sourceReaderFlags, out currentSampleTime);
                    if (skipBufferedFrames)
                    {
                        sw.Stop();
                    }

                    if (sample == null && sourceReaderFlags.HasFlag(SourceReaderFlags.StreamTick))
                    {
                        continue;
                    }

                    if (sourceReaderFlags != SourceReaderFlags.None)
                    {
                        if (sample != null)
                        {
                            sample.Dispose();
                        }
                        throw new Exception("Something went really wrong");
                    }

                    if (skipBufferedFrames)
                    {
                        if (sw.ElapsedMilliseconds <= 5)
                        {
                            SharpDX.Utilities.Dispose(ref sample); lastSampleTime = currentSampleTime; continue;
                        }
                    }

                    justUnfreezed = false;

                    if (lastSampleTime != -1)
                    {
                        fpsStore.Enqueue(currentSampleTime - lastSampleTime);
                        if (fpsStore.Count() > fpsStoreLen)
                        {
                            fpsStore.Dequeue();
                        }
                        fps = 10000000.0 / fpsStore.Average();
                    }
                    lastSampleTime = currentSampleTime;

                    if (cancelTokenSource.Token.IsCancellationRequested)
                    {
                        break;
                    }

                    lock (sampleLocker)
                    {
                        if (lastSample == null || lastSample.TotalLength != sample.TotalLength)
                        {
                            var tp    = reader.GetCurrentMediaType(SourceReaderIndex.FirstVideoStream);
                            var fsize = tp.Get(MediaTypeAttributeKeys.FrameSize);
                            tp.Dispose();
                            long w = fsize >> 32;
                            long h = fsize & 0xFFFF;

                            lastSampleFrameH = (int)h;
                            lastSampleFrameW = (int)w;
                        }

                        SharpDX.Utilities.Dispose(ref lastSample);
                        lastSample = sample;
                    }

                    OnNewFrame?.Invoke(this, new NewFrameEventArgs(gonnaFreeze ? double.NaN : Math.Round(fps, 1)));

                    if (!gonnaFreeze)
                    {
                        continue;
                    }

                    WantToFreezeFlag = false;
                    freezedEvent.Set();
                    kickstartEvent.Reset();
                    kickstartEvent.Wait();
                    justUnfreezed = true;
                    fpsStore.Clear();
                }
            }
            catch (SharpDXException ex)
            {
                if ((ex.ResultCode == SharpDX.MediaFoundation.ResultCode.TopoCodecNotFound ||
                     ex.ResultCode == SharpDX.MediaFoundation.ResultCode.InvalidMediaType))
                {
                    String msg = $"Uncompatible MediaType format for current Source Reader configuration.\nSampler stopped\n\n{ex.Message}";
                    MessageBox.Show(msg, "Oops");
                }
                if (ex.ResultCode == SharpDX.MediaFoundation.ResultCode.VideoRecordingDeviceInvalidated)
                {
                    SharpDX.Utilities.Dispose(ref reader);
                    if (settingsForm != null)
                    {
                        settingsForm.BeginInvoke(new Action(() => settingsForm.Close()));
                    }
                    WantToConfigureReader = true;   //  Recreate the device & reader on possible new connection attempt
                }
                throw;
            }
        }