System designExplainer

Chunk data on camera frames: carry timestamp and exposure per image

What chunk data is, which values a camera can embed per frame, its bandwidth cost, and why the timestamp needs every layer to expose the nodes.

LumaSpec Vision12 min read Share on LinkedIn

On this page 8 sections
  1. 01What is chunk data on a camera frame?
  2. 02Which values can a camera embed in each frame?
  3. 03How much bandwidth does chunk data cost?
  4. 04Why is the camera timestamp different from the host timestamp?
  5. 05When do you need chunk data instead of logging timestamps in software?
  6. 06Why doesn't chunk data show up in the SDK?
  7. 07What should you check before specifying a camera for chunk logging?
  8. 08Questions

A frame arrives at your code carrying pixels, and your logger stamps it with the host clock — then you try to measure anything faster than a few milliseconds and the numbers wobble. Chunk data moves the measurement into the camera: the timestamp, the exposure time actually used, the gain and a frame counter ride inside the image buffer itself. This guide covers what chunk data is, which values a camera can embed, what it costs in bandwidth, why an SDK sometimes hides it, and how to confirm all three layers — firmware, transport, adapter — deliver it. If you specify cameras for event timing, exposure logging or multi-camera alignment, you will leave able to test a stack for chunk support in minutes, with the arithmetic to judge its cost.

What is chunk data on a camera frame?

Chunk data is the GenICam feature in which the camera appends a block of metadata — timestamp, the exposure time it actually used, gain, a frame counter, digital-IO states — to the same buffer that carries the pixels, so the values travel with the image.

The camera packs the block alongside the pixel payload, and the SDK unpacks it and hands you one value set per frame. Both GigE Vision and USB3 Vision carry chunk blocks, and the standardized names come from GenICam's SFNC, so a chunk-enabled camera behaves the same through any conforming API. The clock behind the timestamp belongs to the camera: it free-runs from power-up, is read-only from the host side, and advances monotonically for the whole session.

The contrast is host-side sampling. A logger that reads the PC clock inside the frame callback stamps the moment the buffer reached your process, not the moment the sensor saw light; every microsecond of transfer, driver work and scheduler delay between the two lands inside your measurement. Chunk values are measured where the exposure happens, and that whole class of error leaves the data.

Which values can a camera embed in each frame?

The camera's node map lists exactly which chunks its firmware can produce, and the common set is a timestamp, the exposure time and gain applied to that frame, a frame counter and the digital-IO line states captured with the exposure.

The SFNC names follow one pattern: a master switch, ChunkModeActive, turns the feature on, and each value gets its own selector and enable — the time value is ChunkTimestamp and the others follow the same form. Values are read-only: the timestamp returns the camera's counter, and nothing written from the host changes it. Where in the frame cycle the clock is latched — exposure start or exposure end — differs between cameras, and Chunk data timestamp: camera time at exposure end and how to latch it works through that latch point.

Chunk value What it reports What you use it for
Timestamp Camera clock at the latch point Frame intervals, event timing, stream alignment
Exposure time Exposure actually applied to that frame Light-level logging under auto exposure
Gain Gain actually applied to that frame Matching brightness frame to frame
Frame counter One increment per acquired frame Dropped-frame detection at the source
IO line status Trigger and strobe line states at exposure Tying images to PLC events

Cameras with region support often add chunks naming the region that produced the frame. Read the node map rather than a data-sheet table: the firmware decides the list, and the list is short to check.

How much bandwidth does chunk data cost?

Almost nothing: a chunk block runs a few dozen to a few hundred bytes per frame, so a generous 128-byte block on a camera streaming 4000 × 3000 at 30 fps adds about 3.8 kB/s against roughly 360 MB/s of pixel payload — a 0.001 % share.

pixel payload = width × height × bytes per pixel stream rate = pixel payload × frame rate chunk share = (chunk block × frame rate) / stream rate

The arithmetic for the example stream: 4000 × 3000 = 12,000,000 pixels per frame. At 8 bit mono, one byte per pixel, that is 12,000,000 B ≈ 12.0 MB per frame, and 12.0 MB × 30 fps = 360 MB/s of pixel data. A 128-byte chunk block — illustrative, because the real size grows with the number of values you enable — adds 128 B × 30 = 3,840 B/s. The share is 3,840 / 360,000,000 = 0.0011 %. Even a 1,000-byte block would add 30 kB/s, eight times more and still invisible.

