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); } }
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"); }
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."); }
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"); }
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"); }
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"); }
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"); }
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"); }
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"); }
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"); }
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"); }
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."); }
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); } } }
internal static void SetCameraConfig(this MmalCameraComponent camera, MmalParameterCameraConfigType value) { MmalCheck(MmalPort.SetParameter(camera.Control.Ptr, &value.Hdr), "Unable to set camera config."); }