mirror of
https://github.com/mpv-player/mpv
synced 2024-12-24 15:52:25 +00:00
stats: support for multiple "pages" of stats
Please note that the latest version of this script needs a very recent version of mpv (from yesterday, to be precise, see the readme). For older versions, please go to "releases". HOW IT WORKS: While the stats are visible (i.e. text is printed to the OSD) a subsequent click on a numeric key (1, 2, ...) will display the corresponding "page". This works no matter if the stats are toggled or just shown as a single invocation. In case of a single invocation, the newly displayed page will be shown for the full duration again. The selected page will be remembered (not persistantly though). So far, only 3 pages are available. 1: the default page, stats as they used to be 2: extensive VO performance stats (to be redesigned/changed soon) 3: dummy In the future, many more pages are possible. Implementation is likely to change again (functionality will stay the same). A new timer had to be introduced to remove the forced keybindings in the oneshot case. The toggle case can remove them without a timer. Ensuring that each mode won't remove timers of the other mode didn't really turn out neat. Therefore, I intend to change this again, maybe by merging the oneshot case into the toggle case.
This commit is contained in:
parent
c04ff9dce0
commit
98ddbf8c34
@ -14,8 +14,11 @@ local o = {
|
||||
-- Default key bindings
|
||||
key_oneshot = "i",
|
||||
key_toggle = "I",
|
||||
key_page_1 = "1",
|
||||
key_page_2 = "2",
|
||||
key_page_3 = "3",
|
||||
|
||||
duration = 3,
|
||||
duration = 4,
|
||||
redraw_delay = 1, -- acts as duration in the toggling case
|
||||
ass_formatting = true,
|
||||
timing_warning = true,
|
||||
@ -70,17 +73,24 @@ options.read_options(o)
|
||||
|
||||
local format = string.format
|
||||
local max = math.max
|
||||
|
||||
-- Function used to record performance data
|
||||
local recorder = nil
|
||||
-- Timer used for toggling
|
||||
local timer = nil
|
||||
local toggle_timer = nil
|
||||
-- Timer used to remove forced keybindings
|
||||
local binding_timer = nil
|
||||
-- Current page and <page key>:<page function> mappings
|
||||
local curr_page = o.key_page_1
|
||||
local pages = {}
|
||||
|
||||
-- Save these sequences locally as we'll need them a lot
|
||||
local ass_start = mp.get_property_osd("osd-ass-cc/0")
|
||||
local ass_stop = mp.get_property_osd("osd-ass-cc/1")
|
||||
|
||||
-- Ring buffers for the values used to construct a graph.
|
||||
-- .pos denotes the current position, .len the buffer length
|
||||
-- .max is the max value in the corresponding buffer as computed in record_data().
|
||||
-- .max is the max value in the corresponding buffer
|
||||
local vsratio_buf, vsjitter_buf
|
||||
local function init_buffers()
|
||||
vsratio_buf = {0, pos = 1, len = 50, max = 0}
|
||||
@ -96,6 +106,8 @@ local property_aliases = {
|
||||
["frame-drop-count"] = "vo-drop-frame-count",
|
||||
["container-fps"] = "fps",
|
||||
}
|
||||
|
||||
|
||||
-- Return deprecated name for the given property
|
||||
local function compat(p)
|
||||
while not property_list[p] and property_aliases[p] do
|
||||
@ -167,7 +179,7 @@ end
|
||||
-- Generate a graph from the given values.
|
||||
-- Returns an ASS formatted vector drawing as string.
|
||||
--
|
||||
-- values: Array/Table of numbers representing the data. Used like a ring buffer
|
||||
-- values: Array/table of numbers representing the data. Used like a ring buffer
|
||||
-- it will get iterated backwards `len` times starting at position `i`.
|
||||
-- i : Index of the latest data value in `values`.
|
||||
-- len : The length/amount of numbers in `values`.
|
||||
@ -249,6 +261,7 @@ local function append_property(s, prop, attr, excluded)
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
local function append_perfdata(s, full)
|
||||
local vo_p = mp.get_property_native("vo-passes")
|
||||
if not vo_p then
|
||||
@ -349,7 +362,7 @@ local function append_display_sync(s)
|
||||
end
|
||||
|
||||
-- As we need to plot some graphs we print jitter and ratio on their own lines
|
||||
if timer:is_enabled() and (o.plot_vsync_ratio or o.plot_vsync_jitter) and o.ass_formatting then
|
||||
if toggle_timer:is_enabled() and (o.plot_vsync_ratio or o.plot_vsync_jitter) and o.ass_formatting then
|
||||
local ratio_graph = ""
|
||||
local jitter_graph = ""
|
||||
if o.plot_vsync_ratio then
|
||||
@ -463,14 +476,8 @@ local function add_audio(s)
|
||||
end
|
||||
|
||||
|
||||
local function print_stats(duration)
|
||||
local stats = {
|
||||
header = {},
|
||||
file = {},
|
||||
video = {},
|
||||
audio = {},
|
||||
}
|
||||
|
||||
-- Determine whether ASS formatting shall/can be used
|
||||
local function eval_ass_formatting()
|
||||
o.ass_formatting = o.ass_formatting and has_vo_window()
|
||||
if not o.ass_formatting then
|
||||
o.nl = o.no_ass_nl
|
||||
@ -484,18 +491,76 @@ local function print_stats(duration)
|
||||
o.b0 = o.no_ass_b0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Returns an ASS string with "normal" stats
|
||||
local function default_stats()
|
||||
local stats = {
|
||||
header = {},
|
||||
file = {},
|
||||
video = {},
|
||||
audio = {},
|
||||
}
|
||||
|
||||
eval_ass_formatting()
|
||||
add_header(stats.header)
|
||||
add_file(stats.file)
|
||||
add_video(stats.video)
|
||||
add_audio(stats.audio)
|
||||
|
||||
mp.osd_message(table.concat(stats.header) .. table.concat(stats.file) ..
|
||||
table.concat(stats.video) .. table.concat(stats.audio),
|
||||
duration or o.duration)
|
||||
return table.concat(stats.header) .. table.concat(stats.file) ..
|
||||
table.concat(stats.video) .. table.concat(stats.audio)
|
||||
end
|
||||
|
||||
|
||||
-- Returns an ASS string with extended VO stats
|
||||
local function vo_stats()
|
||||
local stats = {}
|
||||
eval_ass_formatting()
|
||||
add_header(stats)
|
||||
append_perfdata(stats, true)
|
||||
return table.concat(stats)
|
||||
end
|
||||
|
||||
|
||||
-- Returns an ASS string with stats about filters/profiles/shaders
|
||||
local function filter_stats()
|
||||
return "filters/profiles/shaders"
|
||||
end
|
||||
|
||||
|
||||
-- Call the function for `page` and print it to OSD
|
||||
local function print_page(page, duration)
|
||||
mp.osd_message(pages[page](), duration or o.duration)
|
||||
end
|
||||
|
||||
|
||||
-- Add keybindings for every page
|
||||
local function add_page_bindings()
|
||||
local function a(k)
|
||||
return function()
|
||||
curr_page = k
|
||||
binding_timer:kill()
|
||||
binding_timer:resume()
|
||||
print_page(k, toggle_timer:is_enabled() and o.redraw_delay + 1 or nil)
|
||||
end
|
||||
end
|
||||
|
||||
for k, _ in pairs(pages) do
|
||||
mp.add_forced_key_binding(k, k, a(k), {repeatable=false})
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function remove_page_bindings()
|
||||
for k, _ in pairs(pages) do
|
||||
mp.remove_key_binding(k)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Returns a function to record vsratio/jitter with the specified `skip` value
|
||||
local function record_data(skip)
|
||||
init_buffers()
|
||||
skip = max(skip, 0)
|
||||
@ -530,38 +595,71 @@ end
|
||||
|
||||
|
||||
local function toggle_stats()
|
||||
-- In case stats are toggled while oneshot-stats are still visible the
|
||||
-- oneshot-stats will remove our keybindings
|
||||
if binding_timer:is_enabled() then
|
||||
binding_timer:kill()
|
||||
end
|
||||
|
||||
-- Disable
|
||||
if timer:is_enabled() then
|
||||
if toggle_timer:is_enabled() then
|
||||
if recorder then
|
||||
mp.unregister_event(recorder)
|
||||
recorder = nil
|
||||
end
|
||||
timer:kill()
|
||||
mp.osd_message("", 0)
|
||||
toggle_timer:kill()
|
||||
mp.osd_message("", 0) -- clear the screen
|
||||
remove_page_bindings()
|
||||
-- Enable
|
||||
else
|
||||
if o.plot_vsync_jitter or o.plot_vsync_ratio then
|
||||
recorder = record_data(o.skip_frames)
|
||||
mp.register_event("tick", recorder)
|
||||
end
|
||||
timer:resume()
|
||||
print_stats(o.redraw_delay + 1)
|
||||
add_page_bindings()
|
||||
toggle_timer:resume()
|
||||
print_page(curr_page, o.redraw_delay + 1)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Current page and <page key>:<page function> mapping
|
||||
curr_page = o.key_page_1
|
||||
pages = {
|
||||
[o.key_page_1] = default_stats,
|
||||
[o.key_page_2] = vo_stats,
|
||||
[o.key_page_3] = filter_stats,
|
||||
}
|
||||
|
||||
|
||||
-- Create timer used for toggling, pause it immediately
|
||||
timer = mp.add_periodic_timer(o.redraw_delay, function() print_stats(o.redraw_delay + 1) end)
|
||||
timer:kill()
|
||||
toggle_timer = mp.add_periodic_timer(o.redraw_delay, function() print_page(curr_page, o.redraw_delay + 1) end)
|
||||
toggle_timer:kill()
|
||||
|
||||
-- Create timer used to remove forced key bindings, only in the "single invocation" case
|
||||
binding_timer = mp.add_periodic_timer(o.duration, function() remove_page_bindings() end)
|
||||
binding_timer.oneshot = true
|
||||
binding_timer:kill()
|
||||
|
||||
-- Single invocation key binding
|
||||
mp.add_key_binding(o.key_oneshot, "display_stats", print_stats, {repeatable=true})
|
||||
mp.add_key_binding(o.key_oneshot, "display_stats",
|
||||
function()
|
||||
if toggle_timer:is_enabled() then
|
||||
return
|
||||
end
|
||||
binding_timer:kill()
|
||||
binding_timer:resume()
|
||||
add_page_bindings()
|
||||
print_page(curr_page)
|
||||
end, {repeatable=true})
|
||||
|
||||
-- Toggling key binding
|
||||
mp.add_key_binding(o.key_toggle, "display_stats_toggle", toggle_stats, {repeatable=false})
|
||||
|
||||
-- Reprint stats
|
||||
mp.register_event("video-reconfig",
|
||||
function()
|
||||
if timer:is_enabled() then
|
||||
print_stats(o.redraw_delay + 1)
|
||||
if toggle_timer:is_enabled() then
|
||||
print_page(curr_page, o.redraw_delay + 1)
|
||||
end
|
||||
end)
|
||||
|
Loading…
Reference in New Issue
Block a user