rocket-welder-sdk 1.1.28__tar.gz → 1.1.29__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. rocket_welder_sdk-1.1.29/PKG-INFO +819 -0
  2. rocket_welder_sdk-1.1.29/README.md +774 -0
  3. rocket_welder_sdk-1.1.29/VERSION +1 -0
  4. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/rocket_welder_sdk/controllers.py +156 -40
  5. rocket_welder_sdk-1.1.29/rocket_welder_sdk.egg-info/PKG-INFO +819 -0
  6. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/tests/test_controllers.py +4 -2
  7. rocket_welder_sdk-1.1.28/PKG-INFO +0 -627
  8. rocket_welder_sdk-1.1.28/README.md +0 -582
  9. rocket_welder_sdk-1.1.28/VERSION +0 -1
  10. rocket_welder_sdk-1.1.28/rocket_welder_sdk.egg-info/PKG-INFO +0 -627
  11. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/MANIFEST.in +0 -0
  12. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/logo.png +0 -0
  13. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/pyproject.toml +0 -0
  14. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/rocket_welder_sdk/__init__.py +0 -0
  15. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/rocket_welder_sdk/bytes_size.py +0 -0
  16. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/rocket_welder_sdk/connection_string.py +0 -0
  17. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/rocket_welder_sdk/external_controls/__init__.py +0 -0
  18. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/rocket_welder_sdk/external_controls/contracts.py +0 -0
  19. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/rocket_welder_sdk/external_controls/contracts_old.py +0 -0
  20. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/rocket_welder_sdk/gst_metadata.py +0 -0
  21. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/rocket_welder_sdk/opencv_controller.py +0 -0
  22. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/rocket_welder_sdk/periodic_timer.py +0 -0
  23. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/rocket_welder_sdk/py.typed +0 -0
  24. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/rocket_welder_sdk/rocket_welder_client.py +0 -0
  25. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/rocket_welder_sdk/ui/__init__.py +0 -0
  26. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/rocket_welder_sdk/ui/controls.py +0 -0
  27. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/rocket_welder_sdk/ui/icons.py +0 -0
  28. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/rocket_welder_sdk/ui/ui_events_projection.py +0 -0
  29. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/rocket_welder_sdk/ui/ui_service.py +0 -0
  30. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/rocket_welder_sdk/ui/value_types.py +0 -0
  31. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/rocket_welder_sdk.egg-info/SOURCES.txt +0 -0
  32. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/rocket_welder_sdk.egg-info/dependency_links.txt +0 -0
  33. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/rocket_welder_sdk.egg-info/requires.txt +0 -0
  34. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/rocket_welder_sdk.egg-info/top_level.txt +0 -0
  35. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/setup.cfg +0 -0
  36. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/setup.py +0 -0
  37. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/tests/test_bytes_size.py +0 -0
  38. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/tests/test_connection_string.py +0 -0
  39. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/tests/test_external_controls_serialization.py +0 -0
  40. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/tests/test_external_controls_serialization_v2.py +0 -0
  41. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/tests/test_gst_metadata.py +0 -0
  42. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/tests/test_icons.py +0 -0
  43. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/tests/test_ui_controls.py +0 -0
  44. {rocket_welder_sdk-1.1.28 → rocket_welder_sdk-1.1.29}/tests/test_ui_service_happy_path.py +0 -0
@@ -0,0 +1,819 @@
1
+ Metadata-Version: 2.4
2
+ Name: rocket-welder-sdk
3
+ Version: 1.1.29
4
+ Summary: High-performance video streaming SDK for RocketWelder services using ZeroBuffer IPC
5
+ Home-page: https://github.com/modelingevolution/rocket-welder-sdk
6
+ Author: ModelingEvolution
7
+ Author-email: ModelingEvolution <info@modelingevolution.com>
8
+ Maintainer-email: ModelingEvolution <info@modelingevolution.com>
9
+ License: MIT
10
+ Project-URL: Homepage, https://github.com/modelingevolution/rocket-welder-sdk
11
+ Project-URL: Repository, https://github.com/modelingevolution/rocket-welder-sdk.git
12
+ Project-URL: Issues, https://github.com/modelingevolution/rocket-welder-sdk/issues
13
+ Keywords: video,streaming,gstreamer,ipc,shared-memory,zerobuffer,computer-vision
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Topic :: Multimedia :: Video
17
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
18
+ Classifier: License :: OSI Approved :: MIT License
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3.8
21
+ Classifier: Programming Language :: Python :: 3.9
22
+ Classifier: Programming Language :: Python :: 3.10
23
+ Classifier: Programming Language :: Python :: 3.11
24
+ Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Operating System :: OS Independent
26
+ Classifier: Typing :: Typed
27
+ Requires-Python: >=3.8
28
+ Description-Content-Type: text/markdown
29
+ Requires-Dist: numpy>=1.20.0
30
+ Requires-Dist: opencv-python>=4.5.0
31
+ Requires-Dist: zerobuffer-ipc>=1.1.17
32
+ Requires-Dist: pydantic>=2.5.0
33
+ Requires-Dist: py-micro-plumberd>=0.1.8
34
+ Provides-Extra: dev
35
+ Requires-Dist: pytest>=7.0; extra == "dev"
36
+ Requires-Dist: pytest-cov>=4.0; extra == "dev"
37
+ Requires-Dist: pytest-asyncio>=0.21; extra == "dev"
38
+ Requires-Dist: black>=22.0; extra == "dev"
39
+ Requires-Dist: mypy>=1.0; extra == "dev"
40
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
41
+ Requires-Dist: types-setuptools; extra == "dev"
42
+ Dynamic: author
43
+ Dynamic: home-page
44
+ Dynamic: requires-python
45
+
46
+ # Rocket Welder SDK
47
+
48
+ [![NuGet](https://img.shields.io/nuget/v/RocketWelder.SDK.svg)](https://www.nuget.org/packages/RocketWelder.SDK/)
49
+ [![PyPI](https://img.shields.io/pypi/v/rocket-welder-sdk.svg)](https://pypi.org/project/rocket-welder-sdk/)
50
+ [![vcpkg](https://img.shields.io/badge/vcpkg-rocket--welder--sdk-blue)](https://github.com/modelingevolution/rocket-welder-sdk-vcpkg-registry)
51
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
52
+
53
+ **Client libraries for building custom AI/ML video processing containers that integrate with RocketWelder (Neuron) devices.**
54
+
55
+ ## Overview
56
+
57
+ The Rocket Welder SDK enables AI/ML developers to build custom video processing containers for Neuron industrial vision devices. It provides high-performance, **zero-copy** frame access via shared memory, supporting real-time computer vision, object detection, and AI inference workloads.
58
+
59
+ **Target Audience**: AI/ML developers building containerized applications for:
60
+ - Real-time object detection (YOLO, custom models)
61
+ - Computer vision processing
62
+ - AI inference on video streams
63
+ - Industrial vision applications
64
+
65
+ ## Table of Contents
66
+
67
+ - [Quick Start](#quick-start)
68
+ - [Your First AI Processing Container](#your-first-ai-processing-container)
69
+ - [Development Workflow](#development-workflow)
70
+ - [Deploying to Neuron Device](#deploying-to-neuron-device)
71
+ - [RocketWelder Integration](#rocketwelder-integration)
72
+ - [API Reference](#api-reference)
73
+ - [Production Best Practices](#production-best-practices)
74
+
75
+ ## Quick Start
76
+
77
+ ### Installation
78
+
79
+ | Language | Package Manager | Package Name |
80
+ |----------|----------------|--------------|
81
+ | C++ | vcpkg | rocket-welder-sdk |
82
+ | C# | NuGet | RocketWelder.SDK |
83
+ | Python | pip | rocket-welder-sdk |
84
+
85
+ #### Python
86
+ ```bash
87
+ pip install rocket-welder-sdk
88
+ ```
89
+
90
+ #### C#
91
+ ```bash
92
+ dotnet add package RocketWelder.SDK
93
+ ```
94
+
95
+ #### C++
96
+ ```bash
97
+ vcpkg install rocket-welder-sdk
98
+ ```
99
+
100
+ ## Your First AI Processing Container
101
+
102
+ ### Starting with Examples
103
+
104
+ The SDK includes ready-to-use examples in the `/examples` directory:
105
+
106
+ ```
107
+ examples/
108
+ ├── python/
109
+ │ ├── simple_client.py # Timestamp overlay example
110
+ │ ├── integration_client.py # Testing with --exit-after
111
+ │ └── Dockerfile # Ready-to-build container
112
+ ├── csharp/
113
+ │ └── SimpleClient/
114
+ │ ├── Program.cs # Full example with UI controls
115
+ │ └── Dockerfile # Ready-to-build container
116
+ └── cpp/
117
+ ├── simple_client.cpp
118
+ └── CMakeLists.txt
119
+ ```
120
+
121
+ ### Python Example - Simple Timestamp Overlay
122
+
123
+ ```python
124
+ #!/usr/bin/env python3
125
+ import sys
126
+ import cv2
127
+ import numpy as np
128
+ from datetime import datetime
129
+ import rocket_welder_sdk as rw
130
+
131
+ # Create client - reads CONNECTION_STRING from environment or args
132
+ client = rw.Client.from_(sys.argv)
133
+
134
+ def process_frame(frame: np.ndarray) -> None:
135
+ """Add timestamp overlay to frame - zero copy!"""
136
+ timestamp = datetime.now().strftime("%H:%M:%S")
137
+ cv2.putText(frame, timestamp, (10, 30),
138
+ cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2)
139
+
140
+ # Start processing
141
+ client.start(process_frame)
142
+
143
+ # Keep running
144
+ while client.is_running:
145
+ time.sleep(0.1)
146
+ ```
147
+
148
+ ### Building Your Container
149
+
150
+ ```bash
151
+ # Navigate to examples directory
152
+ cd python/examples
153
+
154
+ # Build Docker image
155
+ docker build -t my-ai-app:v1 -f Dockerfile ..
156
+
157
+ # Test locally with file
158
+ docker run --rm \
159
+ -e CONNECTION_STRING="file:///data/test.mp4?loop=true" \
160
+ -v /path/to/video.mp4:/data/test.mp4:ro \
161
+ my-ai-app:v1
162
+ ```
163
+
164
+ ## Development Workflow
165
+
166
+ ### Step 1: Test Locally with Video File
167
+
168
+ Start by testing your container locally before deploying to Neuron:
169
+
170
+ ```bash
171
+ # Build your container
172
+ docker build -t my-ai-app:v1 -f examples/python/Dockerfile .
173
+
174
+ # Test with a video file
175
+ docker run --rm \
176
+ -e CONNECTION_STRING="file:///data/test.mp4?loop=true&preview=false" \
177
+ -v $(pwd)/examples/test_stream.mp4:/data/test.mp4:ro \
178
+ my-ai-app:v1
179
+ ```
180
+
181
+ ### Step 2: Test with Live Stream from Neuron
182
+
183
+ Once your container works locally, test it with a live stream from your Neuron device:
184
+
185
+ #### Configure RocketWelder Pipeline for Streaming
186
+
187
+ 1. Access RocketWelder UI on your Neuron device (usually `http://neuron-ip:8080`)
188
+ 2. Open **Pipeline Designer**
189
+ 3. Click **"Add Element"**
190
+ 4. Choose your video source (e.g., `pylonsrc` for Basler cameras)
191
+ 5. Add **caps filter** to specify format: `video/x-raw,width=1920,height=1080,format=GRAY8`
192
+ 6. Add **jpegenc** element
193
+ 7. Add **tcpserversink** element with properties:
194
+ - `host`: `0.0.0.0`
195
+ - `port`: `5000`
196
+ 8. Start the pipeline
197
+
198
+ Example pipeline:
199
+ ```
200
+ pylonsrc → video/x-raw,width=1920,height=1080,format=GRAY8 → queue max-buffers-size=1, Leaky=Upstream → jpegenc → tcpserversink host=0.0.0.0 port=5000 sync=false
201
+ ```
202
+
203
+ #### Connect from Your Dev Laptop
204
+
205
+ ```bash
206
+ # On your laptop - connect to Neuron's TCP stream
207
+ docker run --rm \
208
+ -e CONNECTION_STRING="mjpeg+tcp://neuron-ip:5000" \
209
+ --network host \
210
+ my-ai-app:v1
211
+ ```
212
+
213
+ This allows you to:
214
+ - Test your AI processing with real camera feeds
215
+ - Debug frame processing logic
216
+ - Measure performance with actual hardware
217
+
218
+ ## Deploying to Neuron Device
219
+
220
+ ### Option 1: Local Docker Registry (Recommended for Development)
221
+
222
+ This is the fastest workflow for iterative development:
223
+
224
+ #### Setup Registry on Your Laptop (One-time)
225
+
226
+ ```bash
227
+ # Start a local Docker registry
228
+ docker run -d \
229
+ -p 5000:5000 \
230
+ --restart=always \
231
+ --name registry \
232
+ registry:2
233
+
234
+ # Verify it's running
235
+ curl http://localhost:5000/v2/_catalog
236
+ ```
237
+
238
+ #### Configure Neuron to Use Your Laptop Registry (One-time)
239
+
240
+ ```bash
241
+ # SSH to Neuron device
242
+ ssh user@neuron-ip
243
+
244
+ # Edit Docker daemon config
245
+ sudo nano /etc/docker/daemon.json
246
+
247
+ # Add your laptop's IP to insecure registries:
248
+ {
249
+ "insecure-registries": ["laptop-ip:5000"]
250
+ }
251
+
252
+ # Restart Docker
253
+ sudo systemctl restart docker
254
+ ```
255
+
256
+ **Note**: Replace `laptop-ip` with your laptop's actual IP address (e.g., `192.168.1.100`).
257
+ To find it: `ip addr show` or `ifconfig`
258
+
259
+ #### Push Image to Your Registry
260
+
261
+ ```bash
262
+ # On your laptop - tag for local registry
263
+ docker tag my-ai-app:v1 localhost:5000/my-ai-app:v1
264
+
265
+ # Push to registry
266
+ docker push localhost:5000/my-ai-app:v1
267
+
268
+ # Verify push
269
+ curl http://localhost:5000/v2/my-ai-app/tags/list
270
+ ```
271
+
272
+ #### Pull on Neuron Device
273
+
274
+ ```bash
275
+ # SSH to Neuron
276
+ ssh user@neuron-ip
277
+
278
+ # Pull from laptop registry
279
+ docker pull laptop-ip:5000/my-ai-app:v1
280
+
281
+ # Verify image
282
+ docker images | grep my-ai-app
283
+ ```
284
+
285
+ #### Workflow Summary
286
+
287
+ ```bash
288
+ # Iterative development loop:
289
+ 1. Edit code on laptop
290
+ 2. docker build -t localhost:5000/my-ai-app:v1 .
291
+ 3. docker push localhost:5000/my-ai-app:v1
292
+ 4. Configure in RocketWelder UI (once)
293
+ 5. RocketWelder pulls and runs your container
294
+ ```
295
+
296
+ ### Option 2: Export/Import (For One-off Transfers)
297
+
298
+ Useful when you don't want to set up a registry:
299
+
300
+ ```bash
301
+ # On your laptop - save image to tar
302
+ docker save my-ai-app:v1 | gzip > my-ai-app-v1.tar.gz
303
+
304
+ # Transfer to Neuron
305
+ scp my-ai-app-v1.tar.gz user@neuron-ip:/tmp/
306
+
307
+ # SSH to Neuron and load
308
+ ssh user@neuron-ip
309
+ docker load < /tmp/my-ai-app-v1.tar.gz
310
+
311
+ # Verify
312
+ docker images | grep my-ai-app
313
+ ```
314
+
315
+ ### Option 3: Azure Container Registry (Production)
316
+
317
+ For production deployments:
318
+
319
+ ```bash
320
+ # Login to ACR (Azure Container Registry)
321
+ az acr login --name your-registry
322
+
323
+ # Tag and push
324
+ docker tag my-ai-app:v1 your-registry.azurecr.io/my-ai-app:v1
325
+ docker push your-registry.azurecr.io/my-ai-app:v1
326
+
327
+ # Configure Neuron to use ACR (credentials required)
328
+ ```
329
+
330
+ ## RocketWelder Integration
331
+
332
+ ### Understanding zerosink vs zerofilter
333
+
334
+ RocketWelder provides two GStreamer elements for container integration:
335
+
336
+ | Element | Mode | Use Case |
337
+ |---------|------|----------|
338
+ | **zerosink** | One-way | RocketWelder → Your Container<br/>Read frames, process, log results |
339
+ | **zerofilter** | Duplex | RocketWelder ↔ Your Container<br/>Read frames, modify them, return modified frames |
340
+
341
+ **Most AI use cases use `zerosink`** (one-way mode):
342
+ - Object detection (draw bounding boxes)
343
+ - Classification (overlay labels)
344
+ - Analytics (count objects, log events)
345
+
346
+ **Use `zerofilter`** (duplex mode) when:
347
+ - You need to modify frames and return them to the pipeline
348
+ - Real-time visual effects/filters
349
+ - Frame enhancement before encoding
350
+
351
+ ### Configuring Your Container in RocketWelder
352
+
353
+ #### Step-by-Step UI Configuration
354
+
355
+ 1. **Access RocketWelder UI**
356
+ - Navigate to `http://neuron-ip:8080`
357
+ - Log in to your Neuron device
358
+
359
+ 2. **Open Pipeline Designer**
360
+ - Go to **Pipelines** section
361
+ - Create new pipeline or edit existing
362
+
363
+ 3. **Add Video Source**
364
+ - Click **"Add Element"**
365
+ - Choose your camera source (e.g., `pylonsrc`, `aravissrc`)
366
+ - Configure camera properties
367
+
368
+ 4. **Add Format**
369
+ - Add caps filter: `video/x-raw,format=RGB`
370
+
371
+ 5. **Add queueue**
372
+ - max-num-buffers: 1
373
+ - leaky: upstream
374
+
375
+ 5. **Add ZeroBuffer Element**
376
+ - Click **"Add Element"**
377
+ - Select **"zerosink"** (or **"zerofilter"** for duplex mode)
378
+ - Scroll down in properties panel on the right
379
+
380
+ 6. **Configure Consumer**
381
+ - Toggle **"Enable ZeroBuffer Consumer"** ✓
382
+ - Select **"Consumer Mode"** dropdown
383
+ - Choose **"Docker Container"** (not Process)
384
+
385
+ 7. **Configure Docker Settings**
386
+ - **Image**: Enter your image name
387
+ - Local registry: `laptop-ip:5000/my-ai-app`
388
+ - ACR: `your-registry.azurecr.io/my-ai-app`
389
+ - Loaded image: `my-ai-app`
390
+ - **Tag**: `v1` (or your version tag)
391
+ - **Environment Variables**: (optional) Add custom env vars if needed
392
+ - **Auto-remove**: ✓ (recommended - cleans up container on stop)
393
+
394
+ 8. **Save Pipeline Configuration**
395
+
396
+ 9. **Start Pipeline**
397
+ - Click **"Start"** button
398
+ - RocketWelder will automatically:
399
+ - Pull your Docker image (if not present)
400
+ - Create shared memory buffer
401
+ - Launch your container with `CONNECTION_STRING` env var
402
+ - Start streaming frames
403
+
404
+ ### Automatic Environment Variables
405
+
406
+ When RocketWelder launches your container, it automatically sets:
407
+
408
+ ```bash
409
+ CONNECTION_STRING=shm://zerobuffer-abc123-456?size=20MB&metadata=4KB&mode=oneway
410
+ SessionId=def789-012 # For UI controls (if enabled)
411
+ EventStore=esdb://host.docker.internal:2113?tls=false # For external controls
412
+ ```
413
+
414
+ Your SDK code simply reads `CONNECTION_STRING`:
415
+
416
+ ```python
417
+ # Python - automatically reads CONNECTION_STRING from environment
418
+ client = rw.Client.from_(sys.argv)
419
+ ```
420
+
421
+ ```csharp
422
+ // C# - automatically reads CONNECTION_STRING
423
+ var client = RocketWelderClient.From(args);
424
+ ```
425
+
426
+ ### Example Pipeline Configurations
427
+
428
+ #### AI Object Detection Pipeline
429
+
430
+ ```
431
+ pylonsrc
432
+ → video/x-raw,width=1920,height=1080,format=Gray8
433
+ → videoconvert
434
+ → zerosink
435
+ └─ Docker: laptop-ip:5000/yolo-detector:v1
436
+ ```
437
+
438
+ Your YOLO container receives frames, detects objects, draws bounding boxes.
439
+
440
+ #### Dual Output: AI Processing
441
+
442
+ ```
443
+ pylonsrc
444
+ → video/x-raw,width=1920,height=1080,format=Gray8
445
+ → tee name=t
446
+ t. → queue → jpegenc → tcpserversink
447
+ t. → queue → zerofilter → queue → jpegenc → tcpserversink
448
+ └─ Docker: laptop-ip:5000/my-ai-app:v1
449
+ ```
450
+
451
+ #### Real-time Frame Enhancement with Live Preview (Duplex Mode)
452
+
453
+ ```
454
+ → pylonsrc hdr-sequence="5000,5500" hdr-sequence2="19,150" hdr-profile=0
455
+ → video/x-raw,width=1920,height=1080,format=Gray8
456
+ → queue max-num-buffers=1 leaky=upstream
457
+ → hdr mode=burst num-frames=2
458
+ → sortingbuffer
459
+ → queue max-num-buffers=1 leaky=upstream
460
+ → zerofilter
461
+ └─ Docker: laptop-ip:5000/frame-enhancer:v1
462
+ → queue max-num-buffers=1 leaky=upstream
463
+ → jpegenc
464
+ → multipartmux enable-html=true
465
+ → tcpserversink host=0.0.0.0 port=5000 sync=false
466
+ ```
467
+
468
+ In duplex mode with `zerofilter`, your container:
469
+ 1. Receives input frames via shared memory (automatically configured by RocketWelder)
470
+ 2. Processes them in real-time (e.g., AI enhancement, object detection, overlays)
471
+ 3. Writes modified frames back to shared memory
472
+ 4. Modified frames flow back into RocketWelder pipeline for streaming/display
473
+
474
+ **Pipeline elements explained:**
475
+ - `pylonsrc hdr-sequence="5000,5500"`: Configures HDR Profile 0 with 5000μs and 5500μs exposures (cycles automatically via camera sequencer)
476
+ - `hdr-sequence2="19,150"`: Configures HDR Profile 1 with 2 exposures for runtime switching
477
+ - `hdr-profile=0`: Starts with Profile 0 (can be changed at runtime to switch between lighting conditions), requires a branch with histogram, dre and pylontarget.
478
+ - `hdr processing-mode=burst num-frames=2`: HDR blending element - combines multiple exposures into single HDR frame
479
+ - `sortingbuffer skip-behaviour=hdr`: Reorders out-of-order frames from Pylon camera using HDR metadata (MasterSequence, ExposureSequenceIndex) - automatically detects frame order using `image_number` from Pylon metadata
480
+ - `zerofilter`: Bidirectional shared memory connection to your Docker container
481
+ - `jpegenc`: JPEG compression for network streaming
482
+ - `multipartmux enable-html=true`: Creates MJPEG stream with CORS headers for browser viewing
483
+ - `tcpserversink`: Streams to RocketWelder UI at `http://neuron-ip:5000`
484
+
485
+ **View live preview:**
486
+ Open in browser: `http://neuron-ip:5000` to see the processed video stream with your AI enhancements in real-time!
487
+
488
+ **HDR Profile Switching:**
489
+ The dual-profile system allows runtime switching between lighting conditions:
490
+ - Profile 0 (2 exposures): Fast cycling for normal conditions
491
+ - Profile 1 (2 exposures): More exposures for challenging lighting
492
+ - Switch dynamically via `hdr-profile` property without stopping the pipeline (requires another branch, histogram, dre, pylon-target)
493
+
494
+ **Use case examples:**
495
+ - **AI object detection**: Draw bounding boxes that appear in RocketWelder preview
496
+ - **Real-time enhancement**: AI super-resolution, denoising, stabilization
497
+ - **Visual feedback**: Add crosshairs, tracking overlays, status indicators
498
+ - **Quality control**: Highlight defects or areas of interest in industrial inspection
499
+
500
+ ## Connection String Format
501
+
502
+ The SDK uses URI-style connection strings:
503
+
504
+ ```
505
+ protocol://[host[:port]]/[path][?param1=value1&param2=value2]
506
+ ```
507
+
508
+ ### Supported Protocols
509
+
510
+ #### Shared Memory (Production - Automatic)
511
+ ```
512
+ shm://buffer-name?size=20MB&metadata=4KB&mode=oneway
513
+ ```
514
+
515
+ When deployed with RocketWelder, this is set automatically via `CONNECTION_STRING` environment variable.
516
+
517
+ **Parameters:**
518
+ - `size`: Buffer size (default: 20MB, supports: B, KB, MB, GB)
519
+ - `metadata`: Metadata size (default: 4KB)
520
+ - `mode`: `oneway` (zerosink) or `duplex` (zerofilter)
521
+
522
+ #### File Protocol (Local Testing)
523
+ ```
524
+ file:///path/to/video.mp4?loop=true&preview=false
525
+ ```
526
+
527
+ **Parameters:**
528
+ - `loop`: Loop playback (`true`/`false`, default: `false`)
529
+ - `preview`: Show preview window (`true`/`false`, default: `false`)
530
+
531
+ #### MJPEG over TCP (Development/Testing)
532
+ ```
533
+ mjpeg+tcp://neuron-ip:5000
534
+ ```
535
+
536
+ Connect to RocketWelder's `tcpserversink` for development testing.
537
+
538
+ #### MJPEG over HTTP
539
+ ```
540
+ mjpeg+http://camera-ip:8080
541
+ ```
542
+
543
+ For network cameras or HTTP streamers.
544
+
545
+ ## API Reference
546
+
547
+ ### Python API
548
+
549
+ ```python
550
+ import rocket_welder_sdk as rw
551
+
552
+ # Create client (reads CONNECTION_STRING from env or args)
553
+ client = rw.Client.from_(sys.argv)
554
+
555
+ # Or specify connection string directly
556
+ client = rw.Client.from_connection_string("shm://buffer-name?size=20MB")
557
+
558
+ # Process frames - one-way mode
559
+ @client.on_frame
560
+ def process_frame(frame: np.ndarray) -> None:
561
+ # frame is a numpy array (height, width, channels)
562
+ # Modify in-place for zero-copy performance
563
+ cv2.putText(frame, "AI Processing", (10, 30),
564
+ cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 255, 0), 2)
565
+
566
+ # Process frames - duplex mode
567
+ def process_frame_duplex(input_frame: np.ndarray, output_frame: np.ndarray) -> None:
568
+ # Copy input to output and modify
569
+ np.copyto(output_frame, input_frame)
570
+ # Add AI overlay to output_frame
571
+ cv2.putText(output_frame, "Processed", (10, 30),
572
+ cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 255, 0), 2)
573
+
574
+ # Start processing
575
+ client.start(process_frame) # or process_frame_duplex for duplex mode
576
+
577
+ # Keep running
578
+ while client.is_running:
579
+ time.sleep(0.1)
580
+
581
+ # Stop
582
+ client.stop()
583
+ ```
584
+
585
+ ### C# API
586
+
587
+ ```csharp
588
+ using RocketWelder.SDK;
589
+ using Emgu.CV;
590
+
591
+ // Create client (reads CONNECTION_STRING from env or config)
592
+ var client = RocketWelderClient.From(args);
593
+
594
+ // Or specify connection string directly
595
+ var client = RocketWelderClient.FromConnectionString("shm://buffer-name?size=20MB");
596
+
597
+ // Process frames - one-way mode
598
+ client.Start((Mat frame) =>
599
+ {
600
+ // frame is an Emgu.CV.Mat (zero-copy)
601
+ CvInvoke.PutText(frame, "AI Processing", new Point(10, 30),
602
+ FontFace.HersheySimplex, 1.0, new MCvScalar(0, 255, 0), 2);
603
+ });
604
+
605
+ // Process frames - duplex mode
606
+ client.Start((Mat input, Mat output) =>
607
+ {
608
+ input.CopyTo(output);
609
+ CvInvoke.PutText(output, "Processed", new Point(10, 30),
610
+ FontFace.HersheySimplex, 1.0, new MCvScalar(0, 255, 0), 2);
611
+ });
612
+ ```
613
+
614
+ ### C++ API
615
+
616
+ ```cpp
617
+ #include <rocket_welder/client.hpp>
618
+ #include <opencv2/opencv.hpp>
619
+
620
+ // Create client (reads CONNECTION_STRING from env or args)
621
+ auto client = rocket_welder::Client::from(argc, argv);
622
+
623
+ // Or specify connection string directly
624
+ auto client = rocket_welder::Client::from_connection_string("shm://buffer-name?size=20MB");
625
+
626
+ // Process frames - one-way mode
627
+ client.on_frame([](cv::Mat& frame) {
628
+ // frame is a cv::Mat reference (zero-copy)
629
+ cv::putText(frame, "AI Processing", cv::Point(10, 30),
630
+ cv::FONT_HERSHEY_SIMPLEX, 1.0, cv::Scalar(0, 255, 0), 2);
631
+ });
632
+
633
+ // Process frames - duplex mode
634
+ client.on_frame([](const cv::Mat& input, cv::Mat& output) {
635
+ input.copyTo(output);
636
+ cv::putText(output, "Processed", cv::Point(10, 30),
637
+ cv::FONT_HERSHEY_SIMPLEX, 1.0, cv::Scalar(0, 255, 0), 2);
638
+ });
639
+
640
+ // Start processing
641
+ client.start();
642
+ ```
643
+
644
+ ## Production Best Practices
645
+
646
+ ### Performance Optimization
647
+
648
+ 1. **Zero-Copy Processing**
649
+ - Modify frames in-place when possible
650
+ - Avoid unnecessary memory allocations in the frame processing loop
651
+ - Use OpenCV operations that work directly on the frame buffer
652
+
653
+ 2. **Frame Rate Management**
654
+ ```python
655
+ # Process every Nth frame for expensive AI operations
656
+ frame_count = 0
657
+
658
+ def process_frame(frame):
659
+ global frame_count
660
+ frame_count += 1
661
+ if frame_count % 5 == 0: # Process every 5th frame
662
+ run_expensive_ai_model(frame)
663
+ ```
664
+
665
+ 3. **Logging**
666
+ - Use structured logging with appropriate levels
667
+ - Avoid logging in the frame processing loop for production
668
+ - Log only important events (errors, detections, etc.)
669
+
670
+ ### Error Handling
671
+
672
+ ```python
673
+ import logging
674
+ import rocket_welder_sdk as rw
675
+
676
+ logger = logging.getLogger(__name__)
677
+
678
+ client = rw.Client.from_(sys.argv)
679
+
680
+ def on_error(sender, error):
681
+ logger.error(f"Client error: {error.Exception}")
682
+ # Implement recovery logic or graceful shutdown
683
+
684
+ client.OnError += on_error
685
+ ```
686
+
687
+ ### Monitoring
688
+
689
+ ```python
690
+ import time
691
+ from datetime import datetime
692
+
693
+ class FrameStats:
694
+ def __init__(self):
695
+ self.frame_count = 0
696
+ self.start_time = time.time()
697
+
698
+ def update(self):
699
+ self.frame_count += 1
700
+ if self.frame_count % 100 == 0:
701
+ elapsed = time.time() - self.start_time
702
+ fps = self.frame_count / elapsed
703
+ logger.info(f"Processed {self.frame_count} frames, {fps:.1f} FPS")
704
+
705
+ stats = FrameStats()
706
+
707
+ def process_frame(frame):
708
+ stats.update()
709
+ # Your processing logic
710
+ ```
711
+
712
+ ### Docker Best Practices
713
+
714
+ 1. **Use Multi-stage Builds**
715
+ ```dockerfile
716
+ FROM python:3.12-slim as builder
717
+ # Build dependencies
718
+
719
+ FROM python:3.12-slim
720
+ # Copy only runtime artifacts
721
+ ```
722
+
723
+ 2. **Minimize Image Size**
724
+ - Use slim base images
725
+ - Remove build tools in final stage
726
+ - Clean apt cache: `rm -rf /var/lib/apt/lists/*`
727
+
728
+ 3. **Health Checks**
729
+ ```dockerfile
730
+ HEALTHCHECK --interval=30s --timeout=3s \
731
+ CMD pgrep -f my_app.py || exit 1
732
+ ```
733
+
734
+ 4. **Resource Limits** (in RocketWelder docker-compose or deployment)
735
+ ```yaml
736
+ deploy:
737
+ resources:
738
+ limits:
739
+ cpus: '2.0'
740
+ memory: 2G
741
+ ```
742
+
743
+ ## Examples
744
+
745
+ The `examples/` directory contains complete working examples:
746
+
747
+ - **python/simple_client.py** - Minimal timestamp overlay
748
+ - **python/integration_client.py** - Testing with --exit-after flag
749
+ - **python/advanced_client.py** - Full-featured with UI controls
750
+ - **csharp/SimpleClient/** - Complete C# example with crosshair controls
751
+ - **cpp/simple_client.cpp** - C++ example
752
+
753
+ ## Troubleshooting
754
+
755
+ ### Container Doesn't Start
756
+
757
+ **Check Docker logs:**
758
+ ```bash
759
+ docker ps -a | grep my-ai-app
760
+ docker logs <container-id>
761
+ ```
762
+
763
+ **Common issues:**
764
+ - Image not found (check `docker images`)
765
+ - Insecure registry not configured on Neuron
766
+
767
+ ### Cannot Pull from Laptop Registry
768
+
769
+ ```bash
770
+ # On Neuron - test connectivity
771
+ ping laptop-ip
772
+
773
+ # Test registry access
774
+ curl http://laptop-ip:5000/v2/_catalog
775
+
776
+ # Check Docker daemon config
777
+ cat /etc/docker/daemon.json
778
+
779
+ # Restart Docker after config change
780
+ sudo systemctl restart docker
781
+ ```
782
+
783
+ ### SDK Connection Timeout
784
+
785
+ **Check shared memory buffer exists:**
786
+ ```bash
787
+ # On Neuron device
788
+ ls -lh /dev/shm/
789
+
790
+ # Should see zerobuffer-* files
791
+ ```
792
+
793
+ **Check RocketWelder pipeline status:**
794
+ - Is pipeline running?
795
+ - Is zerosink element configured correctly?
796
+ - Check RocketWelder logs for errors
797
+
798
+ ### Low Frame Rate / Performance
799
+
800
+ 1. **Check CPU usage:** `htop` or `docker stats`
801
+ 2. **Reduce AI model complexity** or process every Nth frame
802
+ 3. **Profile your code** to find bottlenecks
803
+ 4. **Use GPU acceleration** if available (NVIDIA runtime)
804
+
805
+ ## Support
806
+
807
+ - **Issues**: [GitHub Issues](https://github.com/modelingevolution/rocket-welder-sdk/issues)
808
+ - **Discussions**: [GitHub Discussions](https://github.com/modelingevolution/rocket-welder-sdk/discussions)
809
+ - **Documentation**: [https://docs.rocket-welder.io](https://docs.rocket-welder.io)
810
+
811
+ ## License
812
+
813
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
814
+
815
+ ## Acknowledgments
816
+
817
+ - GStreamer Project for the multimedia framework
818
+ - ZeroBuffer contributors for the zero-copy buffer implementation
819
+ - OpenCV community for computer vision tools