How can I wait for the pipeline destruction?

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

How can I wait for the pipeline destruction?

wl2776
Administrator
Depending on media, my media player destroys previously created playbin2 instance and creates and fills a new pipeline.

This new pipeline uses the previously created videosink, which also was earlier set in the playbin2, because I want to avoid image flickering during the pipeline recreation.

I want to be sure that the old playbin2 is destroyed before creating a new pipeline.
How can I do that?

When I destroy the playbin2 with gst_object_unref(GST_OBJECT(m_player)), I seem to get one more background thread, doing all this destruction stuff.
Two threads (creation and destruction) finish nearly simultaneously, and the destruction thread sends my videosink to the NULL state (and probably zeroes its bus) right after my new pipeline is complete, and the function returns.

I do
gst_object_unref(GST_OBJECT(m_player));
gst_object_unref(GST_OBJECT(m_bus));

bin=(GstElement *)gst_element_get_parent(m_videosink);
if(bin){
  rb=gst_bin_remove(GST_BIN(bin),GST_ELEMENT(m_videosink));
}
gst_object_unparent(GST_OBJECT(m_videosink));

before beginning of a new pipeline construction, but this seems to start a new thread, as I said before, and videosink is removed too late from the playbin2. And this pipeline sets it to the null state.

Again, how can I get sure, that playbin2 is destroyed and will not bring me some new (street) magic?
Reply | Threaded
Open this post in threaded view
|

Re: How can I wait for the pipeline destruction?

Tim-Philipp Müller-2
On Wed, 2010-04-21 at 03:26 -0800, wl2776 wrote:

> I want to be sure that the old playbin2 is destroyed before creating a new
> pipeline. How can I do that?
>
> When I destroy the playbin2 with gst_object_unref(GST_OBJECT(m_player)), I
> seem to get one more background thread, doing all this destruction stuff.

Downwards state changes should be synchronous, so when
gst_object_unref() finishes, the pipeline and all resources used should
be closed/freed, assuming nothing else holds a ref. If that's not the
case for you, that may be a problem in some proprietary element, if you
have one of those in your pipeline, or some refcount issue somewhere.

However, you could try adding a 'weak' reference (See GObject API
reference), that will call a function of yours when the pipeline object
has really been destroyed. That may not actually help you though if you
have some code somewhere that doesn't block until all resources it uses
have been freed.

Cheers
 -Tim


------------------------------------------------------------------------------
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: How can I wait for the pipeline destruction?

wl2776
Administrator
Tim-Philipp Müller-2 wrote
Downwards state changes should be synchronous, so when
gst_object_unref() finishes, the pipeline and all resources used should
be closed/freed, assuming nothing else holds a ref. If that's not the
case for you, that may be a problem in some proprietary element, if you
have one of those in your pipeline, or some refcount issue somewhere.
Is message->src ref included in the refcount? I've noticed that something tries to send the videosink to the NULL state right after the gst_message_unref() in my bus-watch.

My bus-watch has the following structure

gboolean gst_player::bus_watch(... )
{
  switch (GST_MESSAGE_TYPE (msg)) {
    case GST_MESSAGE_...:
      ...
    break;
    case GST_MESSAGE_...:
      ...
    break;
    case GST_MESSAGE_...:
      ...
    break;
  }
  gst_message_unref(msg);
  return TRUE;
}

I also do the ref of the videosink in the open() function, which creates a playbin2, and unref it in the close() function:

void gst_player::open()
{
 ......
  m_videosink=gst_element_factory_make("directdrawsink","videosink")
  gst_object_ref(m_videosink);

  m_player=gst_element_factory_make("playbin2","player");
  g_object_set(G_OBJECT(m_player),"video-sink",m_videosink,NULL);
}

Reply | Threaded
Open this post in threaded view
|

Re: How can I wait for the pipeline destruction?

Zhao, Halley
In reply to this post by wl2776
Two solution:
1> send EOS to the src element of your pipeline, I used this for my camera src. (other src element may not support it well).
2> double check the previous pipeline has been destructed.
sc_ret = gst_element_gst_state(GST_ELEMENT(pipeline), &curr_state, ...);
loop=1
while(loop) {
  If(sc_ret == GST_STATE_CHANGE_SUCCESS || curr_state == GST_STATE_NULL) {
  ....
  Loop = 0;
  }
}

You can also use gst_bus_timed_pop_filtered to optimize the above loop.

-----Original Message-----
From: wl2776 [mailto:[hidden email]]
Sent: 2010年4月21日 19:27
To: [hidden email]
Subject: [gst-devel] How can I wait for the pipeline destruction?


