59#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 27
60#include <sys/syscall.h>
121#if defined HAVE_X || defined BUILD_LIBRARIES
128#define X11_LIB_NAME "libX11.so.6"
132#define restrict __restrict
142#define MOD_NAME "[host] "
151using std::make_tuple;
160using std::unordered_map;
161using std::unique_lock;
189#if defined HAVE_CUDA && defined _WIN32
191extern "C" int _fltused = 0;
206#if defined BUILD_LIBRARIES
207 for (
auto a :
init->opened_libs) {
223#if defined CUDA_DEVICE_RESET
232 "* stdout-buf={no|line|full}\n"
233 " Buffering for stdout\n");
235 "* stderr-buf={no|line|full}\n"
236 " Buffering for stderr\n");
238 const unordered_map<const char *, pair<FILE *, int>> outs = {
240 {
"stdout-buf", pair{stdout, _IONBF} },
242 {
"stdout-buf", pair{stdout, _IOLBF} },
244 {
"stderr-buf", pair{stderr, _IONBF} }
246 for (
const auto& outp : outs) {
247 int mode = outp.second.second;
255 const unordered_map<string, int> buf_map {
256 {
"no", _IONBF }, {
"line", _IOLBF }, {
"full", _IOFBF }
260 printf(
"Available values for buffering are \"no\", \"line\" and \"full\"\n");
264 if (it == buf_map.end()) {
270 if (setvbuf(outp.second.first, NULL,
mode, BUFSIZ) != 0) {
283static int x11_error_handler(Display *d, XErrorEvent *e) {
288 e->error_code, e->serial, e->error_code, e->request_code, e->minor_code);
289 fprintf(stderr,
"Backtrace:\n");
290 array<void *, 256> addresses{};
291 int num_symbols = backtrace(addresses.data(), addresses.size());
292 backtrace_symbols_fd(addresses.data(), num_symbols, 2);
303 array<void *, 1> addresses{};
304 backtrace(addresses.data(), addresses.size());
328 if (strcmp(optarg,
"help") == 0) {
330 TBOLD(
"--conv-policy")
" specifies the order in which various pixfmt properties are to be evaluated "
331 "if some pixel format needs conversion to another suitable pixel format.";
336 color_printf(
"\nDefault: \"" TBOLD(
"dsc")
"\" - first is respected bit-depth, then subsampling and finally color space\n\n"
337 "Permute the above letters to change the default order, eg. \"" TBOLD(
"cds")
"\" to attempt to keep colorspace.\n");
344 if (strchr(optarg,
'd') == NULL || strchr(optarg,
's') == NULL || strchr(optarg,
'c') == NULL) {
359 char *log_opt =
nullptr;
360 static struct option getopt_options[] = {
361 {
"param", required_argument,
nullptr,
'O'},
362 {
"verbose", optional_argument,
nullptr,
'V'},
363 {
nullptr, 0,
nullptr, 0 }
365 const char *
const optstring =
"+O:V";
366 int saved_opterr = opterr;
370 bool logger_skip_repeats =
true;
374 while (optind < argc) {
376 getopt_long(argc, argv, optstring, getopt_options,
nullptr);
379 if (optarg !=
nullptr) {
401 opterr = saved_opterr;
402 if (logging_lvl == 0) {
403 logging_lvl = getenv(
"ULTRAGRID_VERBOSE") !=
nullptr && strlen(getenv(
"ULTRAGRID_VERBOSE")) > 0 ?
LOG_LEVEL_VERBOSE :
log_level;
407 if (log_opt !=
nullptr && !
parse_log_cfg(log_opt, &logging_lvl, &logger_skip_repeats, &logger_show_timestamps)) {
419 while (*argv !=
nullptr) {
420 if (strstr(*argv, tok) !=
nullptr) {
432 fprintf(stderr,
"exit() called unexpectedly! Maybe by some library?\n");
448 std::clog.rdbuf(std::cout.rdbuf());
452 void *handle = dlopen(X11_LIB_NAME, RTLD_NOW);
455 Status (*XInitThreadsProc)();
456 XInitThreadsProc = (Status (*)()) dlsym(handle,
"XInitThreads");
457 if (XInitThreadsProc) {
458 Status s = XInitThreadsProc();
466 typedef int (*XSetErrorHandler_t(
int (*handler)(Display *, XErrorEvent *)))();
467 XSetErrorHandler_t *XSetErrorHandlerProc;
468 XSetErrorHandlerProc = (XSetErrorHandler_t *) dlsym(handle,
"XSetErrorHandler");
469 if (XSetErrorHandlerProc) {
470 XSetErrorHandlerProc(x11_error_handler);
484 int err = WSAStartup(MAKEWORD(2, 2), &wsaData);
486 fprintf(stderr,
"WSAStartup failed with error %d.", err);
489 if(LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
490 fprintf(stderr,
"Counld not found usable version of Winsock.\n");
495 SetConsoleOutputCP(CP_UTF8);
499 const bool init_com = !
tok_in_argv(argv,
"screen:unregister_elevated");
505 if (getenv(
"TERM") ==
nullptr &&
506 _isatty(fileno(stdout)) &&
508 (win_has_ancestor_process(
"powershell.exe") ||
509 win_has_ancestor_process(
"cmd.exe")) &&
510 !win_has_ancestor_process(
"WindowsTerminal.exe")) {
511 MSG(WARNING,
"Running inside PS/cmd terminal is not recommended "
512 "because scrolling the output freezes the process, "
513 "consider using Windows Terminal instead!\n");
518 if (strstr(argv[0],
"run_tests") ==
nullptr) {
548 unique_lock<mutex> lk(
lock);
553 for (
int i = 0; i < 2; ++i) {
564 bool should_exit_thread_notified =
false;
568 perror(
"PLATFORM_PIPE_READ");
570 if (!should_exit_thread_notified) {
571 unique_lock<mutex> lk(s->
lock);
573 get<0>(c)(get<1>(c));
575 should_exit_thread_notified =
true;
583 perror(
"PLATFORM_PIPE_WRITE");
641 cout <<
"[capability][device] {"
642 "\"purpose\":" << std::quoted(purpose) <<
", "
643 "\"module\":" << std::quoted(mod) <<
", "
644 "\"device\":" << std::quoted(device.
dev) <<
", "
645 "\"name\":" << std::quoted(device.
name) <<
", "
646 "\"extra\": {" << device.
extra <<
"}, "
647 "\"repeatable\":\"" << device.
repeatable <<
"\", "
650 for(
unsigned int j = 0; j < std::size(device.
modes); j++) {
651 if (device.
modes[j].
id[0] ==
'\0') {
657 std::cout <<
"{\"name\":" << std::quoted(device.
modes[j].
name) <<
", "
658 "\"opts\":" << device.
modes[j].
id <<
"}";
662 std::cout <<
", \"options\": [";
663 for(
unsigned int j = 0; j < std::size(device.
options); j++) {
673 "\"key\":" << std::quoted(device.
options[j].
key) <<
", "
684 auto vdi =
static_cast<T
>(mod);
687 void (*
deleter)(
void *) =
nullptr;
689 for (
int i = 0; i <
count; ++i) {
698 if(vci->get_module_info){
699 auto module_info = vci->get_module_info();
700 cout <<
"[capability][video_compress] {"
701 "\"name\":" << std::quoted(
name) <<
", "
705 for(
const auto& opt : module_info.opts){
710 "\"display_name\":" << std::quoted(opt.display_name) <<
", "
711 "\"display_desc\":" << std::quoted(opt.display_desc) <<
", "
712 "\"placeholder_text\":" << std::quoted(opt.placeholder_text) <<
", "
713 "\"key\":" << std::quoted(opt.key) <<
", "
714 "\"opt_str\":" << std::quoted(opt.opt_str) <<
", "
715 "\"is_boolean\":\"" << (opt.is_boolean ?
"t" :
"f") <<
"\"}";
722 for(
const auto& c : module_info.codecs){
726 cout <<
"{\"name\":" << std::quoted(c.name) <<
", "
727 "\"priority\": " << c.priority <<
", "
731 for(
const auto& e : c.encoders){
735 cout <<
"{\"name\":" << std::quoted(e.name) <<
", "
736 "\"opt_str\":" << std::quoted(e.opt_str) <<
"}";
741 cout <<
"]}" << std::endl;
753 {
"Compressions",
"compress",
756 {
"Capture filters",
"capture_filter",
759 {
"Capturers",
"capture",
762 {
"Displays",
"display",
765 {
"Audio capturers",
"audio_cap",
768 {
"Audio filters",
"audio_filter",
771 {
"Audio compress",
"audio_compress",
774 {
"Audio playback",
"audio_play",
780static void probe_all(std::map<enum library_class, module_info_map>& class_mod_map)
783 for(
const auto& mod : class_mod_map[mod_class.cls]){
784 if(!mod_class.probe_print)
786 mod_class.probe_print(mod.first, mod.second);
791static void print_modules(std::map<enum library_class, module_info_map>& class_mod_map)
794 std::cout <<
"[cap] " << mod_class.desc <<
":\n";
795 for(
const auto& mod : class_mod_map[mod_class.cls]){
796 cout <<
"[cap][" << mod_class.cap_str <<
"] " << mod.first <<
"\n";
803 std::string_view conf(cfg);
805 std::cout <<
"[capability][start] version 4" << endl;
807 std::map<enum library_class, module_info_map> class_mod_map;
809 class_mod_map.emplace(mod_class.cls,
817 if(conf ==
"noprobe"){
819 }
else if(conf.empty()){
823 auto class_sv =
tokenize(conf,
':');
829 if(i.cap_str == class_sv){
840 auto& modmap = class_mod_map[
cls];
842 auto modinfo = modmap.find(std::string(mod_sv));
843 if(modinfo == modmap.end()){
853 cout <<
"[capability][end]" << endl;
865 "built " __DATE__
" " __TIME__;
870 bool is_release =
true;
872 if (strstr(GIT_BRANCH,
"release") ==
nullptr &&
873 strstr(GIT_BRANCH,
"tags/v") ==
nullptr) {
878 (is_release ?
"" :
"+"))) <<
884 const char *config_flags = CONFIG_FLAGS;
885 if (strlen(config_flags) == 0) {
886 config_flags =
"(none)";
888 printf(
"configuration flags: %s", config_flags);
890 printf(PACKAGE_NAME
" was compiled with following features:\n");
891 printf(AUTOCONF_RESULT);
898 return it->second.c_str();
932 assert(
param != NULL &&
doc != NULL);
933 for (
unsigned int i = 0; i <
sizeof params /
sizeof params[0]; ++i) {
951 for (
unsigned int i = 0; i <
sizeof params /
sizeof params[0]; ++i) {
978 if (!preinit && strcmp(optarg,
"help") == 0) {
979 puts(
"Use of params below is experimental and should be used with a caution and a knowledge of consequences and affected functionality!\n");
980 puts(
"Params can be one or more (separated by comma) of following:");
985 char *
item =
nullptr;
986 char *save_ptr =
nullptr;
987 while ((
item = strtok_r(tmp,
",", &save_ptr)) !=
nullptr) {
989 char *key_cstr =
item;
990 const char *val_cstr =
"";
991 if (
char *delim = strchr(
item,
'=')) {
992 val_cstr = delim + 1;
1014 unordered_map<string, long long int> bitrate_spec_map = {
1020 if (
auto it = bitrate_spec_map.find(optarg);
1021 it != bitrate_spec_map.end()) {
1022 *bitrate = it->second;
1025 if (strcmp(optarg,
"help") == 0) {
1026 constexpr char const *NUMERIC_PATTERN =
"{1-9}{0-9}*[kMG][!][E]";
1029 <<
"\tuv " <<
TERM_BOLD "-l [auto | dynamic | unlimited | "
1034 <<
" - spread packets across frame time\n"
1037 <<
" - similar to \"auto\" but more relaxed - occasional "
1038 "huge frame can spread 1.5x frame time (default)\n"
1040 <<
TBOLD(
"unlimited")
1041 <<
" - send packets at a wire speed (in bursts)\n"
1043 <<
SBOLD(NUMERIC_PATTERN)
1044 <<
" - send packets at most at specified bitrate\n\n"
1046 <<
"Use an exclamation mark to indicate intentionally very "
1047 "low bitrate. 'E' to use the value as a fixed bitrate, "
1048 "not cap /i. e. even the frames that may be sent at "
1049 "lower bitrate are sent at the nominal bitrate)\n"
1055 for (
int i = 0; i < 2; ++i) {
1056 if (optarg[strlen(optarg) - 1] ==
'!' ||
1057 optarg[strlen(optarg) - 1] ==
'E') {
1058 if (optarg[strlen(optarg) - 1] ==
'!') {
1060 optarg[strlen(optarg) - 1] =
'\0';
1062 if (optarg[strlen(optarg) - 1] ==
'E') {
1064 optarg[strlen(optarg) - 1] =
'\0';
1069 if (*bitrate <= 0) {
1073 constexpr long long mb5 =
1076 constexpr long long gb100 =
1077 100ll * 1000 * 1000 *
1079 if ((*bitrate < mb5 || *bitrate > gb100) && !force) {
1081 "Bitrate %lld bps seems to be too %s, use \"-l %s!\" "
1082 "to force if this is not a mistake.\n",
1083 *bitrate, *bitrate < mb5 ?
"low" :
"high", optarg);
1094 for (
unsigned int i = 0; i <
sizeof params /
sizeof params[0]; ++i) {
1104 cout <<
"codec RGB/YCbCr depth description\n";
1124 cout <<
"\nLegend:\n" <<
" I - interframe codec\n";
1147 unique_lock<mutex> lk(s->lock);
1148 s->should_exit_callbacks.emplace_back(
callback, udata);
1162 unique_lock<mutex> lk(s->lock);
1163 for (
auto it = s->should_exit_callbacks.begin();
1164 it != s->should_exit_callbacks.end(); ++it) {
1165 if (get<0>(*it) ==
callback && get<1>(*it) == udata) {
1166 s->should_exit_callbacks.erase(it);
1174 " Treats some errors as fatal and exit even though " PACKAGE_NAME
" could continue otherwise.\n"
1175 " This allows less severe errors to be catched (which should not occur under normal circumstances).\n"
1176 " An environment variable ULTRAGRID_ERRORS_FATAL with the same effect can also be used.\n");
1192 ifstream ppid_f(
"/proc/" + to_string(getppid()) +
"/comm", ifstream::in);
1193 if (ppid_f.is_open()) {
1196 if (comm ==
"gdb") {
1208 print_stacktrace_win();
1212#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 27)
1213 int fd = memfd_create(
"ultragrid_backtrace", MFD_CLOEXEC);
1217 const unsigned long tid = pthread_mach_thread_np(pthread_self());
1219 const unsigned long tid = syscall(__NR_gettid);
1221 snprintf(path,
sizeof path,
"%s/ug-%lu",
get_temp_dir(), tid);
1222 int fd = open(path, O_CLOEXEC | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
1228 char backtrace_msg[] =
"Backtrace:\n";
1229 write_all(fd,
sizeof backtrace_msg, backtrace_msg);
1230 array<void *, 256> addresses{};
1231 const int num_symbols = backtrace(addresses.data(), addresses.size());
1232 backtrace_symbols_fd(addresses.data(), num_symbols, fd);
1233 if (fd == STDERR_FILENO) {
1237 lseek(fd, 0, SEEK_SET);
1240 while ((rbytes = read(fd, buf,
sizeof buf)) > 0) {
1241 ssize_t written = 0;
1243 while (written < rbytes &&
1244 (wbytes = write(STDERR_FILENO, buf + written,
1245 rbytes - written)) > 0) {
1259 char *ptr_end = buf +
sizeof buf;
1260 strappend(&ptr, ptr_end,
"\n" PACKAGE_NAME
" has crashed");
1264 strappend(&ptr, ptr_end,
".\n\nPlease send a bug report to address " PACKAGE_BUGREPORT
".\n");
1265 strappend(&ptr, ptr_end,
"You may find some tips how to report bugs in file doc/REPORTING_BUGS.md distributed with " PACKAGE_NAME
"\n");
1266 strappend(&ptr, ptr_end,
"(or available online at https://github.com/CESNET/UltraGrid/blob/master/doc/REPORTING-BUGS.md).\n");
1268 write_all(STDERR_FILENO, ptr - buf, buf);
1272 signal(sig, SIG_DFL);
1280 assert(sig == SIGALRM);
1281 char msg[] =
"Hang detected - you may continue waiting or kill UltraGrid. Please report if UltraGrid doesn't exit after reasonable amount of time.\n";
1283 signal(SIGALRM, SIG_DFL);
1289 " Do not exit on unknown parameter.\n");
1291 " Sets length of software audio playback buffer (in ms, ALSA/Coreaudio/Portaudio/WASAPI)\n");
1293 " Sets number of audio frames captured at once (CoreAudio)\n");
1294ADD_TO_PARAM(
"audio-disable-adaptive-buffer",
"* audio-disable-adaptive-buffer\n"
1295 " Disables audio adaptive playback buffer (CoreAudio/JACK)\n");
1297 " [experimental] Color space to use, C - colorimetry: 0 - undefined, 1 - BT.709, 2 - BT.2020/2100, 3 - P3; T - transfer fn: 0 - undefined, 1 - 709, 2 - HLG; 3 - PQ (signalized to GLFW on mac, NDI receiver)\n");
1299 " Try to reduce audio latency at the expense of worse reliability\n"
1300 " Add ultra for even more aggressive setting.\n");
1302 " Use alternative window title (SDL/GL only)\n");
int void(** deleter)(void *))
const char * get_codec_name(codec_t codec)
This file contains definition of some common audio types.
#define AUDIO_CAPTURE_ABI_VERSION
#define AUDIO_FILTER_ABI_VERSION
#define AUDIO_PLAYBACK_ABI_VERSION
#define CAPTURE_FILTER_ABI_VERSION
static af_result_code init(struct module *parent, const char *cfg, void **state)
void set_skip_repeats(bool val)
void set_timestamp_mode(log_timestamp_mode val)
vector< tuple< audio_codec_info_t, bool, string > > get_audio_codec_list()
#define AUDIO_COMPRESS_ABI_VERSION
bool color_output_init()
sets internal variable color_stdout and retunrs its contents
int color_printf(const char *format,...)
static ssize_t write_all(fd_t fd, const void *buf, size_t count)
static __device__ vec2 abs(const vec2 &v)
void cuda_wrapper_device_reset(void)
This file contais wrapper around CUDA functions.
void log_msg(int level, const char *format,...)
bool parse_log_cfg(const char *conf_str, int *log_lvl, bool *logger_skip_repeats, log_timestamp_mode *show_timestamps)
#define LOG_LEVEL_NOTICE
information that may be interesting
#define LOG_LEVEL_INFO
normal reporting
#define LOG_LEVEL_ERROR
general errors
#define LOG_LEVEL_VERBOSE
#define LOG_LEVEL_FATAL
errors that prevent UG run
Log_output & get_log_output()
#define LOG_LEVEL_WARNING
less severe errors
#define VIDEO_DISPLAY_ABI_VERSION
void module_init_default(struct module *module_data)
struct module * get_root_module(struct module *node)
#define VIDEO_CAPTURE_ABI_VERSION
#define VIDEO_COMPRESS_ABI_VERSION
void handle_error(int status)
bool running_in_debugger()
static void print_modules(std::map< enum library_class, module_info_map > &class_mod_map)
void set_audio_delay(int audio_delay)
void crash_signal_handler(int sig)
void init_root_module(struct module *root_mod)
unsigned int cuda_devices_count
static bool unexpected_exit_called
void print_capabilities(const char *cfg)
void register_should_exit_callback(struct module *mod, void(*callback)(void *), void *udata)
volatile int audio_offset
added audio delay in ms (non-negative), can be used to tune AV sync
int glfw_init_count
0->1 - call glfwInit, 1->0 call glfwTerminate; glfw{Init,Terminate} should be called from main thr,...
bool cuda_devices_explicit
–cuda-device/-D specified expilcitly
void print_configuration()
static const struct @18 mod_classes[]
static bool parse_opts_set_logging(int argc, char *argv[])
void(* probe_print)(std::string name, const void *)
static void print_device(std::string purpose, std::string const &mod, const device_info &device)
unsigned int audio_capture_bps
const char * get_commandline_param(const char *key)
static void probe_device(std::string_view cap_str, std::string const &name, const void *mod)
int get_exit_status(struct module *root_mod)
int set_pixfmt_conv_policy(const char *optarg)
void unregister_should_exit_callback(struct module *mod, void(*callback)(void *), void *udata)
std::unordered_map< std::string, std::string > commandline_params
static bool validate_param(const char *param)
void register_param(const char *param, const char *doc)
static void print_backtrace()
static void echeck_unexpected_exit(void)
unsigned int cuda_devices[MAX_CUDA_DEVICES]
bool tok_in_argv(char **argv, const char *tok)
bool parse_params(const char *optarg, bool preinit)
static state_root *volatile state_root_static
used by exit_uv() called from signal handler
static void load_libgcc()
std::map< std::string, const void * > module_info_map
unsigned int audio_capture_sample_rate
void hang_signal_handler(int sig)
static bool set_output_buffering()
bool parse_bitrate(char *optarg, long long int *bitrate)
static void probe_all(std::map< enum library_class, module_info_map > &class_mod_map)
volatile int video_offset
added video delay in ms (non-negative), can be used to tune AV sync
struct init_data * common_preinit(int argc, char *argv[])
static void print_param_doc(void)
mainloop_t mainloop
mainloop to be run if display mainloop isn't run
bool register_mainloop(mainloop_t m, void *u)
int get_audio_delay(void)
void set_commandline_param(const char *key, const char *val)
void print_video_codecs(void)
static void probe_compress(std::string const &name, const void *mod) noexcept
int set_audio_capture_format(const char *optarg)
void print_pixel_formats(void)
unsigned int audio_capture_channels
void common_cleanup(struct init_data *init)
const char * get_version_details()
#define RATE_AUTO
spread packets evenly across frame time (currently 3/4)
#define RATE_FLAG_FIXED_RATE
use the bitrate as fixed, not capped
void(* mainloop_t)(void *)
char pixfmt_conv_pref[]
bitdepth, subsampling, color space
#define ADD_TO_PARAM(param, doc)
#define RATE_DYNAMIC
same as RATE_AUTO but occasional excess frame allowed
void restore_old_tio(void)
map< string, const void * > get_libraries_for_class(enum library_class cls, int abi_version, bool include_hidden)
void open_all(const char *pattern, list< void * > &libs)
@ LIBRARY_CLASS_AUDIO_FILTER
@ LIBRARY_CLASS_VIDEO_CAPTURE
@ LIBRARY_CLASS_AUDIO_PLAYBACK
@ LIBRARY_CLASS_AUDIO_CAPTURE
@ LIBRARY_CLASS_VIDEO_DISPLAY
@ LIBRARY_CLASS_UNDEFINED
@ LIBRARY_CLASS_CAPTURE_FILTER
@ LIBRARY_CLASS_AUDIO_COMPRESS
@ LIBRARY_CLASS_VIDEO_COMPRESS
#define IF_NOT_NULL_ELSE(val, default_val)
@ STR_LEN
"standard" string length placeholder
long long unit_evaluate(const char *str, const char **endptr)
const char * ug_strerror(int errnum)
static void strappend(char **dst, size_t *dst_alloc_len, const char *src)
Option::Callback::fcn_type callback
void append_sig_desc(char **ptr, const char *ptr_end, int signum)
std::string_view tokenize(std::string_view &str, char delim, char quot)
Tokenizer for string_view.
char name[1024]
human readable name of the mode
char id[1024]
< optional zero-terminated array of available modes
char name[1024]
human readable name of the device
struct device_option options[64]
struct device_info::mode modes[512]
list< void * > opened_libs
notify_t new_message
if set, notifies module that new message is in queue, receiver lock is hold during the call
list< tuple< void(*)(void *), void * > > should_exit_callbacks
void broadcast_should_exit(bool quit_watcher=false)
friend void register_should_exit_callback(struct module *mod, void(*callback)(void *), void *udata)
friend void unregister_should_exit_callback(struct module *mod, void(*callback)(void *), void *udata)
thread should_exit_thread
static constexpr char QUIT_WATCHER_FLAG
static void deleter(struct module *m)
static void should_exit_watcher(state_root *s)
void set_thread_name(const char *name)
This file contains some common data types.
@ VIDEO_CODEC_COUNT
count of known video codecs (including VIDEO_CODEC_NONE)
char * wrap_paragraph(char *text)
int parse_audio_format(const char *str, struct audio_desc *ret)
bool is_codec_opaque(codec_t codec)
bool codec_is_a_rgb(codec_t codec)
Returns TRUE if specified pixelformat is some form of RGB (not YUV).
bool is_codec_interframe(codec_t codec)
const char * get_codec_name_long(codec_t codec)
int get_bits_per_component(codec_t codec)
API for video compress drivers.
bool com_initialize(bool *com_initialized, const char *err_prefix)
void com_uninitialize(bool *com_initialized)
@ BUILD_WINDOWS_11_OR_LATER