UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
misc.cpp File Reference
#include "utils/misc.h"
#include <unistd.h>
#include <cassert>
#include <cctype>
#include <cerrno>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <stdexcept>
#include <string>
#include "compat/strings.h"
#include "debug.h"
#include "utils/macros.h"
#include "utils/color_out.h"
Include dependency graph for misc.cpp:

Go to the source code of this file.

Functions

const char * format_in_si_units (unsigned long long int val)
 
int get_cpu_core_count (void)
 
int get_framerate_d (double fps)
 
int get_framerate_n (double fps)
 
bool invalid_arg_is_numeric (const char *what)
 
bool is_arm_mac ()
 
bool is_wine ()
 
uint32_t parse_uint32 (const char *value_str) noexcept(false)
 
void print_module_usage (const char *module_name, const struct key_val *options, const struct key_val *options_full, bool print_full_help)
 
void ug_perror (const char *s)
 
const char * ug_strerror (int errnum)
 
long long unit_evaluate (const char *str, const char **endptr)
 
double unit_evaluate_dbl (const char *str, bool case_sensitive, const char **endptr)
 

Detailed Description

Function Documentation

◆ format_in_si_units()

const char * format_in_si_units ( unsigned long long int val)

Formats number in format "ABCD.E [S]" where 'S' is an SI unit prefix.

Definition at line 154 of file misc.cpp.

154 {
155 const char *si_prefixes[] = { "", "k", "M", "G", "T" };
156 int prefix_idx = 0;
157 int reminder = 0;
158 while (val > 10000) {
159 reminder = val % 1000;
160 val /= 1000;
161 prefix_idx += 1;
162 if (prefix_idx == sizeof si_prefixes / sizeof si_prefixes[0] - 1) {
163 break;
164 }
165 }
166 thread_local char buf[128];
167 snprintf(buf, sizeof buf, "%lld.%d %s", val, reminder / 100, si_prefixes[prefix_idx]);
168 return buf;
169}
int void * val

References val.

Referenced by replica::replica(), configure_with(), and main().

◆ get_cpu_core_count()

int get_cpu_core_count ( void )
Return values
numberof usable CPU cores or 1 if unknown

Definition at line 218 of file misc.cpp.

219{
220#ifdef _WIN32
221 SYSTEM_INFO sysinfo;
222 GetSystemInfo(&sysinfo);
223 return MIN(sysinfo.dwNumberOfProcessors, INT_MAX);
224#else
225 long numCPU = sysconf(_SC_NPROCESSORS_ONLN);
226 if (numCPU == -1) {
227 perror("sysconf(_SC_NPROCESSORS_ONLN)");
228 return 1;
229 }
230 return MIN(numCPU, INT_MAX);
231#endif
232}
#define MIN(a, b)
Definition macros.h:63

References MIN.

Referenced by av_to_uv_convert(), configure_video(), parallel_pix_conv(), respawn_parallel(), and vidcap_screen_x11_init().

◆ get_framerate_d()

int get_framerate_d ( double fps)

Definition at line 190 of file misc.cpp.

190 {
191 fps = fps - 0.00001; // we want to round halves down -> base for 10.5 could be 10 rather than 11
192 int fps_rounded_x1000 = round(fps) * 1000;
193 if (fabs(fps * 1001 - fps_rounded_x1000) <
194 fabs(fps * 1000 - fps_rounded_x1000)
195 && fps * 1000 < fps_rounded_x1000) {
196 return 1001;
197 } else {
198 return 1000;
199 }
200}
static __device__ vec3 round(const vec3 &v)
Definition cuda_dxt.cu:122

References round().

Referenced by configure_video(), display_ndi_reconfigure(), display_pw_reconfigure(), display_v4l2_reconfigure(), get_framerate_n(), get_framerate_test_2997(), get_framerate_test_3000(), get_framerate_test_free(), and vidcap_testcard_init().

Here is the call graph for this function:

◆ get_framerate_n()

int get_framerate_n ( double fps)

Definition at line 184 of file misc.cpp.

184 {
185 int denominator = get_framerate_d(fps);
186 return round(fps * denominator / 100.0) * 100.0; // rounding to 100s to fix inaccuracy errors
187 // eg. 23.98 * 1001 = 24003.98
188}
int get_framerate_d(double fps)
Definition misc.cpp:190

References get_framerate_d(), and round().

Referenced by configure_video(), display_ndi_reconfigure(), display_pw_reconfigure(), display_v4l2_reconfigure(), get_framerate_test_2997(), get_framerate_test_3000(), get_framerate_test_free(), and vidcap_testcard_init().

Here is the call graph for this function:

◆ invalid_arg_is_numeric()

bool invalid_arg_is_numeric ( const char * what)
Parameters
whatvalue returned by std::logic_error::what()
Returns
if given std::invalid_argument message belongs to a stoi/stof converison

Definition at line 340 of file misc.cpp.

