matrice-streaming 0.1.72__tar.gz → 0.1.73__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.72 → matrice_streaming-0.1.73}/PKG-INFO +1 -1
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/matrice_streaming.egg-info/PKG-INFO +1 -1
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/camera_streamer/async_camera_worker.py +46 -13
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/LICENSE.txt +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/README.md +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/matrice_streaming.egg-info/SOURCES.txt +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/matrice_streaming.egg-info/dependency_links.txt +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/matrice_streaming.egg-info/not-zip-safe +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/matrice_streaming.egg-info/top_level.txt +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/pyproject.toml +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/setup.cfg +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/setup.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/__init__.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/client/__init__.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/client/client.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/client/client_utils.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/deployment/__init__.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/deployment/camera_manager.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/deployment/deployment.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/deployment/inference_pipeline.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/deployment/streaming_gateway_manager.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/deployment/todo.txt +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/py.typed +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/__init__.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/camera_streamer/ARCHITECTURE.md +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/camera_streamer/__init__.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/camera_streamer/async_ffmpeg_worker.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/camera_streamer/camera_streamer.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/camera_streamer/device_detection.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/camera_streamer/encoder_manager.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/camera_streamer/encoding_pool_manager.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/camera_streamer/ffmpeg_camera_streamer.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/camera_streamer/ffmpeg_config.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/camera_streamer/ffmpeg_worker_manager.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/camera_streamer/frame_processor.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/camera_streamer/gstreamer_camera_streamer.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/camera_streamer/gstreamer_worker.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/camera_streamer/gstreamer_worker_manager.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/camera_streamer/message_builder.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/camera_streamer/nvdec.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/camera_streamer/nvdec_worker_manager.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/camera_streamer/platform_pipelines.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/camera_streamer/retry_manager.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/camera_streamer/stream_statistics.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/camera_streamer/video_capture_manager.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/camera_streamer/worker_manager.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/debug/README.md +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/debug/__init__.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/debug/benchmark.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/debug/debug_gstreamer_gateway.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/debug/debug_stream_backend.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/debug/debug_streaming_gateway.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/debug/debug_utils.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/debug/example_debug_streaming.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/debug/test_videoplayback.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/dynamic_camera_manager.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/event_listener.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/metrics_reporter.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/streaming_action.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/streaming_gateway.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/streaming_gateway_utils.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/streaming_gateway/streaming_status_listener.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/tests/test_async_infrastructure.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/tests/test_batch_auto_calculation.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/tests/test_batching_verification.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/tests/test_e2e_production.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/tests/test_flatten_binary.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/tests/test_gstreamer_integration.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/tests/test_msgpack_fix.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/tests/test_phase1_unit.py +0 -0
- {matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/tests/test_phase2_scaling.py +0 -0
|
@@ -495,6 +495,9 @@ class AsyncCameraWorker:
|
|
|
495
495
|
cap = None
|
|
496
496
|
consecutive_failures = 0
|
|
497
497
|
frame_counter = 0
|
|
498
|
+
# PTS-based pacing for video files
|
|
499
|
+
first_video_ms = None
|
|
500
|
+
first_wall_time = None
|
|
498
501
|
|
|
499
502
|
try:
|
|
500
503
|
# Prepare source (download if URL)
|
|
@@ -570,6 +573,18 @@ class AsyncCameraWorker:
|
|
|
570
573
|
consecutive_failures = 0
|
|
571
574
|
frame_counter += 1
|
|
572
575
|
|
|
576
|
+
# Get video file timestamp (for video files, use video PTS instead of wall clock)
|
|
577
|
+
# This prevents timestamp jumps when pipeline stalls
|
|
578
|
+
video_ts_ms = cap.get(cv2.CAP_PROP_POS_MSEC) if source_type == "video_file" else None
|
|
579
|
+
|
|
580
|
+
# Frame decimation: Read ALL frames, skip based on target FPS
|
|
581
|
+
# This avoids sleep-based throttling which misses frames
|
|
582
|
+
source_fps = video_props.get('original_fps', 30) if video_props else 30
|
|
583
|
+
if fps > 0 and source_fps > fps:
|
|
584
|
+
skip_ratio = int(source_fps / fps)
|
|
585
|
+
if skip_ratio > 1 and frame_counter % skip_ratio != 0:
|
|
586
|
+
continue # Skip this frame, read next immediately
|
|
587
|
+
|
|
573
588
|
# Resize if needed
|
|
574
589
|
if width or height:
|
|
575
590
|
frame = FrameProcessor.resize_frame(frame, width, height)
|
|
@@ -581,7 +596,7 @@ class AsyncCameraWorker:
|
|
|
581
596
|
await self._process_frame_shm_mode(
|
|
582
597
|
frame, stream_key, stream_group_key, topic,
|
|
583
598
|
actual_width, actual_height, frame_counter,
|
|
584
|
-
camera_location, read_time
|
|
599
|
+
camera_location, read_time, video_ts_ms
|
|
585
600
|
)
|
|
586
601
|
else:
|
|
587
602
|
# EXISTING FLOW: JPEG encode and send full frame
|
|
@@ -589,16 +604,22 @@ class AsyncCameraWorker:
|
|
|
589
604
|
frame, stream_key, stream_group_key, topic,
|
|
590
605
|
source, video_props, fps, quality,
|
|
591
606
|
actual_width, actual_height, source_type,
|
|
592
|
-
frame_counter, camera_location, read_time
|
|
607
|
+
frame_counter, camera_location, read_time,
|
|
608
|
+
video_ts_ms
|
|
593
609
|
)
|
|
594
610
|
|
|
595
|
-
#
|
|
596
|
-
#
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
611
|
+
# PTS-based pacing for video files (smooth playback without drift)
|
|
612
|
+
# Instead of fixed-interval sleep, pace based on video timeline
|
|
613
|
+
if source_type == "video_file" and video_ts_ms is not None:
|
|
614
|
+
if first_video_ms is None:
|
|
615
|
+
first_video_ms = video_ts_ms
|
|
616
|
+
first_wall_time = time.time()
|
|
617
|
+
else:
|
|
618
|
+
# Calculate target wall time based on video PTS
|
|
619
|
+
target_wall = first_wall_time + (video_ts_ms - first_video_ms) / 1000.0
|
|
620
|
+
sleep_time = target_wall - time.time()
|
|
621
|
+
if sleep_time > 0:
|
|
622
|
+
await asyncio.sleep(sleep_time)
|
|
602
623
|
|
|
603
624
|
except asyncio.CancelledError:
|
|
604
625
|
self.logger.info(f"Worker {self.worker_id}: Camera {stream_key} task cancelled")
|
|
@@ -671,7 +692,8 @@ class AsyncCameraWorker:
|
|
|
671
692
|
source_type: str,
|
|
672
693
|
frame_counter: int,
|
|
673
694
|
camera_location: str,
|
|
674
|
-
read_time: float
|
|
695
|
+
read_time: float,
|
|
696
|
+
video_ts_ms: Optional[float] = None
|
|
675
697
|
):
|
|
676
698
|
"""Process frame and send to Redis asynchronously.
|
|
677
699
|
|
|
@@ -692,6 +714,7 @@ class AsyncCameraWorker:
|
|
|
692
714
|
frame_counter: Current frame number
|
|
693
715
|
camera_location: Camera location
|
|
694
716
|
read_time: Time taken to read frame
|
|
717
|
+
video_ts_ms: Video file timestamp in milliseconds (None for live streams)
|
|
695
718
|
"""
|
|
696
719
|
frame_start = time.time()
|
|
697
720
|
|
|
@@ -865,7 +888,8 @@ class AsyncCameraWorker:
|
|
|
865
888
|
height: int,
|
|
866
889
|
frame_counter: int,
|
|
867
890
|
camera_location: str,
|
|
868
|
-
read_time: float
|
|
891
|
+
read_time: float,
|
|
892
|
+
video_ts_ms: Optional[float] = None
|
|
869
893
|
):
|
|
870
894
|
"""SHM_MODE: Write raw frame to SHM, send metadata to Redis.
|
|
871
895
|
|
|
@@ -882,6 +906,7 @@ class AsyncCameraWorker:
|
|
|
882
906
|
frame_counter: Current frame number
|
|
883
907
|
camera_location: Camera location string
|
|
884
908
|
read_time: Time taken to read frame
|
|
909
|
+
video_ts_ms: Video file timestamp in milliseconds (None for live streams)
|
|
885
910
|
"""
|
|
886
911
|
frame_start = time.time()
|
|
887
912
|
|
|
@@ -895,7 +920,11 @@ class AsyncCameraWorker:
|
|
|
895
920
|
if is_similar and reference_frame_idx is not None:
|
|
896
921
|
# Frame is similar - send metadata with reference to previous frame
|
|
897
922
|
# Consumer can skip reading SHM and use previous result
|
|
898
|
-
|
|
923
|
+
# Use video PTS for video files, wall clock for live streams
|
|
924
|
+
if video_ts_ms is not None:
|
|
925
|
+
ts_ns = int(video_ts_ms * 1e6) # Convert ms to ns
|
|
926
|
+
else:
|
|
927
|
+
ts_ns = int(time.time() * 1e9)
|
|
899
928
|
shm_buffer = self._shm_buffers.get(stream_key)
|
|
900
929
|
|
|
901
930
|
await self.redis_client.add_shm_metadata(
|
|
@@ -950,7 +979,11 @@ class AsyncCameraWorker:
|
|
|
950
979
|
self._last_shm_frame_idx[stream_key] = frame_idx
|
|
951
980
|
|
|
952
981
|
# Send metadata-only message to Redis
|
|
953
|
-
|
|
982
|
+
# Use video PTS for video files, wall clock for live streams
|
|
983
|
+
if video_ts_ms is not None:
|
|
984
|
+
ts_ns = int(video_ts_ms * 1e6) # Convert ms to ns
|
|
985
|
+
else:
|
|
986
|
+
ts_ns = int(time.time() * 1e9)
|
|
954
987
|
write_start = time.time()
|
|
955
988
|
|
|
956
989
|
await self.redis_client.add_shm_metadata(
|
|
File without changes
|
|
File without changes
|
{matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/matrice_streaming.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/matrice_streaming.egg-info/not-zip-safe
RENAMED
|
File without changes
|
{matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/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.72 → matrice_streaming-0.1.73}/src/matrice_streaming/client/__init__.py
RENAMED
|
File without changes
|
{matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/client/client.py
RENAMED
|
File without changes
|
{matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/client/client_utils.py
RENAMED
|
File without changes
|
{matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/deployment/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/src/matrice_streaming/deployment/deployment.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{matrice_streaming-0.1.72 → matrice_streaming-0.1.73}/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
|