Skip to content

video: MJPEG at 30 fps next to a video stream up to 1920 wide - #360

Merged
dormancygrace merged 2 commits into
mainfrom
video/mjpeg-30-next-to-video
Oct 21, 2026
Merged

dormancygrace merged 2 commits into
mainfrom
video/mjpeg-30-next-to-video

Conversation

@dormancygrace

Copy link
Copy Markdown
Owner

Next to an H.264 or H.265 stream, MJPEG ran at no more than 27 fps over a VPSS output at 30, whatever the video size. With this change, next to a stream up to 1920 wide it runs at 30 over 33. Next to a wider stream it stays at 25 over 27, because 30 over 33 measured worse at 2560 × 1440.

  • server/service/stream/mjpeg/streamer.go: mjpegNextToVideoFPS 27 → 30.
  • kvm_vision.cpp: mjpeg_next_to_video_fps 30 → 33. The server rate stays below the VPSS output rate; with the order reversed, the JPEG reader waits for frames.
  • The test and docs/VIDEO.md are updated.

Stand measurements

H.265 straight from capture, with an MJPEG viewer, #358 pre-submit included:

Mode Video fps, MJPEG 30 Video fps, MJPEG 27
1280×720 @120 107–116 about the same
1920×1080 @90 80–85 about the same
1920×1080 @60 57–60 about the same
1920×1200 @60 59–60 —
1280×720 @60 56–60 —

H.264 1080p90 next to MJPEG at 30 ran at 83–87 fps (78–85 next to 27 in the earlier measurement).

The shared 4:2:0 output (MJPEG choice 4:2:0, H.265 1920×1080 @60) is a trade-off:

MJPEG rate H.265 fps MJPEG fps
30 / 33 30 20
27 / 30 (before) 33 14–17

Not measured: portrait modes. Independent of #358; the measurements above were taken with it.

🤖 Generated with Claude Code

dormancygrace and others added 2 commits October 21, 2026 13:17
Next to an H.264 or H.265 stream MJPEG ran at most at 27 fps (its VPSS
output at 30), whatever the video size. Up to 1920 wide it now runs at
30 over a VPSS output at 33; next to a wider stream it stays at 25 over
27, where 30 over 33 measured worse.

Stand, H.265 straight from capture next to MJPEG at 30: 1280x720 at 120
Hz 107-116 fps, 1920x1080 at 90 Hz 80-85 and at 60 Hz 57-60, 1920x1200
at 60 Hz 59-60 (with #358's pre-submit), about as next to MJPEG at 27.

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

Copy link
Copy Markdown

Build outputs

Compared with the build of main at 3a5263d.

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

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

@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 9823918. No actionable findings. The server/native pair changes together from 27/30 to 30/33 for video up to 1920 pixels wide; the wider-stream pair stays 25/27. Lower requested screen rates and standalone MJPEG behavior are preserved. Both sides classify by the encoded video's width, and the server rate remains below the separate VPSS output rate.

Verified the combination with #358 applies cleanly. Local native source/rate contracts and Go common/stream/MJPEG tests passed; #358's native MJPEG/capture probes also passed ASan/UBSan. All 15 CI checks on this exact head succeeded, including full build/hash. No source fixes required. No device measurements by me: the documented shared-output performance trade-off and unmeasured portrait modes remain as stated by the author. Merging after #358.

@dormancygrace
dormancygrace merged commit 03e6c73 into main Oct 21, 2026
15 checks passed
@dormancygrace
dormancygrace deleted the video/mjpeg-30-next-to-video 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