SmartSpectra C++ SDK
Measure human vitals from video with SmartSpectra C++ SDK.
Loading...
Searching...
No Matches
container.hpp
1
2// container.h
3// Created by Greg on 2/16/2024.
4// Copyright (C) 2024 Presage Security, Inc.
5//
6// This program is free software; you can redistribute it and/or
7// modify it under the terms of the GNU Lesser General Public
8// License as published by the Free Software Foundation; either
9// version 3 of the License, or (at your option) any later version.
10//
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14// Lesser General Public License for more details.
15//
16// You should have received a copy of the GNU Lesser General Public License
17// along with this program; if not, write to the Free Software Foundation,
18// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
21#pragma once
22// === configuration header ===
23#include <physiology/modules/configuration.h>
24// === standard library includes ===
25#include <functional>
26#include <filesystem>
27// === third-party includes (if any) ===
28#include <absl/status/status.h>
29#include <absl/status/statusor.h>
30#include <mediapipe/framework/calculator_graph.h>
31#include <mediapipe/framework/port/opencv_core_inc.h>
32#include <physiology/modules/device_type.h>
33#include <physiology/modules/device_context.h>
34#include <physiology/modules/messages/status.h>
35#include <physiology/modules/messages/metrics.h>
36// === local includes (if any) ===
37#include "settings.hpp"
38#include "operation_context.hpp"
39
48
51
52template<
53 platform_independence::DeviceType TDeviceType,
54 settings::OperationMode TOperationMode,
55 settings::IntegrationMode TIntegrationMode
56>
64class Container {
65public:
67
71 explicit Container(SettingsType settings);
72
76 absl::Status SetOnStatusChange(const std::function<absl::Status(physiology::StatusValue)>& on_status_change);
77
82 absl::Status SetOnStatusCode(const std::function<absl::Status(physiology::StatusValue)>& on_status_code);
83
84 absl::Status SetOnEdgeMetricsOutput(
85 const std::function<absl::Status(const physiology::Metrics&, int64_t input_timestamp)>& on_edge_metrics_output
86 );
87
91 absl::Status SetOnCoreMetricsOutput(
92 const
93 std::function<absl::Status(const physiology::MetricsBuffer&, int64_t input_timestamp)>& on_core_metrics_output
94 );
95
96 absl::Status SetOnVideoOutput(
97 const std::function<absl::Status(cv::Mat& output_frame, int64_t input_timestamp)>& on_video_output
98 );
99
103 absl::Status SetOnFrameSentThrough(
104 const std::function<absl::Status(bool frame_sent_through, int64_t input_timestamp)>& on_dropped_frame
105 );
106
111 const std::function<absl::Status(double, double, int64_t)>& on_effective_core_fps_output
112 );
113
117 virtual absl::Status Initialize();
118
119protected:
121 virtual std::string GetThirdGraphFileSuffix() const;
122
124 virtual std::string GetGraphFilePrefix() const;
125
131 absl::StatusOr<std::filesystem::path> GetGraphFilePath(bool binary_graph = true) const;
132
134 absl::Status ComputeCorePerformanceTelemetry(const physiology::MetricsBuffer& metrics_buffer);
135
137 void AddFrameTimestampToBenchmarkingInfo(const mediapipe::Timestamp& timestamp);
138
139// ==== settings
140// TODO: maybe figure out how to make `settings` `const` again?
141 SettingsType settings;
142
143// ==== state
144 mediapipe::CalculatorGraph graph;
145// == fixed/static after initialization
146
147 // if needed, set to a callback that handles preprocessing status changes
148 std::function<absl::Status(physiology::StatusValue)> OnStatusChange =
149 [](physiology::StatusValue status) { return absl::OkStatus(); };
150
151 // if needed, set to a callback that handles ALL status code updates (not just changes)
152 std::function<absl::Status(physiology::StatusValue)> OnStatusCode =
153 [](physiology::StatusValue status) { return absl::OkStatus(); };
154
155 // if needed, set to a callback that handles new metrics output from edge / local processing
156 std::function<absl::Status(const physiology::Metrics&, int64_t input_timestamp)> OnEdgeMetricsOutput =
157 [](const physiology::Metrics&, int64_t input_timestamp) { return absl::OkStatus(); };
158
159 // if needed, set to a callback that handles new metrics output from core / API
160 std::function<absl::Status(const physiology::MetricsBuffer&, int64_t input_timestamp)> OnCoreMetricsOutput =
161 [](const physiology::MetricsBuffer&, int64_t input_timestamp) { return absl::OkStatus(); };
162
163 // if needed, set to a callback that handles video frames after they get preprocessed on the edge / in SDK
164 std::function<absl::Status(cv::Mat& output_frame, int64_t input_timestamp)> OnVideoOutput =
165 [](cv::Mat& output_frame, int64_t input_timestamp) { return absl::OkStatus(); };
166
167 // if needed, set to a callback that handles frame sent-through-graph / dropped-from-graph events,
168 // e.g., logs them somewhere.
169 std::function<absl::Status(bool frame_sent_through, int64_t input_timestamp)> OnFrameSentThrough =
170 [](bool frame_sent_through, int64_t input_timestamp) { return absl::OkStatus(); };
171
172 // for benchmarking
173 std::optional<std::function<absl::Status(double fps, double latency_s, int64_t input_timestamp)>>
174 OnCorePerformanceTelemetry = std::nullopt;
175
176 platform_independence::DeviceContext<TDeviceType> device_context;
177 bool initialized = false;
178 bool running = false;
179// == dynamic/changing during runtime
180 physiology::StatusValue status;
181 bool recording = false;
182
183 // for video output (optional)
184 cv::Mat output_frame_bgr;
185 OperationContext<TOperationMode> operation_context;
186
187private:
188 // benchmarking
189 std::set<int64_t> frames_in_graph_timestamps;
190 const int64_t fps_averaging_window_microseconds = 3 * 1000000; // 3 seconds
191 struct MetricsBufferBenchmarkingInfo {
192 int64_t first_timestamp = 0;
193 int64_t last_timestamp = 0;
194 int32_t frame_count = 0;
195 double latency_seconds = 0;
196 };
197 std::vector<MetricsBufferBenchmarkingInfo> metrics_buffer_benchmarking_info_buffer;
198 std::optional<double> offset_from_system_time = std::nullopt;
199};
200
201} // namespace presage::smartspectra::container
Container(SettingsType settings)
Definition container_impl.hpp:52
absl::Status SetOnStatusChange(const std::function< absl::Status(physiology::StatusValue)> &on_status_change)
Definition container_impl.hpp:135
absl::Status ComputeCorePerformanceTelemetry(const physiology::MetricsBuffer &metrics_buffer)
Definition container_impl.hpp:251
absl::Status SetOnCoreMetricsOutput(const std::function< absl::Status(const physiology::MetricsBuffer &, int64_t input_timestamp)> &on_core_metrics_output)
Definition container_impl.hpp:174
absl::Status SetOnCorePerformanceTelemetry(const std::function< absl::Status(double, double, int64_t)> &on_effective_core_fps_output)
Definition container_impl.hpp:213
absl::Status SetOnFrameSentThrough(const std::function< absl::Status(bool frame_sent_through, int64_t input_timestamp)> &on_dropped_frame)
Definition container_impl.hpp:200
virtual std::string GetThirdGraphFileSuffix() const
Definition container_impl.hpp:92
virtual std::string GetGraphFilePrefix() const
Definition container_impl.hpp:98
virtual absl::Status Initialize()
Definition container_impl.hpp:68
absl::StatusOr< std::filesystem::path > GetGraphFilePath(bool binary_graph=true) const
Definition container_impl.hpp:104
absl::Status SetOnStatusCode(const std::function< absl::Status(physiology::StatusValue)> &on_status_code)
Definition container_impl.hpp:148
void AddFrameTimestampToBenchmarkingInfo(const mediapipe::Timestamp &timestamp)
Definition container_impl.hpp:227
Helper for managing polling of operation-specific graph streams.
Definition operation_context.hpp:36
Definition background_container.cpp:10