Beispiel #1
0
        void ConfigureVideoProfile(int outputPort)
        {
            var rational        = new MmalRational(CameraConfig.Framerate);
            var macroblocks     = (CameraConfig.Resolution.Width >> 4) * (CameraConfig.Resolution.Height >> 4);
            var macroblocksPSec = macroblocks * (rational.Num / rational.Den);

            var videoLevels = GetNormalLevelLimits();
            var level       = videoLevels.First(c => c.Level == CameraConfig.VideoLevel);

            if (macroblocks > level.MacroblocksLimit)
            {
                throw new PiCameraError("Resolution exceeds macroblock limit for selected profile and level.");
            }
            if (macroblocksPSec > level.MacroblocksPerSecLimit)
            {
                throw new PiCameraError("Resolution exceeds macroblocks/s limit for selected profile and level.");
            }

            var p     = new MmalParameterVideoProfileS(CameraConfig.VideoProfile, CameraConfig.VideoLevel);
            var arr   = new [] { p };
            var param = new MmalParameterVideoProfileType(new MmalParameterHeaderType(MmalParametersVideo.MmalParameterProfile, Marshal.SizeOf <MmalParameterVideoProfileType>()), arr);
            var ptr   = Marshal.AllocHGlobal(Marshal.SizeOf(param));

            Marshal.StructureToPtr(param, ptr, false);

            try
            {
                MmalCheck(MmalPort.SetParameter(Outputs[outputPort].Ptr, (MmalParameterHeaderType *)ptr), "Unable to set video profile.");
            }
            finally
            {
                Marshal.FreeHGlobal(ptr);
            }
        }
        bool ReadV1SensorInfo()
        {
            var ptr1 = Marshal.AllocHGlobal(Marshal.SizeOf <MmalParameterCameraInfoType>());
            var str1 = (MmalParameterHeaderType *)ptr1;

            str1->Id   = MmalParametersCamera.MmalParameterCameraInfo;
            str1->Size = Marshal.SizeOf <MmalParameterCameraInfoType>();

            try
            {
                MmalCheck(MmalPort.GetParameter(Control.Ptr, str1), string.Empty);

                var p = (IntPtr)str1;
                var s = Marshal.PtrToStructure <MmalParameterCameraInfoType>(p);

                if (s.Cameras == null || s.Cameras.Length <= 0)
                {
                    return(false);
                }

                SensorName = "OV5647";
                MaxHeight  = s.Cameras[0].MaxHeight;
                MaxWidth   = s.Cameras[0].MaxWidth;

                return(true);
            }
            catch
            {
                return(false);
            }
            finally
            {
                Marshal.FreeHGlobal(ptr1);
            }
        }
Beispiel #3
0
        internal static void SetDrc(this MmalCameraComponent camera, MmalParameterDrcStrengthType strength)
        {
            var drc = new MmalParameterDrcType(
                new MmalParameterHeaderType(MmalParameterDynamicRangeCompression, Marshal.SizeOf <MmalParameterDrcType>()),
                strength);

            MmalCheck(MmalPort.SetParameter(camera.Control.Ptr, &drc.Hdr), "Unable to set DRC");
        }
Beispiel #4
0
        internal static unsafe void SetFramerateRange(this IPort port, MmalRational fpsLow, MmalRational fpsHigh)
        {
            var str = new MmalParameterFpsRangeType(
                new MmalParameterHeaderType(
                    MmalParametersCamera.MmalParameterFpsRange,
                    Marshal.SizeOf <MmalParameterFpsRangeType>()), fpsLow, fpsHigh);

            MmalCheck(MmalPort.SetParameter(port.Ptr, &str.Hdr), "Unable to set framerate range for port.");
        }
Beispiel #5
0
        internal static void SetFlips(this MmalCameraComponent camera, MmalParamMirrorType flips)
        {
            var mirror = new MmalParameterMirrorType(
                new MmalParameterHeaderType(MmalParameterMirror, Marshal.SizeOf <MmalParameterMirrorType>()),
                flips);

            MmalCheck(MmalPort.SetParameter(camera.StillPort.Ptr, &mirror.Hdr), "Unable to set flips");
            MmalCheck(MmalPort.SetParameter(camera.VideoPort.Ptr, &mirror.Hdr), "Unable to set flips");
        }
