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 777780 - GstBaseParse incorrectly handles non-flush seek
GstBaseParse incorrectly handles non-flush seek
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gstreamer (core)
git master
Other Mac OS
: Normal normal
: 1.11.2
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2017-01-26 09:49 UTC by Julien Isorce
Modified: 2017-02-08 11:15 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
baseparse: correctly handle non-flush seek (1.34 KB, patch)
2017-01-26 14:49 UTC, Julien Isorce
committed Details | Review
Minimal test that does not loop playback with big gap. (3.87 KB, text/x-csrc)
2017-01-26 14:55 UTC, Julien Isorce
  Details
WIP: non-flush seek unit test for gstbaseparse (7.60 KB, application/mbox)
2017-01-27 17:52 UTC, Julien Isorce
  Details
tests: add 2 unit tests for non-flush seek with gstbaseparse (12.72 KB, patch)
2017-01-31 11:33 UTC, Julien Isorce
committed Details | Review

Description Julien Isorce 2017-01-26 09:49:18 UTC
With a simple hello world app that basically just creates a playbin and sets its uri, it is possible to highlight a problem that prevents to properly loop over playbacks.

When doing a gst_element_seek(flag=~flush, position=0) upon GST_MESSAGE_SEGMENT_DONE it waits the duration of the stream before looping.

This is because segment.base is incremented by twice the duration of the stream.

I encountered the problem when playing audio files like file.{aac, flac, mp3, ac3} where there is no proper demuxer involved. More generally the problem happens when this is GstBaseParse that handles the seek.

The segment.base is first incremented here https://cgit.freedesktop.org/gstreamer/gstreamer/tree/libs/gst/base/gstbaseparse.c#n4551 and then here https://cgit.freedesktop.org/gstreamer/gstreamer/tree/libs/gst/base/gstbaseparse.c#n4649 (the memcpy just below actually writes it)

In short it is like gst_segment_to_running_time is called recursively twice (output transfered to input).

So I am wondering if the line 4649 pointed above should just be removed. Any comment ? Thx!
Comment 1 Julien Isorce 2017-01-26 09:53:52 UTC
With git blame it is possible to find the commit bdbc0693 that changes gst_element_set_seek to gst_element_do_seek and also introduces the "base" field of GstSegement. But the memcpy was present before this change.

This code is there since 2011 so I have the feeling the code is correct but the bug could have been hidden all this time. Because most of the time a real demuxer is used and also a flush seek allows to workaround that in the sense it is acceptable to do a flush in most of the situation. But in some cases it is required to do a non-flush seek.
Comment 2 Tim-Philipp Müller 2017-01-26 10:07:36 UTC
Strange that gst-plugins-good/tests/icles/test-segment-seeks foo.flac works at all then.
Comment 3 Sebastian Dröge (slomo) 2017-01-26 12:36:35 UTC
Yes I'm not sure why 4649 is there, it shouldn't be needed. Maybe it was at some point during 0.11 though.

