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 706779 - oggmux: support flushing seeks
oggmux: support flushing seeks
Status: RESOLVED INCOMPLETE
Product: GStreamer
Classification: Platform
Component: gst-plugins-base
git master
Other All
: Normal enhancement
: git master
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on: 708416
Blocks:
 
 
Reported: 2013-08-26 06:25 UTC by Alessandro Decina
Modified: 2018-05-04 13:09 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
WIP patch (11.97 KB, patch)
2013-08-26 06:25 UTC, Alessandro Decina
none Details | Review
new attempt (15.10 KB, patch)
2013-08-28 06:49 UTC, Alessandro Decina
none Details | Review
new version (15.30 KB, patch)
2013-08-28 08:22 UTC, Alessandro Decina
none Details | Review
new patch (15.08 KB, patch)
2013-08-29 05:30 UTC, Alessandro Decina
needs-work Details | Review
new day, new patch (15.41 KB, patch)
2013-08-30 05:30 UTC, Alessandro Decina
accepted-commit_now Details | Review
Fixes an issue which prevents the not racy scenario to actually not be racy. (897 bytes, patch)
2013-09-18 01:05 UTC, Mathieu Duponchelle
rejected Details | Review
updated against new collectpads API (12.46 KB, patch)
2013-10-12 14:46 UTC, Alessandro Decina
none Details | Review
push the correct segment after seeking (2.45 KB, patch)
2013-10-12 14:48 UTC, Alessandro Decina
none Details | Review

Description Alessandro Decina 2013-08-26 06:25:31 UTC
Created attachment 253094 [details] [review]
WIP patch

Here's some initial code that adds flushing seek support to oggmux. Likely not 100% correct/complete, but works for the simple case audiotestsrc ! vorbisenc ! oggmux ! filesink

The logic is copied from (my limited understanding of) videomixer. Things i'm not sure about:

1) not sure if what happens in the case upstream fails to seek after gst_ogg_mux_handle_src_event has already sent FLUSH_START is correct. In that case gst_ogg_mux_collected will send a flush_stop but won't send a new segment. Should it?

2) FLUSH_STOP aggregation is done by forwarding the first FLUSH_STOP and then ignoring the others. That's what videomixer does but what if this case happens: one upstream sends FLUSH_STOP; another upstream sends more data belonging to the old segment; the other upstream finally sends FLUSH_STOP. Isn't this racy?

3) related to 2), the code that handles the _SEEK sets collectpads to flushing, grabs GST_COLLECT_PADS_STREAM_LOCK, sets some internal flags, unsets collectpads flushing. Is that really enough? shouldn't it wait until upstreams have started flushing?

And a final note: the muxer still outputs a start=0, stop=-1 segment. I wonder  if it's worth making it output the incoming seek segment given that other places in the code make the assumption that timestamps start from 0 (see gst_ogg_mux_decorate_buffer for example)

Halp!
Comment 1 Alessandro Decina 2013-08-26 07:34:09 UTC
and to reinforce how I feel hacking in ext/ogg: http://bit.ly/18heoKh
Comment 2 Sebastian Dröge (slomo) 2013-08-26 07:39:41 UTC
(In reply to comment #0)
> Created an attachment (id=253094) [details] [review]
> WIP patch
> 
> Here's some initial code that adds flushing seek support to oggmux. Likely not
> 100% correct/complete, but works for the simple case audiotestsrc ! vorbisenc !
> oggmux ! filesink
> 
> The logic is copied from (my limited understanding of) videomixer. Things i'm
> not sure about:
> 
> 1) not sure if what happens in the case upstream fails to seek after
> gst_ogg_mux_handle_src_event has already sent FLUSH_START is correct. In that
> case gst_ogg_mux_collected will send a flush_stop but won't send a new segment.
> Should it?

What happens when a seek fails? Doesn't it just error out anyway?

> 2) FLUSH_STOP aggregation is done by forwarding the first FLUSH_STOP and then
> ignoring the others. That's what videomixer does but what if this case happens:
> one upstream sends FLUSH_STOP; another upstream sends more data belonging to
> the old segment; the other upstream finally sends FLUSH_STOP. Isn't this racy?

I think you should wait until all FLUSH_START of all upstreams are received. After that you can safely forward the very first FLUSH_STOP. Any data that is sent from upstream before the FLUSH_STOP is dropped because the pads are flushing.

> 3) related to 2), the code that handles the _SEEK sets collectpads to flushing,
> grabs GST_COLLECT_PADS_STREAM_LOCK, sets some internal flags, unsets
> collectpads flushing. Is that really enough? shouldn't it wait until upstreams
> have started flushing?

Wait until upstream started flushing until doing what?

> And a final note: the muxer still outputs a start=0, stop=-1 segment. I wonder 
> if it's worth making it output the incoming seek segment given that other
> places in the code make the assumption that timestamps start from 0 (see
> gst_ogg_mux_decorate_buffer for example)

After a seek it should output exactly the seek segment.
Comment 3 Sebastian Dröge (slomo) 2013-08-26 08:45:15 UTC
(In reply to comment #2)

> > 2) FLUSH_STOP aggregation is done by forwarding the first FLUSH_STOP and then
> > ignoring the others. That's what videomixer does but what if this case happens:
> > one upstream sends FLUSH_STOP; another upstream sends more data belonging to
> > the old segment; the other upstream finally sends FLUSH_STOP. Isn't this racy?
> 
> I think you should wait until all FLUSH_START of all upstreams are received.
> After that you can safely forward the very first FLUSH_STOP. Any data that is
> sent from upstream before the FLUSH_STOP is dropped because the pads are
> flushing.

