<div dir="ltr">I looked into gst_element_set_state, and found:<div style><br></div><div style><div style> * State changes to %GST_STATE_READY or %GST_STATE_NULL never return</div><div style> * #GST_STATE_CHANGE_ASYNC.</div>

</div><div style><br></div><div style>So I'm understanding this as: "when gst_element_set_state(pipeline, GST_STATE_NULL) returns, the state of the pipeline should be GST_STATE_NULL", and it looks like it is so according to my test:</div>

<div style><br></div><div style><div style><span class="" style="white-space:pre">      </span>ret = gst_element_get_state (worker->pipeline, &state, NULL,</div><div style><span class="" style="white-space:pre">  </span>    GST_CLOCK_TIME_NONE);</div>

<div style><span class="" style="white-space:pre">      </span>g_assert (ret == GST_STATE_CHANGE_SUCCESS);</div><div style><span class="" style="white-space:pre">  </span>g_assert (state == GST_STATE_NULL);</div><div style><br>

</div><div style>And also I found the auto-flushing in gstpipeline.c code (which is in the GST_STATE_CHANGE_READY_TO_NULL state change handler of GstPipeline):</div><div style><br></div><div style>      // gstpipeline.c:503</div>

<div style><div style>      if (bus) {</div><div style>        if (auto_flush) {</div><div style>          gst_bus_set_flushing (bus, TRUE);</div><div style>        } else {</div><div style>          GST_INFO_OBJECT (element, "not flushing bus, auto-flushing disabled");</div>

<div style>        }</div><div style>        gst_object_unref (bus);</div><div style>      }</div><div style><br></div><div style>And gst_bus_set_flushing is just <b>discarding</b> all undispatched messages by:</div><div style>

<br></div><div style>    // gstbus.c:452</div><div style><div style>    while ((message = gst_bus_pop (bus)))</div><div style>      <b>gst_message_unref</b> (message);</div><div style><br></div><div style>Which means when we do the following statements on a auto-flush enabled pipeline:</div>

<div style><br></div></div></div></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div style><div style><div style><div style>gst_element_set_state (pipeline, GST_STATE_NULL);</div><div style><br>

</div></div></div></div></blockquote>All undispatched messages are supposed to be discarded, instead of flushing to the installed bus watcher, say:<div style><br></div><div style><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px">

<div style><div style>  worker->bus = gst_pipeline_get_bus (GST_PIPELINE (worker->pipeline));</div><div style>  worker->watch = <b>gst_bus_add_watch</b> (worker->bus,<br></div><div style>      (GstBusFunc) <b>gst_worker_message</b>, worker);</div>

<div style><br></div></div></blockquote></div><div class="gmail_extra" style>I suppose that auto-flush should dispatch the pended messages to the watcher gst_worker_message instead of just discarding the them when we're just setting the pipeline state to NULL. Because when setting the state to NULL, the watcher is still there expecting to see the messages it should see.</div>

<div class="gmail_extra" style><br></div><div class="gmail_extra" style>So I'm think that gst_bus_set_flushing is not safe by just gst_message_unref undispatched messages in the case of auto-flush enabled pipelines. It's not gst_bus_discard. And I'm think that the gst_bus_set_flushing should be something like:</div>

<div class="gmail_extra" style><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra" style>// gstbus.c:452</div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px">

