diff --git a/plugins/oss-audio/oss-input.c b/plugins/oss-audio/oss-input.c
index 699cf9ec0..368ca5acf 100644
--- a/plugins/oss-audio/oss-input.c
+++ b/plugins/oss-audio/oss-input.c
@@ -21,6 +21,7 @@ along with this program. If not, see .
#include
#include
+#include
#include
#include
#include
@@ -38,6 +39,10 @@ along with this program. If not, see .
#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);