livedesk 0.1.152 → 0.1.153

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.
@@ -33,6 +33,7 @@ let encoderCandidates = [];
33
33
  let encoderOutputSeen = false;
34
34
  let encoderRestartTimer = null;
35
35
  let encoderStartupTimer = null;
36
+ let inputWaitTimer = null;
36
37
  let outputBuffer = Buffer.alloc(0);
37
38
  let frameSeq = 0;
38
39
  let tickTimer = null;
@@ -222,7 +223,9 @@ function emitEncodedUnit(payload) {
222
223
  hardwareEncoder: encoder?.candidate?.name || '',
223
224
  layoutVersion,
224
225
  composeMs: lastComposeMs,
225
- poolStarved
226
+ poolStarved,
227
+ readyTileCount: latestTiles.size,
228
+ tileCount: config.deviceIds.length
226
229
  }
227
230
  });
228
231
  }
@@ -295,6 +298,10 @@ function ingestFrame(message) {
295
298
  const rgb565 = decodeLzo1xBlock(new Uint8Array(compressed), expectedLength);
296
299
  const tileState = { width, height, rgb565, rendered: null, frameSeq: Number(message.frameSeq || 0) };
297
300
  latestTiles.set(deviceId, tileState);
301
+ if (config.deviceIds.length > 0 && config.deviceIds.every(id => latestTiles.has(id))) {
302
+ clearTimeout(inputWaitTimer);
303
+ inputWaitTimer = null;
304
+ }
298
305
  const tileLayout = layout.find(item => item.deviceId === deviceId);
299
306
  if (tileLayout) renderTile(tileState, tileLayout);
300
307
  } catch (error) {
@@ -303,6 +310,7 @@ function ingestFrame(message) {
303
310
  }
304
311
 
305
312
  function writeAtlasFrame() {
313
+ if (latestTiles.size === 0) return;
306
314
  const composeStartedAt = performance.now();
307
315
  const target = framePool.pop();
308
316
  const stdin = encoder?.child?.stdin;
@@ -354,6 +362,17 @@ function configure(value) {
354
362
  const encoderChanged = next.width !== config.width || next.height !== config.height || next.fps !== config.fps;
355
363
  config = next;
356
364
  latestTiles = new Map([...latestTiles].filter(([deviceId]) => config.deviceIds.includes(deviceId)));
365
+ clearTimeout(inputWaitTimer);
366
+ inputWaitTimer = config.deviceIds.length > 0 ? setTimeout(() => {
367
+ const missing = config.deviceIds.filter(deviceId => !latestTiles.has(deviceId));
368
+ if (missing.length > 0) {
369
+ send({
370
+ type: 'log',
371
+ level: 'warn',
372
+ message: `Mode 4 waiting for Mode 2 input from ${missing.length}/${config.deviceIds.length} devices: ${missing.slice(0, 8).join(', ')}`
373
+ });
374
+ }
375
+ }, 3000) : null;
357
376
  rebuildLayout();
358
377
  if (encoderChanged || !encoder) {
359
378
  stopEncoder();
@@ -374,6 +393,7 @@ function shutdown() {
374
393
  if (closed) return;
375
394
  closed = true;
376
395
  clearTimeout(tickTimer);
396
+ clearTimeout(inputWaitTimer);
377
397
  stopEncoder();
378
398
  setTimeout(() => process.exit(0), 50).unref?.();
379
399
  }
@@ -4588,6 +4588,7 @@ export function createRemoteHub(options = {}) {
4588
4588
  if (device.activeLiveStream?.streamId === streamId
4589
4589
  && options.forceRestart !== true
4590
4590
  && options.reuseExisting === true
4591
+ && liveStreamMatchesOptions(device.activeLiveStream, normalized)
4591
4592
  && liveStreamIsReusable(device.activeLiveStream)) {
4592
4593
  return {
4593
4594
  ok: true,
package/hub/src/server.js CHANGED
@@ -775,7 +775,9 @@ function buildRemoteFrameBinaryPacket(frameEvent, diagnostics = {}) {
775
775
  sameContentStreak: Number(frame.sameContentStreak || 0) || 0,
776
776
  layoutVersion: Number(frame.layoutVersion || 0) || 0,
777
777
  atlasComposeMs: Number(frame.atlasComposeMs || 0) || 0,
778
- atlasPoolStarved: Number(frame.atlasPoolStarved || 0) || 0
778
+ atlasPoolStarved: Number(frame.atlasPoolStarved || 0) || 0,
779
+ atlasReadyTiles: Number(frame.atlasReadyTiles || 0) || 0,
780
+ atlasTileCount: Number(frame.atlasTileCount || 0) || 0
779
781
  };
780
782
  const metaBuffer = Buffer.from(JSON.stringify(metadata), 'utf8');
781
783
  const header = Buffer.allocUnsafe(4);
@@ -917,7 +919,9 @@ function sendMode4AtlasFrame(ws, output) {
917
919
  platformProfile: 'mode4-hub-atlas-worker',
918
920
  layoutVersion: Number(metadata.layoutVersion || 0),
919
921
  atlasComposeMs: Number(metadata.composeMs || 0),
920
- atlasPoolStarved: Number(metadata.poolStarved || 0)
922
+ atlasPoolStarved: Number(metadata.poolStarved || 0),
923
+ atlasReadyTiles: Number(metadata.readyTileCount || 0),
924
+ atlasTileCount: Number(metadata.tileCount || 0)
921
925
  }
922
926
  };
923
927
  const lane = ensureFrameClientSendLane(ws);
@@ -956,7 +960,7 @@ function configureMode4Atlas(ws, payload = {}) {
956
960
  mode: 'mode2-lzo',
957
961
  frameMode: 'mode2-lzo',
958
962
  monitorIndex: Number(monitorSelections[deviceId] || 0),
959
- reuseExisting: true,
963
+ reuseExisting: false,
960
964
  silentReuse: true
961
965
  });
962
966
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "livedesk",
3
- "version": "0.1.152",
3
+ "version": "0.1.153",
4
4
  "description": "LiveDesk Hub and client launcher",
5
5
  "type": "module",
6
6
  "bin": {