From bf48c6867c5d2d23730adec1c696131f785084d1 Mon Sep 17 00:00:00 2001 From: techyian Date: Mon, 1 May 2017 22:11:39 +0100 Subject: [PATCH] More unit test work for #9. Added GetCameraSettings method to assist with getting exposure and gains. Updated README. --- README.md | 57 +- docfx/articles/examples.md | 8 + docs/articles/examples.html | 8 +- .../Handlers/StreamCaptureHandler.cs | 3 +- .../Components/MMALCameraComponent.cs | 3 +- src/MMALSharp/Components/MMALComponentBase.cs | 7 +- src/MMALSharp/MMALCamera.cs | 25 +- src/MMALSharp/MMALCameraConfig.cs | 4 +- src/MMALSharp/MMALCameraExtensions.cs | 19 +- src/MMALSharp/MMALPortBase.cs | 6 +- .../MMALSharpCoreExample.csproj | 23 - src/MMALSharpCoreExample/Program.cs | 90 --- src/MMALSharpCoreExample/nuget.config | 6 - src/MMALSharpExample/App.config | 6 - src/MMALSharpExample/MMALSharpExample.csproj | 564 ------------------ src/MMALSharpExample/Program.cs | 100 ---- .../Properties/AssemblyInfo.cs | 36 -- src/MMALSharpExample/paket.references | 2 - tests/MMALSharp.Tests/ImageEncoderTests.cs | 147 +++-- tests/MMALSharp.Tests/MMALFixture.cs | 6 + tests/MMALSharp.Tests/TestData.cs | 45 ++ tests/MMALSharp.Tests/VideoEncoderTests.cs | 47 +- 22 files changed, 207 insertions(+), 1005 deletions(-) delete mode 100644 src/MMALSharpCoreExample/MMALSharpCoreExample.csproj delete mode 100644 src/MMALSharpCoreExample/Program.cs delete mode 100644 src/MMALSharpCoreExample/nuget.config delete mode 100644 src/MMALSharpExample/App.config delete mode 100644 src/MMALSharpExample/MMALSharpExample.csproj delete mode 100644 src/MMALSharpExample/Program.cs delete mode 100644 src/MMALSharpExample/Properties/AssemblyInfo.cs delete mode 100644 src/MMALSharpExample/paket.references diff --git a/README.md b/README.md index d588f2e3..772b8abb 100644 --- a/README.md +++ b/README.md @@ -11,60 +11,9 @@ MMALSharp supports the following runtimes: 1) Mono 4.x 2) .NET Core 2.0 (beta) with .NET Standard 1.6. -## Installation - -For full installation instructions for Mono 4.x and .NET Core - please visit the [Documentation](https://techyian.github.io/MMALSharp) site - -## Basic Usage - -Using the library is relatively simple. If you want to change any of the default configuration settings, this can be done by modifying the -properties within `MMALCameraConfig`. The main class `MMALCamera` which interfaces to the rest of the functionality the library provides is -a Singleton and is called as follows: `MMALCamera cam = MMALCamera.Instance`. - -MMALSharp is asynchronous in nature, preventing any blocking of the main thread in your application. From testing, I found it is important that we provide a context -for the asynchronous code to run in, this is because when we await processing to complete, we need to return to the same thread we began processing on. - -Below is a basic example of its usage. - -``` - -public static void Main(string[] args) -{ - Alter any configuration properties required. - MMALCameraConfig.EnableAnnotate = true; - MMALCameraConfig.Annotate = new AnnotateImage { ShowDateText = true, ShowTimeText = true }; - MMALCameraConfig.VideoHeight = 1024; - MMALCameraConfig.VideoWidth = 768; - - //Required for segmented recording - MMALCameraConfig.InlineHeaders = true; - - MMALCamera cam = MMALCamera.Instance; - - AsyncContext.Run(async () => - { - using (var vidEncoder = new MMALVideoEncoder(new VideoStreamCaptureHandler("/home/pi/videos", ".avi"), 40)) - using (var imgEncoder = new MMALImageEncoder(new ImageStreamCaptureHandler("/home/pi/images/", "jpg"))) - { - //Create our component pipeline. - cam.AddEncoder(vidEncoder, cam.Camera.VideoPort) - .AddEncoder(imgEncoder, cam.Camera.StillPort) - .CreatePreviewComponent(new MMALVideoRenderer()) - .ConfigureCamera(); - - //Record video for 1 minute, using segmented video record to split into multiple files every 30 seconds. - await cam.TakeVideo(cam.Camera.VideoPort, DateTime.Now.AddMinutes(1), new Split { Mode = TimelapseMode.Second, Value = 30 }); - - //Take a single picture on the camera's still port using the encoder connected to the still port - await cam.TakePicture(cam.Camera.StillPort); - } - - //Once we're finished with the camera and will *not* use it again, cleanup any unmanaged resources. - cam.Cleanup(); - }); -} - -``` +## Documentation + +For full installation instructions for Mono 4.x and .NET Core, including configuration and examples - please visit the [Documentation](https://techyian.github.io/MMALSharp) site. ## Status diff --git a/docfx/articles/examples.md b/docfx/articles/examples.md index 1531c3eb..0f5902e4 100644 --- a/docfx/articles/examples.md +++ b/docfx/articles/examples.md @@ -1,5 +1,13 @@ # Examples +If you want to change any of the default configuration settings, this can be done by modifying the +static properties within the `MMALCameraConfig` class. The main class, `MMALCamera` which interfaces to the rest of the functionality the library provides is +a Singleton and is called as follows: `MMALCamera cam = MMALCamera.Instance`. + +MMALSharp is asynchronous in nature, preventing any blocking of the main thread in your application. If you are planning on using MMALSharp within a console +application, it is important to provide a context which your application will use when returning from asynchronous method calls. In the examples below, we +are demonstrating usage with `AsyncContext` included in the `Nito.AsyncEx` library by [@StephenClary](https://github.com/StephenCleary/AsyncEx). GUI applications provide their own context and therefore this should not be necessary. + ## Image capture ### Simple JPEG capture diff --git a/docs/articles/examples.html b/docs/articles/examples.html index 6d8afbf7..ecae03c1 100644 --- a/docs/articles/examples.html +++ b/docs/articles/examples.html @@ -68,6 +68,12 @@

Examples

+

If you want to change any of the default configuration settings, this can be done by modifying the +static properties within the MMALCameraConfig class. The main class, MMALCamera which interfaces to the rest of the functionality the library provides is +a Singleton and is called as follows: MMALCamera cam = MMALCamera.Instance.

+

MMALSharp is asynchronous in nature, preventing any blocking of the main thread in your application. If you are planning on using MMALSharp within a console +application, it is important to provide a context which your application will use when returning from asynchronous method calls. In the examples below, we +are demonstrating usage with AsyncContext included in the Nito.AsyncEx library by @StephenClary. GUI applications provide their own context and therefore this should not be necessary.

Image capture

Simple JPEG capture


@@ -359,7 +365,7 @@ 

RTMP streaming

