It appears that Gstreamer-1.0 can't access raw uaudio(4) devices (rsnd/n). I'm struggling to debug further so wanted to ask if this is expected to work or a known limitation of OpenBSD's sndio(7) implementation for gstreamer?
This is where I've got to so far: Gstreamer-1.0 works fine with uaudio(4) devices exposed by sndiod(8) (e.g. snd/n) but fails with the raw (rsnd/n) device. Once gstreamer has attempted to use the raw device, the uaudio(4) device is left in an unuseable state until it is hard reset (unplug / replug). I've tested several uaudio(4) USB-2 class-compliant devices (Focusrite, Tascam, M-Audio) on different amd64 -current hosts and the problem appears to be reproducible on all of them. So it looks like a gstreamer+sndio+uaudio specific issue? A simple test to demonstrate would be: Terminate any running sndiod(8). env AUDIODEVICE=rsnd/1 gst-launch-1.0 -v sndiosrc ! fakesink --gst-debug=sndio:9 0:00:00.103475000 21585 0x37af4e42210 LOG sndio gstsndio.c:77:GstCaps *gst_sndio_getcaps(struct gstsndio *, GstCaps *):<sndiosrc0> getcaps called, returning template caps 0:00:00.103918000 21585 0x37af4e42210 LOG sndio gstsndio.c:77:GstCaps *gst_sndio_getcaps(struct gstsndio *, GstCaps *):<sndiosrc0> getcaps called, returning template caps Setting pipeline to PAUSED ... 0:00:00.105188000 21585 0x37af4e42210 DEBUG sndio gstsndio.c:111:gboolean gst_sndio_open(struct gstsndio *, gint):<sndiosrc0> open 0:00:00.105580000 21585 0x37af4e42210 WARN sndio gstsndio.c:123:gboolean gst_sndio_open(struct gstsndio *, gint):0x37b29982c00 error: Couldn't get device capabilities (gst-launch-1.0:21585): GStreamer-CRITICAL **: gst_element_message_full_with_details: assertion 'GST_IS_ELEMENT (element)' failed ERROR: Pipeline doesn't want to pause. Setting pipeline to NULL ... Freeing pipeline ... Now, nothing but a hard reset will get the uaudio device working correctly again. Any further attempts to access the uaudio(4) device returns a 'failed to open device' error. (examples below with both gstreamer and sndiod) Other, non gstreamer-1.0 code seems to be unaffected e.g. Audacity will happily open and use the raw (rsnd/n) device without any apparent error. The gstreamer code is a bit odd as sndio(7) support is 'patched in' by the OpenBSD port's Makefile. It fails at gst_sndio_open->sio_getcap in gstsndio.c: gboolean gst_sndio_open (struct gstsndio *sio, gint mode) { GValue list = G_VALUE_INIT, item = G_VALUE_INIT; GstStructure *s; GstCaps *caps; struct sio_enc *enc; struct sio_cap cap; char fmt[16]; int i, chan; GST_DEBUG_OBJECT (sio->obj, "open"); sio->hdl = sio_open (sio->device, mode, 0); if (sio->hdl == NULL) { GST_ELEMENT_ERROR (sio->obj, RESOURCE, OPEN_READ_WRITE, ("Couldn't open sndio device"), (NULL)); return FALSE; } sio->mode = mode; if (!sio_getcap(sio->hdl, &cap)) { /* Fails here */ GST_ELEMENT_ERROR (sio, RESOURCE, OPEN_WRITE, ("Couldn't get device capabilities"), (NULL)); sio_close(sio->hdl); sio->hdl = NULL; return FALSE; } All further attempts to open the audio(4) device fail, with either gstreamer or sndiod(8): env AUDIODEVICE=rsnd/1 gst-launch-1.0 -v sndiosrc ! fakesink --gst-debug=sndio:9 0:00:00.100955000 86224 0x122e996b8810 LOG sndio gstsndio.c:77:GstCaps *gst_sndio_getcaps(struct gstsndio *, GstCaps *):<sndiosrc0> getcaps called, returning template caps 0:00:00.101160000 86224 0x122e996b8810 LOG sndio gstsndio.c:77:GstCaps *gst_sndio_getcaps(struct gstsndio *, GstCaps *):<sndiosrc0> getcaps called, returning template caps Setting pipeline to PAUSED ... 0:00:00.101781000 86224 0x122e996b8810 DEBUG sndio gstsndio.c:111:gboolean gst_sndio_open(struct gstsndio *, gint):<sndiosrc0> open 0:00:00.103892000 86224 0x122e996b8810 WARN sndio gstsndio.c:116:gboolean gst_sndio_open(struct gstsndio *, gint):<sndiosrc0> error: Couldn't open sndio device ERROR: Pipeline doesn't want to pause. ERROR: from element /GstPipeline:pipeline0/GstSndioSrc:sndiosrc0: Couldn't open sndio device Additional debug info: gstsndio.c(116): gboolean gst_sndio_open(struct gstsndio *, gint) (): /GstPipeline:pipeline0/GstSndioSrc:sndiosrc0 Setting pipeline to NULL ... Freeing pipeline ... # sndiod -ddd -f rsnd/1 snd0 pst=cfg.default: rec=0:1 dup helper(helper|ini): created worker(worker|ini): created listen(/tmp/aucat/aucat0|ini): created sock(sock|ini): created sock,rmsg,widl: AUTH message sock,rmsg,widl: HELLO message sock,rmsg,widl: hello from <gst-launch->, mode = 2, ver 7 sock,rmsg,widl: using snd0 pst=cfg.default, mode = 2 gstlaun0: overwritten slot 0 snd0 pst=cfg: device requested worker: send: cmd = 0, num = 0, mode = 2, fd = -1 worker: recv: cmd = 3, num = 0, mode = 0, fd = -1 snd0 pst=cfg: rsnd/1: failed to open audio device sock,rmsg,widl: closing sock(sock|zom): destroyed helper: recv: cmd = 0, num = 0, mode = 2, fd = -1 helper: send: cmd = 3, num = 0, mode = 0, fd = -1 ^Cworker(worker|zom): destroyed listen(/tmp/aucat/aucat0|zom): destroyed snd0 pst=cfg: draining nothing to do... snd0 pst=cfg: deleting helper: hup helper(helper|zom): destroyed nothing to do... If you unplug and re-plug the uaudio(4), start sndiod(8) and set gstreamer to use the snd/n device, all is good again: # sndiod -ddd -f rsnd/1 snd0 pst=cfg.default: rec=0:1 dup helper(helper|ini): created worker(worker|ini): created listen(/tmp/aucat/aucat0|ini): created sock(sock|ini): created sock,rmsg,widl: AUTH message helper: recv: cmd = 0, num = 0, mode = 2, fd = -1 helper: send: cmd = 3, num = 0, mode = 0, fd = 3 sock,rmsg,widl: HELLO message sock,rmsg,widl: hello from <gst-launch->, mode = 2, ver 7 sock,rmsg,widl: using snd0 pst=cfg.default, mode = 2 gstlaun0: overwritten slot 0 snd0 pst=cfg: device requested worker: send: cmd = 0, num = 0, mode = 2, fd = -1 worker: recv: cmd = 3, num = 0, mode = 0, fd = 6 sio(rsnd/1|ini): created dec: s24le3, 2 channels snd0 pst=ini: 48000Hz, s24le3, rec 0:1, 8 blocks of 960 frames gstlaun0 vol=127,pst=ini,mmc=off,rmsg,widl: SETPAR message gstlaun0 vol=127,pst=ini,mmc=off,rmsg,widl: recording channels 0:1 -> 0:1 gstlaun0 vol=127,pst=ini,mmc=off,rmsg,widl: 44100Hz sample rate, 882 frame blocks gstlaun0 vol=127,pst=ini,mmc=off,rmsg,widl: 8820 frame buffer gstlaun0 vol=127,pst=ini,mmc=off,rmsg,widl: GETPAR message gstlaun0 vol=127,pst=ini,mmc=off,rmsg,widl: GETPAR message gstlaun0 vol=127,pst=ini,mmc=off,rmsg,widl: START message gstlaun0 vol=127,pst=ini,mmc=off: recording s16le <- s24le3 gstlaun0 vol=127,pst=ini,mmc=off: allocated 8820/15876 fr buffers snd0 pst=ini: device started snd0 pst=run: started gstlaun0 vol=127,pst=run,mmc=off: attached at 0, delta = 0 cmap: nch = 2, ostart = 0, onext = 0, istart = 0, inext = 0 resamp: 960/882 gstlaun0 vol=127,pst=run,mmc=off: 44100Hz, s16le, rec 0:1, 10 blocks of 882 frames sock(sock|ini): processed in 6309us gstlaun0 vol=127,pst=run,mmc=off,rmsg,widl: building SETVOL message, vol = 127 gstlaun0 vol=127,pst=run,mmc=off,rmsg,widl: STOP message gstlaun0 vol=127,pst=run,mmc=off: stopping gstlaun0 vol=127,pst=run,mmc=off: detaching gstlaun0 vol=127,pst=ini,mmc=off,rmsg,widl: stopped gstlaun0 vol=127,pst=ini,mmc=off,rmsg,widl: building STOP message gstlaun0 vol=127,pst=ini,mmc=off,rmsg,widl: BYE message gstlaun0 vol=127,pst=ini,mmc=off,rmsg,widl: closing snd0 pst=run: device released sock(sock|zom): destroyed snd0 pst=run: device stopped snd0 pst=run: stopped, load avg = 6957 / 162320 snd0 pst=ini: closing snd0 pst=cfg: closed sio(rsnd/1|zom): destroyed sio(rsnd/1|zom): processed in 23004us ^Cworker(worker|zom): destroyed listen(/tmp/aucat/aucat0|zom): destroyed snd0 pst=cfg: draining nothing to do... snd0 pst=cfg: deleting helper: hup helper(helper|zom): destroyed nothing to do... $ env AUDIODEVICE=snd/0 gst-launch-1.0 -v sndiosrc ! fakesink --gst-debug=sndio:9 0:00:00.099699000 94966 0x15a533946c10 LOG sndio gstsndio.c:77:GstCaps *gst_sndio_getcaps(struct gstsndio *, GstCaps *):<sndiosrc0> getcaps called, returning template caps 0:00:00.099898000 94966 0x15a533946c10 LOG sndio gstsndio.c:77:GstCaps *gst_sndio_getcaps(struct gstsndio *, GstCaps *):<sndiosrc0> getcaps called, returning template caps Setting pipeline to PAUSED ... 0:00:00.100517000 94966 0x15a533946c10 DEBUG sndio gstsndio.c:111:gboolean gst_sndio_open(struct gstsndio *, gint):<sndiosrc0> open 0:00:00.101631000 94966 0x15a533946c10 DEBUG sndio gstsndio.c:213:gboolean gst_sndio_open(struct gstsndio *, gint): caps are audio/x-raw, rate=(int){ 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000, 128000, 176400, 192000 }, channels=(int){ 1, 2, 4, 6, 8, 10, 12, 16 }, format=(string){ S8, U8, S16BE, S16LE, S24BE, S24LE }, layout=(string)interleaved Pipeline is live and does not need PREROLL ... /GstPipeline:pipeline0/GstSndioSrc:sndiosrc0: mute = false /GstPipeline:pipeline0/GstSndioSrc:sndiosrc0: volume = 1 Setting pipeline to PLAYING ... New clock: GstAudioSrcClock 0:00:00.105053000 94966 0x15a5da9bb630 LOG sndio gstsndio.c:81:GstCaps *gst_sndio_getcaps(struct gstsndio *, GstCaps *):<sndiosrc0> returning audio/x-raw, rate=(int){ 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000, 128000, 176400, 192000 }, channels=(int){ 1, 2, 4, 6, 8, 10, 12, 16 }, format=(string){ S8, U8, S16BE, S16LE, S24BE, S24LE }, layout=(string)interleaved 0:00:00.105411000 94966 0x15a5da9bb630 DEBUG sndio gstsndio.c:246:gboolean gst_sndio_prepare(struct gstsndio *, GstAudioRingBufferSpec *):0x15a5f8656400 prepare /GstPipeline:pipeline0/GstSndioSrc:sndiosrc0: actual-buffer-time = 360000 /GstPipeline:pipeline0/GstSndioSrc:sndiosrc0: actual-latency-time = 20000 Redistribute latency... /GstPipeline:pipeline0/GstSndioSrc:sndiosrc0.GstPad:src: caps = audio/x-raw, rate=(int)44100, channels=(int)2, format=(string)S16LE, layout=(string)interleaved /GstPipeline:pipeline0/GstFakeSink:fakesink0.GstPad:sink: caps = audio/x-raw, rate=(int)44100, channels=(int)2, format=(string)S16LE, layout=(string)interleaved /GstPipeline:pipeline0/GstSndioSrc:sndiosrc0: mute = false /GstPipeline:pipeline0/GstSndioSrc:sndiosrc0: volume = 1 Got EOS from element "pipeline0". Execution ended after 0:00:00.139063000 Setting pipeline to PAUSED ... Setting pipeline to READY ... Setting pipeline to NULL ... 0:00:00.259600000 94966 0x15a533946c10 DEBUG sndio gstsndio.c:220:gboolean gst_sndio_close(struct gstsndio *):<sndiosrc0> close Freeing pipeline ...