Skip to content

Native MJPEG preview can show false frame-stall error after rotation #128

Description

@jeroenbaas

Summary

When SimulatorView uses its native MJPEG <img> mode, rotating the simulator can display the fatal frame-stall overlay even though the stream endpoint is actively producing frames.

The message is:

Stream is not producing frames. The simulator may have stopped - try reconnecting.

Environment

  • serve-sim@0.1.44
  • macOS 26.3 (25D125), Apple Silicon (Mac16,10)
  • Xcode 26.5 / iOS Simulator 26.5
  • iPad Air 11-inch (M4) simulator
  • Node v25.5.0
  • Chromium client on another machine on the LAN

Context

The default JavaScript frame-reader path was unusable because of #103, so a diagnostic patch selected the existing native MJPEG <img> path. A localhost MJPEG keepalive consumer was also attached to avoid the native startup crash described in #120. This meant the helper had multiple stream consumers.

Reproduction

  1. Start serve-sim with MJPEG capture.
  2. Render the existing native MJPEG <img> path in SimulatorView.
  3. Rotate the simulator from the toolbar.
  4. Wait for the liveness timeout.

Actual behavior

The frame-stall overlay appears after rotation. At the same time:

  • a fresh request to /stream.mjpeg returns HTTP 200;
  • the endpoint transferred about 9.4 MB in a four-second sample;
  • /config reflected the new orientation.

The capture service was therefore still producing frames.

Expected behavior

The native image should remain live or reconnect after the orientation/config change. A secondary stream consumer should not be able to mark the visible stream as dead while frames are still being produced.

Suspected cause

In native image mode, SimulatorView renders <img src=".../stream.mjpeg"> and starts a separate JavaScript fetch() of the same endless stream as a boundary watchdog. Either request can stall independently, so the watchdog can set the fatal error while the visible image and capture helper remain healthy.

PR #25 describes the same parallel-fetch false-positive risk and uses a plain <img> for grid mode to avoid it.

Possible direction

Use one native image stream consumer. Liveness could come from the /config frame counter, similar to the Safari support path, and the image URL could be refreshed when orientation/config changes.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions