rocket-welder-sdk 1.1.28__py3-none-any.whl → 1.1.30__py3-none-any.whl

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.
@@ -0,0 +1,832 @@
1
+ Metadata-Version: 2.4
2
+ Name: rocket-welder-sdk
3
+ Version: 1.1.30
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
+ You can also see preview in your terminal.
182
+
183
+ ```bash
184
+ # Install x11-apps
185
+ sudo apt install x11-apps
186
+
187
+ # Test with a video file
188
+ docker run --rm \
189
+ -e CONNECTION_STRING="file:///data/test.mp4?loop=true&preview=true" \
190
+ -e DISPLAY=$DISPLAY \
191
+ -v /path/to/your/file.mp4:/data/test.mp4:ro -v /tmp/.X11-unix:/tmp/.X11-unix my-ai-app:v1
192
+ ```
193
+
194
+ ### Step 2: Test with Live Stream from Neuron
195
+
196
+ Once your container works locally, test it with a live stream from your Neuron device:
197
+
198
+ #### Configure RocketWelder Pipeline for Streaming
199
+
200
+ 1. Access RocketWelder UI on your Neuron device (usually `http://neuron-ip:8080`)
201
+ 2. Open **Pipeline Designer**
202
+ 3. Click **"Add Element"**
203
+ 4. Choose your video source (e.g., `pylonsrc` for Basler cameras)
204
+ 5. Add **caps filter** to specify format: `video/x-raw,width=1920,height=1080,format=GRAY8`
205
+ 6. Add **jpegenc** element
206
+ 7. Add **tcpserversink** element with properties:
207
+ - `host`: `0.0.0.0`
208
+ - `port`: `5000`
209
+ 8. Start the pipeline
210
+
211
+ Example pipeline:
212
+ ```
213
+ 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
214
+ ```
215
+
216
+ #### Connect from Your Dev Laptop
217
+
218
+ ```bash
219
+ # On your laptop - connect to Neuron's TCP stream
220
+ docker run --rm \
221
+ -e CONNECTION_STRING="mjpeg+tcp://neuron-ip:5000" \
222
+ --network host \
223
+ my-ai-app:v1
224
+ ```
225
+
226
+ This allows you to:
227
+ - Test your AI processing with real camera feeds
228
+ - Debug frame processing logic
229
+ - Measure performance with actual hardware
230
+
231
+ ## Deploying to Neuron Device
232
+
233
+ ### Option 1: Local Docker Registry (Recommended for Development)
234
+
235
+ This is the fastest workflow for iterative development:
236
+
237
+ #### Setup Registry on Your Laptop (One-time)
238
+
239
+ ```bash
240
+ # Start a local Docker registry
241
+ docker run -d \
242
+ -p 5000:5000 \
243
+ --restart=always \
244
+ --name registry \
245
+ registry:2
246
+
247
+ # Verify it's running
248
+ curl http://localhost:5000/v2/_catalog
249
+ ```
250
+
251
+ #### Configure Neuron to Use Your Laptop Registry (One-time)
252
+
253
+ ```bash
254
+ # SSH to Neuron device
255
+ ssh user@neuron-ip
256
+
257
+ # Edit Docker daemon config
258
+ sudo nano /etc/docker/daemon.json
259
+
260
+ # Add your laptop's IP to insecure registries:
261
+ {
262
+ "insecure-registries": ["laptop-ip:5000"]
263
+ }
264
+
265
+ # Restart Docker
266
+ sudo systemctl restart docker
267
+ ```
268
+
269
+ **Note**: Replace `laptop-ip` with your laptop's actual IP address (e.g., `192.168.1.100`).
270
+ To find it: `ip addr show` or `ifconfig`
271
+
272
+ #### Push Image to Your Registry
273
+
274
+ ```bash
275
+ # On your laptop - tag for local registry
276
+ docker tag my-ai-app:v1 localhost:5000/my-ai-app:v1
277
+
278
+ # Push to registry
279
+ docker push localhost:5000/my-ai-app:v1
280
+
281
+ # Verify push
282
+ curl http://localhost:5000/v2/my-ai-app/tags/list
283
+ ```
284
+
285
+ #### Pull on Neuron Device
286
+
287
+ ```bash
288
+ # SSH to Neuron
289
+ ssh user@neuron-ip
290
+
291
+ # Pull from laptop registry
292
+ docker pull laptop-ip:5000/my-ai-app:v1
293
+
294
+ # Verify image
295
+ docker images | grep my-ai-app
296
+ ```
297
+
298
+ #### Workflow Summary
299
+
300
+ ```bash
301
+ # Iterative development loop:
302
+ 1. Edit code on laptop
303
+ 2. docker build -t localhost:5000/my-ai-app:v1 .
304
+ 3. docker push localhost:5000/my-ai-app:v1
305
+ 4. Configure in RocketWelder UI (once)
306
+ 5. RocketWelder pulls and runs your container
307
+ ```
308
+
309
+ ### Option 2: Export/Import (For One-off Transfers)
310
+
311
+ Useful when you don't want to set up a registry:
312
+
313
+ ```bash
314
+ # On your laptop - save image to tar
315
+ docker save my-ai-app:v1 | gzip > my-ai-app-v1.tar.gz
316
+
317
+ # Transfer to Neuron
318
+ scp my-ai-app-v1.tar.gz user@neuron-ip:/tmp/
319
+
320
+ # SSH to Neuron and load
321
+ ssh user@neuron-ip
322
+ docker load < /tmp/my-ai-app-v1.tar.gz
323
+
324
+ # Verify
325
+ docker images | grep my-ai-app
326
+ ```
327
+
328
+ ### Option 3: Azure Container Registry (Production)
329
+
330
+ For production deployments:
331
+
332
+ ```bash
333
+ # Login to ACR (Azure Container Registry)
334
+ az acr login --name your-registry
335
+
336
+ # Tag and push
337
+ docker tag my-ai-app:v1 your-registry.azurecr.io/my-ai-app:v1
338
+ docker push your-registry.azurecr.io/my-ai-app:v1
339
+
340
+ # Configure Neuron to use ACR (credentials required)
341
+ ```
342
+
343
+ ## RocketWelder Integration
344
+
345
+ ### Understanding zerosink vs zerofilter
346
+
347
+ RocketWelder provides two GStreamer elements for container integration:
348
+
349
+ | Element | Mode | Use Case |
350
+ |---------|------|----------|
351
+ | **zerosink** | One-way | RocketWelder → Your Container<br/>Read frames, process, log results |
352
+ | **zerofilter** | Duplex | RocketWelder ↔ Your Container<br/>Read frames, modify them, return modified frames |
353
+
354
+ **Most AI use cases use `zerosink`** (one-way mode):
355
+ - Object detection (draw bounding boxes)
356
+ - Classification (overlay labels)
357
+ - Analytics (count objects, log events)
358
+
359
+ **Use `zerofilter`** (duplex mode) when:
360
+ - You need to modify frames and return them to the pipeline
361
+ - Real-time visual effects/filters
362
+ - Frame enhancement before encoding
363
+
364
+ ### Configuring Your Container in RocketWelder
365
+
366
+ #### Step-by-Step UI Configuration
367
+
368
+ 1. **Access RocketWelder UI**
369
+ - Navigate to `http://neuron-ip:8080`
370
+ - Log in to your Neuron device
371
+
372
+ 2. **Open Pipeline Designer**
373
+ - Go to **Pipelines** section
374
+ - Create new pipeline or edit existing
375
+
376
+ 3. **Add Video Source**
377
+ - Click **"Add Element"**
378
+ - Choose your camera source (e.g., `pylonsrc`, `aravissrc`)
379
+ - Configure camera properties
380
+
381
+ 4. **Add Format**
382
+ - Add caps filter: `video/x-raw,format=RGB`
383
+
384
+ 5. **Add queueue**
385
+ - max-num-buffers: 1
386
+ - leaky: upstream
387
+
388
+ 5. **Add ZeroBuffer Element**
389
+ - Click **"Add Element"**
390
+ - Select **"zerosink"** (or **"zerofilter"** for duplex mode)
391
+ - Scroll down in properties panel on the right
392
+
393
+ 6. **Configure Consumer**
394
+ - Toggle **"Enable ZeroBuffer Consumer"** ✓
395
+ - Select **"Consumer Mode"** dropdown
396
+ - Choose **"Docker Container"** (not Process)
397
+
398
+ 7. **Configure Docker Settings**
399
+ - **Image**: Enter your image name
400
+ - Local registry: `laptop-ip:5000/my-ai-app`
401
+ - ACR: `your-registry.azurecr.io/my-ai-app`
402
+ - Loaded image: `my-ai-app`
403
+ - **Tag**: `v1` (or your version tag)
404
+ - **Environment Variables**: (optional) Add custom env vars if needed
405
+ - **Auto-remove**: ✓ (recommended - cleans up container on stop)
406
+
407
+ 8. **Save Pipeline Configuration**
408
+
409
+ 9. **Start Pipeline**
410
+ - Click **"Start"** button
411
+ - RocketWelder will automatically:
412
+ - Pull your Docker image (if not present)
413
+ - Create shared memory buffer
414
+ - Launch your container with `CONNECTION_STRING` env var
415
+ - Start streaming frames
416
+
417
+ ### Automatic Environment Variables
418
+
419
+ When RocketWelder launches your container, it automatically sets:
420
+
421
+ ```bash
422
+ CONNECTION_STRING=shm://zerobuffer-abc123-456?size=20MB&metadata=4KB&mode=oneway
423
+ SessionId=def789-012 # For UI controls (if enabled)
424
+ EventStore=esdb://host.docker.internal:2113?tls=false # For external controls
425
+ ```
426
+
427
+ Your SDK code simply reads `CONNECTION_STRING`:
428
+
429
+ ```python
430
+ # Python - automatically reads CONNECTION_STRING from environment
431
+ client = rw.Client.from_(sys.argv)
432
+ ```
433
+
434
+ ```csharp
435
+ // C# - automatically reads CONNECTION_STRING
436
+ var client = RocketWelderClient.From(args);
437
+ ```
438
+
439
+ ### Example Pipeline Configurations
440
+
441
+ #### AI Object Detection Pipeline
442
+
443
+ ```
444
+ pylonsrc
445
+ → video/x-raw,width=1920,height=1080,format=Gray8
446
+ → videoconvert
447
+ → zerosink
448
+ └─ Docker: laptop-ip:5000/yolo-detector:v1
449
+ ```
450
+
451
+ Your YOLO container receives frames, detects objects, draws bounding boxes.
452
+
453
+ #### Dual Output: AI Processing
454
+
455
+ ```
456
+ pylonsrc
457
+ → video/x-raw,width=1920,height=1080,format=Gray8
458
+ → tee name=t
459
+ t. → queue → jpegenc → tcpserversink
460
+ t. → queue → zerofilter → queue → jpegenc → tcpserversink
461
+ └─ Docker: laptop-ip:5000/my-ai-app:v1
462
+ ```
463
+
464
+ #### Real-time Frame Enhancement with Live Preview (Duplex Mode)
465
+
466
+ ```
467
+ → pylonsrc hdr-sequence="5000,5500" hdr-sequence2="19,150" hdr-profile=0
468
+ → video/x-raw,width=1920,height=1080,format=Gray8
469
+ → queue max-num-buffers=1 leaky=upstream
470
+ → hdr mode=burst num-frames=2
471
+ → sortingbuffer
472
+ → queue max-num-buffers=1 leaky=upstream
473
+ → zerofilter
474
+ └─ Docker: laptop-ip:5000/frame-enhancer:v1
475
+ → queue max-num-buffers=1 leaky=upstream
476
+ → jpegenc
477
+ → multipartmux enable-html=true
478
+ → tcpserversink host=0.0.0.0 port=5000 sync=false
479
+ ```
480
+
481
+ In duplex mode with `zerofilter`, your container:
482
+ 1. Receives input frames via shared memory (automatically configured by RocketWelder)
483
+ 2. Processes them in real-time (e.g., AI enhancement, object detection, overlays)
484
+ 3. Writes modified frames back to shared memory
485
+ 4. Modified frames flow back into RocketWelder pipeline for streaming/display
486
+
487
+ **Pipeline elements explained:**
488
+ - `pylonsrc hdr-sequence="5000,5500"`: Configures HDR Profile 0 with 5000μs and 5500μs exposures (cycles automatically via camera sequencer)
489
+ - `hdr-sequence2="19,150"`: Configures HDR Profile 1 with 2 exposures for runtime switching
490
+ - `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.
491
+ - `hdr processing-mode=burst num-frames=2`: HDR blending element - combines multiple exposures into single HDR frame
492
+ - `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
493
+ - `zerofilter`: Bidirectional shared memory connection to your Docker container
494
+ - `jpegenc`: JPEG compression for network streaming
495
+ - `multipartmux enable-html=true`: Creates MJPEG stream with CORS headers for browser viewing
496
+ - `tcpserversink`: Streams to RocketWelder UI at `http://neuron-ip:5000`
497
+
498
+ **View live preview:**
499
+ Open in browser: `http://neuron-ip:5000` to see the processed video stream with your AI enhancements in real-time!
500
+
501
+ **HDR Profile Switching:**
502
+ The dual-profile system allows runtime switching between lighting conditions:
503
+ - Profile 0 (2 exposures): Fast cycling for normal conditions
504
+ - Profile 1 (2 exposures): More exposures for challenging lighting
505
+ - Switch dynamically via `hdr-profile` property without stopping the pipeline (requires another branch, histogram, dre, pylon-target)
506
+
507
+ **Use case examples:**
508
+ - **AI object detection**: Draw bounding boxes that appear in RocketWelder preview
509
+ - **Real-time enhancement**: AI super-resolution, denoising, stabilization
510
+ - **Visual feedback**: Add crosshairs, tracking overlays, status indicators
511
+ - **Quality control**: Highlight defects or areas of interest in industrial inspection
512
+
513
+ ## Connection String Format
514
+
515
+ The SDK uses URI-style connection strings:
516
+
517
+ ```
518
+ protocol://[host[:port]]/[path][?param1=value1&param2=value2]
519
+ ```
520
+
521
+ ### Supported Protocols
522
+
523
+ #### Shared Memory (Production - Automatic)
524
+ ```
525
+ shm://buffer-name?size=20MB&metadata=4KB&mode=oneway
526
+ ```
527
+
528
+ When deployed with RocketWelder, this is set automatically via `CONNECTION_STRING` environment variable.
529
+
530
+ **Parameters:**
531
+ - `size`: Buffer size (default: 20MB, supports: B, KB, MB, GB)
532
+ - `metadata`: Metadata size (default: 4KB)
533
+ - `mode`: `oneway` (zerosink) or `duplex` (zerofilter)
534
+
535
+ #### File Protocol (Local Testing)
536
+ ```
537
+ file:///path/to/video.mp4?loop=true&preview=false
538
+ ```
539
+
540
+ **Parameters:**
541
+ - `loop`: Loop playback (`true`/`false`, default: `false`)
542
+ - `preview`: Show preview window (`true`/`false`, default: `false`)
543
+
544
+ #### MJPEG over TCP (Development/Testing)
545
+ ```
546
+ mjpeg+tcp://neuron-ip:5000
547
+ ```
548
+
549
+ Connect to RocketWelder's `tcpserversink` for development testing.
550
+
551
+ #### MJPEG over HTTP
552
+ ```
553
+ mjpeg+http://camera-ip:8080
554
+ ```
555
+
556
+ For network cameras or HTTP streamers.
557
+
558
+ ## API Reference
559
+
560
+ ### Python API
561
+
562
+ ```python
563
+ import rocket_welder_sdk as rw
564
+
565
+ # Create client (reads CONNECTION_STRING from env or args)
566
+ client = rw.Client.from_(sys.argv)
567
+
568
+ # Or specify connection string directly
569
+ client = rw.Client.from_connection_string("shm://buffer-name?size=20MB")
570
+
571
+ # Process frames - one-way mode
572
+ @client.on_frame
573
+ def process_frame(frame: np.ndarray) -> None:
574
+ # frame is a numpy array (height, width, channels)
575
+ # Modify in-place for zero-copy performance
576
+ cv2.putText(frame, "AI Processing", (10, 30),
577
+ cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 255, 0), 2)
578
+
579
+ # Process frames - duplex mode
580
+ def process_frame_duplex(input_frame: np.ndarray, output_frame: np.ndarray) -> None:
581
+ # Copy input to output and modify
582
+ np.copyto(output_frame, input_frame)
583
+ # Add AI overlay to output_frame
584
+ cv2.putText(output_frame, "Processed", (10, 30),
585
+ cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 255, 0), 2)
586
+
587
+ # Start processing
588
+ client.start(process_frame) # or process_frame_duplex for duplex mode
589
+
590
+ # Keep running
591
+ while client.is_running:
592
+ time.sleep(0.1)
593
+
594
+ # Stop
595
+ client.stop()
596
+ ```
597
+
598
+ ### C# API
599
+
600
+ ```csharp
601
+ using RocketWelder.SDK;
602
+ using Emgu.CV;
603
+
604
+ // Create client (reads CONNECTION_STRING from env or config)
605
+ var client = RocketWelderClient.From(args);
606
+
607
+ // Or specify connection string directly
608
+ var client = RocketWelderClient.FromConnectionString("shm://buffer-name?size=20MB");
609
+
610
+ // Process frames - one-way mode
611
+ client.Start((Mat frame) =>
612
+ {
613
+ // frame is an Emgu.CV.Mat (zero-copy)
614
+ CvInvoke.PutText(frame, "AI Processing", new Point(10, 30),
615
+ FontFace.HersheySimplex, 1.0, new MCvScalar(0, 255, 0), 2);
616
+ });
617
+
618
+ // Process frames - duplex mode
619
+ client.Start((Mat input, Mat output) =>
620
+ {
621
+ input.CopyTo(output);
622
+ CvInvoke.PutText(output, "Processed", new Point(10, 30),
623
+ FontFace.HersheySimplex, 1.0, new MCvScalar(0, 255, 0), 2);
624
+ });
625
+ ```
626
+
627
+ ### C++ API
628
+
629
+ ```cpp
630
+ #include <rocket_welder/client.hpp>
631
+ #include <opencv2/opencv.hpp>
632
+
633
+ // Create client (reads CONNECTION_STRING from env or args)
634
+ auto client = rocket_welder::Client::from(argc, argv);
635
+
636
+ // Or specify connection string directly
637
+ auto client = rocket_welder::Client::from_connection_string("shm://buffer-name?size=20MB");
638
+
639
+ // Process frames - one-way mode
640
+ client.on_frame([](cv::Mat& frame) {
641
+ // frame is a cv::Mat reference (zero-copy)
642
+ cv::putText(frame, "AI Processing", cv::Point(10, 30),
643
+ cv::FONT_HERSHEY_SIMPLEX, 1.0, cv::Scalar(0, 255, 0), 2);
644
+ });
645
+
646
+ // Process frames - duplex mode
647
+ client.on_frame([](const cv::Mat& input, cv::Mat& output) {
648
+ input.copyTo(output);
649
+ cv::putText(output, "Processed", cv::Point(10, 30),
650
+ cv::FONT_HERSHEY_SIMPLEX, 1.0, cv::Scalar(0, 255, 0), 2);
651
+ });
652
+
653
+ // Start processing
654
+ client.start();
655
+ ```
656
+
657
+ ## Production Best Practices
658
+
659
+ ### Performance Optimization
660
+
661
+ 1. **Zero-Copy Processing**
662
+ - Modify frames in-place when possible
663
+ - Avoid unnecessary memory allocations in the frame processing loop
664
+ - Use OpenCV operations that work directly on the frame buffer
665
+
666
+ 2. **Frame Rate Management**
667
+ ```python
668
+ # Process every Nth frame for expensive AI operations
669
+ frame_count = 0
670
+
671
+ def process_frame(frame):
672
+ global frame_count
673
+ frame_count += 1
674
+ if frame_count % 5 == 0: # Process every 5th frame
675
+ run_expensive_ai_model(frame)
676
+ ```
677
+
678
+ 3. **Logging**
679
+ - Use structured logging with appropriate levels
680
+ - Avoid logging in the frame processing loop for production
681
+ - Log only important events (errors, detections, etc.)
682
+
683
+ ### Error Handling
684
+
685
+ ```python
686
+ import logging
687
+ import rocket_welder_sdk as rw
688
+
689
+ logger = logging.getLogger(__name__)
690
+
691
+ client = rw.Client.from_(sys.argv)
692
+
693
+ def on_error(sender, error):
694
+ logger.error(f"Client error: {error.Exception}")
695
+ # Implement recovery logic or graceful shutdown
696
+
697
+ client.OnError += on_error
698
+ ```
699
+
700
+ ### Monitoring
701
+
702
+ ```python
703
+ import time
704
+ from datetime import datetime
705
+
706
+ class FrameStats:
707
+ def __init__(self):
708
+ self.frame_count = 0
709
+ self.start_time = time.time()
710
+
711
+ def update(self):
712
+ self.frame_count += 1
713
+ if self.frame_count % 100 == 0:
714
+ elapsed = time.time() - self.start_time
715
+ fps = self.frame_count / elapsed
716
+ logger.info(f"Processed {self.frame_count} frames, {fps:.1f} FPS")
717
+
718
+ stats = FrameStats()
719
+
720
+ def process_frame(frame):
721
+ stats.update()
722
+ # Your processing logic
723
+ ```
724
+
725
+ ### Docker Best Practices
726
+
727
+ 1. **Use Multi-stage Builds**
728
+ ```dockerfile
729
+ FROM python:3.12-slim as builder
730
+ # Build dependencies
731
+
732
+ FROM python:3.12-slim
733
+ # Copy only runtime artifacts
734
+ ```
735
+
736
+ 2. **Minimize Image Size**
737
+ - Use slim base images
738
+ - Remove build tools in final stage
739
+ - Clean apt cache: `rm -rf /var/lib/apt/lists/*`
740
+
741
+ 3. **Health Checks**
742
+ ```dockerfile
743
+ HEALTHCHECK --interval=30s --timeout=3s \
744
+ CMD pgrep -f my_app.py || exit 1
745
+ ```
746
+
747
+ 4. **Resource Limits** (in RocketWelder docker-compose or deployment)
748
+ ```yaml
749
+ deploy:
750
+ resources:
751
+ limits:
752
+ cpus: '2.0'
753
+ memory: 2G
754
+ ```
755
+
756
+ ## Examples
757
+
758
+ The `examples/` directory contains complete working examples:
759
+
760
+ - **python/simple_client.py** - Minimal timestamp overlay
761
+ - **python/integration_client.py** - Testing with --exit-after flag
762
+ - **python/advanced_client.py** - Full-featured with UI controls
763
+ - **csharp/SimpleClient/** - Complete C# example with crosshair controls
764
+ - **cpp/simple_client.cpp** - C++ example
765
+
766
+ ## Troubleshooting
767
+
768
+ ### Container Doesn't Start
769
+
770
+ **Check Docker logs:**
771
+ ```bash
772
+ docker ps -a | grep my-ai-app
773
+ docker logs <container-id>
774
+ ```
775
+
776
+ **Common issues:**
777
+ - Image not found (check `docker images`)
778
+ - Insecure registry not configured on Neuron
779
+
780
+ ### Cannot Pull from Laptop Registry
781
+
782
+ ```bash
783
+ # On Neuron - test connectivity
784
+ ping laptop-ip
785
+
786
+ # Test registry access
787
+ curl http://laptop-ip:5000/v2/_catalog
788
+
789
+ # Check Docker daemon config
790
+ cat /etc/docker/daemon.json
791
+
792
+ # Restart Docker after config change
793
+ sudo systemctl restart docker
794
+ ```
795
+
796
+ ### SDK Connection Timeout
797
+
798
+ **Check shared memory buffer exists:**
799
+ ```bash
800
+ # On Neuron device
801
+ ls -lh /dev/shm/
802
+
803
+ # Should see zerobuffer-* files
804
+ ```
805
+
806
+ **Check RocketWelder pipeline status:**
807
+ - Is pipeline running?
808
+ - Is zerosink element configured correctly?
809
+ - Check RocketWelder logs for errors
810
+
811
+ ### Low Frame Rate / Performance
812
+
813
+ 1. **Check CPU usage:** `htop` or `docker stats`
814
+ 2. **Reduce AI model complexity** or process every Nth frame
815
+ 3. **Profile your code** to find bottlenecks
816
+ 4. **Use GPU acceleration** if available (NVIDIA runtime)
817
+
818
+ ## Support
819
+
820
+ - **Issues**: [GitHub Issues](https://github.com/modelingevolution/rocket-welder-sdk/issues)
821
+ - **Discussions**: [GitHub Discussions](https://github.com/modelingevolution/rocket-welder-sdk/discussions)
822
+ - **Documentation**: [https://docs.rocket-welder.io](https://docs.rocket-welder.io)
823
+
824
+ ## License
825
+
826
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
827
+
828
+ ## Acknowledgments
829
+
830
+ - GStreamer Project for the multimedia framework
831
+ - ZeroBuffer contributors for the zero-copy buffer implementation
832
+ - OpenCV community for computer vision tools