add multi cam support
This commit is contained in:
1 parent
5048dbb1ca
commit
1853360506
11 files changed
+108
-22
No files matched your search
@@ -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,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,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,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,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,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
|
||||
|
||||
@@ -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,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,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,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
@@ -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) {
|
||||
|
||||
Reference in new issue
Block a user