NRPhotoCapture.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. /****************************************************************************
  2. * Copyright 2019 Nreal Techonology Limited. All rights reserved.
  3. *
  4. * This file is part of NRSDK.
  5. *
  6. * https://www.nreal.ai/
  7. *
  8. *****************************************************************************/
  9. namespace NRKernal.Record
  10. {
  11. using System;
  12. using UnityEngine;
  13. using System.Collections.Generic;
  14. /// <summary> A nr photo capture. </summary>
  15. public class NRPhotoCapture : IDisposable
  16. {
  17. private const int CameraDataReadyTimeOut = 3000;
  18. /// <summary> The supported resolutions. </summary>
  19. private static IEnumerable<Resolution> m_SupportedResolutions;
  20. /// <summary> A list of all the supported device resolutions for taking pictures. </summary>
  21. /// <value> The supported resolutions. </value>
  22. public static IEnumerable<Resolution> SupportedResolutions
  23. {
  24. get
  25. {
  26. if (m_SupportedResolutions == null)
  27. {
  28. var resolutions = new List<Resolution>();
  29. var resolution = new Resolution();
  30. NativeResolution rgbResolution = new NativeResolution(1280, 720);
  31. if (NRDevice.Subsystem.IsFeatureSupported(NRSupportedFeature.NR_FEATURE_RGB_CAMERA))
  32. rgbResolution = NRFrame.GetDeviceResolution(NativeDevice.RGB_CAMERA);
  33. resolution.width = rgbResolution.width;
  34. resolution.height = rgbResolution.height;
  35. resolutions.Add(resolution);
  36. m_SupportedResolutions = resolutions;
  37. }
  38. return m_SupportedResolutions;
  39. }
  40. }
  41. /// <summary> Context for the capture. </summary>
  42. private FrameCaptureContext m_CaptureContext;
  43. /// <summary> Gets the preview texture. </summary>
  44. /// <value> The preview texture. </value>
  45. public Texture PreviewTexture
  46. {
  47. get
  48. {
  49. return m_CaptureContext?.PreviewTexture;
  50. }
  51. }
  52. /// <summary> Creates an asynchronous. </summary>
  53. /// <param name="showHolograms"> True to show, false to hide the holograms.</param>
  54. /// <param name="onCreatedCallback"> The on created callback.</param>
  55. public static void CreateAsync(bool showHolograms, OnCaptureResourceCreatedCallback onCreatedCallback)
  56. {
  57. NRPhotoCapture photocapture = new NRPhotoCapture();
  58. photocapture.m_CaptureContext = FrameCaptureContextFactory.Create();
  59. onCreatedCallback?.Invoke(photocapture);
  60. }
  61. /// <summary> Dispose must be called to shutdown the PhotoCapture instance. </summary>
  62. public void Dispose()
  63. {
  64. if (m_CaptureContext != null)
  65. {
  66. m_CaptureContext.Release();
  67. m_CaptureContext = null;
  68. }
  69. }
  70. /// <summary>
  71. /// Provides a COM pointer to the native IVideoDeviceController. A native COM pointer to the
  72. /// IVideoDeviceController. </summary>
  73. /// <returns> The unsafe pointer to video device controller. </returns>
  74. public IntPtr GetUnsafePointerToVideoDeviceController()
  75. {
  76. NRDebugger.Warning("[NRPhotoCapture] Interface not supported...");
  77. return IntPtr.Zero;
  78. }
  79. /// <summary> Starts photo mode asynchronous. </summary>
  80. /// <param name="setupParams"> Options for controlling the setup.</param>
  81. /// <param name="onPhotoModeStartedCallback"> The on photo mode started callback.</param>
  82. /// <param name="autoAdaptBlendMode"> Auto adaption for BlendMode based on supported feature on current device.</param>
  83. public void StartPhotoModeAsync(CameraParameters setupParams, OnPhotoModeStartedCallback onPhotoModeStartedCallback, bool autoAdaptBlendMode = false)
  84. {
  85. PhotoCaptureResult result = new PhotoCaptureResult();
  86. try
  87. {
  88. setupParams.camMode = CamMode.PhotoMode;
  89. if (autoAdaptBlendMode)
  90. {
  91. var blendMode = m_CaptureContext.AutoAdaptBlendMode(setupParams.blendMode);
  92. if (blendMode != setupParams.blendMode)
  93. {
  94. NRDebugger.Warning("[PhotoCapture] AutoAdaptBlendMode : {0} => {1}", setupParams.blendMode, blendMode);
  95. setupParams.blendMode = blendMode;
  96. }
  97. }
  98. if (setupParams.frameRate <= 0)
  99. NRDebugger.Warning("[PhotoCapture] frameRate need to be bigger than zero");
  100. m_CaptureContext.StartCaptureMode(setupParams);
  101. m_CaptureContext.StartCapture();
  102. NRKernalUpdater.Instance.StartCoroutine(OnPhotoModeStartedReady((ready) =>
  103. {
  104. if (ready)
  105. {
  106. result.resultType = CaptureResultType.Success;
  107. }
  108. else
  109. {
  110. result.resultType = CaptureResultType.TimeOutError;
  111. }
  112. onPhotoModeStartedCallback?.Invoke(result);
  113. }));
  114. }
  115. catch (Exception)
  116. {
  117. result.resultType = CaptureResultType.UnknownError;
  118. onPhotoModeStartedCallback?.Invoke(result);
  119. throw;
  120. }
  121. }
  122. /// <summary> Executes the 'photo mode started ready' action. </summary>
  123. /// <param name="callback"> The callback.</param>
  124. /// <returns> A list of. </returns>
  125. private System.Collections.IEnumerator OnPhotoModeStartedReady(Action<bool> callback)
  126. {
  127. System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
  128. stopwatch.Start();
  129. while (!this.m_CaptureContext.GetFrameProvider().IsFrameReady())
  130. {
  131. if (stopwatch.ElapsedMilliseconds > CameraDataReadyTimeOut)
  132. {
  133. callback?.Invoke(false);
  134. NRDebugger.Error("[PhotoCapture] Get rgbcamera data timeout...");
  135. yield break;
  136. }
  137. NRDebugger.Debug("[PhotoCapture] Wait for the first frame ready...");
  138. yield return new WaitForEndOfFrame();
  139. }
  140. yield return new WaitForEndOfFrame();
  141. yield return new WaitForEndOfFrame();
  142. yield return new WaitForEndOfFrame();
  143. callback?.Invoke(true);
  144. }
  145. /// <summary> Stops photo mode asynchronous. </summary>
  146. /// <param name="onPhotoModeStoppedCallback"> The on photo mode stopped callback.</param>
  147. public void StopPhotoModeAsync(OnPhotoModeStoppedCallback onPhotoModeStoppedCallback)
  148. {
  149. PhotoCaptureResult result = new PhotoCaptureResult();
  150. try
  151. {
  152. m_CaptureContext.StopCaptureMode();
  153. result.resultType = CaptureResultType.Success;
  154. onPhotoModeStoppedCallback?.Invoke(result);
  155. }
  156. catch (Exception)
  157. {
  158. result.resultType = CaptureResultType.UnknownError;
  159. onPhotoModeStoppedCallback?.Invoke(result);
  160. throw;
  161. }
  162. }
  163. /// <summary> Take photo asynchronous. </summary>
  164. /// <param name="filename"> Filename of the file.</param>
  165. /// <param name="fileOutputFormat"> The file output format.</param>
  166. /// <param name="onCapturedPhotoToDiskCallback"> The on captured photo disk callback.</param>
  167. public void TakePhotoAsync(string filename, PhotoCaptureFileOutputFormat fileOutputFormat, OnCapturedToDiskCallback onCapturedPhotoToDiskCallback)
  168. {
  169. try
  170. {
  171. var capture = m_CaptureContext.GetBehaviour();
  172. ((NRCaptureBehaviour)capture).Do(filename, fileOutputFormat);
  173. }
  174. catch (Exception)
  175. {
  176. throw;
  177. }
  178. }
  179. /// <summary> Take photo asynchronous. </summary>
  180. /// <param name="onCapturedPhotoToMemoryCallback"> The on captured photo memory callback.</param>
  181. public void TakePhotoAsync(OnCapturedToMemoryCallback onCapturedPhotoToMemoryCallback)
  182. {
  183. try
  184. {
  185. var capture = m_CaptureContext.GetBehaviour();
  186. ((NRCaptureBehaviour)capture).DoAsyn(onCapturedPhotoToMemoryCallback);
  187. }
  188. catch (Exception)
  189. {
  190. throw;
  191. }
  192. }
  193. /// <summary> Contains the result of the capture request. </summary>
  194. public enum CaptureResultType
  195. {
  196. /// <summary>
  197. /// Specifies that the desired operation was successful.
  198. /// </summary>
  199. Success = 0,
  200. /// <summary>
  201. /// Specifies that an unknown error occurred.
  202. /// </summary>
  203. UnknownError = 1,
  204. /// <summary>
  205. /// Get rgb camera data timeout.
  206. /// </summary>
  207. TimeOutError = 2,
  208. }
  209. /// <summary>
  210. /// A data container that contains the result information of a photo capture operation. </summary>
  211. public struct PhotoCaptureResult
  212. {
  213. /// <summary>
  214. /// A generic result that indicates whether or not the PhotoCapture operation succeeded. </summary>
  215. public CaptureResultType resultType;
  216. /// <summary> The specific HResult value. </summary>
  217. public long hResult;
  218. /// <summary> Indicates whether or not the operation was successful. </summary>
  219. /// <value> True if success, false if not. </value>
  220. public bool success
  221. {
  222. get
  223. {
  224. return resultType == CaptureResultType.Success;
  225. }
  226. }
  227. }
  228. /// <summary> Called when a PhotoCapture resource has been created. </summary>
  229. /// <param name="captureObject"> The PhotoCapture instance.</param>
  230. public delegate void OnCaptureResourceCreatedCallback(NRPhotoCapture captureObject);
  231. /// <summary> Called when photo mode has been started. </summary>
  232. /// <param name="result"> Indicates whether or not photo mode was successfully activated.</param>
  233. public delegate void OnPhotoModeStartedCallback(PhotoCaptureResult result);
  234. /// <summary> Called when photo mode has been stopped. </summary>
  235. /// <param name="result"> Indicates whether or not photo mode was successfully deactivated.</param>
  236. public delegate void OnPhotoModeStoppedCallback(PhotoCaptureResult result);
  237. /// <summary> Called when a photo has been saved to the file system. </summary>
  238. /// <param name="result"> Indicates whether or not the photo was successfully saved to the file
  239. /// system.</param>
  240. public delegate void OnCapturedToDiskCallback(PhotoCaptureResult result);
  241. /// <summary> Called when a photo has been captured to memory. </summary>
  242. /// <param name="result"> Indicates whether or not the photo was successfully captured
  243. /// to memory.</param>
  244. /// <param name="photoCaptureFrame"> Contains the target texture.If available, the spatial
  245. /// information will be accessible through this structure as well.</param>
  246. public delegate void OnCapturedToMemoryCallback(PhotoCaptureResult result, PhotoCaptureFrame photoCaptureFrame);
  247. }
  248. }