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
|
./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)
|
### Start Streaming (Default Pipeline)
|
||||||
|
|
||||||
In another terminal:
|
In another terminal:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Get available camera formats
|
# 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
|
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
|
#!/bin/bash
|
||||||
# Get streaming status
|
# 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
|
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
|
#!/bin/bash
|
||||||
# Set pipeline for local display (default)
|
# Set pipeline for local display (default)
|
||||||
|
|
||||||
SOCKET="/tmp/vizion_control.sock"
|
SOCKET="${VIZION_SOCKET:-/tmp/vizion_control.sock}"
|
||||||
|
|
||||||
echo "Setting display pipeline (default)..."
|
echo "Setting display pipeline (default)..."
|
||||||
echo '{"command":"set_pipeline","params":{"pipeline":"videoconvert ! autovideosink"}}' | socat - UNIX-CONNECT:$SOCKET
|
echo '{"command":"set_pipeline","params":{"pipeline":"videoconvert ! autovideosink"}}' | socat - UNIX-CONNECT:$SOCKET
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Set pipeline for recording to file
|
# Set pipeline for recording to file
|
||||||
|
|
||||||
SOCKET="/tmp/vizion_control.sock"
|
SOCKET="${VIZION_SOCKET:-/tmp/vizion_control.sock}"
|
||||||
FILE="${1:-/tmp/vizion_recording.mp4}"
|
FILE="${1:-/tmp/vizion_recording.mp4}"
|
||||||
|
|
||||||
echo "Setting file recording pipeline to $FILE..."
|
echo "Setting file recording pipeline to $FILE..."
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Set pipeline for MJPEG HTTP streaming
|
# Set pipeline for MJPEG HTTP streaming
|
||||||
|
|
||||||
SOCKET="/tmp/vizion_control.sock"
|
SOCKET="${VIZION_SOCKET:-/tmp/vizion_control.sock}"
|
||||||
PORT="${1:-8080}"
|
PORT="${1:-8080}"
|
||||||
|
|
||||||
# Check if gst-plugins-good with souphttpsink is available
|
# Check if gst-plugins-good with souphttpsink is available
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# Optimized pipeline for cameras that already output MJPEG format
|
# Optimized pipeline for cameras that already output MJPEG format
|
||||||
# Passes through MJPEG data without re-encoding
|
# Passes through MJPEG data without re-encoding
|
||||||
|
|
||||||
SOCKET="/tmp/vizion_control.sock"
|
SOCKET="${VIZION_SOCKET:-/tmp/vizion_control.sock}"
|
||||||
PORT="${1:-8080}"
|
PORT="${1:-8080}"
|
||||||
|
|
||||||
# Check if gst-plugins-good with souphttpsink is available
|
# Check if gst-plugins-good with souphttpsink is available
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Set pipeline for UDP streaming (H.264)
|
# 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}"
|
HOST="${1:-192.168.1.100}"
|
||||||
PORT="${2:-5000}"
|
PORT="${2:-5000}"
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Quick start script - starts streaming with default pipeline
|
# 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 "Starting stream with default pipeline (videoconvert ! autovideosink)..."
|
||||||
echo '{"command":"start_stream"}' | socat - UNIX-CONNECT:$SOCKET
|
echo '{"command":"start_stream"}' | socat - UNIX-CONNECT:$SOCKET
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Stop streaming
|
# Stop streaming
|
||||||
|
|
||||||
SOCKET="/tmp/vizion_control.sock"
|
SOCKET="${VIZION_SOCKET:-/tmp/vizion_control.sock}"
|
||||||
|
|
||||||
echo "Stopping stream..."
|
echo "Stopping stream..."
|
||||||
echo '{"command":"stop_stream"}' | socat - UNIX-CONNECT:$SOCKET
|
echo '{"command":"stop_stream"}' | socat - UNIX-CONNECT:$SOCKET
|
||||||
+73
-13
@@ -21,11 +21,65 @@ void signalHandler(int signal) {
|
|||||||
g_running = false;
|
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
|
// Setup signal handlers for clean shutdown
|
||||||
signal(SIGINT, signalHandler);
|
signal(SIGINT, signalHandler);
|
||||||
signal(SIGTERM, 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
|
// List available cameras
|
||||||
std::vector<std::string> devList;
|
std::vector<std::string> devList;
|
||||||
const int deviceCount = VxDiscoverCameraDevices(devList);
|
const int deviceCount = VxDiscoverCameraDevices(devList);
|
||||||
@@ -40,19 +94,26 @@ int main() {
|
|||||||
std::cout << "[" << i << "] " << devList[i] << std::endl;
|
std::cout << "[" << i << "] " << devList[i] << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find VCI-AR0234 camera
|
if (cameraIndex >= 0) {
|
||||||
int cameraIndex = -1;
|
if (cameraIndex >= deviceCount) {
|
||||||
for (size_t i = 0; i < devList.size(); i++) {
|
std::cout << "Camera index " << cameraIndex << " out of range (0-" << deviceCount - 1 << ")" << std::endl;
|
||||||
if (devList[i].find("VCI-AR0234") != std::string::npos) {
|
return -1;
|
||||||
cameraIndex = static_cast<int>(i);
|
}
|
||||||
std::cout << "Selected camera [" << cameraIndex << "]: " << devList[i] << std::endl;
|
std::cout << "Selected camera [" << cameraIndex << "]: " << devList[cameraIndex] << std::endl;
|
||||||
break;
|
} 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) {
|
if (cameraIndex == -1) {
|
||||||
std::cout << "VCI-AR0234 camera not found, using default (index 0)" << std::endl;
|
std::cout << "VCI-AR0234 camera not found, using default (index 0)" << std::endl;
|
||||||
cameraIndex = 0;
|
cameraIndex = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open camera
|
// Open camera
|
||||||
@@ -81,7 +142,6 @@ int main() {
|
|||||||
|
|
||||||
const auto controller = std::make_shared<CameraController>(cam);
|
const auto controller = std::make_shared<CameraController>(cam);
|
||||||
|
|
||||||
const std::string socketPath = "/tmp/vizion_control.sock";
|
|
||||||
SocketServer server(socketPath);
|
SocketServer server(socketPath);
|
||||||
|
|
||||||
if (!server.start([controller](const std::string& cmd) {
|
if (!server.start([controller](const std::string& cmd) {
|
||||||
|
|||||||
Reference in new issue
Block a user