add multi cam support

This commit is contained in:
Maik Jurischka committed 2026-10-19 14:48:26 +02:00
1 parent 5048dbb1ca
commit 1853360506
11 files changed
+108 -22

No files matched your search

+26
View File
@@ -35,6 +35,32 @@ cmake --build build
./build/vizionStreamer
```
### Multi-Camera
Run one instance per camera, each with its own camera index and socket path:
```bash
./build/vizionStreamer --camera 0 --socket /tmp/vizion_cam0.sock &
./build/vizionStreamer --camera 1 --socket /tmp/vizion_cam1.sock &
```
Point the control scripts at a specific instance with `VIZION_SOCKET`:
```bash
VIZION_SOCKET=/tmp/vizion_cam0.sock ./scripts/start_stream.sh
VIZION_SOCKET=/tmp/vizion_cam1.sock ./scripts/set_pipeline_udp.sh 192.168.1.100 5001
```
Without the env var, scripts default to `/tmp/vizion_control.sock` (single-camera usage).
CLI options:
```
-c, --camera <idx> Camera index to open (default: auto-detect VCI-AR0234, else 0)
-s, --socket <path> Control socket path (default: /tmp/vizion_control.sock)
-h, --help Show help
```
### Start Streaming (Default Pipeline)
In another terminal:
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/bash
# Get available camera formats
SOCKET="/tmp/vizion_control.sock"
SOCKET="${VIZION_SOCKET:-/tmp/vizion_control.sock}"
echo '{"command":"get_formats"}' | socat - UNIX-CONNECT:$SOCKET | python3 -m json.tool 2>/dev/null || echo '{"command":"get_formats"}' | socat - UNIX-CONNECT:$SOCKET
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/bash
# Get streaming status
SOCKET="/tmp/vizion_control.sock"
SOCKET="${VIZION_SOCKET:-/tmp/vizion_control.sock}"
echo '{"command":"get_status"}' | socat - UNIX-CONNECT:$SOCKET | python3 -m json.tool 2>/dev/null || echo '{"command":"get_status"}' | socat - UNIX-CONNECT:$SOCKET
+1 -1
View File
@@ -1,7 +1,7 @@
#!/bin/bash
# Set pipeline for local display (default)
SOCKET="/tmp/vizion_control.sock"
SOCKET="${VIZION_SOCKET:-/tmp/vizion_control.sock}"
echo "Setting display pipeline (default)..."
echo '{"command":"set_pipeline","params":{"pipeline":"videoconvert ! autovideosink"}}' | socat - UNIX-CONNECT:$SOCKET
+1 -1
View File
@@ -1,7 +1,7 @@
#!/bin/bash
# Set pipeline for recording to file
SOCKET="/tmp/vizion_control.sock"
SOCKET="${VIZION_SOCKET:-/tmp/vizion_control.sock}"
FILE="${1:-/tmp/vizion_recording.mp4}"
echo "Setting file recording pipeline to $FILE..."
+1 -1
View File
@@ -1,7 +1,7 @@
#!/bin/bash
# Set pipeline for MJPEG HTTP streaming
SOCKET="/tmp/vizion_control.sock"
SOCKET="${VIZION_SOCKET:-/tmp/vizion_control.sock}"
PORT="${1:-8080}"
# Check if gst-plugins-good with souphttpsink is available
+1 -1
View File
@@ -2,7 +2,7 @@
# Optimized pipeline for cameras that already output MJPEG format
# Passes through MJPEG data without re-encoding
SOCKET="/tmp/vizion_control.sock"
SOCKET="${VIZION_SOCKET:-/tmp/vizion_control.sock}"
PORT="${1:-8080}"
# Check if gst-plugins-good with souphttpsink is available
+1 -1
View File
@@ -1,7 +1,7 @@
#!/bin/bash
# Set pipeline for UDP streaming (H.264)
SOCKET="/tmp/vizion_control.sock"
SOCKET="${VIZION_SOCKET:-/tmp/vizion_control.sock}"
HOST="${1:-192.168.1.100}"
PORT="${2:-5000}"
+1 -1
View File
@@ -1,7 +1,7 @@
#!/bin/bash
# Quick start script - starts streaming with default pipeline
SOCKET="/tmp/vizion_control.sock"
SOCKET="${VIZION_SOCKET:-/tmp/vizion_control.sock}"
echo "Starting stream with default pipeline (videoconvert ! autovideosink)..."
echo '{"command":"start_stream"}' | socat - UNIX-CONNECT:$SOCKET
+1 -1
View File
@@ -1,7 +1,7 @@
#!/bin/bash
# Stop streaming
SOCKET="/tmp/vizion_control.sock"
SOCKET="${VIZION_SOCKET:-/tmp/vizion_control.sock}"
echo "Stopping stream..."
echo '{"command":"stop_stream"}' | socat - UNIX-CONNECT:$SOCKET
+73 -13
View File
@@ -21,11 +21,65 @@ void signalHandler(int signal) {
g_running = false;
}
int main() {
static void printUsage() {
std::cout << "Usage: vizionStreamer [options]\n"
<< " -c, --camera <idx> Camera index to open (default: auto-detect VCI-AR0234, else 0)\n"
<< " -s, --socket <path> Control socket path (default: /tmp/vizion_control.sock)\n"
<< " -h, --help Show this help\n"
<< "\n"
<< "Run multiple instances for multiple cameras:\n"
<< " ./vizionStreamer --camera 0 --socket /tmp/vizion_cam0.sock\n"
<< " ./vizionStreamer --camera 1 --socket /tmp/vizion_cam1.sock\n";
}
int main(int argc, char* argv[]) {
// Setup signal handlers for clean shutdown
signal(SIGINT, signalHandler);
signal(SIGTERM, signalHandler);
// Parse CLI arguments
int cameraIndex = -1; // -1 = auto-detect
std::string socketPath = "/tmp/vizion_control.sock";
bool argsOk = true;
try {
for (int i = 1; i < argc && argsOk; i++) {
const std::string arg = argv[i];
if (arg == "-h" || arg == "--help") {
printUsage();
return 0;
} else if (arg == "-c" || arg == "--camera") {
if (i + 1 >= argc) {
std::cerr << "Missing value for " << arg << std::endl;
argsOk = false;
} else {
cameraIndex = std::stoi(argv[++i]);
}
} else if (arg.rfind("--camera=", 0) == 0) {
cameraIndex = std::stoi(arg.substr(9));
} else if (arg == "-s" || arg == "--socket") {
if (i + 1 >= argc) {
std::cerr << "Missing value for " << arg << std::endl;
argsOk = false;
} else {
socketPath = argv[++i];
}
} else if (arg.rfind("--socket=", 0) == 0) {
socketPath = arg.substr(8);
} else {
std::cerr << "Unknown argument: " << arg << std::endl;
argsOk = false;
}
}
} catch (const std::exception& e) {
std::cerr << "Invalid argument: " << e.what() << std::endl;
argsOk = false;
}
if (!argsOk) {
printUsage();
return -1;
}
// List available cameras
std::vector<std::string> devList;
const int deviceCount = VxDiscoverCameraDevices(devList);
@@ -40,19 +94,26 @@ int main() {
std::cout << "[" << i << "] " << devList[i] << std::endl;
}
// Find VCI-AR0234 camera
int cameraIndex = -1;
for (size_t i = 0; i < devList.size(); i++) {
if (devList[i].find("VCI-AR0234") != std::string::npos) {
cameraIndex = static_cast<int>(i);
std::cout << "Selected camera [" << cameraIndex << "]: " << devList[i] << std::endl;
break;
if (cameraIndex >= 0) {
if (cameraIndex >= deviceCount) {
std::cout << "Camera index " << cameraIndex << " out of range (0-" << deviceCount - 1 << ")" << std::endl;
return -1;
}
std::cout << "Selected camera [" << cameraIndex << "]: " << devList[cameraIndex] << std::endl;
} else {
// Auto-detect: prefer VCI-AR0234, fall back to index 0
for (size_t i = 0; i < devList.size(); i++) {
if (devList[i].find("VCI-AR0234") != std::string::npos) {
cameraIndex = static_cast<int>(i);
std::cout << "Selected camera [" << cameraIndex << "]: " << devList[i] << std::endl;
break;
}
}
}
if (cameraIndex == -1) {
std::cout << "VCI-AR0234 camera not found, using default (index 0)" << std::endl;
cameraIndex = 0;
if (cameraIndex == -1) {
std::cout << "VCI-AR0234 camera not found, using default (index 0)" << std::endl;
cameraIndex = 0;
}
}
// Open camera
@@ -81,7 +142,6 @@ int main() {
const auto controller = std::make_shared<CameraController>(cam);
const std::string socketPath = "/tmp/vizion_control.sock";
SocketServer server(socketPath);
if (!server.start([controller](const std::string& cmd) {