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; }
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; } }