Pure-Go GigE Vision client (package gige) for Huaray/Dahua 3D volume cameras.
Tested on:
| Manufacturer | Model | Description |
|---|---|---|
| Huaray Technology (iRAYPLE) | DS5131MG30CE | 3D stereo industrial smart camera for machine vision, industrial automation, and precise depth measurement. |
- GigE Vision control — GVCP register read/write, heartbeat maintenance, and access-privilege management over a dedicated control channel.
- Streaming — GVSP receiver with pre-allocated buffer pool, packet resend, and multi-part/GenDC payload parsing.
- GenICam GenApi XML — Fetch, decompress, and build the camera node map (IntReg, Enumeration, SwissKnife, Converter, Port, …).
- 3D volume (BSCF) — Per-frame color/depth/mono components with JPEG encoding and mm-scale measurements (
WidthMm,HeightMm,Length,PackCount). - Live preview — App-owned sinks (
live.NewLive), switch components mid-stream. - Zero-alloc hot path —
gvsp.Receiverallocates nothing per packet during streaming.
- Go 1.23+
- A GigE Vision camera on the same L2 network (a simulator works for control-plane work)
- Optional: Jumbo-frames-capable NIC for high-throughput streaming
go get github.com/aaronmurniadi/gogigeOpen a camera, configure a feature, and grab a frame. There are two handles that
share one feature vocabulary (SetInteger/SetEnum/SetBoolean/SetFloat/SetString
plus matching getters):
gogige.OpenDevice→*Camera: control + live frames + one-shot samples.gogige.Open→Device: control (dev.Features()) +StartGrabber/Grabber.
One-shot sample straight from the Camera:
cam, err := gige.OpenDevice(ctx, "192.168.1.10",
gige.WithLogger(logger),
gige.WithTimeout(2*time.Second),
)
defer cam.Close()
_ = cam.SetEnum("PixelFormat", "Mono8")
sample, err := cam.GrabSample(ctx, gige.ComponentDepth) // Sample: JPEG + LengthMm/WidthMm/HeightMm/PackCount/PacksContinuous frames:
stream, err := cam.StartStream(ctx)
defer stream.Stop()
for frame := range stream.Frames() {
// use frame.Data
frame.Release() // return to the buffer pool
}One-shot grab (fully automated open→grab→close):
jpeg, err := gogige/grab.GrabJPEG(ctx, "192.168.1.10")
// or from a Camera you already hold:
jpeg, err := gogige/grab.FromCamera(ctx, cam, gogige.ComponentColor)Discover cameras:
devs, err := gige.Discover(ctx, 2*time.Second)Live preview (app owns the sink):
l := gogige/live.NewLive(dev, gogige/live.WithSink(gogige.JPEGFunc(hub.Broadcast)), gogige/live.WithLiveComponent(gogige.ComponentDepth))
l.Start(ctx)
defer l.Stop()
sample := l.LatestSample() // filter/validate in the app
// l.SetComponent(gogige.ComponentColor) // switch mid-streamLogging: gogige.WithLogger(...) accepts any Logger implementation (e.g. gogige.Slog(slog.Default()) or your own wrapper around zerolog/zap). Default is a no-op.
gogige/
├── cmd/
│ ├── gogige-discover/ # CLI discovery utility
│ └── gogige-stream/ # CLI stream capture utility
├── camera.go # Camera, feature get/set, one-shot grabs
├── device.go # Device (Open), OpenDevice, Features impl
├── stream.go # Session/Grabber, StartStream + Stream.Frames()
├── options.go # WithLogger/WithTimeout/WithComponent, const Version
├── interfaces.go # Device, Features, Grabber, FrameSink, JPEGFunc
├── alias.go # gogige.Sample/Frame/GVCP/… re-exports
├── discovery.go # Discover → DeviceInfo
├── log.go # Logger, NopLogger, Slog
├── genapi/ # GenICam GenApi XML parser / node map
├── gvcp/ # GigE Vision Control Protocol
├── gvsp/ # GigE Vision Streaming Protocol
├── gentl/ # GenTL constants (no CGO)
├── internal/ # color (PFNC decode + JPEG), genDC
├── grab/ # One-shot GrabJPEG / FromCamera
├── live/ # Continuous preview loop
├── examples/ # Runnable examples (smoke-test, grab, live, …)
├── .githooks/ # Versioned git hooks (gofmt + go test)
├── AGENTS.md # Project & protocol rules
├── CHANGELOG.md
├── ROADMAP.md
├── go.mod
└── LICENSE
Omit -ip to pick the first camera from GigE discovery (or pass -ip explicitly).
- Full stack smoke (CCP/heartbeat/XML/stream/pause/live):
examples/smoke-test - GenICam
Has/ApplyControlPair/Execute:examples/features - One-shot color JPEG to disk:
examples/grab - Discover BSCF components (color/depth/mono) and grab all:
examples/grab-components - Probe available stream types (pixel formats, payload/chunk/component features, per-frame JPEG encodability):
examples/probe-streams - Stream measurements only:
examples/stream-measurements - Dump GenICam XML:
examples/dump-xml - Configure volume TCP preset:
examples/configure-camera - Browser live stream:
examples/websocket-stream - CLI discover:
cmd/gogige-discover - CLI N-frame capture:
cmd/gogige-stream
Once per clone, point git at the versioned hooks (runs gofmt on staged .go files, then go test ./...):
git config core.hooksPath .githooksContributions are welcome! Feel free to open an issue or submit a pull request following these simple steps:
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature) - Commit your Changes (
git commit -m 'Add some AmazingFeature') - Push to the Branch (
git push origin feature/AmazingFeature) - Open a Pull Request
Distributed under the BSD 3-Clause License. See LICENSE for more information.