The overhead scales with frame rate and stays flat with resolution; the payload is what decides the transport. The same frame at 16 bit doubles to 24 MB and 720 MB/s, past what a USB3 link sustains, while a GigE link moves 1000 Mbit/s ÷ 8 = 125 MB/s at line rate and USB3 about three times that. If a measured stream lands far below this arithmetic, suspect the link before the software: on embedded hosts a USB3 camera stuck at a fraction of its expected rate usually traces to a fallback or driver cause, as in this USB3 camera low-speed troubleshooting guide.

The example stream is the printed spec of the camera below — 12 MP USB3, 4000 × 3000 at 30 fps:

Area scan cameras12 MP USB3 area scan camera, IMX226, 1/1.7" rolling shutter, 30 fps, 4000 × 3000 resolution (LS-CMR-0166)LS-CMR-0166
Sensor format
1/1.7"
Interface
USB3
Resolution
12 MP
Shutter
Rolling
$560.00View partBuild a system with it

Why is the camera timestamp different from the host timestamp?

Host time marks when the buffer reached your callback — after transfer, driver and OS scheduling delay — while the chunk timestamp is latched inside the camera at the frame's latch point, so the two differ by milliseconds that move from frame to frame.

The camera interval is the measurement; the host interval is the measurement plus jitter. On a busy host the callback lands late by a scheduling quantum or a buffer-queue hiccup, and the size of the lateness changes per frame. GigE Vision frame arrival jitter: isolate camera and host timing walks that isolation, and Camera buffer timestamp latency: interpret frame timing explains what a buffer stamp actually includes.

T1, T2 = chunk timestamps of frames 1 and 2 A1, A2 = host arrival times of the same frames camera interval = T2 - T1 host interval = A2 - A1 error = (host interval - camera interval) / camera interval

To place camera time on the host clock, map it once per session: capture a frame, read the arrival time A and the chunk stamp T, and carry the offset A − T as the session's conversion. The counter is monotonic and read-only, so the offset holds until you close the camera; re-map after any reconnect.

When do you need chunk data instead of logging timestamps in software?

You need chunk data whenever the number must describe the exposure rather than the arrival: frame interval and speed under jitter, exposure and gain under auto exposure, dropped-frame detection, IO-event correlation and time alignment between cameras — five jobs host-side logging does not survive.

  • Frame interval and speed under jitter. The 34 % error above is the case. Any speed or timing number computed from arrival times inherits it, and the chunk stamps remove it.
  • Exposure and gain under auto exposure. The exposure you wrote to the camera is not the exposure the sensor used; the per-frame chunk records what actually happened, as Read exposure time from frame metadata under auto exposure shows, and Camera exposure and gain units: interpreting raw values covers how to read those numbers.
  • Dropped-frame detection. When the frame counter steps 847 → 850, two frames vanished at the source. A host-side counter can miss frames for its own reasons and cannot say where they went.
  • IO correlation. The IO-line chunk records the trigger input's state at the exposure, so a frame whose trigger came from the wrong source shows up immediately.
  • Multi-camera alignment. Two cameras each free-run their own counter, and per-frame stamps are the only time base the streams share — whether the cameras are two USB3 units triggered together, as in Hardware sync two USB cameras: trigger both cameras together, or a rack of CoaXPress cameras onto a frame grabber such as the MV-GX1008, with ports assigned as in Assign cameras to ports reliably in a multi-camera system.

Two hardware shapes cover that last case — cameras sharing one NIC, and cameras feeding a frame grabber:

Frame grabbersHikrobot MV-GE2002P Dual-port PoE NIC, full height V2.0MV-GE2002P
Interface
GigE
Ports
2 ports
$249.00View part
Frame grabbersHikrobot MV-GX1008 Octo CXP-6 Frame GrabberMV-GX1008
Interface
CoaXPress
$1,949.00View part

Why doesn't chunk data show up in the SDK?

Three layers must agree: firmware that generates the chunks, a GigE Vision or USB3 Vision transport that carries them, and an SDK adapter that both exposes the GenICam chunk nodes and parses them out of each buffer — hide the nodes anywhere and supported hardware still delivers nothing.