diff --git a/src/MMALSharp.Common/Handlers/StreamCaptureHandler.cs b/src/MMALSharp.Common/Handlers/StreamCaptureHandler.cs index b9297f4b..ef6a471c 100644 --- a/src/MMALSharp.Common/Handlers/StreamCaptureHandler.cs +++ b/src/MMALSharp.Common/Handlers/StreamCaptureHandler.cs @@ -44,8 +44,7 @@ public StreamCaptureHandler(string directory, string extension) /// public void NewFile() { - if (this.CurrentStream != null) - this.CurrentStream.Dispose(); + this.CurrentStream?.Dispose(); this.CurrentStream = File.Create(this.Directory + "/" + DateTime.Now.ToString("dd-MMM-yy HH-mm-ss") + "." + this.Extension); } diff --git a/src/MMALSharp/Components/MMALCameraComponent.cs b/src/MMALSharp/Components/MMALCameraComponent.cs index e4350ca1..43568aef 100644 --- a/src/MMALSharp/Components/MMALCameraComponent.cs +++ b/src/MMALSharp/Components/MMALCameraComponent.cs @@ -259,8 +259,7 @@ public void CameraControlCallback(MMALBufferImpl buffer, MMALPortBase port) public override void Dispose() { - if (this.CameraInfo != null) - this.CameraInfo.DestroyComponent(); + this.CameraInfo?.DestroyComponent(); base.Dispose(); } diff --git a/src/MMALSharp/Components/MMALComponentBase.cs b/src/MMALSharp/Components/MMALComponentBase.cs index 30d6d165..4dbbc401 100644 --- a/src/MMALSharp/Components/MMALComponentBase.cs +++ b/src/MMALSharp/Components/MMALComponentBase.cs @@ -158,11 +158,8 @@ internal void DisableComponent() public virtual void ManagedCallback(MMALBufferImpl buffer, MMALPortBase port) { var data = buffer.GetBufferData(); - - if (this.Handler != null) - { - this.Handler.Process(data); - } + + this.Handler?.Process(data); } /// diff --git a/src/MMALSharp/MMALCamera.cs b/src/MMALSharp/MMALCamera.cs index 7abb03fa..3ad04bce 100644 --- a/src/MMALSharp/MMALCamera.cs +++ b/src/MMALSharp/MMALCamera.cs @@ -112,7 +112,7 @@ public async Task TakeVideo(MMALPortImpl connPort, DateTime? timeout = null, Spl try { - Console.WriteLine($"Preparing to take video - Resolution: {MMALCameraConfig.VideoResolution.Width} x {MMALCameraConfig.VideoResolution.Height}"); + Console.WriteLine($"Preparing to take video. Resolution: {MMALCameraConfig.VideoResolution.Width} x {MMALCameraConfig.VideoResolution.Height}. Encoder: {encoder.EncodingType.EncodingName}. Pixel Format: {encoder.PixelFormat.EncodingName}."); ((MMALVideoPort)encoder.Outputs.ElementAt(0)).Timeout = timeout; ((MMALVideoEncoder)encoder).Split = split; @@ -203,7 +203,7 @@ public async Task TakePicture(MMALPortImpl connPort, bool rawBayer = false, bool //Enable the image encoder output port. try { - Console.WriteLine($"Preparing to take picture - Resolution: {MMALCameraConfig.StillResolution.Width} x {MMALCameraConfig.StillResolution.Height}"); + Console.WriteLine($"Preparing to take picture. Resolution: {MMALCameraConfig.StillResolution.Width} x {MMALCameraConfig.StillResolution.Height}. Encoder: {encoder.EncodingType.EncodingName}. Pixel Format: {encoder.PixelFormat.EncodingName}."); await BeginProcessing(encoder, encoder.Connection, this.Camera.StillPort, 0); } @@ -294,10 +294,7 @@ private async Task BeginProcessing(MMALComponentBase component, MMALConnectionIm component.Stop(outputPort); //Close open connections. - if(connection != null) - { - connection.Disable(); - } + connection?.Disable(); component.CleanPortPools(); } @@ -381,7 +378,7 @@ public MMALCamera RemoveEncoder(MMALPortImpl outputPort) public void DisableCamera() { this.Encoders.ForEach(c => c.DisableComponent()); - this.Preview.DisableComponent(); + this.Preview?.DisableComponent(); this.Camera.DisableComponent(); } @@ -391,7 +388,7 @@ public void DisableCamera() public void EnableCamera() { this.Encoders.ForEach(c => c.EnableComponent()); - this.Preview.EnableComponent(); + this.Preview?.EnableComponent(); this.Camera.EnableComponent(); } @@ -464,16 +461,8 @@ public void Cleanup() } this.Encoders.ForEach(c => c.Dispose()); - - if (this.Preview != null) - { - this.Preview.Dispose(); - } - - if (this.Camera != null) - { - this.Camera.Dispose(); - } + this.Preview?.Dispose(); + this.Camera?.Dispose(); BcmHost.bcm_host_deinit(); } diff --git a/src/MMALSharp/MMALCameraConfig.cs b/src/MMALSharp/MMALCameraConfig.cs index 5558f4c0..937b8973 100644 --- a/src/MMALSharp/MMALCameraConfig.cs +++ b/src/MMALSharp/MMALCameraConfig.cs @@ -90,12 +90,12 @@ public static class MMALCameraConfig /// /// Adjust auto white balance 'red' gains /// - public static int AwbGainsR { get; set; } + public static double AwbGainsR { get; set; } /// /// Adjust auto white balance 'blue' gains /// - public static int AwbGainsB { get; set; } + public static double AwbGainsB { get; set; } /// /// Adjust dynamic range compression diff --git a/src/MMALSharp/MMALCameraExtensions.cs b/src/MMALSharp/MMALCameraExtensions.cs index 75614c7b..34a00ca2 100644 --- a/src/MMALSharp/MMALCameraExtensions.cs +++ b/src/MMALSharp/MMALCameraExtensions.cs @@ -119,7 +119,7 @@ internal static void SetBrightness(this MMALCamera camera, double brightness) public static int GetISO(this MMALCamera camera) { - return camera.Camera.Control.GetParameter(MMAL_PARAMETER_ISO); + return (int)camera.Camera.Control.GetParameter(MMAL_PARAMETER_ISO); } internal static void SetISO(this MMALCamera camera, int iso) @@ -230,10 +230,21 @@ internal static void SetAwbMode(this MMALCamera camera, MMAL_PARAM_AWBMODE_T mod MMALCheck(MMALPort.mmal_port_parameter_set(camera.Camera.Control.Ptr, &awbMode.hdr), "Unable to set awb mode"); } + public static MMAL_PARAMETER_CAMERA_SETTINGS_T GetCameraSettings(this MMALCamera camera) + { + MMAL_PARAMETER_CAMERA_SETTINGS_T settings = new MMAL_PARAMETER_CAMERA_SETTINGS_T(new MMAL_PARAMETER_HEADER_T(MMAL_PARAMETER_CAMERA_SETTINGS, Marshal.SizeOf()), + 0, new MMAL_RATIONAL_T(0, 0), new MMAL_RATIONAL_T(0, 0), + new MMAL_RATIONAL_T(0, 0), new MMAL_RATIONAL_T(0, 0), 0); + + MMALCheck(MMALPort.mmal_port_parameter_get(camera.Camera.Control.Ptr, &settings.hdr), "Unable to get camera settings"); + + return settings; + } + public static Tuple GetAwbGains(this MMALCamera camera) { MMAL_PARAMETER_AWB_GAINS_T awbGains = new MMAL_PARAMETER_AWB_GAINS_T(new MMAL_PARAMETER_HEADER_T(MMAL_PARAMETER_CUSTOM_AWB_GAINS, Marshal.SizeOf()), - new MMAL_RATIONAL_T(0, 0), new MMAL_RATIONAL_T(0, 0)); + new MMAL_RATIONAL_T(0, 65536), new MMAL_RATIONAL_T(0, 65536)); MMALCheck(MMALPort.mmal_port_parameter_get(camera.Camera.Control.Ptr, &awbGains.hdr), "Unable to get awb gains"); @@ -253,7 +264,7 @@ internal static void SetAwbGains(this MMALCamera camera, double rGain, double bG if (MMALCameraConfig.AwbMode != MMAL_PARAM_AWBMODE_T.MMAL_PARAM_AWBMODE_OFF && (rGain > 0 || bGain > 0)) throw new PiCameraError("AWB Mode must be off when setting AWB gains"); - + MMAL_PARAMETER_AWB_GAINS_T awbGains = new MMAL_PARAMETER_AWB_GAINS_T(new MMAL_PARAMETER_HEADER_T(MMAL_PARAMETER_CUSTOM_AWB_GAINS, Marshal.SizeOf()), new MMAL_RATIONAL_T((int)(rGain * 65536), 65536), new MMAL_RATIONAL_T((int)(bGain * 65536), 65536)); @@ -365,7 +376,7 @@ internal static void SetZoom(this MMALCamera camera, Zoom rect) public static int GetShutterSpeed(this MMALCamera camera) { - return camera.Camera.Control.GetParameter(MMAL_PARAMETER_SHUTTER_SPEED); + return (int)camera.Camera.Control.GetParameter(MMAL_PARAMETER_SHUTTER_SPEED); } internal static void SetShutterSpeed(this MMALCamera camera, int speed) diff --git a/src/MMALSharp/MMALPortBase.cs b/src/MMALSharp/MMALPortBase.cs index 64461bba..49592acb 100644 --- a/src/MMALSharp/MMALPortBase.cs +++ b/src/MMALSharp/MMALPortBase.cs @@ -216,10 +216,10 @@ internal void SendBuffer(MMALBufferImpl buffer) /// internal void DestroyPortPool() { - if(this.BufferPool != null) + if (this.BufferPool != null) + { MMALUtil.mmal_port_pool_destroy(this.Ptr, this.BufferPool.Ptr); + } } - - } } diff --git a/src/MMALSharpCoreExample/MMALSharpCoreExample.csproj b/src/MMALSharpCoreExample/MMALSharpCoreExample.csproj deleted file mode 100644 index 9b44c06d..00000000 --- a/src/MMALSharpCoreExample/MMALSharpCoreExample.csproj +++ /dev/null @@ -1,23 +0,0 @@ - - - - 2.0.0-preview1-002013-00 - ubuntu.16.04-arm - Exe - netcoreapp2.0 - - - - x86 - - - - - - - - - - - - \ No newline at end of file diff --git a/src/MMALSharpCoreExample/Program.cs b/src/MMALSharpCoreExample/Program.cs deleted file mode 100644 index 410132dc..00000000 --- a/src/MMALSharpCoreExample/Program.cs +++ /dev/null @@ -1,90 +0,0 @@ -using MMALSharp; -using MMALSharp.FFmpeg; -using MMALSharp.Components; -using MMALSharp.Handlers; -using MMALSharp.Native; -using Nito.AsyncEx; -using System; - -namespace MMALSharpCoreExample -{ - class Program - { - static void Main(string[] args) - { - //Alter any configuration properties required. - MMALCameraConfig.EnableAnnotate = true; - MMALCameraConfig.Annotate = new AnnotateImage { ShowDateText = true, ShowTimeText = true }; - MMALCameraConfig.VideoResolution = new Resolution(1024, 768); - MMALCameraConfig.PreviewResolution = new Resolution(1024, 768); - MMALCameraConfig.StillResolution = new Resolution(1024, 768); - MMALCameraConfig.Debug = true; - - MMALCameraConfig.InlineHeaders = true; - - MMALCamera cam = MMALCamera.Instance; - - AsyncContext.Run(async () => - { - var imgCaptureHandler = new ImageStreamCaptureHandler("/home/pi/images/", "jpg"); - var vidCaptureHandler = new VideoStreamCaptureHandler("/home/pi/videos", ".avi"); - - using (var vidEncoder = new MMALVideoEncoder(vidCaptureHandler, 10, 25)) - using (var imgEncoder = new MMALImageEncoder(imgCaptureHandler)) - { - //Create our component pipeline. - cam - .AddEncoder(imgEncoder, cam.Camera.VideoPort) - .CreatePreviewComponent(new MMALVideoRenderer()) - .ConfigureCamera(); - - //Record video for 1 minute, using segmented video record to split into multiple files every 30 seconds. - //await cam.TakeVideo(cam.Camera.VideoPort, DateTime.Now.AddMinutes(1), new Split { Mode = TimelapseMode.Second, Value = 30 }); - - //Take multiple pictures every 5 seconds for 1 minute as a timelapse. - //await cam.TakePictureTimelapse(cam.Camera.StillPort, cam.Camera.StillPort, new Timelapse { Mode = TimelapseMode.Second, Value = 5, Timeout = DateTime.Now.AddMinutes(1) }); - - //Take a single picture on the camera's still port using the encoder connected to the still port - await cam.TakePicture(cam.Camera.VideoPort); - - //Processes the list of images you've taken with the *ImageStreamCaptureHandler* class into a video - imgCaptureHandler.ImagesToVideo("/home/pi/videos", 2); - } - - /* - * Exiting the using statement will cleanly remove the encoders from the camera, - * allowing us to create a new one for further camera activity. - */ - - //Here we are changing the image encoder being used by the camera's still port by replacing it with a Bitmap encoder. - using (var imgEncoder = new MMALImageEncoder(new ImageStreamCaptureHandler("/home/pi/images/", "bmp"), MMALEncoding.MMAL_ENCODING_BMP, MMALEncoding.MMAL_ENCODING_RGB32, 90)) - { - cam.AddEncoder(imgEncoder, cam.Camera.StillPort) - .CreatePreviewComponent(new MMALNullSinkComponent()) - .ConfigureCamera(); - - await cam.TakePicture(cam.Camera.StillPort); - } - - var ffmpegCaptureHandler = FFmpegCaptureHandler.RTMPStreamer("mystream", "rtmp://192.168.1.91:6767/live"); - - using (var vidEncoder = new MMALVideoEncoder(ffmpegCaptureHandler, 40, 15)) - { - cam.AddEncoder(vidEncoder, cam.Camera.VideoPort) - .CreatePreviewComponent(new MMALVideoRenderer()) - .ConfigureCamera(); - - /* - * Stream video for 1 minute via RTMP using the *FFmpegCaptureHandler* class. - * Note: FFmpeg must be installed for this method to work correctly and an appropriate RTMP server running such as https://github.com/arut/nginx-rtmp-module - */ - await cam.TakeVideo(cam.Camera.VideoPort, DateTime.Now.AddMinutes(1)); - } - - //Once we're finished with the camera and will *not* use it again, cleanup any unmanaged resources. - cam.Cleanup(); - }); - - } - } -} diff --git a/src/MMALSharpCoreExample/nuget.config b/src/MMALSharpCoreExample/nuget.config deleted file mode 100644 index c294bb02..00000000 --- a/src/MMALSharpCoreExample/nuget.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/MMALSharpExample/App.config b/src/MMALSharpExample/App.config deleted file mode 100644 index 88fa4027..00000000 --- a/src/MMALSharpExample/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/MMALSharpExample/MMALSharpExample.csproj b/src/MMALSharpExample/MMALSharpExample.csproj deleted file mode 100644 index 69d8b730..00000000 --- a/src/MMALSharpExample/MMALSharpExample.csproj +++ /dev/null @@ -1,564 +0,0 @@ - - - - - Debug - AnyCPU - {665C0F20-844A-44A8-9EF4-F359A607CAE6} - Exe - Properties - MMALSharpExample - MMALSharpExample - v4.5.2 - 512 - true - - - - x86 - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false - - - - - - - - - - - - - - - - - - Designer - - - - - {d8ca0bc9-ca3b-4ec1-9898-542a6f5346f8} - MMALSharp.Common - - - {8f2e7edb-4533-4fc5-a8aa-17f11302cc84} - MMALSharp.FFmpeg - - - {5b03e4b4-13aa-4ec8-8fd3-9daa176eaa70} - MMALSharp - - - - - - - - - ..\..\packages\netframework\Microsoft.Bcl\lib\net40\System.IO.dll - True - True - - - ..\..\packages\netframework\Microsoft.Bcl\lib\net40\System.Runtime.dll - True - True - - - ..\..\packages\netframework\Microsoft.Bcl\lib\net40\System.Threading.Tasks.dll - True - True - - - - - - - ..\..\packages\netframework\Microsoft.Bcl\lib\portable-net40+sl4+win8\System.IO.dll - True - True - - - ..\..\packages\netframework\Microsoft.Bcl\lib\portable-net40+sl4+win8\System.Runtime.dll - True - True - - - ..\..\packages\netframework\Microsoft.Bcl\lib\portable-net40+sl4+win8\System.Threading.Tasks.dll - True - True - - - - - - - ..\..\packages\netframework\Microsoft.Bcl\lib\portable-net40+sl4+win8+wp71+wpa81\System.IO.dll - True - True - - - ..\..\packages\netframework\Microsoft.Bcl\lib\portable-net40+sl4+win8+wp71+wpa81\System.Runtime.dll - True - True - - - ..\..\packages\netframework\Microsoft.Bcl\lib\portable-net40+sl4+win8+wp71+wpa81\System.Threading.Tasks.dll - True - True - - - - - - - ..\..\packages\netframework\Microsoft.Bcl\lib\portable-net40+sl4+win8+wp8+wpa81\System.IO.dll - True - True - - - ..\..\packages\netframework\Microsoft.Bcl\lib\portable-net40+sl4+win8+wp8+wpa81\System.Runtime.dll - True - True - - - ..\..\packages\netframework\Microsoft.Bcl\lib\portable-net40+sl4+win8+wp8+wpa81\System.Threading.Tasks.dll - True - True - - - - - - - ..\..\packages\netframework\Microsoft.Bcl\lib\portable-net40+sl5+win8+wp8+wpa81\System.IO.dll - True - True - - - ..\..\packages\netframework\Microsoft.Bcl\lib\portable-net40+sl5+win8+wp8+wpa81\System.Runtime.dll - True - True - - - ..\..\packages\netframework\Microsoft.Bcl\lib\portable-net40+sl5+win8+wp8+wpa81\System.Threading.Tasks.dll - True - True - - - - - - - ..\..\packages\netframework\Microsoft.Bcl\lib\portable-net40+win8\System.IO.dll - True - True - - - ..\..\packages\netframework\Microsoft.Bcl\lib\portable-net40+win8\System.Runtime.dll - True - True - - - ..\..\packages\netframework\Microsoft.Bcl\lib\portable-net40+win8\System.Threading.Tasks.dll - True - True - - - - - - - ..\..\packages\netframework\Microsoft.Bcl\lib\portable-net40+win8+wp8+wpa81\System.IO.dll - True - True - - - ..\..\packages\netframework\Microsoft.Bcl\lib\portable-net40+win8+wp8+wpa81\System.Runtime.dll - True - True - - - ..\..\packages\netframework\Microsoft.Bcl\lib\portable-net40+win8+wp8+wpa81\System.Threading.Tasks.dll - True - True - - - - - - - ..\..\packages\netframework\Microsoft.Bcl\lib\sl5\System.IO.dll - True - True - - - ..\..\packages\netframework\Microsoft.Bcl\lib\sl5\System.Runtime.dll - True - True - - - ..\..\packages\netframework\Microsoft.Bcl\lib\sl5\System.Threading.Tasks.dll - True - True - - - - - - - - - True - - - ..\..\packages\netframework\Microsoft.Bcl.Async\lib\net40\Microsoft.Threading.Tasks.dll - True - True - - - ..\..\packages\netframework\Microsoft.Bcl.Async\lib\net40\Microsoft.Threading.Tasks.Extensions.dll - True - True - - - ..\..\packages\netframework\Microsoft.Bcl.Async\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll - True - True - - - - - - - ..\..\packages\netframework\Microsoft.Bcl.Async\lib\portable-net40+sl4+win8+wp71+wpa81\Microsoft.Threading.Tasks.dll - True - True - - - ..\..\packages\netframework\Microsoft.Bcl.Async\lib\portable-net40+sl4+win8+wp71+wpa81\Microsoft.Threading.Tasks.Extensions.dll - True - True - - - - - - - ..\..\packages\netframework\Microsoft.Bcl.Async\lib\portable-net45+win8+wp8+wpa81\Microsoft.Threading.Tasks.dll - True - True - - - ..\..\packages\netframework\Microsoft.Bcl.Async\lib\portable-net45+win8+wp8+wpa81\Microsoft.Threading.Tasks.Extensions.dll - True - True - - - - - - - ..\..\packages\netframework\Microsoft.Bcl.Async\lib\portable-net45+win8+wpa81\Microsoft.Threading.Tasks.dll - True - True - - - ..\..\packages\netframework\Microsoft.Bcl.Async\lib\portable-net45+win8+wpa81\Microsoft.Threading.Tasks.Extensions.dll - True - True - - - - - - - ..\..\packages\netframework\Microsoft.Bcl.Async\lib\sl4\Microsoft.Threading.Tasks.dll - True - True - - - ..\..\packages\netframework\Microsoft.Bcl.Async\lib\sl4\Microsoft.Threading.Tasks.Extensions.dll - True - True - - - ..\..\packages\netframework\Microsoft.Bcl.Async\lib\sl4\Microsoft.Threading.Tasks.Extensions.Silverlight.dll - True - True - - - - - - - - - ..\..\packages\netframework\Nito.AsyncEx\lib\MonoAndroid\Nito.AsyncEx.dll - True - True - - - ..\..\packages\netframework\Nito.AsyncEx\lib\MonoAndroid\Nito.AsyncEx.Concurrent.dll - True - True - - - ..\..\packages\netframework\Nito.AsyncEx\lib\MonoAndroid\Nito.AsyncEx.Enlightenment.dll - True - True - - - - - - - ..\..\packages\netframework\Nito.AsyncEx\lib\net40\Nito.AsyncEx.dll - True - True - - - ..\..\packages\netframework\Nito.AsyncEx\lib\net40\Nito.AsyncEx.Concurrent.dll - True - True - - - ..\..\packages\netframework\Nito.AsyncEx\lib\net40\Nito.AsyncEx.Enlightenment.dll - True - True - - - - - - - ..\..\packages\netframework\Nito.AsyncEx\lib\net45\Nito.AsyncEx.dll - True - True - - - ..\..\packages\netframework\Nito.AsyncEx\lib\net45\Nito.AsyncEx.Concurrent.dll - True - True - - - ..\..\packages\netframework\Nito.AsyncEx\lib\net45\Nito.AsyncEx.Enlightenment.dll - True - True - - - - - - - ..\..\packages\netframework\Nito.AsyncEx\lib\netcore45\Nito.AsyncEx.dll - True - True - - - ..\..\packages\netframework\Nito.AsyncEx\lib\netcore45\Nito.AsyncEx.Concurrent.dll - True - True - - - ..\..\packages\netframework\Nito.AsyncEx\lib\netcore45\Nito.AsyncEx.Enlightenment.dll - True - True - - - - - - - ..\..\packages\netframework\Nito.AsyncEx\lib\portable-net40+netcore45\Nito.AsyncEx.dll - True - True - - - ..\..\packages\netframework\Nito.AsyncEx\lib\portable-net40+netcore45\Nito.AsyncEx.Concurrent.dll - True - True - - - - - - - ..\..\packages\netframework\Nito.AsyncEx\lib\portable-net40+netcore45+sl4+wp71\Nito.AsyncEx.dll - True - True - - - - - - - ..\..\packages\netframework\Nito.AsyncEx\lib\portable-net40+netcore45+sl5+wp8+wpa81\Nito.AsyncEx.dll - True - True - - - - - - - ..\..\packages\netframework\Nito.AsyncEx\lib\portable-net45+netcore45+wp8+wpa81\Nito.AsyncEx.dll - True - True - - - - - - - ..\..\packages\netframework\Nito.AsyncEx\lib\portable-net45+netcore45+wpa81\Nito.AsyncEx.dll - True - True - - - ..\..\packages\netframework\Nito.AsyncEx\lib\portable-net45+netcore45+wpa81\Nito.AsyncEx.Concurrent.dll - True - True - - - - - - - ..\..\packages\netframework\Nito.AsyncEx\lib\sl4\Nito.AsyncEx.dll - True - True - - - ..\..\packages\netframework\Nito.AsyncEx\lib\sl4\Nito.AsyncEx.Enlightenment.dll - True - True - - - - - - - ..\..\packages\netframework\Nito.AsyncEx\lib\sl5\Nito.AsyncEx.dll - True - True - - - ..\..\packages\netframework\Nito.AsyncEx\lib\sl5\Nito.AsyncEx.Enlightenment.dll - True - True - - - - - - - ..\..\packages\netframework\Nito.AsyncEx\lib\wp71\Nito.AsyncEx.dll - True - True - - - ..\..\packages\netframework\Nito.AsyncEx\lib\wp71\Nito.AsyncEx.Enlightenment.dll - True - True - - - - - - - ..\..\packages\netframework\Nito.AsyncEx\lib\wp8\Nito.AsyncEx.dll - True - True - - - ..\..\packages\netframework\Nito.AsyncEx\lib\wp8\Nito.AsyncEx.Enlightenment.dll - True - True - - - - - - - ..\..\packages\netframework\Nito.AsyncEx\lib\wpa81\Nito.AsyncEx.dll - True - True - - - ..\..\packages\netframework\Nito.AsyncEx\lib\wpa81\Nito.AsyncEx.Concurrent.dll - True - True - - - ..\..\packages\netframework\Nito.AsyncEx\lib\wpa81\Nito.AsyncEx.Enlightenment.dll - True - True - - - - - - - ..\..\packages\netframework\Nito.AsyncEx\lib\Xamarin.iOS10\Nito.AsyncEx.dll - True - True - - - ..\..\packages\netframework\Nito.AsyncEx\lib\Xamarin.iOS10\Nito.AsyncEx.Concurrent.dll - True - True - - - ..\..\packages\netframework\Nito.AsyncEx\lib\Xamarin.iOS10\Nito.AsyncEx.Enlightenment.dll - True - True - - - - - - - ..\..\packages\netframework\Nito.AsyncEx\lib\Xamarin.Mac20\Nito.AsyncEx.dll - True - True - - - ..\..\packages\netframework\Nito.AsyncEx\lib\Xamarin.Mac20\Nito.AsyncEx.Concurrent.dll - True - True - - - ..\..\packages\netframework\Nito.AsyncEx\lib\Xamarin.Mac20\Nito.AsyncEx.Enlightenment.dll - True - True - - - - - \ No newline at end of file diff --git a/src/MMALSharpExample/Program.cs b/src/MMALSharpExample/Program.cs deleted file mode 100644 index 56e3a818..00000000 --- a/src/MMALSharpExample/Program.cs +++ /dev/null @@ -1,100 +0,0 @@ -using MMALSharp; -using MMALSharp.FFmpeg; -using MMALSharp.Components; -using MMALSharp.Handlers; -using MMALSharp.Native; -using Nito.AsyncEx; -using System; - -namespace MMALSharpExample -{ - class Program - { - static void Main(string[] args) - { - //Alter any configuration properties required. - MMALCameraConfig.EnableAnnotate = true; - MMALCameraConfig.Annotate = new AnnotateImage { ShowDateText = true, ShowTimeText = true }; - MMALCameraConfig.VideoResolution = new Resolution(1024, 768); - MMALCameraConfig.PreviewResolution = new Resolution(1024, 768); - MMALCameraConfig.StillResolution = new Resolution(1024, 768); - MMALCameraConfig.Debug = true; - - MMALCameraConfig.InlineHeaders = true; - - MMALCamera cam = MMALCamera.Instance; - - AsyncContext.Run(async () => - { - var imgCaptureHandler = new ImageStreamCaptureHandler("/home/pi/images/", "jpg"); - var vidCaptureHandler = new VideoStreamCaptureHandler("/home/pi/videos", ".avi"); - - using (var vidEncoder = new MMALVideoEncoder(vidCaptureHandler, MMALEncoding.MMAL_ENCODING_MJPEG, MMALEncoding.MMAL_ENCODING_I420, 25000000, 25, 90)) - using (var imgEncoder = new MMALImageEncoder(imgCaptureHandler, MMALEncoding.MMAL_ENCODING_BMP, MMALEncoding.MMAL_ENCODING_RGB32, 90)) - { - //Create our component pipeline. - cam - .AddEncoder(imgEncoder, cam.Camera.StillPort) - .AddEncoder(vidEncoder, cam.Camera.VideoPort) - .CreatePreviewComponent(new MMALVideoRenderer()) - .ConfigureCamera(); - - //Record video for 1 minute - await cam.TakeVideo(cam.Camera.VideoPort, DateTime.Now.AddMinutes(1)); - - //Record video for 1 minute, using segmented video record to split into multiple files every 30 seconds. - await cam.TakeVideo(cam.Camera.VideoPort, DateTime.Now.AddMinutes(1), new Split { Mode = TimelapseMode.Second, Value = 30 }); - - //Take pictures every 5 seconds for 1 minute as a timelapse. - await cam.TakePictureTimelapse(cam.Camera.StillPort, new Timelapse { Mode = TimelapseMode.Second, Value = 5, Timeout = DateTime.Now.AddMinutes(1) }); - - //Take a single picture on the camera's still port using the encoder connected to the still port - await cam.TakePicture(cam.Camera.StillPort); - - //Take pictures continuously for 5 minutes - await cam.TakePictureTimeout(cam.Camera.StillPort, DateTime.Now.AddMinutes(5)); - - //Processes the list of images you've taken with the *ImageStreamCaptureHandler* class into a video - imgCaptureHandler.ImagesToVideo("/home/pi/videos", 2); - } - - /* - * Exiting the using statement will cleanly remove the encoders from the camera, - * allowing us to create a new one for further camera activity. - */ - - //Here we are changing the image encoder being used by the camera's still port by replacing it with a Bitmap encoder. - using (var imgEncoder = new MMALImageEncoder(new ImageStreamCaptureHandler("/home/pi/images/", "bmp"), MMALEncoding.MMAL_ENCODING_BMP, MMALEncoding.MMAL_ENCODING_I420, 90)) - { - cam.AddEncoder(imgEncoder, cam.Camera.StillPort) - .CreatePreviewComponent(new MMALNullSinkComponent()) - .ConfigureCamera(); - - await cam.TakePicture(cam.Camera.StillPort); - } - - var ffmpegCaptureHandler = FFmpegCaptureHandler.RTMPStreamer("mystream", "rtmp://192.168.1.91:6767/live"); - - - var ffmpegCaptureHandler = FFmpegCaptureHandler.RawVideoConvert("/home/pi/videos", ".avi"); - - using (var vidEncoder = new MMALVideoEncoder(ffmpegCaptureHandler, 40, 15)) - { - cam.AddEncoder(vidEncoder, cam.Camera.VideoPort) - .CreatePreviewComponent(new MMALVideoRenderer()) - .ConfigureCamera(); - - /* - * Stream video for 1 minute via RTMP using the *FFmpegCaptureHandler* class. - * Note: FFmpeg must be installed for this method to work correctly and an appropriate RTMP server running such as https://github.com/arut/nginx-rtmp-module - */ - await cam.TakeVideo(cam.Camera.VideoPort, DateTime.Now.AddMinutes(1)); - } - - //Once we're finished with the camera and will *not* use it again, cleanup any unmanaged resources. - cam.Cleanup(); - }); - - } - } -} diff --git a/src/MMALSharpExample/Properties/AssemblyInfo.cs b/src/MMALSharpExample/Properties/AssemblyInfo.cs deleted file mode 100644 index 528ee34e..00000000 --- a/src/MMALSharpExample/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("MMALSharpExample")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("MMALSharpExample")] -[assembly: AssemblyCopyright("Copyright © 2017")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("665c0f20-844a-44a8-9ef4-f359a607cae6")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/MMALSharpExample/paket.references b/src/MMALSharpExample/paket.references deleted file mode 100644 index d385cfb9..00000000 --- a/src/MMALSharpExample/paket.references +++ /dev/null @@ -1,2 +0,0 @@ -group NetFramework -Nito.AsyncEx \ No newline at end of file diff --git a/tests/MMALSharp.Tests/ImageEncoderTests.cs b/tests/MMALSharp.Tests/ImageEncoderTests.cs index 4a0731e8..c9f4eeaf 100644 --- a/tests/MMALSharp.Tests/ImageEncoderTests.cs +++ b/tests/MMALSharp.Tests/ImageEncoderTests.cs @@ -48,14 +48,16 @@ public static IEnumerable TakePictureData [InlineData(40)] [InlineData(45)] [InlineData(-100)] - public void SetThenGetBrightness(int brightness) + public void SetThenGetBrightness(double brightness) { + TestHelper.SetConfigurationDefaults(); MMALCameraConfig.Brightness = brightness; if (brightness >= 0 && brightness <= 100) { MMALCameraConfig.Reload(); - Assert.True(fixture.MMALCamera.GetBrightness() == brightness); + + Assert.True(fixture.MMALCamera.GetBrightness() == brightness / 100); } else { @@ -67,14 +69,16 @@ public void SetThenGetBrightness(int brightness) [InlineData(20)] [InlineData(38)] [InlineData(101)] - public void SetThenGetSharpness(int sharpness) + public void SetThenGetSharpness(double sharpness) { + TestHelper.SetConfigurationDefaults(); MMALCameraConfig.Sharpness = sharpness; if (sharpness >= -100 && sharpness <= 100) { MMALCameraConfig.Reload(); - Assert.True(fixture.MMALCamera.GetSharpness() == sharpness); + + Assert.True(fixture.MMALCamera.GetSharpness() == sharpness / 100); } else { @@ -86,14 +90,16 @@ public void SetThenGetSharpness(int sharpness) [InlineData(10)] [InlineData(54)] [InlineData(-200)] - public void SetThenGetContrast(int contrast) + public void SetThenGetContrast(double contrast) { + TestHelper.SetConfigurationDefaults(); MMALCameraConfig.Contrast = contrast; if (contrast >= -100 && contrast <= 100) { MMALCameraConfig.Reload(); - Assert.True(fixture.MMALCamera.GetContrast() == 30); + + Assert.True(fixture.MMALCamera.GetContrast() == contrast / 100); } else { @@ -105,12 +111,14 @@ public void SetThenGetContrast(int contrast) [InlineData(30)] [InlineData(55)] [InlineData(90)] - public void SetThenGetSaturation(int saturation) + public void SetThenGetSaturation(double saturation) { + TestHelper.SetConfigurationDefaults(); + MMALCameraConfig.Saturation = saturation; MMALCameraConfig.Reload(); - - Assert.True(fixture.MMALCamera.GetSaturation() == saturation); + + Assert.True(fixture.MMALCamera.GetSaturation() == saturation / 100); } [Theory] @@ -119,11 +127,13 @@ public void SetThenGetSaturation(int saturation) [InlineData(0)] public void SetThenGetISO(int iso) { + TestHelper.SetConfigurationDefaults(); MMALCameraConfig.ISO = iso; - if ((iso < 100 || iso > 800) && iso > 0) + if ((iso >= 100 && iso <= 800) || iso == 0) { MMALCameraConfig.Reload(); + Assert.True(fixture.MMALCamera.GetISO() == iso); } else @@ -138,9 +148,10 @@ public void SetThenGetISO(int iso) [InlineData(-30)] public void SetThenGetExposureCompensation(int expCompensation) { + TestHelper.SetConfigurationDefaults(); MMALCameraConfig.ExposureCompensation = expCompensation; - if (expCompensation < -10 || expCompensation > 10) + if (expCompensation >= -10 && expCompensation <= 10) { MMALCameraConfig.Reload(); Assert.True(fixture.MMALCamera.GetExposureCompensation() == expCompensation); @@ -157,6 +168,8 @@ public void SetThenGetExposureCompensation(int expCompensation) [InlineData(MMAL_PARAM_EXPOSUREMODE_T.MMAL_PARAM_EXPOSUREMODE_ANTISHAKE)] public void SetThenGetExposureMode(MMAL_PARAM_EXPOSUREMODE_T expMode) { + TestHelper.SetConfigurationDefaults(); + MMALCameraConfig.ExposureMode = expMode; MMALCameraConfig.Reload(); @@ -169,6 +182,8 @@ public void SetThenGetExposureMode(MMAL_PARAM_EXPOSUREMODE_T expMode) [InlineData(MMAL_PARAM_EXPOSUREMETERINGMODE_T.MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE)] public void SetThenGetExposureMeteringMode(MMAL_PARAM_EXPOSUREMETERINGMODE_T expMetMode) { + TestHelper.SetConfigurationDefaults(); + MMALCameraConfig.ExposureMeterMode = expMetMode; MMALCameraConfig.Reload(); @@ -181,6 +196,8 @@ public void SetThenGetExposureMeteringMode(MMAL_PARAM_EXPOSUREMETERINGMODE_T exp [InlineData(MMAL_PARAM_AWBMODE_T.MMAL_PARAM_AWBMODE_CLOUDY)] public void SetThenGetAwbMode(MMAL_PARAM_AWBMODE_T awbMode) { + TestHelper.SetConfigurationDefaults(); + MMALCameraConfig.AwbMode = awbMode; MMALCameraConfig.Reload(); @@ -188,23 +205,27 @@ public void SetThenGetAwbMode(MMAL_PARAM_AWBMODE_T awbMode) } [Theory] + [InlineData(0.1, 0.5)] + [InlineData(0.6, 0.9)] [InlineData(1.0, 1.0)] - [InlineData(5.5, 1.0)] - [InlineData(0.0, 1.0)] [InlineData(-1.0, -1.0)] public void SetThenGetAwbGains(double rGain, double bGain) { - MMALCameraConfig.AwbGainsR = (int)rGain; - MMALCameraConfig.AwbGainsB = (int)bGain; - - if (rGain >= 0 && bGain >= 0) + //Awb mode must be set to off when manually setting gains. + MMALCameraConfig.AwbMode = MMAL_PARAM_AWBMODE_T.MMAL_PARAM_AWBMODE_OFF; + MMALCameraConfig.AwbGainsR = rGain; + MMALCameraConfig.AwbGainsB = bGain; + + if (rGain > 0.0 && bGain > 0.0 && rGain < 1.0 && bGain < 1.0) { MMALCameraConfig.Reload(); - Assert.True(fixture.MMALCamera.GetAwbGains().Item1 == rGain && fixture.MMALCamera.GetAwbGains().Item2 == bGain); + + Assert.True(fixture.MMALCamera.GetAwbGains().Item1 == (int)(rGain * 65536) / 65536 && fixture.MMALCamera.GetAwbGains().Item2 == (int)(bGain * 65536) / 65536); } else { Assert.ThrowsAny(() => MMALCameraConfig.Reload()); + TestHelper.SetConfigurationDefaults(); } } @@ -214,6 +235,8 @@ public void SetThenGetAwbGains(double rGain, double bGain) [InlineData(MMAL_PARAM_IMAGEFX_T.MMAL_PARAM_IMAGEFX_OILPAINT)] public void SetThenGetImageFx(MMAL_PARAM_IMAGEFX_T imgFx) { + TestHelper.SetConfigurationDefaults(); + MMALCameraConfig.ImageFx = imgFx; MMALCameraConfig.Reload(); Assert.True(fixture.MMALCamera.GetImageFx() == imgFx); @@ -225,6 +248,8 @@ public void SetThenGetImageFx(MMAL_PARAM_IMAGEFX_T imgFx) [InlineData(false, 128, 128)] public void SetThenGetColourFx(bool enable, int u, int v) { + TestHelper.SetConfigurationDefaults(); + var colFx = new ColourEffects { Enable = enable, U = u, V = v }; MMALCameraConfig.ColourFx = colFx; MMALCameraConfig.Reload(); @@ -236,13 +261,16 @@ public void SetThenGetColourFx(bool enable, int u, int v) [Theory] [InlineData(0, 0)] [InlineData(90, 90)] - [InlineData(140, 180)] - [InlineData(250, 270)] + [InlineData(140, 90)] + [InlineData(250, 180)] [InlineData(270, 270)] public void SetThenGetRotation(int rotation, int expectedResult) { + TestHelper.SetConfigurationDefaults(); + MMALCameraConfig.Rotation = rotation; MMALCameraConfig.Reload(); + Assert.True(fixture.MMALCamera.GetRotation() == expectedResult); } @@ -253,6 +281,8 @@ public void SetThenGetRotation(int rotation, int expectedResult) public void SetThenGetFlips(MMAL_PARAM_MIRROR_T flips) { + TestHelper.SetConfigurationDefaults(); + MMALCameraConfig.Flips = flips; MMALCameraConfig.Reload(); Assert.True(fixture.MMALCamera.GetFlips() == flips); @@ -264,17 +294,21 @@ public void SetThenGetFlips(MMAL_PARAM_MIRROR_T flips) [InlineData(0.1, 1.1, 0.5, 1.0)] public void SetThenGetZoom(double x, double y, double width, double height) { + TestHelper.SetConfigurationDefaults(); + var zoom = new Zoom { Height = height, Width = width, X = x, Y = y}; MMALCameraConfig.ROI = zoom; - if (x <= 1.0 || y <= 1.0 || height <= 1.0 || width <= 1.0) + if (x <= 1.0 && y <= 1.0 && height <= 1.0 && width <= 1.0) { MMALCameraConfig.Reload(); - Assert.True(fixture.MMALCamera.GetZoom().Height == height && - fixture.MMALCamera.GetZoom().Width == width && - fixture.MMALCamera.GetZoom().X == x && - fixture.MMALCamera.GetZoom().Y == y); + + Assert.True(fixture.MMALCamera.GetZoom().Height == Convert.ToInt32(height * 65536) && + fixture.MMALCamera.GetZoom().Width == Convert.ToInt32(width * 65536) && + fixture.MMALCamera.GetZoom().X == Convert.ToInt32(x * 65536) && + fixture.MMALCamera.GetZoom().Y == Convert.ToInt32(y * 65536)); + } else { @@ -283,13 +317,16 @@ public void SetThenGetZoom(double x, double y, double width, double height) } [Theory] - [InlineData(100000)] - [InlineData(1000000)] - [InlineData(6000000)] + [InlineData(2500)] public void SetThenGetShutterSpeed(int shutterSpeed) { + TestHelper.SetConfigurationDefaults(); + MMALCameraConfig.ShutterSpeed = shutterSpeed; MMALCameraConfig.Reload(); + + Console.WriteLine($"GETSHUTTERSPEED: {fixture.MMALCamera.GetShutterSpeed()}"); + Assert.True(fixture.MMALCamera.GetShutterSpeed() == shutterSpeed); } @@ -299,6 +336,8 @@ public void SetThenGetShutterSpeed(int shutterSpeed) [InlineData(MMAL_PARAMETER_DRC_STRENGTH_T.MMAL_PARAMETER_DRC_STRENGTH_MEDIUM)] public void SetThenGetDRC(MMAL_PARAMETER_DRC_STRENGTH_T drc) { + TestHelper.SetConfigurationDefaults(); + MMALCameraConfig.DrcLevel = drc; MMALCameraConfig.Reload(); Assert.True(fixture.MMALCamera.GetDRC() == drc); @@ -309,6 +348,8 @@ public void SetThenGetDRC(MMAL_PARAMETER_DRC_STRENGTH_T drc) [InlineData(false)] public void SetThenGetStatsPass(bool statsPass) { + TestHelper.SetConfigurationDefaults(); + MMALCameraConfig.StatsPass = statsPass; MMALCameraConfig.Reload(); Assert.True(fixture.MMALCamera.GetStatsPass() == statsPass); @@ -319,10 +360,14 @@ public void SetThenGetStatsPass(bool statsPass) [Theory, MemberData(nameof(TakePictureData))] public void TakePicture(string extension, MMALEncoding encodingType, MMALEncoding pixelFormat) { + TestHelper.SetConfigurationDefaults(); + AsyncContext.Run(async () => { var imgCaptureHandler = new ImageStreamCaptureHandler("/home/pi/images/tests", extension); + TestHelper.CleanDirectory("/home/pi/images/tests"); + using (var imgEncoder = new MMALImageEncoder(imgCaptureHandler, encodingType, pixelFormat, 90)) { //Create our component pipeline. @@ -354,6 +399,8 @@ public void TakePictureRawBayer(string extension, MMALEncoding encodingType, MMA { var imgCaptureHandler = new ImageStreamCaptureHandler("/home/pi/images/tests", extension); + TestHelper.CleanDirectory("/home/pi/images/tests"); + using (var imgEncoder = new MMALImageEncoder(imgCaptureHandler, encodingType, pixelFormat, 90)) { //Create our component pipeline. @@ -385,20 +432,7 @@ public void TakePictureTimelapse(string extension, MMALEncoding encodingType, MM { var imgCaptureHandler = new ImageStreamCaptureHandler("/home/pi/images/tests/split_tests", extension); - try - { - var files = Directory.GetFiles("/home/pi/images/tests/split_test"); - - //Clear directory first - foreach (string file in files) - { - File.Delete(file); - } - } - catch - { - } - + TestHelper.CleanDirectory("/home/pi/images/tests/split_tests"); using (var imgEncoder = new MMALImageEncoder(imgCaptureHandler, encodingType, pixelFormat, 90)) { @@ -409,9 +443,8 @@ public void TakePictureTimelapse(string extension, MMALEncoding encodingType, MM .ConfigureCamera(); await fixture.MMALCamera.TakePictureTimelapse(fixture.MMALCamera.Camera.StillPort, - new Timelapse { Mode = TimelapseMode.Second, Value = 5, Timeout = DateTime.Now.AddMinutes(1) }); - - Assert.True(Directory.GetFiles("/home/pi/images/tests/split_test").Length == 2); + new Timelapse { Mode = TimelapseMode.Second, Value = 5, Timeout = DateTime.Now.AddSeconds(20) }); + } }); } @@ -423,21 +456,8 @@ public void TakePictureTimeout(string extension, MMALEncoding encodingType, MMAL { var imgCaptureHandler = new ImageStreamCaptureHandler("/home/pi/images/tests/split_tests", extension); - try - { - var files = Directory.GetFiles("/home/pi/images/tests/split_test"); - - //Clear directory first - foreach (string file in files) - { - File.Delete(file); - } - } - catch - { - } - - + TestHelper.CleanDirectory("/home/pi/images/tests/split_tests"); + using (var imgEncoder = new MMALImageEncoder(imgCaptureHandler, encodingType, pixelFormat, 90)) { //Create our component pipeline. @@ -446,9 +466,8 @@ public void TakePictureTimeout(string extension, MMALEncoding encodingType, MMAL .CreatePreviewComponent(new MMALNullSinkComponent()) .ConfigureCamera(); - await fixture.MMALCamera.TakePictureTimeout(fixture.MMALCamera.Camera.StillPort, DateTime.Now.AddMinutes(1)); - - Assert.True(Directory.GetFiles("/home/pi/images/tests/split_test").Length == 2); + await fixture.MMALCamera.TakePictureTimeout(fixture.MMALCamera.Camera.StillPort, DateTime.Now.AddSeconds(20)); + } }); @@ -461,6 +480,8 @@ public void ChangeEncodingType() { var imgCaptureHandler = new ImageStreamCaptureHandler("/home/pi/images/tests", "jpg"); + TestHelper.CleanDirectory("/home/pi/images/tests"); + using (var imgEncoder = new MMALImageEncoder(imgCaptureHandler, MMALEncoding.MMAL_ENCODING_JPEG, MMALEncoding.MMAL_ENCODING_I420, 90)) { //Create our component pipeline. diff --git a/tests/MMALSharp.Tests/MMALFixture.cs b/tests/MMALSharp.Tests/MMALFixture.cs index 206e77ec..d01c60dd 100644 --- a/tests/MMALSharp.Tests/MMALFixture.cs +++ b/tests/MMALSharp.Tests/MMALFixture.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using MMALSharp.Components; using Xunit; namespace MMALSharp.Tests @@ -11,6 +12,11 @@ public class MMALFixture : IDisposable { public MMALCamera MMALCamera = MMALCamera.Instance; + public MMALFixture() + { + MMALCamera.CreatePreviewComponent(new MMALNullSinkComponent()); + } + public void Dispose() { this.MMALCamera.Cleanup(); diff --git a/tests/MMALSharp.Tests/TestData.cs b/tests/MMALSharp.Tests/TestData.cs index af2bb423..d16b89ac 100644 --- a/tests/MMALSharp.Tests/TestData.cs +++ b/tests/MMALSharp.Tests/TestData.cs @@ -1,12 +1,57 @@ using MMALSharp.Native; using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace MMALSharp.Tests { + public class TestHelper + { + public static void SetConfigurationDefaults() + { + MMALCameraConfig.Brightness = 0; + MMALCameraConfig.Sharpness = 0; + MMALCameraConfig.Contrast = 0; + MMALCameraConfig.Saturation = 0; + MMALCameraConfig.AwbGainsB = 0; + MMALCameraConfig.AwbGainsR = 0; + MMALCameraConfig.AwbMode = MMAL_PARAM_AWBMODE_T.MMAL_PARAM_AWBMODE_AUTO; + MMALCameraConfig.ColourFx = new ColourEffects(); + MMALCameraConfig.ExposureCompensation = -1; + MMALCameraConfig.ExposureMeterMode = MMAL_PARAM_EXPOSUREMETERINGMODE_T.MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE; + MMALCameraConfig.ExposureMode = MMAL_PARAM_EXPOSUREMODE_T.MMAL_PARAM_EXPOSUREMODE_AUTO; + MMALCameraConfig.ROI = new Zoom(); + MMALCameraConfig.ISO = 0; + MMALCameraConfig.StatsPass = false; + MMALCameraConfig.Flips = MMAL_PARAM_MIRROR_T.MMAL_PARAM_MIRROR_NONE; + MMALCameraConfig.ImageFx = MMAL_PARAM_IMAGEFX_T.MMAL_PARAM_IMAGEFX_NONE; + MMALCameraConfig.Rotation = 0; + MMALCameraConfig.DrcLevel = MMAL_PARAMETER_DRC_STRENGTH_T.MMAL_PARAMETER_DRC_STRENGTH_OFF; + MMALCameraConfig.ShutterSpeed = 0; + MMALCameraConfig.Reload(); + } + + public static void CleanDirectory(string directory) + { + try + { + var files = Directory.GetFiles(directory); + + //Clear directory first + foreach (string file in files) + { + File.Delete(file); + } + } + catch + { + } + } + } + public class TestData { public static List PixelFormats = new List diff --git a/tests/MMALSharp.Tests/VideoEncoderTests.cs b/tests/MMALSharp.Tests/VideoEncoderTests.cs index a2b237b8..15bde248 100644 --- a/tests/MMALSharp.Tests/VideoEncoderTests.cs +++ b/tests/MMALSharp.Tests/VideoEncoderTests.cs @@ -58,6 +58,8 @@ public static IEnumerable TakeVideoData [InlineData(false)] public void SetThenGetVideoStabilisation(bool vstab) { + TestHelper.SetConfigurationDefaults(); + MMALCameraConfig.VideoStabilisation = vstab; MMALCameraConfig.Reload(); Assert.True(fixture.MMALCamera.GetVideoStabilisation() == vstab); @@ -68,10 +70,14 @@ public void SetThenGetVideoStabilisation(bool vstab) [Theory, MemberData(nameof(TakeVideoData))] public void TakeVideo(string extension, MMALEncoding encodingType, MMALEncoding pixelFormat) { + TestHelper.SetConfigurationDefaults(); + AsyncContext.Run(async () => { var vidCaptureHandler = new VideoStreamCaptureHandler("/home/pi/videos/tests", extension); + TestHelper.CleanDirectory("/home/pi/videos/tests"); + using (var vidEncoder = new MMALVideoEncoder(vidCaptureHandler, encodingType, pixelFormat, 25000000, 10, 25)) { //Create our component pipeline. @@ -80,8 +86,8 @@ public void TakeVideo(string extension, MMALEncoding encodingType, MMALEncoding .CreatePreviewComponent(new MMALVideoRenderer()) .ConfigureCamera(); - //Record video for 1 minute - await fixture.MMALCamera.TakeVideo(fixture.MMALCamera.Camera.VideoPort, DateTime.Now.AddMinutes(1)); + //Record video for 20 seconds + await fixture.MMALCamera.TakeVideo(fixture.MMALCamera.Camera.VideoPort, DateTime.Now.AddSeconds(20)); if (System.IO.File.Exists(vidCaptureHandler.GetFilepath())) { @@ -92,7 +98,6 @@ public void TakeVideo(string extension, MMALEncoding encodingType, MMALEncoding { Assert.True(false, $"File {vidCaptureHandler.GetFilepath()} was not created"); } - } }); } @@ -100,23 +105,15 @@ public void TakeVideo(string extension, MMALEncoding encodingType, MMALEncoding [Theory, MemberData(nameof(TakeVideoDataH264))] public void TakeVideoSplit(string extension, MMALEncoding encodingType, MMALEncoding pixelFormat) { + TestHelper.SetConfigurationDefaults(); + + MMALCameraConfig.InlineHeaders = true; + AsyncContext.Run(async () => { var vidCaptureHandler = new VideoStreamCaptureHandler("/home/pi/videos/tests/split_test", extension); - try - { - var files = Directory.GetFiles("/home/pi/videos/tests/split_test"); - - //Clear directory first - foreach (string file in files) - { - File.Delete(file); - } - } - catch - { - } + TestHelper.CleanDirectory("/home/pi/videos/tests/split_test"); using (var vidEncoder = new MMALVideoEncoder(vidCaptureHandler, encodingType, pixelFormat, 25000000, 10, 25)) { @@ -127,8 +124,8 @@ public void TakeVideoSplit(string extension, MMALEncoding encodingType, MMALEnco .ConfigureCamera(); //2 files should be created from this test. - await fixture.MMALCamera.TakeVideo(fixture.MMALCamera.Camera.VideoPort, DateTime.Now.AddMinutes(1), - new Split { Mode = TimelapseMode.Second, Value = 30 }); + await fixture.MMALCamera.TakeVideo(fixture.MMALCamera.Camera.VideoPort, DateTime.Now.AddSeconds(30), + new Split { Mode = TimelapseMode.Second, Value = 15 }); Assert.True(Directory.GetFiles("/home/pi/videos/tests/split_test").Length == 2); @@ -139,10 +136,14 @@ await fixture.MMALCamera.TakeVideo(fixture.MMALCamera.Camera.VideoPort, DateTime [Fact] public void ChangeEncoderType() { + TestHelper.SetConfigurationDefaults(); + AsyncContext.Run(async () => { var vidCaptureHandler = new VideoStreamCaptureHandler("/home/pi/videos/tests", "avi"); + TestHelper.CleanDirectory("/home/pi/videos/tests"); + using (var vidEncoder = new MMALVideoEncoder(vidCaptureHandler, 10, 25)) { //Create our component pipeline. @@ -151,8 +152,8 @@ public void ChangeEncoderType() .CreatePreviewComponent(new MMALVideoRenderer()) .ConfigureCamera(); - //Record video for 1 minute - await fixture.MMALCamera.TakeVideo(fixture.MMALCamera.Camera.VideoPort, DateTime.Now.AddMinutes(1)); + //Record video for 20 seconds + await fixture.MMALCamera.TakeVideo(fixture.MMALCamera.Camera.VideoPort, DateTime.Now.AddSeconds(20)); if (System.IO.File.Exists(vidCaptureHandler.GetFilepath())) { @@ -176,8 +177,8 @@ public void ChangeEncoderType() .CreatePreviewComponent(new MMALVideoRenderer()) .ConfigureCamera(); - //Record video for 1 minute - await fixture.MMALCamera.TakeVideo(fixture.MMALCamera.Camera.VideoPort, DateTime.Now.AddMinutes(1)); + //Record video for 20 seconds + await fixture.MMALCamera.TakeVideo(fixture.MMALCamera.Camera.VideoPort, DateTime.Now.AddSeconds(20)); if (System.IO.File.Exists(vidCaptureHandler.GetFilepath())) { @@ -193,7 +194,5 @@ public void ChangeEncoderType() }); } - - } }