camcom 1.0.0-pre2
 
Loading...
Searching...
No Matches
server.hpp
Go to the documentation of this file.
1
6
7#ifndef CAMCOM_TESTBENCH_SERVER_HPP
8#define CAMCOM_TESTBENCH_SERVER_HPP
9
17#include <string>
18#include <atomic>
19#include <memory>
20#include <mutex>
21#include <condition_variable>
22#include <vector>
23#include <thread>
24#include <set>
25#include <cmath>
26#include <chrono>
27
28namespace camcom::server {
29
31
44public:
45 explicit CameraServer(const ServerConfig& config);
47
48 CameraServer(const CameraServer&) = delete;
50
51 bool start();
52 void stop();
53 bool isRunning() const { return running_; }
54 const std::string& getServerId() const { return config_.camera_name; }
55
56private:
57 ServerConfig config_;
58 std::atomic<bool> running_{false};
59 std::unique_ptr<CameraController> camera_controller_;
60 std::unique_ptr<HttpServer> http_server_;
61
62 // --- Frame queue (capture -> publisher) ---
64 std::mutex queue_cv_mutex_;
65 std::condition_variable queue_cv_; // signalled when a frame is pushed
66
67 // --- Capture thread (runs during acquisition) ---
68 std::atomic<bool> capture_running_{false};
69 std::thread capture_thread_;
70 void captureFrameLoop();
71 void startCapture();
72 void stopCapture();
73
74 // --- Publisher thread (runs while server is running) ---
75 std::atomic<bool> publisher_running_{false};
76 std::thread publisher_thread_;
77 void publishFrameLoop();
78
79 // --- Cached JPEG for HTTP /image (written by publisher) ---
80 std::mutex image_cache_mutex_;
81 std::vector<uint8_t> cached_image_data_;
82 std::shared_ptr<DataFrame> cached_frame_;
83 int cached_display_width_{0}; // display dimensions (may differ from frame
84 int cached_display_height_{0}; // dimensions when JPEG mode uses downscaling)
85
86 // --- WebSocket streaming ---
87 std::mutex ws_mutex_;
88 std::set<httplib::ws::WebSocket*> websocket_clients_;
89 std::chrono::steady_clock::time_point last_ws_frame_time_{std::chrono::steady_clock::now()};
90
91 // --- Recording thread ---
92 std::atomic<bool> recording_active_{false};
93 std::atomic<bool> recorder_running_{false};
94 std::atomic<bool> recording_waiting_{false}; // true during delay/absolute countdown
95 std::thread recorder_thread_;
96 common::Queue<std::shared_ptr<DataFrame>> recording_queue_;
97 std::mutex recording_cv_mutex_;
98 std::condition_variable recording_cv_;
99 std::unique_ptr<FitsRecorder> fits_recorder_;
100
101 // Recording runtime config (may be overridden per-session via /recording/start)
102 RecordingConfig active_recording_config_;
103
104 // Recording progress (read by /recording/status)
105 std::atomic<int> recording_frames_target_{0};
106 std::atomic<int> recording_frames_done_{0};
107 std::atomic<size_t> recording_bytes_done_{0};
108 std::chrono::steady_clock::time_point recording_start_time_;
109 std::atomic<double> recording_wait_remaining_{0}; // seconds left in delay/absolute countdown
110
111 // Recording drop stats
112 std::atomic<uint32_t> recording_drop_count_{0};
113 std::chrono::steady_clock::time_point recording_last_drop_log_{std::chrono::steady_clock::now()};
114
115 // Written files (persisted after session ends for GUI listing)
116 std::mutex recording_files_mutex_;
117 std::vector<std::string> recording_written_files_;
118
119 void recorderLoop();
120 void startRecording(const RecordingConfig& cfg);
121 void stopRecording();
122
123 // --- Telemetry / monitoring thread ---
124 std::atomic<bool> telemetry_running_{false};
125 std::thread telemetry_thread_;
126 void telemetryLoop();
127
128 // Telemetry data (written by telemetry thread, read by HTTP handler)
129 struct TelemetrySample {
130 std::string value;
131 std::string type;
132 std::string camera_name; // Camera-native parameter name
133 std::string unit; // Unit (from parameter_registry, empty if not defined)
134 double timestamp{0}; // seconds since epoch
135 };
136 std::mutex telemetry_mutex_;
137 std::map<std::string, TelemetrySample> telemetry_current_;
138 // Parameters to sample (resolved at start from config + adapter)
139 std::vector<std::string> telemetry_params_;
140
141 // --- Acquisition statistics ---
142 struct SlidingWindowStats {
143 std::vector<double> samples;
144 int pos{0}; // write cursor
145 int count{0}; // number of valid samples (<= capacity)
146
147 void init(int capacity) { samples.resize(capacity, 0.0); pos = 0; count = 0; }
148 void push(double v) {
149 samples[pos] = v;
150 pos = (pos + 1) % static_cast<int>(samples.size());
151 if (count < static_cast<int>(samples.size())) count++;
152 }
153 struct Summary { double mean{0}; double stddev{0}; double min_val{0}; double max_val{0}; };
154 Summary compute() const {
155 if (count == 0) return {};
156 double sum = 0, mn = samples[0], mx = samples[0];
157 for (int i = 0; i < count; i++) {
158 double v = samples[i];
159 sum += v;
160 if (v < mn) mn = v;
161 if (v > mx) mx = v;
162 }
163 double mean = sum / count;
164 double sq_sum = 0;
165 for (int i = 0; i < count; i++) {
166 double d = samples[i] - mean;
167 sq_sum += d * d;
168 }
169 return {mean, (count > 1 ? std::sqrt(sq_sum / (count - 1)) : 0.0), mn, mx};
170 }
171 };
172
173 struct FrameStatistics {
174 SlidingWindowStats inter_frame; // inter-frame interval (ms)
175 SlidingWindowStats processing_latency; // time from receive to queue push (ms)
176 uint64_t frames_total{0};
177 uint64_t bytes_total{0};
178 uint64_t frames_dropped_capture{0};
179 uint64_t frames_dropped_recording{0};
180 std::chrono::steady_clock::time_point acquisition_start;
181 std::chrono::steady_clock::time_point last_frame_time;
182 bool has_last_frame{false};
183
184 // Publishing stats (display pipeline: JPEG encode + HTTP cache update)
185 SlidingWindowStats publish_interval; // inter-publish interval (ms)
186 SlidingWindowStats encode_time; // JPEG encoding duration (ms)
187 uint64_t frames_published{0};
188 uint64_t publish_bytes_total{0}; // cumulative JPEG bytes published
189 std::chrono::steady_clock::time_point last_publish_time;
190 bool has_last_publish{false};
191 };
192
193 std::mutex stats_mutex_;
194 FrameStatistics frame_stats_;
195 void resetStatistics();
196
197 // --- Helpers ---
198 static void jpegWriteCallback(void* context, void* data, int size);
199 std::vector<uint8_t> encodeFrameToJpeg(const DataFrame& frame, int quality,
200 int max_width, int max_height,
201 int& out_width, int& out_height);
202 std::vector<uint8_t> normalizeToUint8(const DataFrame& frame);
203 static std::vector<uint8_t> downscaleGray(const uint8_t* src, int src_w, int src_h,
204 int dst_w, int dst_h);
205};
206
207} // namespace camcom::server
208
209#endif
Definition queue.hpp:26
Definition camera_controller.hpp:22
void stop()
Definition server_impl.cpp:2768
CameraServer(const CameraServer &)=delete
CameraServer & operator=(const CameraServer &)=delete
bool start()
Definition server_impl.cpp:804
CameraServer(const ServerConfig &config)
Definition server_impl.cpp:183
~CameraServer()
Definition server_impl.cpp:188
bool isRunning() const
Definition server.hpp:53
const std::string & getServerId() const
Definition server.hpp:54
Header file for the CamCom Common Library.
Definition adapter_loader.cpp:11
Header file for the CamCom Common Library.
Main server configuration.
Definition config.hpp:157