Skip to content
/ wiki Public

memory-tuning: document the self-sizing frame pool and the settings that shrink it - #479

Open
widgetii wants to merge 2 commits into
masterfrom
memory-tuning-self-sizing-pool
Open

memory-tuning: document the self-sizing frame pool and the settings that shrink it#479
widgetii wants to merge 2 commits into
masterfrom
memory-tuning-self-sizing-pool

Conversation

@widgetii

@widgetii widgetii commented Aug 4, 2026

Copy link
Copy Markdown
Member

Brings the streamer section in line with how memory actually works now, after majestic#277, #278 and #281.

The section led with the wrong thing

It explained how to hand-tune isp.blkCnt — "change it one step at a time and confirm the stream still runs" — when the pool now sizes itself, and when the cheapest way to shrink it is to stop asking for channels you don't use. Every channel costs a whole frame whether or not it's producing one, because the pool is fixed at startup. On a 24 MB gk7205v200 one frame is an eighth of everything.

So it now opens with what each setting is worth, in frames:

Setting What it does Typical saving
jpeg.enabled: false no snapshots at all, and no frame reserved for them one frame
video1.enabled: false drops the second stream and its frame one frame
isp.yuvCompression: seg stores the pooled frames compressed 2–6 MB, some SoCs
jpeg.tuned caps parameterised snapshots to a size you choose avoids a full frame
isp.blkCnt overrides the frame count outright one frame per step
isp.memMode encoder-side buffers, not the pool a few MB

isp.blkCnt — derived, not tuned

Documents what the streamer arrives at and why two cameras with the same chip differ — the sensor's width, not the SoC. A sensor too wide for the capture pipe routes frames through memory, which costs whole frames:

Camera Capture path Blocks held Pipeline total
gk7205v200 + 1920x1080 straight through 0 3
hi3516ev300 + 2592x1520 raw through memory 2 4
hi3516av300 + 3840x2160 processed through memory 4 6

Plus how running short presents, which is the least intuitive part: a pool one block short encodes video perfectly and answers no snapshots, so a camera judged by its RTSP feed looks healthy. And how to read the headroom from /proc/umap/vb (MinFree) rather than guessing.

Two new sections

jpeg.enabled no longer half-works — it used to reserve a frame for a channel it would not raise, and answer /image.jpg anyway. Off now means no frame and a named refusal, with measured figures (gk 12156→9116 KB, ev300 28860→23088 KB). The article says plainly that this takes ONVIF snapshot URIs and the web UI preview with it, since that's the part someone would otherwise discover the hard way.

jpeg.tuned is new: a size rather than a switch, because the memory follows it. Reserving for the size you actually fetch costs ~1 MB at 640x360 against 5.6 MB for a sensor frame — including the point where a large cap stops being a saving at all.

Also

  • Drops the advice to pair compression with a lower blkCnt — the streamer now works out how many frames it can compress while keeping the rest of the pipeline supplied.
  • Drops the "a recent majestic update" framing from the compression section.
  • Fixes a missing blank line before a --- rule that was swallowing the preceding paragraph.

All figures are measured on the lab cameras, not derived. Depends on majestic#281 for the jpeg.tuned behaviour.

isp.blkCnt was written up as a number to tune by hand, one step at a time,
watching whether the stream survived. The streamer now derives it from the
pipeline, so the useful thing to document is what it arrives at and why two
cameras with the same chip land on different figures — which turns out to be
the sensor's width rather than the model of SoC, since a sensor too wide for the
capture pipe has to route frames through memory and that costs whole frames.

Also documents how running short presents, because it is the least intuitive
part: a pool one block short encodes video perfectly and answers no snapshots,
so a camera judged by its RTSP feed looks healthy. And how to read the headroom
from /proc/umap/vb rather than guessing at it.

Drops the advice to pair compression with a lower blkCnt. The streamer works out
how many frames it can compress while keeping the rest of the pipeline supplied,
and says when there is nothing to spare.

Drops the "a recent majestic update" framing from the compression section. What
the software does now is the documentation; when it started doing it is not.
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Document self-sized frame pool (isp.blkCnt) and VB headroom checks

📝 Documentation 🕐 10-20 Minutes

Grey Divider

AI Description

• Explain how the streamer derives isp.blkCnt from the configured pipeline.
• Document symptoms of an undersized pool and the new diagnostic log lines.
• Add guidance for reading real headroom from /proc/umap/vb and compression behavior.
Diagram

graph TD
  U[User/admin] --> API["HTTP API /api/v1/set"] --> S[Streamer] --> VB[("VB frame pool")]
  U --> C["Pipeline config"] --> S
  S --> L["Startup logs"]
  VB --> PVB["/proc/umap/vb (MinFree)"]
  VB --> PMM["/proc/media-mem (usage)"]
Loading
High-Level Assessment

The documentation-first approach is the right fit: it reflects the current runtime behavior (auto-derived blkCnt, explicit logs, and procfs-based validation) rather than preserving obsolete manual-tuning guidance. Alternatives like splitting into a separate troubleshooting page were considered but would reduce discoverability for the core tuning workflow.

Files changed (1) +108 / -20

Documentation (1) +108 / -20
memory-tuning.mdRewrite 'isp.blkCnt' section for auto-sized VB pool and diagnostics +108/-20

Rewrite 'isp.blkCnt' section for auto-sized VB pool and diagnostics

• Replaces manual-tuning guidance for 'isp.blkCnt' with an explanation of how the streamer derives the required block count from the pipeline, including sensor-width-dependent capture paths and example totals. Documents non-obvious failure modes when the pool is one block short, adds concrete log lines to look for, and explains how to check real headroom via '/proc/umap/vb' ('MinFree'). Updates the compression section to remove historical framing and clarifies that compression is auto-split based on spare blocks, with logs when split is skipped.

en/memory-tuning.md

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider

Great, no issues found!

Qodo reviewed your code and found no material issues that require review

Grey Divider

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

The section explained how to tune the frame pool before saying that the cheapest
way to shrink it is to stop asking for channels you do not use. Every channel
costs a whole frame whether or not it is producing one, because the pool is
fixed when the streamer starts — so jpeg.enabled and video1.enabled each return
more than any amount of tuning below them, and on a 24MB board one frame is an
eighth of everything.

So the section now opens with a table of what each setting is worth, in frames
rather than in prose, and the two JPEG settings get their own entries:

jpeg.enabled, which no longer half-works — it used to reserve a frame for a
channel it would not raise, and answer /image.jpg anyway. Off now means no frame
and a named refusal, and the article says plainly that this takes ONVIF snapshot
URIs and the web UI preview with it, since that is the part someone will
discover the hard way.

jpeg.tuned, which is new: a size rather than a switch, because the memory
follows it. Parameterised snapshots need a second encoder, and reserving for the
size you actually fetch costs about 1MB at 640x360 against 5.6MB for a sensor
frame. Includes the sizes where a cap stops being a saving.
@widgetii widgetii changed the title memory-tuning: the frame pool sizes itself, so say what it arrives at memory-tuning: document the self-sizing frame pool and the settings that shrink it Aug 5, 2026
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