GigE Vision

MediaX implements the GigE Vision standard for industrial camera discovery, control, and video streaming over standard Gigabit Ethernet.

Standards Compliance

Standard Version Role
GigE Vision (AIA) 2.x Device discovery, control, streaming
GVCP — GigE Vision Control Protocol 2.x UDP/3956 register read/write, discovery, heartbeat
GVSP — GigE Vision Streaming Protocol 2.x UDP unicast frame packetization (leader/data/trailer)
GenICam (EMVA) 3.x XML device description, feature naming (SFNC)
IEEE 802.3 Underlying Gigabit Ethernet transport

GVCP Port

GVCP listens on UDP port 3956 (IANA assigned). Ensure this port is accessible on the device host.

Packet Size

The default GVSP stream packet size is 1456 bytes (excluding UDP/IP headers), matching a standard 1500-byte MTU. Jumbo frames (up to 9000 bytes) can be configured for higher throughput.

Supported Pixel Formats

GigE Vision pixel format codes are defined in the GVSP specification (Appendix A — Pixel Formats).

GvspPixelFormat enum Pixel Format Code Description Bytes/Pixel
kMono8 0x01080001 8-bit monochrome 1
kMono16 0x01100007 16-bit monochrome (big-endian on wire) 2
kRgb8 0x02180014 24-bit RGB, 8 bits per channel 3
kBayerGr8 0x01080008 8-bit Bayer, GR phase first 1
kBayerRg8 0x01080009 8-bit Bayer, RG phase first 1
kBayerGb8 0x0108000A 8-bit Bayer, GB phase first 1
kBayerBg8 0x0108000B 8-bit Bayer, BG phase first 1
kYcbcr422_8 0x0210003B YCbCr 4:2:2, 8-bit interleaved (YUYV) 2

Bayer demosaicing

Bayer raw frames can be converted to RGB using mediax::video::ColourSpaceCpu::BayerToRgb() or the GPU-accelerated mediax::video::ColourSpaceCuda::BayerToRgb().
Use mediax::video::BayerPattern to specify the phase (kRggb, kGrbg, kGbrg, kBggr).

Architecture

GigE Vision Architecture

The device side (GigEDevice) wraps a GvcpServer and a GvspSender. The host side (GigEReceiver) wraps a GvcpClient that discovers the device, negotiates the stream channel destination address/port, sends AcquisitionStart, and then receives GVSP frames via GvspReceiver.

Device Side (Camera Emulation)

Use mediax::gige::GigEDevice to emulate a GigE Vision camera:

#include "gige/gige_device.h"

mediax::gige::GigEDevice device;

// Set manufacturer metadata (appears in GenICam XML)
device.SetDeviceInfo("Astute Systems",           // manufacturer
                     "MediaX GigE Vision",       // model
                     "1.0.0",                    // device version
                     "SN00001",                  // serial number
                     "mediax-dev");              // user-defined name

// Configure image parameters
device.SetImageParams(1920, 1080,
                      mediax::gige::GvspPixelFormat::kRgb8,
                      25 /*fps*/);

if (!device.Open()) {
    std::cerr << "Port 3956 unavailable\n";
    return 1;
}

// Acquisition callback (fired when host sends AcquisitionStart)
device.SetAcquisitionStartCallback([]() {
    std::cout << "Acquisition started\n";
});

// Stream frames
std::vector<uint8_t> frame(1920 * 1080 * 3);
while (running) {
    if (device.IsStreaming())
        device.SendFrame(frame.data());
    // pace to target fps ...
}

device.Close();

Bayer Camera Example

device.SetImageParams(1920, 1080,
                      mediax::gige::GvspPixelFormat::kBayerRg8,
                      30);
// Populate raw Bayer frame before calling SendFrame()

Host Side (Frame Receiver)

Use mediax::gige::GigEReceiver to connect to any GigE Vision device:

#include "gige/gige_receiver.h"
#include "gige/gvsp/gvsp_receiver.h"

mediax::gige::GigEReceiver receiver;
receiver.SetReceivePort(55100);            // local UDP port for GVSP

if (!receiver.Connect("192.168.1.100")) {  // device IP
    std::cerr << "GVCP connect failed\n";
    return 1;
}

if (!receiver.Open()) {                    // takes control, sends AcquisitionStart
    std::cerr << "Stream open failed\n";
    return 1;
}

mediax::gige::gvsp::GvspFrameData frame;
while (running) {
    if (receiver.Receive(&frame, 2000 /*ms timeout*/)) {
        // frame.pixels  — raw pixel data
        // frame.width   — frame width
        // frame.height  — frame height
        // frame.pixel_format — GvspPixelFormat
        processFrame(frame);
    }
}

receiver.Close();

Converting Received Bayer Frames

#include "utils/colourspace_cpu.h"

mediax::video::ColourSpaceCpu cs;
mediax::gige::gvsp::GvspFrameData frame;

while (receiver.Receive(&frame, 2000)) {
    if (frame.pixel_format == mediax::gige::GvspPixelFormat::kBayerRg8) {
        std::vector<uint8_t> rgb(frame.width * frame.height * 3);
        cs.BayerToRgb(frame.height, frame.width,
                      frame.pixels.data(), rgb.data(),
                      mediax::video::BayerPattern::kRggb);
        // rgb now contains demosaiced RGB24 data
    }
}

Building with GigE Vision

Enable the BUILD_GIGE CMake option:

cmake -B build -DBUILD_GIGE=ON -DEXAMPLES=ON ..
make -C build -j$(nproc)

This builds:

  • libmediax — with GigE Vision support compiled in
  • bin/gige-transmit — camera emulator example
  • bin/gige-receive — frame receiver example

Example Applications

Binary Source Description
gige-transmit example/gige_vision/gige_transmit.cc Camera emulator — serves colour-bar frames over GVSP
gige-receive example/gige_vision/gige_receive.cc Host receiver — connects, receives frames, prints statistics

Run the transmitter and receiver on the same or different machines:

# Terminal 1: start the camera emulator (listens on UDP 3956)
./build/bin/gige-transmit --width 1920 --height 1080 --fps 25

# Terminal 2: connect and receive frames
./build/bin/gige-receive --device 127.0.0.1 --port 55100

Network Configuration

For production GigE Vision deployments:

  • Assign a static IP to the GigE interface on both device and host
  • Set interface MTU to 9000 (jumbo frames) for maximum throughput
  • Disable energy-efficient Ethernet (EEE) to avoid latency spikes:
ethtool --set-eee eth0 eee off
  • Use a dedicated VLAN or switch port to isolate camera traffic

See Also