matrice-streaming 0.1.14__py3-none-any.whl → 0.1.65__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.
Files changed (38) hide show
  1. matrice_streaming/__init__.py +44 -32
  2. matrice_streaming/streaming_gateway/camera_streamer/__init__.py +68 -1
  3. matrice_streaming/streaming_gateway/camera_streamer/async_camera_worker.py +1388 -0
  4. matrice_streaming/streaming_gateway/camera_streamer/async_ffmpeg_worker.py +966 -0
  5. matrice_streaming/streaming_gateway/camera_streamer/camera_streamer.py +188 -24
  6. matrice_streaming/streaming_gateway/camera_streamer/device_detection.py +507 -0
  7. matrice_streaming/streaming_gateway/camera_streamer/encoding_pool_manager.py +136 -0
  8. matrice_streaming/streaming_gateway/camera_streamer/ffmpeg_camera_streamer.py +1048 -0
  9. matrice_streaming/streaming_gateway/camera_streamer/ffmpeg_config.py +192 -0
  10. matrice_streaming/streaming_gateway/camera_streamer/ffmpeg_worker_manager.py +470 -0
  11. matrice_streaming/streaming_gateway/camera_streamer/gstreamer_camera_streamer.py +1368 -0
  12. matrice_streaming/streaming_gateway/camera_streamer/gstreamer_worker.py +1063 -0
  13. matrice_streaming/streaming_gateway/camera_streamer/gstreamer_worker_manager.py +546 -0
  14. matrice_streaming/streaming_gateway/camera_streamer/message_builder.py +60 -15
  15. matrice_streaming/streaming_gateway/camera_streamer/nvdec.py +1330 -0
  16. matrice_streaming/streaming_gateway/camera_streamer/nvdec_worker_manager.py +412 -0
  17. matrice_streaming/streaming_gateway/camera_streamer/platform_pipelines.py +680 -0
  18. matrice_streaming/streaming_gateway/camera_streamer/stream_statistics.py +111 -4
  19. matrice_streaming/streaming_gateway/camera_streamer/video_capture_manager.py +223 -27
  20. matrice_streaming/streaming_gateway/camera_streamer/worker_manager.py +694 -0
  21. matrice_streaming/streaming_gateway/debug/__init__.py +27 -2
  22. matrice_streaming/streaming_gateway/debug/benchmark.py +727 -0
  23. matrice_streaming/streaming_gateway/debug/debug_gstreamer_gateway.py +599 -0
  24. matrice_streaming/streaming_gateway/debug/debug_streaming_gateway.py +245 -95
  25. matrice_streaming/streaming_gateway/debug/debug_utils.py +29 -0
  26. matrice_streaming/streaming_gateway/debug/test_videoplayback.py +318 -0
  27. matrice_streaming/streaming_gateway/dynamic_camera_manager.py +656 -39
  28. matrice_streaming/streaming_gateway/metrics_reporter.py +676 -139
  29. matrice_streaming/streaming_gateway/streaming_action.py +71 -20
  30. matrice_streaming/streaming_gateway/streaming_gateway.py +1026 -78
  31. matrice_streaming/streaming_gateway/streaming_gateway_utils.py +175 -20
  32. matrice_streaming/streaming_gateway/streaming_status_listener.py +89 -0
  33. {matrice_streaming-0.1.14.dist-info → matrice_streaming-0.1.65.dist-info}/METADATA +1 -1
  34. matrice_streaming-0.1.65.dist-info/RECORD +56 -0
  35. matrice_streaming-0.1.14.dist-info/RECORD +0 -38
  36. {matrice_streaming-0.1.14.dist-info → matrice_streaming-0.1.65.dist-info}/WHEEL +0 -0
  37. {matrice_streaming-0.1.14.dist-info → matrice_streaming-0.1.65.dist-info}/licenses/LICENSE.txt +0 -0
  38. {matrice_streaming-0.1.14.dist-info → matrice_streaming-0.1.65.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,318 @@
1
+ """Benchmark all 4 streaming modes with videoplayback.mp4.
2
+
3
+ This script tests and compares performance across all streaming modes:
4
+ - Mode 1: CameraStreamer (single-threaded OpenCV)
5
+ - Mode 2: WorkerManager (multi-process OpenCV)
6
+ - Mode 3: GStreamerCameraStreamer (single-threaded GStreamer)
7
+ - Mode 4: GStreamerWorkerManager (multi-process GStreamer)
8
+
9
+ Usage:
10
+ python -m matrice_streaming.streaming_gateway.debug.test_videoplayback
11
+
12
+ Or run directly (from project root):
13
+ python src/matrice_streaming/streaming_gateway/debug/test_videoplayback.py
14
+
15
+ With custom options:
16
+ python src/matrice_streaming/streaming_gateway/debug/test_videoplayback.py --duration 60 --fps 30
17
+ """
18
+ import sys
19
+ from pathlib import Path
20
+
21
+ # Add src to path for direct execution - must be before other imports
22
+ # Path: debug -> streaming_gateway -> matrice_streaming -> src
23
+ _script_dir = Path(__file__).resolve().parent
24
+ _src_dir = _script_dir.parent.parent.parent # Goes to src/
25
+ _project_dir = _src_dir.parent # Goes to py_streaming/
26
+ _common_src = _project_dir / "py_common" / "src" # py_common/src for matrice_common
27
+
28
+ if str(_src_dir) not in sys.path:
29
+ sys.path.insert(0, str(_src_dir))
30
+ if _common_src.exists() and str(_common_src) not in sys.path:
31
+ sys.path.insert(0, str(_common_src))
32
+
33
+ import os
34
+ import time
35
+ import logging
36
+ import argparse
37
+ from typing import Dict, Any, List, Optional
38
+
39
+ logging.basicConfig(
40
+ level=logging.INFO,
41
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
42
+ )
43
+ logger = logging.getLogger(__name__)
44
+
45
+
46
+ def benchmark_mode(
47
+ mode_name: str,
48
+ gateway,
49
+ duration_seconds: int = 30
50
+ ) -> Dict[str, Any]:
51
+ """Benchmark a single streaming mode.
52
+
53
+ Args:
54
+ mode_name: Name of the streaming mode
55
+ gateway: Gateway instance to benchmark
56
+ duration_seconds: How long to run the benchmark
57
+
58
+ Returns:
59
+ Dictionary with benchmark results
60
+ """
61
+ print(f"\n{'='*60}")
62
+ print(f"Benchmarking {mode_name}")
63
+ print(f"{'='*60}")
64
+
65
+ # Start streaming
66
+ start_time = time.time()
67
+ success = gateway.start_streaming(block=False)
68
+
69
+ if not success:
70
+ print(f"Failed to start {mode_name}")
71
+ return {
72
+ 'mode': mode_name,
73
+ 'success': False,
74
+ 'error': 'Failed to start streaming',
75
+ }
76
+
77
+ # Run for specified duration
78
+ print(f"Running for {duration_seconds} seconds...")
79
+ time.sleep(duration_seconds)
80
+
81
+ # Get statistics before stopping
82
+ stats = gateway.get_statistics()
83
+
84
+ # Stop streaming
85
+ gateway.stop_streaming()
86
+
87
+ elapsed = time.time() - start_time
88
+
89
+ # Extract key metrics
90
+ transmission_stats = stats.get('transmission_stats', {})
91
+ total_frames = transmission_stats.get('total_frames_sent', 0)
92
+ total_bytes = transmission_stats.get('total_bytes_sent', 0)
93
+
94
+ avg_fps = total_frames / elapsed if elapsed > 0 else 0
95
+ bandwidth_mbps = (total_bytes * 8) / (elapsed * 1_000_000) if elapsed > 0 else 0
96
+
97
+ result = {
98
+ 'mode': mode_name,
99
+ 'success': True,
100
+ 'runtime_seconds': elapsed,
101
+ 'total_frames': total_frames,
102
+ 'total_bytes': total_bytes,
103
+ 'avg_fps': avg_fps,
104
+ 'bandwidth_mbps': bandwidth_mbps,
105
+ 'cache_efficiency': stats.get('cache_efficiency', 0),
106
+ 'stats': stats,
107
+ }
108
+
109
+ print(f"\nResults for {mode_name}:")
110
+ print(f" Runtime: {elapsed:.1f}s")
111
+ print(f" Total frames: {total_frames:,}")
112
+ print(f" Avg FPS: {avg_fps:.2f}")
113
+ print(f" Bandwidth: {bandwidth_mbps:.2f} Mbps")
114
+
115
+ if stats.get('cache_efficiency'):
116
+ print(f" Cache efficiency: {stats.get('cache_efficiency', 0):.1f}%")
117
+
118
+ return result
119
+
120
+
121
+ def run_mode1_benchmark(video_path: str, fps: int, duration: int) -> Optional[Dict]:
122
+ """Benchmark Mode 1: CameraStreamer (single-threaded OpenCV)."""
123
+ try:
124
+ from matrice_streaming.streaming_gateway.debug.debug_streaming_gateway import DebugStreamingGateway
125
+
126
+ gateway = DebugStreamingGateway(
127
+ video_paths=[video_path],
128
+ fps=fps,
129
+ video_codec="h264",
130
+ loop_videos=True,
131
+ use_workers=False, # Single-threaded
132
+ log_messages=False,
133
+ )
134
+ return benchmark_mode("Mode 1 (CameraStreamer)", gateway, duration)
135
+ except Exception as e:
136
+ logger.error(f"Mode 1 failed: {e}")
137
+ return {'mode': 'Mode 1 (CameraStreamer)', 'success': False, 'error': str(e)}
138
+
139
+
140
+ def run_mode2_benchmark(video_path: str, fps: int, duration: int, num_workers: int = 2) -> Optional[Dict]:
141
+ """Benchmark Mode 2: WorkerManager (multi-process OpenCV)."""
142
+ try:
143
+ from matrice_streaming.streaming_gateway.debug.debug_streaming_gateway import DebugStreamingGateway
144
+
145
+ gateway = DebugStreamingGateway(
146
+ video_paths=[video_path],
147
+ fps=fps,
148
+ video_codec="h264",
149
+ loop_videos=True,
150
+ use_workers=True, # Multi-process
151
+ num_workers=num_workers,
152
+ log_messages=False,
153
+ )
154
+ return benchmark_mode(f"Mode 2 (WorkerManager, {num_workers} workers)", gateway, duration)
155
+ except Exception as e:
156
+ logger.error(f"Mode 2 failed: {e}")
157
+ return {'mode': 'Mode 2 (WorkerManager)', 'success': False, 'error': str(e)}
158
+
159
+
160
+ def run_mode3_benchmark(video_path: str, fps: int, duration: int) -> Optional[Dict]:
161
+ """Benchmark Mode 3: GStreamerCameraStreamer (single-threaded GStreamer)."""
162
+ try:
163
+ from matrice_streaming.streaming_gateway.debug.debug_gstreamer_gateway import DebugGStreamerGateway
164
+
165
+ gateway = DebugGStreamerGateway(
166
+ video_paths=[video_path],
167
+ fps=fps,
168
+ gstreamer_encoder="jpeg",
169
+ jpeg_quality=85,
170
+ loop_videos=True,
171
+ use_workers=False, # Single-threaded
172
+ enable_frame_optimizer=True,
173
+ log_messages=False,
174
+ )
175
+ return benchmark_mode("Mode 3 (GStreamer)", gateway, duration)
176
+ except Exception as e:
177
+ logger.error(f"Mode 3 failed: {e}")
178
+ return {'mode': 'Mode 3 (GStreamer)', 'success': False, 'error': str(e)}
179
+
180
+
181
+ def run_mode4_benchmark(video_path: str, fps: int, duration: int, num_workers: int = 2) -> Optional[Dict]:
182
+ """Benchmark Mode 4: GStreamerWorkerManager (multi-process GStreamer)."""
183
+ try:
184
+ from matrice_streaming.streaming_gateway.debug.debug_gstreamer_gateway import DebugGStreamerGateway
185
+
186
+ gateway = DebugGStreamerGateway(
187
+ video_paths=[video_path],
188
+ fps=fps,
189
+ gstreamer_encoder="jpeg",
190
+ jpeg_quality=85,
191
+ loop_videos=True,
192
+ use_workers=True, # Multi-process
193
+ num_workers=num_workers,
194
+ enable_frame_optimizer=True,
195
+ log_messages=False,
196
+ )
197
+ return benchmark_mode(f"Mode 4 (GStreamer Workers, {num_workers} workers)", gateway, duration)
198
+ except Exception as e:
199
+ logger.error(f"Mode 4 failed: {e}")
200
+ return {'mode': 'Mode 4 (GStreamer Workers)', 'success': False, 'error': str(e)}
201
+
202
+
203
+ def print_summary(results: List[Dict]):
204
+ """Print benchmark comparison summary."""
205
+ print("\n" + "="*70)
206
+ print("BENCHMARK SUMMARY")
207
+ print("="*70)
208
+
209
+ # Filter successful results
210
+ successful = [r for r in results if r.get('success', False)]
211
+ failed = [r for r in results if not r.get('success', False)]
212
+
213
+ if successful:
214
+ print(f"\n{'Mode':<45} {'FPS':>10} {'Bandwidth':>15}")
215
+ print("-"*70)
216
+
217
+ for result in successful:
218
+ print(f"{result['mode']:<45} {result['avg_fps']:>10.2f} {result['bandwidth_mbps']:>12.2f} Mbps")
219
+
220
+ # Find best performers
221
+ if len(successful) > 1:
222
+ best_fps = max(successful, key=lambda r: r['avg_fps'])
223
+ best_bandwidth = min(successful, key=lambda r: r['bandwidth_mbps'])
224
+
225
+ print(f"\nBest FPS: {best_fps['mode']} ({best_fps['avg_fps']:.2f} fps)")
226
+ print(f"Lowest Bandwidth: {best_bandwidth['mode']} ({best_bandwidth['bandwidth_mbps']:.2f} Mbps)")
227
+
228
+ if failed:
229
+ print("\nFailed modes:")
230
+ for result in failed:
231
+ print(f" - {result['mode']}: {result.get('error', 'Unknown error')}")
232
+
233
+
234
+ def main():
235
+ """Benchmark all 4 streaming modes."""
236
+ parser = argparse.ArgumentParser(description="Benchmark all streaming modes")
237
+ parser.add_argument("--video", type=str, default="videoplayback.mp4",
238
+ help="Video file to use for benchmarking")
239
+ parser.add_argument("--duration", type=int, default=30,
240
+ help="Duration in seconds for each benchmark")
241
+ parser.add_argument("--fps", type=int, default=30,
242
+ help="Target FPS")
243
+ parser.add_argument("--workers", type=int, default=2,
244
+ help="Number of workers for multi-process modes")
245
+ parser.add_argument("--modes", type=str, default="all",
246
+ help="Modes to test: all, 1, 2, 3, 4, or comma-separated (e.g., '1,3')")
247
+
248
+ args = parser.parse_args()
249
+
250
+ video_path = args.video
251
+
252
+ if not Path(video_path).exists():
253
+ print(f"Error: {video_path} not found")
254
+ print(f"Current directory: {Path.cwd()}")
255
+ return
256
+
257
+ print("="*70)
258
+ print("STREAMING MODE BENCHMARK")
259
+ print("="*70)
260
+ print(f"\nVideo: {video_path}")
261
+ print(f"Duration: {args.duration}s per mode")
262
+ print(f"Target FPS: {args.fps}")
263
+ print(f"Workers: {args.workers}")
264
+
265
+ results = []
266
+
267
+ # Determine which modes to run
268
+ if args.modes == "all":
269
+ modes_to_run = [1, 2, 3, 4]
270
+ else:
271
+ modes_to_run = [int(m.strip()) for m in args.modes.split(',')]
272
+
273
+ # Run benchmarks with delay between modes for resource cleanup
274
+ if 1 in modes_to_run:
275
+ print("\n" + "="*70)
276
+ print("MODE 1: CameraStreamer (single-threaded OpenCV)")
277
+ print("="*70)
278
+ result = run_mode1_benchmark(video_path, args.fps, args.duration)
279
+ if result:
280
+ results.append(result)
281
+ time.sleep(2) # Allow cleanup
282
+
283
+ if 2 in modes_to_run:
284
+ print("\n" + "="*70)
285
+ print("MODE 2: WorkerManager (multi-process OpenCV)")
286
+ print("="*70)
287
+ result = run_mode2_benchmark(video_path, args.fps, args.duration, args.workers)
288
+ if result:
289
+ results.append(result)
290
+ time.sleep(2) # Allow cleanup
291
+
292
+ if 3 in modes_to_run:
293
+ print("\n" + "="*70)
294
+ print("MODE 3: GStreamerCameraStreamer (single-threaded GStreamer)")
295
+ print("="*70)
296
+ result = run_mode3_benchmark(video_path, args.fps, args.duration)
297
+ if result:
298
+ results.append(result)
299
+ time.sleep(2) # Allow GStreamer cleanup before Mode 4
300
+
301
+ if 4 in modes_to_run:
302
+ print("\n" + "="*70)
303
+ print("MODE 4: GStreamerWorkerManager (multi-process GStreamer)")
304
+ print("="*70)
305
+ result = run_mode4_benchmark(video_path, args.fps, args.duration, args.workers)
306
+ if result:
307
+ results.append(result)
308
+
309
+ # Print summary
310
+ print_summary(results)
311
+
312
+ print("\n" + "="*70)
313
+ print("Benchmark complete!")
314
+ print("="*70)
315
+
316
+
317
+ if __name__ == "__main__":
318
+ main()