After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 690014 - playbin: lockup when seeking in initial paused state
playbin: lockup when seeking in initial paused state
Status: RESOLVED OBSOLETE
Product: GStreamer
Classification: Platform
Component: gst-plugins-base
git master
Other Linux
: Normal normal
: git master
Assigned To: GStreamer Maintainers
GStreamer Maintainers
playback
Depends on:
Blocks:
 
 
Reported: 2012-12-10 23:21 UTC by Brendan Long
Modified: 2016-03-03 20:53 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Program that uses a basic playbin(2) pipeline and switches video or audio tracks randomly (3.75 KB, text/x-c++src)
2012-12-18 18:42 UTC, Brendan Long
Details
A GStreamer program that sets up a paused pipeline and then seeks to the start (2.70 KB, text/x-c++src)
2013-01-18 00:02 UTC, Brendan Long
Details

Description Brendan Long 2012-12-10 23:21:51 UTC
More specific OS: Ubuntu 12.04 32 or 64-bit

I'm making some changes to QtWebKit, which uses GStreamer. I switch the video track using:

    g_object_set(m_playBin, "current-video", trackIndex, NULL);

For some reason, the video gets messed up if I don't do a seek immediately afterwards, so I see to the current position. Similar code works for audio tracks.

This works perfectly as long as the video is playing, but if it I try to switch the current-video (or current-audio) before starting playback, I get this error:

> TestBrowser:48324): GStreamer-WARNING **: wrong STREAM_LOCK count 0

I thought it was bug #670846, but the fixed version of the package is already installed (I downloaded the source, checked it, and built it myself just to make sure).

The backtrace from where I get the warning looks like this:

Breakpoint 1, g_logv (log_domain=0x7fffec607260 "GStreamer", 
    log_level=G_LOG_LEVEL_WARNING, 
    format=0x7fffec61efaf "wrong STREAM_LOCK count %d", args1=0x7fffd94cdd08)
    at /build/buildd/glib2.0-2.32.3/./glib/gmessages.c:661
661	/build/buildd/glib2.0-2.32.3/./glib/gmessages.c: No such file or directory.
(gdb) backtrace 
  • #0 g_logv
    at /build/buildd/glib2.0-2.32.3/./glib/gmessages.c line 661
  • #1 g_log
    at /build/buildd/glib2.0-2.32.3/./glib/gmessages.c line 792
  • #2 gst_task_func
    at gsttask.c line 309
  • #3 g_thread_pool_thread_proxy
    at /build/buildd/glib2.0-2.32.3/./glib/gthreadpool.c line 309
  • #4 g_thread_proxy
    at /build/buildd/glib2.0-2.32.3/./glib/gthread.c line 801
  • #5 start_thread
    at pthread_create.c line 308
  • #6 clone
    at ../sysdeps/unix/sysv/linux/x86_64/clone.S line 112
  • #7 ??

This happens *almost* every time, so I there's some sort of race condition going on.

I created an example that sets up a basic playbin2 pipeline, then switches tracks every couple seconds, and performs a seek to the current position, and it worked fine, even if I did the track switching and seeking in a different thread. Since WebKit is gigantic, and I don't really understand a lot of what's going on, I haven't been able to narrow down what exactly makes WebKit's pipeline different than my basic version.

Is there any information that would narrow this down a bit?
Comment 1 Brendan Long 2012-12-10 23:32:36 UTC
Maybe this is somehow a duplicate of #670846, since these are lines 307-310 of gsttask.c:

        t = g_static_rec_mutex_unlock_full (lock);
        if (t <= 0) {
          g_warning ("wrong STREAM_LOCK count %d", t);
        }

But I'm looking at the source for gthread-deprecated.c (from apt-get source glib2.0) and it shows the fix from that bug though.
Comment 2 Brendan Long 2012-12-10 23:35:52 UTC
I put a print statement in g_static_rec_mutex_unlock_full to make sure I'm using the right version, and it shows up, so I'm definitely using the correct version of the code:

guint
g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex)
{
  GRecMutex *rm;
  gint depth;
  gint i;

  rm = g_static_rec_mutex_get_rec_mutex_impl (mutex);

  /* all access to mutex->depth done while still holding the lock */
  depth = mutex->depth;
  i = mutex->depth;
  mutex->depth = 0;

  while (i--)
    g_rec_mutex_unlock (rm);

  return depth;
}
Comment 3 Tim-Philipp Müller 2012-12-10 23:45:11 UTC
I'm afraid the 0.10 branch is not really maintained any longer. It would be more interesting to us to see if the problem persists with GStreamer 1.0.

However:

 - have you tried if this also happens with GStreamer from git (0.10 branch)? It might have gotten fixed since in git since the last 0.10 release.

 - perhaps you could try and narrow down which pad/element that lock relates to exactly? (e.g. by correlating the pointer to info found in the GST_DEBUG=*:8 log).
Comment 4 Brendan Long 2012-12-11 22:29:46 UTC
It looks like Qt isn't designed to compile against GStreamer 1.0 at the moment, and neither is WebKit. Switching to 0.10 from git causes lockups every time I switch, but with no warning, so presumably something else is going on. I'm trying the GST_DEBUG thing now.
Comment 5 Brendan Long 2012-12-18 18:42:09 UTC
Created attachment 231824 [details]
Program that uses a basic playbin(2) pipeline and switches video or audio tracks randomly

This should build against GStreamer 0.10 or 1.0 from Git:

