#pragma once #include "camera.hpp" #include "frame_result.hpp" #include "output_writer.hpp" #include #include namespace cms { struct PipelineConfig { CameraConfig camera; OutputOptions output; std::filesystem::path engines,door_mask,door_zone_config; bool can_enabled{true}; std::string can_side{"left"},active_door{"can"}; double can_timeout_ms{1000}; std::uint64_t max_frames{}; std::filesystem::path results_path,pose_records_path; double detector_confidence{0.30}; int max_people{3}; double warning_relative{0.30},release_relative{0.45}; std::size_t queue_capacity{2}; bool door_mask_calibration_verified{false}; }; struct PipelineStats { std::uint64_t captured{},published{},driver_sequence_gaps{},discarded_error_frames{}; double mean_capture_to_result_ms{}; }; // One lifecycle per instance. start() warms engines before starting capture. // Runs continuously until requestStop() or a worker failure. // latest() reads the immutable result variable without removing or acknowledging it. // No result queue, consumer registration or frame-count termination. // Stop is safe from any thread; // destruction closes queues, interrupts capture and joins every worker. class CameraPipeline { public: explicit CameraPipeline(PipelineConfig config); ~CameraPipeline(); CameraPipeline(CameraPipeline const&)=delete; CameraPipeline& operator=(CameraPipeline const&)=delete; void start(); FrameResultPtr latest() const; bool running() const noexcept; void requestStop() noexcept; void join(); PipelineStats stats() const; private: struct Impl; std::unique_ptr impl_; }; }