Beispiel #6
0
        internal static unsafe void SetStereoMode(this IPort port, StereoMode mode)
        {
            var stereo = new MmalParameterStereoscopicModeType(
                new MmalParameterHeaderType(MmalParameterStereoscopicMode, Marshal.SizeOf <MmalParameterStereoscopicModeType>()),
                mode.Mode,
                mode.Decimate,
                mode.SwapEyes);

            MmalCheck(MmalPort.SetParameter(port.Ptr, &stereo.Hdr), "Unable to set Stereo mode");
        }
Beispiel #7
0
        internal static void SetImageFx(this MmalCameraComponent camera, MmalParamImagefxType imageFx)
        {
            MmalLog.Logger.LogDebug($"Setting Image FX: {imageFx}");

            var imgFx = new MmalParameterImageFxType(
                new MmalParameterHeaderType(MmalParameterImageEffect, Marshal.SizeOf <MmalParameterImageFxType>()),
                imageFx);

            MmalCheck(MmalPort.SetParameter(camera.Control.Ptr, &imgFx.Hdr), "Unable to set image fx");
        }
Beispiel #8
0
        internal static void SetAwbMode(this MmalCameraComponent camera, MmalParamAwbmodeType mode)
        {
            MmalLog.Logger.LogDebug($"Setting AWB mode: {mode}");

            var awbMode = new MmalParameterAwbModeType(
                new MmalParameterHeaderType(MmalParameterAwbMode, Marshal.SizeOf <MmalParameterAwbModeType>()),
                mode);

            MmalCheck(MmalPort.SetParameter(camera.Control.Ptr, &awbMode.Hdr), "Unable to set awb mode");
        }
Beispiel #9
0
        internal static void SetExposureMeteringMode(this MmalCameraComponent camera, MmalParamExposuremeteringmodeType mode)
        {
            MmalLog.Logger.LogDebug($"Setting exposure metering mode: {mode}");

            var expMode = new MmalParameterExposuremeteringmodeType(
                new MmalParameterHeaderType(MmalParameterExpMeteringMode, Marshal.SizeOf <MmalParameterExposuremeteringmodeType>()),
                mode);

            MmalCheck(MmalPort.SetParameter(camera.Control.Ptr, &expMode.Hdr), "Unable to set exposure metering mode");
        }
Beispiel #10
0
        internal static void SetZoom(this MmalCameraComponent camera, Zoom rect)
        {
            if (rect.X > 1.0 || rect.Y > 1.0 || rect.Height > 1.0 || rect.Width > 1.0)
            {
                throw new ArgumentOutOfRangeException(nameof(rect), "Invalid zoom settings. Value mustn't be greater than 1.0");
            }

            var crop = new MmalParameterInputCropType(
                new MmalParameterHeaderType(MmalParameterInputCrop, Marshal.SizeOf <MmalParameterInputCropType>()),
                new MmalRect(Convert.ToInt32(65536 * rect.X), Convert.ToInt32(65536 * rect.Y), Convert.ToInt32(65536 * rect.Width), Convert.ToInt32(65536 * rect.Height)));

            MmalCheck(MmalPort.SetParameter(camera.Control.Ptr, &crop.Hdr), "Unable to set zoom");
        }
Beispiel #11
0
        internal static void SetColourFx(this MmalCameraComponent camera, ColorEffects colorFx)
        {
            MmalLog.Logger.LogDebug("Setting colour effects");

            var(_, u, v) = MmalColor.RgbToYuvBytes(colorFx.Color);

            var colFx = new MmalParameterColorFxType(
                new MmalParameterHeaderType(MmalParameterColorEffect, Marshal.SizeOf <MmalParameterColorFxType>()),
                colorFx.Enable ? 1 : 0,
                u,
                v);

            MmalCheck(MmalPort.SetParameter(camera.Control.Ptr, &colFx.Hdr), "Unable to set colour fx");
        }
