mirror of
https://github.com/mpv-player/mpv
synced 2025-02-20 06:46:55 +00:00
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.
This commit is contained in:
parent
fbe154831a
commit
37927b65f7
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user