GNOME Bugzilla – Bug 766707
alsasrc format=S16BE results in Internal data flow error
Last modified: 2018-01-20 15:56:53 UTC
$ GST_DEBUG="*:2" gst-launch-1.0 -v alsasrc ! audio/x-raw,format=S16BE ! alsasink sync=false Setting pipeline to PAUSED ... Pipeline is live and does not need PREROLL ... Setting pipeline to PLAYING ... New clock: GstAudioSrcClock 0:00:00.024275613 4807 0x1935590 WARN alsa conf.c:4694:snd_config_expand: alsalib error: Unknown parameters {AES0 0x02 AES1 0x82 AES2 0x00 AES3 0x02} 0:00:00.024333166 4807 0x1935590 WARN alsa pcm.c:2239:snd_pcm_open_noupdate: alsalib error: Unknown PCM default:{AES0 0x02 AES1 0x82 AES2 0x00 AES3 0x02} 0:00:00.024386608 4807 0x1935590 WARN basesrc gstbasesrc.c:2865:gst_base_src_loop:<alsasrc0> error: Internal data flow error. 0:00:00.024424785 4807 0x1935590 WARN basesrc gstbasesrc.c:2865:gst_base_src_loop:<alsasrc0> error: streaming task paused, reason not-negotiated (-4) ERROR: from element /GstPipeline:pipeline0/GstAlsaSrc:alsasrc0: Internal data flow error. Additional debug info: gstbasesrc.c(2865): gst_base_src_loop (): /GstPipeline:pipeline0/GstAlsaSrc:alsasrc0: streaming task paused, reason not-negotiated (-4) Execution ended after 0:00:00.000792370 Setting pipeline to PAUSED ... Setting pipeline to READY ... Setting pipeline to NULL ... Freeing pipeline ...
Can you get a full debug log with GST_DEBUG=6? But most likely this means that your driver does not support S16BE, either on the source or sink side or both.
Created attachment 328368 [details] GST_DEBUG="6" GST_DEBUG="6" gst-launch-1.0 -v alsasrc ! audio/x-raw,format=S16BE ! alsasink > debug.log 2>&1 tar -zcvf debug.tar.gz debug.log
I've attached the log file. S16BE is definitely supported on the system, as demonstrated by this loopback: $ arecord -t raw -f S16_BE -r 16000 -c 1 | aplay -t raw -f S16_BE -r 16000 -c 1 Recording raw data 'stdin' : Signed 16 bit Big Endian, Rate 16000 Hz, Mono Playing raw data 'stdin' : Signed 16 bit Big Endian, Rate 16000 Hz, Mono
Adding some code to the gstalsa.c code that determines whether the alsa device supports a particular format, I see that my device does not support S16BE. However, this works fine: arecord -t raw -f S16_BE -r 16000 -c 1 --disable-format -v -v -v This uses Pulseaudio behind the scenes (I'm always a bit confused by alsa using pulse and pulse using alsa, but whatever). So I think your device may well not support S16BE. I'll attach the hack I made if you want to test your device.
diff --git a/ext/alsa/gstalsa.c b/ext/alsa/gstalsa.c index a44e6e1..95286b0 100644 --- a/ext/alsa/gstalsa.c +++ b/ext/alsa/gstalsa.c @@ -144,6 +144,7 @@ format_supported (const GValue * format_val, snd_pcm_format_mask_t * mask, return FALSE; format = gst_audio_format_from_string (g_value_get_string (format_val)); +GST_DEBUG ("XX checking %s", g_value_get_string (format_val)); if (format == GST_AUDIO_FORMAT_UNKNOWN) return FALSE; @@ -157,7 +158,11 @@ format_supported (const GValue * format_val, snd_pcm_format_mask_t * mask, if (pcm_format == SND_PCM_FORMAT_UNKNOWN) return FALSE; - return snd_pcm_format_mask_test (mask, pcm_format); + { + gboolean ret = snd_pcm_format_mask_test (mask, pcm_format); +GST_DEBUG ("XX checking %s: %d", g_value_get_string(format_val), ret); +return ret; + } } static GstCaps *
I'm not sure I understand. You're saying the device does not support S16BE according to GStreamer, but the arecord you're given supposedly works. Isn't that a discrepancy? If you ask me if my device supports it, I shouldn't be using GStreamer to determine that. My bug is about the fact ALSA proves it is natively supported but the plugin fails! Does this mean that the plugin just doesn't support alsa completely? I have no idea how to run such a hack you've provided.
Ok, please relax, arecord uses libalsa audio converters to give you what you asked for. GStreamer has it's own converters, just use them if you need it. Natively, embedded audio cards usually only support the endianness of their CPU. The exception being for dedicated hardware hosting their own memory.
FYI, this is a appropriate pipeline to represent what arecord/aplay will do. gst-launch-1.0 -v alsasrc ! audioconvert ! audio/x-raw,format=S16BE ! audioconvert ! alsasink sync=false
I'm as relaxed as I'll ever be. I think the true core of my bug is misunderstood or ignored. The format is listed when using gst-inspect, the arecord records S16BE natively, but the GStreamer plugin alsasrc gives an internal data flow error. I know how to use audioconvert and how I can use it to get mimic the behaviour, but it doesn't solve the underlying problem I am talking about here. I'll try to word my bug differently: ALSA supports S16BE natively, as shown before, but alsasrc errors when asked to use that format. Thanks for looking into it anyway.
Why do you think your hardware supports S16BE *natively*? As Nicolas mentioned in comment 7, arecord uses the libalsa converters if needed automatically so it will look like everything is supported. If you want the same behaviour, use audioconvert and audioresample. In the pad template caps you will see S16BE in gst-inspect-1.0 because it initially lists all possibilities that all hardware could do. Only once the device is opened (that is, the sink/src is in READY state) the CAPS query on the pad should give the correct caps that are actually supported. Does it list S16BE there?
As Sebastian said, gst-inspect-1.0 shows all formats that alsasrc can theoretically support, the formats actually support by a specific device will depend on the driver and hardware and be a subset of what you see in gst-inspect-1.0. This is what is detected as supported formats for the "default" device: gstalsasrc.c:320:gst_alsasrc_getcaps:<alsasrc0> returning caps audio/x-raw, format=(string){ S16LE, S32LE }, layout=(string)interleaved, rate=(int)[ 4000, 192000 ], channels=(int)2, channel-mask=(bitmask)0x0000000000000003; audio/x-raw, format=(string){ S16LE, S32LE }, layout=(string)interleaved, rate=(int)[ 4000, 192000 ], channels=(int)1; (snipped 3-6 channels structures) Now I don't know what the "default" device maps to exactly, but this shows that ALSA only advertises little endian formats to us. You can try different devices that will do similar things like arecord by going through internal alsa conversion layers. Something like device=plughw:XYZ might do the trick (see arecord -L for list). On my laptop this shows BE formats: GST_DEBUG=*alsa*:6 gst-launch-1.0 alsasrc device=plughw:CARD=PCH,DEV=0 num-buffers=1 ! fakesink 2>&1 | grep getcaps while GST_DEBUG=*alsa*:6 gst-launch-1.0 alsasrc device=default num-buffers=1 ! fakesink 2>&1 | grep getcaps does not.
Closing this bug report as no further information has been provided. Please feel free to reopen this bug report if you can provide the information that was asked for in a previous comment. Thanks!