Skip to content
This repository has been archived by the owner on Mar 28, 2024. It is now read-only.

Commit

Permalink
Merge pull request #1 from techyian/dev
Browse files Browse the repository at this point in the history
techyian#163 - Allow individual frames to be recorded by the CircularBufferCa…
  • Loading branch information
MV10 authored Aug 17, 2020
2 parents 7ba9f69 + e8d3ed8 commit ffc9ced
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 6 deletions.
51 changes: 47 additions & 4 deletions src/MMALSharp.Processing/Handlers/CircularBufferCaptureHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -168,28 +203,32 @@ public void DisableMotionDetection()
/// </summary>
/// <param name="initRecording">Optional Action to execute when recording starts, for example, to request an h.264 I-frame.</param>
/// <param name="cancellationToken">When the token is canceled, <see cref="StopRecording"/> is called. If a token is not provided, the caller must stop the recording.</param>
/// <param name="recordNumFrames">Optional number of full frames to record. If value is 0, <paramref name="cancellationToken"/> parameter will be used to manage timeout.</param>
/// <param name="splitFrames">Optional flag to state full frames should be split to new files.</param>
/// <returns>Task representing the recording process if a CancellationToken was provided, otherwise a completed Task.</returns>
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)
{
throw new InvalidOperationException($"Recording unavailable, {nameof(CircularBufferCaptureHandler)} was not created with output-file arguments");
}

_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)
}
Expand All @@ -212,6 +251,10 @@ public void StopRecording()

_recordToFileStream = false;
_receivedIFrame = false;
_beginRecordFrame = false;
_recordNumFrames = 0;
_numFramesRecorded = 0;
_splitFrames = false;

(_analyser as FrameDiffAnalyser)?.ResetAnalyser();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ public string GetFilepath() =>
/// </summary>
public virtual void NewFile()
{
if(this.CurrentStream == null)
if (this.CurrentStream == null)
{
return;
}
Expand Down
2 changes: 1 addition & 1 deletion src/MMALSharp.Processing/Handlers/StreamCaptureHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down

0 comments on commit ffc9ced

Please sign in to comment.