Skip to content

Detection Worker

app.infrastructure.detection.worker.detection_worker

View source code

Background YOLO detection worker — thread-safe batch frame inference.

See Also

Layer: Infrastructure. Context: Implements concrete processing and I/O behind application-facing contracts.

DetectionWorker

Bases: QThread

Background QThread that runs YOLO inference on all video frames, emitting batches asynchronously.

ATTRIBUTE DESCRIPTION
_s_id

Session ID for batch routing.

TYPE: SessionId

_video_path

Video path extracted from s_id.

TYPE: str

_detection_engine

YOLO model wrapper used for inference.

TYPE: DetectionEngine

_detections_by_frame_index

Thread-safe cache protected by _mutex.

TYPE: dict[int, list[DetectionResult]]

_mutex

Guards base detection view_state.

TYPE: QMutex

_stop_requested

True when shutdown is requested.

TYPE: bool

_is_complete

True after the full stream is processed.

TYPE: bool

Note

Signals emitted by this worker: progress_updated(frame_idx, total_frames): Emitted per frame for UI sync. batch_ready(s_id, batch): Emitted every 30 frames. finished_processing(): Emitted when the thread exits. error_occurred(msg): Emitted on exception.

Thread lifecycle: start() triggers the native QThread lifecycle, run() loops and emits, stop() sets _stop_requested, and finished_processing() is emitted when the thread exits.

Batch emission: accumulate detections in current_batch until it reaches 30 frames, emit batch_ready(), then reset. Remaining frames are flushed at stream end.

Thread affinity: do not access UI from run(). Only emit signals. Callers must use moveToThread(worker) before starting. Shutdown sequence: worker.stop() -> worker.quit() -> worker.wait() -> deleteLater().

Example

worker = DetectionWorker(s_id, engine) thread = QThread() worker.moveToThread(thread) worker.batch_ready.connect(on_batch_ready) worker.finished_processing.connect(thread.quit) thread.start() worker.start()

PARAMETER DESCRIPTION
s_id

Identifier of the session associated with this object.

TYPE: SessionId

detection_engine

Detection engine used to process video frames.

TYPE: DetectionEngineInterface

parent

Optional Qt parent object.

TYPE: QObject | None DEFAULT: None

batch_ready = Signal(object, object, float) class-attribute instance-attribute

error_occurred = Signal(str) class-attribute instance-attribute

finished_processing = Signal() class-attribute instance-attribute

progress_updated = Signal(int, int, float) class-attribute instance-attribute

__init__(s_id: SessionId, detection_engine: DetectionEngineInterface, parent: QObject | None = None) -> None

get_all_detections() -> dict[int, list[DetectionResult]]

Return copy of all cached detections (thread-safe via _mutex).

RETURNS DESCRIPTION
dict[int, list[DetectionResult]]

New mapping of frame indices to new detection lists.

get_detections(frame_index: int) -> list[DetectionResult] | None

Retrieve cached detections for frame_index, or None if not yet processed.

PARAMETER DESCRIPTION
frame_index

Zero-based index of the frame to query.

TYPE: int

RETURNS DESCRIPTION
list[DetectionResult] | None

A new list of detections for the frame, or None if it has no cached result.

isRunning() -> bool

Return True if thread is currently processing frames.

RETURNS DESCRIPTION
bool

True while the underlying QThread is running.

is_complete() -> bool

Return True if stream reached end (all frames processed).

RETURNS DESCRIPTION
bool

True after the worker reaches the end of the video stream.

run() -> None

Main thread loop — read all frames, run YOLO inference, emit batches (30 frames).

Note

Workflow: 1. Open VideoReader for _video_path. 2. The first sequential read is index zero; loop: read frame, call _detection_engine.detect(), and store the result in the cache and current batch. 3. Every 30 frames, emit batch_ready(s_id, batch) and reset the batch. 4. On stream end, flush any remaining batch. 5. On exception, emit error_occurred(msg). 6. Finally, close the reader and emit finished_processing().

Do not access UI from this thread. Only emit signals. progress_updated() is used to synchronize UI progress.

RAISES DESCRIPTION
None

Worker failures are reported through error_occurred.

Example

worker.start()

start(priority: QThread.Priority = QThread.Priority.InheritPriority) -> None

Start the detection thread (calls run() in background).

PARAMETER DESCRIPTION
priority

Qt thread scheduling priority passed to QThread.start.

TYPE: Priority DEFAULT: InheritPriority

stop() -> None

Request thread to stop (sets _stop_requested flag).