From e8d3ed840b915ecf4739c59525707662b053a5c3 Mon Sep 17 00:00:00 2001 From: techyian Date: Mon, 17 Aug 2020 20:05:30 +0100 Subject: [PATCH] #163 - Allow individual frames to be recorded by the CircularBufferCaptureHandler. Also added additional check to the PostProcess method on StreamCaptureHandler as it was randomly throwing exceptions. --- .../Handlers/CircularBufferCaptureHandler.cs | 51 +++++++++++++++++-- .../Handlers/FileStreamCaptureHandler.cs | 2 +- .../Handlers/StreamCaptureHandler.cs | 2 +- 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/MMALSharp.Processing/Handlers/CircularBufferCaptureHandler.cs b/src/MMALSharp.Processing/Handlers/CircularBufferCaptureHandler.cs index a0e5fcfb..2e9ed910 100644 --- a/src/MMALSharp.Processing/Handlers/CircularBufferCaptureHandler.cs +++ b/src/MMALSharp.Processing/Handlers/CircularBufferCaptureHandler.cs @@ -23,6 +23,10 @@ public sealed class CircularBufferCaptureHandler : VideoStreamCaptureHandler, IM private int _bufferSize; private bool _shouldDetectMotion; private bool _receivedIFrame; + private int _recordNumFrames; + private int _numFramesRecorded; + private bool _splitFrames; + private bool _beginRecordFrame; private IFrameAnalyser _analyser; private MotionConfig _motionConfig; @@ -77,6 +81,37 @@ public override void Process(ImageContext context) this.Buffer.PushBack(context.Data[i]); } } + else if (_recordNumFrames > 0) + { + // We will begin storing data immediately after we receive an EOS, this means we're sure to record frame data from the beginning of the stream. + if (_beginRecordFrame) + { + this.CurrentStream.Write(context.Data, 0, context.Data.Length); + this.Processed += context.Data.Length; + + if (context.Eos) + { + // We've reached the end of the frame. Check if we want to create a new file and increment number of recorded frames. + _numFramesRecorded++; + + if (_numFramesRecorded >= _recordNumFrames) + { + // Effectively stop recording individual frames at this point. + _beginRecordFrame = false; + } + } + } + + if (context.Eos && _numFramesRecorded < _recordNumFrames) + { + _beginRecordFrame = true; + + if (_splitFrames) + { + this.Split(); + } + } + } else { if (context.Encoding == MMALEncoding.H264) @@ -168,8 +203,10 @@ public void DisableMotionDetection() /// /// Optional Action to execute when recording starts, for example, to request an h.264 I-frame. /// When the token is canceled, is called. If a token is not provided, the caller must stop the recording. + /// Optional number of full frames to record. If value is 0, parameter will be used to manage timeout. + /// Optional flag to state full frames should be split to new files. /// Task representing the recording process if a CancellationToken was provided, otherwise a completed Task. - public async Task StartRecording(Action initRecording = null, CancellationToken cancellationToken = default) + public async Task StartRecording(Action initRecording = null, CancellationToken cancellationToken = default, int recordNumFrames = 0, bool splitFrames = false) { if (this.CurrentStream == null) { @@ -177,19 +214,21 @@ public async Task StartRecording(Action initRecording = null, CancellationToken } _recordToFileStream = true; - + _recordNumFrames = recordNumFrames; + _splitFrames = splitFrames; + if (initRecording != null) { initRecording.Invoke(); } - if(cancellationToken != CancellationToken.None) + if (cancellationToken != CancellationToken.None) { try { await cancellationToken.AsTask().ConfigureAwait(false); } - catch(TaskCanceledException) + catch (TaskCanceledException) { // normal, but capture here because we may be running in the async void lambda (onDetect) } @@ -212,6 +251,10 @@ public void StopRecording() _recordToFileStream = false; _receivedIFrame = false; + _beginRecordFrame = false; + _recordNumFrames = 0; + _numFramesRecorded = 0; + _splitFrames = false; (_analyser as FrameDiffAnalyser)?.ResetAnalyser(); } diff --git a/src/MMALSharp.Processing/Handlers/FileStreamCaptureHandler.cs b/src/MMALSharp.Processing/Handlers/FileStreamCaptureHandler.cs index 3f4f8c74..c0b1497b 100644 --- a/src/MMALSharp.Processing/Handlers/FileStreamCaptureHandler.cs +++ b/src/MMALSharp.Processing/Handlers/FileStreamCaptureHandler.cs @@ -130,7 +130,7 @@ public string GetFilepath() => /// public virtual void NewFile() { - if(this.CurrentStream == null) + if (this.CurrentStream == null) { return; } diff --git a/src/MMALSharp.Processing/Handlers/StreamCaptureHandler.cs b/src/MMALSharp.Processing/Handlers/StreamCaptureHandler.cs index 09ea25d4..6d23a438 100644 --- a/src/MMALSharp.Processing/Handlers/StreamCaptureHandler.cs +++ b/src/MMALSharp.Processing/Handlers/StreamCaptureHandler.cs @@ -42,7 +42,7 @@ public override void PostProcess() { try { - if (this.CurrentStream != null && this.CurrentStream.Length > 0) + if (this.CurrentStream != null && this.CurrentStream.CanRead && this.CurrentStream.Length > 0) { if (this.OnManipulate != null && this.ImageContext != null) {