import 'package:camera/camera.dart'; import '../detection/detection_result.dart'; import '../detection/detector_worker.dart'; import 'camera_view_model.dart'; /// 抽帧节流 + 后台推理(对应 Kotlin FrameAnalyzer)。 /// 推理在后台 isolate(DetectorWorker)执行,主 isolate 只投递帧与收结果。 class FrameAnalyzer { /// 连续检测:100ms 一帧 int intervalMs = 100; /// null = 模型加载失败,仅预览不分析 final DetectorWorker? worker; final CameraViewModel viewModel; int _lastDetectMs = 0; /// 诊断计数:推理调用/异常次数 int detectCalls = 0; int detectErrors = 0; String? lastError; /// 最近一次完整处理(预处理+推理+运动检测)耗时 ms(worker 侧) int lastProcessMs = 0; /// 图像流回调是否到达(诊断用) int framesReceived = 0; FrameAnalyzer({required this.worker, required this.viewModel}) { worker?.onResult = _onResult; worker?.onError = _onError; } void recordStreamError(String msg) { lastError = msg; detectErrors++; } void _onResult( List results, List motion, List novelty, int rotation, int width, int height, int processMs) { detectCalls++; lastProcessMs = processMs; viewModel.onFramesAnalyzed( results, rotation, width, height, motion, novelty, detectCalls: detectCalls, detectErrors: detectErrors, lastError: lastError, framesReceived: framesReceived, lastProcessMs: lastProcessMs, ); } void _onError(String msg) { detectErrors++; lastError = msg; viewModel.onFramesAnalyzed( const [], 90, 0, 0, const [], const [], detectCalls: detectCalls, detectErrors: detectErrors, lastError: lastError, framesReceived: framesReceived, lastProcessMs: lastProcessMs, ); } void analyze(CameraImage image, int rotationDegrees) { framesReceived++; final w = worker; if (w == null) return; final now = DateTime.now().millisecondsSinceEpoch; if (now - _lastDetectMs < intervalMs) return; _lastDetectMs = now; if (w.busy) return; // 上一帧未返回则丢帧,避免在途积压 w.analyze(image, rotationDegrees); } void reset() => _lastDetectMs = 0; void dispose() => worker?.dispose(); }