using System;
using System.Collections.Generic;
using Unity.Collections;
namespace UnityEngine.XR.ARSubsystems
{
///
/// Provides access to a device's camera.
///
///
/// The XRCameraSubsystem links a Unity Camera to a device camera for video overlay (pass-thru
/// rendering). It also allows developers to query for environmental light estimation, when available.
///
public abstract class XRCameraSubsystem : XRSubsystem
{
///
/// The provider created by the implementation that contains the required camera functionality.
///
///
/// The provider created by the implementation that contains the required camera functionality.
///
Provider m_Provider;
///
/// Construct the XRCameraSubsystem.
///
public XRCameraSubsystem()
{
m_Provider = CreateProvider();
Debug.Assert(m_Provider != null, "camera functionality provider cannot be null");
}
///
/// Interface for providing camera functionality for the implementation.
///
protected class Provider
{
///
/// Property to be implemented by the provder to get the material used by XRCameraSubsystem to
/// render the camera texture.
///
///
/// The material to render the camera texture.
///
public virtual Material cameraMaterial => null;
///
/// Property to be implemented by the provider to determine whether camera permission has been granted.
///
///
/// true if camera permission has been granted. Otherwise, false.
///
public virtual bool permissionGranted => false;
///
/// Whether or not culling should be inverted during rendering. Some front-facing
/// camera modes may require this.
///
public virtual bool invertCulling => false;
///
/// Method to be implemented by provider to start the camera for the subsystem.
///
public virtual void Start() { }
///
/// Method to be implemented by provider to stop the camera for the subsystem.
///
public virtual void Stop() { }
///
/// Method to be implemented by provider to destroy the camera for the subsystem.
///
public virtual void Destroy() { }
///
/// Method to be implemented by provider to get the camera frame for the subsystem.
///
/// The current Unity Camera parameters.
/// The current camera frame returned by the method.
///
/// true if the method successfully got a frame. Otherwise, false.
///
public virtual bool TryGetFrame(
XRCameraParams cameraParams,
out XRCameraFrame cameraFrame)
{
cameraFrame = default(XRCameraFrame);
return false;
}
///
/// Property to be implemented by the provider to get or set the focus mode for the camera.
///
public virtual CameraFocusMode cameraFocusMode
{
get => CameraFocusMode.Fixed;
set { }
}
///
/// Method to be implemented by the provider to set the light estimation mode.
///
/// The light estimation mode to set.
///
/// true if the method successfully set the light estimation mode. Otherwise, false.
///
public virtual bool TrySetLightEstimationMode(LightEstimationMode lightEstimationMode) => false;
///
/// Method to be implemented by the provider to get the camera intrinisics information.
///
/// The camera intrinsics information returned from the method.
///
/// true if the method successfully gets the camera intrinsics information. Otherwise, false.
///
public virtual bool TryGetIntrinsics(
out XRCameraIntrinsics cameraIntrinsics)
{
cameraIntrinsics = default(XRCameraIntrinsics);
return false;
}
///
/// Method to be implemented by the provider to query the supported camera configurations.
///
/// A default value used to fill the returned array before copying
/// in real values. This ensures future additions to this struct are backwards compatible.
/// The allocation strategy to use for the returned data.
///
/// The supported camera configurations.
///
public virtual NativeArray GetConfigurations(XRCameraConfiguration defaultCameraConfiguration,
Allocator allocator)
{
return new NativeArray(0, allocator);
}
///
/// Property to be implemented by the provider to query/set the current camera configuration.
///
///
/// The current camera configuration if it exists. Otherise, null.
///
/// Thrown when setting the current configuration if the
/// implementation does not support camera configurations.
/// Thrown when setting the current configuration if the given
/// configuration is not a valid, supported camera configuration.
/// Thrown when setting the current configuration if the
/// implementation is unable to set the current camera configuration.
public virtual XRCameraConfiguration? currentConfiguration
{
get => null;
set => throw new NotSupportedException("setting current camera configuration is not supported by this implementation");
}
///
/// Get the s associated with the current
/// .
///
/// The current texture descriptors.
/// A default value which should
/// be used to fill the returned array before copying in the
/// real values. This ensures future additions to this struct
/// are backwards compatible.
/// The allocator to use when creating
/// the returned NativeArray.
public virtual NativeArray GetTextureDescriptors(
XRTextureDescriptor defaultDescriptor,
Allocator allocator)
{
return new NativeArray(0, allocator);
}
///
/// Method to be implemented by the provider to get the enabled and disabled shader keywords for the
/// material.
///
/// The keywords to enable for the material.
/// The keywords to disable for the material.
public virtual void GetMaterialKeywords(out List enabledKeywords, out List disabledKeywords)
{
enabledKeywords = null;
disabledKeywords = null;
}
///
/// Method to be implemented by the provider to query for the latest native camera image.
///
/// The metadata required to construct a
///
/// true if the camera image is acquired. Otherwise, false.
///
/// Thrown if the implementation does not support camera
/// image.
public virtual bool TryAcquireLatestImage(out CameraImageCinfo cameraImageCinfo)
{
throw new NotSupportedException("getting camera image is not supported by this implementation");
}
///
/// Method to be implemented by the provider to get the status of an existing asynchronous conversion
/// request.
///
/// The unique identifier associated with a request.
/// The state of the request.
/// Thrown if the implementation does not support camera
/// image.
///
public virtual AsyncCameraImageConversionStatus GetAsyncRequestStatus(int requestId)
{
throw new NotSupportedException("camera image conversion is not supported by this implementation");
}
///
/// Method to be implemented by the provider to dispose an existing native image identified by
/// .
///
/// A unique identifier for this camera image.
/// Thrown if the implementation does not support camera
/// image.
///
public virtual void DisposeImage(int nativeHandle)
{
throw new NotSupportedException("camera image conversion is not supported by this implementation");
}
///
/// Method to be implemented by the provider to dispose an existing async conversion request.
///
/// A unique identifier for the request.
/// Thrown if the implementation does not support camera
/// image.
///
public virtual void DisposeAsyncRequest(int requestId)
{
throw new NotSupportedException("camera image conversion is not supported by this implementation");
}
///
/// Method to be implemented by the provider to get information about an image plane from a native image
/// handle by index.
///
/// A unique identifier for this camera image.
/// The index of the plane to get.
/// The returned camera plane information if successful.
///
/// true if the image plane was acquired. Otherwise, false.
///
/// Thrown if the implementation does not support camera
/// image.
///
public virtual bool TryGetPlane(
int nativeHandle,
int planeIndex,
out CameraImagePlaneCinfo planeCinfo)
{
throw new NotSupportedException("camera image conversion is not supported by this implementation");
}
///
/// Method to be implemented by the provider to determine whether a native image handle returned by
/// is currently valid. An image may become invalid if it has been
/// disposed.
///
///
/// If a handle is valid, and should not fail.
///
/// A unique identifier for the camera image in question.
/// true, if it is a valid handle. Otherwise, false.
/// Thrown if the implementation does not support camera
/// image.
///
public virtual bool NativeHandleValid(
int nativeHandle)
{
throw new NotSupportedException("camera image conversion is not supported by this implementation");
}
///
/// Method to be implemented by the provider to get the number of bytes required to store an image with the
/// given dimensions and TextureFormat.
///
/// A unique identifier for the camera image to convert.
/// The dimensions of the output image.
/// The TextureFormat for the image.
/// The number of bytes required to store the converted image.
/// true if the output was set.
/// Thrown if the implementation does not support camera
/// image.
public virtual bool TryGetConvertedDataSize(
int nativeHandle,
Vector2Int dimensions,
TextureFormat format,
out int size)
{
throw new NotSupportedException("camera image conversion is not supported by this implementation");
}
///
/// Method to be implemented by the provider to convert the image with handle
/// using the provided .
///
/// A unique identifier for the camera image to convert.
/// The parameters to use during the conversion.
/// A buffer to write the converted image to.
/// The number of bytes available in the buffer.
///
/// true if the image was converted and stored in .
///
/// Thrown if the implementation does not support camera
/// image.
public virtual bool TryConvert(
int nativeHandle,
XRCameraImageConversionParams conversionParams,
IntPtr destinationBuffer,
int bufferLength)
{
throw new NotSupportedException("camera image conversion is not supported by this implementation");
}
///
/// Method to be implemented by the provider to create an asynchronous request to convert a camera image,
/// similar to except the conversion should happen on a thread other than the
/// calling (main) thread.
///
/// A unique identifier for the camera image to convert.
/// The parameters to use during the conversion.
/// A unique identifier for this request.
/// Thrown if the implementation does not support camera
/// image.
public virtual int ConvertAsync(
int nativeHandle,
XRCameraImageConversionParams conversionParams)
{
throw new NotSupportedException("camera image conversion is not supported by this implementation");
}
///
/// Method to be implemented by the provider to get a pointer to the image data from a completed
/// asynchronous request. This method should only succeed if returns
/// .
///
/// The unique identifier associated with a request.
/// A pointer to the native buffer containing the data.
/// The number of bytes in .
/// true if and were set and point
/// to the image data.
/// Thrown if the implementation does not support camera
/// image.
public virtual bool TryGetAsyncRequestData(int requestId, out IntPtr dataPtr, out int dataLength)
{
throw new NotSupportedException("camera image conversion is not supported by this implementation");
}
///
/// Method to be implemented by the provider to similar to
/// but takes a delegate to invoke when the
/// request is complete, rather than returning a request id.
///
///
/// If the first parameter to is
/// then the dataPtr parameter must be valid
/// for the duration of the invocation. The data may be destroyed immediately upon return. The
/// parameter must be passed back to the .
///
/// A unique identifier for the camera image to convert.
/// The parameters to use during the conversion.
/// A delegate which must be invoked when the request is complete, whether the
/// conversion was successfully or not.
/// A native pointer which must be passed back unaltered to
/// .
/// Thrown if the implementation does not support camera
/// image.
public virtual void ConvertAsync(
int nativeHandle,
XRCameraImageConversionParams conversionParams,
OnImageRequestCompleteDelegate callback,
IntPtr context)
{
throw new NotSupportedException("camera image conversion is not supported by this implementation");
}
///
/// Create the camera material from the given camera shader name.
///
/// The name of the camera shader.
///
/// The created camera material shader.
///
/// Thrown if the shader cannot be found or if a
/// material cannot be created for the shader.
protected Material CreateCameraMaterial(string cameraShaderName)
{
var shader = Shader.Find(cameraShaderName);
if (shader == null)
{
throw new InvalidOperationException($"Could not find shader named '{cameraShaderName}' required "
+ $"for video overlay on camera subsystem.");
}
Material material = new Material(shader);
if (material == null)
{
throw new InvalidOperationException($"Could not create a material for shader named "
+ $"'{cameraShaderName}' required for video overlay on camera "
+ $"subsystem.");
}
return material;
}
}
///
/// Get or set the focus mode for the camera.
///
///
/// The focus mode for the camera.
///
public CameraFocusMode focusMode
{
get => m_Provider.cameraFocusMode;
set => m_Provider.cameraFocusMode = value;
}
///
/// Specifies the light estimation mode.
///
///
/// The light estimation mode.
///
public LightEstimationMode lightEstimationMode
{
get => m_LightEstimationMode;
set
{
if ((m_LightEstimationMode != value) && m_Provider.TrySetLightEstimationMode(value))
{
m_LightEstimationMode = value;
}
}
}
LightEstimationMode m_LightEstimationMode = LightEstimationMode.Disabled;
///
/// Start the camera subsystem.
///
protected sealed override void OnStart() => m_Provider.Start();
///
/// Stop the camera subsystem.
///
protected sealed override void OnStop() => m_Provider.Stop();
///
/// Destroy the camera subsystem.
///
protected sealed override void OnDestroyed() => m_Provider.Destroy();
///
/// Gets the s associated with the
/// current frame. The caller owns the returned NativeArray
/// and is responsible for calling Dispose on it.
///
/// An array of texture descriptors.
/// The allocator to use when creating
/// the returned NativeArray.
public NativeArray GetTextureDescriptors(
Allocator allocator)
{
return m_Provider.GetTextureDescriptors(
default(XRTextureDescriptor),
allocator);
}
///
/// Get the material used by XRCameraSubsystem to render the camera texture.
///
///
/// The material to render the camera texture.
///
public Material cameraMaterial => m_Provider.cameraMaterial;
///
/// Returns the camera intrinsics information.
///
/// The camera intrinsics information returned from the method.
///
/// true if the method successfully gets the camera intrinsics information. Otherwise, false.
///
public bool TryGetIntrinsics(out XRCameraIntrinsics cameraIntrinsics)
{
return m_Provider.TryGetIntrinsics(out cameraIntrinsics);
}
///
/// Queries for the supported camera configurations.
///
/// The allocation strategy to use for the returned data.
///
/// The supported camera configurations.
///
public NativeArray GetConfigurations(Allocator allocator)
{
return m_Provider.GetConfigurations(default(XRCameraConfiguration), allocator);
}
///
/// The current camera configuration.
///
///
/// The current camera configuration if it exists. Otherise, null.
///
/// Thrown when setting the current configuration if the
/// implementation does not support camera configurations.
/// Thrown when setting the current configuration if the given
/// configuration is null.
/// Thrown when setting the current configuration if the given
/// configuration is not a supported camera configuration.
/// Thrown when setting the current configuration if the
/// implementation is unable to set the current camera configuration.
public virtual XRCameraConfiguration? currentConfiguration
{
get => m_Provider.currentConfiguration;
set
{
if (value == null)
{
throw new ArgumentNullException("value", "cannot set the camera configuration to null");
}
m_Provider.currentConfiguration = value;
}
}
///
/// Whether to invert the culling mode during rendering. Some front-facing
/// camera modes may require this.
///
public bool invertCulling => m_Provider.invertCulling;
///
/// Method for the implementation to create the camera functionality provider.
///
///
/// The camera functionality provider.
///
protected abstract Provider CreateProvider();
///
/// Get the latest frame from the provider.
///
/// The Unity Camera parameters.
/// The camera frame to be populated if the subsystem is running and successfully provides
/// the latest camera frame.
///
/// true if the camera frame is successfully returned. Otherwise, false.
///
public bool TryGetLatestFrame(
XRCameraParams cameraParams,
out XRCameraFrame frame)
{
if (running && m_Provider.TryGetFrame(cameraParams, out frame))
{
return true;
}
frame = default(XRCameraFrame);
return false;
}
///
/// Determines whether camera permission has been granted.
///
///
/// true if camera permission has been granted. Otherwise, false.
///
public bool permissionGranted => m_Provider.permissionGranted;
///
/// Get the enabled and disabled shader keywords for the material.
///
/// The keywords to enable for the material.
/// The keywords to disable for the material.
public void GetMaterialKeywords(out List enabledKeywords, out List disabledKeywords)
=> m_Provider.GetMaterialKeywords(out enabledKeywords, out disabledKeywords);
///
/// Attempt to get the latest camera image. This provides directly access to the raw pixel data, as well as
/// utilities to convert to RGB and Grayscale formats.
///
///
/// The returned must be disposed to avoid resource leaks.
///
/// A valid if this method returns true.
///
/// true if the image was acquired. Otherwise, false.
///
/// Thrown if the implementation does not support camera image.
///
public bool TryGetLatestImage(out XRCameraImage cameraImage)
{
CameraImageCinfo cameraImageCinfo;
if (m_Provider.TryAcquireLatestImage(out cameraImageCinfo))
{
cameraImage = new XRCameraImage(this, cameraImageCinfo.nativeHandle, cameraImageCinfo.dimensions,
cameraImageCinfo.planeCount, cameraImageCinfo.timestamp,
cameraImageCinfo.format);
return true;
}
else
{
cameraImage = default(XRCameraImage);
return false;
}
}
///
/// Registers a camera subsystem implementation based on the given subsystem parameters.
///
/// The parameters defining the camera subsystem functionality implemented
/// by the subsystem provider.
///
/// true if the subsystem implementation is registered. Otherwise, false.
///
/// Thrown when the values specified in the
/// parameter are invalid. Typically, this will occur
///
/// -
/// if is null or empty
///
/// -
/// if is null
///
/// -
/// if does not derive from the
/// class
///
///
///
///
public static bool Register(XRCameraSubsystemCinfo cameraSubsystemParams)
{
XRCameraSubsystemDescriptor cameraSubsystemDescriptor = XRCameraSubsystemDescriptor.Create(cameraSubsystemParams);
return SubsystemRegistration.CreateDescriptor(cameraSubsystemDescriptor);
}
///
/// Get the status of an existing asynchronous conversion request.
///
/// The unique identifier associated with a request.
/// The state of the request.
/// Thrown if the implementation does not support camera image.
///
///
internal AsyncCameraImageConversionStatus GetAsyncRequestStatus(int requestId)
{
return m_Provider.GetAsyncRequestStatus(requestId);
}
///
/// Dispose an existing native image identified by .
///
/// A unique identifier for this camera image.
/// Thrown if the implementation does not support camera image.
///
///
internal void DisposeImage(int nativeHandle) => m_Provider.DisposeImage(nativeHandle);
///
/// Dispose an existing async conversion request.
///
/// A unique identifier for the request.
/// Thrown if the implementation does not support camera image.
///
///
internal void DisposeAsyncRequest(int requestId) => m_Provider.DisposeAsyncRequest(requestId);
///
/// Attempt to get information about an image plane from a native image by index.
///
/// A unique identifier for this camera image.
/// The index of the plane to get.
/// The returned camera plane information if successful.
///
/// true if the image plane is successfully acquired. Otherwise, false.
///
/// Thrown if the implementation does not support camera image.
///
///
internal bool TryGetPlane(
int nativeHandle,
int planeIndex,
out CameraImagePlaneCinfo planeCinfo)
{
return m_Provider.TryGetPlane(nativeHandle, planeIndex, out planeCinfo);
}
///
/// Determine whether a native image handle returned by is
/// currently valid. An image may become invalid if it has been disposed.
///
///
/// If a handle is valid, and should not fail.
///
/// A unique identifier for the camera image in question.
/// true if it is a valid handle, false otherwise.
/// Thrown if the implementation does not support camera image.
///
///
internal bool NativeHandleValid(int nativeHandle) => m_Provider.NativeHandleValid(nativeHandle);
///
/// Get the number of bytes required to store an image with the given dimensions and TextureFormat.
///
/// A unique identifier for the camera image to convert.
/// The dimensions of the output image.
/// The TextureFormat for the image.
/// The number of bytes required to store the converted image.
/// true if the output was set.
/// Thrown if the implementation does not support camera image.
///
internal bool TryGetConvertedDataSize(
int nativeHandle,
Vector2Int dimensions,
TextureFormat format,
out int size)
{
return m_Provider.TryGetConvertedDataSize(nativeHandle, dimensions, format, out size);
}
///
/// Convert the image with handle using the provided
/// .
///
/// A unique identifier for the camera image to convert.
/// The parameters to use during the conversion.
/// A buffer to write the converted image to.
/// The number of bytes available in the buffer.
///
/// true if the image was converted and stored in .
///
/// Thrown if the implementation does not support camera image.
///
internal bool TryConvert(
int nativeHandle,
XRCameraImageConversionParams conversionParams,
IntPtr destinationBuffer,
int bufferLength)
{
return m_Provider.TryConvert(nativeHandle, conversionParams, destinationBuffer, bufferLength);
}
///
/// Create an asynchronous request to convert a camera image, similar to except the
/// conversion should happen on a thread other than the calling (main) thread.
///
/// A unique identifier for the camera image to convert.
/// The parameters to use during the conversion.
/// A unique identifier for this request.
/// Thrown if the implementation does not support camera image.
///
internal int ConvertAsync(
int nativeHandle,
XRCameraImageConversionParams conversionParams)
{
return m_Provider.ConvertAsync(nativeHandle, conversionParams);
}
///
/// Get a pointer to the image data from a completed asynchronous request. This method should only succeed if
/// returns .
///
/// The unique identifier associated with a request.
/// A pointer to the native buffer containing the data.
/// The number of bytes in .
/// true if and were set and point to
/// the image data.
/// Thrown if the implementation does not support camera image.
///
internal bool TryGetAsyncRequestData(int requestId, out IntPtr dataPtr, out int dataLength)
{
return m_Provider.TryGetAsyncRequestData(requestId, out dataPtr, out dataLength);
}
///
/// Callback from native code for when the asychronous conversion is complete.
///
/// The status of the conversion operation.
/// The parameters for the conversion.
/// The native pointer to the converted data.
/// The memory size of the converted data.
/// The native context for the conversion operation.
protected internal delegate void OnImageRequestCompleteDelegate(
AsyncCameraImageConversionStatus status,
XRCameraImageConversionParams conversionParams,
IntPtr dataPtr,
int dataLength,
IntPtr context);
///
/// Similar to but takes a delegate to invoke
/// when the request is complete, rather than returning a request id.
///
///
/// If the first parameter to is
/// then the dataPtr parameter must be valid for
/// the duration of the invocation. The data may be destroyed immediately upon return. The
/// parameter must be passed back to the .
///
/// A unique identifier for the camera image to convert.
/// The parameters to use during the conversion.
/// A delegate which must be invoked when the request is complete, whether the
/// conversion was successfully or not.
/// A native pointer which must be passed back unaltered to .
///
/// Thrown if the implementation does not support camera image.
///
internal void ConvertAsync(
int nativeHandle,
XRCameraImageConversionParams conversionParams,
OnImageRequestCompleteDelegate callback,
IntPtr context)
{
m_Provider.ConvertAsync(nativeHandle, conversionParams, callback, context);
}
///
/// Container for native camera image construction metadata.
///
protected struct CameraImageCinfo : IEquatable
{
///
/// The handle representing the camera image on the native level.
///
///
/// The handle representing the camera image on the native level.
///
public int nativeHandle => m_NativeHandle;
int m_NativeHandle;
///
/// The dimensions of the camera image.
///
///
/// The dimensions of the camera image.
///
public Vector2Int dimensions => m_Dimensions;
Vector2Int m_Dimensions;
///
/// The number of video planes in the camera image.
///
///
/// The number of video planes in the camera image.
///
public int planeCount => m_PlaneCount;
int m_PlaneCount;
///
/// The timestamp for when the camera image was captured.
///
///
/// The timestamp for when the camera image was captured.
///
public double timestamp => m_Timestamp;
double m_Timestamp;
///
/// The format of the camera image.
///
///
/// The format of the camera image.
///
public CameraImageFormat format => m_Format;
CameraImageFormat m_Format;
///
/// Constructs the camera image cinfo.
///
/// The handle representing the camera image on the native level.
/// The dimensions of the camera image.
/// The number of video planes in the camera image.
/// The timestamp for when the camera image was captured.
/// The format of the camera image.
public CameraImageCinfo(int nativeHandle, Vector2Int dimensions, int planeCount, double timestamp,
CameraImageFormat format)
{
this.m_NativeHandle = nativeHandle;
this.m_Dimensions = dimensions;
this.m_PlaneCount = planeCount;
this.m_Timestamp = timestamp;
this.m_Format = format;
}
public bool Equals(CameraImageCinfo other)
{
return (nativeHandle.Equals(other.nativeHandle) && dimensions.Equals(other.dimensions)
&& planeCount.Equals(other.planeCount) && timestamp.Equals(other.timestamp)
&& format.Equals(other.format));
}
public override bool Equals(System.Object obj)
{
return ReferenceEquals(this, obj) || ((obj is CameraImageCinfo) && Equals((CameraImageCinfo)obj));
}
public static bool operator ==(CameraImageCinfo lhs, CameraImageCinfo rhs) => lhs.Equals(rhs);
public static bool operator !=(CameraImageCinfo lhs, CameraImageCinfo rhs) => !(lhs == rhs);
public override int GetHashCode()
{
int hashCode = 486187739;
unchecked
{
hashCode = (hashCode * 486187739) + nativeHandle.GetHashCode();
hashCode = (hashCode * 486187739) + dimensions.GetHashCode();
hashCode = (hashCode * 486187739) + planeCount.GetHashCode();
hashCode = (hashCode * 486187739) + timestamp.GetHashCode();
hashCode = (hashCode * 486187739) + ((int)format).GetHashCode();
}
return hashCode;
}
public override string ToString()
{
return string.Format("nativeHandle: {0} dimensions:{1} planes:{2} timestamp:{3} format:{4}",
nativeHandle.ToString(), dimensions.ToString(), planeCount.ToString(),
timestamp.ToString(), format.ToString());
}
}
///
/// Container for the metadata describing access to the raw camera image plane data.
///
protected internal struct CameraImagePlaneCinfo : IEquatable
{
///
/// The pointer to the raw native image data.
///
///
/// The pointer to the raw native image data.
///
public IntPtr dataPtr => m_DataPtr;
IntPtr m_DataPtr;
///
/// The length of the native image data.
///
///
/// The length of the native image data.
///
public int dataLength => m_DataLength;
int m_DataLength;
///
/// The stride for iterating through the rows of the native image data.
///
///
/// The stride for iterating through the rows of the native image data.
///
public int rowStride => m_RowStride;
int m_RowStride;
///
/// The stride for iterating through the pixels of the native image data.
///
///
/// The stride for iterating through the pixels of the native image data.
///
public int pixelStride => m_PixelStride;
int m_PixelStride;
///
/// Constructs the camera image plane cinfo.
///
/// The pointer to the raw native image data.
/// The length of the native image data.
/// The stride for iterating through the rows of the native image data.
/// The stride for iterating through the pixels of the native image data.
public CameraImagePlaneCinfo(IntPtr dataPtr, int dataLength, int rowStride, int pixelStride)
{
this.m_DataPtr = dataPtr;
this.m_DataLength = dataLength;
this.m_RowStride = rowStride;
this.m_PixelStride = pixelStride;
}
public bool Equals(CameraImagePlaneCinfo other)
{
return (dataPtr.Equals(other.dataPtr) && dataLength.Equals(other.dataLength)
&& rowStride.Equals(other.rowStride) && pixelStride.Equals(other.pixelStride));
}
public override bool Equals(System.Object obj)
{
return ReferenceEquals(this, obj) || ((obj is CameraImagePlaneCinfo) && Equals((CameraImagePlaneCinfo)obj));
}
public static bool operator ==(CameraImagePlaneCinfo lhs, CameraImagePlaneCinfo rhs) => lhs.Equals(rhs);
public static bool operator !=(CameraImagePlaneCinfo lhs, CameraImagePlaneCinfo rhs) => !(lhs == rhs);
public override int GetHashCode()
{
int hashCode = 486187739;
unchecked
{
hashCode = (hashCode * 486187739) + dataPtr.GetHashCode();
hashCode = (hashCode * 486187739) + dataLength.GetHashCode();
hashCode = (hashCode * 486187739) + rowStride.GetHashCode();
hashCode = (hashCode * 486187739) + pixelStride.GetHashCode();
}
return hashCode;
}
public override string ToString()
{
return string.Format("dataPtr: {0} length:{1} rowStride:{2} pixelStride:{3}", dataPtr.ToString(),
dataLength.ToString(), rowStride.ToString(), pixelStride.ToString());
}
}
}
}