Beispiel #12
0
        internal static void SetAwbGains(this MmalCameraComponent camera, double rGain, double bGain)
        {
            MmalLog.Logger.LogDebug($"Setting AWB gains: {rGain}, {bGain}");

            if (CameraConfig.AwbMode != MmalParamAwbmodeType.MmalParamAwbmodeOff && (rGain > 0 || bGain > 0))
            {
                throw new PiCameraError("AWB Mode must be off when setting AWB gains");
            }

            var awbGains = new MmalParameterAwbGainsType(
                new MmalParameterHeaderType(MmalParameterCustomAwbGains, Marshal.SizeOf <MmalParameterAwbGainsType>()),
                new MmalRational((int)(rGain * 65536), 65536),
                new MmalRational((int)(bGain * 65536), 65536));

            MmalCheck(MmalPort.SetParameter(camera.Control.Ptr, &awbGains.Hdr), "Unable to set awb gains");
        }
Beispiel #13
0
        void ConfigureIntraRefresh(int outputPort)
        {
            var param = new MmalParameterVideoIntraRefreshType(new MmalParameterHeaderType(MmalParametersVideo.MmalParameterVideoIntraRefresh, Marshal.SizeOf <MmalParameterVideoIntraRefreshType>()), MmalParametersVideo.MmalVideoIntraRefreshT.MmalVideoIntraRefreshBoth, 0, 0, 0, 0);

            int airMbs = 0, airRef = 0, cirMbs = 0, pirMbs = 0;

            try
            {
                MmalCheck(MmalPort.GetParameter(Outputs[outputPort].Ptr, param.HdrPtr), "Unable to set video profile.");
                airMbs = param.AirMbs;
                airRef = param.AirRef;
                cirMbs = param.CirMbs;
                pirMbs = param.PirMbs;
            }
            catch
            {
                /* catch all */
            }

            param = new MmalParameterVideoIntraRefreshType(new MmalParameterHeaderType(MmalParametersVideo.MmalParameterVideoIntraRefresh, Marshal.SizeOf <MmalParameterVideoIntraRefreshType>()), CameraConfig.IntraRefresh, airMbs, airRef, cirMbs, pirMbs);
            MmalCheck(MmalPort.SetParameter(Outputs[outputPort].Ptr, param.HdrPtr), "Unable to set video intra refresh.");
        }
