trying to achieve playbin2 gapless transition

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

trying to achieve playbin2 gapless transition

Captian Ham
To get acquainted with gstreamer I'm writing (what I would assume to be) a very simple program to play a succession of media files (pictures and videos); when I transition between files I'd like the frame of the last file to freeze in place until the next file starts playing. I'm using playbin2 with an xvimagesink linked to a gtk window to display the output. My understanding of the process is to handle the transition like this:

gst_element_set_locked_state( xvimagesink_, TRUE );
gst_element_set_state( playbin2_, GST_STATE_READY );
g_object_set( G_OBJECT( playbin2_ ), "uri", newfile_.c_str(), NULL );
gst_element_set_state( playbin2_, GST_STATE_PLAYING );
gst_element_set_locked_state( xvimagesink_, FALSE );

And while this seems to work exactly as intended initially, after about ten/twenty transitions it deadlocks without fail on the GST_STATE_READY call to the playbin2 element:

#0  0x0012d422 in __kernel_vsyscall ()
#1  0x00df7af9 in __lll_lock_wait () at ../nptl/sysdeps/unix/sysv/linux/i386/i686/../i486/lowlevellock.S:142
#2  0x00df313b in _L_lock_748 () from /lib/tls/i686/cmov/libpthread.so.0
#3  0x00df2f61 in __pthread_mutex_lock (mutex=0x826225c) at pthread_mutex_lock.c:61
#4  0x00c7283e in g_static_rec_mutex_lock () from /lib/libglib-2.0.so.0
#5  0x013c8421 in ?? () from /usr/lib/libgstbase-0.10.so.0
#6  0x013c9814 in ?? () from /usr/lib/libgstbase-0.10.so.0
#7  0x0032900f in gst_pad_activate_push () from /usr/lib/libgstreamer-0.10.so.0
#8  0x00329d98 in gst_pad_set_active () from /usr/lib/libgstreamer-0.10.so.0
#9  0x0030815b in ?? () from /usr/lib/libgstreamer-0.10.so.0
#10 0x0031a9f7 in gst_iterator_fold () from /usr/lib/libgstreamer-0.10.so.0
#11 0x0030808f in ?? () from /usr/lib/libgstreamer-0.10.so.0
#12 0x0030a6f8 in ?? () from /usr/lib/libgstreamer-0.10.so.0
#13 0x0030cc19 in ?? () from /usr/lib/libgstreamer-0.10.so.0
#14 0x00309435 in gst_element_change_state () from /usr/lib/libgstreamer-0.10.so.0
#15 0x0030c928 in ?? () from /usr/lib/libgstreamer-0.10.so.0
#16 0x003087f0 in gst_element_set_state () from /usr/lib/libgstreamer-0.10.so.0
#17 0x002f8827 in ?? () from /usr/lib/libgstreamer-0.10.so.0
#18 0x00309435 in gst_element_change_state () from /usr/lib/libgstreamer-0.10.so.0
#19 0x0030c928 in ?? () from /usr/lib/libgstreamer-0.10.so.0
#20 0x003087f0 in gst_element_set_state () from /usr/lib/libgstreamer-0.10.so.0
#21 0x002f8827 in ?? () from /usr/lib/libgstreamer-0.10.so.0
#22 0x0136acfa in ?? () from /usr/lib/gstreamer-0.10/libgstplaybin.so
#23 0x00309435 in gst_element_change_state () from /usr/lib/libgstreamer-0.10.so.0
#24 0x0030c928 in ?? () from /usr/lib/libgstreamer-0.10.so.0
#25 0x003087f0 in gst_element_set_state () from /usr/lib/libgstreamer-0.10.so.0
#26 0x002f8827 in ?? () from /usr/lib/libgstreamer-0.10.so.0
#27 0x0032cdf2 in ?? () from /usr/lib/libgstreamer-0.10.so.0
#28 0x013615ba in ?? () from /usr/lib/gstreamer-0.10/libgstplaybin.so
#29 0x00309435 in gst_element_change_state () from /usr/lib/libgstreamer-0.10.so.0
#30 0x0030922e in gst_element_continue_state () from /usr/lib/libgstreamer-0.10.so.0
#31 0x003094bf in gst_element_change_state () from /usr/lib/libgstreamer-0.10.so.0
#32 0x0030c928 in ?? () from /usr/lib/libgstreamer-0.10.so.0
#33 0x003087f0 in gst_element_set_state () from /usr/lib/libgstreamer-0.10.so.0

No deadlock occurs if I don't lock xvimagesink first. I'd appreciate some guidance on; why locking a child element might cause a state change to a parent to fail? Why does locking in this way produce a volatile outcome that fails every now and then? Is this the most sensible approach to simple "gapless" transition between media with using a playbin2 pipeline.

Thanks in advance,
CH
Reply | Threaded
Open this post in threaded view
|

Re: trying to achieve playbin2 gapless transition

Tim-Philipp Müller-2
On Thu, 2012-07-12 at 13:23 -0700, Captian Ham wrote:

> To get acquainted with gstreamer I'm writing (what I would assume to be) a
> very simple program to play a succession of media files (pictures and
> videos); when I transition between files I'd like the frame of the last file
> to freeze in place until the next file starts playing. I'm using playbin2
> with an xvimagesink linked to a gtk window to display the output. My
> understanding of the process is to handle the transition like this:
>
> gst_element_set_locked_state( xvimagesink_, TRUE );
> gst_element_set_state( playbin2_, GST_STATE_READY );
> g_object_set( G_OBJECT( playbin2_ ), "uri", newfile_.c_str(), NULL );
> gst_element_set_state( playbin2_, GST_STATE_PLAYING );
> gst_element_set_locked_state( xvimagesink_, FALSE );
>
> (snip backtrace)
> No deadlock occurs if I don't lock xvimagesink first. I'd appreciate some
> guidance on; why locking a child element might cause a state change to a
> parent to fail? Why does locking in this way produce a volatile outcome that
> fails every now and then? Is this the most sensible approach to simple
> "gapless" transition between media with using a playbin2 pipeline.

Have you tried using the "about-to-finish" signal and just setting the
next URI to play from there? Then you shouldn't have to lock the
videosink or even change playbin's state. It should pre-load the next
file so it's ready to play immediately after the previous one finishes.
(Having said that, there's bug #673305, so I don't know if there major
issues with that or not).

 Cheers
  -Tim

_______________________________________________
gstreamer-devel mailing list
[hidden email]
http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: trying to achieve playbin2 gapless transition

Captian Ham
Hi Tim,

Thanks for that but I don't think that's quite what I'm after. Essentially I'd like to be able to change files at entirely arbitrary points that are midway through being played, or are just a static image file, without the gap that triggers when the next file is loaded.

If I set the playbin to READY, change the URI and go back to PLAYING (which is far as I know is the best way to change the file source halfway through play-through?), there's a slight but none the less very noticeable gap where nothing is playing on the screen. To minimise this, I want to freeze the last displayed frame of the previous file until the next file is playing.

The best way (it seemed to me) to do this was to lock the video-sink while changing the URI of the playbin2 until the next file is loaded, but that appears to quickly (but not consistently) deadlock the playbin2 element. I'm hoping to clarify why this might be or if this is even the most sensible solution!

Cheers,
CH