<div class="gmail_extra" style>while ((message = gst_bus_pop (bus))</div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra" style>    <b><i>send_message_to_the_installed_watchers</i></b> (message);</div>

<div class="gmail_extra" style><br></div></blockquote>Instead of just gst_message_unref them. Because I think I'm setting a pipeline to NULL, the watcher is expecting to get a GST_STATE_CHANGE_READY_TO_NULL, or it's risky as an application writer to produce buggy stuffs.<div>

<br></div><div>Best Regards Sincerely</div><div>Duzy Chan<br><div class="gmail_extra" style><br><br><div class="gmail_quote" style>On Thu, Feb 7, 2013 at 7:00 PM, Tim-Philipp Müller <span dir="ltr"><<a href="mailto:t.i.m@zen.co.uk" target="_blank">t.i.m@zen.co.uk</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class="im" style>On Thu, 2013-02-07 at 17:12 +0800, Duzy Chan wrote:<br>


<br>
<br>
> It looks like the GST_STATE_CHANGE_READY_TO_NULL message was not<br>
> issued while I was stopping the worker (setting the pipeline to<br>
> GST_STATE_NULL). Yet the state did changed into NULL (according to<br>
> gst_element_get_state). I'm wondering if I was doing something wrong.<br>
<br>
</div>That is entirely expected.<br>
<div class="im" style><br>
>          see:<br>
>         <a href="https://github.com/duzy/gst-switch/blob/master/tools/gstworker.c#L629" target="_blank">https://github.com/duzy/gst-switch/blob/master/tools/gstworker.c#L629</a><br>
>         gst_pipeline_set_auto_flush_bus (GST_PIPELINE<br>
>         (worker->pipeline), FALSE);<br>
><br>
> I got the expected GST_STATE_CHANGE_READY_TO_NULL state change<br>
> message.<br>
><br>
> Do you guys have some ideas on this? I assume I should have missed<br>
> something.<br>
<br>
</div>See the documentation for gst_pipeline_set_auto_flush_bus():<br>
<br>
<a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstPipeline.html#gst-pipeline-set-auto-flush-bus" target="_blank">http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstPipeline.html#gst-pipeline-set-auto-flush-bus</a><br>


<br>
"Usually, when a pipeline goes from READY to NULL state, it<br>
automatically flushes all pending messages on the bus, which is done for<br>
refcounting purposes, to break circular references.<br>
<br>
This means that applications that update state using (async) bus<br>
messages (e.g. do certain things when a pipeline goes from PAUSED to<br>
READY) might not get to see messages when the pipeline is shut down,<br>
because they might be flushed before they can be dispatched in the main<br>
thread. This behaviour can be disabled using this function.<br>
<br>
It is important that all messages on the bus are handled when the<br>
automatic flushing is disabled else memory leaks will be introduced."<br>
<br>
Cheers<br>
<span class=""><font color="#888888"> -Tim<br>
</font></span><div class="" style><div class="h5" style><br>
><br>
> On Thu, Feb 7, 2013 at 9:12 AM, Duzy Chan <<a href="mailto:geek@duzy.info">geek@duzy.info</a>> wrote:<br>
><br>
><br>
><br>
>         On Thu, Feb 7, 2013 at 6:17 AM, David Schleef <<a href="mailto:ds@schleef.org">ds@schleef.org</a>><br>
>         wrote:<br>
>                 On Wed, Feb 06, 2013 at 06:40:08PM +0800, Duzy Chan<br>
>                 wrote:<br>
>                 > On Wed, Feb 6, 2013 at 6:22 PM, Tim-Philipp Müller<br>
>                 <<a href="mailto:t.i.m@zen.co.uk">t.i.m@zen.co.uk</a>> wrote:<br>
>                 ><br>
><br>
>                 > > Yes, I did check that out and did look at it, but<br>
>                 I'm afraid I don't<br>
>                 > > really have time to look at all that in detail,<br>
>                 hence the request for<br>
>                 > > something stand-alone and minimal. If it's an<br>
>                 issue with pipeline<br>
>                 > > creation / GstBus / watch usage, it shouldn't be<br>
>                 too hard to re-create.<br>
>                 > ><br>
>                 ><br>
>                 > I would like to do a bit effort to make a stand<br>
>                 alone minimal test case of<br>
>                 > the GstBus usage, and see if we can duplicate the<br>
>                 same issue to help to<br>
>                 > find out the reason.<br>
>                 ><br>
><br>
><br>
>                 The first thing you should check is that you are<br>
>                 properly cleaning<br>
>                 up all your objects.  If you leak a pipeline, object,<br>
>                 or bus, you'll<br>
>                 end up with multiple copies of intervideosrc around,<br>
>                 which will<br>
>                 use file descriptors.<br>
><br>
><br>
>         I hacked a bit into intervideosrc, but it looks like the inter<br>
>         elements are all memory based, which I think should be<br>
>         in-process available, without allocating a file descriptor,<br>
>         all memory based utilities: list, buffer, mutex.<br>
><br>
><br>
>         Now I'm thinking that if there're any messages which holding<br>
>         the references of the pipeline, and when I unref-ed the<br>
>         pipeline, somehow caused cycling-referencing (my guess).<br>
>         Because in per cycle reset of the pipeline, I did<br>
>         g_source_remove the watch, gst_object_unref the bus, null and<br>
>         gst_object_unref the pipeline.<br>
><br>
><br>
>         I tried to make my reset function (say gst_worker_reset)<br>
>         none-operation (which I commented out all, leaving a "result =<br>
>         TRUE"), and the file descriptor leaks gone.<br>
><br>
><br>
>         So I'm guessing it's somehow getting cycling-referencing or I<br>
>         did forgot to unref something.<br>
><br>
><br>
>         I'll spend some time to play around the stand-alone test code<br>
>         to try to duplicate the execution flow in minimal. And also<br>
>         check further.<br>
><br>
><br>
><br>
><br>
>                 David<br>
><br>
>                 _______________________________________________<br>
>                 gstreamer-devel mailing list<br>
>                 <a href="mailto:gstreamer-devel@lists.freedesktop.org">gstreamer-devel@lists.freedesktop.org</a><br>
>                 <a href="http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel" target="_blank">http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel</a><br>
><br>
><br>
><br>
><br>
><br>
> _______________________________________________<br>
> gstreamer-devel mailing list<br>
> <a href="mailto:gstreamer-devel@lists.freedesktop.org">gstreamer-devel@lists.freedesktop.org</a><br>
> <a href="http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel" target="_blank">http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel</a><br>
<br>
<br>
_______________________________________________<br>
gstreamer-devel mailing list<br>
<a href="mailto:gstreamer-devel@lists.freedesktop.org">gstreamer-devel@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel" target="_blank">http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel</a><br>
</div></div></blockquote></div><br></div></div></div>