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