Newbie question about Pipelines

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Newbie question about Pipelines

Manuel.Serrano
Hello there,

I hope that this mailing is the good place to post this mail, if not, you
will pardon me...

I'm quite new to Gstreamer and I have a stupid question. It's probably
very naive and also it has probably been already asked. However, I
have browsed the mailing list archive without discovering the
information I'm looking for.

I'm currently developing a binding for Gstreamer for Hop
(http://hop.inria.fr), a new programming language dedicated to
programming interactive and multimedia applications on the Web. I have
a roughly operational binding (even though, I'm still struggling with
some multi-threading and GC issues) and I'm now conducting several
tests. One of this test fail and I cannot find the reason for that
failure.

For those that are interested, I attach the actual source code in the
mail but since I don't expect any of you to be familiar with Hop ;-)
I will explain it too...

I have defined a function named "play-streams" that creates an pipeline
containing:

 - a filesrc element
 - a decodebin element
 - an audioconvert element
 - an audioresample element
 - an audiosink element

All the elements are linked together and an asynchronous event handler is
attached for "pad-added" signals.

The function then starts a thread that sets the location property of
the filesrc element, then it sets the state of the pipeline to
GST_STATE_PLAYING.  and it runs a loop that calls "gst_bus_poll" until
and EOS message is intercepted. So far, so good. The music is played
and the signals correctly intercepted.

Now, the problem comes from a second function, named "replay", that
sets the pipeline state to GST_STATE_NULL, then to GST_STATE_READY.
Then it kills the first threads, and it invokes again the function
"play-streams". That is, the function "replay" creates a new pipeline,
filesrc, a new decodebin, etc, and it starts a new thread for polling
messages coming from the associated bus.

This second time, the music is played (that is sound is emitted by the
output speakers) but the threads hangs either in the call
   gst_element_state_set( pipeline, GST_STATE_PLAYING )

or (in a way that looks like unpredictable) in the call to gst_bus_poll.

I imagine that some cleanup is needed on the first pipeline or on the
first audiosink element. I have browsed the Gstreamer's documentation
without discovering the information that could help me solving this
problem. Is there someone here that could help me with this issue?
Many thanks in advance.

Cheers,

--
Manuel


-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gstreamer-devel

bgst-play.scm (8K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Newbie question about Pipelines

Andy Wingo
Hi Manuel,

Sorry for the very late reply. Parentheses can be very distracting!

On Thu 31 Jul 2008 00:56, [hidden email] writes:

> I'm currently developing a binding for Gstreamer for Hop

Neat!

> All the elements are linked together and an asynchronous event handler is
> attached for "pad-added" signals.

Asynchronous is probably bad in this case; the typical behaviour of a
demuxer is to create pads when it finds streams, then start pushing on
those pads. If you do not install a synchronous handler for pad-added to
link that pad downstream, there is a race between the pad addition and
when the streaming thread starts to push; if you lose, the element's
call to gst_pad_push() returns UNLINKED, and the pipeline stops.

Perhaps you have figured a way around this, blocking in the signal
emission and marshalling to the main thread. That sounds like you could
get into deadlocks though -- is that what you're doing?

If you need to do handle pad-added from the main thread, you probably
want to call gst_pad_set_blocked from within a stub handler, set a flag
to signal the main thread to do something, and then return from
pad-added, freeing up the streaming thread to do other things.

> Now, the problem comes from a second function, named "replay", that
> sets the pipeline state to GST_STATE_NULL, then to GST_STATE_READY.

Well, among the other possibilities is that you have run into a bug.
This is not the typical use case for gstreamer; if you want to rewind,
set the pipeline to PAUSED, seek, and then PLAYING. If you really want
to "replay", it's probably just as fast to pass around a thunk to call
to make a new pipeline instead of reusing an old one.

Regards,

Andy
--
http://wingolog.org/

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Newbie question about Pipelines

Manuel.Serrano
Hello Andy,

First of all, thank you very for your help. I appreciate it.

> Asynchronous is probably bad in this case; the typical behaviour of a
> demuxer is to create pads when it finds streams, then start pushing on
> those pads. If you do not install a synchronous handler for pad-added to
> link that pad downstream, there is a race between the pad addition and
> when the streaming thread starts to push; if you lose, the element's
> call to gst_pad_push() returns UNLINKED, and the pipeline stops.
>
> Perhaps you have figured a way around this, blocking in the signal
> emission and marshalling to the main thread. That sounds like you could
> get into deadlocks though -- is that what you're doing?
My problem, in deed, looks like a deadlock. The strange thing is that
when the "replay" function is invoked, the first pipeline stops and
the second one plays the audio content but no message are delivered on
the bus. If I call the "replay" function a second time, everything get
stuck.

> If you need to do handle pad-added from the main thread, you probably
> want to call gst_pad_set_blocked from within a stub handler, set a flag
> to signal the main thread to do something, and then return from
> pad-added, freeing up the streaming thread to do other things.
Pardon me, I do not understand your suggestion. My problem seems definitively
related to multi-threading because if I move the "pad-added" handler
from the main thread to the thread that start the pipeline, everything
blocks. Are you suggesting the problem is coming from g_signal_connect_closure
used in a multi-threaded context.

> > Now, the problem comes from a second function, named "replay", that
> > sets the pipeline state to GST_STATE_NULL, then to GST_STATE_READY.
>
> Well, among the other possibilities is that you have run into a bug.
> This is not the typical use case for gstreamer; if you want to rewind,
> set the pipeline to PAUSED, seek, and then PLAYING. If you really want
My intention here was just to stop the first pipeline before throwing it away.

> to "replay", it's probably just as fast to pass around a thunk to call
> to make a new pipeline instead of reusing an old one.
I realize that the name "replay" is confusing... The program I sent just
do exactly this. It creates a new pipeline and no longer uses the former
one...

Thanks again for your help.

--
Manuel

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Newbie question about Pipelines

Manuel.Serrano
Tracking down possible dead-locks, I have realized that a small modification
to my program makes it work. The "replay" function used to be defined as:

-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----
(define (replay)
   (thread-terminate! thread)
   (gst-element-state-set! pipeline 'null)
   (play-streams))
-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----

Just getting rid of the "thread-terminate!" call fixes the problem.
As far as I understand, a first thread was calling gst_bus_poll. This
thread was abruptly killed by the "tread-terminate!" call while a
gst_bus_poll call was already initiated (and, as unveiled, by GDB, a
gstreamer lock acquired). When the second thread call gst_bus_poll
then it got stuck while trying to get the already locked mutex.

So, if my understanding is correct, the problem was in my program
(I knew from the beginning that the error was mine :-) and not at all
in gstreamer.

Anyhow, thanks again for your mail. It has helped me spotting the problem
by showing me the good direction.

Cheers,

--
Manuel

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gstreamer-devel