How to set channel positions / channel mask in gstreamer?

I am trying to get 28 channels from jackaudiosrc

, but as soon as I connect, say, an element deinterleave

, the source reverts to a 2 channel setup, which works without a channel mask. My attempts to set a channel mask were in vain.

Here's what's going on:

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 is the Python code that produces this 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 setting output limits directly instead of using a filter, but that didn't do anything either.

The last line of the bin-to-dot-file is displayed here (click to enlarge).

dot file output for 0.10

Here's a line gst-launch

that works without a real multi-channel audio setup, but doesn't actually reproduce the error, I suppose, because the item interleave

correctly sets the default caching to NONE and jackaudiosrc

doesn't. Perhaps it still helps people to play with this question, which cannot reproduce it on its own due to technical limitations. Sign up http://tristanswork.blogspot.de/2008/08/multichannel-audio-with-gstreamer.html for the original startup string 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 have now tried to do the same in GStreamer 1.x. The datatype is tuple

no longer accepted, so this is what I came up with, looking at others, writing the channel positions directly in the function get_caps_from_string

.

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 in the graph is 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

+3


source to share





All Articles