/// <summary> /// Creates a new instance of a Overlay renderer component. This component is identical to the <see cref="MMALVideoRenderer"/> class, however it provides /// the ability to overlay a static source onto the render overlay. /// </summary> /// <param name="parent">The parent renderer which is being used to overlay onto the display.</param> /// <param name="config">The configuration for rendering a static preview overlay.</param> /// <param name="source">A reference to the current stream being used in the overlay.</param> public MMALOverlayRenderer(MMALVideoRenderer parent, PreviewOverlayConfiguration config, byte[] source) : base(config) { this.Source = source; this.ParentRenderer = parent; this.OverlayConfiguration = config; parent.Overlays.Add(this); this.Inputs[0] = new OverlayPort(this.Inputs[0]); if (config != null) { if (config.Resolution.Width > 0 && config.Resolution.Height > 0) { this.Inputs[0].Resolution = config.Resolution; this.Inputs[0].Crop = new Rectangle(0, 0, config.Resolution.Width, config.Resolution.Height); } else { this.Inputs[0].Resolution = parent.Inputs[0].Resolution; this.Inputs[0].Crop = new Rectangle(0, 0, parent.Inputs[0].Resolution.Width, parent.Inputs[0].Resolution.Height); } this.Inputs[0].FrameRate = new MMAL_RATIONAL_T(0, 0); if (config.Encoding == null) { var sourceLength = source.Length; var planeSize = this.Inputs[0].Resolution.Pad(); var planeLength = Math.Floor((double)planeSize.Width * planeSize.Height); if (Math.Floor(sourceLength / planeLength) == 3) { config.Encoding = MMALEncoding.RGB24; } else if (Math.Floor(sourceLength / planeLength) == 4) { config.Encoding = MMALEncoding.RGBA; } else { throw new PiCameraError("Unable to determine encoding from image size."); } } this.Inputs[0].NativeEncodingType = config.Encoding.EncodingVal; } if (!this.AllowedEncodings.Any(c => c.EncodingVal == this.Inputs[0].NativeEncodingType)) { throw new PiCameraError($"Incompatible encoding type for use with Preview Render overlay {MMALEncodingHelpers.ParseEncoding(this.Inputs[0].NativeEncodingType).EncodingName}."); } this.Inputs[0].Commit(); this.Control.Start(); this.Inputs[0].Start(); }
/// <summary> /// Creates a new instance of a Overlay renderer component. This component is identical to the <see cref="MMALVideoRenderer"/> class, however it provides /// the ability to overlay a static source onto the render overlay. /// </summary> /// <param name="parent">The parent renderer which is being used to overlay onto the display.</param> /// <param name="config">The configuration for rendering a static preview overlay.</param> /// <param name="source">A reference to the current stream being used in the overlay.</param> public MMALOverlayRenderer(MMALVideoRenderer parent, PreviewOverlayConfiguration config, byte[] source) : base(config) { this.Source = source; this.ParentRenderer = parent; this.OverlayConfiguration = config; parent.Overlays.Add(this); if (config != null) { var width = 0; var height = 0; if (config.Resolution.Width > 0 && config.Resolution.Height > 0) { width = config.Resolution.Width; height = config.Resolution.Height; } else { width = parent.Inputs[0].Resolution.Width; height = parent.Inputs[0].Resolution.Height; } if (config.Encoding == null) { var sourceLength = source.Length; var planeSize = this.Inputs[0].Resolution.Pad(); var planeLength = Math.Floor((double)planeSize.Width * planeSize.Height); if (Math.Floor(sourceLength / planeLength) == 3) { config.Encoding = MMALEncoding.RGB24; } else if (Math.Floor(sourceLength / planeLength) == 4) { config.Encoding = MMALEncoding.RGBA; } else { throw new PiCameraError("Unable to determine encoding from image size."); } } if (!this.AllowedEncodings.Any(c => c.EncodingVal == this.Inputs[0].NativeEncodingType)) { throw new PiCameraError($"Incompatible encoding type for use with Preview Render overlay {this.Inputs[0].NativeEncodingType.ParseEncoding().EncodingName}."); } var portConfig = new MMALPortConfig(config.Encoding, null, width, height, 0, 0, 0, false, null, 0, 0); this.ConfigureInputPort(portConfig, null); this.Control.Start(); this.Inputs[0].Start(); } }