Hybrid Vision Toolkit C++ API
In v2.0, all three backends (USB / MIPI / Ethernet) share the same unified Shimeta::hv::Camera API. This page is the complete C++ public API reference; MIPI-specific differences (RAW8 decoding, board-dependent APS format, ARM builds) are noted in the corresponding sections.
Symbols and signatures follow the
include/shimetapi/headers (source repo and release repo are identical, zero drift). All symbols live under theShimeta::namespace, with zero third-party event-SDK dependencies.
core
Headers: <shimetapi/core/*.h>
Shimeta::EventCD
#include <shimetapi/core/event_cd.h>
Purpose: the native event type (POD); its fields map one-to-one to common industry event structures.
struct EventCD {
uint16_t x; // pixel X coordinate
uint16_t y; // pixel Y coordinate
int64_t t; // timestamp (microseconds)
bool polarity; // 1 = CD_ON, 0 = CD_OFF
};Shimeta::Status
#include <shimetapi/core/status.h>
Purpose: the library's unified error-code enum; statusToString() converts a code to a human-readable string for logs and diagnostics.
enum class Status : int32_t {
Ok = 0, ErrDeviceNotFound = -1, ErrPermissionDenied = -2,
ErrUsbTransfer = -3, ErrV4l2Ioctl = -4, ErrNetworkTimeout = -5,
ErrInvalidParam = -6, ErrBufferFull = -7, ErrDecodeFailure = -8,
ErrUnsupportedFormat = -9,
};
const char* statusToString(Status s);Shimeta::BufferView / BufferPool
#include <shimetapi/core/buffer_pool.h>
Purpose: BufferView is a non-owning, read-only view over a pool slab; BufferPool is a fixed-size slab pool for zero-copy frame lifetime management.
struct BufferView {
const uint8_t* data = nullptr;
size_t size = 0;
};
class BufferPool {
public:
BufferPool(size_t slab_size, size_t slab_count);
std::shared_ptr<uint8_t[]> acquire();
size_t slab_size() const;
size_t capacity() const;
size_t available() const;
};BufferPool constructor
Syntax: BufferPool(size_t slab_size, size_t slab_count);
Description: constructs the pool and pre-allocates slab_count slabs of slab_size bytes each.
Parameters
| Parameter | Type | Description |
|---|---|---|
| slab_size | size_t (in) | Size of one slab in bytes (e.g. an NV12 frame = w×h×3/2) |
| slab_count | size_t (in) | Total slab count (bounds the number of concurrent frames) |
Returns: nothing (constructor).
Notes: when slabs are exhausted, acquire() returns nullptr; slab_count should be ≥ the number of concurrent frames.
Example
Shimeta::BufferPool pool(768 * 608 * 3 / 2, 8); // NV12 frames × 8acquire
Syntax: std::shared_ptr<uint8_t[]> acquire();
Description: takes one slab out of the pool and returns a reference-counted handle. The slab returns to the pool automatically when the last reference is released.
Parameters: none.
Returns
| Return value | Description |
|---|---|
non-null shared_ptr<uint8_t[]> | slab acquired successfully |
nullptr | pool exhausted (all slabs in use) |
Notes: the returned shared_ptr can be safely assigned to Frame.*_owner, keeping the view valid for the Frame's lifetime.
Example
auto slab = pool.acquire();
if (!slab) { /* pool exhausted — drop the frame or wait */ }slab_size / capacity / available
Syntax
size_t slab_size() const; // bytes per slab
size_t capacity() const; // total slab count
size_t available() const; // currently free slabsDescription: queries pool capacity and availability.
Parameters: none.
Returns: size_t (the corresponding value).
Notes: available() monitors pool pressure; approaching 0 means frame drops are imminent.
Example: none.
Shimeta::PixelFormat
#include <shimetapi/core/pixel_format.h>
Purpose: pixel-format enum for APS images.
enum class PixelFormat : uint8_t { BayerRG8 = 0, RGB888 = 1, Gray8 = 2, RAW8 = 3, RAW10 = 4, NV12 = 5 };
NV12is the packed YUV format of MIPI HVS APS frames after ISP→PYM; the USB backend's APS defaults to NV12 (768×608). On X5 carrier boards, APS is read directly by VIN and outputsGray8(expected behavior — see MIPI notes).
Shimeta::TimestampInfo
#include <shimetapi/core/timestamp.h>
Purpose: frame timestamp information.
struct TimestampInfo {
int64_t evs_ts_ns = 0; // EVS event reference timestamp (ns)
int64_t aps_ts_ns = 0; // APS exposure instant (ns)
bool ptp_locked = false; // whether the Ethernet backend's PTP is locked
};Shimeta::EvsTimestamp
#include <shimetapi/core/evs_timestamp.h>
Purpose: the EVS sensor's internal timestamp (extracted from a MIPI RAW8 subframe header), used for the tsmp chunks of HybridWriter / HybridReader. Extracted by Shimeta::codec::extractEvsTimestamp().
struct EvsTimestamp {
uint64_t raw_timestamp = 0; // sensor's 45-bit raw timestamp
uint64_t processed_timestamp = 0; // raw_timestamp / 200 (microseconds)
bool valid = false;
};Shimeta::Frame
#include <shimetapi/core/frame.h>
Purpose: the unified frame. aps / evs are read-only views over pool memory; the *_owner fields hold slab references that keep the views valid for the Frame's lifetime (zero-copy, pool-managed lifetime).
struct Frame {
BufferView aps{};
BufferView evs{};
TimestampInfo ts{};
int width{0};
int height{0};
int frame_id{0};
PixelFormat format{};
std::shared_ptr<uint8_t[]> aps_owner{};
std::shared_ptr<uint8_t[]> evs_owner{};
};
Frame.evsholds raw, undecoded event bytes from the HAL (usually EVT2 on the USB backend); decode with the matching codec.
hv
Headers: <shimetapi/hv/camera.h>, <shimetapi/hv/device_config.h>, <shimetapi/hv/event_format.h>, <shimetapi/hv/event_packet.h>, <shimetapi/hv/image_data.h>.
Shimeta::hv::Backend / EventFormat
#include <shimetapi/hv/device_config.h>#include <shimetapi/hv/event_format.h>
Purpose: Backend selects the capture backend; EventFormat selects the event byte encoding (determines how Frame.evs is decoded).
enum class Backend { Auto, Usb, Mipi, MipiHvs, Ethernet };
enum class EventFormat { Evt2, Evt3 };| Backend | Description |
|---|---|
Auto | Automatic selection (inferred from the DeviceConfig fields). |
Usb | libusb backend (USB cameras). |
Mipi | MIPI backend (EVS-only). |
MipiHvs | MIPI HVS dual-VC backend: VC0 carries EVS events, VC1 carries APS frames. |
Ethernet | Ethernet backend (POSIX sockets, DVS1 protocol). |
Shimeta::hv::DeviceConfig
#include <shimetapi/hv/device_config.h>
Purpose: capture configuration — backend selection plus per-backend parameters. Passed to Camera::Init().
struct DeviceConfig {
Backend backend = Backend::Auto;
std::string device_node; // MIPI: "/dev/video0"
std::string ip; // Ethernet
uint16_t data_port = 8000;
uint16_t ctrl_port = 8001;
EventFormat event_fmt = EventFormat::Evt3;
int buffer_count = 8;
uint16_t vendor_id = 0, product_id = 0; // USB VID/PID
enum class QueuePolicy { DropOldest, Block };
QueuePolicy queue_policy = QueuePolicy::DropOldest;
int event_urbs = 4; // in-flight URBs on the USB event endpoint
uint16_t evs_fps = 0; // 0 = not set; non-0 = applied automatically at Init
int sensor_index = 0; // MIPI sensor index; platform samples usually override via build config
uint8_t i2c_bus = 1; // MIPI secure-chip authentication I2C bus
uint16_t listen_port = 8888; // Ethernet: TCP listen port
std::string bind_ip; // Ethernet: local bind IP (empty = INADDR_ANY)
};| Field | Backends | Description |
|---|---|---|
backend | all | Selects the backend type |
vendor_id / product_id | USB | USB device VID/PID (e.g. 0x1d6b / 0x0105) |
event_urbs | USB | In-flight URBs on the event endpoint, default 4; higher raises throughput at the cost of memory |
queue_policy | all | Pool-full policy: DropOldest (drop old frames, default) / Block (block and wait) |
event_fmt | all | Event byte format: Evt2 (USB default) / Evt3 |
evs_fps | all | MIPI frame-rate tier; to change frame rate at runtime on USB/Ethernet use Camera::SetFrameRate¹ |
device_node | MIPI | Device node path, e.g. "/dev/video0" |
sensor_index | MIPI | RDK sensor index; API default 0 — S100/X5 samples currently use 9/49 |
i2c_bus | MIPI | Secure-chip authentication I2C bus number, default 1 |
ip / data_port / ctrl_port | Ethernet | Camera IP + data/control ports |
listen_port / bind_ip | Ethernet | Listen port and local bind IP when the camera acts as the server |
¹ MIPI: 0 = default 240; options 120 / 240 / 300 / 500 / 750 / 1000; applied at Init, non-tier values raise an error.
Shimeta::hv::Camera
#include <shimetapi/hv/camera.h>
Purpose: the unified capture API; one interface covers all three backends (USB / MIPI / Ethernet). Supports synchronous pulling (GetFrame) and async callbacks (Frame / Event / Image — one or more).
namespace Shimeta::hv {
class Camera {
public:
Camera();
~Camera();
Camera(const Camera&) = delete;
Camera& operator=(const Camera&) = delete;
bool Init(const DeviceConfig& cfg);
bool StartStream();
void StopStream();
void Destroy();
bool GetFrame(Frame& frame, int timeout_ms = 1000);
using FrameCallback = std::function<void(const Frame&)>;
using EventCallback = std::function<void(const EventPacket&)>;
using ImageCallback = std::function<void(const ImageData&)>;
void SetFrameCallback(FrameCallback cb);
void SetEventCallback(EventCallback cb);
void SetImageCallback(ImageCallback cb);
bool SetExposure(int value);
bool SetFrameRate(unsigned fps);
bool GetFrameRate(unsigned& fps);
bool SyncClock();
};
} // namespace Shimeta::hvInit
Syntax: bool Init(const DeviceConfig& cfg);
Description: initializes the backend per DeviceConfig (does not block opening the hardware; some backends only connect at StartStream).
Parameters
| Parameter | Type | Description |
|---|---|---|
| cfg | const DeviceConfig& (in) | Capture configuration: backend type + VID/PID / IP / sensor_index etc. |
Returns
| Return value | Description |
|---|---|
| true | configuration accepted, backend initialized successfully |
| false | invalid configuration (unknown backend / missing required field / out-of-range parameter) |
Notes
Initdoes not open the hardware; the actual connection happens atStartStream.- Can be called multiple times (internally
Destroys first, then re-initializes).
Example
Shimeta::hv::DeviceConfig cfg;
cfg.backend = Shimeta::hv::Backend::Usb;
cfg.vendor_id = 0x1d6b;
cfg.product_id = 0x0105;
cam.Init(cfg);StartStream
Syntax: bool StartStream();
Description: starts the capture thread and connects the device. This is the entry point that actually opens the hardware and begins data transfer.
Parameters: none.
Returns
| Return value | Description |
|---|---|
| true | connected to the device and capture started |
| false | device not found / insufficient permissions / busy |
Notes
Initmust be called first.- Returns
falsewithout throwing; checkStatusor retry.
Example
if (!cam.StartStream()) {
std::cerr << "Cannot connect to the device; check the USB connection and permissions" << std::endl;
return 1;
}GetFrame
Syntax: bool GetFrame(Frame& frame, int timeout_ms = 1000);
Description: synchronously pulls one combined frame (EVS events + APS image), blocking until a frame arrives or the timeout expires.
Parameters
| Parameter | Type | Description |
|---|---|---|
| frame | Frame& (out) | Output frame; aps/evs are read-only views over pool memory, *_owner holds the slab reference |
| timeout_ms | int (in) | Timeout in milliseconds, default 1000 |
Returns
| Return value | Description |
|---|---|
| true | frame obtained within the timeout |
| false | timed out (device not connected / capture stopped / data exhausted) |
Notes
frame.evsis raw, undecoded event bytes from the HAL (usually EVT2 on USB); decode withEvt2Decoder/Evt3Decoder.frame.apsholds raw APS bytes whose format is given byframe.format; usually NV12 on S100/USB, Gray8 on X5. Convert per format in the application layer.- The same
Frameinstance can be passed repeatedly; each call overwrites its contents.
Example
Shimeta::codec::Evt2Decoder dec;
Shimeta::Frame f;
while (cam.GetFrame(f, 1000)) {
std::vector<Shimeta::EventCD> events;
dec.Decode(f.evs.data, f.evs.size, events); // decode events
// f.aps.data / f.aps.size → NV12; cvtColor in the application layer
}SetFrameCallback / SetEventCallback / SetImageCallback
Syntax
void SetFrameCallback(FrameCallback cb); // combined frame (events + APS)
void SetEventCallback(EventCallback cb); // raw event packet
void SetImageCallback(ImageCallback cb); // APS imageDescription: registers async callbacks. Callbacks fire serially on the dispatch thread only; the capture thread never calls back. All three callbacks can be registered simultaneously without interfering.
Parameters
| Parameter | Type | Description |
|---|---|---|
| cb | FrameCallback / EventCallback / ImageCallback (in) | Callback function object; pass nullptr to unregister that callback |
Returns: nothing.
Notes
- Callbacks run on the internal dispatch thread — do not block inside a callback or call the camera's synchronous interfaces back (e.g.
GetFrame,StopStream). - Heavy computation should be handed off to a worker thread.
EventCallbackreceives anEventPacket(raw bytes), which also needs codec decoding.
Example
cam.SetEventCallback([&dec](const Shimeta::hv::EventPacket& pkt) {
std::vector<Shimeta::EventCD> events;
dec.Decode(pkt.data.data, pkt.data.size, events);
// process events (on a worker thread; never block the callback)
});SetExposure
Syntax: bool SetExposure(int value);
Description: sets the APS exposure value.
Parameters
| Parameter | Type | Description |
|---|---|---|
| value | int (in) | Exposure value (device-defined units; generally higher = brighter) |
Returns
| Return value | Description |
|---|---|
| true | set successfully |
| false | unsupported by the device / not connected |
Notes: only takes effect on APS-capable backends (USB / MipiHvs).
Example: none.
SetFrameRate / GetFrameRate
Syntax
bool SetFrameRate(unsigned fps);
bool GetFrameRate(unsigned& fps);Description: sets / reads the EVS event frame rate.
Parameters
| Parameter | Type | Description |
|---|---|---|
| fps | unsigned (in/out) | Frame rate (fps); an output parameter for GetFrameRate |
Returns
| Return value | Description |
|---|---|
| true | success |
| false | unsupported by the backend / not connected |
Notes: currently supported on the USB / Ethernet backends; the MIPI backend sets the frame rate via DeviceConfig.evs_fps at Init.
Example
cam.SetFrameRate(120); // set to 120 fps
unsigned current;
cam.GetFrameRate(current); // read the current frame rateStopStream / Destroy / SyncClock
Syntax
void StopStream();
void Destroy();
bool SyncClock();Description
| Method | Description |
|---|---|
StopStream() | Stops capture and joins the capture thread (blocks until the thread exits). |
Destroy() | Releases backend resources (callable after StopStream or instead of it). |
SyncClock() | Clock synchronization (Ethernet PTP mode 0, etc.). |
Parameters: none.
Returns
| Method | Return | Description |
|---|---|---|
StopStream / Destroy | void | — |
SyncClock | bool | true = sync succeeded; false = backend unsupported or not connected |
Notes: recommended shutdown order: StopStream() → Destroy().
Example
cam.StopStream();
cam.Destroy();Shimeta::hv::EventPacket / ImageData
#include <shimetapi/hv/event_packet.h>#include <shimetapi/hv/image_data.h>
Purpose: EventPacket is one packet of raw event bytes (undecoded, straight from the HAL), delivered to EventCallback; ImageData is one APS image frame plus metadata, delivered to ImageCallback.
namespace Shimeta::hv {
struct EventPacket {
BufferView data{}; // one packet of raw event bytes
int64_t t_begin_ns = 0;
int64_t t_end_ns = 0;
};
struct ImageData {
BufferView pixels{};
int width = 0, height = 0;
PixelFormat format{};
TimestampInfo ts{};
};
}codec
Headers: <shimetapi/codec/evt2_codec.h>, <shimetapi/codec/evt3_codec.h>, <shimetapi/codec/mipi_raw8_codec.h>. Namespace: Shimeta::codec.
EVT2
32-bit word stream, the USB default.
class Evt2Encoder {
public:
Evt2Encoder();
void Encode(const EventCD* events, size_t count, std::vector<uint8_t>& out);
void Reset();
};
class Evt2Decoder {
public:
Evt2Decoder();
size_t Decode(const uint8_t* buffer, size_t buffer_size, std::vector<EventCD>& out);
void Reset();
};Evt2Encoder::Encode
Syntax: void Encode(const EventCD* events, size_t count, std::vector<uint8_t>& out);
Description: encodes count events into an EVT2 32-bit word byte stream (with the necessary TimeHigh redundancy words), appending to out.
Parameters
| Parameter | Type | Description |
|---|---|---|
| events | const EventCD* (in) | Pointer to the event array |
| count | size_t (in) | Number of events |
| out | std::vector<uint8_t>& (out) | Output bytes (appended, not cleared) |
Returns: nothing.
Notes: the encoder is stateful (it maintains the time base); reuse one instance across a multi-packet stream and call Reset() before a new stream.
Example
Shimeta::codec::Evt2Encoder enc;
std::vector<Shimeta::EventCD> events = { /* ... */ };
std::vector<uint8_t> raw;
enc.Encode(events.data(), events.size(), raw);Evt2Decoder::Decode
Syntax: size_t Decode(const uint8_t* buffer, size_t buffer_size, std::vector<EventCD>& out);
Description: decodes an EVT2 32-bit word byte stream, appending CD events to out.
Parameters
| Parameter | Type | Description |
|---|---|---|
| buffer | const uint8_t* (in) | Input bytes |
| buffer_size | size_t (in) | Input length in bytes |
| out | std::vector<EventCD>& (out) | Output events (appended, not cleared) |
Returns
| Return value | Description |
|---|---|
size_t | Number of CD events decoded by this call |
Notes
- The decoder is stateful (it maintains the time base / rollover count across packets); reuse one instance across a multi-packet stream.
- Call
Reset()before a new stream.
Example
Shimeta::codec::Evt2Decoder dec;
std::vector<Shimeta::EventCD> events;
size_t n = dec.Decode(frame.evs.data, frame.evs.size, events);Evt2Encoder::Reset / Evt2Decoder::Reset
Syntax
void Evt2Encoder::Reset(); // reset the encoder (next stream starts from time base 0)
void Evt2Decoder::Reset(); // clear decoder state (call before a new stream)Parameters: none. Returns: nothing. Notes: must be called when switching to a new event stream (e.g. a new file or recording segment). Example: none.
EVT3
16-bit word stream.
class Evt3Encoder {
public:
Evt3Encoder();
void Encode(const EventCD* events, size_t count, std::vector<uint8_t>& out);
void Reset();
};
class Evt3Decoder {
public:
Evt3Decoder();
size_t Decode(const uint8_t* buf, size_t len, std::vector<EventCD>& out);
void Reset();
};Evt3Encoder::Encode
Syntax: void Encode(const EventCD* events, size_t count, std::vector<uint8_t>& out);
Description: encodes count events into an EVT3 16-bit word byte stream, appending to out.
Parameters: same as Evt2Encoder::Encode.
Returns: nothing.
Notes: stateful; same rules as EVT2. Example: none.
Evt3Decoder::Decode
Syntax: size_t Decode(const uint8_t* buf, size_t len, std::vector<EventCD>& out);
Description: decodes an EVT3 16-bit word byte stream into CD events.
Parameters
| Parameter | Type | Description |
|---|---|---|
| buf | const uint8_t* (in) | Input bytes |
| len | size_t (in) | Must be a multiple of 2 (16-bit aligned) |
| out | std::vector<EventCD>& (out) | Output events (appended) |
Returns
| Return value | Description |
|---|---|
size_t | Number of CD events decoded by this call |
Notes: len must be even; otherwise behavior is undefined. Otherwise the same as Evt2Decoder::Decode (stateful; Reset before a new stream).
Example
Shimeta::codec::Evt3Decoder dec;
std::vector<Shimeta::EventCD> events;
dec.Decode(frame.evs.data, frame.evs.size, events);Evt3Encoder::Reset / Evt3Decoder::Reset
Same as EVT2; call before a new stream.
MIPI RAW8
The apx003 subframe stream.
Purpose: MipiRaw8Decoder decodes the apx003 RAW8 subframe stream into EventCD, statelessly. The USB backend never produces RAW8, so this class is usually not needed there. For details see the C++ API.
class MipiRaw8Decoder {
public:
MipiRaw8Decoder() = default;
// subframe_count<=0 = auto mode: decode all subframes by len/kSubframeBytes
// (subframes per package differ by frame-rate tier: 120fps=16 … 1000fps=128)
size_t Decode(const uint8_t* data, size_t len, std::vector<EventCD>& out,
int subframe_count = 0);
void Reset(); // stateless, no-op
};MipiRaw8Decoder::Decode
Syntax: size_t Decode(const uint8_t* data, size_t len, std::vector<EventCD>& out, int subframe_count = 0);
Description: decodes the apx003 RAW8 subframe stream into CD events. Stateless (no cross-packet timestamp bookkeeping).
Parameters
| Parameter | Type | Description |
|---|---|---|
| data | const uint8_t* (in) | RAW8 bytes |
| len | size_t (in) | Length in bytes |
| out | std::vector<EventCD>& (out) | Output events (appended) |
| subframe_count | int (in) | Subframe count; ≤0 = auto mode decodes all by length, >0 = only the first N |
Returns
| Return value | Description |
|---|---|
size_t | Number of CD events decoded by this call |
Notes: only for the Frame.evs of the MIPI HVS backend (the RAW8 subframe stream) — not for EVT2/EVT3 byte streams.
Example
Shimeta::codec::MipiRaw8Decoder dec;
std::vector<Shimeta::EventCD> events;
dec.Decode(frame.evs.data, frame.evs.size, events);extractEvsTimestamp
Syntax: Shimeta::EvsTimestamp extractEvsTimestamp(const uint8_t* data, size_t len);
Description: extracts the sensor timestamp from an apx003 RAW8 subframe header (45-bit / 200 → microseconds). Walks the subframes in order and takes the first header-mask match.
Parameters
| Parameter | Type | Description |
|---|---|---|
| data | const uint8_t* (in) | RAW8 bytes (must contain at least one full 32768-byte subframe) |
| len | size_t (in) | Length in bytes |
Returns
| Return value | Description |
|---|---|
EvsTimestamp | valid=true → processed_timestamp holds microseconds; valid=false → no matching subframe found |
Notes: pairs with MipiRaw8Decoder: extract the timestamp first, then decode the events.
Example
auto ts = Shimeta::codec::extractEvsTimestamp(frame.evs.data, frame.evs.size);
if (ts.valid) { /* ts.processed_timestamp = microseconds */ }io
Headers: <shimetapi/io/event_reader.h>, <shimetapi/io/event_writer.h>, <shimetapi/io/hybrid_writer.h>, <shimetapi/io/hybrid_reader.h>. Namespace: Shimeta::io.
Shimeta::io::RawFormat
#include <shimetapi/io/event_reader.h>
enum class RawFormat { Evt2, Evt3, Unknown };Shimeta::io::EventReader
#include <shimetapi/io/event_reader.h>
Purpose: reads RAW event files (.raw), auto-selecting EVT2/EVT3 decoding per the header's ev_version into EventCD.
class EventReader {
public:
bool open(const std::string& filename);
void close();
bool isOpen() const;
RawFormat format() const;
std::pair<uint32_t, uint32_t> imageSize() const;
size_t readAllEvents(std::vector<EventCD>& events);
void reset();
};open
Syntax: bool open(const std::string& filename);
Description: opens the RAW file and parses its header (auto-detecting EVT2/EVT3).
Parameters
| Parameter | Type | Description |
|---|---|---|
| filename | const std::string& (in) | Path to the RAW file |
Returns
| Return value | Description |
|---|---|
| true | opened successfully |
| false | file missing / invalid format |
Notes: after opening, query metadata via format() / imageSize(). Example
Shimeta::io::EventReader reader;
reader.open("events.raw");readAllEvents
Syntax: size_t readAllEvents(std::vector<EventCD>& events);
Description: reads and decodes all events in the file into events.
Parameters
| Parameter | Type | Description |
|---|---|---|
| events | std::vector<EventCD>& (out) | Output event vector |
Returns
| Return value | Description |
|---|---|
size_t | Total number of events read |
Notes: large files consume a lot of memory (read in one shot); v2.0 has no streaming/batched read yet.
Example
std::vector<Shimeta::EventCD> events;
size_t n = reader.readAllEvents(events);format / imageSize / isOpen / close / reset
Syntax
RawFormat format() const; // the file's actual event format
std::pair<uint32_t, uint32_t> imageSize() const; // sensor {width, height}
bool isOpen() const; // whether the file is open
void close(); // close the file
void reset(); // move the read position back to the start of the data areaDescription: queries and control.
Parameters: none. Returns: see the signatures. Notes: reset() allows re-reading the same file. Example: none.
Shimeta::io::EventWriter
#include <shimetapi/io/event_writer.h>
Purpose: writes events to a RAW file; supports both raw byte pass-through (writing Frame.evs directly) and event-encoding write paths.
class EventWriter {
public:
bool open(const std::string& filename, uint32_t width, uint32_t height,
RawFormat fmt = RawFormat::Evt3, uint64_t start_timestamp = 0);
void close();
bool isOpen() const;
size_t writeRaw(const uint8_t* data, size_t len);
size_t writeEvents(const std::vector<EventCD>& events);
void flush();
uint64_t writtenEventCount() const;
};open
Syntax: bool open(const std::string& filename, uint32_t width, uint32_t height, RawFormat fmt = RawFormat::Evt3, uint64_t start_timestamp = 0);
Description: creates a new file and writes its header.
Parameters
| Parameter | Type | Description |
|---|---|---|
| filename | const std::string& (in) | Output file path |
| width | uint32_t (in) | Sensor width |
| height | uint32_t (in) | Sensor height |
| fmt | RawFormat (in) | Determines the header's ev_version, default Evt3 |
| start_timestamp | uint64_t (in) | Start timestamp (microseconds), default 0 |
Returns: bool (whether the file was created). Notes: an existing file is overwritten. Example: none.
writeRaw
Syntax: size_t writeRaw(const uint8_t* data, size_t len);
Description: raw byte pass-through write (write Frame.evs directly, no re-encoding) — the fastest path.
Parameters
| Parameter | Type | Description |
|---|---|---|
| data | const uint8_t* (in) | Raw event bytes |
| len | size_t (in) | Length in bytes |
Returns: size_t (bytes written).
Notes: the bytes written must already be in the target format (EVT2/EVT3); does not update writtenEventCount().
Example
writer.writeRaw(frame.evs.data, frame.evs.size); // write Frame.evs directlywriteEvents
Syntax: size_t writeEvents(const std::vector<EventCD>& events);
Description: encodes events with Evt2Encoder, then writes them.
Parameters
| Parameter | Type | Description |
|---|---|---|
| events | const std::vector<EventCD>& (in) | Events to write |
Returns: size_t (events written). Notes: updates writtenEventCount(). Example: none.
flush / writtenEventCount / isOpen / close
Syntax
void flush(); // force buffered data to disk
uint64_t writtenEventCount() const; // cumulative events written
bool isOpen() const;
void close(); // close (flushes automatically)Parameters: none. Returns: see the signatures. Notes: always flush() or close() at the end of capture to make sure data lands on disk. Example: none.
Shimeta::io::HybridWriter
#include <shimetapi/io/hybrid_writer.h>
Purpose: the hybrid-recording facade — EVS goes to a RAW event file (reusing EventWriter), APS raw frames go to an AVI (with tsmp timestamp chunks). The APS format follows the input Frame.format.
class HybridWriter {
public:
~HybridWriter();
bool open(const std::string& evs_path, const std::string& aps_path,
uint32_t width, uint32_t height, RawFormat evs_format = RawFormat::Evt3,
double aps_fps = 30.0);
bool writeFrame(const Shimeta::Frame& frame, const Shimeta::EvsTimestamp* evs_ts = nullptr);
void close();
uint32_t apsFrameCount() const;
};open
Syntax: bool open(const std::string& evs_path, const std::string& aps_path, uint32_t width, uint32_t height, RawFormat evs_format = RawFormat::Evt3, double aps_fps = 30.0);
Description: opens both output files (EVS / APS).
Parameters
| Parameter | Type | Description |
|---|---|---|
| evs_path | const std::string& (in) | Path to the EVS raw file |
| aps_path | const std::string& (in) | Path to the APS AVI file |
| width / height | uint32_t (in) | Sensor width / height |
| evs_format | RawFormat (in) | EVS file format, default Evt3 |
| aps_fps | double (in) | Written to the AVI header only, does not control capture; default 30.0 |
Returns: bool. Notes: existing files are overwritten. Example
Shimeta::io::HybridWriter hw;
hw.open("events.raw", "aps.avi", 768, 608);writeFrame
Syntax: bool writeFrame(const Shimeta::Frame& frame, const Shimeta::EvsTimestamp* evs_ts = nullptr);
Description: writes one frame: EVS goes through writeRaw, APS is written into the AVI per Frame.format.
Parameters
| Parameter | Type | Description |
|---|---|---|
| frame | const Shimeta::Frame& (in) | Frame to write (frame.evs + frame.aps) |
| evs_ts | const Shimeta::EvsTimestamp* (in, optional) | EVS sensor timestamp; injected into the AVI tsmp chunk, default nullptr |
Returns: bool. Notes: obtain evs_ts via extractEvsTimestamp(frame.evs.data, frame.evs.size). Example
auto ts = Shimeta::codec::extractEvsTimestamp(frame.evs.data, frame.evs.size);
hw.writeFrame(frame, &ts);close / apsFrameCount
Syntax
void close(); // close both outputs and finalize the AVI index
uint32_t apsFrameCount() const; // number of APS frames writtenParameters: none. Returns: see the signatures. Notes: close() flushes automatically. Example: none.
Shimeta::io::HybridReader
#include <shimetapi/io/hybrid_reader.h>
Purpose: the read counterpart of HybridWriter — reads the hybrid recordings it produces (EVS raw + APS AVI, with tsmp chunks). Like Camera, it returns raw bytes; the application decodes per format.
class HybridReader {
public:
HybridReader(); ~HybridReader();
bool open(const std::string& evs_path, const std::string& aps_path);
void close();
bool isOpen() const;
uint32_t width() const;
uint32_t height() const;
double apsFps() const;
uint32_t apsFrameCount() const;
bool readApsFrame(Shimeta::Frame& out, Shimeta::EvsTimestamp* evs_ts = nullptr);
bool readEvsPacket(Shimeta::Frame& out, size_t packet_bytes = 0);
};open
Syntax: bool open(const std::string& evs_path, const std::string& aps_path);
Description: opens both files (EVS / APS); an empty path skips that side.
Parameters
| Parameter | Type | Description |
|---|---|---|
| evs_path | const std::string& (in) | Path to the EVS raw file (empty = do not read EVS) |
| aps_path | const std::string& (in) | Path to the APS AVI file (empty = do not read APS) |
Returns: bool (both sides must open their files successfully).
Notes: the APS side parses the RIFF/AVI header; input/output formats follow the APS frame format at recording time (usually NV12 on S100/USB, Gray8 on X5); the EVS side skips the EVT3 text header automatically.
Example
Shimeta::io::HybridReader hr;
hr.open("events.raw", "aps.avi");readApsFrame
Syntax: bool readApsFrame(Shimeta::Frame& out, Shimeta::EvsTimestamp* evs_ts = nullptr);
Description: reads the next APS frame's raw bytes in order; the format is tagged in .format.
Parameters
| Parameter | Type | Description |
|---|---|---|
| out | Shimeta::Frame& (out) | Filled with .aps + .format/.width/.height/.ts.aps_ts_ns |
| evs_ts | Shimeta::EvsTimestamp* (out, optional) | The frame's sensor timestamp (extracted from the AVI tsmp chunk) |
Returns
| Return value | Description |
|---|---|
| true | one frame read successfully |
| false | end of file / APS not opened |
Notes
out.aps.dataholds raw APS bytes; the application must decode perout.format(NV12 → BGR, Gray8 can be used directly as grayscale).out.aps_ownerholds the slab, so the Frame stays valid after leaving the reader (self-contained).
Example
Shimeta::Frame f;
Shimeta::EvsTimestamp ts;
while (hr.readApsFrame(f, &ts)) {
// f.aps.data: decode per f.format (NV12 or Gray8)
// ts.processed_timestamp = microseconds
}readEvsPacket
Syntax: bool readEvsPacket(Shimeta::Frame& out, size_t packet_bytes = 0);
Description: reads the next packet of raw EVS bytes in order (the EVT3 text header is already skipped).
Parameters
| Parameter | Type | Description |
|---|---|---|
| out | Shimeta::Frame& (out) | Filled with .evs (self-contained owner) |
| packet_bytes | size_t (in) | Bytes to read per call; 0 = default 1 MiB (one apx003 RAW8 packet is 32768×32) |
Returns
| Return value | Description |
|---|---|
| true | read successfully (out.evs.size is the actual bytes read; the final packet may be < packet_bytes) |
| false | end of file / EVS not opened |
Notes: the raw bytes read must be decoded with MipiRaw8Decoder (MIPI RAW8) or Evt2Decoder/Evt3Decoder (EVT2/3).
Example
Shimeta::codec::MipiRaw8Decoder dec;
Shimeta::Frame f;
while (hr.readEvsPacket(f)) {
std::vector<Shimeta::EventCD> events;
dec.Decode(f.evs.data, f.evs.size, events);
}width / height / apsFps / apsFrameCount / isOpen / close
Syntax
uint32_t width() const; // APS width
uint32_t height() const; // APS height
double apsFps() const; // frame rate from the AVI header (falls back to 30.0 if invalid)
uint32_t apsFrameCount() const; // total frames declared in the AVI header
bool isOpen() const;
void close();Parameters: none. Returns: see the signatures. Notes: none. Example: none.
MIPI notes
APS images
On Backend::MipiHvs, Frame.aps comes from the VC1 channel and the format depends on the board:
| Board | Frame.format | Path | Application handling |
|---|---|---|---|
| S100 | NV12 (color) | After ISP→PYM processing | Convert to BGR with cv::cvtColorTwoPlane |
| X5 | Gray8 (grayscale) | VIN reads RAW10 directly (ISP 2A ioctls are limited; bypassing is expected behavior) | Use directly as a grayscale image |
Backend::Mipi (EVS-only) provides no APS.
License
Apache License 2.0. The EVT2/EVT3 codecs are an independent clean-room implementation based on the public specifications, containing no third-party closed-source code.
