add SharedMemoryWriter support - without gstreamer
This commit is contained in:
@@ -600,10 +600,14 @@ Retrieve all current eHDR settings.
|
||||
|
||||
### 21. Enable Shared Memory
|
||||
|
||||
Enable shared memory output for direct frame access by external processes. This creates a shared memory region at `/dev/shm/<name>` where frames are written in parallel to the GStreamer pipeline.
|
||||
Enable shared memory output for direct frame access by external processes. This creates a shared memory region at `/dev/shm/<name>` where frames are written.
|
||||
|
||||
**Note:** Cannot be enabled while streaming is active. Must be enabled before starting the stream.
|
||||
|
||||
**Important:** Shared memory can be used **with or without** GStreamer:
|
||||
- **With GStreamer:** Frames are written to both GStreamer pipeline and shared memory
|
||||
- **Without GStreamer:** Set pipeline to empty string `""` - frames are only written to shared memory
|
||||
|
||||
**Command:**
|
||||
```json
|
||||
{
|
||||
@@ -698,7 +702,7 @@ Query the current shared memory configuration.
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Complete Workflow Example
|
||||
### Complete Workflow Example (GStreamer + Shared Memory)
|
||||
|
||||
```bash
|
||||
# 1. Set GStreamer pipeline for UDP streaming
|
||||
@@ -721,7 +725,7 @@ echo '{"command":"set_ehdr_ratio_max","params":{"value":"24"}}' | socat - UNIX-C
|
||||
# 3b. (Optional) Enable shared memory output
|
||||
echo '{"command":"enable_shared_memory","params":{"name":"/vizion_frame","buffer_size":"8294528"}}' | socat - UNIX-CONNECT:/tmp/vizion_control.sock
|
||||
|
||||
# 4. Start streaming
|
||||
# 4. Start streaming (both GStreamer and shared memory active)
|
||||
echo '{"command":"start_stream"}' | socat - UNIX-CONNECT:/tmp/vizion_control.sock
|
||||
|
||||
# 5. Check status
|
||||
@@ -735,6 +739,36 @@ echo '{"command":"stop_stream"}' | socat - UNIX-CONNECT:/tmp/vizion_control.sock
|
||||
echo '{"command":"disable_shared_memory"}' | socat - UNIX-CONNECT:/tmp/vizion_control.sock
|
||||
```
|
||||
|
||||
### Shared Memory Only Workflow (No GStreamer)
|
||||
|
||||
```bash
|
||||
# 1. Disable GStreamer pipeline
|
||||
echo '{"command":"set_pipeline","params":{"pipeline":""}}' | socat - UNIX-CONNECT:/tmp/vizion_control.sock
|
||||
|
||||
# 2. Set video format
|
||||
echo '{"command":"set_format","params":{"width":"1920","height":"1080","framerate":"30","format":"YUY2"}}' | socat - UNIX-CONNECT:/tmp/vizion_control.sock
|
||||
|
||||
# 3. Configure camera settings
|
||||
echo '{"command":"set_exposure","params":{"mode":"auto"}}' | socat - UNIX-CONNECT:/tmp/vizion_control.sock
|
||||
echo '{"command":"set_brightness","params":{"value":"50"}}' | socat - UNIX-CONNECT:/tmp/vizion_control.sock
|
||||
|
||||
# 4. Enable shared memory
|
||||
echo '{"command":"enable_shared_memory","params":{"name":"/vizion_frame","buffer_size":"8294528"}}' | socat - UNIX-CONNECT:/tmp/vizion_control.sock
|
||||
|
||||
# 5. Start streaming (shared memory only)
|
||||
echo '{"command":"start_stream"}' | socat - UNIX-CONNECT:/tmp/vizion_control.sock
|
||||
# Output: "GStreamer pipeline disabled (using shared memory only)"
|
||||
|
||||
# 6. Check that shared memory is being updated
|
||||
ls -l /dev/shm/vizion_frame # Watch file modification time
|
||||
|
||||
# 7. Stop streaming
|
||||
echo '{"command":"stop_stream"}' | socat - UNIX-CONNECT:/tmp/vizion_control.sock
|
||||
|
||||
# 8. Disable shared memory
|
||||
echo '{"command":"disable_shared_memory"}' | socat - UNIX-CONNECT:/tmp/vizion_control.sock
|
||||
```
|
||||
|
||||
### GStreamer Pipeline Examples
|
||||
|
||||
```bash
|
||||
@@ -819,6 +853,35 @@ ls -lh /dev/shm/vizion_frame
|
||||
watch -n 0.1 'ls -l /dev/shm/vizion_frame'
|
||||
```
|
||||
|
||||
### Shared Memory WITHOUT GStreamer (Shared Memory Only)
|
||||
|
||||
To use shared memory without GStreamer, disable the GStreamer pipeline by setting it to an empty string:
|
||||
|
||||
```bash
|
||||
# 1. Disable GStreamer pipeline
|
||||
echo '{"command":"set_pipeline","params":{"pipeline":""}}' | socat - UNIX-CONNECT:/tmp/vizion_control.sock
|
||||
|
||||
# 2. Enable shared memory
|
||||
echo '{"command":"enable_shared_memory","params":{"name":"/vizion_frame","buffer_size":"8294528"}}' | socat - UNIX-CONNECT:/tmp/vizion_control.sock
|
||||
|
||||
# 3. Start streaming (frames will only go to shared memory)
|
||||
echo '{"command":"start_stream"}' | socat - UNIX-CONNECT:/tmp/vizion_control.sock
|
||||
|
||||
# Output: "GStreamer pipeline disabled (using shared memory only)"
|
||||
|
||||
# 4. Stop streaming
|
||||
echo '{"command":"stop_stream"}' | socat - UNIX-CONNECT:/tmp/vizion_control.sock
|
||||
|
||||
# 5. Optionally re-enable GStreamer for next session
|
||||
echo '{"command":"set_pipeline","params":{"pipeline":"videoconvert ! autovideosink"}}' | socat - UNIX-CONNECT:/tmp/vizion_control.sock
|
||||
```
|
||||
|
||||
**Benefits of Shared Memory Only Mode:**
|
||||
- Lower CPU usage (no GStreamer overhead)
|
||||
- Lower memory bandwidth (no duplicate frame copies to GStreamer)
|
||||
- Suitable for headless systems or custom processing pipelines
|
||||
- Multiple external processes can still read from shared memory simultaneously
|
||||
|
||||
### Using `nc` (netcat with Unix socket support)
|
||||
|
||||
```bash
|
||||
@@ -864,7 +927,7 @@ print(send_command("set_ehdr_ratio_min", {"value": "12"}))
|
||||
print(send_command("set_ehdr_ratio_max", {"value": "24"}))
|
||||
print(send_command("get_ehdr_status")) # Get current eHDR settings
|
||||
|
||||
# Shared memory control examples
|
||||
# Shared memory control examples (with GStreamer)
|
||||
print(send_command("enable_shared_memory", {
|
||||
"name": "/vizion_frame",
|
||||
"buffer_size": "8294528"
|
||||
@@ -874,6 +937,17 @@ print(send_command("start_stream"))
|
||||
# ... streaming active, external process can read /dev/shm/vizion_frame ...
|
||||
print(send_command("stop_stream"))
|
||||
print(send_command("disable_shared_memory"))
|
||||
|
||||
# Shared memory only (without GStreamer)
|
||||
print(send_command("set_pipeline", {"pipeline": ""})) # Disable GStreamer
|
||||
print(send_command("enable_shared_memory", {
|
||||
"name": "/vizion_frame",
|
||||
"buffer_size": "8294528"
|
||||
}))
|
||||
print(send_command("start_stream")) # Frames only go to shared memory
|
||||
# Output: "GStreamer pipeline disabled (using shared memory only)"
|
||||
print(send_command("stop_stream"))
|
||||
print(send_command("disable_shared_memory"))
|
||||
```
|
||||
|
||||
### Using C++
|
||||
@@ -915,7 +989,7 @@ int main() {
|
||||
std::cout << sendCommand(R"({"command":"set_ehdr_exposure_max","params":{"value":"4"}})") << std::endl;
|
||||
std::cout << sendCommand(R"({"command":"get_ehdr_status"})") << std::endl;
|
||||
|
||||
// Shared memory control examples
|
||||
// Shared memory control examples (with GStreamer)
|
||||
std::cout << sendCommand(R"({"command":"enable_shared_memory","params":{"name":"/vizion_frame","buffer_size":"8294528"}})") << std::endl;
|
||||
std::cout << sendCommand(R"({"command":"get_shared_memory_status"})") << std::endl;
|
||||
std::cout << sendCommand(R"({"command":"start_stream"})") << std::endl;
|
||||
@@ -923,6 +997,14 @@ int main() {
|
||||
std::cout << sendCommand(R"({"command":"stop_stream"})") << std::endl;
|
||||
std::cout << sendCommand(R"({"command":"disable_shared_memory"})") << std::endl;
|
||||
|
||||
// Shared memory only (without GStreamer)
|
||||
std::cout << sendCommand(R"({"command":"set_pipeline","params":{"pipeline":""}})") << std::endl; // Disable GStreamer
|
||||
std::cout << sendCommand(R"({"command":"enable_shared_memory","params":{"name":"/vizion_frame","buffer_size":"8294528"}})") << std::endl;
|
||||
std::cout << sendCommand(R"({"command":"start_stream"})") << std::endl; // Frames only go to shared memory
|
||||
// Output: "GStreamer pipeline disabled (using shared memory only)"
|
||||
std::cout << sendCommand(R"({"command":"stop_stream"})") << std::endl;
|
||||
std::cout << sendCommand(R"({"command":"disable_shared_memory"})") << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
@@ -1316,7 +1398,11 @@ finally:
|
||||
- Default pipeline: `videoconvert ! autovideosink` (display locally)
|
||||
- eHDR features require compatible camera models (VCI/VCS/VLS3/VLS-GM2/TEVS-AR0821/AR0822)
|
||||
- eHDR settings may be reset to defaults when the camera starts streaming (driver behavior)
|
||||
- Shared memory output is independent of GStreamer pipeline (both run in parallel)
|
||||
- Shared memory output can run with or without GStreamer pipeline:
|
||||
- **With GStreamer:** Both outputs active (parallel operation)
|
||||
- **Without GStreamer:** Set pipeline to `""` for shared memory only (lower CPU/memory usage)
|
||||
- Shared memory must be enabled before starting the stream
|
||||
- At least one output (GStreamer or shared memory) must be configured to start streaming
|
||||
- Shared memory files are automatically cleaned up when disabled or on clean exit
|
||||
- Multiple processes can read from the same shared memory region simultaneously
|
||||
- Shared memory only mode is recommended for headless systems or custom processing applications
|
||||
|
||||
@@ -35,8 +35,14 @@ bool StreamingEngine::start(const std::string& gstPipeline) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set pipeline description
|
||||
gstPipeline_->setPipelineDescription(gstPipeline);
|
||||
// Check if at least one output is configured
|
||||
const bool useGStreamer = !gstPipeline.empty();
|
||||
const bool useSharedMemory = (shmWriter_ && shmWriter_->isCreated());
|
||||
|
||||
if (!useGStreamer && !useSharedMemory) {
|
||||
std::cerr << "No output configured. Enable GStreamer pipeline or shared memory first." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Start camera streaming
|
||||
if (VxStartStreaming(camera_) != 0) {
|
||||
@@ -58,11 +64,17 @@ bool StreamingEngine::start(const std::string& gstPipeline) {
|
||||
bufferSize_ = calculatedBufferSize;
|
||||
buffer_ = std::make_unique<uint8_t[]>(bufferSize_);
|
||||
|
||||
// Start GStreamer pipeline
|
||||
if (!gstPipeline_->start()) {
|
||||
std::cerr << "Failed to start GStreamer pipeline" << std::endl;
|
||||
VxStopStreaming(camera_);
|
||||
return false;
|
||||
// Start GStreamer pipeline if configured
|
||||
if (useGStreamer) {
|
||||
gstPipeline_->setPipelineDescription(gstPipeline);
|
||||
if (!gstPipeline_->start()) {
|
||||
std::cerr << "Failed to start GStreamer pipeline" << std::endl;
|
||||
VxStopStreaming(camera_);
|
||||
return false;
|
||||
}
|
||||
std::cout << "GStreamer pipeline started" << std::endl;
|
||||
} else {
|
||||
std::cout << "GStreamer pipeline disabled (using shared memory only)" << std::endl;
|
||||
}
|
||||
|
||||
// Start acquisition thread
|
||||
@@ -85,8 +97,10 @@ void StreamingEngine::stop() {
|
||||
acquisitionThread_->join();
|
||||
}
|
||||
|
||||
// Stop GStreamer pipeline
|
||||
gstPipeline_->stop();
|
||||
// Stop GStreamer pipeline if running
|
||||
if (gstPipeline_->isRunning()) {
|
||||
gstPipeline_->stop();
|
||||
}
|
||||
|
||||
// Stop camera streaming
|
||||
VxStopStreaming(camera_);
|
||||
@@ -131,11 +145,13 @@ void StreamingEngine::acquisitionLoop() {
|
||||
default: formatStr = "UNKNOWN"; break;
|
||||
}
|
||||
|
||||
// Push frame to GStreamer pipeline
|
||||
if (!gstPipeline_->pushBuffer(buffer_.get(), dataSize,
|
||||
currentFormat_.width, currentFormat_.height,
|
||||
formatStr)) {
|
||||
std::cerr << "Failed to push frame to GStreamer pipeline" << std::endl;
|
||||
// Push frame to GStreamer pipeline if active
|
||||
if (gstPipeline_->isRunning()) {
|
||||
if (!gstPipeline_->pushBuffer(buffer_.get(), dataSize,
|
||||
currentFormat_.width, currentFormat_.height,
|
||||
formatStr)) {
|
||||
std::cerr << "Failed to push frame to GStreamer pipeline" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Push frame to shared memory if enabled
|
||||
|
||||
Reference in New Issue
Block a user