matrice-streaming 0.1.63__tar.gz → 0.1.65__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.
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/PKG-INFO +1 -1
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/matrice_streaming.egg-info/PKG-INFO +1 -1
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/camera_streamer/nvdec.py +101 -12
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/camera_streamer/nvdec_worker_manager.py +34 -2
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/LICENSE.txt +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/README.md +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/matrice_streaming.egg-info/SOURCES.txt +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/matrice_streaming.egg-info/dependency_links.txt +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/matrice_streaming.egg-info/not-zip-safe +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/matrice_streaming.egg-info/top_level.txt +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/pyproject.toml +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/setup.cfg +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/setup.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/__init__.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/client/__init__.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/client/client.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/client/client_utils.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/deployment/__init__.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/deployment/camera_manager.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/deployment/deployment.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/deployment/inference_pipeline.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/deployment/streaming_gateway_manager.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/deployment/todo.txt +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/py.typed +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/__init__.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/camera_streamer/ARCHITECTURE.md +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/camera_streamer/__init__.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/camera_streamer/async_camera_worker.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/camera_streamer/async_ffmpeg_worker.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/camera_streamer/camera_streamer.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/camera_streamer/device_detection.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/camera_streamer/encoder_manager.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/camera_streamer/encoding_pool_manager.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/camera_streamer/ffmpeg_camera_streamer.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/camera_streamer/ffmpeg_config.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/camera_streamer/ffmpeg_worker_manager.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/camera_streamer/frame_processor.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/camera_streamer/gstreamer_camera_streamer.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/camera_streamer/gstreamer_worker.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/camera_streamer/gstreamer_worker_manager.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/camera_streamer/message_builder.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/camera_streamer/platform_pipelines.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/camera_streamer/retry_manager.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/camera_streamer/stream_statistics.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/camera_streamer/video_capture_manager.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/camera_streamer/worker_manager.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/debug/README.md +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/debug/__init__.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/debug/benchmark.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/debug/debug_gstreamer_gateway.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/debug/debug_stream_backend.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/debug/debug_streaming_gateway.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/debug/debug_utils.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/debug/example_debug_streaming.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/debug/test_videoplayback.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/dynamic_camera_manager.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/event_listener.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/metrics_reporter.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/streaming_action.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/streaming_gateway.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/streaming_gateway_utils.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/streaming_gateway/streaming_status_listener.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/tests/test_async_infrastructure.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/tests/test_batch_auto_calculation.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/tests/test_batching_verification.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/tests/test_e2e_production.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/tests/test_flatten_binary.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/tests/test_gstreamer_integration.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/tests/test_msgpack_fix.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/tests/test_phase1_unit.py +0 -0
- {matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/tests/test_phase2_scaling.py +0 -0
|
@@ -547,7 +547,12 @@ def surface_to_nv12(frame, target_h: int = 640, target_w: int = 640) -> Optional
|
|
|
547
547
|
return nv12_frame[:, :, cp.newaxis] if nv12_frame is not None else None
|
|
548
548
|
|
|
549
549
|
except Exception as e:
|
|
550
|
-
|
|
550
|
+
# Safely encode error message (some CUDA errors contain non-ASCII chars like '×')
|
|
551
|
+
try:
|
|
552
|
+
err_msg = str(e).encode('ascii', errors='replace').decode('ascii')
|
|
553
|
+
except Exception:
|
|
554
|
+
err_msg = "unknown error"
|
|
555
|
+
logger.warning(f"surface_to_nv12 failed: {err_msg}")
|
|
551
556
|
return None
|
|
552
557
|
|
|
553
558
|
|
|
@@ -709,12 +714,17 @@ def nvdec_pool_worker(
|
|
|
709
714
|
target_w: int = 640,
|
|
710
715
|
target_fps: int = 0,
|
|
711
716
|
shared_frame_count: Optional[mp.Value] = None,
|
|
717
|
+
gpu_frame_count: Optional[mp.Value] = None,
|
|
712
718
|
):
|
|
713
719
|
"""NVDEC worker thread.
|
|
714
720
|
|
|
715
721
|
Decodes frames and writes NV12 tensors to ring buffers.
|
|
716
722
|
Uses dedicated CUDA stream per worker for kernel overlap.
|
|
717
723
|
Supports FPS limiting when target_fps > 0.
|
|
724
|
+
|
|
725
|
+
Args:
|
|
726
|
+
shared_frame_count: Global counter (all GPUs)
|
|
727
|
+
gpu_frame_count: Per-GPU counter (this GPU only)
|
|
718
728
|
"""
|
|
719
729
|
if CUPY_AVAILABLE:
|
|
720
730
|
cp.cuda.Device(pool.gpu_id).use()
|
|
@@ -727,7 +737,6 @@ def nvdec_pool_worker(
|
|
|
727
737
|
frames_since_counter_update = 0
|
|
728
738
|
counter_batch_size = 100
|
|
729
739
|
start_time = time.perf_counter()
|
|
730
|
-
last_log_time = start_time
|
|
731
740
|
camera_ids = pool.get_camera_ids_for_decoder(decoder_idx)
|
|
732
741
|
num_streams = len(camera_ids)
|
|
733
742
|
|
|
@@ -745,19 +754,12 @@ def nvdec_pool_worker(
|
|
|
745
754
|
next_frame_time = 0
|
|
746
755
|
fps_mode = ", unlimited FPS"
|
|
747
756
|
|
|
748
|
-
logger.
|
|
757
|
+
logger.debug(f"Worker {worker_id}: decoder={decoder_idx}, cams={num_streams}{fps_mode}")
|
|
749
758
|
|
|
750
759
|
while not stop_event.is_set():
|
|
751
760
|
if time.perf_counter() - start_time >= duration_sec:
|
|
752
761
|
break
|
|
753
762
|
|
|
754
|
-
now = time.perf_counter()
|
|
755
|
-
if now - last_log_time >= 5.0:
|
|
756
|
-
elapsed = now - start_time
|
|
757
|
-
fps = local_frames / elapsed if elapsed > 0 else 0
|
|
758
|
-
logger.info(f"Worker {worker_id}: {local_frames} frames, {fps:.0f} FPS")
|
|
759
|
-
last_log_time = now
|
|
760
|
-
|
|
761
763
|
# FPS limiting: wait until next scheduled frame time
|
|
762
764
|
if fps_limit_enabled:
|
|
763
765
|
current_time = time.perf_counter()
|
|
@@ -782,11 +784,16 @@ def nvdec_pool_worker(
|
|
|
782
784
|
local_frames += 1
|
|
783
785
|
frames_since_counter_update += 1
|
|
784
786
|
|
|
785
|
-
# Update
|
|
787
|
+
# Update global counter (all GPUs)
|
|
786
788
|
if shared_frame_count is not None:
|
|
787
789
|
with shared_frame_count.get_lock():
|
|
788
790
|
shared_frame_count.value += 1
|
|
789
791
|
|
|
792
|
+
# Update per-GPU counter (this GPU only)
|
|
793
|
+
if gpu_frame_count is not None:
|
|
794
|
+
with gpu_frame_count.get_lock():
|
|
795
|
+
gpu_frame_count.value += 1
|
|
796
|
+
|
|
790
797
|
# Update next frame time for FPS limiting
|
|
791
798
|
if fps_limit_enabled:
|
|
792
799
|
next_frame_time += frame_interval
|
|
@@ -842,10 +849,19 @@ def nvdec_pool_process(
|
|
|
842
849
|
num_slots: int = 32,
|
|
843
850
|
target_fps: int = 0,
|
|
844
851
|
shared_frame_count: Optional[mp.Value] = None,
|
|
852
|
+
gpu_frame_counts: Optional[Dict[int, mp.Value]] = None,
|
|
853
|
+
total_num_streams: int = 0,
|
|
854
|
+
total_num_gpus: int = 1,
|
|
845
855
|
):
|
|
846
856
|
"""NVDEC process for one GPU.
|
|
847
857
|
|
|
848
858
|
Creates NV12 ring buffers: (H*1.5, W) = 0.6 MB/frame.
|
|
859
|
+
|
|
860
|
+
Args:
|
|
861
|
+
gpu_frame_counts: Dict mapping gpu_id -> per-GPU frame counter (for per-GPU stats)
|
|
862
|
+
shared_frame_count: Global frame counter (for overall stats)
|
|
863
|
+
total_num_streams: Total streams across ALL GPUs (for global per-stream calc)
|
|
864
|
+
total_num_gpus: Total number of GPUs (for context in logging)
|
|
849
865
|
"""
|
|
850
866
|
if not camera_configs:
|
|
851
867
|
return
|
|
@@ -854,6 +870,9 @@ def nvdec_pool_process(
|
|
|
854
870
|
target_h = camera_configs[0].height
|
|
855
871
|
target_w = camera_configs[0].width
|
|
856
872
|
|
|
873
|
+
# Get per-GPU counter (or fall back to shared if not provided)
|
|
874
|
+
gpu_frame_count = gpu_frame_counts.get(gpu_id) if gpu_frame_counts else None
|
|
875
|
+
|
|
857
876
|
if CUPY_AVAILABLE:
|
|
858
877
|
cp.cuda.Device(gpu_id).use()
|
|
859
878
|
|
|
@@ -947,15 +966,85 @@ def nvdec_pool_process(
|
|
|
947
966
|
target_w,
|
|
948
967
|
target_fps,
|
|
949
968
|
shared_frame_count,
|
|
969
|
+
gpu_frame_count, # Per-GPU counter
|
|
950
970
|
)
|
|
951
971
|
)
|
|
952
972
|
t.start()
|
|
953
973
|
threads.append(t)
|
|
954
974
|
|
|
975
|
+
# Progress monitoring loop with current/avg FPS tracking
|
|
955
976
|
start_time = time.perf_counter()
|
|
977
|
+
last_report_time = start_time
|
|
978
|
+
last_gpu_frame_count = 0
|
|
979
|
+
last_global_frame_count = 0
|
|
980
|
+
report_interval = 5.0
|
|
981
|
+
processing_start_time = None
|
|
982
|
+
gpu_frames_at_start = 0
|
|
983
|
+
global_frames_at_start = 0
|
|
984
|
+
num_gpu_streams = len(camera_configs)
|
|
985
|
+
|
|
956
986
|
while not stop_event.is_set():
|
|
957
|
-
|
|
987
|
+
current_time = time.perf_counter()
|
|
988
|
+
if current_time - start_time >= duration_sec:
|
|
958
989
|
break
|
|
990
|
+
|
|
991
|
+
# Periodic progress report with current and average FPS
|
|
992
|
+
if current_time - last_report_time >= report_interval:
|
|
993
|
+
elapsed = current_time - start_time
|
|
994
|
+
remaining = max(0, duration_sec - elapsed)
|
|
995
|
+
|
|
996
|
+
# Get per-GPU frame count (this GPU only)
|
|
997
|
+
gpu_frames = gpu_frame_count.value if gpu_frame_count else 0
|
|
998
|
+
gpu_interval_frames = gpu_frames - last_gpu_frame_count
|
|
999
|
+
gpu_interval_fps = gpu_interval_frames / report_interval
|
|
1000
|
+
gpu_per_stream_fps = gpu_interval_fps / num_gpu_streams if num_gpu_streams > 0 else 0
|
|
1001
|
+
|
|
1002
|
+
# Get global frame count (all GPUs)
|
|
1003
|
+
global_frames = shared_frame_count.value if shared_frame_count else 0
|
|
1004
|
+
global_interval_frames = global_frames - last_global_frame_count
|
|
1005
|
+
global_interval_fps = global_interval_frames / report_interval
|
|
1006
|
+
global_per_stream_fps = global_interval_fps / total_num_streams if total_num_streams > 0 else 0
|
|
1007
|
+
|
|
1008
|
+
# Track when processing actually starts (exclude warmup)
|
|
1009
|
+
if processing_start_time is None and gpu_frames > 0:
|
|
1010
|
+
processing_start_time = last_report_time
|
|
1011
|
+
gpu_frames_at_start = last_gpu_frame_count
|
|
1012
|
+
global_frames_at_start = last_global_frame_count
|
|
1013
|
+
|
|
1014
|
+
# Calculate average FPS excluding warmup
|
|
1015
|
+
if processing_start_time is not None:
|
|
1016
|
+
processing_elapsed = current_time - processing_start_time
|
|
1017
|
+
|
|
1018
|
+
# Per-GPU averages
|
|
1019
|
+
gpu_processing_frames = gpu_frames - gpu_frames_at_start
|
|
1020
|
+
gpu_avg_fps = gpu_processing_frames / processing_elapsed if processing_elapsed > 0 else 0
|
|
1021
|
+
gpu_avg_per_stream = gpu_avg_fps / num_gpu_streams if num_gpu_streams > 0 else 0
|
|
1022
|
+
|
|
1023
|
+
# Global averages
|
|
1024
|
+
global_processing_frames = global_frames - global_frames_at_start
|
|
1025
|
+
global_avg_fps = global_processing_frames / processing_elapsed if processing_elapsed > 0 else 0
|
|
1026
|
+
global_avg_per_stream = global_avg_fps / total_num_streams if total_num_streams > 0 else 0
|
|
1027
|
+
|
|
1028
|
+
# Log per-GPU stats
|
|
1029
|
+
logger.info(
|
|
1030
|
+
f"GPU{gpu_id} [{elapsed:5.1f}s] {gpu_frames:,} frames ({num_gpu_streams} cams) | "
|
|
1031
|
+
f"cur: {gpu_interval_fps:,.0f} FPS ({gpu_per_stream_fps:.1f}/cam) | "
|
|
1032
|
+
f"avg: {gpu_avg_fps:,.0f} FPS ({gpu_avg_per_stream:.1f}/cam)"
|
|
1033
|
+
)
|
|
1034
|
+
|
|
1035
|
+
# Log global stats (only from GPU0 to avoid spam)
|
|
1036
|
+
if gpu_id == 0:
|
|
1037
|
+
logger.info(
|
|
1038
|
+
f"GLOBAL [{elapsed:5.1f}s] {global_frames:,} frames ({total_num_streams} cams, {total_num_gpus} GPUs) | "
|
|
1039
|
+
f"cur: {global_interval_fps:,.0f} FPS ({global_per_stream_fps:.1f}/cam) | "
|
|
1040
|
+
f"avg: {global_avg_fps:,.0f} FPS ({global_avg_per_stream:.1f}/cam) | "
|
|
1041
|
+
f"{remaining:.0f}s left"
|
|
1042
|
+
)
|
|
1043
|
+
|
|
1044
|
+
last_gpu_frame_count = gpu_frames
|
|
1045
|
+
last_global_frame_count = global_frames
|
|
1046
|
+
last_report_time = current_time
|
|
1047
|
+
|
|
959
1048
|
time.sleep(0.1)
|
|
960
1049
|
|
|
961
1050
|
thread_stop_event.set()
|
|
@@ -123,6 +123,7 @@ class NVDECWorkerManager:
|
|
|
123
123
|
self._stop_event: Optional[mp.Event] = None
|
|
124
124
|
self._result_queue: Optional[mp.Queue] = None
|
|
125
125
|
self._shared_frame_count: Optional[mp.Value] = None
|
|
126
|
+
self._gpu_frame_counts: Dict[int, mp.Value] = {} # Per-GPU counters
|
|
126
127
|
self._start_time: Optional[float] = None
|
|
127
128
|
self._is_running = False
|
|
128
129
|
|
|
@@ -200,9 +201,20 @@ class NVDECWorkerManager:
|
|
|
200
201
|
ctx = mp.get_context("spawn")
|
|
201
202
|
self._stop_event = ctx.Event()
|
|
202
203
|
self._result_queue = ctx.Queue()
|
|
203
|
-
self._shared_frame_count = ctx.Value('
|
|
204
|
+
self._shared_frame_count = ctx.Value('L', 0) # Global counter (all GPUs)
|
|
204
205
|
self._start_time = time.perf_counter()
|
|
205
206
|
|
|
207
|
+
# Create per-GPU frame counters
|
|
208
|
+
self._gpu_frame_counts = {}
|
|
209
|
+
for gpu_id in range(self.num_gpus):
|
|
210
|
+
if self._gpu_camera_assignments[gpu_id]: # Only if GPU has cameras
|
|
211
|
+
self._gpu_frame_counts[gpu_id] = ctx.Value('L', 0)
|
|
212
|
+
|
|
213
|
+
total_num_streams = len(self._stream_configs)
|
|
214
|
+
total_num_gpus = len([g for g in range(self.num_gpus) if self._gpu_camera_assignments[g]])
|
|
215
|
+
|
|
216
|
+
logger.info(f"Starting NVDEC: {total_num_streams} cameras across {total_num_gpus} GPUs")
|
|
217
|
+
|
|
206
218
|
# Start one process per GPU that has cameras
|
|
207
219
|
for gpu_id in range(self.num_gpus):
|
|
208
220
|
gpu_cameras = self._gpu_camera_assignments[gpu_id]
|
|
@@ -221,7 +233,10 @@ class NVDECWorkerManager:
|
|
|
221
233
|
self.nvdec_burst_size, # burst_size
|
|
222
234
|
self.num_slots, # num_slots
|
|
223
235
|
self.target_fps, # target_fps
|
|
224
|
-
self._shared_frame_count, # shared_frame_count
|
|
236
|
+
self._shared_frame_count, # shared_frame_count (global)
|
|
237
|
+
self._gpu_frame_counts, # gpu_frame_counts (per-GPU dict)
|
|
238
|
+
total_num_streams, # total_num_streams
|
|
239
|
+
total_num_gpus, # total_num_gpus
|
|
225
240
|
),
|
|
226
241
|
name=f"NVDECWorker-GPU{gpu_id}",
|
|
227
242
|
daemon=False,
|
|
@@ -311,6 +326,23 @@ class NVDECWorkerManager:
|
|
|
311
326
|
if self._stream_configs else 0
|
|
312
327
|
)
|
|
313
328
|
|
|
329
|
+
# Add per-GPU frame counts and FPS
|
|
330
|
+
if self._gpu_frame_counts and self._start_time:
|
|
331
|
+
elapsed = time.perf_counter() - self._start_time
|
|
332
|
+
gpu_stats = {}
|
|
333
|
+
for gpu_id, counter in self._gpu_frame_counts.items():
|
|
334
|
+
gpu_frames = counter.value
|
|
335
|
+
num_cams = len(self._gpu_camera_assignments.get(gpu_id, []))
|
|
336
|
+
gpu_fps = gpu_frames / elapsed if elapsed > 0 else 0
|
|
337
|
+
gpu_per_cam = gpu_fps / num_cams if num_cams > 0 else 0
|
|
338
|
+
gpu_stats[f'GPU{gpu_id}'] = {
|
|
339
|
+
'frames': gpu_frames,
|
|
340
|
+
'cameras': num_cams,
|
|
341
|
+
'fps': gpu_fps,
|
|
342
|
+
'fps_per_cam': gpu_per_cam,
|
|
343
|
+
}
|
|
344
|
+
stats['per_gpu_stats'] = gpu_stats
|
|
345
|
+
|
|
314
346
|
# Collect any available results from queue (non-blocking)
|
|
315
347
|
gpu_results = []
|
|
316
348
|
if self._result_queue:
|
|
File without changes
|
|
File without changes
|
{matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/matrice_streaming.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/matrice_streaming.egg-info/not-zip-safe
RENAMED
|
File without changes
|
{matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/matrice_streaming.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/client/__init__.py
RENAMED
|
File without changes
|
{matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/client/client.py
RENAMED
|
File without changes
|
{matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/client/client_utils.py
RENAMED
|
File without changes
|
{matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/deployment/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/deployment/deployment.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{matrice_streaming-0.1.63 → matrice_streaming-0.1.65}/src/matrice_streaming/deployment/todo.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|