summaryrefslogtreecommitdiffstats
path: root/player/client.c
Commit message (Collapse)AuthorAgeFilesLines
* scripting: load scripts from directorieswm42020-02-011-10/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* client API: fix property notification from non-playloop sourceswm42020-01-091-2/+4
| | | | | | | | | | | | | | | 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)
* client API: change event mask to event number in one placewm42020-01-091-4/+5
| | | | Cosmetic change. Slightly more convenient/readable.
* osd: fix possible misses of osd-dimensions property updateswm42020-01-081-0/+11
| | | | | | | | | | | | | 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.
* client API, lua: add new API for setting OSD overlayswm42019-12-231-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* client API: deprecate tick eventwm42019-12-221-0/+2
| | | | | This is conceptually outdated and should not exist. This affects Lua scripting and JSON IPC too.
* client API: rewrite property observation (again)wm42019-12-191-137/+192
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | I intend to rewrite this code approximately every 2 months. Last time, I did this in commit d66eb93e5d4 (and 065c307e8e7 and b2006eeb74f). 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.
* client API: remove some dead codewm42019-12-171-6/+0
| | | | | This was for the "suspend" API, which has been removed (turned into stubs) a long time ago.
* player: remove mechanisms for better logging with repl.luawm42019-11-181-7/+22
| | | | | | | | | | | | | | | | | | | | | | As preparation for making repl.lua part of the core (maybe), add some mechanisms which are supposed to improve its behavior. Add a silent mode. Calling mpv_request_log_messages() with the log level name prefixed with "silent:" will disable logging from the API user's perspective. But it will keep the log buffer, and record new messages, without returning them to the user. If logging is enabled again by requesting the same log level without "silent:" prefix, the buffered log messages are returned to the user at once. This is not documented, because it's far too messy and special as that I'd want anyone to rely on this behavior, but it will be perfectly fine for an internal script. Another thing is that we record early startup messages. The goal is to make the repl.lua script show option and config parsing file errors. This works only with the special "terminal-default" log level. In addition, reduce the "terminal-default" capacity to only 100 log messages. If this is going to be enabled by default, it shouldn't use too much resources.
* client API: remove sync. property notification code againwm42019-11-161-41/+14
| | | | | | | | | | | | It's too easy to introduce unintended circular lock dependencies. Just now we found that the (old) cocoa vo_gpu backend is also affected by this, because it waits on the Cocoa main thread, which in turn uses libmpv API for OSX... stuff. Also fix a missing initial property update after observe. This leaves me unhappy, because it just leads to a stupid thread ping pong. Will probably rewrite this later.
* options: remove M_SETOPT_RUNTIMEwm42019-11-101-5/+2
| | | | | | | Used to contain flags for "save" setting of options at runtime. Now there is nothing special needed anymore and it's 0. So drop it completely, and remove anything that distinguishes between runtime and initialization time.
* client API: reduce log level of client exitingwm42019-11-011-1/+1
| | | | See previous commit message.
* client API: copy instead of move old value on async pathwm42019-10-251-4/+1
| | | | | | | | In theory, it's better to keep the old value, because that's more consistent with the logic of using change timestamps. With the current code, the old value will probably never be used (instead it will fetch a new value on every change), so this shouldn't make a difference in practice.
* client API: add async path; fix deadlock for vo_libmpv userswm42019-10-251-9/+95
| | | | | | | | | | | | | | | | | | | | | | In commit 065c307e8e7db, I broke everything. It seemed like a nice idea, but it explicitly broke an assumption vo_libmpv were explicitly allowed to make: that observing properties does not lock the core. The commit did just that and locked the core for property updates. This made for example mpv's own OSX backend freeze (it uses vo_libmpv for convenience to make up for Apple's incredibly broken OpenGL shit). I don't want to revert that commit just because vo_libmpv's design is horrible. So instead add an optional asynchronous path, that is only used if vo_libmpv is in use (best idea ever?). Interestingly, this isn't so hard. It adds about 90 lines of code, which are only run on OSX and libmpv users, so I don't have to care about the crashes and weird behavior this might cause. It even worked on the first try except for a quickly fixed memory leak. The code path can be tested anywhere by just turning the uses_vo_libmpv condition into always true. The atomic is out of laziness. Saves some thinking how to get around the locking order.
* client API: avoid lost wakeupswm42019-10-241-3/+7
| | | | | | | | | | | | The commit linked below added temporary unlocking to update_prop(), which is indirectly called by mpv_wait_event(). If an unlock happens, and no property change event is returned, we must re-poll the event queue. Rechecking the state on unlocks is basically a standard requirement for code using condition variables. Untested beyond a simple test. Fixes: 065c307e8e7dbf
* client API: simplify (?) property change notification generationwm42019-10-241-75/+79
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Property change notification works by having the mpv core wake up all clients observing a property when the property potentially changes. The clients then read the property's value, and determine if there was an actual change. (The latter part depends what the property returned for the previous change notification, so it depends on the client, and cannot be generated by the core itself.) Until now, reading the property value was done in a pseudo-async way by queuing a callback back to the core, running it there, and then waking up the client thread again. I cannot comprehend why this was done in such a complicated, fragile way. Maybe it's a leftover from times when client.c had to do this (in short, because properties could access vo_opengl, which has thread-local state). One past idea was to make the implementation of true async properties easier (for which you would need such a state machine anyway). But they don't exist yet, and I doubt the current mess would be really helpful when actually implementing them. Simplify this, and run the update in the client's thread directly. In addition to the fundamental change, many roundabout things can be removed as a consequence. Unfortunately, I noticed that lock order issues force you to release ctx->lock before doing so, which makes things more complex due to possible concurrent mpv_unobserve_property() calls. Solve this by removing properties lazily, which means you may have to do multiple mpv_wait_event() calls before the property entry is actually destroyed. This should not matter in practice, and does not affect the semantics. It could also cause "leaks" by observing/unobserving properties in a loop, without ever calling mpv_wait_event(). Just don't do this, duh. (I considered making this dependent on whether the previous mpv_wait_event() call returned the property being removed, but a separate code path seemed too complicated. I also considered copying the name and property data when returning a MPV_EVENT_PROPERTY_CHANGE, but actually this doesn't solve the problem of update_prop() being interrupted by mpv_unobserve_property(); there are ways around it, but I just said no.) This was made using the cowboy coding software engineering methodology. If you find any bugs, keep them yourself.
* client API: move a functionwm42019-10-241-7/+7
| | | | May reduce the diff of the next commit.
* client API: remove unused global event maskwm42019-10-241-35/+0
| | | | | | Apparently this was only added and used for cache update stuff, which was changed in commit 8dbc93a94cdc3c. Now it's unused, messy, ugly, and is in the way, so get rid of it.
* client API: add mpv_command_retDark2019-09-211-0/+9
| | | | | | | | | | This change adds a version of `mpv_command` that also returns a result. The main rationale behind this is `mpv_command_node` requires defining multiple structs before you can even use it, which results in a pretty painful to use interface just to get the result from a command. There isn't really a good name for this function, so I'm open to suggestions on a better name for it.
* client API: fix missing property change events after property updatesGunnar Marten2019-09-201-24/+28
| | | | | | | | | | | | | | | | | | | | | | | | | When update_prop() successfully fetched a changed property value, it set prop->changed to true to indicate the success. mark_property_changed() also always set prop->changed to true and additionally prop->need_new_value to true This is the case since 6ac0ef78 If the observed property changes every frame and then due to timing the next mark_property_changed() is called before gen_property_change_event() and therefore directly after update_prop(), prop->need_new_value was again true and indicated that a new value has to be retrieved with update_prop(). As a result the event for the last successful update_prop() was never triggered. This meant that a property change event were never generated for frame-based properties only for properties that were observed with MPV_FORMAT_NONE or when the timing was different and gen_property_change_event() was called after update_prop(). To fix this, mark_property_change() and update_prop() should not use the same flag to indicate different things and therefore a new flag for successfully update a property is introduced. But with the now decoupled property changed and updated the need_new_value flag is redundant and removed completely. Fixes #4195
* render api: fix use-after-freewnoun2019-09-201-19/+3
| | | | | | | | render api needs to wait for vo to be destroyed before frees the context. The purpose of kill_cb is to wake up render api after vo is destroyed, but uninit did that before kill_cb, so kill_cb tries using the freed memory. Remove kill_cb to fix the issue as uninit is able to do the work.
* client: fix potential mpv_cmd/async leakdudemanguy2019-07-081-4/+8
|
* player: make playback termination asynchronouswm42018-05-241-3/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Until now, stopping playback aborted the demuxer and I/O layer violently by signaling mp_cancel (bound to libavformat's AVIOInterruptCB mechanism). Change it to try closing them gracefully. The main purpose is to silence those libavformat errors that happen when you request termination. Most of libavformat barely cares about the termination mechanism (AVIOInterruptCB), and essentially it's like the network connection is abruptly severed, or file I/O suddenly returns I/O errors. There were issues with dumb TLS warnings, parsers complaining about incomplete data, and some special protocols that require server communication to gracefully disconnect. We still want to abort it forcefully if it refuses to terminate on its own, so a timeout is required. Users can set the timeout to 0, which should give them the old behavior. This also removes the old mechanism that treats certain commands (like "quit") specially, and tries to terminate the demuxers even if the core is currently frozen. This is for situations where the core synchronized to the demuxer or stream layer while network is unresponsive. This in turn can only happen due to the "program" or "cache-size" properties in the current code (see one of the previous commits). Also, the old mechanism doesn't fit particularly well with the new one. We wouldn't want to abort playback immediately on a "quit" command - the new code is all about giving it a chance to end it gracefully. We'd need some sort of watchdog thread or something equally complicated to handle this. So just remove it. The change in osd.c is to prevent that it clears the status line while waiting for termination. The normal status line code doesn't output anything useful at this point, and the code path taken clears it, both of which is an annoying behavior change, so just let it show the old one.
* misc: move some helper code from client.cwm42018-05-241-49/+2
| | | | | (Slightly oddly function names, because I want to avoid starting them with mpv_*, which is reserved for public API.)
* client API: kill async commands on terminationwm42018-05-241-13/+41
| | | | | | | | | | | This affects async commands started by client API, commands with async capability run in a sync way by client API (think mpv_command_node() with "subprocess"), and detached async work. Since scripts might want to do some cleanup work (that might involve launching processes, don't ask), we don't unconditionally kill everything on exit, but apply an arbitrary timeout of 2 seconds until async commands are aborted.
* command: add a way to abort asynchronous commandswm42018-05-241-3/+33
| | | | | | | | | | | | Many asynchronous commands are potentially long running operations, such as loading something from network or running a foreign process. Obviously it shouldn't just be possible for them to freeze the player if they don't terminate as expected. Also, there will be situations where you want to explicitly stop some of those operations explicitly. So add an infrastructure for this. Commands have to support this explicitly. The next commit uses this to actually add support to a command.
* client API: merge status_reply() helper with only remaining callerwm42018-05-241-12/+5
| | | | | All other callers had to be changed, so there's no point in keeping this helper function around. It's just another unnecessary indirection.
* client API: add returning of data from async commandswm42018-05-241-5/+10
| | | | This was not done sooner out of laziness.
* command: add infrastructure for async commandswm42018-05-241-20/+81
| | | | | | | | | | | | | | | | | | | | | | | | | | | This enables two types of command behavior: 1. Plain async behavior, like "loadfile" not completing until the file is fully loaded. 2. Running parts of the command on worker threads, e.g. for I/O, such as "sub-add" doing network accesses on a thread while the core continues. Both have no implementation yet, and most new code is actually inactive. The plan is to implement a number of useful cases in the following commits. The most tricky part is handling internal keybindings (input.conf) and the multi-command feature (concatenating commands with ";"). It requires a bunch of roundabout code to make it do the expected thing in combination with async commands. There is the question how commands should be handled that come in at a higher rate than what can be handled by the core. Currently, it will simply queue up input.conf commands as long as memory lasts. The client API is limited by the size of the reply queue per client. For commands which require a worker thread, the thread pool is limited to 30 threads, and then will queue up work in memory. The number is completely arbitrary.
* client: merge can_terminate() functionwm42018-05-241-15/+12
| | | | | | | | | | | This has some tricky interactions. In particular, it requires the core to be locked due to reading outstanding_async, which is documented on the only caller only. It's probably better to merge it with its only caller. The new code should be strictly equivalent, other than the fact that it doesn't temporarily unlock+lock when entering the loop for the first time (which doesn't matter here).
* input: merge cmd_list.c with cmd.cwm42018-05-031-1/+1
| | | | | | It doesn't really make sense to keep a separate cmd_list.c file, which does _not_ contain a command list, but only a few minor helper functions.
* client API: preparations for allowing render API to use DR etc.wm42018-04-291-5/+26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | DR (letting the decoder allocate texture memory) requires running the allocation on the render thread. This is rather hard with the render API, because the user controls this thread and when it's entered. It was not possible until now. This commit adds a bunch of infrastructure to make this possible. We add a new optional mode (MPV_RENDER_PARAM_ADVANCED_CONTROL) which basically lets the user's render thread and libmpv agree how this should be done. Misuse would lead to deadlocks. To make this less likely, strictly document thread safety/locking issues. In particular, document which libmpv functions can be called without issues. (The rest has to be assumed unsafe.) The worst issue is destruction of the render context while video is still active. To avoid certain unintended recursive locks (i.e. deadlocks, unless we'd make the locks recursive), make the update callback lock separate. Make "killing" the video chain asynchronous, so we can do extra work while video is being destroyed. Because losing wakeups is a big deal, setting the update callback now triggers a wakeup. (It would have been better if the wakeup callback were a parameter to mpv_render_context_create(), but too late.) This commit does not add DR yet; the following commit does this.
* client API: make sure to send IDLE event after mpv_initialize()wm42018-04-161-0/+1
| | | | | | | | | | | This was slightly broken: since mp_initialize() did not necessarily interrupt core_thread() (which is waiting for initialization), it did not enter mp_play_files(), which would have sent an IDLE event. I suppose that in some cases (like with mpv-android), the initial IDLE event was never actually sent, because the first wakeup of the core thread happens with the "loadfile" command, which will disallow the core thread an IDLE event.
* client API: fix potential sporadic freezes on terminationwm42018-04-161-4/+4
| | | | | | | | | | | | | | | Although this was never observed to be happening, it seems definitely possible: we first tell the main thread to exit, and then we ask the main thread to do some work for us (with mp_dispatch_run()). Obviously this is racy, and the main thread could exit without doing this, which would block mp_dispatch_run() forever. Fix this by changing the order of operation, so that it makes sense. We could also just store the pthread_t of the main thread in some variable, but the fact that pthread_create() might set the pthread_t argument _after_ starting the thread makes this a bit messy (at least it doesn't seem to be guaranteed on a superficial look at the manpage).
* client API: add a first class hook API, and deprecate old APIwm42018-03-261-2/+21
| | | | | | | | | | | | | | | As it turns out, there are multiple libmpv users who saw a need to use the hook API. The API is kind of shitty and was never meant to be actually public (it was mostly a hack for the ytdl script). Introduce a proper API and deprecate the old one. The old one will probably continue to work for a few releases, but will be removed eventually. There are some slight changes to the old API, but if a user followed the manual properly, it won't break. Mostly untested. Appears to work with ytdl_hook.
* client API: add a new way to pass X11 Display etc. to render APIwm42018-03-261-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Hardware decoding things often need access to additional handles from the windowing system, such as the X11 or Wayland display when using vaapi. The opengl-cb had nothing dedicated for this, and used the weird GL_MP_MPGetNativeDisplay GL extension (which was mpv specific and not officially registered with OpenGL). This was awkward, and a pain due to having to emulate GL context behavior (like needing a TLS variable to store context for the pseudo GL extension function). In addition (and not inherently due to this), we could pass only one resource from mpv builtin context backends to hwdecs. It was also all GL specific. Replace this with a newer mechanism. It works for all RA backends, not just GL. the API user can explicitly pass the objects at init time via mpv_render_context_create(). Multiple resources are naturally possible. The API uses MPV_RENDER_PARAM_* defines, but internally we use strings. This is done for 2 reasons: 1. trying to leave libmpv and internal mechanisms decoupled, 2. not having to add public API for some of the internal resource types (especially D3D/GL interop stuff). To remain sane, drop support for obscure half-working opengl-cb things, like the DRM interop (was missing necessary things), the RPI window thing (nobody used it), and obscure D3D interop things (not needed with ANGLE, others were undocumented). In order not to break ABI and the C API, we don't remove the associated structs from opengl_cb.h. The parts which are still needed (in particular DRM interop) needs to be ported to the render API.
* client API: send MPV_EVENT_SHUTDOWN only oncewm42018-03-151-0/+2
| | | | | | | | | | | | Before this change, mpv_wait_event() could inconsistently return multiple MPV_EVENT_SHUTDOWN events to a single mpv_handle, up to the point of spamming the event queue under certain circumstances. Change this and just send it exactly once to each mpv_handle. Some client API users might have weird requirements about destroying their state asynchronously (and not reacting immediately to the SHUTDOWN event). This change will help a bit to make this less weird and surprising.
* client API: rename mpv_detach_destroy() to mpv_destroy()wm42018-03-151-1/+6
| | | | | Since this has clearer semantics now, the old name is just clunky and confusing.
* client API: add mpv_create_weak_client()wm42018-03-151-2/+21
|
* client API: cleanup mpv_handle terminationwm42018-03-151-90/+116
| | | |