mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-07-19 09:39:15 +00:00
oss-audio: Improve /dev/sndstat parsing on FreeBSD
This commit targets FreeBSD and potentially DragonFly BSD. The commit fixes issue parsing /dev/sndstat when hw.snd.verbose is greater than 0. Besides, the commit also adds support for audio devices created by user space daemons, such as virtual_oss.
This commit is contained in:
parent
5803504c36
commit
a1e99d7903
|
@ -21,6 +21,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include <util/threading.h>
|
||||
#include <obs-module.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <poll.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
@ -38,6 +39,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#define OSS_RATE_DEFAULT 48000
|
||||
#define OSS_CHANNELS_DEFAULT 2
|
||||
|
||||
#define OSS_DEVICE_BEGIN "Installed devices:"
|
||||
#define OSS_USERDEVICE_BEGIN "Installed devices from userspace:"
|
||||
#define OSS_FV_BEGIN "File Versions:"
|
||||
|
||||
/**
|
||||
* Control block of plugin instance
|
||||
*/
|
||||
|
@ -215,6 +220,7 @@ static void *oss_reader_thr(void *vptr)
|
|||
size_t framesize;
|
||||
|
||||
framesize = oss_calc_framesize(handle->channels, handle->sample_fmt);
|
||||
|
||||
fds[0].fd = handle->dsp_fd;
|
||||
fds[0].events = POLLIN;
|
||||
fds[1].fd = handle->notify_pipe[0];
|
||||
|
@ -460,6 +466,8 @@ static void oss_prop_add_devices(obs_property_t *p)
|
|||
char *line = NULL;
|
||||
size_t linecap = 0;
|
||||
FILE *fp;
|
||||
bool ud_matching = false;
|
||||
bool skipall = false;
|
||||
|
||||
fp = fopen(OSS_SNDSTAT_PATH, "r");
|
||||
if (fp == NULL) {
|
||||
|
@ -470,35 +478,83 @@ static void oss_prop_add_devices(obs_property_t *p)
|
|||
|
||||
while (getline(&line, &linecap, fp) > 0) {
|
||||
int pcm;
|
||||
char *ptr, *pdesc, *descr, *devname, *pmode;
|
||||
char *ptr, *pdesc, *pmode;
|
||||
char *descr = NULL, *devname = NULL;
|
||||
char *udname = NULL;
|
||||
|
||||
if (sscanf(line, "pcm%i: ", &pcm) != 1)
|
||||
if (!strncmp(line, OSS_FV_BEGIN, strlen(OSS_FV_BEGIN))) {
|
||||
skipall = true;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(line, OSS_DEVICE_BEGIN,
|
||||
strlen(OSS_DEVICE_BEGIN))) {
|
||||
ud_matching = false;
|
||||
skipall = false;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(line, OSS_USERDEVICE_BEGIN,
|
||||
strlen(OSS_USERDEVICE_BEGIN))) {
|
||||
ud_matching = true;
|
||||
skipall = false;
|
||||
continue;
|
||||
}
|
||||
if (skipall || isblank(line[0]))
|
||||
continue;
|
||||
|
||||
if (!ud_matching) {
|
||||
if (sscanf(line, "pcm%i: ", &pcm) != 1)
|
||||
continue;
|
||||
} else {
|
||||
char *end = strchr(line, ':');
|
||||
if (end == NULL || end - line == 0)
|
||||
continue;
|
||||
|
||||
udname = strndup(line, end - line);
|
||||
if (udname == NULL)
|
||||
continue;
|
||||
}
|
||||
if ((ptr = strchr(line, '<')) == NULL)
|
||||
continue;
|
||||
goto free_all_str;
|
||||
pdesc = ptr + 1;
|
||||
if ((ptr = strrchr(pdesc, '>')) == NULL)
|
||||
continue;
|
||||
goto free_all_str;
|
||||
*ptr++ = '\0';
|
||||
if (*ptr++ != ' ' || *ptr++ != '(')
|
||||
continue;
|
||||
pmode = ptr;
|
||||
if ((pmode = strchr(ptr, '(')) == NULL)
|
||||
goto free_all_str;
|
||||
pmode++;
|
||||
if ((ptr = strrchr(pmode, ')')) == NULL)
|
||||
continue;
|
||||
goto free_all_str;
|
||||
*ptr++ = '\0';
|
||||
if (strcmp(pmode, "rec") != 0 && strcmp(pmode, "play/rec") != 0)
|
||||
continue;
|
||||
if (asprintf(&descr, "pcm%i: %s", pcm, pdesc) == -1)
|
||||
continue;
|
||||
if (asprintf(&devname, "/dev/dsp%i", pcm) == -1) {
|
||||
free(descr);
|
||||
continue;
|
||||
if (!isdigit(pmode[0])) {
|
||||
if (strcmp(pmode, "rec") != 0 &&
|
||||
strcmp(pmode, "play/rec") != 0)
|
||||
goto free_all_str;
|
||||
} else {
|
||||
int npcs, nrcs;
|
||||
if (sscanf(pmode, "%dp:%*dv/%dr:%*dv", &npcs, &nrcs) !=
|
||||
2)
|
||||
goto free_all_str;
|
||||
if (nrcs < 1)
|
||||
goto free_all_str;
|
||||
}
|
||||
if (!ud_matching) {
|
||||
if (asprintf(&descr, "pcm%i: %s", pcm, pdesc) == -1)
|
||||
goto free_all_str;
|
||||
if (asprintf(&devname, "/dev/dsp%i", pcm) == -1)
|
||||
goto free_all_str;
|
||||
} else {
|
||||
if (asprintf(&descr, "%s: %s", udname, pdesc) == -1)
|
||||
goto free_all_str;
|
||||
if (asprintf(&devname, "/dev/%s", udname) == -1)
|
||||
goto free_all_str;
|
||||
}
|
||||
|
||||
obs_property_list_add_string(p, descr, devname);
|
||||
|
||||
free_all_str:
|
||||
free(descr);
|
||||
free(devname);
|
||||
free(udname);
|
||||
}
|
||||
free(line);
|
||||
|
||||
|
|
Loading…
Reference in a new issue