SmartSpectra C++ SDK
Measure human vitals from video with SmartSpectra C++ SDK.
Loading...
Searching...
No Matches
packet_helpers.hpp
1
2// packet_helpers.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// === standard library includes (if any) ===
23// === third-party includes (if any) ===
24#include <mediapipe/framework/output_stream_poller.h>
25#include <physiology/modules/messages/status.h>
26#include <google/protobuf/message.h>
27// === local includes (if any) ===
28
29namespace presage::smartspectra::container::packet_helpers {
30
31// Generic operator<< for protobuf messages
32// Allows streaming any protobuf message using ShortDebugString()
33template <typename T, typename = std::enable_if_t<std::is_base_of<google::protobuf::Message, T>::value>>
34std::ostream& operator<<(std::ostream& os, const T& proto) {
35 return os << proto.DebugString();
36}
37
38// Lightweight operator<< for std::pair to support simple debug logging
39template <typename A, typename B>
40inline std::ostream& operator<<(std::ostream& os, const std::pair<A, B>& p) {
41 os << "(" << p.first << ", " << p.second << ")";
42 return os;
43}
44
45// functional predicate, with grabbing packet timestamp
46template<typename TPacketContentsType, typename TReportPredicate, bool TPrintTimestamp = false>
47inline absl::Status GetPacketContentsIfAny(
48 TPacketContentsType& contents,
49 bool& nonempty_packet_received,
50 mediapipe::OutputStreamPoller& poller,
51 const char* stream_name,
52 mediapipe::Timestamp& timestamp,
53 TReportPredicate&& report_if
54) {
55 nonempty_packet_received = false;
56 if (poller.QueueSize() > 0) {
57 mediapipe::Packet packet;
58 if (!poller.Next(&packet)) {
59 return absl::UnknownError(
60 "Failed to get packet from output stream " + std::string(stream_name) + ".");
61 } else {
62 if (!packet.IsEmpty()) {
63 nonempty_packet_received = true;
64 contents = packet.Get<TPacketContentsType>();
65 std::string extra_information = "";
66 timestamp = packet.Timestamp();
67 if (TPrintTimestamp) {
68 extra_information = " (timestamp: " + std::to_string(timestamp.Value()) + ")";
69 }
70 if (report_if()) {
71 LOG(INFO) << "Got " + std::string(stream_name) + " packet: " << contents << extra_information;
72 }
73 }
74 }
75 }
76 return absl::OkStatus();
77}
78
79// functional predicate, without grabbing packet timestamp
80template<typename TPacketContentsType, typename TReportPredicate, bool TPrintTimestamp = false>
81inline absl::Status GetPacketContentsIfAny(
82 TPacketContentsType& contents,
83 bool& nonempty_packet_received,
84 mediapipe::OutputStreamPoller& poller,
85 const char* stream_name,
86 TReportPredicate&& report_if
87) {
88 mediapipe::Timestamp timestamp;
89 return GetPacketContentsIfAny<TPacketContentsType, TReportPredicate, TPrintTimestamp>(
90 contents, nonempty_packet_received, poller, stream_name, timestamp, std::forward<TReportPredicate>(report_if)
91 );
92}
93
94// constant boolean predicate, with grabbing packet timestamp
95template<typename TPacketContentsType>
96inline absl::Status GetPacketContentsIfAny(
97 TPacketContentsType& contents,
98 bool& nonempty_packet_received,
99 mediapipe::OutputStreamPoller& poller,
100 const char* string_name,
101 mediapipe::Timestamp& timestamp,
102 bool report_on_package_retrieval
103) {
104 return GetPacketContentsIfAny(
105 contents, nonempty_packet_received, poller, string_name, timestamp, [&report_on_package_retrieval]() {
106 return report_on_package_retrieval;
107 }
108 );
109}
110
111// constant boolean predicate, without grabbing packet timestamp
112template<typename TPacketContentsType>
113inline absl::Status GetPacketContentsIfAny(
114 TPacketContentsType& contents,
115 bool& nonempty_packet_received,
116 mediapipe::OutputStreamPoller& poller,
117 const char* string_name,
118 bool report_on_package_retrieval
119) {
120 mediapipe::Timestamp timestamp;
121 return GetPacketContentsIfAny(
122 contents, nonempty_packet_received, poller, string_name, timestamp, [&report_on_package_retrieval]() {
123 return report_on_package_retrieval;
124 }
125 );
126}
127
128} // namespace presage::smartspectra::container::packet_helpers