HardwareUdpJpegViewer.cs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. using System;
  2. using LightGlue.Unity.Networking;
  3. using LightGlue.Unity.Bridge;
  4. using LightGlue.Unity.Game;
  5. using UnityEngine;
  6. using UnityEngine.UI;
  7. namespace LightGlue.Unity.Demo
  8. {
  9. /// <summary>
  10. /// Demo: 从 HardwareToPythonUdpBridge 共享 JPEG 接收器,在 RawImage 上显示硬件图像。
  11. /// 仅支持 Shared 模式(强制复用 Bridge 的 UDPJpegReceiver,避免端口冲突)。
  12. /// </summary>
  13. public sealed class HardwareUdpJpegViewer : MonoBehaviour
  14. {
  15. [Header("Source (Shared Only)")]
  16. [Tooltip("HardwareToPythonUdpBridge组件(共享其JPEG接收器,避免端口冲突)")]
  17. public HardwareToPythonUdpBridge bridge;
  18. [Header("UI")]
  19. public RawImage target;
  20. [Tooltip("是否在没有贴图时自动创建 Texture2D。")]
  21. public bool autoCreateTexture = true;
  22. private Texture2D _tex;
  23. private void Start()
  24. {
  25. // 优先从全局 LightGlueManager 获取 Bridge(如果未在 Inspector 指定)
  26. if (bridge == null && LightGlueManager.Instance != null)
  27. {
  28. bridge = LightGlueManager.Instance.bridge;
  29. }
  30. if (bridge == null)
  31. {
  32. Debug.LogWarning("[Viewer] HardwareUdpJpegViewer 需要 HardwareToPythonUdpBridge 引用,请在 Inspector 中指定或确保存在 LightGlueManager 实例。");
  33. }
  34. else
  35. {
  36. Debug.Log("[Viewer] Using shared receiver from HardwareToPythonUdpBridge (no port conflict)");
  37. }
  38. }
  39. private void OnDisable()
  40. {
  41. // Shared 模式下不管理 Bridge 内部的接收器,这里无需额外清理
  42. }
  43. private float _lastDecodeFailLogTime = -1f;
  44. private void Update()
  45. {
  46. byte[] latest = null;
  47. if (bridge == null) return;
  48. latest = bridge.GetLatestJpeg();
  49. if (latest == null || latest.Length < 4) return;
  50. // 只尝试解码形似完整 JPEG 的缓冲(SOI+EOI),避免对 UDP 组帧残片反复解码并刷日志
  51. if (latest[0] != 0xFF || latest[1] != 0xD8 || latest[latest.Length - 2] != 0xFF || latest[latest.Length - 1] != 0xD9)
  52. return;
  53. if (target == null) return;
  54. if (_tex == null)
  55. {
  56. if (!autoCreateTexture) return;
  57. _tex = new Texture2D(2, 2, TextureFormat.RGB24, mipChain: false);
  58. _tex.wrapMode = TextureWrapMode.Clamp;
  59. _tex.filterMode = FilterMode.Bilinear;
  60. target.texture = _tex;
  61. }
  62. bool ok = _tex.LoadImage(latest, markNonReadable: false);
  63. if (!ok)
  64. {
  65. if (Time.unscaledTime - _lastDecodeFailLogTime >= 1f)
  66. {
  67. _lastDecodeFailLogTime = Time.unscaledTime;
  68. Debug.LogWarning($"[Viewer] Failed to decode JPEG (size: {latest.Length} bytes)");
  69. }
  70. }
  71. }
  72. }
  73. }