diff options
author | Avi Halachmi (:avih) <avihpit@yahoo.com> | 2022-02-21 13:16:30 +0200 |
---|---|---|
committer | Avi Halachmi (:avih) <avihpit@yahoo.com> | 2022-02-21 16:05:02 +0200 |
commit | 37927b65f719aac817717c88c10b05ca7246248a (patch) | |
tree | 8213bdf902d09350a5affdfa5c0fbe485c9b7f17 /player | |
parent | fbe154831a8addfc18a4f81e1c4b9284c31acace (diff) | |
download | mpv-37927b65f719aac817717c88c10b05ca7246248a.tar.bz2 mpv-37927b65f719aac817717c88c10b05ca7246248a.tar.xz |
stats.lua: graphs: fix bad rendering due to division by 0
This fixes two potential divisions by 0 at generate_graph(...):
- If v_avg is (given and) 0.
- if v_max is 0.
The former doesn't seem to happen in practice because v_avg is only
used at one generate_gpah call, where it's apparently not 0.
The latter triggers if all the graph values are 0 (hence v_max is
also 0).
The implication of these divisions by 0 is an invalid y-value which
ends up at the ASS coordinates string for the graph inner content.
On linux the value ends as "nan" (luajit) or "-nan" (lua 5.1/5.2), and
on Windows it's "nan" (luajit) or "-1.#IND00" (lua 5.1/5.2), maybe due
to msvcrt's snprintf.
All these strings are wrong as ASS numbers, but due to luck in how
libass parses the coordinates, "nan" and "-nan" result in empty graph
(which looks OK for "all values are 0"), while "-1.#IND00" is parsed
as -1, which breaks the graph rendering (affects other graphs too).
One example of "all values are 0" is at page 0 (internal performance
graphs) on Windows - because the cpu metrics don't work.
So this fixes at least page 0 on Windows with lua 5.1/5.2.
While at it, move the scale calculations to one place, which now
avoids division by 0, instead of duplicating this calculation.
In the future, we can consider improving the generate_graph API:
- It needs one peak value, but takes 3 (v_max, v_avg, scale) which
are meshed into one final value.
- v_avg is only used in 1 of 6 call sites, but at the middle of the
arguments, so all other call sites need to pass explicit "nil".
- "scale" is arbitrary and used to leave some space at the top of the
graph. 5 places use 0.8, one uses 0.9. Could probably be unified.
Diffstat (limited to 'player')
-rw-r--r-- | player/lua/stats.lua | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/player/lua/stats.lua b/player/lua/stats.lua index 8e42351690..4ae5aaa73a 100644 --- a/player/lua/stats.lua +++ b/player/lua/stats.lua @@ -211,18 +211,21 @@ local function generate_graph(values, i, len, v_max, v_avg, scale, x_tics) local y_max = o.font_size * 0.66 local x = 0 - -- try and center the graph if possible, but avoid going above `scale` - if v_avg then - scale = min(scale, v_max / (2 * v_avg)) - end + if v_max > 0 then + -- try and center the graph if possible, but avoid going above `scale` + if v_avg and v_avg > 0 then + scale = min(scale, v_max / (2 * v_avg)) + end + scale = scale * y_max / v_max + end -- else if v_max==0 then all values are 0 and scale doesn't matter - local s = {format("m 0 0 n %f %f l ", x, y_max - (y_max * values[i] / v_max * scale))} + local s = {format("m 0 0 n %f %f l ", x, y_max - scale * values[i])} i = ((i - 2) % len) + 1 for p = 1, len - 1 do if values[i] then x = x - x_tics - s[#s+1] = format("%f %f ", x, y_max - (y_max * values[i] / v_max * scale)) + s[#s+1] = format("%f %f ", x, y_max - scale * values[i]) end i = ((i - 2) % len) + 1 end |