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 785948 - audioencoder: Integer overflows in timestamp/granulepos calculation code on discont
audioencoder: Integer overflows in timestamp/granulepos calculation code on d...
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-base
unspecified
Other Linux
: Normal normal
: 1.12.3
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2017-08-07 14:08 UTC by Sebastian Dröge (slomo)
Modified: 2017-08-11 08:06 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
audioencoder: also adjust sample count upon discont to avoid ts overflow (1.66 KB, patch)
2017-08-07 19:59 UTC, Mark Nauwelaerts
none Details | Review
audioencoder: also adjust sample count upon discont to avoid ts overflow (1.93 KB, patch)
2017-08-08 18:41 UTC, Mark Nauwelaerts
committed Details | Review

Description Sebastian Dröge (slomo) 2017-08-07 14:08:21 UTC
In gst_audio_encoder_chain() we calculate the difference "diff" between the expected and actual timestamp.

> diff = GST_CLOCK_DIFF (next_ts, GST_BUFFER_TIMESTAMP (buffer));

This can sometimes be negative and that's not necessarily a problem.

Further below we shift the base_ts by that difference, and that's where things go wrong:

>     if (discont) {
>       /* now re-sync ts */
>       priv->base_ts += diff;
>       gst_audio_encoder_set_base_gp (enc);
>       priv->discont |= discont;
>     }

If base_ts was 0 before (which it usually is), this would cause an integer overflow and suddenly we have a huge timestamp.

There seem to be two potential solutions:
1) Make this an error
2) Store base_ts as a signed integer, and make sure that everything is handled correctly with negative values everywhere where it is used


As a side-note, it would also make sense to add the "discont-wait" code from e.g. audiobasesink or audiomixer here, to allow a bigger timestamp discontinuity as long as it is not that big for a longer timespan.
Comment 1 Mark Nauwelaerts 2017-08-07 19:59:18 UTC
Created attachment 357142 [details] [review]
audioencoder: also adjust sample count upon discont to avoid ts overflow
Comment 2 Mark Nauwelaerts 2017-08-07 20:00:02 UTC
When writing the second code-fragment, I was assuming to have enough time-slack to handle the diff.  But indeed, the base_ts is usually 0 (or thereabout).  However, there is a lot of slack in the sample count, so we could do it as in attached patch.  That avoid the tricky-ness of a negative ts, and only errors out if things are really bad.

Applying the "discont-wait" could indeed make things a bit less jitterish and align it with audiobasesink (as it was once originally).
Comment 3 Sebastian Dröge (slomo) 2017-08-08 08:00:41 UTC
Review of attachment 357142 [details] [review]:

Looks good to me, please add some further details about what and why and how to the commit message though :) Thanks for the fast patch!

::: gst-libs/gst/audio/gstaudioencoder.c
@@ +1330,3 @@
+          GST_SECOND, ctx->info.rate * ctx->info.bpf);
+
+      if (shift > GST_BUFFER_TIMESTAMP (buffer)) {

I think this can never happen, or can it?
Comment 4 Mark Nauwelaerts 2017-08-08 18:22:48 UTC
It is very unlikely to happen.  It theoretically could if after (say) 5s another buffer would come in with ts 0 while still some other stuff in the adapter.  Then I would not want to be caught trying to subtract into the negative, but as said things are already pretty weird for that to happen.  But I suppose it's then better to error out than to have more weird stuff happening.  A G_UNLIKELY could be sprinkled there for good measure.

I shall also endeavour to restrain succinct proclivity ...
Comment 5 Mark Nauwelaerts 2017-08-08 18:41:48 UTC
Created attachment 357214 [details] [review]
audioencoder: also adjust sample count upon discont to avoid ts overflow
Comment 6 Sebastian Dröge (slomo) 2017-08-08 19:17:42 UTC
Comment on attachment 357214 [details] [review]
audioencoder: also adjust sample count upon discont to avoid ts overflow

Go for it :)
Comment 7 Mark Nauwelaerts 2017-08-09 07:39:05 UTC
commit 00fa39befae4076277c9a046f72c9fe8a4275048
Author: Mark Nauwelaerts <mnauw@users.sourceforge.net>
Date:   Tue Aug 8 20:35:25 2017 +0200

    audioencoder: also adjust sample count upon discont to avoid ts overflow
    
    Only adjusting the base_ts might lead to a negative ts and as such integer
    overflow into a huge timestamp which then propagates into the granulepos
    and so on.  Instead, resync to incoming buffer timestamp using both base_ts
    and sample count rather than only base_ts.
    
    Fixes https://bugzilla.gnome.org/show_bug.cgi?id=785948