Does your testcase work (and also Tim's) after removing that line? If so, go ahead, ideally with a test.
Comment 4 Julien Isorce 2017-01-26 14:49:00 UTC
(In reply to Tim-Philipp Müller from comment #2)
> Strange that gst-plugins-good/tests/icles/test-segment-seeks foo.flac works
> at all then.

Thx for pointing that test. I just tried it and it does not work as expected. You can hear a cut at each seek. With the following attached patch the sound is continuous.
Comment 5 Julien Isorce 2017-01-26 14:49:57 UTC
Created attachment 344323 [details] [review]
baseparse: correctly handle non-flush seek
Comment 6 Julien Isorce 2017-01-26 14:55:20 UTC
Created attachment 344324 [details]
Minimal test that does not loop playback with big gap.

gcc -Wall -O0 main.c -o main $(pkg-config --cflags --libs gstreamer-1.0)
./main file.mp3
Without attached patch: At each end the pipeline waits for the duration of the stream doing nothing (just a clock_wait)
With patch: it plays and restart continuously.

Should I put this test in gstreamer/tests/examples ? Or do you want something which is run upon make check ?
Comment 7 Sebastian Dröge (slomo) 2017-01-26 14:56:05 UTC
Comment on attachment 344323 [details] [review]
baseparse: correctly handle non-flush seek

Makes sense to me
Comment 8 Sebastian Dröge (slomo) 2017-01-26 14:58:22 UTC
(In reply to Julien Isorce from comment #6)

> Should I put this test in gstreamer/tests/examples ? Or do you want
> something which is run upon make check ?

If you can make it an automated test that would be great, but that doesn't seem trivial here
Comment 9 Tim-Philipp Müller 2017-01-26 15:01:51 UTC
> Thx for pointing that test. I just tried it and it does not work as
> expected. You can hear a cut at each seek. With the following attached patch
> the sound is continuous.

Ah, that's great. I never investigated what caused the crackle, I just assumed it was related to the audiosink resetting things on the DISCONT flag or such :)
Comment 10 Julien Isorce 2017-01-26 16:53:34 UTC
Comment on attachment 344323 [details] [review]
baseparse: correctly handle non-flush seek

commit b2c05cac8e50204d9ded4a858618c8b8b5b00910
Author: Julien Isorce <jisorce@oblong.com>
Date:   Thu Jan 26 16:51:21 2017 +0000

    baseparse: correctly handle non-flush seek
    
    Otherwise when seeking/looping to the start when reaching the end,
    the sink waits for the duration of the stream. So the user hears
    nothing for the duration of the stream before it actually loop again.
    See example attached to the bug for that.
    
    Existing test:
    gst-plugins-good/tests/icles/test-segment-seeks foo.flac
    Without the patch the user hears a crack/cut at each seek.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=777780
Comment 11 Julien Isorce 2017-01-26 16:57:14 UTC
Thx you both for the review and comments. I realized I cannot integrate my example in the patch since the example should go to -good, at least not to -core. So I updated commit message and I pushed it. Because the new example will go in a separate patch anyway and the exiting example is good enough to reproduce that issue.

I keep the bug open till I push the new example and will think about an automated test.
Comment 12 Julien Isorce 2017-01-27 17:52:39 UTC
Created attachment 344435 [details]
WIP: non-flush seek unit test for gstbaseparse

Added automated unit test tests/check/pipelines/seek.c::test_loopback (similar as basesrc ! baseparse ! fakesink sync=1). On going work, will try to finish next week.
Comment 13 Julien Isorce 2017-01-31 11:33:42 UTC
Created attachment 344643 [details] [review]
tests: add 2 unit tests for non-flush seek with gstbaseparse

Please review this patch that contains 2 unit tests. Both would have fail without the fix above. The bug could manifest itself differently because it messed-up the "segment.base". In one case it could make the pipeline to wait (for sync) and on an other case it could make the pipeline to play out of sync.
These 2 new unit tests verify these 2 cases.
Comment 14 Julien Isorce 2017-02-08 09:10:27 UTC
Should I just merge the test then ?
Comment 15 Sebastian Dröge (slomo) 2017-02-08 09:26:29 UTC
Does it work reliably? If so, go ahead :)
Comment 16 Julien Isorce 2017-02-08 09:37:23 UTC
(In reply to Sebastian Dröge (slomo) from comment #15)
> Does it work reliably? If so, go ahead :)

I designed it to be reliable and it looks to work reliably. I have not seen anything wrong for all the run I did. So I will push it and if anyone see any flakiness let me know (but it should not be flaky at all in principle :) )
Comment 17 Julien Isorce 2017-02-08 10:58:19 UTC
Comment on attachment 344643 [details] [review]
tests: add 2 unit tests for non-flush seek with gstbaseparse

commit b66109abf7d4968164af30253b94582e1e835dff
Author: Julien Isorce <jisorce@oblong.com>
Date:   Tue Jan 31 09:55:59 2017 +0000

    tests: add 2 unit tests for non-flush seek with gstbaseparse
    
    The unit test defines a test parse element that inherit from GstBaseParse.
    The test pipeline is: fakesrc ! testparse ! fakesink sync=1
    
    Before the fix b2c05cac8 the first new test would have fail because the
    pipeline would have wait doing nothing just after proceeded the seek event.
    The second new test would have fail because the pipeline would have
    played the media instantly just after proceeded the seek event
    (like if sync was FALSE on the sink).
    
    https://bugzilla.gnome.org/show_bug.cgi?id=777780
Comment 18 Julien Isorce 2017-02-08 11:10:08 UTC
All done, closing. As a follow-up I think we should create a new debug element "testseek" to send a customizable seek event upon a selectable event/action. It would superseed existing navseek element.