nedo-vision-worker-core 0.4.1__py3-none-any.whl → 0.4.4__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.
Potentially problematic release.
This version of nedo-vision-worker-core might be problematic. Click here for more details.
- nedo_vision_worker_core/__init__.py +1 -1
- nedo_vision_worker_core/pipeline/PipelineManager.py +14 -0
- nedo_vision_worker_core/pipeline/PipelineProcessor.py +17 -5
- nedo_vision_worker_core/pipeline/PipelineSyncThread.py +14 -0
- nedo_vision_worker_core/repositories/WorkerSourcePipelineDetectionRepository.py +11 -3
- nedo_vision_worker_core/repositories/WorkerSourceRepository.py +35 -0
- nedo_vision_worker_core/streams/RTMPStreamer.py +1 -1
- nedo_vision_worker_core/streams/VideoStream.py +14 -0
- {nedo_vision_worker_core-0.4.1.dist-info → nedo_vision_worker_core-0.4.4.dist-info}/METADATA +1 -1
- {nedo_vision_worker_core-0.4.1.dist-info → nedo_vision_worker_core-0.4.4.dist-info}/RECORD +13 -13
- {nedo_vision_worker_core-0.4.1.dist-info → nedo_vision_worker_core-0.4.4.dist-info}/WHEEL +0 -0
- {nedo_vision_worker_core-0.4.1.dist-info → nedo_vision_worker_core-0.4.4.dist-info}/entry_points.txt +0 -0
- {nedo_vision_worker_core-0.4.1.dist-info → nedo_vision_worker_core-0.4.4.dist-info}/top_level.txt +0 -0
|
@@ -7,7 +7,7 @@ A library for running AI vision processing and detection in the Nedo Vision plat
|
|
|
7
7
|
from .core_service import CoreService
|
|
8
8
|
from .callbacks import DetectionType, CallbackTrigger, DetectionData, IntervalMetadata
|
|
9
9
|
|
|
10
|
-
__version__ = "0.4.
|
|
10
|
+
__version__ = "0.4.4"
|
|
11
11
|
__all__ = [
|
|
12
12
|
"CoreService",
|
|
13
13
|
"DetectionType",
|
|
@@ -31,6 +31,11 @@ class PipelineManager:
|
|
|
31
31
|
self._stop_lock = threading.Lock()
|
|
32
32
|
self.on_pipeline_stopped = on_pipeline_stopped
|
|
33
33
|
|
|
34
|
+
# Stagger pipeline startup to reduce CPU spikes
|
|
35
|
+
self._last_pipeline_start = 0
|
|
36
|
+
self._pipeline_start_delay = 1.0 # 1 second between pipeline starts
|
|
37
|
+
self._start_lock = threading.Lock()
|
|
38
|
+
|
|
34
39
|
logging.info(f"🚀 PipelineManager initialized with {max_workers} worker threads")
|
|
35
40
|
|
|
36
41
|
def start_pipeline(self, pipeline, detector):
|
|
@@ -46,6 +51,15 @@ class PipelineManager:
|
|
|
46
51
|
logging.warning(f"⚠️ Pipeline {pipeline_id} is already running.")
|
|
47
52
|
return
|
|
48
53
|
|
|
54
|
+
# Stagger pipeline starts to reduce CPU spikes
|
|
55
|
+
with self._start_lock:
|
|
56
|
+
time_since_last_start = time.time() - self._last_pipeline_start
|
|
57
|
+
if time_since_last_start < self._pipeline_start_delay:
|
|
58
|
+
delay = self._pipeline_start_delay - time_since_last_start
|
|
59
|
+
logging.info(f"⏳ Staggering pipeline {pipeline_id} start by {delay:.2f}s to reduce CPU spike")
|
|
60
|
+
time.sleep(delay)
|
|
61
|
+
self._last_pipeline_start = time.time()
|
|
62
|
+
|
|
49
63
|
logging.info(f"🚀 Starting Pipeline processing for pipeline: {pipeline_id} | Source: {worker_source_id} ({pipeline.name})")
|
|
50
64
|
|
|
51
65
|
# Acquire video stream
|
|
@@ -47,6 +47,10 @@ class PipelineProcessor:
|
|
|
47
47
|
self.last_preview_check_time = 0
|
|
48
48
|
self.preview_check_interval = 10.0 # Check every 10 seconds (reduced from 5s to save CPU)
|
|
49
49
|
self.pipeline_repo = WorkerSourcePipelineRepository()
|
|
50
|
+
|
|
51
|
+
# RTMP frame rate limiting to reduce CPU
|
|
52
|
+
self.last_rtmp_frame_time = 0
|
|
53
|
+
self.rtmp_frame_interval = 1.0 / 25.0 # 25 FPS for RTMP (matching render FPS)
|
|
50
54
|
|
|
51
55
|
self.detection_processor_codes = [
|
|
52
56
|
PPEDetectionProcessor.code,
|
|
@@ -198,10 +202,15 @@ class PipelineProcessor:
|
|
|
198
202
|
if loop_start - last_preview_check >= self.preview_check_interval:
|
|
199
203
|
self._check_and_update_rtmp_streaming()
|
|
200
204
|
last_preview_check = loop_start
|
|
201
|
-
|
|
202
|
-
should_draw = self.rtmp_streaming_active or self.debug_flag
|
|
203
205
|
|
|
204
|
-
if
|
|
206
|
+
# For RTMP, also check if it's time to send a frame (rate limiting)
|
|
207
|
+
should_draw_for_rtmp = (
|
|
208
|
+
self.rtmp_streaming_active and
|
|
209
|
+
self.rtmp_streamer is not None and
|
|
210
|
+
(loop_start - self.last_rtmp_frame_time >= self.rtmp_frame_interval)
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
if should_draw_for_rtmp or self.debug_flag:
|
|
205
214
|
try:
|
|
206
215
|
frame_to_draw = frame.copy()
|
|
207
216
|
self.frame_drawer.draw_polygons(frame_to_draw)
|
|
@@ -215,7 +224,7 @@ class PipelineProcessor:
|
|
|
215
224
|
logging.error(f"❌ Draw failed, using raw frame: {e}")
|
|
216
225
|
drawn_frame = frame
|
|
217
226
|
else:
|
|
218
|
-
drawn_frame =
|
|
227
|
+
drawn_frame = None # Don't waste CPU drawing if not needed
|
|
219
228
|
|
|
220
229
|
if self.debug_flag:
|
|
221
230
|
tracked_objects_render = self._process_frame(frame)
|
|
@@ -235,13 +244,16 @@ class PipelineProcessor:
|
|
|
235
244
|
try:
|
|
236
245
|
self.rtmp_streamer = RTMPStreamer(self.pipeline_id)
|
|
237
246
|
logging.info(f"🎬 RTMP streamer initialized for pipeline {pipeline_id} (preview requested)")
|
|
247
|
+
self.last_rtmp_frame_time = 0 # Reset frame time on new stream
|
|
238
248
|
except Exception as e:
|
|
239
249
|
logging.error(f"❌ Failed to initialize RTMP streamer for pipeline {pipeline_id}: {e}")
|
|
240
250
|
self.rtmp_streamer = None
|
|
241
251
|
|
|
242
|
-
if self.rtmp_streamer:
|
|
252
|
+
if self.rtmp_streamer and drawn_frame is not None:
|
|
253
|
+
# Frame already rate-limited by drawing logic above
|
|
243
254
|
try:
|
|
244
255
|
self.rtmp_streamer.push_frame(drawn_frame)
|
|
256
|
+
self.last_rtmp_frame_time = loop_start
|
|
245
257
|
except Exception as e:
|
|
246
258
|
logging.error(f"❌ RTMP push error for pipeline {pipeline_id}: {e}")
|
|
247
259
|
if "initialization_failed" in str(e).lower():
|
|
@@ -5,6 +5,7 @@ import threading
|
|
|
5
5
|
from typing import Dict, Set, Optional
|
|
6
6
|
from ..repositories.WorkerSourcePipelineDebugRepository import WorkerSourcePipelineDebugRepository
|
|
7
7
|
from ..repositories.WorkerSourcePipelineRepository import WorkerSourcePipelineRepository
|
|
8
|
+
from ..repositories.WorkerSourceRepository import WorkerSourceRepository
|
|
8
9
|
from .PipelineManager import PipelineManager
|
|
9
10
|
from .ModelManager import ModelManager
|
|
10
11
|
from ..streams.VideoStreamManager import VideoStreamManager
|
|
@@ -19,6 +20,7 @@ class PipelineSyncThread(threading.Thread):
|
|
|
19
20
|
self.polling_interval = polling_interval
|
|
20
21
|
self.pipeline_repo = WorkerSourcePipelineRepository()
|
|
21
22
|
self.debug_repo = WorkerSourcePipelineDebugRepository()
|
|
23
|
+
self.source_repo = WorkerSourceRepository()
|
|
22
24
|
self.model_manager = ModelManager()
|
|
23
25
|
self.running = True
|
|
24
26
|
self.pipeline_manager = PipelineManager(video_manager, self.on_pipeline_stopped, max_workers)
|
|
@@ -82,6 +84,11 @@ class PipelineSyncThread(threading.Thread):
|
|
|
82
84
|
pipeline.pipeline_status_code = 'run'
|
|
83
85
|
|
|
84
86
|
if pipeline.pipeline_status_code == 'run':
|
|
87
|
+
# Check if source is connected before starting pipeline
|
|
88
|
+
if not self.source_repo.is_source_connected(pipeline.worker_source_id):
|
|
89
|
+
logging.warning(f"⚠️ Skipping pipeline {pid} ({pipeline.name}): Source {pipeline.worker_source_id} is disconnected")
|
|
90
|
+
continue
|
|
91
|
+
|
|
85
92
|
detector = self.model_manager.get_detector(pipeline.ai_model_id)
|
|
86
93
|
|
|
87
94
|
if not detector and pipeline.ai_model_id:
|
|
@@ -144,8 +151,15 @@ class PipelineSyncThread(threading.Thread):
|
|
|
144
151
|
])
|
|
145
152
|
|
|
146
153
|
if requires_restart:
|
|
154
|
+
# Check if source is connected before restarting
|
|
155
|
+
if not self.source_repo.is_source_connected(db_pipeline.worker_source_id):
|
|
156
|
+
logging.warning(f"⚠️ Cannot restart pipeline {pid}: Source {db_pipeline.worker_source_id} is disconnected")
|
|
157
|
+
return
|
|
158
|
+
|
|
147
159
|
logging.info(f"🔄 Restarting pipeline due to significant changes: {pid}")
|
|
148
160
|
self.pipeline_manager.stop_pipeline(pid)
|
|
161
|
+
|
|
162
|
+
|
|
149
163
|
self.pipeline_manager.start_pipeline(db_pipeline, db_detector)
|
|
150
164
|
else:
|
|
151
165
|
# Update config for minor changes that don't require restart
|
|
@@ -18,12 +18,14 @@ class WorkerSourcePipelineDetectionRepository(BaseRepository):
|
|
|
18
18
|
def save_detection(self, pipeline_id: int, frame, tracked_objects, frame_drawer: FrameDrawer):
|
|
19
19
|
"""
|
|
20
20
|
Save detection data that need to be sent to database.
|
|
21
|
+
Only saves if there are violations detected.
|
|
21
22
|
"""
|
|
22
23
|
now = datetime.now(timezone.utc)
|
|
23
24
|
current_datetime = now.strftime("%Y%m%d_%H%M%S")
|
|
24
25
|
|
|
25
26
|
frame_drawer.draw_polygons(frame)
|
|
26
27
|
filtered_objects = []
|
|
28
|
+
has_violations = False
|
|
27
29
|
|
|
28
30
|
for tracked_obj in tracked_objects:
|
|
29
31
|
attributes = tracked_obj["attributes"]
|
|
@@ -34,9 +36,17 @@ class WorkerSourcePipelineDetectionRepository(BaseRepository):
|
|
|
34
36
|
obj = tracked_obj.copy()
|
|
35
37
|
obj["attributes"] = [attr for attr in attributes if attr.get("count", 0) >= 5]
|
|
36
38
|
|
|
39
|
+
# Check if any attribute is a violation
|
|
40
|
+
for attr in obj["attributes"]:
|
|
41
|
+
attr_label = attr.get("label", "")
|
|
42
|
+
if attr_label in frame_drawer.violation_labels:
|
|
43
|
+
has_violations = True
|
|
44
|
+
break
|
|
45
|
+
|
|
37
46
|
filtered_objects.append(obj)
|
|
38
47
|
|
|
39
|
-
if
|
|
48
|
+
# Only save and trigger webhook/MQTT if there are actual violations
|
|
49
|
+
if not filtered_objects or not has_violations:
|
|
40
50
|
return
|
|
41
51
|
|
|
42
52
|
drawn_frame = frame_drawer.draw_frame(frame.copy(), filtered_objects)
|
|
@@ -64,7 +74,5 @@ class WorkerSourcePipelineDetectionRepository(BaseRepository):
|
|
|
64
74
|
)
|
|
65
75
|
session.add(new_detection)
|
|
66
76
|
session.flush()
|
|
67
|
-
# Commit happens automatically via context manager
|
|
68
|
-
print(f"✅ Inserted detection data for pipeline {pipeline_id}")
|
|
69
77
|
except Exception as e:
|
|
70
78
|
print(f"❌ Database error while saving detection: {e}")
|
|
@@ -19,3 +19,38 @@ class WorkerSourceRepository(BaseRepository):
|
|
|
19
19
|
for source in sources:
|
|
20
20
|
session.expunge(source)
|
|
21
21
|
return sources
|
|
22
|
+
|
|
23
|
+
def get_worker_source(self, source_id: str):
|
|
24
|
+
"""
|
|
25
|
+
Fetch a single worker source by ID.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
source_id (str): The worker source ID
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
WorkerSourceEntity: The worker source entity or None if not found
|
|
32
|
+
"""
|
|
33
|
+
with self._get_session() as session:
|
|
34
|
+
session.expire_all()
|
|
35
|
+
source = session.query(WorkerSourceEntity).filter(
|
|
36
|
+
WorkerSourceEntity.id == source_id
|
|
37
|
+
).first()
|
|
38
|
+
if source:
|
|
39
|
+
session.expunge(source)
|
|
40
|
+
return source
|
|
41
|
+
|
|
42
|
+
def is_source_connected(self, source_id: str) -> bool:
|
|
43
|
+
"""
|
|
44
|
+
Check if a worker source is connected.
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
source_id (str): The worker source ID
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
bool: True if source is connected, False otherwise
|
|
51
|
+
"""
|
|
52
|
+
source = self.get_worker_source(source_id)
|
|
53
|
+
if not source:
|
|
54
|
+
return False
|
|
55
|
+
|
|
56
|
+
return source.status_code == "connected" if source.status_code else False
|
|
@@ -25,7 +25,7 @@ class RTMPStreamer:
|
|
|
25
25
|
# Class-level lock to stagger stream initialization across all instances
|
|
26
26
|
_initialization_lock = threading.Lock()
|
|
27
27
|
_last_initialization_time = 0
|
|
28
|
-
_min_initialization_delay =
|
|
28
|
+
_min_initialization_delay = 1.5 # 1.5 seconds between stream starts (increased from 0.5s)
|
|
29
29
|
|
|
30
30
|
def __init__(self, pipeline_id: str, fps: int = 25, bitrate: str = "1500k"):
|
|
31
31
|
self.pipeline_id = pipeline_id
|
|
@@ -237,6 +237,8 @@ class VideoStream(threading.Thread):
|
|
|
237
237
|
def run(self) -> None:
|
|
238
238
|
"""Main capture loop."""
|
|
239
239
|
failures = 0
|
|
240
|
+
last_frame_time = time.perf_counter()
|
|
241
|
+
|
|
240
242
|
while self.running:
|
|
241
243
|
try:
|
|
242
244
|
if not self.capture or not self.capture.isOpened():
|
|
@@ -247,6 +249,18 @@ class VideoStream(threading.Thread):
|
|
|
247
249
|
failures = 0
|
|
248
250
|
self._reconnect_attempts = 0
|
|
249
251
|
self._current_interval = self.reconnect_interval
|
|
252
|
+
last_frame_time = time.perf_counter()
|
|
253
|
+
|
|
254
|
+
# For video files, respect the FPS to avoid playing too fast
|
|
255
|
+
if self.is_file:
|
|
256
|
+
target_fps = self.target_fps if self.target_fps else self.fps
|
|
257
|
+
if target_fps > 0:
|
|
258
|
+
frame_interval = 1.0 / target_fps
|
|
259
|
+
elapsed = time.perf_counter() - last_frame_time
|
|
260
|
+
if elapsed < frame_interval:
|
|
261
|
+
sleep_time = frame_interval - elapsed
|
|
262
|
+
time.sleep(sleep_time)
|
|
263
|
+
last_frame_time = time.perf_counter()
|
|
250
264
|
|
|
251
265
|
ret, frame = self.capture.read()
|
|
252
266
|
|
{nedo_vision_worker_core-0.4.1.dist-info → nedo_vision_worker_core-0.4.4.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nedo-vision-worker-core
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.4
|
|
4
4
|
Summary: Nedo Vision Worker Core Library for AI Vision Processing
|
|
5
5
|
Author-email: Willy Achmat Fauzi <willy.achmat@gmail.com>
|
|
6
6
|
Maintainer-email: Willy Achmat Fauzi <willy.achmat@gmail.com>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
nedo_vision_worker_core/__init__.py,sha256=
|
|
1
|
+
nedo_vision_worker_core/__init__.py,sha256=ZlpHZZ54eVsepVdpBxhuJHhyEpKF8OqZAP9UvfFjMa4,1923
|
|
2
2
|
nedo_vision_worker_core/cli.py,sha256=8YuKWsIgICUYXE_QtwyU3WzGhVjTWiAo5uzpFOmjNc8,5766
|
|
3
3
|
nedo_vision_worker_core/core_service.py,sha256=q8-GuGW_l5l6wTWQDqc7BDdhM7zKC-mMLZ5wIHu9xV0,11628
|
|
4
4
|
nedo_vision_worker_core/doctor.py,sha256=K_-hVV2-mdEefZ4Cfu5hMCiOxBiI1aXY8VtkkpK80Lc,10651
|
|
@@ -59,10 +59,10 @@ nedo_vision_worker_core/models/worker_source_pipeline_debug.py,sha256=6S7TkN37Fr
|
|
|
59
59
|
nedo_vision_worker_core/models/worker_source_pipeline_detection.py,sha256=p6CJsiVCKprTYrNxJsiTB8njXdHkjZKVEyBceRVE6fY,560
|
|
60
60
|
nedo_vision_worker_core/pipeline/ModelManager.py,sha256=2DoQiIdF-PAqU7nT_u6bj-DY0aT2FHb8kt24okGGCRc,7449
|
|
61
61
|
nedo_vision_worker_core/pipeline/PipelineConfigManager.py,sha256=X55i9GyXcW9ylO6cj2UMAZFSxxPViacL4H4DZl60CAY,1157
|
|
62
|
-
nedo_vision_worker_core/pipeline/PipelineManager.py,sha256=
|
|
62
|
+
nedo_vision_worker_core/pipeline/PipelineManager.py,sha256=AlDwBYYRPeAeh2ilmC8n-A_2gYPqAzeSSVpR1Tc0ipE,8366
|
|
63
63
|
nedo_vision_worker_core/pipeline/PipelinePrepocessor.py,sha256=cCiVSHHqsKCtKYURdYoEjHJX2GnT6zd8kQ6ZukjQ3V0,1271
|
|
64
|
-
nedo_vision_worker_core/pipeline/PipelineProcessor.py,sha256=
|
|
65
|
-
nedo_vision_worker_core/pipeline/PipelineSyncThread.py,sha256=
|
|
64
|
+
nedo_vision_worker_core/pipeline/PipelineProcessor.py,sha256=5j0FvGwBw5hgJ-FzI493cLpZomfYiG-bmUZZyklmahI,35149
|
|
65
|
+
nedo_vision_worker_core/pipeline/PipelineSyncThread.py,sha256=8HOVdeWO0dAXY9rMAk4VlX-bIhWrkhSzyJwlJobUnvw,9517
|
|
66
66
|
nedo_vision_worker_core/pipeline/__init__.py,sha256=Nqnn8clbgv-5l0PgxcTOldg8mkMKrFn4TvPL-rYUUGg,1
|
|
67
67
|
nedo_vision_worker_core/preprocessing/ImageResizer.py,sha256=RvOazxe6dJQuiy0ZH4lIGbdFfiu0FLUVCHoMvxkDNT4,1324
|
|
68
68
|
nedo_vision_worker_core/preprocessing/ImageRoi.py,sha256=iO7oQ-SdUSA_kTIVBuq_mdycXsiJNfiFD3J7-VTxiQ4,2141
|
|
@@ -73,17 +73,17 @@ nedo_vision_worker_core/repositories/BaseRepository.py,sha256=FvdcD8I8_4_6TMZa8X
|
|
|
73
73
|
nedo_vision_worker_core/repositories/PPEDetectionRepository.py,sha256=dIOPUU7xOCJ8A5v6AnBVKwtKPVlc5M5cUhLCWumTXyo,6882
|
|
74
74
|
nedo_vision_worker_core/repositories/RestrictedAreaRepository.py,sha256=a5Vc8WLTtAa6Tn-ZSKkBEw4-cM29VW8WUwhbH7YfM9E,4416
|
|
75
75
|
nedo_vision_worker_core/repositories/WorkerSourcePipelineDebugRepository.py,sha256=lN_yip6woya9YUA5sYKbTyDQz2qSfgqkr3YP2hSd9ws,3211
|
|
76
|
-
nedo_vision_worker_core/repositories/WorkerSourcePipelineDetectionRepository.py,sha256=
|
|
76
|
+
nedo_vision_worker_core/repositories/WorkerSourcePipelineDetectionRepository.py,sha256=AVmrpeu6YziX2255_ZhK-5X5snxVMlr8xzb4ymAe5SA,2954
|
|
77
77
|
nedo_vision_worker_core/repositories/WorkerSourcePipelineRepository.py,sha256=vwwRA1INuK66siOHNZxSBX8CE9uEW8VVcCIA7dmshKo,4714
|
|
78
|
-
nedo_vision_worker_core/repositories/WorkerSourceRepository.py,sha256
|
|
78
|
+
nedo_vision_worker_core/repositories/WorkerSourceRepository.py,sha256=YFevfYhAsYd7Eho1iagzjk67tKAQfqmoIExyxvR2Bzc,1760
|
|
79
79
|
nedo_vision_worker_core/repositories/__init__.py,sha256=Nqnn8clbgv-5l0PgxcTOldg8mkMKrFn4TvPL-rYUUGg,1
|
|
80
80
|
nedo_vision_worker_core/services/SharedVideoStreamServer.py,sha256=rhCineMKPG3GQbrMHlSHP4xhXaGZ6Rn1oqIajW5xpaY,9827
|
|
81
81
|
nedo_vision_worker_core/services/VideoSharingDaemon.py,sha256=iY6afEKTOsphfHvmZTL0grezka2DS9DDq-1EIpVMy0Y,28524
|
|
82
82
|
nedo_vision_worker_core/services/VideoSharingDaemonManager.py,sha256=sc8VZo5iwoOdR8uTiel5BKz6-eZ7wwLy3IwV_3tsAu0,10340
|
|
83
|
-
nedo_vision_worker_core/streams/RTMPStreamer.py,sha256=
|
|
83
|
+
nedo_vision_worker_core/streams/RTMPStreamer.py,sha256=7vg2as_TtmZavLnzhEUOv6HhjoGH5X3JO9HUI74meNs,18789
|
|
84
84
|
nedo_vision_worker_core/streams/SharedVideoDeviceManager.py,sha256=vSslwxbhKH6FPndR1HcSFIVWtF-iiOQMlSa4VvFa6M4,16265
|
|
85
85
|
nedo_vision_worker_core/streams/StreamSyncThread.py,sha256=ETT0N_P90ksn6Q5pb7NvMadqCuoicz_g52lcDkHIp88,5382
|
|
86
|
-
nedo_vision_worker_core/streams/VideoStream.py,sha256=
|
|
86
|
+
nedo_vision_worker_core/streams/VideoStream.py,sha256=Xg3gxa9JZfCkwqD5OnvNmvf_iKmlEpjTlk4_YS2f2xU,14046
|
|
87
87
|
nedo_vision_worker_core/streams/VideoStreamManager.py,sha256=g5cz-YXPewSubBXxCg4mfzsuGKoOHXu-SrMxaGjYPHw,14956
|
|
88
88
|
nedo_vision_worker_core/streams/__init__.py,sha256=Nqnn8clbgv-5l0PgxcTOldg8mkMKrFn4TvPL-rYUUGg,1
|
|
89
89
|
nedo_vision_worker_core/tracker/SFSORT.py,sha256=0kggw0l4yPZ55AKHdqVX6mu9ehHmJed7jcJ3JQoC4sk,14061
|
|
@@ -98,8 +98,8 @@ nedo_vision_worker_core/util/PipelinePreviewChecker.py,sha256=XxlSMlrDlRrzfV8_Y-
|
|
|
98
98
|
nedo_vision_worker_core/util/PlatformDetector.py,sha256=GGL8UfeMQITR22EMYIRWnuOEnSqo7Dr5mb0PaFrl8AM,3006
|
|
99
99
|
nedo_vision_worker_core/util/TablePrinter.py,sha256=wzLGgb1GFMeIbAP6HmKcZD33j4D-IlyqlyeR7C5yD7w,1137
|
|
100
100
|
nedo_vision_worker_core/util/__init__.py,sha256=Nqnn8clbgv-5l0PgxcTOldg8mkMKrFn4TvPL-rYUUGg,1
|
|
101
|
-
nedo_vision_worker_core-0.4.
|
|
102
|
-
nedo_vision_worker_core-0.4.
|
|
103
|
-
nedo_vision_worker_core-0.4.
|
|
104
|
-
nedo_vision_worker_core-0.4.
|
|
105
|
-
nedo_vision_worker_core-0.4.
|
|
101
|
+
nedo_vision_worker_core-0.4.4.dist-info/METADATA,sha256=NeX_eRQ8lbk8z9HYN0ERFouzwjnbdc_xLXytxzvrQtw,14426
|
|
102
|
+
nedo_vision_worker_core-0.4.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
103
|
+
nedo_vision_worker_core-0.4.4.dist-info/entry_points.txt,sha256=pIPafsvPnBw-fpBKBmc1NQCQ6PQY3ad8mZ6mn8_p5FI,70
|
|
104
|
+
nedo_vision_worker_core-0.4.4.dist-info/top_level.txt,sha256=y8kusXjVYqtG8MSHYWTrk8bRrvjOrphKXYyzu943TTQ,24
|
|
105
|
+
nedo_vision_worker_core-0.4.4.dist-info/RECORD,,
|
|
File without changes
|
{nedo_vision_worker_core-0.4.1.dist-info → nedo_vision_worker_core-0.4.4.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{nedo_vision_worker_core-0.4.1.dist-info → nedo_vision_worker_core-0.4.4.dist-info}/top_level.txt
RENAMED
|
File without changes
|