Actually the waiting shouldn't even be necessary. It should just be ensured that collectpads drop data from all pads as soon as the flushing seek is received (or possibly when the first FLUSH_START is received on any pad). See bug #706441
Comment 4 Alessandro Decina 2013-08-28 06:49:23 UTC
Created attachment 253344 [details] [review]
new attempt

Here's a better attempt which (i think) implements what we discussed on IRC. 

The steps involved are:

1) when the flushing seek is received, mark that we're flushing and forward the event upstream. Do not set collectpads as flushing here else forwarding the event wouldn't work obviously (and doing set_flushing(TRUE); set_flushing(FALSE); forward; would be racy)

2a) on the first FLUSH_START coming from an upstream pad, flush internal state and set collectpads as flushing. Setting collectpads as flushing means that every pad is marked as FLUSHING until it gets the next FLUSH_STOP

2b) mark that we need to send FLUSH_STOP in the first next _collected call

3) in the first _collected call, send FLUSH_STOP downstream. We flush here since if we're in _collected, it means that all the pads have finished flushing (FLUSH_STOP) and have a buffer queued belonging to the new segment
Comment 5 Alessandro Decina 2013-08-28 06:51:11 UTC
(and btw: this is how I feel now that I understand oggmux/collectpads a little more: http://bit.ly/12JXa4r)
Comment 6 Alessandro Decina 2013-08-28 08:22:07 UTC
Created attachment 253349 [details] [review]
new version

changed gst_ogg_mux_flush to send flush_start() downstream to unblock the GST_COLLECT_PADS_STREAM_LOCK before calling gst_collect_pads_set_flushing()
Comment 7 Alessandro Decina 2013-08-28 09:10:31 UTC
Hm, looks like there's an issue with this approach. Non-serialized events are not blocked by collectpads so sending FLUSH_STOP in _collected doesn't work.
Comment 8 Alessandro Decina 2013-08-29 05:30:09 UTC
Created attachment 253468 [details] [review]
new patch

New patch that changes the FLUSH_STOP logic a little. Instead of sending FLUSH_STOP from the first _collected() call after a flush, we now send FLUSH_STOP right after flushing. This way oggmux:src and downstream are ready to process events/data immediately. Buffers will still resume traveling downstream again after all upstreams have finished flushing, but events that are not queued by collectpads (like _TAG events), will be able to be pushed by the upstream elements that have finished flushing (possibly while some instead are still flushing), without things failing because oggmux:src is flushing.

...or just look at gst_ogg_mux_flush in the patch.

This patch is functional now and i'll try to add a test. In the meantime, can anyone spot anything obviously wrong?
Comment 9 Sebastian Dröge (slomo) 2013-08-29 08:30:13 UTC
Review of attachment 253468 [details] [review]:

Maybe there should be some collectpads API to make this more easy, also for other elements?

::: ext/ogg/gstoggmux.c
@@ +369,3 @@
+      if (g_atomic_int_compare_and_exchange (&ogg_mux->pending_flush, TRUE,
+              FALSE)) {
+        gst_ogg_mux_flush (ogg_mux);

This now sends flush-stop from the thread that called flush-start. flush-start is OOB, so can happen from any thread. flush-stop is serialized and must happen from the streaming thread and with the srcpad stream lock.
Comment 10 Alessandro Decina 2013-08-30 05:30:46 UTC
Created attachment 253576 [details] [review]
new day, new patch

Ok this moves sending FLUSH_STOP to when the first FLUSH_STOP is received from upstream.

If we agree that the logic is alright now, I can try to move it down to collectpads and implement it in videomixer as well.
Comment 11 Sebastian Dröge (slomo) 2013-08-30 08:18:27 UTC
Review of attachment 253576 [details] [review]:

Looks good :) Also adder and interleave have the same code as videomixer

::: ext/ogg/gstoggmux.c
@@ +384,3 @@
+         * mmkay?
+         */
+        gst_pad_push_event (ogg_mux->srcpad, gst_event_new_flush_stop (TRUE));

Why not just forward the event here? ;)
Comment 12 Sebastian Dröge (slomo) 2013-09-12 10:25:44 UTC
Alessandro?
Comment 13 Mathieu Duponchelle 2013-09-18 01:05:06 UTC
Created attachment 255151 [details] [review]
Fixes an issue which prevents the not racy scenario to actually not be racy.

Current implementation uses the public list, which sometimes doesn't contain newly-added pad. It's fairly trivial to highlight this with our test suite. This uses the private list which contains *all* the pads.
Comment 14 Alessandro Decina 2013-09-18 13:08:56 UTC
Oops, sorry have been traveling and forgot about this. I'll post patches to collectpads/oggmux later today...
Comment 15 Sebastian Dröge (slomo) 2013-09-20 09:04:52 UTC
Comment on attachment 255151 [details] [review]
Fixes an issue which prevents the not racy scenario to actually not be racy.

Obsolete with Alessandro's collectpads changes
Comment 16 Alessandro Decina 2013-10-12 14:46:16 UTC
Created attachment 257105 [details] [review]
updated against new collectpads API
Comment 17 Alessandro Decina 2013-10-12 14:48:33 UTC
Created attachment 257108 [details] [review]
push the correct segment after seeking

This patch makes output timestamps after a seek match the target start/stop timestamps, instead of always starting at ts=0. Attaching as a separate patch as i'm not 100% sure this is allowed in ogg.
Comment 18 Sebastian Dröge (slomo) 2018-05-04 13:09:28 UTC
Let's close this one for now. Before adding this to oggmux or anything else, we first of all need to define a design how flushing seeks should behave in muxers so we can get consistent and meaningful behaviour.