A maximum-resolution still looks harmless until the pipeline refuses to start: the camera reports out of memory while creating the frame pool for its still output, before a single image has moved. The message usually prints the two numbers you need — how many frames and how many bytes each — so the fix is arithmetic, not guesswork. This guide is for engineers capturing full-resolution stills from embedded camera modules whose spare memory is a few hundred megabytes. You will compute the pool size from resolution, pixel format and frame count, decide whether the buffers belong on the device or the host, and apply the fixes in the order that costs the least.
What the error message tells you
An error that reads out of memory while creating pool for still frames — 4 frames, each 47,808,000 bytes — is not a crash during capture. Pipelines that run on an embedded camera module preallocate their buffers when the pipeline is loaded onto the device, and this allocation failed before the first frame arrived. The message hands you the whole calculation:
- frame count: 4
- bytes per frame: 47,808,000
- pool request: 4 × 47,808,000 = 191,232,000 bytes, about 191 MB (182 MiB)
That 191 MB has to fit in the device's spare memory alongside the video preview pool, the image signal processor's working buffers and any on-device inference model. At maximum still resolution it usually does not, which is why the pipeline refuses to load. The same error naming a different output — video, preview, depth — means the identical arithmetic applies to that pool instead.
Count the bytes before you change anything
Frame memory is arithmetic, so do it before touching any setting:
The pixel format sets bytes per pixel. NV12 stores each pixel as one luminance byte plus a quarter-size interleaved chroma plane, which averages 12 bits — 1.5 bytes — per pixel: the luma plane alone is width × height bytes, and the chroma plane adds another width × height / 2 bytes, so check that your pipeline's reported per-frame size matches that sum.
| Capture format | Bytes per pixel | A 12 MP frame |
|---|---|---|
| Mono8 | 1.0 | 12 MB |
| NV12, NV21, YUV420 | 1.5 | 18 MB |
| Bayer RAW12, packed | 1.5 | 18 MB |
| YUV422 (YUYV) | 2.0 | 24 MB |
| Mono16, RAW16 | 2.0 | 24 MB |
| RGB888, BGR888 | 3.0 | 36 MB |
Sensitivity, so you know what each change buys: demand scales linearly with frame count, linearly with bytes per pixel, and with the square of resolution — halving both sides divides the pool by four. Drivers round sizes up to alignment boundaries, so treat the formula as the floor.
Sizing the still pool for a 5312 × 6000 NV12 sensor
Inputs, each with its source:
- width 5312 px, height 6000 px — the sensor's maximum still resolution;
- pixel format NV12 at 1.5 bytes per pixel — the semi-planar color format the pipeline emits;
- pool depth 4 frames — the count the error message printed.
The rule in words: one frame costs width × height × bytes per pixel, and the pool costs one frame times the frame count.
Arithmetic:
- pixels per frame: 5312 × 6000 = 31,872,000 px
- bytes per frame: 31,872,000 px × 1.5 bytes = 47,808,000 bytes ≈ 47.8 MB (45.6 MiB)
- pool of 4: 4 × 47,808,000 bytes = 191,232,000 bytes ≈ 191 MB (182 MiB)
Result: the still pool alone asks for about 191 MB of device memory before the video preview pool, ISP scratch and any model take theirs.
Decision: on a module whose camera-buffer budget is a few hundred megabytes, that request fails at load — exactly the failure observed. Cut the pool to 2 frames and the request halves to 95,616,000 bytes, about 96 MB. Quarter the resolution to 2656 × 3000 and a pool of 4 costs 2656 × 3000 px × 1.5 bytes × 4 = 47,808,000 bytes, about 47.8 MB. Working rule: keep the largest single pool under a quarter of the memory you can spare for camera buffers, because the video pool and any models share the remainder. If 4 frames × 47.8 MB busts that quarter, cut frames or resolution before adding any other output.
Why the buffers are allocated on the device
An embedded camera module runs its image pipeline on its own processor, next to the sensor, and allocates the pool in that processor's memory at load time. Host memory does not participate until frames cross USB or GigE, so adding host RAM cannot fix a device-side allocation failure.
The host-side cousin of this error looks similar and is fixed differently: when the failure code is a Windows out-of-memory value such as -2147024882, the question is how much your own process asks per read, which the out-of-memory error -2147024882 page works through.
Device memory also serves competing tenants. When inference buffers crowd out frame buffers on the same chip, the triage in out of fast frame buffer memory: fit algorithms to embedded RAM applies to the same squeeze.
Likely causes, in order of probability
- Pool depth sized for video. Four-frame defaults keep live preview smooth; a still output is pulled on demand and needs two. Test: set the still pool to 2 frames and reload — most SDKs expose a per-output pool size or frame count setting in the camera node's properties.
- Outputs stacked past the budget. Video, still, depth and AI each hold their own pool, and the allocator sees only the sum. Test: load the pipeline with one output removed at a time; the version that loads points at the pool that tips the total.
- Format heavier than the job. RGB888 doubles the per-pixel cost against NV12 and triples it against Mono8. Test: recompute the pool with the table above and ask whether your algorithm really consumes 24-bit color at full resolution.
- Hardware genuinely too small. If two frames at quarter resolution still fail, the module cannot host the job. Test: read the free memory the device reports after boot and compare it with your pool sum.
Fixes, in the order to try them
- Set the still pool to 2 frames. Stills are pulled on demand, and halving the depth halves the request — from 191 MB to about 96 MB in the worked case. This alone resolves most maximum-resolution still failures.
- Quarter the still resolution. At 2656 × 3000 the same pool of 4 costs about 47.8 MB, the largest win per setting — and it loses nothing if your measurement window spans half the field per side.
- Lighten the format where color is not consumed. Mono8 at the full 5312 × 6000 costs 31,872,000 bytes per frame, about 31.9 MB — two thirds of the NV12 cost. With a 2-frame pool that is about 64 MB; even 4 frames stay near 128 MB.
- Move full-resolution capture to a host-connected camera. A camera that streams over GigE or USB3 into a PC builds its buffers in host memory, where a 48 MB pool is trivial. Size that transfer with full resolution image capture is slow or stalls: size the data first, and keep it fast by reusing image buffers instead of per-frame allocation.
- Re-sum every pool after each added output. An output that passed alone can sink a pipeline that now carries video, stills and a model.
When the usual answer is wrong
- A still taken once per shift for calibration does not justify a resident maximum-resolution pool. Keep the pipeline at working resolution and shoot the occasional full-resolution frame from a host-connected camera instead.
- Cutting the pool too far produces the opposite failure: the consumer waits for a buffer and times out, and frames drop. If capture turns flaky after you shrink a pool, the depth fell below the consumer's appetite — the mechanism behind camera3 getBuffer timed out after 3000 ms: why output buffers starve.
- When the deliverable is a maximum-resolution color still produced on the device itself, with no host in the system, the arithmetic is the specification: choose a module whose spare memory exceeds the pool sum. No setting reduces bytes per pixel below what the format requires.
Choosing hardware when the numbers will not close
If the pool sum cannot fit the module you have, pick hardware that matches the arithmetic: board-level cameras for tight embedded builds, area scan cameras for host-connected capture.
For full-resolution stills landed in host memory, use a host-connected camera. The LS-CMR-0166 is a 12 MP USB3 camera with an IMX226 sensor, a 1/1.7-inch sensor format, a rolling shutter, 4000 × 3000 resolution and 30 fps. A 4000 × 3000 NV12 frame is about 18 MB, so a four-frame pool sits at 72 MB — an easy fit in host memory.
- Sensor format
- 1/1.7"
- Interface
- USB3
- Resolution
- 12 MP
- Shutter
- Rolling
Where the camera must stay on the module and the resolution can be smaller, size down. The LS-BCM-0003 is a 3.1 MP USB3 board-level camera with an IMX252 sensor, a 1/1.8-inch sensor format, a global shutter, 120 fps and a C-mount lens mount. At 3.1 MP, an NV12 still is about 4.7 MB, so even a pool of 4 stays under 20 MB.
- Sensor format
- 1/1.8"
- Lens mount
- C-mount
- Interface
- USB3
- Resolution
- 5 MP
If the module itself must deliver 12 MP stills, plan the memory in from the start. The LS-BCM-0056 is a 12 MP GigE board camera with 1.6 μm × 1.6 μm pixels, a 1/2-inch sensor format and a C-mount lens mount. At 12 MP, an NV12 still is about 18 MB and a pool of 4 about 72 MB — a figure you budget at design time rather than discover at load.
- Sensor format
- 1/2"
- Lens mount
- C-mount
- Interface
- GigE
- Resolution
- 12 MP
Take your pool sum to the camera finder and the configurator, filtered by resolution and interface. The selection criteria are laid out in board level camera selection for embedded vision machines.
Before you ship the capture plan
- Compute each pool separately: frames × width × height × bytes per pixel, per output, using the format table above.
- Sum the pools and compare the total with the free memory the device reports after its firmware boots.
- Apply the quarter rule to the largest pool: keep it under a quarter of the spare camera-buffer budget.
- Capture one full-resolution still end to end and confirm no drops, no timeouts and no reload failure.
- Re-run the sum after adding any output, model or higher frame rate; allocations only grow.
If the totals close only on paper, move the full-resolution capture to the host rather than tuning it in production. The neighboring sizing problems — stream bandwidth, preview paths, host buffers — are gathered on the systems topic page, and the contact page reaches the applications team when a pipeline's numbers will not close.
Questions
How many frames does a still-capture pool need?
Two is the right starting number for a still output, because the application pulls frames on demand instead of continuously. Four-frame defaults exist to keep video preview smooth, and they are what breaks when a maximum-resolution still is enabled. Set two, capture a still, and raise the count only if a real drop appears — each extra frame costs another full frame's bytes.
Why does a full-resolution still fail when lower resolutions capture fine?
Buffer demand grows with the pixel count: 5312 × 6000 in NV12 is 47,808,000 bytes per frame, while 2656 × 3000 is 11,952,000 bytes — a quarter of it. A four-frame pool of the large still asks for about 191 MB of device memory, which a small module cannot spare alongside its video pool, while the small pool fits at about 48 MB.
Can I fix a device-side pool failure with more host RAM?
No. The pipeline allocates its frame pool in the camera module's own memory when it loads, before any frame crosses the USB or GigE link. Host RAM only receives frames after they leave the device. If you need buffers that large, capture full-resolution frames with a host-connected camera instead, so the pool lives in host memory from the start.
How do I convert megapixels to megabytes for a frame buffer?
Multiply megapixels by the format's bytes per pixel, then by the pool's frame count. NV12 and packed RAW12 need 1.5 bytes per pixel, so a 12 MP frame is about 18 MB and a four-frame pool about 72 MB. Mono8 needs 1.0 byte per pixel and RGB888 needs 3.0, giving 12 MB and 36 MB for the same frame. The per-frame figure is a floor; alignment can add a small rounding margin.
The pipeline fails even though each output's pool looked affordable. Why?
Pools are allocated together, so their totals add. A 96 MB still pool plus a 48 MB video pool plus tens of megabytes for an on-device model can pass the budget even when each item alone fits. Recompute frames × width × height × bytes per pixel for every linked output and compare the sum with the memory the device reports free after boot.