Depending on media, my media player destroys previously created playbin2
instance and creates and fills a new pipeline.

This new pipeline uses the previously created videosink, which also was
earlier set in the playbin2, because I want to avoid image flickering during
the pipeline recreation.

I want to be sure that the old playbin2 is destroyed before creating a new
pipeline.
How can I do that?

When I destroy the playbin2 with gst_object_unref(GST_OBJECT(m_player)), I
seem to get one more background thread, doing all this destruction stuff.
Two threads (creation and destruction) finish nearly simultaneously, and the
destruction thread sends my videosink to the NULL state (and probably zeroes
its bus) right after my new pipeline is complete, and the function returns.

I do
gst_object_unref(GST_OBJECT(m_player));
gst_object_unref(GST_OBJECT(m_bus));

bin=(GstElement *)gst_element_get_parent(m_videosink);
if(bin){
  rb=gst_bin_remove(GST_BIN(bin),GST_ELEMENT(m_videosink));
}
gst_object_unparent(GST_OBJECT(m_videosink));

before beginning of a new pipeline construction, but this seems to start a
new thread, as I said before, and videosink is removed too late from the
playbin2. And this pipeline sets it to the null state.

Again, how can I get sure, that playbin2 is destroyed and will not bring me
some new (street) magic?

--
View this message in context: http://n4.nabble.com/How-can-I-wait-for-the-pipeline-destruction-tp2018772p2018772.html
Sent from the GStreamer-devel mailing list archive at Nabble.com.

------------------------------------------------------------------------------
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gstreamer-devel
------------------------------------------------------------------------------
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: How can I wait for the pipeline destruction?

Edward Hervey
In reply to this post by wl2776
On Wed, 2010-04-21 at 03:26 -0800, wl2776 wrote:
> Depending on media, my media player destroys previously created
> playbin2
> instance and creates and fills a new pipeline.
>
> This new pipeline uses the previously created videosink, which also
> was
> earlier set in the playbin2, because I want to avoid image flickering
> during
> the pipeline recreation.

  If you use gstreamer >= 0.10.28 you shouldn't have to tear down
playbin2 completely, but instead should be able to re-use it.
  Just set it to READY (instead of NULL), set your new URI, and then
back to PLAYING. If you still get issues with that, you might have
encountered a bug.

   Edward


------------------------------------------------------------------------------
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: How can I wait for the pipeline destruction?

wl2776
Administrator
Edward Hervey wrote
On Wed, 2010-04-21 at 03:26 -0800, wl2776 wrote:
> Depending on media, my media player destroys previously created
> playbin2
> instance and creates and fills a new pipeline.
  If you use gstreamer >= 0.10.28 you shouldn't have to tear down
playbin2 completely, but instead should be able to re-use it.
My player has to play a sound from a separate file. Playbin2 is unable to do that, and I have to manually create a new pipeline. I've chosen a design, containing two uridecodebins and two bins, similar to those, a playsink creates.

BTW, I still have doubts about this, as setting new uri to the uridecodebin doesn't work. Its filesrc keeps the previous uri.
Reply | Threaded
Open this post in threaded view
|

Re: How can I wait for the pipeline destruction?

wl2776
Administrator
In reply to this post by Edward Hervey
Edward Hervey wrote
On Wed, 2010-04-21 at 03:26 -0800, wl2776 wrote:
> Depending on media, my media player destroys previously created
> playbin2
> instance and creates and fills a new pipeline.
  If you use gstreamer >= 0.10.28 you shouldn't have to tear down
playbin2 completely, but instead should be able to re-use it.
My player has to play a sound from a separate file. Playbin2 is unable to do that, and I have to manually create a new pipeline. I've chosen a design, containing two uridecodebins and two bins, similar to those, a playsink creates.

BTW, I still have doubts about this, as setting new uri to the uridecodebin doesn't work. Its filesrc keeps the previous uri.
Reply | Threaded
Open this post in threaded view
|

Re: How can I wait for the pipeline destruction?

wl2776
Administrator
In reply to this post by Zhao, Halley
Zhao, Halley wrote
Two solutions:
1> send EOS to the src element of your pipeline, I used this for my camera src. (other src element may not support it well).
2> double check the previous pipeline has been destructed.
My solution is just removal of the videosink. The problem was in correct using of references.

rs=gst_element_set_state(GST_ELEMENT(m_player),GST_STATE_NULL);
GstElement *bin=(GstElement *)gst_element_get_parent(m_videosink);
if(bin){
  rb=gst_bin_remove(GST_BIN(bin),GST_ELEMENT(m_videosink));
}
gst_object_unref(GST_OBJECT(m_player));
gst_object_unref(GST_OBJECT(m_bus));