vcap/screen_avf: set device d=100 if unspec

Otherwise d=0 would be initialized implicitly, which isn't screen cap
device but rather FaceTime HD Camera or so.
This commit is contained in:
Martin Pulec
2026-01-20 15:06:51 +01:00
parent 74c47c53bd
commit 3ae62524d1
3 changed files with 51 additions and 3 deletions

View File

@@ -79,12 +79,51 @@ vidcap_screen_avf_probe(struct device_info **available_cards, int *count,
}
}
/// @returns whether the config string contains device spec (d=/uid=/name=)
static bool
contains_dev_spec(const char *fmt)
{
char *cpy = strdup(fmt);
char *tmp = cpy;
char *saveptr = nullptr;
char *item = nullptr;
while ((item = strtok_r(tmp, ":", &saveptr)) != nullptr) {
tmp = nullptr;
char *delim = strchr(item, '=');
if (!delim) {
continue;
}
*delim = '\0';
if (strstr(item, "device") == item ||
strstr(item, "uid") == item ||
strstr(item, "name") == item) {
return true;
}
}
return false;
}
static int
vidcap_screen_avf_init(struct vidcap_params *params, void **state)
{
if (avfoundation_usage(vidcap_params_get_fmt(params), true)) {
const char *fmt = vidcap_params_get_fmt(params);
if (avfoundation_usage(fmt, true)) {
return VIDCAP_INIT_NOERR; // help shown
}
if (contains_dev_spec(fmt)) {
return vidcap_avfoundation_info.init(params, state);
}
// add "d=100" to initialize first screen cap av foundation device
const size_t orig_len = strlen(fmt);
const size_t new_len = orig_len + 50;
char *new_fmt = malloc(new_len);
(void) snprintf(new_fmt, new_len, "%s%sd=%u", fmt,
orig_len == 0 ? "" : ":", AVF_SCR_CAP_OFF);
vidcap_params_replace_fmt(params, new_fmt);
free(new_fmt);
return vidcap_avfoundation_info.init(params, state);
}

View File

@@ -5,7 +5,7 @@
* @ingroup vidcap
*/
/*
* Copyright (c) 2013-2025 CESNET, zájmové sdružení právnických osob
* Copyright (c) 2013-2026 CESNET, zájmové sdružení právnických osob
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -280,6 +280,13 @@ struct vidcap_params *vidcap_params_copy(const struct vidcap_params *params)
return ret;
}
void
vidcap_params_replace_fmt(struct vidcap_params *params, const char *new_fmt)
{
free(params->fmt);
params->fmt = strdup(new_fmt);
}
/**
* Frees all members of the given structure as well as its members.
*

View File

@@ -10,7 +10,7 @@
* individual devices' parameters (namely per-device capture filter).
*/
/**
* Copyright (c) 2013-2025 CESNET, zájmové sdružení právnických osob
* Copyright (c) 2013-2026 CESNET, zájmové sdružení právnických osob
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -81,6 +81,8 @@ void vidcap_params_add_capture_filter(struct vidcap_params *par
const char *vidcap_params_get_capture_filter(const struct vidcap_params *params);
void vidcap_params_set_flags(struct vidcap_params *params, unsigned int flags);
void vidcap_params_add_flags(struct vidcap_params *params, unsigned int flags);
void vidcap_params_replace_fmt(struct vidcap_params *params,
const char *new_fmt);
/// @}
#ifdef __cplusplus