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 576381 - [basesink] QoS: emergency rendering not always done
[basesink] QoS: emergency rendering not always done
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gstreamer (core)
git master
Other Linux
: Normal normal
: 0.10.23
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2009-03-23 11:05 UTC by Tim-Philipp Müller
Modified: 2009-03-23 13:00 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
log 1: no emergency rendering done. Try: grep -C1 last_in_time log (97.90 KB, text/plain)
2009-03-23 11:10 UTC, Tim-Philipp Müller
Details
log 2: with patch, emergency rendering done as expected (101.61 KB, text/plain)
2009-03-23 11:15 UTC, Tim-Philipp Müller
Details

Description Tim-Philipp Müller 2009-03-23 11:05:20 UTC
Consider a situation where a video decoder is very very slow, *much* slower than the desired framerate. The decoder supports QoS, yet still only the very first frame is ever rendered; no 'emergency renderings' are done, because all buffers but the very first are late and the code in gst_base_sink_is_too_late() goes like this:

     /* !!emergency!!, if we did not receive anything valid for more than a 
      * second, render it anyway so the user sees something */
     if (priv->last_in_time && start - priv->last_in_time > GST_SECOND) {
      late = FALSE;
      GST_DEBUG_OBJECT (basesink,
          "**emergency** last buffer at %" GST_TIME_FORMAT " > GST_SECOND",
          GST_TIME_ARGS (priv->last_in_time));
    }

The problem is the priv->last_in_time != 0 check here. priv->last_in_time is updated whenever a frame/buffer is actually rendered (normal or emergency), so if only the very first frame with a timestamp of 0 ever got rendered, no emergency renderings will be done ever again, unless a buffer actually arrives in time, which would set last_in_time to something non-0.

I think this should be:

     /* !!emergency!!, if we did not receive anything valid for more than a 
      * second, render it anyway so the user sees something */
-    if (priv->last_in_time && start - priv->last_in_time > GST_SECOND) {
+    if (priv->last_in_time != -1 && start - priv->last_in_time > GST_SECOND) {

instead (or maybe the last_in_time check should just be dropped at all?).

I will attach two logs that demonstrate the problem.
Comment 1 Tim-Philipp Müller 2009-03-23 11:10:30 UTC
Created attachment 131173 [details]
log 1: no emergency rendering done. Try: grep -C1 last_in_time log
Comment 2 Tim-Philipp Müller 2009-03-23 11:15:33 UTC
Created attachment 131174 [details]
log 2: with patch, emergency rendering done as expected
Comment 3 Wim Taymans 2009-03-23 12:15:06 UTC
This is correct, it should check for != -1.
Comment 4 Tim-Philipp Müller 2009-03-23 13:00:10 UTC
commit 13f804123800839b4d8114deacb8a36224c62cde
Author: Tim-Philipp Müller <tim.muller@collabora.co.uk>
Date:   Mon Mar 23 12:34:34 2009 +0000

    basesink: fix once-per-second 'emergency rendering' for case where all buffers but the very first are late
    
    Due to a typo basesink didn't do any emergency rendering of late buffers
    if the only buffer ever rendered was the first one with timestamp 0. This
    means that in cases where the decoder is very very slow, we'd never see
    any buffers but the very first one rendered. Fixes #576381.