libtool --mode=link g++ -o example switchtrackexample.cpp `pkg-config --libs --cflags gstreamer-1.0`
# or
libtool --mode=link g++ -o example switchtrackexample.cpp `pkg-config --libs --cflags gstreamer-0.10`

Run it against the attached MKV and OGV files to see how it locks up consistently on both.
Comment 6 Tim-Philipp Müller 2012-12-18 18:46:03 UTC
It might be a wrong/superfluous UNLOCK  call somewhere inside playbin/playsink or some plugin or GStreamer core even. Will try your code.
Comment 7 Tim-Philipp Müller 2012-12-18 18:49:27 UTC
Just to confirm: you are saying you can reproduce the lockups or warnings still with 1.0, right?

Bugzilla only accepts attachements up to 1MB or 750kB or so, maybe you could make the sample files available some other way, or see if you can reproduce it with one of the widely available tears of steels / sintel / big buck bunny files.
Comment 8 Brendan Long 2012-12-18 18:53:21 UTC
Here's some example files (~15 MB each, too big to upload here). The first two definitely lock up on GStreamer 0.10 and 1.0 from Git. The third one locked up with GStreamer 0.10 from Ubuntu, but I can't get it to play from Git (missing plugin).

MKV file with two video tracks, two audio tracks, and a bunch of subtitle tracks:
http://dl.dropbox.com/u/61100892/two_videos.mkv

OGV file with two video tracks and two audio tracks (maybe subtitles, I can't remember):
http://dl.dropbox.com/u/61100892/two_videos.ogv

M4V file I got from W3C somewhere with two audio tracks (warning: extremely annoying beeping):
http://dl.dropbox.com/u/61100892/multi-audio-en-es.m4v
Comment 9 Brendan Long 2012-12-18 18:57:59 UTC
I tested against the 0.10 and master (presumably 1.0) branches with identical results.
Comment 10 Brendan Long 2012-12-18 19:06:35 UTC
One one clarification: My first comment was when I was running against Ubuntu's GStreamer 0.10 package, where this bug was intermittent and caused the wrong STREAM_LOCK error. My example from today is GStreamer 1.0/0.10 from Git, the lockup happens every time, and there's no STREAM_LOCK warning.
Comment 11 Brendan Long 2013-01-09 18:31:41 UTC
This was changed to UNCONFIRMED. Is there any more information you'll need from me to confirm this?

I realize you're probably on vacation, so no hurry, I just want to make sure you're not waiting on me.
Comment 12 Tim-Philipp Müller 2013-01-09 18:40:49 UTC
We don't really differentiate between UNCONFIRMED and NEW. It was changed back to UNCONFIRMED from NEEDINFO to re-open it after you provided information. bugzilla doesn't allow one to go straight to NEW from there. In any case, doesn't make much difference to us. I'm only interested in 1.0 stuff though. 0.10 is no longer maintained.
Comment 13 Brendan Long 2013-01-09 18:45:37 UTC
My most recent attachments demonstrate the problem in 1.0 also (master on git). I'm hoping that whatever fixes that will be close enough to the problem that I can come up with a patch for the 0.10 branch, but just fixing the 1.0 branch would be very helpful.
Comment 14 Brendan Long 2013-01-10 22:30:39 UTC
I was going some research today to try to figure out how major programs are using this without problems, and what I've found is that the majority of GStreamer media players don't expose multiple tracks (most just use whatever is auto-selected). Totem is the only exception I found, and it runs into a different bug: If you switch audio tracks (Sound -> Languages), the audio doesn't actually change until you do a seek. If you switch text tracks (View -> Subtitles), subtitles stop working until you do a seek. I ran into that bug before and assumed it had something to do with buffers, which is why I'm doing a (flushing) seek right after I switch tracks.

You can reproduce this yourself by opening either of the videos I linked to in my Dropbox in Totem, and trying to switch the language or subtitles.
Comment 15 Brendan Long 2013-01-17 21:38:34 UTC
A coworker had trouble reproducing this, so I want to clarify -- the lockup only happens if you try to switch the track, then seek, while the player is in GST_STATE_PAUSED. Once you set it to GST_STATE_PLAYING, everything works fine.
Comment 16 Brendan Long 2013-01-18 00:02:36 UTC
Created attachment 233706 [details]
A GStreamer program that sets up a paused pipeline and then seeks to the start

Actually, it looks like trying to seek before the video starts playing causes the problem. Switching video/audio/text tracks doesn't matter. The reason this came up is that I was using the seek as a workaround for changing tracks not working. My coworker helped me realize I was focusing too much on the work around.

So:

1. Create playbin pipeline
2. Set to GST_STATE_PAUSED
3. Do any kind of seek
4. Lockup

This is important for more than just changing tracks. Users may also want to set the playback rate before the video starts playing, and the only way I know of to do that is to do a seek.
Comment 17 Brendan Long 2013-01-18 00:30:31 UTC
Nevermind, it is something about the interaction between switching the tracks and seeking. I did something stupid while testing that.

This causes it:

1. Create playbin pipeline
2. Set to GST_STATE_PAUSED
3. Switch tracks
4. Do a seek with GST_SEEK_FLAG_FLUSH
4. Lockup
Comment 18 Tim-Philipp Müller 2016-03-03 18:57:36 UTC
Is this still a problem with recent versions of GStreamer? It sounds like something we may have fixed, possibly multiple times even ;)
Comment 19 Brendan Long 2016-03-03 20:53:16 UTC
I haven't tried in a long time, but I assume it's probably fixed by now.