@displayxr/inline3d 1.49.1 → 1.49.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,49 @@ entry points (`.`, `./three`) are frozen for 1.x, while the **scene subpaths** (
5
5
  `./splat`, `./model`) are a preview tier whose options may change in any release. Entries below say
6
6
  which tier they touch, because that is what tells you whether an upgrade can move your pixels.
7
7
 
8
+ ## 1.49.3 — 2026-11-04
9
+
10
+ ### Fixed — a camera view is not "woven" before the camera's first frame; `frameAgeMs` tells a stalled track (`.`, `./camera`, `./call`)
11
+
12
+ Core and preview tier. A camera view (`addCameraView`, and the call's self view, which is one)
13
+ registers its tile on the wall with an SBS buffer it fills from the camera. That buffer started
14
+ as a blank default 300x150 canvas, and the wall counted any image source as a stereo frame, so
15
+ `firstWoven` settled `woven: true` (`hold-elapsed`) on a tile that had never shown the camera.
16
+ On an Android 3D tablet whose camera track was `live` but delivered no frames, the call reported
17
+ the self view woven over a black tile.
18
+
19
+ - **Core:** an `addImage` source that is a canvas or image with no pixels (0x0) is not a stereo
20
+ frame: `firstWoven` / `rewoven()` wait for one. Sources that report no size keep the old rule.
21
+ - **`./camera`:** the woven buffer starts 0x0 until the first camera frame is painted into it.
22
+ - **New: `view.frameAgeMs`** and `weaveState().frameAgeMs` (also `call.diagnostics().self`): ms
23
+ since the camera last delivered a new frame to the view, null before the first. A stalled track
24
+ keeps its last frame on screen; a growing age is how a page shows "no video".
25
+
26
+ ## 1.49.2 — 2026-11-04
27
+
28
+ ### Fixed — the camera probe waits for the DisplayXR 3D camera before opening a plain lens (`./camera`, `./call`)
29
+
30
+ Preview tier. In a DisplayXR Browser the runtime lists its 3D camera lazily. On a phone it is
31
+ missing from the list right after a runtime restart, or after the camera service restarted. With
32
+ the 3D camera absent, `camera: 'auto'` read the list once more and then opened the plain front lens.
33
+ On some phones that open crashes the camera HAL while head tracking streams. The HAL restart takes
34
+ the 3D camera down again, so the call never got it back: the self view stayed 2D, or the call
35
+ reported "Camera busy".
36
+
37
+ - **The wait:** with camera labels visible and no stereo-named device listed, `'auto'` / `'stereo'`
38
+ now wait up to `stereoWaitMs` (new option, default **2500 ms in a DisplayXR Browser**, 0
39
+ elsewhere) before opening any plain lens. They re-read the list on every `devicechange` and every
40
+ 500 ms, and open the 3D camera as soon as it appears. `'mono'`, an explicit `deviceId` and
41
+ `label:` never wait. The rule is in [`docs/camera.md`](docs/camera.md), "Waiting for the 3D camera".
42
+ - **No shape probe of a second lens in a DisplayXR Browser:** once a plain lens is in hand, the
43
+ last-resort probe no longer opens the other plain lenses to test whether one is a side-by-side
44
+ pair. There, a stereo webcam (a USB SBS one included, through the runtime's UVC source) is the
45
+ runtime's named "3D Camera". The extra open is the one that can crash a phone's camera HAL. Other
46
+ browsers keep the shape probe, which is how a USB stereo webcam is found there.
47
+ - **Pinned:** when the default camera opens but delivers no picture (0x0), a lens that opens by id
48
+ is kept as the fallback, never stopped and reported as busy. This has worked since 1.48.0; a test
49
+ now covers it.
50
+
8
51
  ## 1.49.1 — 2026-11-03
9
52
 
10
53
  ### Fixed — app share on browsers without the app-share device patch (`./call`, `./camera`)
package/camera.d.ts CHANGED
@@ -73,6 +73,13 @@ export interface CameraOptions {
73
73
  * list off. An explicit `deviceId` or `label:` (`prefer`) is your choice and is opened regardless.
74
74
  */
75
75
  exclude?: ReadonlyArray<string | RegExp> | false;
76
+ /**
77
+ * `'auto'` / `'stereo'` with labels visible and no 3D camera listed: how long (ms) to wait for
78
+ * the runtime's 3D camera to be listed before any plain lens is opened. Default 2500 in a
79
+ * DisplayXR Browser, 0 elsewhere (one re-read of the list). Opening a phone lens while head
80
+ * tracking streams can crash the camera HAL on some devices and take the 3D camera down with it.
81
+ */
82
+ stereoWaitMs?: number;
76
83
  /** Verbose console logging. */
77
84
  debug?: boolean;
78
85
  }
@@ -278,6 +285,11 @@ export interface CameraViewWeaveState {
278
285
  firstWoven: { woven: boolean; confirmed: boolean; reason: string | null; ms: number } | 'pending' | null;
279
286
  /** Layer re-registrations attempted after a `'layer-failed'` (bounded; reset by a woven result). */
280
287
  layerRetries: number;
288
+ /**
289
+ * Milliseconds since the camera last delivered a new frame to the view, or null before the first.
290
+ * A stalled track keeps its last frame on screen; a growing age is how a page shows "no video".
291
+ */
292
+ frameAgeMs: number | null;
281
293
  }
282
294
 
283
295
  /** A self view from {@link addCameraView}. */