Skip to content

video: pre-submit next to an MJPEG reader above 30 fps - #358

Merged
dormancygrace merged 2 commits into
mainfrom
video/presubmit-beside-mjpeg-any-rate
Oct 21, 2026
Merged

dormancygrace merged 2 commits into
mainfrom
video/presubmit-beside-mjpeg-any-rate

Conversation

@dormancygrace

@dormancygrace dormancygrace commented Oct 21, 2026 •

Copy link
Copy Markdown
Owner

What

Pre-submitting the next video frame started only above the fast pixel rate (2560×1440×50). Below that rate a video read alone keeps up. Next to an MJPEG reader on its own output, though, the read also waits for the JPEG encode, so the stream ran serially: 2560×1080 at 60 fps gave 34 fps of H.265.

With a JPEG reader apart from a video output straight from capture, pre-submit now also runs below the fast pixel rate when the stream is above 30 fps and above half that pixel rate (about 92 Mpix/s). Where the encoder is done long before the next frame, pre-submitting lost frames: 2560×1440 at 30 fps gave 15 instead of 24, 1280×720 at 60 gave 31 instead of 56–60. So those stay serial. Without a JPEG reader the rate threshold is unchanged, and a JPEG reader on the video output still never pre-submits. presubmit_next_video_frame takes the stream rate, and its comment and the one above submit_next_video_frame now state the three cases.

Stand

LT6911UXC, H.265 VI-direct, one MJPEG viewer at 25 fps; same viewer, rates switched through /api/vm/video.

Input Before After
2560×1440 at 30 23–24 22–24 (with pre-submit it was 15–16)
2560×1440 at 40 25–28 30–31
2560×1440 at 50 24–25 46–48
2560×1440 at 60 53–57 unchanged (pre-submit as before)
2560×1080 at 60 33–35 54–60
1920×1080 at 60 about 43 60
1280×720 at 60 — (serial in both) 56–60 (MJPEG at 30)
1280×720 at 120 — 105–116

Tests

  • capture_pacing_test.cpp: the three cases (no reader, apart, shared) at several sizes and rates, including the 30 fps and half-pixel-rate floors.
  • tests/test-mjpeg-native-contracts.py.
  • tests/test-video-recovery-native.py.

🤖 Generated with Claude Code

Pre-submitting the next video frame started only above the fast pixel
rate (2560x1440x50). Below it a video read alone keeps up, but next to an
MJPEG reader on its own output the read also waits for the JPEG encode,
so the stream ran serially. With a JPEG reader apart from a video output
straight from capture, pre-submit now also runs below that rate when the
stream is above 30 fps. At 30 fps it lost frames, so it stays off there;
without a JPEG reader the rate threshold is unchanged.

Stand (LT6911UXC, H.265 VI-direct, one MJPEG viewer at 25 fps), serial ->
now:
  2560x1440 at 30: 23-24 -> 22-24 (pre-submitting there gave 15-16)
  2560x1440 at 40: 25-28 -> 30-31
  2560x1440 at 50: 24-25 -> 46-48
  2560x1440 at 60: unchanged, 53-57 (pre-submit as before)
  2560x1080 at 60: 33-35 -> 54-60
  1920x1080 at 60: about 43 -> 60
  1280x720 at 120: 105-114
MJPEG unchanged; no VB starvation messages in any window.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Build outputs

Compared with the build of main at 3a5263d.

1 changed, 0 added, 0 removed of 541 outputs.

directory files
changed native native/libkvm.so
Hashes: outputs-sha256 artifact of this run.

At 1280x720 and 60 fps the encoder is done long before the next frame:
pre-submitting next to an MJPEG reader gave H.265 31-33 fps, serially it
runs 56-60. Next to a JPEG reader apart from the video output, pre-submit
below the fast pixel rate now also needs half of it (2560x1440x25,
about 92 Mpix/s): 1280x720 at 120, 1920x1080 at 60 and up keep it.

Stand, next to MJPEG: 1280x720 at 60 56-60, at 120 107-116; 1920x1080
at 60 57-60; 2560x1440 at 30 24-25.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@dormancygrace dormancygrace left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the complete change at 32deb14, including the call site and the existing buffer lease/release paths. No actionable findings. The lower threshold applies only to an active JPEG reader on a separate output beside VI-direct video, with >30 fps and >half the fast pixel rate; shared-output JPEG still disables pre-submit, and the video-only threshold is unchanged. All call sites use the effective encoder output FPS.

Local validation: all native MJPEG/capture contract probes passed with ASan/UBSan, including capture pacing and direct capture/teardown; video-recovery native ABI guard and positive control passed. Also applied #360 locally: clean combination, native source/rate contracts and Go common/stream/MJPEG tests passed. All 15 CI checks on this exact head succeeded, including full build/hash. No source fixes required. I did not run device benchmarks; performance numbers remain the author's measurements. Merging #358 before #360.

@dormancygrace
dormancygrace merged commit 5926411 into main Oct 21, 2026
15 checks passed
@dormancygrace
dormancygrace deleted the video/presubmit-beside-mjpeg-any-rate branch October 21, 2026 12:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant