summaryrefslogtreecommitdiffstats
path: root/video/out/vo_libmpv.c
Commit message (Collapse)AuthorAgeFilesLines
* client API: fix potential deadlock problems by throwing more shit at itwm42019-09-261-15/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The render API (vo_libmpv) had potential deadlock problems with MPV_RENDER_PARAM_ADVANCED_CONTROL. This required vd-lavc-dr to be enabled (the default). I never observed these deadlocks in the wild (doesn't mean they didn't happen), although I could specifically provoke them with some code changes. The problem was mostly about DR (direct rendering, letting the video decoder write to OpenGL buffer memory). Allocating/freeing a DR image needs to be done on the OpenGL thread, even though _lots_ of threads are involved with handling images. Freeing a DR image is a special case that can happen any time. dr_helper.c does most of the evil magic of achieving this. Unfortunately, there was a (sort of) circular lock dependency: freeing an image while certain internal locks are held would trigger the user's context update callback, which in turn would call mpv_render_context_update(), which processed all pending free requests, and then acquire an internal lock - which the caller might not release until a further DR image could be freed. "Solve" this by making freeing DR images asynchronous. This is slightly risky, but actually not much. The DR images will be free'd eventually. The biggest disadvantage is probably that debugging might get trickier. Any solution to this problem will probably add images to free to some sort of queue, and then process it later. I considered making this more explicit (so there'd be a point where the caller forcibly waits for all queued items to be free'd), but discarded these ideas as this probably would only increase complexity. Another consequence is that freeing DR images on the GL thread is not synchronous anymore. Instead, it mpv_render_context_update() will do it with a delay. This seems roundabout, but doesn't actually change anything, and avoids additional code. This also fixes that the render API required the render API user to remain on the same thread, even though this wasn't documented. As such, it was a bug. OpenGL essentially forces you to do all GL usage on a single thread, but in theory the API user could for example move the GL context to another thread. The API bump is because I think you can't make enough noise about this. Since we don't backport fixes to old versions, I'm specifically stating that old versions are broken, and I'm supplying workarounds. Internally, dr_helper_create() does not use pthread_self() anymore, thus the vo.c change. I think it's better to make binding to the current thread as explicit as possible. Of course it's not sure that this fixes all deadlocks (probably not).
* client API, vo_libmpv: document random deadlock problemswm42019-09-201-0/+16
| | | | | | | I guess trying to make DR work on libmpv was a mistake. I never observed such a deadlock, but it's looks like it's theoretically possible.
* vo_libmpv: fix some more uninit issueswm42019-09-201-24/+35
| | | | | | | | | | | | | | | | | | | | | | This is mostly for the case when mpv_render_context_free() is called while video is going on. This is supposed to gracefully stop video and deinitialize everything properly. (I feel like it would put too much on the API user to require that video is stopped before calling this function. Whether video is running or not is a fairly highlevel thing, and the API user could not do it in a race-free way.) One problem was that unit() accessed ctx after ctx->in_use was set to false. The update(ctx) call was basically a racy use-after-free. It needed that call to wake up the mpv_render_context_free() loop that waited for VO uninit. Fix this by triggering the wakeup inside the lock, and then doing "barrier" locking in mpv_render_context_free(). Another problem was that the wait loop didn't really wait properly. IT seems the had_kill_update field was a botched attempt to do that. It's indeed quite hairy to do that with update(). Instead make use of the dispatch queue (infinite timeout, using mp_dispatch_interrupt()), which handles the problem of having to wait both for dispatch queue updates and VO uninit at the same time.
* vo_libmpv: always create ctx->dispatchwm42019-09-201-19/+12
| | | | | | | | Preparation for the next commit. Until now, it was only needed if DR was involved. One reason for not always creating it was that you normally must not use it if advanced_control is not enabled. This is why e.g. VOCTRL_SCREENSHOT now checks for that variable; it still can't use ctx->dispatch if the render API user did not enable it.
* render api: fix use-after-freewnoun2019-09-201-12/+2
| | | | | | | | 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.
* vo_libmpv: fix null pointer dereferencewnoun2019-03-111-3/+5
| | | | Closes: #6507
* vo_libmpv: support render performance dataAkemi2018-11-131-0/+14
|
* vo_libmpv: pass vo struct to the control callbackAkemi2018-06-121-1/+2
|
* client API: add some render API extensions for timingwm42018-04-291-24/+68
| | | | | | | | | | | | Attempts to enable the following things: - let a render API user do "proper" audio-sync video timing itself - make it possible to not re-render repeated frames if the API user has better mechanisms available (e.g. waiting for a DisplayLink cycle instead) - allow the user to delay or skip redraws if it makes sense Basically this information will be needed by API users who want to be "clever" about optimizing timing and rendering.
* vo_libmpv: support GPU rendered screenshotswm42018-04-291-0/+34
| | | | | Like DR, this needed a lot of preparation, and here's the boring glue code that finally implements it.
* vo_libmpv: adjust redraw handling to new API semanticswm42018-04-291-12/+4
| | | | | | | | | | | | | | | | | In MPV_RENDER_PARAM_ADVANCED_CONTROL mode, a simple update callback does not necessarily make the API user redraw. So handle it differently. For one, setting vo->want_redraw already uses the "normal" redraw path, which will call draw_frame() and set next_frame. Then there are redraws trigered by mpv_render_context_set_parameter(), which are on the render thread, and would require a separate mechanism. I decided this is not really a good idea, since it's not even clear that setting an arbitrary parameter should redraw. Also this could trigger an unbounded number of redraws. The user can trigger redraws manually if really needed, depending on the parameter that's being set. If we really wanted vo_libmpv to do this, we could add a new flag like need_redraw, which would be 4 lines of code or so.
* vo_libmpv: remove annoying indirectionswm42018-04-291-71/+80
| | | | I think this is a bit more readable this way.
* vo_libmpv: move some update() callbacks out of context lockwm42018-04-291-3/+3
| | | | | | | | update() used to require the lock, but now it doesn't matter. It's slightly better to do it outside of the lock now, in case the update callback reschedules before returning, and the user render thread tries to acquire the still held lock (which would require 2 more context switches).
* vo_libmpv: move up update() functionwm42018-04-291-14/+12
| | | | Avoids a forward declaration.
* vo_libmpv: add support for DRwm42018-04-291-0/+26
| | | | | With all the preparation work done, this only has to do the annoying dance of passing it through all the damn layers.
* client API: preparations for allowing render API to use DR etc.wm42018-04-291-22/+110
| | | | | | | | | | | | | | | | | | | | | | | | | | | | 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: deprecate opengl-cb API and introduce a replacement APIwm42018-02-281-0/+538
The purpose of the new API is to make it useable with other APIs than OpenGL, especially D3D11 and vulkan. In theory it's now possible to support other vo_gpu backends, as well as backends that don't use the vo_gpu code at all. This also aims to get rid of the dumb mpv_get_sub_api() function. The life cycle of the new mpv_render_context is a bit different from mpv_opengl_cb_context, and you explicitly create/destroy the new context, instead of calling init/uninit on an object returned by mpv_get_sub_api(). In other to make the render API generic, it's annoyingly EGL style, and requires you to pass in API-specific objects to generic functions. This is to avoid explicit objects like the internal ra API has, because that sounds more complicated and annoying for an API that's supposed to never change. The opengl_cb API will continue to exist for a bit longer, but internally there are already a few tradeoffs, like reduced thread-safety. Mostly untested. Seems to work fine with mpc-qt.