Question regarding use of interleaved and deinterleaved elements in processing chain

public-hk at ind.rwth-aachen.de public-hk at ind.rwth-aachen.de
Wed Aug 24 20:03:10 UTC 2016


Am 23.08.2016 um 15:29 schrieb Sebastian Dröge:
> On Tue, 2016-08-23 at 15:23 +0200, Hauke Krüger wrote:
>> On 08/23/2016 10:24 AM, Sebastian Dröge wrote:
>>> On Mon, 2016-08-22 at 21:15 +0200, Hauke Krüger wrote:
>>>>> You'll have to connect to the "pad-added" signal of it, and from there
>>>>> link the pads further. See also the first part in chapter 8 of the
>>>>> manual (application developer's manual).
>>>> Yes, that worked out as you said. However, it seems to be impossible to
>>>> set the pipeline into the
>>>> PLAYING state afterwards: Whenever trying to set the state of the
>>>> pipeline to PLAYING, the pipeline element
>>>> is blocked since it expects an ASYNC state change which unfortunately
>>>> never really is solved.
>>>>
>>>> How is that part supposed to work? Is there any way to somehow observe
>>>> the ASYNC state change by catching
>>>> a message in the main loop?
>>> That all depends on your actual pipeline. How does it look like?
>>>
>>> Most commonly this means that you have one or more sinks in your
>>> pipeline that never receive any buffer and are async=true (which is the
>>> default). You should check where data flows in your pipeline and why it
>>> doesn't reach all sinks. Also check if you get any error messages.
>>>
>>>
>> My pipeline is rather simple:
>>
>> alsasrc -> capsfilter -> deinterleaver -<channel0>-> interleaver -> 
>> capsfilter -> alsasink
>> -<channel1>->
>>
>> alsasrc and alsasink are configured to allow 2 channels, no rate 
>> conversion must be
>> done.
>>
>> I tracked the problem by means of my debugger: once all pads are 
>> connected, I can see
>> the deinterleaver working: It has 2 output sources and I can see the 
>> code in which the deinterleaver
>> loops over all sources here: deinterleave.c, line 896 (current master 
>> release of gstreamer 1.0 project).
>> I see that the function "gst_pad_push" is used within the loop to pass 
>> the single buffers to the connected
>> interleaver sink.
>>
>> When debugging into this function call of "gst_pad_push" for the first 
>> single buffer to be transferred, I end
>> up in "gstcollectpad.c" since the interleaver seems to use this 
>> collector block. The buffers seem to arrive
>> in  function "gst_collect_pads_chain" to wait for all buffers before 
>> interleaving takes place.
>>
>> Debugger shows that the first buffer is accepted but the program flow 
>> ends in a non-returning wait condition
>> in line 2257 in "gstcollectpad.c",
>>
>> /* wait to be collected, this must happen from another thread triggered
>>       * by the _chain function of another pad. We release the lock so we
>>       * can get stopped or flushed as well. We can however not get EOS
>>       * because we still hold the STREAM_LOCK.
>>       */
>>      GST_COLLECT_PADS_STREAM_UNLOCK (pads);
>>      GST_COLLECT_PADS_EVT_WAIT (pads, cookie); <---- HERE
>>      GST_COLLECT_PADS_STREAM_LOCK (pads);
>>
>> It seems that the wait will persist locked until the chain function is 
>> called from within the context of another thread.
>>
>> This behavior would make sense if the deinterleaver would decompose the 
>> single buffers to be
>> processed within different thread contexts. This, however, seems not to 
>> be the case.
> That's exactly the problem: you have to put a queue element after each
> deinterleave pad for adding this new thread.
>
>

Thank you, that was the trick I was looking for ;-)

For those who will run into the same problem: If you connect the
interleaver to alsasink, you will
in addition need to provide a channel mask by setting the property
"channel-positions" properly.
Otherwise, the interleaver will not connect to alsasink.
And if you set that property, you will need to link against the
gstreamer-audio library in order to set the
correct GValue type (type|GST_TYPE_AUDIO_CHANNEL_POSITION)|.

And finally: we have a soundcard running which has 196 channels. The
interleave gstreamer plugin has a limitation
to expect a maximum of 64 channels only: In line 63 of interleaver.h,
the limitatin is given as

gint default_channels_ordering_map[64];

By connecting 196 channels, this limit does not really stop the
interleaver from returning requested pads as it seems.
But it will cause a segmentatin fault later. Setting the 64 to 196
solved this problem. The same modification maybe done in line 275 in
file interleave.c. But I have to admit those 196 channels are really an
unexpected hardware setting.

Thank you and best regards

Hauke


>
> _______________________________________________
> gstreamer-devel mailing list
> gstreamer-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel

-- 
Dr.-Ing. Hauke Krüger
Institute of Communication Systems (IKS)
RWTH Aachen University
Muffeter Weg 3a, 52074 Aachen, Germany
+49 241 80 26963
krueger at iks.rwth-aachen.de
http://www.iks.rwth-aachen.de

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/gstreamer-devel/attachments/20160824/1292596b/attachment-0001.html>


More information about the gstreamer-devel mailing list