24#include "configuration.hpp"
26#include <mediapipe/framework/port/logging.h>
27#include <mediapipe/framework/port/opencv_core_inc.h>
28#include <mediapipe/framework/port/opencv_highgui_inc.h>
29#include <mediapipe/framework/formats/image_frame.h>
30#include <mediapipe/framework/formats/image_frame_opencv.h>
31#include <physiology/graph/stream_and_packet_names.h>
33#include "container.hpp"
34#include "initialization.hpp"
35#include "image_transfer.hpp"
36#include "packet_helpers.hpp"
37#include "benchmarking.hpp"
38#include "keyboard_input.hpp"
39#include "json_file_io.hpp"
44namespace pi = platform_independence;
45namespace init = initialization;
46namespace keys = keyboard_input;
47namespace ph = packet_helpers;
48namespace it = image_transfer;
49namespace bench = benchmarking;
51template<platform_independence::DeviceType TDeviceType, settings::OperationMode TOperationMode, settings::IntegrationMode TIntegrationMode>
53 settings(std::move(settings)),
56 operation_context(settings.operation),
57 status(physiology::BuildStatusValue(physiology::StatusCode::PROCESSING_NOT_STARTED,
58 std::chrono::duration_cast<std::chrono::microseconds>(
59 std::chrono::system_clock::now().time_since_epoch()).count()
64 platform_independence::DeviceType TDeviceType,
65 settings::OperationMode TOperationMode,
66 settings::IntegrationMode TIntegrationMode
69 if (this->initialized) {
71 return absl::OkStatus();
74 static_assert(CV_MAJOR_VERSION > 4 || (CV_MAJOR_VERSION >= 4 && CV_MINOR_VERSION >= 2),
75 "OpenCV 4.2 or above is required");
79 init::InitializeGraph<TDeviceType>(this->graph,
82 this->settings.binary_graph)
84 MP_RETURN_IF_ERROR(init::InitializeComputingDevice<TDeviceType>(this->graph, this->device_context));
87 return absl::OkStatus();
91template<platform_independence::DeviceType TDeviceType, settings::OperationMode TOperationMode, settings::IntegrationMode TIntegrationMode>
93 return settings::AbslUnparseFlag(TIntegrationMode);
97template<platform_independence::DeviceType TDeviceType, settings::OperationMode TOperationMode, settings::IntegrationMode TIntegrationMode>
102template<platform_independence::DeviceType TDeviceType, settings::OperationMode TOperationMode, settings::IntegrationMode TIntegrationMode>
103absl::StatusOr<std::filesystem::path>
105 std::string device_type = pi::AbslUnparseFlag(TDeviceType);
106 std::string operation_mode = settings::AbslUnparseFlag(TOperationMode);
108 std::string extension = binary_graph ?
".binarypb" :
".pbtxt";
110 std::filesystem::path graph_directory = PHYSIOLOGY_EDGE_GRAPH_DIRECTORY;
111 auto graph_file_path = graph_directory /
112 (prefix +
"_" + device_type +
"_" + operation_mode +
"_" + third_graph_suffix + extension);
113 if (this->settings.verbosity_level > 1) {
114 LOG(INFO) <<
"Retrieving graph from path: " << graph_file_path.string();
116 return graph_file_path;
120template<
typename TCallback>
121absl::Status CheckCallbackNotNull(
const TCallback& callback) {
122 if (callback ==
nullptr) {
123 return absl::InvalidArgumentError(
124 "Callback cannot be nullptr."
127 return absl::OkStatus();
131 platform_independence::DeviceType TDeviceType,
132 settings::OperationMode TOperationMode,
133 settings::IntegrationMode TIntegrationMode
136 const std::function<absl::Status(physiology::StatusValue)>& on_status_change
138 MP_RETURN_IF_ERROR(CheckCallbackNotNull(on_status_change));
139 this->OnStatusChange = on_status_change;
140 return absl::OkStatus();
144 platform_independence::DeviceType TDeviceType,
145 settings::OperationMode TOperationMode,
146 settings::IntegrationMode TIntegrationMode
149 const std::function<absl::Status(physiology::StatusValue)>& on_status_code
151 MP_RETURN_IF_ERROR(CheckCallbackNotNull(on_status_code));
152 this->OnStatusCode = on_status_code;
153 return absl::OkStatus();
157 platform_independence::DeviceType TDeviceType,
158 settings::OperationMode TOperationMode,
159 settings::IntegrationMode TIntegrationMode
161absl::Status Container<TDeviceType, TOperationMode, TIntegrationMode>::SetOnEdgeMetricsOutput(
162 const std::function<absl::Status(
const physiology::Metrics&, int64_t input_timestamp)>& on_edge_metrics_output
164 MP_RETURN_IF_ERROR(CheckCallbackNotNull(on_edge_metrics_output));
165 this->OnEdgeMetricsOutput = on_edge_metrics_output;
166 return absl::OkStatus();
170 platform_independence::DeviceType TDeviceType,
171 settings::OperationMode TOperationMode,
172 settings::IntegrationMode TIntegrationMode
175 const std::function<absl::Status(
const physiology::MetricsBuffer&, int64_t input_timestamp)>& on_core_metrics_output
177 MP_RETURN_IF_ERROR(CheckCallbackNotNull(on_core_metrics_output));
178 this->OnCoreMetricsOutput = on_core_metrics_output;
179 return absl::OkStatus();
183 platform_independence::DeviceType TDeviceType,
184 settings::OperationMode TOperationMode,
185 settings::IntegrationMode TIntegrationMode
187absl::Status Container<TDeviceType, TOperationMode, TIntegrationMode>::SetOnVideoOutput(
188 const std::function<absl::Status(cv::Mat&, int64_t)>& on_video_output
190 MP_RETURN_IF_ERROR(CheckCallbackNotNull(on_video_output));
191 this->OnVideoOutput = on_video_output;
192 return absl::OkStatus();
196 platform_independence::DeviceType TDeviceType,
197 settings::OperationMode TOperationMode,
198 settings::IntegrationMode TIntegrationMode
201 const std::function<absl::Status(
bool, int64_t)>& on_dropped_frame
203 MP_RETURN_IF_ERROR(CheckCallbackNotNull(on_dropped_frame));
204 this->OnFrameSentThrough = on_dropped_frame;
205 return absl::OkStatus();
209 platform_independence::DeviceType TDeviceType,
210 settings::OperationMode TOperationMode,
211 settings::IntegrationMode TIntegrationMode
214 const std::function<absl::Status(
double,
double, int64_t)>& on_effective_core_fps_output
216 MP_RETURN_IF_ERROR(CheckCallbackNotNull(on_effective_core_fps_output));
217 this->OnCorePerformanceTelemetry = on_effective_core_fps_output;
218 return absl::OkStatus();
223 platform_independence::DeviceType TDeviceType,
224 settings::OperationMode TOperationMode,
225 settings::IntegrationMode TIntegrationMode
228 if (this->OnCorePerformanceTelemetry.has_value() && this->recording) {
230 if (!offset_from_system_time.has_value()) {
231 double current_system_seconds =
232 std::chrono::duration<double>(std::chrono::system_clock::now().time_since_epoch()).count();
233 offset_from_system_time = current_system_seconds - timestamp.Seconds();
235 this->frames_in_graph_timestamps.insert(timestamp.Value());
247 platform_independence::DeviceType TDeviceType,
248 settings::OperationMode TOperationMode,
249 settings::IntegrationMode TIntegrationMode
252 const physiology::MetricsBuffer& metrics_buffer
254 if (this->OnCorePerformanceTelemetry.has_value()) {
255 double current_system_seconds =
256 std::chrono::duration<double>(std::chrono::system_clock::now().time_since_epoch()).count();
258 auto last_buffer_input_timestamp = metrics_buffer.metadata().frame_timestamp();
259 auto last_buffer_input_timestamp_location =
260 this->frames_in_graph_timestamps.find(last_buffer_input_timestamp);
261 auto first_buffer_input_timestamp = *this->frames_in_graph_timestamps.begin();
268 this->frames_in_graph_timestamps.erase(this->frames_in_graph_timestamps.begin(),
269 last_buffer_input_timestamp_location);
272 double absolute_last_output_system_seconds =
273 mediapipe::Timestamp(last_buffer_input_timestamp).Seconds() + offset_from_system_time.value();
274 double buffer_latency_seconds = current_system_seconds - absolute_last_output_system_seconds;
277 this->metrics_buffer_benchmarking_info_buffer.push_back(
278 MetricsBufferBenchmarkingInfo{
279 first_buffer_input_timestamp,
280 last_buffer_input_timestamp,
281 metrics_buffer.metadata().frame_count(),
282 buffer_latency_seconds
288 auto metrics_buffer_benchmarking_info_location =
289 this->metrics_buffer_benchmarking_info_buffer.begin();
290 auto current_window_start = last_buffer_input_timestamp - this->fps_averaging_window_microseconds;
291 while (metrics_buffer_benchmarking_info_location != this->metrics_buffer_benchmarking_info_buffer.end()
292 && metrics_buffer_benchmarking_info_location->last_timestamp < current_window_start) {
293 metrics_buffer_benchmarking_info_location++;
295 if (metrics_buffer_benchmarking_info_location > this->metrics_buffer_benchmarking_info_buffer.begin() + 1) {
296 this->metrics_buffer_benchmarking_info_buffer.erase(this->metrics_buffer_benchmarking_info_buffer.begin(),
297 metrics_buffer_benchmarking_info_location--);
301 int64_t window_total_microseconds =
302 last_buffer_input_timestamp - this->metrics_buffer_benchmarking_info_buffer.begin()->first_timestamp;
303 int32_t window_frame_count = 0;
304 double aggregate_latency_seconds = 0.0;
305 for (
const auto& buffer_benchmarking_info: this->metrics_buffer_benchmarking_info_buffer) {
306 window_frame_count += buffer_benchmarking_info.frame_count;
307 aggregate_latency_seconds += buffer_benchmarking_info.latency_seconds;
312 double effective_core_fps =
313 static_cast<double>(window_frame_count - 1) * 1000000.0 /
314 static_cast<double>(window_total_microseconds);
316 double effective_core_latency_seconds =
317 aggregate_latency_seconds / this->metrics_buffer_benchmarking_info_buffer.size();
319 MP_RETURN_IF_ERROR(this->OnCorePerformanceTelemetry.value()(
320 effective_core_fps, effective_core_latency_seconds, first_buffer_input_timestamp
324 return absl::OkStatus();
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 ×tamp)
Definition container_impl.hpp:227
Definition background_container.cpp:10