+
+static int DevicesEnum (audio_output_t *aout)
+{
+ int fd = vlc_open ("/dev/dsp", O_WRONLY);
+ if (fd == -1)
+ return -1;
+
+ oss_sysinfo si;
+ int n = -1;
+
+ if (ioctl (fd, SNDCTL_SYSINFO, &si) < 0)
+ {
+ msg_Err (aout, "cannot get system infos: %m");
+ goto out;
+ }
+
+ msg_Dbg (aout, "using %s version %s (0x%06X) under %s", si.product,
+ si.version, si.versionnum, si.license);
+
+ for (int i = 0; i < si.numaudios; i++)
+ {
+ oss_audioinfo ai = { .dev = i };
+
+ if (ioctl (fd, SNDCTL_AUDIOINFO, &ai) < 0)
+ {
+ msg_Warn (aout, "cannot get device %d infos: %m", i);
+ continue;
+ }
+ if (ai.caps & (PCM_CAP_HIDDEN|PCM_CAP_MODEM))
+ continue;
+ if (!(ai.caps & PCM_CAP_OUTPUT))
+ continue;
+ if (!ai.enabled)
+ continue;
+
+ aout_HotplugReport (aout, ai.devnode, ai.name);
+ n++;
+ }
+out:
+ close (fd);
+ return n;
+}
+
+static int DeviceSelect (audio_output_t *aout, const char *id)
+{
+ aout_sys_t *sys = aout->sys;
+ char *path = NULL;
+
+ if (id != NULL)
+ {
+ path = strdup (id);
+ if (unlikely(path == NULL))
+ return -1;
+ }
+
+ free (sys->device);
+ sys->device = path;
+ aout_DeviceReport (aout, path);
+ aout_RestartRequest (aout, AOUT_RESTART_OUTPUT);
+ return 0;
+}
+
+static int Open (vlc_object_t *obj)
+{
+ audio_output_t *aout = (audio_output_t *)obj;
+
+ aout_sys_t *sys = malloc (sizeof (*sys));
+ if(unlikely( sys == NULL ))
+ return VLC_ENOMEM;
+
+ sys->fd = -1;
+
+ sys->level = 100;
+ sys->mute = false;
+ sys->device = var_InheritString (aout, "oss-audio-device");
+
+ aout->sys = sys;
+ aout->start = Start;
+ aout->stop = Stop;
+ aout->volume_set = VolumeSet;
+ aout->mute_set = MuteSet;
+ aout->device_select = DeviceSelect;
+
+ DevicesEnum (aout);
+ return VLC_SUCCESS;
+}
+
+static void Close (vlc_object_t *obj)
+{
+ audio_output_t *aout = (audio_output_t *)obj;
+ aout_sys_t *sys = aout->sys;
+
+ free (sys->device);
+ free (sys);
+}