add SharedMemoryWriter support - without gstreamer
This commit is contained in:
@@ -600,10 +600,14 @@ Retrieve all current eHDR settings.
|
|||||||
|
|
||||||
### 21. Enable Shared Memory
|
### 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.
|
**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:**
|
**Command:**
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -698,7 +702,7 @@ Query the current shared memory configuration.
|
|||||||
|
|
||||||
## Usage Examples
|
## Usage Examples
|
||||||
|
|
||||||
### Complete Workflow Example
|
### Complete Workflow Example (GStreamer + Shared Memory)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 1. Set GStreamer pipeline for UDP streaming
|
# 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
|
# 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
|
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
|
echo '{"command":"start_stream"}' | socat - UNIX-CONNECT:/tmp/vizion_control.sock
|
||||||
|
|
||||||
# 5. Check status
|
# 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
|
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
|
### GStreamer Pipeline Examples
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -819,6 +853,35 @@ ls -lh /dev/shm/vizion_frame
|
|||||||
watch -n 0.1 'ls -l /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)
|
### Using `nc` (netcat with Unix socket support)
|
||||||
|
|
||||||
```bash
|
```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("set_ehdr_ratio_max", {"value": "24"}))
|
||||||
print(send_command("get_ehdr_status")) # Get current eHDR settings
|
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", {
|
print(send_command("enable_shared_memory", {
|
||||||
"name": "/vizion_frame",
|
"name": "/vizion_frame",
|
||||||
"buffer_size": "8294528"
|
"buffer_size": "8294528"
|
||||||
@@ -874,6 +937,17 @@ print(send_command("start_stream"))
|
|||||||
# ... streaming active, external process can read /dev/shm/vizion_frame ...
|
# ... streaming active, external process can read /dev/shm/vizion_frame ...
|
||||||
print(send_command("stop_stream"))
|
print(send_command("stop_stream"))
|
||||||
print(send_command("disable_shared_memory"))
|
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++
|
### 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":"set_ehdr_exposure_max","params":{"value":"4"}})") << std::endl;
|
||||||
std::cout << sendCommand(R"({"command":"get_ehdr_status"})") << 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":"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":"get_shared_memory_status"})") << std::endl;
|
||||||
std::cout << sendCommand(R"({"command":"start_stream"})") << 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":"stop_stream"})") << std::endl;
|
||||||
std::cout << sendCommand(R"({"command":"disable_shared_memory"})") << 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;
|
return 0;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -1316,7 +1398,11 @@ finally:
|
|||||||
- Default pipeline: `videoconvert ! autovideosink` (display locally)
|
- Default pipeline: `videoconvert ! autovideosink` (display locally)
|
||||||
- eHDR features require compatible camera models (VCI/VCS/VLS3/VLS-GM2/TEVS-AR0821/AR0822)
|
- 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)
|
- 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
|
- 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
|
- Shared memory files are automatically cleaned up when disabled or on clean exit
|
||||||
- Multiple processes can read from the same shared memory region simultaneously
|
- 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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set pipeline description
|
// Check if at least one output is configured
|
||||||
gstPipeline_->setPipelineDescription(gstPipeline);
|
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
|
// Start camera streaming
|
||||||
if (VxStartStreaming(camera_) != 0) {
|
if (VxStartStreaming(camera_) != 0) {
|
||||||
@@ -58,11 +64,17 @@ bool StreamingEngine::start(const std::string& gstPipeline) {
|
|||||||
bufferSize_ = calculatedBufferSize;
|
bufferSize_ = calculatedBufferSize;
|
||||||
buffer_ = std::make_unique<uint8_t[]>(bufferSize_);
|
buffer_ = std::make_unique<uint8_t[]>(bufferSize_);
|
||||||
|
|
||||||
// Start GStreamer pipeline
|
// Start GStreamer pipeline if configured
|
||||||
if (!gstPipeline_->start()) {
|
if (useGStreamer) {
|
||||||
std::cerr << "Failed to start GStreamer pipeline" << std::endl;
|
gstPipeline_->setPipelineDescription(gstPipeline);
|
||||||
VxStopStreaming(camera_);
|
if (!gstPipeline_->start()) {
|
||||||
return false;
|
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
|
// Start acquisition thread
|
||||||
@@ -85,8 +97,10 @@ void StreamingEngine::stop() {
|
|||||||
acquisitionThread_->join();
|
acquisitionThread_->join();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop GStreamer pipeline
|
// Stop GStreamer pipeline if running
|
||||||
gstPipeline_->stop();
|
if (gstPipeline_->isRunning()) {
|
||||||
|
gstPipeline_->stop();
|
||||||
|
}
|
||||||
|
|
||||||
// Stop camera streaming
|
// Stop camera streaming
|
||||||
VxStopStreaming(camera_);
|
VxStopStreaming(camera_);
|
||||||
@@ -131,11 +145,13 @@ void StreamingEngine::acquisitionLoop() {
|
|||||||
default: formatStr = "UNKNOWN"; break;
|
default: formatStr = "UNKNOWN"; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push frame to GStreamer pipeline
|
// Push frame to GStreamer pipeline if active
|
||||||
if (!gstPipeline_->pushBuffer(buffer_.get(), dataSize,
|
if (gstPipeline_->isRunning()) {
|
||||||
currentFormat_.width, currentFormat_.height,
|
if (!gstPipeline_->pushBuffer(buffer_.get(), dataSize,
|
||||||
formatStr)) {
|
currentFormat_.width, currentFormat_.height,
|
||||||
std::cerr << "Failed to push frame to GStreamer pipeline" << std::endl;
|
formatStr)) {
|
||||||
|
std::cerr << "Failed to push frame to GStreamer pipeline" << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push frame to shared memory if enabled
|
// Push frame to shared memory if enabled
|
||||||
|
|||||||
Reference in New Issue
Block a user