SW 중심대학 OSS GIT 서버 박건태, 이승준, 고기완, 이준호 새로운 배포
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

1025 lines
50 KiB

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