How to correctly reuse elements?

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

How to correctly reuse elements?

wl2776
Administrator
I am building an embedded player, capable to play audio and video from separate files.

General algorithm is the following.

1. Create the videosink (directdrawsink) and set its window ID to the HWND of the given window.
2. Create the playbin2 instance and set its "video-sink" property.
3. Set playbin2's uri and send it to the PLAYING state.
4. Listen on the message bus and decide if both audio and video streams are present.
5. Catch the state-changed message from the playbin2 in the bus-sync-handler and set playbin2 to the PAUSED state. This will draw the first video frame and pauses the playback - a condition, my player must satisfy.
6. Also, in the same bus-sync-handler, check if both audio and video present, and if not, send an application message, with the structure, saying the player must additionally render some more media.

7. Catch that application message in the bus watch and call the function dorender() which:
7.1. Destroys playbin2
7.2. Unparents the created videosink.
7.3. Creates new empty pipeline
7.4. Destroys old message bus
7.5. Creates new bus and connect bus watch and bus-sync-handler
7.6. Puts two uridecodebin2's in the pipeline
7.7. Creates an audio bin and puts it in the pipeline
7.8. Creates a video bin reusing the existing videosink and puts it in the pipeline

The problem is - everything is created and linked, but soon after the function dorender() exits, the videosink looses its link to its sink pad and goes to the NULL state.
However, when the pipeline was creating, graphviz dumps showed that it was linked and was in the READY and in the PAUSED states.

Why does it go to the NULL state?
Reply | Threaded
Open this post in threaded view
|

Re: How to correctly reuse elements?

wl2776
Administrator
Found.
Please, correct if I am wrong.

wl2776 wrote
I am building an embedded player, capable to play audio and video from separate files.
...
Create playbin2
7. Catch that application message in the bus watch and call the function dorender() which:
7.1. Destroys playbin2
with the gst_object_unref(playbin2)

wl2776 wrote
7.2. Unparents the created videosink.
was done using gst_object_unparent().

This function seems to just zeroing the parent field of an element, but its parent still thinks that it is an element's parent.
Is it correct?

I also tried gst_bin_remove(GST_BIN(m_player),GST_ELEMENT(m_videosink)), but it returned false - the bin doesn't want to remove the videosink.

wl2776 wrote
7.3. Creates new empty pipeline
7.4. Destroys old message bus
7.5. Creates new bus and connect bus watch and bus-sync-handler
7.6. Puts two uridecodebin2's in the pipeline
7.7. Creates an audio bin and puts it in the pipeline
7.8. Creates a video bin reusing the existing videosink and puts it in the pipeline

The problem is - everything is created and linked, but soon after the function dorender() exits, the videosink looses its link to its sink pad and goes to the NULL state.
However, when the pipeline was creating, graphviz dumps showed that it was linked and was in the READY and in the PAUSED states.

Why does it go to the NULL state?
As a result, by the end of 7.8, I was still having one more background thread running, that was removing the previously created playbin2 instance, and also setting my videosink to the NULL state.

And the playbin2 didn't want to leave the videosink alone.
How can I make  to remove the videosink?

I really need it in the other place, since it still has a frame displayed, and I want it frame to be on the window all the time, the pipeline reconstruction takes place.

The pipeline (playbin2) was sent to the NULL state before the games with the videosink began.
Reply | Threaded
Open this post in threaded view
|

Re: How to correctly reuse elements?

wl2776
Administrator
wl2776 wrote
And the playbin2 didn't want to leave the videosink alone.
How can I make  to remove the videosink?
Continuing.
I've developed the following code.

*DO NOT* send the m_player to the NULL state.

gboolean rb;
GstElement *bin=gst_bin_get_by_name(GST_BIN(m_player),"playsink0");
if(bin){
  rb=gst_bin_remove(GST_BIN(bin),GST_ELEMENT(m_videosink));
  bin=gst_bin_get_by_name(GST_BIN(bin),"vbin");
  if(bin){
    rb=gst_bin_remove(GST_BIN(bin),GST_ELEMENT(m_videosink));
  }
}

I am getting the following output during this.

0:00:19.367850000  3828   04114C38 INFO           GST_PARENTAGE gstbin.c:3589:gst_bin_get_by_name: [playbin0]: looking up child element playsink0
The thread 'Win32 Thread' (0x758) has exited with code 0 (0x0).
0:00:27.579658000  3828   04114C38 DEBUG          GST_PARENTAGE gstbin.c:1447:gst_bin_remove: removing element videosink from bin playsink0
(null) log_level Element videosink is not in bin playsink0
0:00:44.113432000  3828   04114C38 INFO           GST_PARENTAGE gstbin.c:3589:gst_bin_get_by_name: [playsink0]: looking up child element vbin
0:00:55.920410000  3828   04114C38 DEBUG          GST_PARENTAGE gstbin.c:1447:gst_bin_remove: removing element videosink from bin vbin
0:00:55.920410000  3828   04114C38 INFO           GST_PARENTAGE gstbin.c:1406:gst_bin_remove_func:<vbin> already removing child

However, rb is always 0 - the bin doesn't want to remove a child.
These calls return immediately.
Is the removing takes place in the separate thread?
Should I wait for this thread to finish?
How can I detect the child was removed?
Reply | Threaded
Open this post in threaded view
|

Re: How to correctly reuse elements?

wl2776
Administrator
Finally.

The solution is in the GStreamer's sources.

http://www.codase.com/search/smart?join=gst_bin_remove&scope=join%2Fjoin&lang=%2A&project=

GstElement *bin= gst_element_get_parent (element);
if(bin){
  gst_bin_remove (GST_BIN (bin), element);
}