streaming thread and gst_element_set_state in gstreamer

Taeho Oh ohhara at gmail.com
Thu Jul 10 13:22:14 PDT 2014


Thank you guys for the thorough explanation!

Best regards,
Taeho

On Thu, Jul 10, 2014 at 6:33 AM, Wim Taymans <wim.taymans at gmail.com> wrote:

> Some clarifications below,
>
> On 10 July 2014 09:00, Edward Hervey <bilboed at bilboed.com> wrote:
>
>> On Wed, 2014-07-09 at 02:11 -0600, Taeho Oh wrote:
>> > Hello
>> >
>> >
>> > I am a newbie in gstreamer and have several questions about gstreamer.
>> > I am sorry if it is a silly question.
>> >
>> >
>> > According
>> > to
>> http://lists.freedesktop.org/archives/gstreamer-devel/2006-July/012776.html
>> ( gst_element_set_state hangs ? ), Mike said that
>> > "You are not - ever - allowed to call gst_element_set_state() from one
>> > of
>> > these streaming threads."
>>
>>   So. That statement is not 100% true. If you have no clue what you're
>> doing, you should indeed just respect that rule.
>>
>>   The first rule that *always* applies is:
>>    An element (and the code within) is *never* allowed to change *its*
>> state. Only the parent container(s) of an element can change its state.
>> There are mechanisms to hint at the parent container that it should do
>> that, but it's not common.
>>    Furthermore, you are *not* allowed to change the state of
>> upstream/downstream elements. That's the standard "black box"
>> programming paradigm (as an element, you can only control your realm,
>> i.e. what's in yourself).
>>
>>   Astute readers will have figured out the following though:
>>    That being said, if your element is a GstBin/GstPipeline subclass, or
>> if you are application code (which is the "container" of the top-level
>> pipeline), you _can_ change, if/when needed, the state of the elements
>> contained within yourself.
>>    This is actually needed when you dynamically add/remove elements
>> within yourself at runtime. _When_ you can do that is explained after.
>>
>>   Understanding why we have the initial statement (don't change states),
>> and why it can cause havoc, can lead you to better understand what the
>> issues can potentially be.
>>
>>
>>   The common problem one wants to avoid is the following deadlock:
>>   1) The "streaming" lock is taken on each pad (sourcepad and sinkpad,
>> i.e. a link) whenever a buffer or serialized event/query is being pushed
>> through them. The reason is ... to only allow one buffer (or serialized
>> event/query) to go through that link.
>>   2) If, from the thread that has gone through those links (and
>> therefore holding those locks), you try to re-acquire that lock ... you
>> will deadlock. That is the problem you want to avoid.
>>
>
> This is not a problem, the stream lock is recursive.
>
>
>>
>>   There are also a couple of other cases where those streaming locks
>> will be taken:
>>   1) The most other common one is when a pad is deactivated (which
>> happens when the element it belongs to goes from PAUSED to READY, but
>> also when pads are removed), it needs to ensure that no data flow is
>> currently taking place.
>>   # If you try to deactivate the pad, or by extension change the state
>> of that element from PAUSED to READY, from the thread that was already
>> flowing through it => deadlock.
>>
>
> This is only true for elements that created the GstTask for this streaming
> thread and
> not because of the streaming lock but because of the fact that it wants to
> stop and join the thread you are currently in. We catch this case with a
> big warning
> on the console, we won't deadlock (for any GstTask).
>
>
>>
>>   2) An other one is for elements that initiate a streaming thread (such
>> as push-based sources or pull-based demuxers which run what is commonly
>> called a "loop" function) and that want to ensure that loop is no longer
>> running.
>>    For example, when a demuxer receives a seek (whether flushing or not)
>> it wants to ensure that that loop is not running before it modifies the
>> information/properties regarding where the loop should resume from (the
>> requested position for example).
>>   # If you try to seek on an element from that streaming thread =>
>> deadlock.
>>
>
> Not true, you can seek fine from a streaming thread because the lock is
> recursive, otherwise push based seeking would just never work.
>
>
>>
>>   Now, there are some cases where you can safely change an element
>> state:
>>   1) It's not connected downstream, you know the streaming thread that
>> might flow out of that element will not block, you can change the state.
>
>
>
>>   2) It is connected downstream, but it's in the NULL or READY state,
>> you know no dataflow was happening, therefore it can't be
>> pushing/blocking.
>>   3) It is connected downstream, but you forced the streaming thread
>> that might flow out of that element to never block, by issuing a
>> GST_EVENT_FLUSH_START on the downstream pads (serialized-event/buffer
>> pushes always return immediately on all pads that received that event).
>>   4) Regardless of the above, you are bringing the state of an element
>> "upwards" (i.e. from NULL=>READY, READY=>PAUSED, PAUSED=>PLAYING). In
>> those cases, you either have no streaming happening (2), or it's already
>> running and you are not attempting to stop it.
>>
>
> These cases are when  you want to change the state of an element to
> READY/NULL individually without setting the state of the downstream
> elements to READY first. You will do this when you want to dynamically
> remove an element from a playing pipeline, for example.
>
> Again, you can't do any of the above state changes from the streaming
> thread that you would be trying to stop with a state change to READY/NULL.
>
> So, in short, the only thing you can't do from a streaming thread is
> trying to stop the element that created the streaming thread.
>
> Wim
>
>>
>> >
>> > Q1) In gstreamer user's point of view, where can I meet 'streaming
>> > thread'? Should I assume that all callback functions(ex. typefind
>> > have-type callback, pad-added callback, etc) run in 'streaming
>> > thread'? Are there any other 'streaming thread' cases other than the
>> > callback functions?
>>
>
>>   The short rule is :
>>    * just assume signals and pad blocks will be emitted from a streaming
>> thread. Never do state changes from that *unless* you understand
>> everything I explained above.
>>    * (asynchronous) messages from the bus are in your main thread,
>> they're guaranteed not to be emitted from a streaming thread, you can do
>> whatever you want.
>>
>>   => If you don't know for sure which thread it is, assume it's a
>> streaming thread.
>>
>> >
>> >
>> > Q2) Are there any allowed scenarios where gst_element_set_state() can
>> > be called in the streaming thread?
>> > I am a little bit confused, because according to
>> >
>> http://debathena.mit.edu/trac/browser/trunk/third/gstreamer/docs/manual/helloworld2.xml?rev=21005,
>> gst_element_set_state() is called in gst_play_have_type callback function.
>>
>>   Hopefully everything above made that clear.
>>   1) It's code from outside the element/pipeline (it's application code)
>>   2) it's bringing the state of that element (or rather pipeline)
>> upwards (which doesn't acquire the streaming lock)
>>
>> >
>> >
>> > Q3) Are there any other gstreamer APIs not allowed to be called in the
>> > 'streaming thread'?
>>
>>   Apart from changing state and seeking, it's down to sending serialized
>> data (buffers, serialized events, serialized queries) downstream, which
>> is perfectly fine since you're pushing data *downstream* and therefore
>> not through the (upstream) streaming locks that might have been taken.
>>
>
>
>>
>>   Hope this clarifies things a bit,
>>
>>    Edward
>>
>> >
>> >
>> > Best regards,
>> >
>> > Taeho
>> > --
>> > Taeho Oh ( ohhara at postech.edu )
>> > http://ohhara.sarang.net
>> > Postech ( Pohang University of Science and Technology )
>> > http://www.postech.edu
>> > Alticast Corp.
>> > http://www.alticast.com
>> > _______________________________________________
>> > gstreamer-devel mailing list
>> > gstreamer-devel at lists.freedesktop.org
>> > http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
>>
>>
>> _______________________________________________
>> gstreamer-devel mailing list
>> gstreamer-devel at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
>>
>>
>


-- 
Taeho Oh ( ohhara at postech.edu )
http://ohhara.sarang.net
Postech ( Pohang University of Science and Technology )
http://www.postech.edu
Alticast Corp.
http://www.alticast.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/gstreamer-devel/attachments/20140710/ef8eaca9/attachment-0001.html>


More information about the gstreamer-devel mailing list