The classic failure is the third layer. The camera's own configuration tool shows a chunk category with every value you want; enumerate the node map from your acquisition API and the chunk nodes are absent. The firmware is rarely the cause — if the vendor's tool sees the nodes, the camera produces them. For GenICam-based hosts the adapter is the GenTL producer or the vendor's API layer, and it decides what your code can reach; one that predates the feature or never maps the chunk category drops it silently.

Run this check on any camera you plan to log from:

  1. Open the camera in the vendor's node browser and find the chunk category; write down the values it offers.
  2. Enumerate the same node map from your own API and count the chunk nodes. A browser list your API cannot reproduce is the adapter gap, located in five minutes.
  3. Enable the master switch and select the values you need; confirm the buffer length grows or the SDK exposes per-frame values.
  4. Log ten frames and read them back: the counter must step by exactly 1, and the stamp must advance by roughly the frame period — 33.3 ms at 30 fps.

If your flow depends on a configuration built in the vendor's tool, the supported equivalent is the camera's user-set feature: save the settings to a user set and load that set from your API, if the adapter exposes those nodes too. Once the chunk nodes do appear, Setting camera exposure time through a GenICam API in Python shows the shape of the calls, and Access GigE camera registers at runtime from your control code covers reading the underlying registers when a feature is not exposed at all.

What should you check before specifying a camera for chunk logging?

Check four things before you order: the firmware must list the chunks you need, your SDK adapter must expose those nodes, the timestamp's tick rate must fit the interval you plan to measure, and the link must carry your payload with headroom.

  • The node map lists your values. Timestamp, exposure, gain, counter, IO status — in the vendor's browser, on the exact firmware version you will run.
  • Your API reproduces the list. Same nodes, same names; this is the layer that fails most often.
  • The tick rate fits the interval. A microsecond tick resolves a 5 ms interval to 0.02 %; a millisecond tick resolves it to 20 % — the difference between usable and useless for the timing example above.
  • The latch point is known. Exposure start or exposure end, per camera; compare two cameras only after both are written down.
  • The payload fits the link. Run the bandwidth arithmetic for your resolution, bit depth and frame rate against the line rate — 125 MB/s for GigE, about three times that for USB3.
  • The buffer handling survives the extra fields. If the SDK reuses buffers, copy the chunk values out before the next frame, as Torn frames in a camera callback: copy the buffer before you queue it shows for the pixels.

Shortlist the cameras in the area scan cameras category with the camera finder, run the node-map test on the shortlist, then size camera, grabber and host together in the vision system configurator. More systems-level guides sit on the systems topic page.

Questions

Does chunk data work the same over GigE Vision and USB3 Vision?

Yes at the feature level: both transports carry chunk blocks and GenICam's SFNC defines the names, so a chunk-enabled camera behaves the same either way. What differs is the pipe: a GigE link moves 125 MB/s of payload at line rate and USB3 roughly three times that, so the same 12 MB frame fits a USB3 stream at 30 fps and does not fit GigE. The adapter layer, not the transport, is where chunk support usually breaks.

Can I set the camera's clock so chunk timestamps read wall-clock time?

No — the timestamp is read-only and returns the camera's free-running counter, which GenICam does not let you set. Map it once per session: capture one frame, record the host arrival time and the chunk timestamp together, and carry the offset A − T as long as the session runs, because the counter is monotonic. For a shared absolute time across several devices, look for IEEE 1588 (PTP) in the camera's feature list instead of trying to steer the clock.

Is the chunk timestamp taken at the start or the end of exposure?

The node map or the camera manual states it, and both conventions exist: some cameras latch at exposure start, others at exposure end. The difference is worth one number — a 5 ms exposure shifts the stamp by 5 ms between conventions, which is the whole 5.0 ms interval in the timing example above. Write each camera's latch point into your logging notes and compare cameras only on the same convention.

How much extra buffer memory does chunk mode need?

Plan for the pixel payload, not the chunks: 4000 × 3000 at 8 bit is 12.0 MB per frame, so ten buffers need about 120 MB plus the few hundred bytes per frame the chunk block adds. Chunk mode does not meaningfully change allocation size; size buffers for the pixels and let the block ride.

Do frame grabbers handle chunk data differently from direct GigE or USB3 links?

The same three-layer rule applies: the camera firmware must generate the chunks and the frame grabber's SDK must expose the GenICam nodes and parse the blocks the camera sends. What changes is where parsing happens — in the grabber driver rather than a camera SDK — so run the same node-map test against the grabber's API before you build timing logic on chunk values.