UVCManager.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. #define ENABLE_LOG
  2. #define DEBUG
  3. /*
  4. * Copyright (c) 2014 - 2022 t_saki@serenegiant.com
  5. */
  6. using AOT;
  7. using System;
  8. using System.Collections;
  9. using System.Collections.Generic;
  10. using System.Runtime.CompilerServices;
  11. using System.Runtime.InteropServices;
  12. using System.Threading;
  13. using UnityEngine;
  14. using UnityEngine.Events;
  15. #if UNITY_ANDROID && UNITY_2018_3_OR_NEWER
  16. using UnityEngine.Android;
  17. #endif
  18. namespace SLAMUVC
  19. {
  20. //[RequireComponent(typeof(UVCInterface))]
  21. public class UVCManager : MonoBehaviour
  22. {
  23. private const string TAG = "UVCManager#";
  24. //--------------------------------------------------------------------------------
  25. public Int32 DefaultWidth = 1280;
  26. public Int32 DefaultHeight = 720;
  27. //前端这里默认是none,只记录前端,不传给dll,dll自己有默认的旋转
  28. public CameraMirror DefaultMirror = CameraMirror.NONE;
  29. protected UVCInterface _interface;
  30. /**
  31. * 保持正在使用的相机信息
  32. */
  33. public class CameraInfo
  34. {
  35. //internal readonly UVCDevice device;
  36. internal UVCInterface uvcInterface;
  37. internal Texture previewTexture;
  38. internal int frameType;
  39. internal volatile Int32 activeId;
  40. private Int32 currentWidth;
  41. private Int32 currentHeight;
  42. //校准时候使用的分辨率
  43. Vector2 CalibrationResolution = new Vector2(1280, 720);//"1280x720";
  44. //识别的最高分辨率
  45. Vector2 HighResolution = new Vector2(320, 240);//"320x240";
  46. //识别的最低分辨率
  47. Vector2 LowResolution = new Vector2(160, 120);// "160x120";
  48. //摄像机参数
  49. private Dictionary<string, UVCCtrlInfo> ctrlInfos = new Dictionary<string, UVCCtrlInfo>();
  50. //当前摄像机分辨率
  51. private Dictionary<string, Vector2> resolutionInfos = new Dictionary<string, Vector2>();
  52. //PC测试用
  53. internal CameraInfo(Texture texture)
  54. {
  55. // this.device = null;
  56. activeId = 1;
  57. previewTexture = texture;
  58. SetSize(texture.width, texture.height);
  59. }
  60. internal CameraInfo(UVCInterface _uvcInterface)
  61. {
  62. this.uvcInterface = _uvcInterface;
  63. }
  64. /**
  65. * 是否正在获取图像
  66. */
  67. public bool IsPreviewing
  68. {
  69. get { return (activeId != 0) && (previewTexture != null); }
  70. }
  71. /**
  72. * 当前分辨率(宽度)
  73. * 如果不在预览中则为0
  74. */
  75. public Int32 CurrentWidth
  76. {
  77. get { return currentWidth; }
  78. }
  79. /**
  80. * 当前分辨率(高度)
  81. * 如果不在预览中则为0
  82. */
  83. public Int32 CurrentHeight
  84. {
  85. get { return currentHeight; }
  86. }
  87. /**
  88. * 返回一个尺寸
  89. */
  90. public Vector2 Size => new Vector2(currentWidth, currentHeight);
  91. public Vector2Int IndexToCoord(int i)
  92. {
  93. var y = i / currentWidth;
  94. var x = i % currentWidth;
  95. return new Vector2Int(x, y);
  96. }
  97. public int CoordToIndex(int x, int y)
  98. {
  99. return y * currentWidth + x;
  100. }
  101. /**
  102. * 修改当前分辨率
  103. * @param width
  104. * @param height
  105. */
  106. internal bool SetSize(Int32 width, Int32 height)
  107. {
  108. bool bChange = false;
  109. if (width != currentWidth || height != currentHeight)
  110. {
  111. bChange = true;
  112. currentWidth = width;
  113. currentHeight = height;
  114. }
  115. Debug.Log("CameraInfo设置SetSize,大小变化:" + bChange + ",Size:[" + width + "," + height + "]");
  116. return bChange;
  117. }
  118. /**
  119. * 当前默认分辨率
  120. */
  121. public Vector2 CurrentCalibrationResolution
  122. {
  123. get { return CalibrationResolution; }
  124. }
  125. /**
  126. * 当前默认校准时候高分辨率
  127. */
  128. public Vector2 CurrentHighResolution
  129. {
  130. get { return HighResolution; }
  131. }
  132. /**
  133. * 当前默认最低分辨率
  134. */
  135. public Vector2 CurrentLowResolution
  136. {
  137. get { return LowResolution; }
  138. }
  139. /**
  140. * 修改相机的分辨率,相机分辨率修改成功回调后才修改 本地分辨率
  141. * @param width
  142. * @param height
  143. */
  144. internal bool SetCameraSize(Int32 width, Int32 height)
  145. {
  146. bool bChange = false;
  147. if (width != currentWidth || height != currentHeight)
  148. {
  149. bChange = true;
  150. uvcInterface?.ChangeCameraInfo(width, height);
  151. }
  152. return bChange;
  153. }
  154. /**
  155. * 更新支持的分辨率
  156. */
  157. public void UpdateResolution()
  158. {
  159. string[] resolutions = uvcInterface.GetSupportedResolutions();
  160. resolutionInfos.Clear();
  161. //resolutions 数组是从大到小
  162. for (int i = 0; i < resolutions.Length; i++)
  163. {
  164. string resolution = resolutions[i];
  165. string[] res = resolution.ToString().Split('x');
  166. resolutionInfos.Add(resolution, new Vector2(int.Parse(res[0]), int.Parse(res[1])));
  167. }
  168. }
  169. /**
  170. * 获取分辨率的key: 1280 * 720
  171. */
  172. public List<string> GetResolutionsStrs()
  173. {
  174. return new List<string>(resolutionInfos.Keys);
  175. }
  176. /**
  177. * 获取分辨率的values:Vector2(1280,720)
  178. */
  179. public List<Vector2> GetResolutionsVec2s()
  180. {
  181. return new List<Vector2>(resolutionInfos.Values);
  182. }
  183. /**
  184. * 是否存在分辨率
  185. */
  186. public bool ContainsResulutionKey(string type)
  187. {
  188. return resolutionInfos.ContainsKey(type);
  189. }
  190. /**
  191. * 更新支持的 UVC 控制/处理功能信息
  192. */
  193. public void UpdateCtrls()
  194. {
  195. uvcInterface.GetUvcCtrlList();
  196. ctrlInfos.Clear();
  197. foreach (UVCCtrl ctrl in uvcInterface.UVCCtrls)
  198. {
  199. if (ctrl.name == "PU_BRIGHTNESS")
  200. Debug.Log($"name:{ctrl.name}, limit: {string.Join(", ", ctrl.limit)}, value: {ctrl.value}, 转插件值后: {ctrl.value / 1000f}");
  201. else if (ctrl.name == "PU_CONTRAST")
  202. Debug.Log($"name:{ctrl.name}, limit: {string.Join(", ", ctrl.limit)}, value: {ctrl.value}, 转插件值后: {ctrl.value / 100f}");
  203. ctrlInfos.Add(ctrl.name,
  204. new UVCCtrlInfo
  205. {
  206. name = ctrl.name,
  207. current = ctrl.value,
  208. min = ctrl.limit != null && ctrl.limit.Length > 0 ? ctrl.limit[0] : 0,
  209. max = ctrl.limit != null && ctrl.limit.Length > 1 ? ctrl.limit[1] : 0,
  210. def = ctrl.limit != null && ctrl.limit.Length > 2 ? ctrl.limit[2] : 0
  211. });
  212. }
  213. }
  214. /**
  215. * 获取支持的 UVC 控制/处理功能的类型列表
  216. */
  217. public List<string> GetCtrls()
  218. {
  219. return new List<string>(ctrlInfos.Keys);
  220. }
  221. /**
  222. * 获取指定 UVC 控制/处理功能的信息
  223. * @param type
  224. * @return UVCCtrlInfo
  225. * @throws ArgumentOutOfRangeException
  226. */
  227. public UVCCtrlInfo GetInfo(string type)
  228. {
  229. if (ctrlInfos.ContainsKey(type))
  230. {
  231. return ctrlInfos.GetValueOrDefault(type, new UVCCtrlInfo());
  232. }
  233. else
  234. {
  235. throw new ArgumentOutOfRangeException($"不支持的控制类型{type:X}");
  236. }
  237. }
  238. public bool ContainsKey(string type)
  239. {
  240. return ctrlInfos.ContainsKey(type);
  241. }
  242. /**
  243. * 获取 UVC 控制/处理功能的设置值
  244. * @param type
  245. * @return 变更后的值
  246. * @throws ArgumentOutOfRangeException
  247. * @throws Exception
  248. */
  249. public Int32 GetValue(string type)
  250. {
  251. if (ctrlInfos.ContainsKey(type))
  252. {
  253. var r = ctrlInfos.GetValueOrDefault(type, new UVCCtrlInfo());
  254. if (r.name != null)
  255. {
  256. return r.current;
  257. }
  258. else
  259. {
  260. throw new Exception($"获取控制值失败,type={type},err={r}");
  261. }
  262. }
  263. else
  264. {
  265. throw new ArgumentOutOfRangeException($"不支持的控制类型{type:X}");
  266. }
  267. }
  268. /**
  269. * 修改 UVC 控制/处理功能的设置
  270. * @param type
  271. * @param value
  272. * @return 变更后的值
  273. * @throws ArgumentOutOfRangeException
  274. * @throws Exception
  275. */
  276. public Int32 SetValue(string type, Int32 value)
  277. {
  278. if (ctrlInfos.ContainsKey(type))
  279. {
  280. var r = uvcInterface.SetCtrlValue(type, value);
  281. if (r == 0)
  282. {
  283. UpdateCtrls(); // 同步刷列表
  284. var info = ctrlInfos.GetValueOrDefault(type, new UVCCtrlInfo());
  285. info.current = value;
  286. ctrlInfos[type] = info;
  287. return value;
  288. }
  289. else
  290. {
  291. Debug.LogError($"设置控制值失败,type={type},err={r}");
  292. }
  293. }
  294. else
  295. {
  296. Debug.LogError($"不支持的控制类型{type:X}");
  297. }
  298. return 0;
  299. }
  300. public override string ToString()
  301. {
  302. return $"{base.ToString()}({currentWidth}x{currentHeight},activeId={activeId},IsPreviewing={IsPreviewing})";
  303. }
  304. } // CameraInfo
  305. /**
  306. * 获取映像中的 UVC 设备映射
  307. */
  308. private CameraInfo cameraInfo;
  309. /// <summary>
  310. /// 开始事件
  311. /// </summary>
  312. [HideInInspector]
  313. public UnityEvent<CameraInfo> startUVCManager;
  314. /// <summary>
  315. /// 更新事件
  316. /// </summary>
  317. [HideInInspector]
  318. public UnityEvent<bool> updateUVCManager;
  319. private bool bInit = false;
  320. private void Awake()
  321. {
  322. // _interface = GetComponent<UVCInterface>();
  323. #if UNITY_IOS
  324. _interface = gameObject.AddComponent<UVCInterface_IOS>();
  325. #elif UNITY_ANDROID
  326. _interface = gameObject.AddComponent<UVCInterface_Android>();
  327. #else
  328. Debug.LogError("Unsupported platform!");
  329. #endif
  330. _interface.systemCameraPermissionHandle += () =>
  331. {
  332. //授权系统相机之后,初始化红外相机
  333. initUVCManagerCamera();
  334. };
  335. }
  336. private void Start()
  337. {
  338. //initUVCManagerCamera();
  339. }
  340. /// <summary>
  341. /// 初始化相机系统
  342. /// </summary>
  343. public void initUVCManagerCamera()
  344. {
  345. _interface.cameraTextureHandle += () =>
  346. {
  347. Debug.Log("cameraTextureHandle");
  348. if (_interface.CameraTexture == null)
  349. {
  350. Debug.LogError("[Error] CameraTexture is NULL!");
  351. return;
  352. }
  353. var info = GetCamera();
  354. if (info == null)
  355. {
  356. Debug.LogError("[Error] GetCamera() returned NULL!");
  357. return;
  358. }
  359. //bChange反馈是否变化宽高
  360. bool bChange = info.SetSize(_interface.CameraTexture.width, _interface.CameraTexture.height);
  361. info.previewTexture = _interface.CameraTexture;
  362. info.activeId = 1;
  363. if (bInit)
  364. {
  365. //之后的触发的重新创建纹理更新
  366. updateUVCManager?.Invoke(bChange);
  367. }
  368. else
  369. {
  370. /**
  371. * 第一次更新触发初始化
  372. */
  373. info.UpdateCtrls();//获取摄像机参数
  374. info.UpdateResolution();//获取摄像机分辨率
  375. startUVCManager?.Invoke(info);
  376. // StartCoroutine(DelayGetInfo(info));
  377. }
  378. bInit = true;
  379. };
  380. //初始化相机,连接设备时候自动开启渲染
  381. if (DefaultMirror == CameraMirror.NONE)
  382. {
  383. _interface.InitCamera(DefaultWidth, DefaultHeight);
  384. }
  385. else {
  386. _interface.InitCamera(DefaultWidth, DefaultHeight, DefaultMirror);
  387. }
  388. }
  389. /// <summary>
  390. /// 延迟一下获取操作参数
  391. /// </summary>
  392. /// <param name="info"></param>
  393. /// <returns></returns>
  394. //IEnumerator DelayGetInfo(CameraInfo info)
  395. //{
  396. // yield return new WaitForSecondsRealtime(0.5f);
  397. //}
  398. /// <summary>
  399. /// 开启渲染
  400. /// </summary>
  401. public void onStartPreview()
  402. {
  403. _interface.OpenCamera();
  404. }
  405. /// <summary>
  406. /// 停止渲染
  407. /// </summary>
  408. public void onStopPreview()
  409. {
  410. _interface.CloseCamera();
  411. //重置cameraInfo的参数
  412. var info = GetCamera();
  413. info.SetSize(0, 0);
  414. info.previewTexture = null;
  415. info.activeId = 0;
  416. }
  417. /**
  418. * 获取与指定的 UVC 识别字符串对应的 CameraInfo
  419. * @param device
  420. * @return 如果已注册,则返回 CameraInfo;如果未注册,则返回 New CameraInfo
  421. */
  422. /*Nullable*/
  423. private CameraInfo GetCamera()
  424. {
  425. if (cameraInfo == null)
  426. cameraInfo = new CameraInfo(_interface);
  427. return cameraInfo;
  428. }
  429. /**
  430. * 水平翻转
  431. */
  432. public void FlipHorizontally()
  433. {
  434. _interface.FlipHorizontally();
  435. }
  436. /**
  437. * 垂直翻转
  438. */
  439. public void FlipVertically() {
  440. _interface.FlipVertically();
  441. }
  442. public void DoubleFlip() {
  443. _interface.DoubleFlip();
  444. }
  445. public void FlipDefault() {
  446. _interface.FlipDefault();
  447. }
  448. }
  449. }