// %BANNER_BEGIN% // --------------------------------------------------------------------- // %COPYRIGHT_BEGIN% // Copyright (c) (2018-2024) Magic Leap, Inc. All Rights Reserved. // Use of this file is governed by the Software License Agreement, located here: https://www.magicleap.com/software-license-agreement-ml2 // Terms and conditions applicable to third-party materials accompanying this distribution may also be found in the top-level NOTICE file appearing herein. // %COPYRIGHT_END% // --------------------------------------------------------------------- // %BANNER_END% using System; using System.Linq; using System.Runtime.InteropServices; namespace UnityEngine.XR.MagicLeap { public partial class MLCameraBase { internal partial class NativeBindings { /// /// Structure to encapsulate connection settings for MR capture. /// [StructLayout(LayoutKind.Sequential)] public struct MLCameraMRConnectInfo { /// /// MR video quality /// public MLCamera.MRQuality MrQuality; /// /// blending type for mixed reality capture /// public MLCamera.MRBlendType MrBlendType; /// /// capture frame rate /// public MLCamera.CaptureFrameRate FrameRate; /// /// Create and return an initialized version of this struct. /// /// A new instance of this struct. public static MLCameraMRConnectInfo Create(MLCamera.MRConnectInfo connectInfo) { return new MLCameraMRConnectInfo() { MrQuality = connectInfo.MRQuality, MrBlendType = connectInfo.MRBlendType, FrameRate = connectInfo.FrameRate }; } } /// /// Structure to encapsulate context for a CameraConnect Request. /// [StructLayout(LayoutKind.Sequential)] public struct MLCameraConnectContext { /// /// version contains the version number for this structure. /// public uint Version; /// /// logical camera idenitifier /// public MLCamera.Identifier CamId; /// /// The Context in which the camera should operate in. /// public MLCamera.ConnectFlag Flags; /// /// Video Stabilization enable/disable 1 - enable 0 - disabled /// [MarshalAs(UnmanagedType.I1)] public bool EnableVideoStab; /// /// MR capture connection settings /// public MLCameraMRConnectInfo MrInfo; /// /// Create and return an initialized version of this struct. /// /// A new instance of this struct. public static MLCameraConnectContext Create(MLCamera.ConnectContext cameraContext) { return new MLCameraConnectContext() { Version = 1, CamId = cameraContext.CamId, Flags = cameraContext.Flags, EnableVideoStab = cameraContext.EnableVideoStabilization, MrInfo = MLCameraMRConnectInfo.Create(cameraContext.MixedRealityConnectInfo) }; } } /// /// The capabilities for each stream supported by logical camera device * can be queried with MLCameraGetDeviceCaps /// [StructLayout(LayoutKind.Sequential)] public struct MLCameraCaptureStreamCaps { /// /// capture_type Video, Image ,Preview /// public MLCamera.CaptureType CaptureType; /// /// Capture Resolution /// public int Width; /// /// Resolution height /// public int Height; /// /// Create and return an initialized version of this struct. /// /// A new instance of this struct. public static MLCameraCaptureStreamCaps Create() { return new MLCameraCaptureStreamCaps() { }; } } /// /// Structure to encapsulate stream configurations /// [StructLayout(LayoutKind.Sequential)] public struct MLCameraCaptureStreamConfig { /// /// capture_type Image Preview /// public MLCamera.CaptureType CaptureType; /// /// Capture Resolution /// public int Width; /// /// Resolution height /// public int Height; /// /// output Format /// public MLCamera.OutputFormat OutputFormat; /// /// media recorder surface, only valid for capture type video * set to ML_INVALID_HANDLE for yuv/rgba video capture /// public ulong MediaRecorderSurfaceHandle; /// /// Create and return an initialized version of this struct. /// /// A new instance of this struct. public static MLCameraCaptureStreamConfig Create() { return new MLCameraCaptureStreamConfig() { }; } public static MLCameraCaptureStreamConfig Create(MLCamera.CaptureStreamConfig config) { return new MLCameraCaptureStreamConfig() { Height = config.Height, Width = config.Width, CaptureType = config.CaptureType, OutputFormat = config.OutputFormat, MediaRecorderSurfaceHandle = config.Surface?.Handle ?? InvalidHandle, }; } } /// /// Structure to encapsulate capture configuration /// [StructLayout(LayoutKind.Sequential)] public struct MLCameraCaptureConfig { /// /// version contains the version number for this structure. /// public uint Version; /// /// capture frame rate /// public MLCamera.CaptureFrameRate CaptureFrameRate; /// /// no of capture streams. /// public uint NumStreams; /// /// Stream configurations /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = MLCameraMaxStreams)] public MLCameraCaptureStreamConfig[] StreamConfig; /// /// Create and return an initialized version of this struct. /// /// A new instance of this struct. public static MLCameraCaptureConfig Create() { return new MLCameraCaptureConfig() { Version = 1, StreamConfig = new MLCameraCaptureStreamConfig[MLCameraMaxStreams] }; } /// /// Create and initialize this native struct based on values exposed in . /// /// A new instance of this struct. public static MLCameraCaptureConfig Create(MLCamera.CaptureConfig config) { MLCameraCaptureConfig nativeConfig = MLCameraCaptureConfig.Create(); nativeConfig.NumStreams = (uint)config.StreamConfigs.Length; nativeConfig.CaptureFrameRate = config.CaptureFrameRate; for (var i = 0; i < config.StreamConfigs.Length; i++) nativeConfig.StreamConfig[i] = MLCameraCaptureStreamConfig.Create(config.StreamConfigs[i]); return nativeConfig; } } /// /// Per plane info for captured output /// [StructLayout(LayoutKind.Sequential)] public struct MLCameraPlaneInfo { /// /// version contains the version number for this structure. /// public uint Version; /// /// Width of the output image in pixels /// public uint Width; /// /// Height of the output image in pixels /// public uint Height; /// /// Stride of the output image in pixels /// public uint Stride; /// /// Number of bytes used to represent a pixel /// public uint BytesPerPixel; public uint PixelsStride; /// /// Image data /// public IntPtr Data; /// /// Number of bytes in the image output data /// public uint Size; /// /// Create and return an initialized version of this struct. /// /// Returns a new MLCamera.PlaneInfo structure. public static MLCameraPlaneInfo Create() { return new MLCameraPlaneInfo { Version = 0u, Width = 0u, Height = 0u, Stride = 0u, BytesPerPixel = 0u, PixelsStride = 0u, Data = IntPtr.Zero, Size = 0u }; } public MLCamera.PlaneInfo CreatePlaneInfo(bool copyToManagedMemory, byte[] byteArrayToUse = null) { if (copyToManagedMemory && byteArrayToUse == null) { byteArrayToUse = new byte[Size]; } var planeInfo = new MLCamera.PlaneInfo() { IsValid = true, Width = this.Width, Height = this.Height, Stride = this.Stride, BytesPerPixel = this.BytesPerPixel, PixelStride = this.PixelsStride, DataPtr = this.Data, Size = this.Size, Data = (copyToManagedMemory) ? byteArrayToUse : null }; if (planeInfo.Data != null) { uint width = planeInfo.Stride == 0 ? planeInfo.Width : planeInfo.Stride; planeInfo.Data = new byte[width * planeInfo.Height]; if (planeInfo.PixelStride == 2) { Marshal.Copy(Data, planeInfo.Data, 0, (int)((width * (planeInfo.Height - 1)) + (planeInfo.Width * planeInfo.PixelStride) - 1)); } else { Marshal.Copy(Data, planeInfo.Data, 0, (int)((width * (planeInfo.Height - 1)) + (planeInfo.Width * planeInfo.PixelStride))); } if (planeInfo.Stride != 0) { planeInfo.Size = planeInfo.Stride * planeInfo.Height; } } return planeInfo; } } /// /// Captured output /// [StructLayout(LayoutKind.Sequential)] public struct MLCameraOutput { /// /// version contains the version number for this structure. /// public uint Version; /// /// Number of output image planes: /// - 1 for compressed output such as JPEG stream, /// - 3 for separate color component output such as YUV/YCbCr/RGB. /// public byte PlaneCount; /// /// Output image plane info. /// The number of output planes is specified by PlaneCount. /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = NativeBindings.MLCameraMaxImagePlanes)] public MLCameraPlaneInfo[] Planes; /// /// Supported output format specified by MLCamera.OutputFormat /// public MLCamera.OutputFormat Format; /// /// Create and return an initialized version of this struct. /// /// Returns a new MLCamera.Output structure. public static MLCameraOutput Create() { return new MLCameraOutput { Version = 0, PlaneCount = 0, Planes = Enumerable.Repeat(MLCameraPlaneInfo.Create(), NativeBindings.MLCameraMaxImagePlanes).ToArray(), Format = MLCamera.OutputFormat.JPEG }; } public MLCamera.CameraOutput CreateFrameInfo(bool copyToManagedMemory, byte[][] byteArraysToUse = null) { var frameInfo = new MLCamera.CameraOutput() { Planes = new MLCamera.PlaneInfo[this.PlaneCount], Format = this.Format }; for (int i = 0; i < this.PlaneCount; ++i) { frameInfo.Planes[i] = Planes[i].CreatePlaneInfo(copyToManagedMemory, byteArraysToUse?[i]); } return frameInfo; } } /// /// IntrinsicCalibrationParameters is a structure to provide instrisic calibration information /// [StructLayout(LayoutKind.Sequential)] public readonly struct MLCameraIntrinsicCalibrationParameters { /// /// version contains the version number for this structure. /// public readonly uint Version; /// /// Camera width. /// public readonly uint Width; /// /// Camera height. /// public readonly uint Height; /// /// Camera focal length. /// public readonly MLVec2f FocalLength; /// /// Camera principal point. /// public readonly MLVec2f PrincipalPoint; /// /// Field of view in degrees /// public readonly float FOV; /// /// Distortion vector. /// The distortion co-efficients are in the following order: /// [k1, k2, p1, p2, k3] /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = MLCameraMaxDistortionCoefficients)] public readonly double[] Distortion; } /// /// ResultExtras is a structure to encapsulate various indices for a capture result. /// [StructLayout(LayoutKind.Sequential)] public readonly struct MLCameraResultExtras { /// /// version contains the version number for this structure. /// public readonly uint Version; /// /// A 64bit integer to index the frame number associated with this result /// public readonly long FrameNumber; /// /// VCam exposure timestamp in microseconds (us) /// public readonly long VcamTimestamp; /// /// Camera intrinsic parameter. /// Only valid within callback scope. /// The Library allocates and maintains the lifetime of intrinsics. /// Only valid for on_image_buffer_available, on_video_buffer_available, on_preview_buffer_available callbacks. /// NULL for on_capture_completed, on_capture_failed callbacks public readonly IntPtr Intrinsics; } [StructLayout(LayoutKind.Sequential)] public readonly struct MLCameraDeviceAvailabilityInfo { public readonly MLCamera.Identifier CamId; public readonly IntPtr UserData; } /// /// Device availability status callbacks to be implemented by client to receive device availability status. /// [StructLayout(LayoutKind.Sequential)] public struct MLCameraDeviceAvailabilityStatusCallbacks { /// /// Version contains the version number for this structure. /// public uint Version; /// /// Callback is invoked when the camera becomes available. /// public DeviceAvailabilityStatusDelegate OnDeviceAvailable; /// /// Callback is invoked when the camera becomes unavailable. /// public DeviceAvailabilityStatusDelegate OnDeviceUnavailable; /// /// Create and return an initialized version of this struct. /// /// A new instance of this struct. public static MLCameraDeviceAvailabilityStatusCallbacks Create() { return new MLCameraDeviceAvailabilityStatusCallbacks() { Version = 1, OnDeviceAvailable = OnDeviceAvailableCallback, OnDeviceUnavailable = OnDeviceUnavailableCallback }; } public static MLCameraDeviceAvailabilityStatusCallbacks CreateUninitialized() { return new MLCameraDeviceAvailabilityStatusCallbacks() { Version = 1, OnDeviceAvailable = null, OnDeviceUnavailable = null }; } } /// /// Device status callbacks to be implemented by client to receive device status if callback mechanism is used. /// [StructLayout(LayoutKind.Sequential)] public struct MLCameraDeviceStatusCallbacks { /// /// Version contains the version number for this structure. /// public uint Version; /// /// Callback is invoked when the camera is streaming. /// public OnDeviceStreamingDelegate OnDeviceStreaming; /// /// Callback is invoked when the camera stops streaming. /// public OnDeviceIdleDelegate OnDeviceIdle; /// /// Callback is invoked when the camera is disconnected. /// public OnDeviceDisconnectedDelegate OnDeviceDisconnected; /// /// Callback is invoked when the camera encountered errors. Invalid: The camera device is not available. Disabled: The /// camera device can't be opened due to a device policy. Device error: The camera device encountered a fatal error such as /// the Lightwear device has lost connection or the hardware comm bus is busy and not be able to response and caused a /// timeout. Service error: The camera service has encountered a fatal error and could not provide service. Capture failed: The /// capure request has failed. on_capture_failed or on_capture_buffer_lost callbacks will be invoked when this error /// happens. /// public OnDeviceErrorDelegate OnDeviceError; /// /// Create and return an initialized version of this struct. /// /// A new instance of this struct. public static MLCameraDeviceStatusCallbacks Create() { return new MLCameraDeviceStatusCallbacks() { Version = 1, OnDeviceStreaming = OnDeviceStreamingCallback, OnDeviceIdle = OnDeviceIdleCallback, OnDeviceDisconnected = OnDeviceDisconnectCallback, OnDeviceError = OnDeviceErrorCallback }; } } /// /// Capture callbacks to be implemented by client to receive capture status if callback mechanism is used. This structure /// must be initialized by calling MLCameraCaptureCallbacksInit() before use. /// [StructLayout(LayoutKind.Sequential)] public struct MLCameraCaptureCallbacks { /// /// version contains the version number for this structure. /// public uint Version; /// /// Callback is invoked when a capture has failed when the camera device failed to produce a capture result for the request. /// public OnCaptureFailedDelegate OnCaptureFailed; /// /// Callback is invoked when an ongoing video or preview capture or both are aborted due to an error. /// public OnCaptureAbortedDelegate OnCaptureAborted; /// /// Callback is invoked when capturing single frame is completed and result is available. /// public OnCaptureCompletedDelegate OnCaptureCompleted; /// /// Callback is invoked when a captured image buffer is available with #MLCameraCaptureType_ImageRaw. /// public OnImageBufferAvailableDelegate OnImageBufferAvailable; /// /// Callback is invoked when a captured raw/compressed video frame buffer is available with #MLCameraCaptureType_VideoRaw. /// public OnVideoBufferAvailableDelegate OnVideoBufferAvailable; /// /// Callback is invoked when a preview video frame buffer is available with #MLCameraCaptureType_Preview. /// public OnPreviewBufferAvailableDelegate OnPreviewBufferAvailable; /// /// Create and return an initialized version of this struct. /// /// A new instance of this struct. public static MLCameraCaptureCallbacks Create() { return new MLCameraCaptureCallbacks() { Version = 1, OnCaptureFailed = OnCaptureFailCallback, OnCaptureAborted = OnCaptureAbortCallback, OnCaptureCompleted = OnCaptureCompleteCallback, OnImageBufferAvailable = OnImageBufferAvailableCallback, OnVideoBufferAvailable = OnVideoBufferAvailableCallback, OnPreviewBufferAvailable = OnPreviewBufferAvailableCallback }; } } } } }