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

see MMALSharp issue #163 #164

Closed
wants to merge 2 commits into from
Closed

Conversation

MV10
Copy link
Collaborator

@MV10 MV10 commented Aug 4, 2020

Fixes #163

Adds OnDemandImageCaptureHandler and IStreamWriter to the Processing project.

Modifies FastImageOutputCallbackHandler in the main project to recognize an IStreamWriter handler.

@MV10
Copy link
Collaborator Author

MV10 commented Aug 4, 2020

Modifications to the wiki motion detection example to capture three images at the start of recording, one per second. Motion detection comments removed so that on-demand comments will stand out:

public async Task DetectMotionWithImages()
{
    MMALCamera cam = MMALCamera.Instance;
    MMALCameraConfig.InlineHeaders = true;

    // Stores the most current full frame; will write it on demand in response to a call to NewFile()
    using (var imgCaptureHandler = new OnDemandImageCaptureHandler(ramdiskPath, "jpg"))

    // Setting continuousCapture puts the handler into fast image processing mode
    using (var imgEncoder = new MMALImageEncoder(continuousCapture: true))

    using (var vidCaptureHandler = new CircularBufferCaptureHandler(4000000, "/home/pi/videos/detections", "h264"))
    using (var motionCircularBufferCaptureHandler = new CircularBufferCaptureHandler(4000000))
    using (var splitter = new MMALSplitterComponent())
    using (var resizer = new MMALIspComponent())
    using (var vidEncoder = new MMALVideoEncoder())
    using (var renderer = new MMALVideoRenderer())
    {
        cam.ConfigureCameraSettings();

        splitter.ConfigureInputPort(new MMALPortConfig(MMALEncoding.OPAQUE, MMALEncoding.I420), cam.Camera.VideoPort, null);
        resizer.ConfigureOutputPort<VideoPort>(0, new MMALPortConfig(MMALEncoding.RGB24, MMALEncoding.RGB24, width: 640, height: 480), motionCaptureHandler);
        vidEncoder.ConfigureOutputPort(new MMALPortConfig(MMALEncoding.H264, MMALEncoding.I420, 0, MMALVideoEncoder.MaxBitrateLevel4, null), vidCaptureHandler);

        // Note the image quality argument for still image capture
        imgEncoder.ConfigureOutputPort(new MMALPortConfig(MMALEncoding.JPEG, MMALEncoding.I420, quality: 90), imgCaptureHandler);

        cam.Camera.VideoPort.ConnectTo(splitter);
        cam.Camera.PreviewPort.ConnectTo(renderer);

        splitter.Outputs[0].ConnectTo(resizer);
        splitter.Outputs[1].ConnectTo(vidEncoder);
        splitter.Outputs[2].ConnectTo(imgEncoder); // Still-image input/output connection

        await Task.Delay(2000);
        
        var cts = new CancellationTokenSource(TimeSpan.FromSeconds(60));
        
        var motionConfig = new MotionConfig(threshold: 130, testFrameInterval: TimeSpan.FromSeconds(3));

        await cam.WithMotionDetection(motionCircularBufferCaptureHandler, motionConfig,
        async () =>
        {
            // This callback will be invoked when motion has been detected.

            motionCircularBufferCaptureHandler.DisableMotionDetection();

            var ctsStopRecording = new CancellationTokenSource();
            ctsStopRecording.Token.Register(() =>
            {
                motionCircularBufferCaptureHandler.EnableMotionDetection();
                vidCaptureHandler.StopRecording();
                vidCaptureHandler.Split();
            });

            // These will time out and record a still image one and two seconds after the recording starts
            var ctsImageOneSecond = new CancellationTokenSource();
            var ctsImageTwoSecond = new CancellationTokenSource();

            // Save image on demand by calling NewFile() when the token timeout expires
            ctsImageOneSecond.Token.Register(imgCaptureHandler.NewFile)
            ctsImageTwoSecond.Token.Register(imgCaptureHandler.NewFile)

            // Record an image right now, then set the still-image timers, and the overall recording timer
            imgCaptureHandler.NewFile();
            ctsImageOneSecond.CancelAfter(1000);
            ctsImageTwoSecond.CancelAfter(2000);
            ctsStopRecording.CancelAfter(10 * 1000);

            await Task.WhenAny(
                vidCaptureHandler.StartRecording(vidEncoder.RequestIFrame, ctsStopRecording.Token),
                cts.Token.AsTask()
            );

            if (!recordingCTS.IsCancellationRequested) 
            {
                ctsImageOneSecond.Cancel();
                ctsImageTwoSecond.Cancel();
                recordingCTS.Cancel();
            }
        })
        .ProcessAsync(cam.Camera.VideoPort, cts.Token);
    }
    
    cam.Cleanup();
}

@MV10
Copy link
Collaborator Author

MV10 commented Aug 15, 2020

Closing in favor of modifications to existing handlers.

@MV10 MV10 closed this Aug 15, 2020
@MV10 MV10 deleted the OnDemandImageCaptureHandler branch August 15, 2020 12:47
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Write JPGs during motion-detection recording
1 participant