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 737055 - audiosink: Setting URI on playbin at about-to-finish when playing AAC and using an alsasink causes delayed playback
audiosink: Setting URI on playbin at about-to-finish when playing AAC and usi...
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-base
1.4.2
Other Linux
: Normal normal
: 1.4.4
Assigned To: GStreamer Maintainers
GStreamer Maintainers
: 745887 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2014-09-21 00:34 UTC by Richard Röjfors
Modified: 2015-03-10 23:13 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
audiosink: compensate for segment restart with clock's time_offset (2.25 KB, patch)
2014-09-23 17:26 UTC, Thiago Sousa Santos
committed Details | Review

Description Richard Röjfors 2014-09-21 00:34:08 UTC
I setup a playbin with an alsasink.

Then assign it an URI pointing to an AAC file. When I get the about-to-finish signal I update the uri to an URI pointing to a non AAC, for instance ape, mp3 or flac. Then I get a strange behaviour where the playbin indicates via state that it is playing. But its quiet and I see by polling the playbin for position that it is 0.

Then suddenly after a long while > 30 seconds, the position starts to increase and the song start playing (I hear audio).

During the time its quiet I can see that 

This is 100% reproducible, I use gst-libva for AAC decoding.

I switched to using a pulsesink instead, then it works as expected. Also playing let say an MP3 then a FLAC file is also working as expected. So it seems to be the combination of AAC and alsasink.

I reproduced this with 1.4.2 and 1.4.0.
Comment 1 Thiago Sousa Santos 2014-09-22 15:51:04 UTC
Is this delay before the second URI is played around the same duration of the first file?
Comment 2 Richard Röjfors 2014-09-22 19:53:11 UTC
Very interesting point!

I played a song of duration:
200690068027

Then it stalled for 401 half second timeouts -> 200,5 seconds -> The same amount of time!

Sounds like you have a clue about this?
Comment 3 Richard Röjfors 2014-09-22 19:54:31 UTC
By the way I did a test where I seeked in the first file, then the delay was shorter.
But as I as wrote earlier; when I played the while file the delay was as long as the first file...
Comment 4 Thiago Sousa Santos 2014-09-22 20:13:27 UTC
Do you mind checking if it also happens when you play those URIs with gst-play tool from gst-plugins-base?
Comment 5 Thiago Sousa Santos 2014-09-22 20:33:33 UTC
Just tested, and it indeed fails also with gst-play:

gst-play-1.0 --audiosink alsasink --gapless <aac-uri> <mp3-uri>


I have seen a similar behavior when doing some other tests. It seems related to either the DISCONT flag handling in audiobasesink, how it deals with late buffers or buffers that have a smaller timestamp than the last one received.
Comment 6 Richard Röjfors 2014-09-23 07:41:06 UTC
"Good" to hear that you could reproduce the issue as well.

But why wont we see this issue in pulsesink if it would be related to the audiobasesink?
Comment 7 Thiago Sousa Santos 2014-09-23 16:34:35 UTC
pulsesink and alsasink use different ring buffers.

Alsasink one seems to reset its writing point to 0 and then it gets requested to write to position X = previous sample last position and it has to wait to actually write and play that.

Pulsesink one does the same reset, but it sets the time_offset properly to compensate for it.

I'm trying to come up with a fix (this code is dense).
Comment 8 Thiago Sousa Santos 2014-09-23 17:26:36 UTC
Created attachment 286905 [details] [review]
audiosink: compensate for segment restart with clock's time_offset

When playing chained data the audio ringbuffer is released and
then acquired again. This makes it reset the segbase/segdone
variables, but the next sample will be scheduled to play in
the next position (right after the sample from the previous media)
and, as the segdone is at 0, the audiosink will wait the duration
of this previous media before it can write and play the new data.

What happens is this:
pointer at 0, write to 698-1564, diff 698, segtotal 20, segsize 1764, base 0

it will have to wait the length of 698 samples before being able to write.

In a regular sample playback it looks like:
pointer at 677, write to 696-1052, diff 19, segtotal 20, segsize 1764, base 0

In this case it will write to the next available position and it
doesn't need to wait or fill with silence.

This solution is borrowed from pulsesink that resets the clock to
start again from 0, which makes it reset the time_offset to the time
of the last played sample. This is used to correct the place of
writing in the ringbuffer to the new start (0 again)
Comment 9 Richard Röjfors 2014-09-23 20:12:38 UTC
The fix seem to fix the issue here!
Comment 10 Thiago Sousa Santos 2014-09-24 13:33:52 UTC
commit 8242676dc20b0a9b5dcac9a0e8048fc672d3b314
Author: Thiago Santos <thiagoss@osg.samsung.com>
Date:   Tue Sep 23 14:14:36 2014 -0300

    audiosink: compensate for segment restart with clock's time_offset
Comment 11 Sebastian Dröge (slomo) 2015-03-10 23:13:11 UTC
*** Bug 745887 has been marked as a duplicate of this bug. ***