340 {
341 if (what == nullptr) {
342 return false;
343 }
344 return strncmp(what, "stoi", 4) == 0 || strncmp(what, "stod", 4) == 0;
345}

Referenced by display_decklink_init(), main(), and parse_options().

◆ is_arm_mac()

bool is_arm_mac ( void )

Checks whether host machine is an ARM Mac (native or running x86_64 code with Rosetta2)

Definition at line 315 of file misc.cpp.

315 {
316#ifdef __APPLE__
317 char machine[256];
318 size_t len = sizeof machine;
319 if (sysctlbyname("hw.machine", &machine, &len, NULL, 0) != 0) {
320 perror("sysctlbyname hw.machine");
321 return false;
322 }
323 int proc_translated = -1; // Rosetta2 - 0 off, 1 on; sysctl ENOENT - x86_64 mac
324 len = sizeof proc_translated;
325 if (int ret = sysctlbyname("sysctl.proc_translated", &proc_translated, &len, NULL, 0); ret != 0 && errno != ENOENT) {
326 perror("sysctlbyname sysctl.proc_translated");
327 }
328 return strstr(machine, "arm") != NULL || proc_translated == 1;
329#else
330 return false;
331#endif
332}
int void size_t * len

References len.

◆ is_wine()

bool is_wine ( void )

Definition at line 172 of file misc.cpp.

172 {
173#ifdef _WIN32
174 HMODULE hntdll = GetModuleHandle("ntdll.dll");
175 if(!hntdll) {
176 return false;
177 }
178
179 return GetProcAddress(hntdll, "wine_get_version");
180#endif
181 return false;
182}

Referenced by udp_init_if().

◆ parse_uint32()

uint32_t parse_uint32 ( const char * value_str)

Definition at line 296 of file misc.cpp.

297{
298 size_t pos = 0;
299 long long val = stoll(value_str, &pos);
300 if (val < 0) {
301 throw out_of_range("negative number");
302 }
303 if (val > UINT32_MAX) {
304 throw out_of_range("higher value than range of uint32");
305 }
306 if (pos == 0) {
307 throw invalid_argument("no conversion was performed");
308 }
309 return val;
310}

References val.

Referenced by settings_init().

◆ print_module_usage()

void print_module_usage ( const char * module_name,
const struct key_val * options,
const struct key_val * options_full,
bool print_full_help )

Prints module usage in unified format.

Parameters
module_namemodule name including command-line parameter (eg. "-t syphon")
optionsaccepted options (may be NULL if no options are accepted)
options_fulloptions that are shown only if fullhelp is requested (NULL if none)
printf_full_helpwhether to print options_full

Definition at line 242 of file misc.cpp.

242 {
243 UNUSED(options_full), UNUSED(print_full_help);
244 struct key_val nullopts[] = { { nullptr, nullptr } };
245 if (options == nullptr) {
246 options = nullopts;
247 }
248 std::ostringstream oss;
249 oss << TERM_BOLD << TERM_FG_RED << module_name << TERM_FG_RESET;
250 int max_key_len = 0;
251 auto desc_key = [](const char *key) {
252 // print only <val> for key=<val> if right side is "simple" (mandatory and without further opts like "key=<val>:opt=<o>")
253 if (const char *k = strchr(key, '='); k != nullptr && strpbrk(key, "[:") == nullptr) {
254 key = k + 1;
255 }
256 return key;
257 };
258 bool first = true;
259 auto add_opt = [&](const struct key_val *it) {
260 if (first) {
261 oss << "[";
262 first = false;
263 } else {
264 oss << "|";
265 }
266 max_key_len = MAX(max_key_len, (int) strlen(desc_key(it->key)));
267 oss << ":" << it->key;
268 };
269 for (const auto *it = options; it->key != nullptr; ++it) {
270 add_opt(it);
271 }
272 if (print_full_help && options_full) {
273 for (const auto *it = options_full; it->key != nullptr; ++it) {
274 add_opt(it);
275 }
276 }
277 if (!first) { // == has at least one option
278 oss << "] | " << module_name << (options_full ? ":[full]help" : ":help") << TERM_RESET;
279 }
280
281 color_printf("Usage:\n\t%s\n", oss.str().c_str());
282 if (first) { // no opts
283 return;
284 }
285 color_printf("where\n");
286 for (const auto *it = options; it->key != nullptr; ++it) {
287 color_printf("\t" TBOLD("%*s") " - %s\n", max_key_len, desc_key(it->key), it->val);
288 }
289 if (print_full_help && options_full) {
290 for (const auto *it = options_full; it->key != nullptr; ++it) {
291 color_printf("\t" TBOLD("%*s") " - %s\n", max_key_len, desc_key(it->key), it->val);
292 }
293 }
294}
#define UNUSED(x)
int color_printf(const char *format,...)
#define TERM_BOLD
Definition color_out.h:48
#define TERM_FG_RED
Definition color_out.h:50
#define TERM_RESET
Definition color_out.h:47
#define TERM_FG_RESET
Definition color_out.h:59
#define TBOLD(x)
Definition color_out.h:70
#define MAX(a, b)
Definition macros.h:65
codec_t first
Definition sdl2.c:423
Definition misc.h:68
Definition rtp.c:253
const char * key
Definition cineform.cpp:125

