matrice-streaming 0.1.67__tar.gz → 0.1.69__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.67 → matrice_streaming-0.1.69}/PKG-INFO +1 -1
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/matrice_streaming.egg-info/PKG-INFO +1 -1
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/camera_streamer/nvdec.py +141 -33
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/LICENSE.txt +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/README.md +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/matrice_streaming.egg-info/SOURCES.txt +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/matrice_streaming.egg-info/dependency_links.txt +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/matrice_streaming.egg-info/not-zip-safe +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/matrice_streaming.egg-info/top_level.txt +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/pyproject.toml +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/setup.cfg +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/setup.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/__init__.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/client/__init__.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/client/client.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/client/client_utils.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/deployment/__init__.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/deployment/camera_manager.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/deployment/deployment.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/deployment/inference_pipeline.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/deployment/streaming_gateway_manager.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/deployment/todo.txt +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/py.typed +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/__init__.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/camera_streamer/ARCHITECTURE.md +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/camera_streamer/__init__.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/camera_streamer/async_camera_worker.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/camera_streamer/async_ffmpeg_worker.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/camera_streamer/camera_streamer.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/camera_streamer/device_detection.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/camera_streamer/encoder_manager.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/camera_streamer/encoding_pool_manager.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/camera_streamer/ffmpeg_camera_streamer.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/camera_streamer/ffmpeg_config.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/camera_streamer/ffmpeg_worker_manager.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/camera_streamer/frame_processor.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/camera_streamer/gstreamer_camera_streamer.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/camera_streamer/gstreamer_worker.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/camera_streamer/gstreamer_worker_manager.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/camera_streamer/message_builder.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/camera_streamer/nvdec_worker_manager.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/camera_streamer/platform_pipelines.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/camera_streamer/retry_manager.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/camera_streamer/stream_statistics.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/camera_streamer/video_capture_manager.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/camera_streamer/worker_manager.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/debug/README.md +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/debug/__init__.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/debug/benchmark.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/debug/debug_gstreamer_gateway.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/debug/debug_stream_backend.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/debug/debug_streaming_gateway.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/debug/debug_utils.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/debug/example_debug_streaming.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/debug/test_videoplayback.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/dynamic_camera_manager.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/event_listener.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/metrics_reporter.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/streaming_action.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/streaming_gateway.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/streaming_gateway_utils.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/streaming_gateway/streaming_status_listener.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/tests/test_async_infrastructure.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/tests/test_batch_auto_calculation.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/tests/test_batching_verification.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/tests/test_e2e_production.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/tests/test_flatten_binary.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/tests/test_gstreamer_integration.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/tests/test_msgpack_fix.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/tests/test_phase1_unit.py +0 -0
- {matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/tests/test_phase2_scaling.py +0 -0
|
@@ -96,8 +96,23 @@ except (ImportError, AttributeError, RuntimeError, TypeError):
|
|
|
96
96
|
CudaIpcRingBuffer = None
|
|
97
97
|
GlobalFrameCounter = None
|
|
98
98
|
|
|
99
|
+
try:
|
|
100
|
+
from matrice_common.stream.gpu_camera_map import GpuCameraMap
|
|
101
|
+
GPU_CAMERA_MAP_AVAILABLE = True
|
|
102
|
+
except ImportError:
|
|
103
|
+
GPU_CAMERA_MAP_AVAILABLE = False
|
|
104
|
+
GpuCameraMap = None
|
|
105
|
+
|
|
99
106
|
logger = logging.getLogger(__name__)
|
|
100
107
|
|
|
108
|
+
# =============================================================================
|
|
109
|
+
# Fixed dimensions for NV12 output - ALL cameras resize to this size
|
|
110
|
+
# This matches the TensorRT model input requirements (640x640)
|
|
111
|
+
# =============================================================================
|
|
112
|
+
TARGET_WIDTH = 640
|
|
113
|
+
TARGET_HEIGHT = 640
|
|
114
|
+
NV12_HEIGHT = TARGET_HEIGHT + TARGET_HEIGHT // 2 # 960 = H * 1.5 for NV12 format
|
|
115
|
+
|
|
101
116
|
def setup_logging(quiet: bool = True):
|
|
102
117
|
"""Configure logging level based on quiet mode."""
|
|
103
118
|
level = logging.WARNING if quiet else logging.INFO
|
|
@@ -407,6 +422,8 @@ class StreamState:
|
|
|
407
422
|
width: int = 640
|
|
408
423
|
height: int = 640
|
|
409
424
|
empty_packets: int = 0
|
|
425
|
+
decode_errors: int = 0 # Consecutive decode errors
|
|
426
|
+
MAX_DECODE_ERRORS: int = 5 # Restart demuxer after this many consecutive errors
|
|
410
427
|
|
|
411
428
|
|
|
412
429
|
# =============================================================================
|
|
@@ -420,8 +437,8 @@ def _get_nv12_resize_kernel():
|
|
|
420
437
|
"""Get or compile the NV12 resize kernel.
|
|
421
438
|
|
|
422
439
|
This kernel resizes NV12 directly (no color conversion).
|
|
423
|
-
Output: concatenated Y (
|
|
424
|
-
This is 50% smaller than RGB (
|
|
440
|
+
Output: concatenated Y (H*W) + UV ((H/2)*W) = H*W*1.5 bytes
|
|
441
|
+
This is 50% smaller than RGB (H*W*3 bytes).
|
|
425
442
|
|
|
426
443
|
Consumer will do: NV12→RGB→CHW→FP16 in one fused kernel.
|
|
427
444
|
"""
|
|
@@ -429,9 +446,9 @@ def _get_nv12_resize_kernel():
|
|
|
429
446
|
if _nv12_resize_kernel is None and CUPY_AVAILABLE:
|
|
430
447
|
_nv12_resize_kernel = cp.RawKernel(r'''
|
|
431
448
|
extern "C" __global__ void nv12_resize(
|
|
432
|
-
const unsigned char* src_y,
|
|
433
|
-
const unsigned char* src_uv,
|
|
434
|
-
unsigned char* dst,
|
|
449
|
+
const unsigned char* src_y,
|
|
450
|
+
const unsigned char* src_uv,
|
|
451
|
+
unsigned char* dst,
|
|
435
452
|
int src_h, int src_w,
|
|
436
453
|
int dst_h, int dst_w,
|
|
437
454
|
int y_stride, int uv_stride
|
|
@@ -477,8 +494,8 @@ def nv12_resize(y_plane: cp.ndarray, uv_plane: cp.ndarray,
|
|
|
477
494
|
dst_h: int = 640, dst_w: int = 640) -> cp.ndarray:
|
|
478
495
|
"""Resize NV12 without color conversion.
|
|
479
496
|
|
|
480
|
-
Output: concatenated Y (
|
|
481
|
-
Total size:
|
|
497
|
+
Output: concatenated Y (H*W) + UV ((H/2)*W) as single buffer.
|
|
498
|
+
Total size: H*W + (H/2)*W = H*W*1.5 bytes (50% of RGB).
|
|
482
499
|
"""
|
|
483
500
|
kernel = _get_nv12_resize_kernel()
|
|
484
501
|
if kernel is None:
|
|
@@ -504,7 +521,7 @@ def surface_to_nv12(frame, target_h: int = 640, target_w: int = 640) -> Optional
|
|
|
504
521
|
"""Convert NVDEC surface to resized NV12 (50% smaller than RGB).
|
|
505
522
|
|
|
506
523
|
Output: (H + H/2, W) uint8 - concatenated Y + UV planes.
|
|
507
|
-
Total size:
|
|
524
|
+
Total size: H*W*1.5 bytes (vs H*W*3 for RGB).
|
|
508
525
|
"""
|
|
509
526
|
if not CUPY_AVAILABLE or frame is None:
|
|
510
527
|
return None
|
|
@@ -552,11 +569,14 @@ def surface_to_nv12(frame, target_h: int = 640, target_w: int = 640) -> Optional
|
|
|
552
569
|
return nv12_frame[:, :, cp.newaxis] if nv12_frame is not None else None
|
|
553
570
|
|
|
554
571
|
except Exception as e:
|
|
555
|
-
# Safely
|
|
572
|
+
# Safely handle any characters in error message (CUDA errors may contain Unicode like ×)
|
|
556
573
|
try:
|
|
557
574
|
err_msg = str(e).encode('ascii', errors='replace').decode('ascii')
|
|
558
575
|
except Exception:
|
|
559
|
-
|
|
576
|
+
try:
|
|
577
|
+
err_msg = repr(str(e))[:200]
|
|
578
|
+
except Exception:
|
|
579
|
+
err_msg = "failed to format error message"
|
|
560
580
|
logger.warning(f"surface_to_nv12 failed: {err_msg}")
|
|
561
581
|
return None
|
|
562
582
|
|
|
@@ -569,7 +589,7 @@ class NVDECDecoderPool:
|
|
|
569
589
|
"""Pool of NVDEC decoders that time-multiplex streams.
|
|
570
590
|
|
|
571
591
|
Each decoder is exclusively owned by one worker thread.
|
|
572
|
-
Outputs NV12: 1.5
|
|
592
|
+
Outputs NV12: 1.5*H*W bytes (50% smaller than RGB).
|
|
573
593
|
"""
|
|
574
594
|
|
|
575
595
|
def __init__(self, pool_size: int, gpu_id: int = 0):
|
|
@@ -661,18 +681,44 @@ class NVDECDecoderPool:
|
|
|
661
681
|
break
|
|
662
682
|
|
|
663
683
|
frames_before = frames_this_stream
|
|
664
|
-
for surface in decoder.Decode(packet):
|
|
665
|
-
tensor = surface_to_nv12(surface, target_h, target_w)
|
|
666
|
-
|
|
667
|
-
if tensor is not None:
|
|
668
|
-
decoded_frames.append((stream.camera_id, tensor))
|
|
669
|
-
frames_this_stream += 1
|
|
670
|
-
stream.frames_decoded += 1
|
|
671
|
-
total_frames += 1
|
|
672
|
-
stream.empty_packets = 0
|
|
673
684
|
|
|
674
|
-
|
|
675
|
-
|
|
685
|
+
# Wrap decode loop in try/except to catch decode errors
|
|
686
|
+
try:
|
|
687
|
+
for surface in decoder.Decode(packet):
|
|
688
|
+
tensor = surface_to_nv12(surface, target_h, target_w)
|
|
689
|
+
|
|
690
|
+
if tensor is not None:
|
|
691
|
+
decoded_frames.append((stream.camera_id, tensor))
|
|
692
|
+
frames_this_stream += 1
|
|
693
|
+
stream.frames_decoded += 1
|
|
694
|
+
total_frames += 1
|
|
695
|
+
stream.empty_packets = 0
|
|
696
|
+
stream.decode_errors = 0 # Reset on success
|
|
697
|
+
|
|
698
|
+
if frames_this_stream >= frames_per_stream:
|
|
699
|
+
break
|
|
700
|
+
|
|
701
|
+
except Exception as decode_err:
|
|
702
|
+
# Handle decode errors - these can happen with corrupted packets
|
|
703
|
+
stream.decode_errors += 1
|
|
704
|
+
if stream.decode_errors == 1:
|
|
705
|
+
# Only log first error per stream to avoid spam
|
|
706
|
+
logger.warning(f"{stream.camera_id}: Decode error: {decode_err}")
|
|
707
|
+
|
|
708
|
+
if stream.decode_errors >= stream.MAX_DECODE_ERRORS:
|
|
709
|
+
# Too many consecutive errors - restart demuxer
|
|
710
|
+
logger.warning(
|
|
711
|
+
f"{stream.camera_id}: {stream.decode_errors} consecutive decode errors, "
|
|
712
|
+
f"restarting demuxer"
|
|
713
|
+
)
|
|
714
|
+
try:
|
|
715
|
+
stream.demuxer = nvc.CreateDemuxer(stream.video_path)
|
|
716
|
+
stream.decode_errors = 0
|
|
717
|
+
stream.empty_packets = 0
|
|
718
|
+
logger.info(f"{stream.camera_id}: Demuxer restarted successfully")
|
|
719
|
+
except Exception as restart_err:
|
|
720
|
+
logger.error(f"{stream.camera_id}: Failed to restart demuxer: {restart_err}")
|
|
721
|
+
break # Exit this stream's loop
|
|
676
722
|
|
|
677
723
|
if frames_this_stream == frames_before:
|
|
678
724
|
stream.empty_packets += 1
|
|
@@ -680,7 +726,17 @@ class NVDECDecoderPool:
|
|
|
680
726
|
stream.demuxer = nvc.CreateDemuxer(stream.video_path)
|
|
681
727
|
stream.empty_packets = 0
|
|
682
728
|
|
|
683
|
-
except Exception:
|
|
729
|
+
except Exception as demux_err:
|
|
730
|
+
# Handle demux errors
|
|
731
|
+
logger.warning(f"{stream.camera_id}: Demux error: {demux_err}")
|
|
732
|
+
stream.decode_errors += 1
|
|
733
|
+
if stream.decode_errors >= stream.MAX_DECODE_ERRORS:
|
|
734
|
+
try:
|
|
735
|
+
stream.demuxer = nvc.CreateDemuxer(stream.video_path)
|
|
736
|
+
stream.decode_errors = 0
|
|
737
|
+
logger.info(f"{stream.camera_id}: Demuxer restarted after demux errors")
|
|
738
|
+
except Exception:
|
|
739
|
+
pass
|
|
684
740
|
break
|
|
685
741
|
|
|
686
742
|
if frames_this_stream >= frames_per_stream:
|
|
@@ -775,16 +831,28 @@ def nvdec_pool_worker(
|
|
|
775
831
|
|
|
776
832
|
try:
|
|
777
833
|
with cuda_stream:
|
|
834
|
+
# Always use fixed TARGET dimensions to ensure consistent NV12 output
|
|
778
835
|
num_frames, decoded_frames = pool.decode_round(
|
|
779
836
|
decoder_idx,
|
|
780
837
|
frames_per_stream=burst_size,
|
|
781
|
-
target_h=
|
|
782
|
-
target_w=
|
|
838
|
+
target_h=TARGET_HEIGHT, # Always 640
|
|
839
|
+
target_w=TARGET_WIDTH # Always 640
|
|
783
840
|
)
|
|
784
841
|
|
|
785
842
|
for cam_id, tensor in decoded_frames:
|
|
786
843
|
if cam_id in ring_buffers:
|
|
787
844
|
try:
|
|
845
|
+
# Validate frame shape matches expected NV12 dimensions
|
|
846
|
+
expected_shape = (NV12_HEIGHT, TARGET_WIDTH, 1) # (960, 640, 1)
|
|
847
|
+
if tensor.shape != expected_shape:
|
|
848
|
+
local_errors += 1
|
|
849
|
+
if local_errors <= 5:
|
|
850
|
+
logger.error(
|
|
851
|
+
f"Worker {worker_id} shape mismatch for {cam_id}: "
|
|
852
|
+
f"got {tensor.shape}, expected {expected_shape}"
|
|
853
|
+
)
|
|
854
|
+
continue # Skip this frame
|
|
855
|
+
|
|
788
856
|
ring_buffers[cam_id].write_frame_fast(tensor, sync=False)
|
|
789
857
|
local_frames += 1
|
|
790
858
|
frames_since_counter_update += 1
|
|
@@ -808,8 +876,14 @@ def nvdec_pool_worker(
|
|
|
808
876
|
if local_errors <= 3:
|
|
809
877
|
logger.error(f"Worker {worker_id} write error: {e}")
|
|
810
878
|
|
|
811
|
-
if decoded_frames
|
|
812
|
-
|
|
879
|
+
if decoded_frames:
|
|
880
|
+
# Sync all buffers that received frames in this round
|
|
881
|
+
# Critical for cross-container IPC - ensures GPU writes are visible
|
|
882
|
+
synced_cams = set()
|
|
883
|
+
for cam_id, _ in decoded_frames:
|
|
884
|
+
if cam_id in ring_buffers and cam_id not in synced_cams:
|
|
885
|
+
ring_buffers[cam_id].sync_writes()
|
|
886
|
+
synced_cams.add(cam_id)
|
|
813
887
|
|
|
814
888
|
if num_frames == 0:
|
|
815
889
|
time.sleep(0.0001)
|
|
@@ -923,30 +997,64 @@ def nvdec_pool_process(
|
|
|
923
997
|
})
|
|
924
998
|
return
|
|
925
999
|
|
|
926
|
-
# Create NV12 ring buffers
|
|
1000
|
+
# Create NV12 ring buffers with FIXED dimensions (640x640 -> 960x640 for NV12)
|
|
1001
|
+
# ALL cameras resize to TARGET_WIDTH x TARGET_HEIGHT regardless of source resolution
|
|
927
1002
|
ring_buffers: Dict[str, CudaIpcRingBuffer] = {}
|
|
928
|
-
frame_size_mb =
|
|
1003
|
+
frame_size_mb = TARGET_WIDTH * NV12_HEIGHT * 1 / 1e6 # 640 * 960 * 1 channel
|
|
929
1004
|
|
|
930
1005
|
try:
|
|
1006
|
+
# Initialize GPU camera map (producer side) - process 0 creates, others connect
|
|
1007
|
+
gpu_map = None
|
|
1008
|
+
if GPU_CAMERA_MAP_AVAILABLE:
|
|
1009
|
+
gpu_map = GpuCameraMap(is_producer=True)
|
|
1010
|
+
if process_id == 0:
|
|
1011
|
+
if gpu_map.initialize():
|
|
1012
|
+
logger.info(f"Process {process_id}: GpuCameraMap initialized")
|
|
1013
|
+
else:
|
|
1014
|
+
logger.warning(f"Process {process_id}: Failed to initialize GpuCameraMap")
|
|
1015
|
+
gpu_map = None
|
|
1016
|
+
else:
|
|
1017
|
+
# Wait for process 0 to initialize
|
|
1018
|
+
for retry in range(50):
|
|
1019
|
+
if gpu_map.connect():
|
|
1020
|
+
logger.info(f"Process {process_id}: Connected to GpuCameraMap")
|
|
1021
|
+
break
|
|
1022
|
+
time.sleep(0.1)
|
|
1023
|
+
else:
|
|
1024
|
+
logger.warning(f"Process {process_id}: Failed to connect to GpuCameraMap")
|
|
1025
|
+
gpu_map = None
|
|
1026
|
+
|
|
1027
|
+
# Collect GPU mappings for bulk write
|
|
1028
|
+
gpu_mappings = {}
|
|
1029
|
+
|
|
931
1030
|
for i, config in enumerate(camera_configs):
|
|
1031
|
+
# Use fixed dimensions - ALL cameras output 640x640 (960x640 for NV12)
|
|
932
1032
|
rb = CudaIpcRingBuffer.create_producer(
|
|
933
1033
|
config.camera_id,
|
|
934
1034
|
gpu_id=config.gpu_id,
|
|
935
1035
|
num_slots=num_slots,
|
|
936
|
-
width=
|
|
937
|
-
height=
|
|
1036
|
+
width=TARGET_WIDTH, # Always 640
|
|
1037
|
+
height=NV12_HEIGHT, # Always 960 (640 * 1.5 for NV12)
|
|
938
1038
|
channels=1,
|
|
939
1039
|
)
|
|
940
1040
|
ring_buffers[config.camera_id] = rb
|
|
941
1041
|
|
|
1042
|
+
# Track GPU assignment for this camera
|
|
1043
|
+
gpu_mappings[config.camera_id] = config.gpu_id
|
|
1044
|
+
|
|
942
1045
|
pool.assign_stream(
|
|
943
1046
|
stream_id=i,
|
|
944
1047
|
camera_id=config.camera_id,
|
|
945
1048
|
video_path=config.video_path,
|
|
946
|
-
width=
|
|
947
|
-
height=
|
|
1049
|
+
width=TARGET_WIDTH, # Use fixed width
|
|
1050
|
+
height=TARGET_HEIGHT # Use fixed height
|
|
948
1051
|
)
|
|
949
1052
|
|
|
1053
|
+
# Write all GPU mappings at once
|
|
1054
|
+
if gpu_map and gpu_mappings:
|
|
1055
|
+
gpu_map.set_bulk_mapping(gpu_mappings)
|
|
1056
|
+
logger.info(f"Process {process_id}: Wrote {len(gpu_mappings)} camera-GPU mappings")
|
|
1057
|
+
|
|
950
1058
|
logger.info(f"Process {process_id}: {pool.actual_pool_size} decoders, "
|
|
951
1059
|
f"{len(camera_configs)} streams, NV12 ({frame_size_mb:.1f} MB/frame)")
|
|
952
1060
|
|
|
File without changes
|
|
File without changes
|
{matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/matrice_streaming.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/matrice_streaming.egg-info/not-zip-safe
RENAMED
|
File without changes
|
{matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/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.67 → matrice_streaming-0.1.69}/src/matrice_streaming/client/__init__.py
RENAMED
|
File without changes
|
{matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/client/client.py
RENAMED
|
File without changes
|
{matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/client/client_utils.py
RENAMED
|
File without changes
|
{matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/deployment/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/src/matrice_streaming/deployment/deployment.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{matrice_streaming-0.1.67 → matrice_streaming-0.1.69}/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
|
|
File without changes
|