Previously stats_time_start first sampled cpu-time and then real-time,
while stats_time_end sampled them in reverse order.
This resulted in real-time delta values being possibly a bit smaller
than the respective cpu-time deltas, which could become meaningful if
the start/end durations are consistently very short and very frequent.
In one test case (measuging the time spent at the event loop of
a script which spins on zero timeouts), this resulted in accumulated
real-time value of ~230ms per second, with a respective cpu-time
values of ~500ms. This should not be possible with single thread load.
Now start and end sample the values at the same order, so that it
balances on average. Each start/end delta now includes overhead of one
of each sample type, and excludes one of each sample type on average.
With the test case above, it's now 490 +-1 ms for both.
(the other 510ms real-time are at the excluded mpv_wait_event calls
and the unmeasured-overhead-parts of stats_time_start/end).
This fixes a bug where if stats reset happened after stats_time_start
and before stats_time_end, then the next reported cpu-time value of
that measurement was from the thread startup.
The long version:
stats resets the time-accumulated values if more than two seconds
ellapsed since last poll.
The reset keeps the elements, but makes them as if no measurement was
yet taken, so that they don't show up at new reports until a new
measurement is taken.
While the events and (untimed) cpu are reset, the timed-cpu value
was only partially reset - the values are reset but the indication
that the element is empty was not enough for stats_time_end.
So when reset happened between start/end calls, stats_time_end was
entered eventhough it shouldn't have, but with reset cpu-time value
it calculated the time since the thread's startup, hence this bug.
Further polls were ok, because they are of the delta since the
previous poll. But at the next reset it happened again.
Now the cpu-value is reset correctly, which fixes this bug.
stats_time_start and stats_time_end accumulate real-time and cpu-time
between these calls, but the total was only updated on stats_time_end.
This resulted in two issues:
- Inaccurate measured value if a report (read the perf-info property)
happened between start/end. No biggie because it's OK on average and
typically each start/end duration is quite smaller than the interval.
- If the start/end duration is bigger than the interval, then one or
more intervals had a report value (delta) of 0, and then one report
with a value bigger than the interval - which shouldn't be possible.
This commit effectively does end+start at the report time for ongoing
timed measurements, so that the report accounts for them too.
Doing end+start at the report required two more changes:
Store the element type (VAL_TIME) at stats_time_start rather than at
the end. Otherwise if the report happens after the first start but
before the first end, then the type is not yet set and the element
is skipped at the report (bypassing the end+start).
Store the thread id at the element. start/end measure the cpu-time at
the current thread so they used pthread_self(), but with the report
usually running on a different thread, it needs the thread id for the
measurement. Measuring cpu-time from a different thread is OK, and
already happens with VAL_THREAD_CPU_TIME elements during the report.
While at it, stats_time_end now uses the thread id which was stored on
start instead of using pthread_self(). This also serves as a general
protection against measuring start/end from different threads, which
would yield generally meaningless results anyway. In mpv all the
start/end calls for the same element are at the same thread.
On Windows and any other platform where cpu-time is unsuported,
previously the cpu-time was reported as 0, and now it's omitted
(at the perf-info property native value).
Code which process this report, like stats.lua, could not distinguish
between 0 which was due to unsupported platform, and "real" 0 which
indicates zero cpu activity in this poll-period.
In stats.lua this resulted in a whole lot of empty cpu graphs,
including one for every loaded script.
Now cpu-time is excluded from the report on unsupported platforms.
Real-time is obviously still being reported where requested.
Implementation wise, this is slightly hacky, by literally only
excluding the cpu-time nodes from the report itself, while keeping
all the other cpu-tinme code intact.
A more correct solution might be to identify support at compile
(configure) time, and no-op the relevant code if needed.
However, stats.c is already hacky in parts, and there's no real cost
to keeping the code active even if the result is excluded at the
report, and it's also way simpler and less bug prone. So be it.
If the cloned repo is shallow (e.g. like the default github actions
settings), the git describe command won't actually be able to fetch any
tags and will instead just get a hash. The resulting binary version
string will end up being that git hash. While it does tell you the exact
commit, it's not exactly helpful when wanting to know the general
version at a glance. For the case where we do have a git directory but
no available tags, build a version string using the mpv version + the
commit hash.
Fixes#15789.
This update introduces a demux_packet_pool, allowing for the reuse of
previously allocated packets when needed.
sizeof(AVPacket) is not a part of the lavc public ABI, which prevents us
to allocate memory in larger blocks. However, we can substantially
decrease the amount of alloc/free operations during playback by reusing
both mpv's demux_packet and AVPacket.
This adjustment addresses the root cause of issue #12076, which,
although resolved upstream, did not fully tackle the persistent problem
of allocating small blocks of aligned memory. This issue largely stems
from the FFmpeg design of the AVPacket API. After this change memory
will no longer be allocated once cache limits is reached.
The demux_packet_pool is shared as a global pool of packets for a given
MPContext.
This change significantly speeds up the demuxer deinitialization,
benefiting file switching scenarios, especially when a large demuxer
cache is used.
See: #12294
See: #12563
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
There's several path-related options that do not handle common shortcuts
(like ~/). Fix this by using mp_get_user_path where appropriate which
expands the path so users get more intuitive behavior. Fixes#15598.
If the playlist is loaded directly from a protocol like memory://, the
playlist_path represents the entire playlist. In cases where we have a
large playlist, this results in the entire playlist being duplicated for
each item. For example, if the input size is 300 kB with 10k items, we
end up using 3 GB of memory just to store the playlist_path strings.
In idle mode, there is not status line and we sometimes want to have
output without last new line, which were always added after truncation.
Also, make sure we don't overwrite important chars with ellipsis, this
could happen when cut point is near the end.
Fixes: bf025cd289
Add 4 stage trie to lookup unicode codepoint width and grapheme join
rules.
Generated by GraphemeTableGen from Microsoft Terminal (MIT Licence):
a7e47b711a/src/tools/GraphemeTableGen/Program.cs
With minor adjustment to use it in C codebase.
- Replaced constexpr with static
- Replaced auto with explicit types
Generated from Unicode 16.0.0:
ucd.nounihan.grouped.xml: sha256(b11c2d23673bae660fff8ddcd3c1de4d54bdf6c60188a07696b010282f515fcf)
Also avoid regular white/black, because it is often the terminal
background and invisible as foreground color.
Change debug messages to blue while at it to differentiate them from
trace ones.
Similar to the previous commit but the other way around. If you start
mpv as idle, load up a playlist without immediately hitting play and
then try to go to the next item, nothing happens. Naturally, you would
expect this to go to the first item. Fix this detecting if the playlist
has not started yet, the direction, and going to the first item in the
list.
Previously, playlist-prev didn't work if you played a playlist to
completion using --idle and tried to go back. Naturally, one would
expect this to bring up the last item in the playlist, but nothing
happens. This is just because playlist_get_next is stupid and doesn't
take this into account since pl->current is NULL and thus returns NULL.
Fix this by considering the direction, checking if the playlist was
played to completion and grabbing the last entry in the index.
Previously, all stream protocols were a static list in mpv. This is okay
for own builtin stuff, but for protocols that depend on ffmpeg it's not
so great. Support for certain protocols may or may not be enabled in a
user's ffmpeg and the protocol list that mpv generates should ideally
match this. Fix this by implementing a get_protocols method for
stream_lavf that will have different results depending on the ffmpeg mpv
is built against. We keep the safe and unsafe protocols separation. The
former is essentially a whitelist. Any protocol that is found in ffmpeg
but is not in the safe whitelist is considered unsafe. In the stream
list, ffmpeg is moved to the bottom so any possible protocols that are
added in the future don't automatically take precedence over any builtin
mpv ones.
This avoids printing any stray messages in encode output stream.
--o is already pre-parse cli option which is designed to be parsed
before anything else is printed to output. So we can use that to force
stderr output if needed for encode mode.