Beispiel #14
0
        internal static void SetAnnotateSettings(this MmalCameraComponent camera)
        {
            if (CameraConfig.Annotate == null)
            {
                return;
            }

            var sb = new StringBuilder();

            var showShutter           = 0;
            var showAnalogGain        = 0;
            var showLens              = 0;
            var showCaf               = 0;
            var showMotion            = 0;
            var showFrame             = 0;
            var enableTextBackground  = 0;
            var customTextColor       = 0;
            var customTextY           = (byte)0;
            var customTextU           = (byte)0;
            var customTextV           = (byte)0;
            var customBackgroundColor = 0;
            var customBackgroundY     = (byte)0;
            var customBackgroundU     = (byte)0;
            var customBackgroundV     = (byte)0;
            var justify               = CameraConfig.Annotate.Justify;
            var xOffset               = CameraConfig.Annotate.XOffset;
            var yOffset               = CameraConfig.Annotate.YOffset;

            if (!string.IsNullOrEmpty(CameraConfig.Annotate.CustomText))
            {
                sb.Append(CameraConfig.Annotate.CustomText + " ");
            }

            if (CameraConfig.Annotate.ShowDateText)
            {
                sb.Append(DateTime.Now.ToString(CameraConfig.Annotate.DateFormat) + " ");
            }

            if (CameraConfig.Annotate.ShowTimeText)
            {
                sb.Append(DateTime.Now.ToString(CameraConfig.Annotate.TimeFormat) + " ");
            }

            if (CameraConfig.Annotate.ShowShutterSettings)
            {
                showShutter = 1;
            }

            if (CameraConfig.Annotate.ShowGainSettings)
            {
                showAnalogGain = 1;
            }

            if (CameraConfig.Annotate.ShowLensSettings)
            {
                showLens = 1;
            }

            if (CameraConfig.Annotate.ShowCafSettings)
            {
                showCaf = 1;
            }

            if (CameraConfig.Annotate.ShowMotionSettings)
            {
                showMotion = 1;
            }

            if (CameraConfig.Annotate.ShowFrameNumber)
            {
                showFrame = 1;
            }

            if (CameraConfig.Annotate.AllowCustomBackgroundColour)
            {
                enableTextBackground = 1;
            }

            var textSize = Convert.ToByte(CameraConfig.Annotate.TextSize);

            if (CameraConfig.Annotate.TextColour != Color.Empty)
            {
                customTextColor = 1;

                var(y, u, v) = MmalColor.RgbToYuvBytes(CameraConfig.Annotate.TextColour);
                customTextY  = y;
                customTextU  = u;
                customTextV  = v;
            }

            if (CameraConfig.Annotate.BgColour != Color.Empty)
            {
                customBackgroundColor = 1;
                var(y, u, v)          = MmalColor.RgbToYuvBytes(CameraConfig.Annotate.BgColour);
                customBackgroundY     = y;
                customBackgroundU     = u;
                customBackgroundV     = v;
            }

            // .NET Core has an issue with marshalling arrays "ByValArray". The array being passed MUST equal the size
            // specified in the "SizeConst" field or you will receive an exception. Mono does not have this restriction
            // and is quite happy to pass an array of a lower size if asked. In order to get around this, I am creating
            // an array equaling "SizeConst" and copying the contents of the annotation text into it, minus the EOL character.
            var text  = sb.ToString() + char.MinValue;
            var arr   = new byte[MmalCameraAnnotateMaxTextLenV3];
            var bytes = Encoding.ASCII.GetBytes(text);

            Array.Copy(bytes, arr, bytes.Length);

            var strV4 = new MmalParameterCameraAnnotateV4Type(
                new MmalParameterHeaderType(MmalParameterAnnotate, Marshal.SizeOf <MmalParameterCameraAnnotateV4Type>() + (arr.Length - 1)),
                1, showShutter, showAnalogGain, showLens,
                showCaf, showMotion, showFrame, enableTextBackground,
                customBackgroundColor, customBackgroundY, customBackgroundU, customBackgroundV, 0, customTextColor,
                customTextY, customTextU, customTextV, textSize, arr, (int)justify, xOffset, yOffset);

            var ptrV4 = Marshal.AllocHGlobal(Marshal.SizeOf <MmalParameterCameraAnnotateV4Type>() + (arr.Length - 1));

            Marshal.StructureToPtr(strV4, ptrV4, false);

            try
            {
                MmalCheck(MmalPort.SetParameter(camera.Control.Ptr, (MmalParameterHeaderType *)ptrV4), "Unable to set annotate");
            }
            catch
            {
                Marshal.FreeHGlobal(ptrV4);
                ptrV4 = IntPtr.Zero;

                MmalLog.Logger.LogWarning("Unable to set V4 annotation structure. Trying V3. Please update firmware to latest version.");

                var str = new MmalParameterCameraAnnotateV3Type(
                    new MmalParameterHeaderType(MmalParameterAnnotate, Marshal.SizeOf <MmalParameterCameraAnnotateV3Type>() + (arr.Length - 1)),
                    1, showShutter, showAnalogGain, showLens,
                    showCaf, showMotion, showFrame, enableTextBackground,
                    customBackgroundColor, customBackgroundY, customBackgroundU, customBackgroundV, 0, customTextColor,
                    customTextY, customTextU, customTextV, textSize, arr);

                var ptr = Marshal.AllocHGlobal(Marshal.SizeOf <MmalParameterCameraAnnotateV3Type>() + (arr.Length - 1));
                Marshal.StructureToPtr(str, ptr, false);

                try
                {
                    MmalCheck(MmalPort.SetParameter(camera.Control.Ptr, (MmalParameterHeaderType *)ptr), "Unable to set annotate V3.");
                }
                finally
                {
                    Marshal.FreeHGlobal(ptr);
                }
            }
            finally
            {
                if (ptrV4 != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(ptrV4);
                }
            }
        }
Beispiel #15
0
 internal static void SetCameraConfig(this MmalCameraComponent camera, MmalParameterCameraConfigType value)
 {
     MmalCheck(MmalPort.SetParameter(camera.Control.Ptr, &value.Hdr), "Unable to set camera config.");
 }