GNOME Bugzilla – Bug 345188
[alsa] can't handle more than 8 channels
Last modified: 2006-08-03 14:16:57 UTC
GST_DEBUG="alsa*:4" gst-launch-0.10 filesrc location=xyz.mp3 ! mad ! alsasink DEBUG (0x8051260 - 0:00:00.116843000) alsa( 3859) gstalsaplugin.c(75):plugin_init: binding text domain gst-plugins-base-0.10 to locale dir /opt/gnome/share/locale DEBUG (0x8051260 - 0:00:00.117223000) alsa( 3859) gstalsasink.c(273):gst_alsasink_init:<GstAlsaSink@0x80fb4c8> initializing alsasink DEBUG (0x8051260 - 0:00:00.117779000) alsa( 3859) gstalsasink.c(303):gst_alsasink_getcaps:<alsasink0> device not open, using template caps Setting pipeline to PAUSED ... Pipeline is PREROLLING ... DEBUG (0x8104750 - 0:00:00.121841000) alsa( 3859) gstalsasink.c(567):alsasink_parse_spec:<alsasink0> Linear format : depth=32, width=32, sign=1, bigend=0 DEBUG (0x8104750 - 0:00:00.121879000) alsa( 3859) gstalsasink.c(339):set_hwparams:<alsasink0> Negotiating to 2 channels @ 44100 Hz (format = S32_LE) WARN (0x8104750 - 0:00:00.122017000) alsa( 3859) gstalsasink.c(461):set_hwparams:<alsasink0> error: Could not open device for playback in stereo mode. WARN (0x8104750 - 0:00:00.122037000) alsa( 3859) gstalsasink.c(461):set_hwparams:<alsasink0> error: Das Argument ist ungültig F
What's the output of GST_DEBUG="alsa*:5" gst-launch-0.10 filesrc location=xyz.mp3 ! mad ! audioconvert ! alsasink ? My guess is: this is really a bug. It doesn't probe the device before it's opened, so basically what happens is that mad and alsasink are linked wrongly (which wouldn't have happend had alsasink already probed its caps) and then it errors out correct as it is being given a wrong format.
isn't really a bug, I meant of course ;)
now this is fun > GST_DEBUG="alsa*:5" gst-launch-0.10 filesrc location=xyz.mp3 ! mad ! audioconvert ! alsasink device=hw:0,0 DEBUG (0x8051260 - 0:00:00.107326000) alsa(15947) gstalsasink.c(273):gst_alsasink_init:<GstAlsaSink@0x8101338> initializing alsasink DEBUG (0x8051260 - 0:00:00.110051000) alsa(15947) gstalsasink.c(303):gst_alsasink_getcaps:<alsasink0> device not open, using template caps Setting pipeline to PAUSED ... Pipeline is PREROLLING ... LOG (0x8103588 - 0:00:00.114676000) alsa(15947) gstalsa.c(30):gst_alsa_detect_rates:<alsasink0> probing sample rates ... DEBUG (0x8103588 - 0:00:00.114706000) alsa(15947) gstalsa.c(49):gst_alsa_detect_rates:<alsasink0> Min. rate = 8000 (8000) DEBUG (0x8103588 - 0:00:00.114722000) alsa(15947) gstalsa.c(50):gst_alsa_detect_rates:<alsasink0> Max. rate = 96000 (96000) LOG (0x8103588 - 0:00:00.114738000) alsa(15947) gstalsa.c(233):gst_alsa_detect_channels:<alsasink0> probing channels ... DEBUG (0x8103588 - 0:00:00.114753000) alsa(15947) gstalsa.c(265):gst_alsa_detect_channels:<alsasink0> Min. channels = 10 (10) DEBUG (0x8103588 - 0:00:00.114769000) alsa(15947) gstalsa.c(266):gst_alsa_detect_channels:<alsasink0> Max. channels = 8 (10) INFO (0x8103588 - 0:00:00.114793000) alsa(15947) gstalsasink.c(323):gst_alsasink_getcaps:<alsasink0> returning caps audio/x-raw-int, endianness=(int)1234, signed=(boolean)true, width=(int)32, depth=(int)32, rate=(int)[ 8000, 96000 ], channels=(int)10 ERROR (0x8103588 - 0:00:00.114890000) GST_CAPS(15947) gstpad.c(1862):gst_pad_get_caps_unlocked:<alsasink0:sink> pad returned caps audio/x-raw-int, endianness=(int)1234, signed=(boolean)true, width=(int)32, depth=(int)32, rate=(int)[ 8000, 96000 ], channels=(int)10 which are not a real subset of its template caps audio/x-raw-int, endianness=(int){ 1234, 4321 }, signed=(boolean){ true, false }, width=(int)32, depth=(int)32, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 8 ]; audio/x-raw-int, endianness=(int){ 1234, 4321 }, signed=(boolean){ true, false }, width=(int)16, depth=(int)16, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 8 ]; audio/x-raw-int, signed=(boolean){ true, false }, width=(int)8, depth=(int)8, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 8 ] (gst-launch-0.10:15947): GStreamer-WARNING **: pad alsasink0:sink returned caps that are not a real subset of its template caps LOG (0x8103588 - 0:00:00.115108000) alsa(15947) gstalsasink.c(308):gst_alsasink_getcaps:<alsasink0> Returning cached caps ERROR (0x8103588 - 0:00:00.115161000) GST_CAPS(15947) gstpad.c(1862):gst_pad_get_caps_unlocked:<alsasink0:sink> pad returned caps audio/x-raw-int, endianness=(int)1234, signed=(boolean)true, width=(int)32, depth=(int)32, rate=(int)[ 8000, 96000 ], channels=(int)10 which are not a real subset of its template caps audio/x-raw-int, endianness=(int){ 1234, 4321 }, signed=(boolean){ true, false }, width=(int)32, depth=(int)32, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 8 ]; audio/x-raw-int, endianness=(int){ 1234, 4321 }, signed=(boolean){ true, false }, width=(int)16, depth=(int)16, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 8 ]; audio/x-raw-int, signed=(boolean){ true, false }, width=(int)8, depth=(int)8, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 8 ] (gst-launch-0.10:15947): GStreamer-WARNING **: pad alsasink0:sink returned caps that are not a real subset of its template caps FEHLER: Von Element /pipeline0/filesrc0: Internal data flow error.
Created attachment 67650 [details] [review] avoid min>max This patch at least fixes the min>max problem that occurs if min-channels > GST_ALSA_MAX_CHANNELS. Still need to figure out why alsa reports min-channels=10 (the hardware has 10 channels).
> Still need to figure out why alsa reports min-channels=10 (the hardware has 10 > channels). That's probably dmix, which will only settle for min_channels = max_channels min_rate = max_rate and the format with the max. bytes per sample
*** Bug 346326 has been marked as a duplicate of this bug. ***
Created attachment 68813 [details] [review] possible fix Possible fix. Can't test it here, so would appreciate feedback. There is a policy question involved here; basically, the question is: how do we want input with N channels and no channel layout to be represented, given our current policy that all caps with more than 2 channels must contain a channel layout as well? This patch just adds a layout with all channels being set to FRONT_MONO (which could be some new UNDEFINED enum or something as well). Theoretically, it would also be an option to provide all channels on separate pads in this case, with one channel each (makes implementation a lot more awkward though for very little benefit IMHO). Or we could just not attach any layout at all, but that seems a bit inconsistent to me.
this seems to be not yet it (same when trying to play a stereo mp3): > gst-launch-0.10 audiotestsrc ! alsasink device=hw:1 Setting pipeline to PAUSED ... ERROR: Pipeline doesn't want to pause. FEHLER: Von Element /pipeline0/audiotestsrc0: Could not negotiate format Zusätzliche Debugginginformation: gstbasesrc.c(1786): gst_base_src_start (): /pipeline0/audiotestsrc0: Check your filtered caps, if any Setting pipeline to NULL ... FREEING pipeline ... > gst-launch-0.10 audiotestsrc ! audioconvert ! alsasink device=hw:1 Setting pipeline to PAUSED ... Pipeline is PREROLLING ... FEHLER: Von Element /pipeline0/alsasink0: Could not open device for playback in 3-channel mode. Zusätzliche Debugginginformation: gstalsasink.c(461): set_hwparams (): /pipeline0/alsasink0: Das Argument ist ungültig ERROR: pipeline doesn't want to preroll. Setting pipeline to NULL ... FREEING pipeline ...
Yeah, the patch needs some more work (a new define like POS_UNDEFINED that also doesn't fail the duplicates check in libgstaudio, for example). The first error is not really a bug/problem, since audiotestsrc only supports one channel as output. So this is an audiotestsrc limitation, no? The second pipeline might or might not work. If the card returns min_channels=10 or whatever I wouldn't expect this to work in any meaningful way really (audioconvert limitation). I am not sure if this should ever work if the card returns min_channels=10. Does the second pipeline work with device=plughw:1 ? Will make a new patch tomorrow ...
gst-launch-0.10 audiotestsrc ! alsasink device=plughw:1 works. Same for playing stereo mp3. I will investigate if I can somehow tell alsa how the 10 channels of the card are configured (they are configured as 5 stereo pairs).
Created attachment 69046 [details] [review] second attempt, this time adding a GST_AUDIO_CHANNEL_POSITION_UNDEFINED So, another attempt. There are two separate issues/use cases here: (a) alsasink, and (b) alsasrc. For alsasink, I don't think it's particularly bad if things don't work out of the box with playbin/whatever. If the card says min_channels=10, there's not much we can do IMHO. These are semi-professional/professional cards and not user cards, so I think it's okay to just have owners of cards like this configure their system so that device=plughw:0 is used for totem/rhythmbox/etc. Applications that are geared to make use of that many output channels will just have to handle this themselves by creating/merging the output appropriately IMHO. It is unfortunate though that the merging element would be outputting caps with UNDEFINED channel positions again (to please caps negotiation). Maybe we should just not attach any positions at all in the >8 channels case? However, that would be inconsistent then. Not sure what the best thing to do is. Same for alsasrc really: applications that handle that many inputs will have to do so in a special way and split the N*UNDEFINED output in a way that can be processed normally in GStreamer (ie pairs of stereo streams or whatever). Doesn't really feel right yet. Comments?
gst-launch-0.10 audiotestsrc ! audioconvert ! alsasink device=hw:1 Setting pipeline to PAUSED ... ERROR (0x8052258 - 0:00:00.119764000) GST_CAPS(20068) gstpad.c(1904):gst_pad_get_caps_unlocked:<alsasink0:sink> pad returned caps audio/x-raw-int, endianness=(int)1234, signed=(boolean)true, width=(int)32, depth=(int)32, rate=(int)[ 8000, 96000 ], channels=(int)10 which are not a real subset of its template caps audio/x-raw-int, endianness=(int){ 1234, 4321 }, signed=(boolean){ true, false }, width=(int)32, depth=(int)32, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 8 ]; audio/x-raw-int, endianness=(int){ 1234, 4321 }, signed=(boolean){ true, false }, width=(int)16, depth=(int)16, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 8 ]; audio/x-raw-int, signed=(boolean){ true, false }, width=(int)8, depth=(int)8, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 8 ] (gst-launch-0.10:20068): GStreamer-WARNING **: pad alsasink0:sink returned caps that are not a real subset of its template caps anyway with plughw: it works (no need to audioconvert)
Created attachment 69165 [details] [review] same as before plus updated alsasink caps templates Ah, right, the template in alsasink needs updating as well. Thanks for testing this.
okay the caps stuff is fixed. Do you understand why it is going to open the device in *3*-channel mode? What exactly is 3 channel mode and why 3 and not 5 or perhaps 1. > gst-launch-0.10 audiotestsrc ! audioconvert ! alsasink device=hw:0 Setting pipeline to PAUSED ... Pipeline is PREROLLING ... ERROR: from element /pipeline0/alsasink0: Could not open device for playback in 3-channel mode. Additional debug info: gstalsasink.c(461): set_hwparams (): /pipeline0/alsasink0: Invalid argument ERROR: pipeline doesn't want to preroll. ...
(In reply to comment #14) > okay the caps stuff is fixed. Do you understand why it is going to open the > device in *3*-channel mode? What exactly is 3 channel mode and why 3 and not 5 > or perhaps 1. No idea why it negotiates to 3 channels. Maybe you could attach a full GST_DEBUG=*:5 log so we don't have to take wild guesses as to what's happening? :)
I belive the problem is in gstalsa.c:caps_add_channel_configuration() with if (max_chans >= 3) { ... } ... for (c = 4; c <= 8; c += 2) { ... } it creates channel configs starting with channels=3, whereas min_chans=max_chans=10 in my case. So it should rather be if (max_chans >= 3 && min_chans<=3) { ... } ...
Created attachment 69313 [details] [review] new patch Indeed, nice catch, thanks. Updated the patch for that. and it should also be /* everything else (4, 6, 8 channels) needs a channel layout */ - for (c = 4; c <= 8; c += 2) { + for (c = MAX (4, min_chans); c <= 8; c += 2) { ... } I presume. The patch also changes the channel position validity check in multichannel.c so that it is no longer allowed to have only some channel positions UNDEFINED. Either all are UNDEFINED or all are defined, but mixing UNDEFINED with other channel positions isn't allowed. I think that makes sense (and we can still permit additional possibilities later if it seems necessary, but we can't really change it to be stricter).
Your pipeline will still not work of course, but it should be audioconvert that errors out because it doesn't know what to do.
Stefan: Does gst-launch-0.10 -v alsasrc ! alsasink go into PLAYING state successfully with that card and this patch? And does it negotiate to 10 channels (or whatever it was)? Michael (Sheldon): Do you have any comments about this? Does this patch work fine for you? Does the channel layout assignment stuff seem to make sense to you? Any other comments? (such as on the usage of _UNDEFINED and the policy involved)
I think the patch is now correct. gst-launch-0.10 -v alsasrc ! alsasink still does not play as my card actually has 12 inputs and 10 outputs :) but it correctly fails. so +1 for commiting from me.
Committed, but renamed AUDIO_CHANNEL_POSITION_UNDEFINED to _NONE: 2006-08-03 Tim-Philipp Müller <tim at centricular dot net> * ext/alsa/gstalsa.c: (caps_add_channel_configuration), (gst_alsa_detect_channels): * ext/alsa/gstalsasink.c: Add support for cards that (only) do more than 8 channels, like the Delta 44 (#345188). * gst-libs/gst/audio/multichannel.c: (gst_audio_check_channel_positions): * gst-libs/gst/audio/multichannel.h: API: add GST_AUDIO_CHANNEL_POSITION_NONE, which stands for an unspecified channel position and cannot be combined with any of the other audio channel positions; adjust position layout checks accordingly (#345188).