Maximum number of audio channels in alsasrc
Konstantin K. Oblaukhov
Oblaukhov at sl.iae.nsk.su
Fri Dec 7 04:54:53 UTC 2018
Hello all.
I'm an Linux driver/software developer in a company producing custom video capture boards for PCIe.
Our drivers using v4l2 and alsa API, and some of our customers uses gstreamer to process video.
One of our customer requires to capture 16 audio channels (8 stereo pairs) from SDI and faced issue with simple pipeline:
$ gst-launch-1.0 alsa-src device=hw:1,0 ! audio/x-raw,channels=16 ! fakesink
Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
Setting pipeline to PLAYING ...
New clock: GstAudioSrcClock
ERROR: from element /GstPipeline:pipeline0/GstAlsaSrc:alsasrc0: Internal data stream error.
Additional debug info:
gstbasesrc.c(3055): gst_base_src_loop (): /GstPipeline:pipeline0/GstAlsaSrc:alsasrc0:
streaming stopped, reason not-negotiated (-4)
Execution ended after 0:00:00.000081501
Setting pipeline to PAUSED ...
Setting pipeline to READY ...
Setting pipeline to NULL ...
Freeing pipeline ...
$
same pipeline works with channels=4 and channels=8.
arecord captures 16 channels sucessfully.
After some investigation I've found this interesting code in gst-plugins-base/ext/alsa/gstalsa.c:
/* we don't have channel mappings for more than this many channels */
#define GST_ALSA_MAX_CHANNELS 8
....
static GstCaps *
gst_alsa_detect_channels (GstObject * obj, snd_pcm_hw_params_t * hw_params,
GstCaps * in_caps)
{
....
if ((err = snd_pcm_hw_params_get_channels_min (hw_params, &min)) < 0)
goto min_chan_error;
if ((err = snd_pcm_hw_params_get_channels_max (hw_params, &max)) < 0)
goto max_chan_error;
min_chans = min;
max_chans = max;
if (min_chans < 0) {
min_chans = 1;
max_chans = GST_ALSA_MAX_CHANNELS;
} else if (max_chans < 0) {
max_chans = GST_ALSA_MAX_CHANNELS;
}
....
/* pro cards seem to return large numbers for min_channels */
if (min_chans > GST_ALSA_MAX_CHANNELS) {
GST_DEBUG_OBJECT (obj, "min_chans = %u, looks like a pro card", min_chans);
if (max_chans < min_chans) {
max_chans = min_chans;
} else {
/* only support [max_chans; max_chans] for these cards for now
* to avoid inflating the source caps with loads of structures ... */
min_chans = max_chans;
}
} else {
min_chans = MAX (min_chans, 1);
max_chans = MIN (GST_ALSA_MAX_CHANNELS, max_chans);
}
Our board returns min_chans=1, max_chans=16, so gstreamer limits it to 1-8
And now, some questions arising:
1) Why there is limit for 8 channels?
Yes, common 7.1 audio is maximum you can face in real video files.
But in case of SDI 16 channels is usually used as 8 stereo pairs for transferring 8 different languages at same time.
This 8 streams MUST be synchronous, so they are interleaved in one 16-channel stream.
I'm not a GStreamer expert, but it seems that it can support up to 64 channels at least (according to channel mask width), that "pro card" condition proves that.
Is that "caps inflating" is a real problem?
2) Ok, I can accept 8-channel limit, and that "pro card" term, but why condition ("min_chans > GST_ALSA_MAX_CHANNELS") is so strange?
For example, 1-32 card will be limited to 1-8 (gstreamer will generate 8 caps for 1-8 channels, as I understood), but, if same card will report 16-32 channels it will be limited to 32-32 (single cap).
Makes no sense for me. Condition "(min_chans > GST_ALSA_MAX_CHANNELS) || (max_chans > GST_ALSA_MAX_CHANNELS)" looks more correct, IMO.
It would be nice if someone explained that to me...
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/gstreamer-devel/attachments/20181207/0a8f05e4/attachment-0001.html>
More information about the gstreamer-devel
mailing list