GNOME Bugzilla – Bug 541566
GstAudioSink: sound glitches when pausing and resuming playback
Last modified: 2015-01-19 09:24:00 UTC
Please describe the problem: After resuming playback of a paused track, there is a glitch in the sound. Steps to reproduce: 1. Start playing a track 2. Pause playing the track 3. Resume playback Actual results: There is a small glitch in the sound, (sounds a bit like a hickup) Expected results: No glitches or sound artefacts. Does this happen every time? Yes Other information: This might be a bug in gstreamer (probably is), since I got the same glitches when using phonon with a gstreamer backend, and with totem.
Sure sounds like a gstreamer bug to me.
This is apparently a known issue in the GStreamer base classes and is "caused by delay between capturing the clock and pausing the audio playback" according to Wim. As such, this should probably have the component marked as gst-plugins-base.
Created attachment 217264 [details] [review] fix for "delay between capturing the clock and pausing the audio playback" This bug is not fixed yet when using alsasink. I found two issues about the sound glitches when resuming playback. The first issue is the same as Robert Swain mentioned above. The glitch is generated when gst_ring_buffer_advance() function which increments the clock is called after capturing the clock. This can be monitored by looking base_time changes with GST_DEBUG=pipeline:4. To reproduce the first issue easily, insert a short sleep as shown below before calling gst_ring_buffer_advance() in audioringbuffer_thread_func() function. if (g_atomic_int_get (&buf->state) != GST_RING_BUFFER_STATE_STARTED) usleep (10000); The attached patch is my proposal for this issue. The patch makes gstaudiosink wait for gst_ring_buffer_advance() when pausing. The second issue is buffer underrun of a gst ring buffer. When resuming/starting playback, especially on singleprocessor/singlecore systems, the gst ring buffer may temporarily be empty that caused by: - The gst ring buffer is exactly the same size of the ALSA buffer. - The ALSA buffer is empty when resuming/starting playback. - Transferring data in the gst ring buffer to the ALSA buffer while the ALSA buffer is not filled up is done in an instant. - A thread running audioringbuffer_thread_func() function usually continues running without switching to other threads on singleprocessor/singlecore systems until the ALSA buffer is filled up. The glitch appears if the ALSA driver starts transferring the next data from the empty gst ring buffer (buffer underrun). To reproduce that the gst ring buffer is temporarily empty, run a command below on a terminal (using sh, ksh, bash or zsh), then play the audio file on the totem, then pause and resume: GST_DEBUG=ringbuffer:4,alsa:4 taskset 1 totem testfile.wav 2>logfile Then look at the logfile. Before pausing: 0:00:02.800878995 7946 0x9cd55b8 DEBUG ringbuffer gstringbuffer.c:1677:default_commit: pointer at 78, write to 86-0, diff 8, segtotal 8, segsize 3760, base 0 "diff 8, segtotal 8" means that the gst ring buffer is filled. After resuming: 0:00:02.801257003 7946 0x9cd5b88 DEBUG alsa gstalsasink.c:857:gst_alsasink_write:<autoaudiosink1-actual-sink-alsa> written 940 frames out of 940 0:00:02.801374580 7946 0x9cd5b88 DEBUG alsa gstalsasink.c:857:gst_alsasink_write:<autoaudiosink1-actual-sink-alsa> written 940 frames out of 940 0:00:02.801491344 7946 0x9cd5b88 DEBUG alsa gstalsasink.c:857:gst_alsasink_write:<autoaudiosink1-actual-sink-alsa> written 940 frames out of 940 0:00:02.801604551 7946 0x9cd5b88 DEBUG alsa gstalsasink.c:857:gst_alsasink_write:<autoaudiosink1-actual-sink-alsa> written 940 frames out of 940 0:00:02.801719800 7946 0x9cd5b88 DEBUG alsa gstalsasink.c:857:gst_alsasink_write:<autoaudiosink1-actual-sink-alsa> written 940 frames out of 940 0:00:02.801833163 7946 0x9cd5b88 DEBUG alsa gstalsasink.c:857:gst_alsasink_write:<autoaudiosink1-actual-sink-alsa> written 940 frames out of 940 0:00:02.802750115 7946 0x9cd5b88 DEBUG alsa gstalsasink.c:857:gst_alsasink_write:<autoaudiosink1-actual-sink-alsa> written 940 frames out of 940 0:00:02.802784232 7946 0x9cd55b8 DEBUG ringbuffer gstringbuffer.c:1677:default_commit: pointer at 86, write to 86-0, diff 0, segtotal 8, segsize 3760, base 0 gst_alsasink_write transfers data in the gst ring buffer to the ALSA buffer. "diff 0" means that the gst ring buffer is empty. In my opinion, the second issue should be fixed by transferring data to the ALSA buffer directly without the gst ring buffer, or using ALSA mmap functions to share the gst ring buffer and the ALSA buffer.
There's a patch.
Does this still happen in 1.0? I tried: ./playback-test 1 'playbin uri=file:///home/wim/data/JB_FF9_TheGravityOfLove.ogg audio-sink="alsasink device=hw:0"' and I can't hear any clicks when pausing/playing
Not sure what to do about this. It seems like some effort was put into analyzing and explaining a corner case, and the code hasn't changed that much from the look of it (although the state change clock time taking/adjusting code has changed a little iirc), but it's not something I (or wim) can reproduce myself here, nor does the patch make any discernable different for me, nor do I get any underruns reported from alsa. So unless someone wants to have a closer look I'd say let's close it and if there are still issues in 1.x someone will file a new bug sooner or later.
Can't repro either using and pressing space over and over: gst-play-1.0 --interactive --audiosink "alsasink device=plughw:0" ~/Music/1.mp3