This change removes convoluted core thread extraction through dispatch
added in 500ce69a06.
Currently we fully control this thread, create it and join, there is no
reason not to keep the handle of it in the player context.
As a bonus to code simplification this also fixes thread handle leak on
Windows.
Fixes: #14472
This change essentially removes mp_thread_self() and instead add
mp_thread_id to track threads and have ability to query current thread
id during runtime.
This will be useful for upcoming win32 implementation, where accessing
thread handle is different than on pthreads. Greatly reduces complexity.
Otherweis locked map of tid <-> handle is required which is completely
unnecessary for all mpv use-cases.
Note that this is the mp_thread_id, not to confuse with system tid. For
example on threads-posix implementation it is simply pthread_t.
I'd like some names to be more descriptive, but to work with 15 chars
limit we have to make some sacrifice.
Also because of the limit, remove the `mpv/` prefix and prioritize
actuall thread name.
C standard says that `= {0}` activates and initializes first member of
union. We expect whole union to be zeroed, it is used as default value.
Initialize union with one zeroed default instance to ensure proper init.
Fixes: #12711
since i was going to fix the include order of stdatomic, might as well
sort the surrouding includes in accordance with the project's coding
style.
some headers can sometime require specific include order. standard
library headers usually don't. but mpv might "hack into" the standard
headers (e.g pthreads) so that complicates things a bit more.
hopefully nothing breaks. if it does, the style guide is to blame.
replace it with <stdatomic.h> and replace the mp_atomic_* typedefs with
explicit _Atomic qualified types.
also add missing config.h includes on some files.
With the previous series of commits, all internal usage has been
replaced by the nanosecond functions. There's not really any point in
keeping these around anymore plus there are macros for unit conversions
now so we can just axe them. It's worth noting that mpv_get_time_us()
obviously still needs to work for API reasons, but we can just divide
mp_time_ns() by 1000 to get the same thing.
9606c3fca9 added mp_time_ns(). Since we
apparently expose the mp_time_us() to clients already, there's no reason
to not also expose the new nanosecond one.
Changing the CONF_TYPE_FLAG was a bad idea because mpv_node.u.flag
continues to be an int, leading to a mismatch in type sizes which can
lead to problems with memcpy().
ref. #11373
This partially reverts commit 17d91b9d4d.
In debug mode the macro causes an assertion failure.
In release mode it works differently and tells the compiler that it can
assume the codepath will never execute. For this reason I was conversative
in replacing it, e.g. in mpv-internal code that exhausts all valid values
of an enum or when a condition is clear from directly preceding code.
Not all deprecated symbols were removed. Only three events were removed for now
since these are not used internally.
This bumps the library version to 2.0.
The render API replaced the opengl_cb API over 2 years ago. Since then,
the opengl_cb API was emulated on top of the render API. While it would
probably be reasonable to emulate these APIs until they're removed in an
eventual libmpv 2.0 bump, I have some non-technical reasons to disable
the API now.
The API stubs remain; they're needed for formal ABI compatibility.
May or may not help when dealing with playlist loading in scripts. It's
supposed to help with the mean fact that loading a recursive playlist
will essentially edit the playlist behind the API user's back.
Scripts such as the OSC can be loaded and unloaded at runtime by
toggling the option that enables them. (It even works, although normally
it's only used to control initial loading.)
Unloading was racy because it used the client name; fix this.
The load-script change is an accidental feature. And probably useless.
I mostly intend this for internal purposes. Probably pretty useless for
external API users, but on the other hand trivial to expose. While it
makes a lot of sense internally, I'll probably regret exposing it.
Move some parts that can be generic to the client API code. It turns out
lua.c doesn't need anything special.
This adds the "id" field. I think this was actually missing from the
JSON IPC code (i.e. it's a very recent regression that is fixed with
this commit).
Both Lua and the JSON IPC code need to convert the mpv_event struct (and
everything it points to) to Lua tables or JSON.
I was getting sick of having to make the same changes to Lua and IPC. Do
what has been done everywhere else, and let the core handle this by
going through mpv_node (which is supposed to serve both Lua tables and
JSON, and potentially other scripting language backends). Expose it as
new libmpv API function.
The new API is still a bit "rough" and support for other event types
might be added in the future.
This silently adds support for the playlist_entry_id fields to both Lua
and JSON IPC.
There is a small API change for Lua; I don't think this matters, so I
didn't care about compatibility. The new code in client.c is mashed up
from the Lua and the IPC code. The manpage additions are moved from the
Lua docs, and made slightly more "general".
Some danger for unintended regressions both in Lua and IPC. Also damn
these node functions suck, expect crashes due to UB.
Not sure why this became more code instead of less compared to before
(according to the diff stat), even though some code duplication across
Lua and IPC was removed. Software development sucks.
This was not reset in the num_properties==0 case. This didn't really
matter, but for debugging it's slightly nicer to see new_property_events
reset once the client thread is done with it.
When the current file changes (or rather, when starting/finishing
playback of a playlist entry), clients tend to have the problem that
it's hard to tell whether a property change notification (via
mpv_observe_property() and mechanisms layered on top of it) is from the
previous or new playlist entry. The previous commit probably helps, but
all the asynchronity is still a bit unhelpful.
Try to make this better by adding new hooks, that are run before/after
playback init/deinit. This is similar to the existing hooks, except
they're outside of "initialized" playback, which excludes that you might
accidentally get an overlap between the current and the previous/next
playlist entry.
That still doesn't seem quite enough, since normally, property change
notifications come after the hook event. So basically a client would
have to explicitly "drain" the event queue within the hook, and make the
hook continue only after that is done. Knowing when property
notifications are done is another asynchronous nightmare (how exactly it
works keeps changing within client.c, and an API user probably can't
tell anymore when all pending properties are truly done). So introduce
another guarantee: properties that were changed before the hook happens
will be returned before the hook event is returned. That means the
client will have received all pending property notifications from the
previous playlist entry (or whatever) before the hook is entered.
As another minor complication, we shouldn't just keep the hook pending
until _all_ property notifications are done, since the client's hook
could produce new ones. (Or just consider things like the demuxer thread
hammering the client with cache update events, while the "on_preloaded"
hook is run.) So there is some extra untested, fragile logic in client.c
to handle this (the waiting_for_hook flag).
This probably works, but was barely tested. Not sure if this helps
anyone, but I think it's fine for my own purposes. (I really hated this
aspect of the API whenever I used it myself.)
This could happen if a property was flagged as changed, then updated,
then flagged again, but gen_property_change_event() was called before
the value was updated a second time. Then the function simply returned
the old value, and would later trigger a new change event again.
This was considered acceptable before, since property notifications are
asynchronous anyway (so they may always be "outdated", it just mattered
whether the most recent value was eventually delivered).
But consider ordering with events. It seems desirable that specific
important events (e.g. MPV_EVENT_START_FILE) should not be followed by
property updates that happened before it, because that would make
application logic really a mess, and property notification near-useless
in certain cases.
Avoid this by never returning a value if it was marked changed, but not
updated yet.
Unfortunately, this could lead to clients never receiving a value (or
receiving it with a high random delay), if they're too slow to read it
(or the property simply updates too often). Note that this is done for
_all_ property notifications, not just returned events. Hopefully not a
problem in practice. If it turns out to be one, this mechanism could be
restricted to actually returned events, for which this really matters.
The relatively recently added property update code has a race condition
when clients exit. It still tried to access mpv_handle during and after
it was destroyed.
The reason is that it unlocks the lock for the mpv_handle list (while
mpv_handle is locked), but nothing in mp_destroy_client() cares about
this case. The latter function locks mpv_handle only before/while it
makes sure all of its activity is coming to an end, such as asynchronous
requests, and property updates that are in progress. It did not include
the case when mp_client_send_property_changes() was still calling
send_client_property_changes() with mpv_handle locked.
Fix this by checking the mpv_handle.destroying field. This field can be
set only when mpv_handle is locked. While we're checking the lock, the
mpv_handle list is still locked, so at worst we might be at the point
before mp_destroy_client() locks the list again and finally destroys the
mpv_handle.
This is a hard to reproduce race condition which I spotted only once in
valgrind by chance, so the fix is unconfirmed.
The intention is to provide a slightly nicer way to distribute scripts.
For example, you could put multiple source files into the directory, and
then import them from the actual script file (this is still
unimplemented).
At first I wanted to require a config file (because you need to know at
least which scripting backend it should use). This wouldn't have been
too hard (could have reused/abused the mpv config file parsing
mechanism, and I already had working code that was just 2 function
calls). But probably better to do this without new config files, because
it might become a pain in the distant future.
So this just probes for "main.lua", "main.js", etc., until an existing
file is found.
Another important change is that this skips all directory entries whose
name starts with ".". This automatically excludes the "." and ".."
special directories, and is probably useful to exclude random crap that
might be lying around in the directory (such as editor temporary files,
or OSX, in its usual hrmful, annoying, and idiotic modus operandi,
sharting all over any directories opened by "Finder").
Although the changelog mentions the docs, they're added only in a later
commit.
This code assumed that the function is only called from the playloop
itself (and since property notification is done at the end of it, i.e.
before sleeping, it obviously would not have needed to wake up the
core).
But this function is actually called from some comments (such as
playlist-move), so this assumption was incorrect. Use the same method as
the other function.
Untested.
Fixes: #7339 (probably)
check_obj_resize() in sub/osd.c calls mp_client_broadcast_event(), which
calls notify_property_events(). This is pretty unexpected, because
check_obj_resize() may be called from the VO thread. While that's sort
of awful, it seems to be OK locking-wise. But it breaks an assumption in
notify_property_events() that the core doesn't need to be woken up,
which could possibly lead to a missed/delayed property update (although
rather unlikely).
Fix this by explicitly waking up the core when it's called from the OSD
code.
Lua scripting has an undocumented mp.set_osd_ass() function, which is
used by osc.lua and console.lua. Apparently, 3rd party scripts also use
this. It's probably time to make this a public API.
The Lua implementation just bypassed the libmpv API. To make it usable
by any type of client, turn it into a command, "osd-overlay".
There's already a "overlay-add". Ignore it (although the manpage admits
guiltiness). I don't really want to deal with that old command. Its main
problem is that it uses global IDs, while I'd like to avoid that scripts
mess with each others overlays (whether that is accidentally or
intentionally). Maybe "overlay-add" can eventually be merged into
"osd-overlay", but I'm too lazy to do that now.
Scripting now uses the commands. There is a helper to manage OSD
overlays. The helper is very "thin"; I only want to force script authors
to use the ID allocation, which may help with putting multiple scripts
into a single .lua file without causing conflicts (basically, avoiding
singletons within a script's environment). The old set_osd_ass() is
emulated with the new API.
The JS scripting wrapper also provides a set_osd_ass() function, which
calls internal mpv API. Comment that part (to keep it compiling), but
I'm leaving it to @avih to finish the change.
I intend to rewrite this code approximately every 2 months.
Last time, I did this in commit d66eb93e5d (and 065c307e8e and
b2006eeb74). It was intended to remove the roundabout synchronous
thread "ping pong" when observing properties. At first, the original
async. code was replaced with some nice mostly synchronous code. But
then an async. code path had to be added for vo_libmpv, and finally the
sync. code was dropped because it broke in other obscure cases (like the
Objective-C Cocoa backend).
Try again. This time, update properties entirely on the main thread.
Updates get batched out on every playloop iteration. (At first I wanted
it to make it every time the player goes to sleep, but that might starve
API clients if the playloop get saturated.) One nice thing is that
clients only get woken up once all changed events have been sent, which
might reduce overhead.
While this sounds simple, it's not. The main problem is that reading
properties must not block the client API, i.e. no client API locks can
be held while reading the property. Maybe eventually we can avoid this
requirement, but currently it's just a fact. This means we have to
iterate over all clients and then over all properties (of each client),
all while releasing all locks when updating a property. Solve this by
rechecking on each iteration whether the list changed, and if so,
aborting the iteration and redo it "next time".
High risk change, expect bugs such as crashes and missing property
updates.