From: Alexandre Ratchov Subject: gstreamer: Add sndio device monitor (fixes audio in dino, maybe others) To: ports@openbsd.org Cc: kirill@korins.ky Date: Sun, 13 Jul 2025 16:48:36 +0200 Few programs enumerate the audio devices at audio initialization and abort if this fails. The net/dino port is one of them, which explains why audio phone calls dont work. This was discussed in this thread: https://marc.info/?l=openbsd-misc&m=173183259932223&w=4 This diff adds the missing "device provider" class to the sndio plugin. It just returns the defaut device, so programs that need to enumerate the audio devices dont fail. OK? Index: Makefile =================================================================== RCS file: /cvs/ports/multimedia/gstreamer1/plugins-base/Makefile,v diff -u -p -u -p -r1.122 Makefile --- Makefile 27 Jun 2025 10:12:15 -0000 1.122 +++ Makefile 13 Jul 2025 14:25:14 -0000 @@ -1,6 +1,7 @@ COMMENT= base elements for GStreamer DISTNAME= gst-plugins-base-${V} +REVISION= 0 SHARED_LIBS += gsttag-1.0 7.3 # 0.2603.0 SHARED_LIBS += gstfft-1.0 7.3 # 0.2603.0 Index: files/gstsndio.c =================================================================== RCS file: /cvs/ports/multimedia/gstreamer1/plugins-base/files/gstsndio.c,v diff -u -p -u -p -r1.4 gstsndio.c --- files/gstsndio.c 21 Apr 2019 08:49:42 -0000 1.4 +++ files/gstsndio.c 13 Jul 2025 14:25:14 -0000 @@ -21,6 +21,7 @@ #include #include "gstsndio.h" +#include "sndiodeviceprovider.h" GST_DEBUG_CATEGORY (gst_sndio_debug); #define GST_CAT_DEFAULT gst_sndio_debug @@ -40,6 +41,9 @@ plugin_init (GstPlugin * plugin) /* prefer sndiosink over pulsesink (GST_RANK_PRIMARY + 10) */ if (!gst_element_register (plugin, "sndiosink", GST_RANK_PRIMARY + 20, gst_sndiosink_get_type())) + return FALSE; + if (!gst_device_provider_register (plugin, "sndiodeviceprovider", GST_RANK_PRIMARY + 20, + gst_sndio_device_provider_get_type())) return FALSE; return TRUE; } Index: files/meson.build =================================================================== RCS file: /cvs/ports/multimedia/gstreamer1/plugins-base/files/meson.build,v diff -u -p -u -p -r1.3 meson.build --- files/meson.build 25 Jan 2023 08:31:52 -0000 1.3 +++ files/meson.build 13 Jul 2025 14:25:14 -0000 @@ -1,5 +1,7 @@ sndio_sources = [ 'gstsndio.c', + 'sndiodevice.c', + 'sndiodeviceprovider.c', 'sndiosink.c', 'sndiosrc.c', ] Index: files/sndiodevice.c =================================================================== RCS file: files/sndiodevice.c diff -N files/sndiodevice.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ files/sndiodevice.c 13 Jul 2025 14:25:14 -0000 @@ -0,0 +1,79 @@ +#include +#include +#include +#include +#include "gstsndio.h" +#include "sndiodevice.h" + +G_DEFINE_TYPE (GstSndioDevice, gst_sndio_device, GST_TYPE_DEVICE); + +GstDevice * +gst_sndio_device_new (const gchar *name, int mode) +{ + static GstStaticCaps sndio_caps = GST_STATIC_CAPS (GST_SNDIO_CAPS_STRING); + GstSndioDevice *sndio_device; + GstCaps *caps; + GstStructure *props; + const gchar *klass; + + klass = (mode == SIO_REC) ? "Audio/Source" : "Audio/Sink"; + + caps = gst_static_caps_get (&sndio_caps); + + props = gst_structure_new ("sndio-proplist", + "device.api", G_TYPE_STRING, "sndio", + "device.class", G_TYPE_STRING, "sound", + NULL); + + sndio_device = g_object_new (GST_TYPE_SNDIO_DEVICE, + "display-name", name, + "caps", caps, + "device-class", klass, + "properties", props, + NULL); + + sndio_device->mode = mode; + + /* sndio_device owns 'caps' and 'props', so free ours */ + + gst_structure_free (props); + gst_caps_unref (caps); + + return GST_DEVICE (sndio_device); +} + +static GstElement * +gst_sndio_device_create_element (GstDevice *device, const gchar *name) +{ + GstSndioDevice *sndio_device = GST_SNDIO_DEVICE (device); + GstElement *element; + const char *element_name; + + element_name = (sndio_device->mode == SIO_REC) ? "sndiosrc" : "sndiosink"; + + element = gst_element_factory_make (element_name, name); + g_object_set (element, "device", gst_device_get_display_name(device), NULL); + + return element; +} + +static void +gst_sndio_device_finalize (GObject *object) +{ + G_OBJECT_CLASS (gst_sndio_device_parent_class)->finalize (object); +} + +static void +gst_sndio_device_class_init (GstSndioDeviceClass *klass) +{ + GstDeviceClass *dev_class = GST_DEVICE_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + dev_class->create_element = gst_sndio_device_create_element; + object_class->finalize = gst_sndio_device_finalize; +} + +static void +gst_sndio_device_init (GstSndioDevice *device) +{ +} Index: files/sndiodevice.h =================================================================== RCS file: files/sndiodevice.h diff -N files/sndiodevice.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ files/sndiodevice.h 13 Jul 2025 14:25:14 -0000 @@ -0,0 +1,40 @@ +#ifndef __GST_SNDIODEVICE_H__ +#define __GST_SNDIODEVICE_H__ + +#include + +G_BEGIN_DECLS + +typedef struct _GstSndioDevice GstSndioDevice; +typedef struct _GstSndioDeviceClass GstSndioDeviceClass; + +#define GST_TYPE_SNDIO_DEVICE \ + (gst_sndio_device_get_type()) +#define GST_IS_SNDIO_DEVICE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_SNDIO_DEVICE)) +#define GST_IS_SNDIO_DEVICE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_SNDIO_DEVICE)) +#define GST_SNDIO_DEVICE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_SNDIO_DEVICE, GstSndioDeviceClass)) +#define GST_SNDIO_DEVICE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_SNDIO_DEVICE, GstSndioDevice)) +#define GST_SNDIO_DEVICE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DEVICE, GstSndioDeviceClass)) +#define GST_SNDIO_DEVICE_CAST(obj) \ + ((GstSndioDevice *)(obj)) + +struct _GstSndioDevice { + GstDevice parent; + int mode; +}; + +struct _GstSndioDeviceClass { + GstDeviceClass parent_class; +}; + +GstDevice *gst_sndio_device_new (const gchar *, int); +GType gst_sndio_device_get_type (void); + +G_END_DECLS + +#endif Index: files/sndiodeviceprovider.c =================================================================== RCS file: files/sndiodeviceprovider.c diff -N files/sndiodeviceprovider.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ files/sndiodeviceprovider.c 13 Jul 2025 14:25:14 -0000 @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include "sndiodeviceprovider.h" +#include "sndiodevice.h" + +G_DEFINE_TYPE (GstSndioDeviceProvider, gst_sndio_device_provider, GST_TYPE_DEVICE_PROVIDER); + +static GList * +gst_sndio_device_provider_probe (GstDeviceProvider *provider) +{ + GList *list = NULL; + GstDevice *device; + struct sio_hdl *hdl; + + /* + * There's no way to discover all devices on the network, so + * just return the default device. The user can point it to + * any device. + */ + + device = gst_sndio_device_new (SIO_DEVANY, SIO_PLAY); + if (device) + list = g_list_prepend (list, device); + + device = gst_sndio_device_new (SIO_DEVANY, SIO_REC); + if (device) + list = g_list_prepend (list, device); + + return list; +} + +static void +gst_sndio_device_provider_class_init (GstSndioDeviceProviderClass *klass) +{ + GstDeviceProviderClass *dm_class = GST_DEVICE_PROVIDER_CLASS (klass); + + dm_class->probe = gst_sndio_device_provider_probe; + + gst_device_provider_class_set_static_metadata (dm_class, + "Sndio Device Provider", "Sink/Source/Audio", + "List and provide sndio source and sink devices", + "Alexandre Ratchov "); +} + +static void +gst_sndio_device_provider_init (GstSndioDeviceProvider *self) +{ +} Index: files/sndiodeviceprovider.h =================================================================== RCS file: files/sndiodeviceprovider.h diff -N files/sndiodeviceprovider.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ files/sndiodeviceprovider.h 13 Jul 2025 14:25:14 -0000 @@ -0,0 +1,38 @@ +#ifndef __GST_SNDIODEVICEPROVIDER_H__ +#define __GST_SNDIODEVICEPROVIDER_H__ + +#include + +G_BEGIN_DECLS + +typedef struct _GstSndioDeviceProvider GstSndioDeviceProvider; +typedef struct _GstSndioDeviceProviderClass GstSndioDeviceProviderClass; + +#define GST_TYPE_SNDIO_DEVICE_PROVIDER \ + (gst_sndio_device_provider_get_type()) +#define GST_IS_SNDIO_DEVICE_PROVIDER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_SNDIO_DEVICE_PROVIDER)) +#define GST_IS_SNDIO_DEVICE_PROVIDER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_SNDIO_DEVICE_PROVIDER)) +#define GST_SNDIO_DEVICE_PROVIDER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_SNDIO_DEVICE_PROVIDER, GstSndioDeviceProviderClass)) +#define GST_SNDIO_DEVICE_PROVIDER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_SNDIO_DEVICE_PROVIDER, GstSndioDeviceProvider)) +#define GST_SNDIO_DEVICE_PROVIDER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DEVICE_PROVIDER, GstSndioDeviceProviderClass)) +#define GST_SNDIO_DEVICE_PROVIDER_CAST(obj) \ + ((GstSndioDeviceProvider *)(obj)) + +struct _GstSndioDeviceProvider { + GstDeviceProvider parent; +}; + +struct _GstSndioDeviceProviderClass { + GstDeviceProviderClass parent_class; +}; + +GType gst_sndio_device_provider_get_type (void); + +G_END_DECLS + +#endif