References color_printf(), first, key, key_val::key, MAX, TBOLD, TERM_BOLD, TERM_FG_RED, TERM_FG_RESET, TERM_RESET, and UNUSED.

Referenced by audio_cap_testcard_init(), display_dummy_init(), and usage().

Here is the call graph for this function:

◆ ug_perror()

void ug_perror ( const char * s)

Definition at line 213 of file misc.cpp.

213 {
214 log_msg(LOG_LEVEL_ERROR, "%s: %s\n", s, ug_strerror(errno));
215}
void log_msg(int level, const char *format,...)
Definition debug.cpp:130
#define LOG_LEVEL_ERROR
general errors
Definition debug.h:59
const char * ug_strerror(int errnum)
Definition misc.cpp:203

References LOG_LEVEL_ERROR, log_msg(), and ug_strerror().

Referenced by process_data_chunk(), and read_ds64().

Here is the call graph for this function:

◆ ug_strerror()

const char * ug_strerror ( int errnum)
Note
consider using rather strerror_s() directly

Definition at line 203 of file misc.cpp.

204{
205 enum {
206 STRERROR_BUF_LEN = 1024,
207 };
208 static thread_local char strerror_buf[STRERROR_BUF_LEN];
209 strerror_s(strerror_buf, sizeof strerror_buf, errnum); // C11 Annex K (bounds-checking interfaces)
210 return strerror_buf;
211}
#define strerror_s(buf, bufsz, errnum)
Definition strings.h:66

References strerror_s.

Referenced by audio_export_thread(), create_implicit_dir(), display_v4l2_init(), display_v4l2_probe(), gen_sdp(), log_perror(), rtcp_udp_send(), rtp_send_data_hdr(), set_output_buffering(), show_help(), testcard_load_from_file(), and ug_perror().

◆ unit_evaluate()

long long unit_evaluate ( const char * str,
const char ** endptr )

Converts units in format <val>[.<val>][kMG] to integral representation.

Parameters
strstring to be parsed
endptrif not NULL, point to suffix after parse
Returns
positive integral representation of the string
LLONG_MIN if error

Definition at line 81 of file misc.cpp.

82{
83 double ret = unit_evaluate_dbl(str, false, endptr);
84
85 if (ret == NAN || ret >= nexttoward((double) LLONG_MAX, LLONG_MAX)) {
86 return LLONG_MIN;
87 }
88
89 return ret;
90}
double unit_evaluate_dbl(const char *str, bool case_sensitive, const char **endptr)
Definition misc.cpp:102

References unit_evaluate_dbl().

Referenced by fec_check_messages(), parse_audio_codec_params(), parse_audio_format(), and parse_bitrate().

Here is the call graph for this function:

◆ unit_evaluate_dbl()

double unit_evaluate_dbl ( const char * str,
bool case_sensitive,
const char ** endptr )

Converts units in format <val>[.<val>][kMG] to floating point representation.

Parameters
strstring to be parsed, suffix following SI suffix is ignored (as in 1ms or 100MB)
case_sensitiveif true 'm' will be considered as milli, otherwise mega
endptrif not NULL, point to suffix after parse
Returns
positive floating point representation of the string
NAN if error

Definition at line 102 of file misc.cpp.

103{
104 char *endptr_tmp = nullptr;
105 errno = 0;
106 double ret = strtod(str, &endptr_tmp);
107 if (errno != 0) {
108 perror("strtod");
109 return NAN;
110 }
111 if (endptr_tmp == str) {
112 log_msg(LOG_LEVEL_ERROR, "'%s' is not a number\n", str);
113 return NAN;
114 }
115 char unit_prefix = case_sensitive ? *endptr_tmp : toupper(*endptr_tmp);
116 endptr_tmp += 1;
117 switch(unit_prefix) {
118 case 'n':
119 case 'N':
120 ret /= 1000'000'000;
121 break;
122 case 'u':
123 case 'U':
124 ret /= 1000'000;
125 break;
126 case 'm':
127 ret /= 1000;
128 break;
129 case 'k':
130 case 'K':
131 ret *= 1000;
132 break;
133 case 'M':
134 ret *= 1000'000LL;
135 break;
136 case 'g':
137 case 'G':
138 ret *= 1000'000'000LL;
139 break;
140 default:
141 endptr_tmp -= 1;
142 }
143
144 if (endptr != nullptr) {
145 *endptr = endptr_tmp;
146 }
147
148 return ret;
149}

References LOG_LEVEL_ERROR, and log_msg().

Referenced by decompress_thread(), j2k_decompress_init(), and unit_evaluate().

Here is the call graph for this function: