4

I'm trying to get 28 channels out of a jackaudiosrc but as soon as I connect, say, a deinterleave element, the source will fall back to the 2-channel setup that works without any channel mask. My attempts at setting a channel mask have been futile.

Here's what happens:

potential caps: audio/x-raw-float, endianness=(int)1234, width=(int)32, rate=(int)48000, channels=(int)[ 1, 28 ]
filter caps: audio/x-raw-float, channels=(int)28, channel-positions=(GstAudioChannelPosition)< GST_AUDIO_CHANNEL_POSITION_NONE, GST_AUDIO_CHANNEL_POSITION_NONE, GST_AUDIO_CHANNEL_POSITION_NONE, GST_AUDIO_CHANNEL_POSITION_NONE, GST_AUDIO_CHANNEL_POSITION_NONE, GST_AUDIO_CHANNEL_POSITION_NONE, GST_AUDIO_CHANNEL_POSITION_NONE, GST_AUDIO_CHANNEL_POSITION_NONE, GST_AUDIO_CHANNEL_POSITION_NONE, GST_AUDIO_CHANNEL_POSITION_NONE, GST_AUDIO_CHANNEL_POSITION_NONE, GST_AUDIO_CHANNEL_POSITION_NONE, GST_AUDIO_CHANNEL_POSITION_NONE, GST_AUDIO_CHANNEL_POSITION_NONE, GST_AUDIO_CHANNEL_POSITION_NONE, GST_AUDIO_CHANNEL_POSITION_NONE, GST_AUDIO_CHANNEL_POSITION_NONE, GST_AUDIO_CHANNEL_POSITION_NONE, GST_AUDIO_CHANNEL_POSITION_NONE, GST_AUDIO_CHANNEL_POSITION_NONE, GST_AUDIO_CHANNEL_POSITION_NONE, GST_AUDIO_CHANNEL_POSITION_NONE, GST_AUDIO_CHANNEL_POSITION_NONE, GST_AUDIO_CHANNEL_POSITION_NONE, GST_AUDIO_CHANNEL_POSITION_NONE, GST_AUDIO_CHANNEL_POSITION_NONE, GST_AUDIO_CHANNEL_POSITION_NONE, GST_AUDIO_CHANNEL_POSITION_NONE >
actual caps: audio/x-raw-float, endianness=(int)1234, width=(int)32, rate=(int)48000, channels=(int)2, channel-positions=(GstAudioChannelPosition)< GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT >

And here's the Python code that produces that output:

import pygst
pygst.require("0.10")
import gst
import gobject
import gst.audio

gobject.threads_init()
pipeline = gst.Pipeline("mypipeline")
src = gst.element_factory_make("jackaudiosrc", "jacksrc")
pipeline.add(src)
srcpad = src.get_pad("src")
pipeline.set_state(gst.STATE_PLAYING)
print 'potential caps:',srcpad.get_caps()
sink = gst.element_factory_make("fakesink", "sink")
pipeline.add(sink)
filtercaps = gst.caps_from_string("audio/x-raw-float,channels=28")
filtercaps[0].set_value("channel-positions", tuple([gst.audio.AUDIO_CHANNEL_POSITION_NONE]*28))
print "filter caps:",filtercaps
src.link_filtered(sink, filtercaps)
pipeline.set_state(gst.STATE_PLAYING)
print 'actual caps:',srcpad.get_negotiated_caps()
#gst.DEBUG_BIN_TO_DOT_FILE_WITH_TS(pipeline, gst.DEBUG_GRAPH_SHOW_ALL, 'caps')

I also tried to set the caps of the output directly instead of using a filter but that didn't do anything either.

Here's the output of that last bin-to-dot-file line (click to enlarge).

dot file output for 0.10

Here's a gst-launch line that works without an actual multichannel audio setup but does not actually reproduce the error, I believe because the interleave element sets the NONE caps correctly by default while the jackaudiosrc doesn't. Maybe it still helps people to play around with this issue who can't reproduce it themselves because of technical restrictions. Credit to http://tristanswork.blogspot.de/2008/08/multichannel-audio-with-gstreamer.html for the original launch line that I adapted.

gst-launch-0.10 interleave name=i ! audioconvert ! audioresample ! queue ! deinterleave name=o audiotestsrc ! audioconvert ! queue ! i. audiotestsrc ! audioconvert ! queue ! i. audiotestsrc ! audioconvert ! queue ! i. o. ! queue ! fakesink dump=true o. ! queue ! fakesink dump=true o. ! queue ! fakesink dump=true

Edit: I now tried to do the same thing in GStreamer 1.x. The tuple data type is no longer accepted so here's what I came up with after having a look at others wrote channel positions directly to the get_caps_from_string function.

from gi.repository import GObject, Gst, GstAudio
GObject.threads_init()
Gst.init(None)
pipeline = Gst.Pipeline("mypipeline")
src = Gst.ElementFactory.make("jackaudiosrc", "jacksrc")
pipeline.add(src)
srcpad = src.get_static_pad("src")
pipeline.set_state(Gst.State.PLAYING)
print 'potential caps:', srcpad.query_caps()
sink = Gst.ElementFactory.make("fakesink", "sink")
pipeline.add(sink)
filtercaps = Gst.caps_from_string("audio/x-raw, channels=(int)28, channel-positions=(int)< 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28 >")
print "filter caps:", filtercaps
src.link_filtered(sink, filtercaps)
pipeline.set_state(Gst.State.PLAYING)
print 'actual caps:', srcpad.get_current_caps()
Gst.debug_bin_to_dot_file_with_ts(pipeline, Gst.DebugGraphDetails.ALL, 'caps')

The output both in text form and the graph are shockingly similar:

potential caps: audio/x-raw, format=(string)F32LE, layout=(string)interleaved, rate=(int)48000, channels=(int)[ 1, 28 ]
filter caps: audio/x-raw, channels=(int)28, channel-positions=(int)< 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28 >
actual caps: audio/x-raw, format=(string)F32LE, layout=(string)interleaved, rate=(int)48000, channels=(int)2

dot file output for 1.4

Christian
  • 470
  • 6
  • 22

0 Answers0