diff options
Diffstat (limited to 'video/out')
-rw-r--r-- | video/out/opengl/hwdec.c | 29 | ||||
-rw-r--r-- | video/out/opengl/hwdec.h | 12 | ||||
-rw-r--r-- | video/out/opengl/hwdec_d3d11egl.c | 18 | ||||
-rw-r--r-- | video/out/opengl/hwdec_dxva2.c | 27 | ||||
-rw-r--r-- | video/out/opengl/hwdec_dxva2egl.c | 20 | ||||
-rw-r--r-- | video/out/opengl/hwdec_dxva2gldx.c | 20 | ||||
-rw-r--r-- | video/out/opengl/hwdec_osx.c | 26 | ||||
-rw-r--r-- | video/out/opengl/hwdec_vaegl.c | 7 | ||||
-rw-r--r-- | video/out/opengl/hwdec_vaglx.c | 7 | ||||
-rw-r--r-- | video/out/opengl/hwdec_vdpau.c | 7 | ||||
-rw-r--r-- | video/out/vo.c | 1 | ||||
-rw-r--r-- | video/out/vo.h | 6 | ||||
-rw-r--r-- | video/out/vo_opengl.c | 36 | ||||
-rw-r--r-- | video/out/vo_opengl_cb.c | 21 | ||||
-rw-r--r-- | video/out/vo_vaapi.c | 17 | ||||
-rw-r--r-- | video/out/vo_vdpau.c | 12 |
16 files changed, 135 insertions, 131 deletions
diff --git a/video/out/opengl/hwdec.c b/video/out/opengl/hwdec.c index 9c3bec1a0f..b4b5c23580 100644 --- a/video/out/opengl/hwdec.c +++ b/video/out/opengl/hwdec.c @@ -61,6 +61,7 @@ static const struct gl_hwdec_driver *const mpgl_hwdec_drivers[] = { static struct gl_hwdec *load_hwdec_driver(struct mp_log *log, GL *gl, struct mpv_global *global, + struct mp_hwdec_devices *devs, const struct gl_hwdec_driver *drv, bool is_auto) { @@ -70,6 +71,7 @@ static struct gl_hwdec *load_hwdec_driver(struct mp_log *log, GL *gl, .log = mp_log_new(hwdec, log, drv->name), .global = global, .gl = gl, + .devs = devs, .gl_texture_target = GL_TEXTURE_2D, .probing = is_auto, }; @@ -79,19 +81,19 @@ static struct gl_hwdec *load_hwdec_driver(struct mp_log *log, GL *gl, mp_verbose(log, "Loading failed.\n"); return NULL; } - if (hwdec->hwctx && !hwdec->hwctx->driver_name) - hwdec->hwctx->driver_name = hwdec->driver->name; return hwdec; } -struct gl_hwdec *gl_hwdec_load_api_id(struct mp_log *log, GL *gl, - struct mpv_global *g, int id) +struct gl_hwdec *gl_hwdec_load_api(struct mp_log *log, GL *gl, + struct mpv_global *g, + struct mp_hwdec_devices *devs, + enum hwdec_type api) { - bool is_auto = id == HWDEC_AUTO; + bool is_auto = api == HWDEC_AUTO; for (int n = 0; mpgl_hwdec_drivers[n]; n++) { const struct gl_hwdec_driver *drv = mpgl_hwdec_drivers[n]; - if (is_auto || id == drv->api) { - struct gl_hwdec *r = load_hwdec_driver(log, gl, g, drv, is_auto); + if (is_auto || api == drv->api) { + struct gl_hwdec *r = load_hwdec_driver(log, gl, g, devs, drv, is_auto); if (r) return r; } @@ -99,19 +101,6 @@ struct gl_hwdec *gl_hwdec_load_api_id(struct mp_log *log, GL *gl, return NULL; } -// Like gl_hwdec_load_api_id(), but use option names. -struct gl_hwdec *gl_hwdec_load_api(struct mp_log *log, GL *gl, - struct mpv_global *g, const char *api_name) -{ - int id = HWDEC_NONE; - for (const struct m_opt_choice_alternatives *c = mp_hwdec_names; c->name; c++) - { - if (strcmp(c->name, api_name) == 0) - id = c->value; - } - return gl_hwdec_load_api_id(log, gl, g, id); -} - void gl_hwdec_uninit(struct gl_hwdec *hwdec) { if (hwdec) diff --git a/video/out/opengl/hwdec.h b/video/out/opengl/hwdec.h index a9d524a1d7..fcc6d3c11e 100644 --- a/video/out/opengl/hwdec.h +++ b/video/out/opengl/hwdec.h @@ -4,14 +4,12 @@ #include "common.h" #include "video/hwdec.h" -struct mp_hwdec_info; - struct gl_hwdec { const struct gl_hwdec_driver *driver; struct mp_log *log; struct mpv_global *global; GL *gl; - struct mp_hwdec_ctx *hwctx; + struct mp_hwdec_devices *devs; // For free use by hwdec driver void *priv; // For working around the vdpau vs. vaapi mess. @@ -33,7 +31,7 @@ struct gl_hwdec_driver { enum hwdec_type api; // The hardware surface IMGFMT_ that must be passed to map_image later. int imgfmt; - // Create the hwdec device. It must fill in hw->info, if applicable. + // Create the hwdec device. It must add it to hw->devs, if applicable. // This also must set hw->converted_imgfmt. int (*create)(struct gl_hwdec *hw); // Prepare for rendering video. (E.g. create textures.) @@ -49,9 +47,9 @@ struct gl_hwdec_driver { }; struct gl_hwdec *gl_hwdec_load_api(struct mp_log *log, GL *gl, - struct mpv_global *g, const char *api_name); -struct gl_hwdec *gl_hwdec_load_api_id(struct mp_log *log, GL *gl, - struct mpv_global *g, int id); + struct mpv_global *g, + struct mp_hwdec_devices *devs, + enum hwdec_type api); void gl_hwdec_uninit(struct gl_hwdec *hwdec); diff --git a/video/out/opengl/hwdec_d3d11egl.c b/video/out/opengl/hwdec_d3d11egl.c index de872d1396..caf27e1dc4 100644 --- a/video/out/opengl/hwdec_d3d11egl.c +++ b/video/out/opengl/hwdec_d3d11egl.c @@ -27,11 +27,10 @@ #include "osdep/timer.h" #include "osdep/windows_utils.h" #include "hwdec.h" -#include "video/d3d.h" #include "video/hwdec.h" struct priv { - struct mp_d3d_ctx ctx; + struct mp_hwdec_ctx hwctx; ID3D11Device *d3d11_device; ID3D11VideoDevice *video_dev; @@ -94,6 +93,8 @@ static void destroy(struct gl_hwdec *hw) destroy_objects(hw); + hwdec_devices_remove(hw->devs, &p->hwctx); + if (p->video_ctx) ID3D11VideoContext_Release(p->video_ctx); p->video_ctx = NULL; @@ -109,9 +110,6 @@ static void destroy(struct gl_hwdec *hw) static int create(struct gl_hwdec *hw) { - if (hw->hwctx) - return -1; - EGLDisplay egl_display = eglGetCurrentDisplay(); if (!egl_display) return -1; @@ -199,11 +197,13 @@ static int create(struct gl_hwdec *hw) hw->converted_imgfmt = IMGFMT_RGB0; - p->ctx.d3d11_device = p->d3d11_device; - p->ctx.hwctx.type = HWDEC_D3D11VA; - p->ctx.hwctx.d3d_ctx = &p->ctx; + p->hwctx = (struct mp_hwdec_ctx){ + .type = HWDEC_D3D11VA, + .driver_name = hw->driver->name, + .ctx = p->d3d11_device, + }; + hwdec_devices_add(hw->devs, &p->hwctx); - hw->hwctx = &p->ctx.hwctx; return 0; fail: destroy(hw); diff --git a/video/out/opengl/hwdec_dxva2.c b/video/out/opengl/hwdec_dxva2.c index f72c817a20..35d091f14f 100644 --- a/video/out/opengl/hwdec_dxva2.c +++ b/video/out/opengl/hwdec_dxva2.c @@ -1,8 +1,9 @@ +#include <d3d9.h> + #include "common/common.h" #include "hwdec.h" #include "utils.h" -#include "video/d3d.h" #include "video/hwdec.h" // This does not provide real (zero-copy) interop - it merely exists for @@ -10,35 +11,39 @@ // may help with OpenGL fullscreen mode. struct priv { - struct mp_d3d_ctx ctx; + struct mp_hwdec_ctx hwctx; }; static void destroy(struct gl_hwdec *hw) { struct priv *p = hw->priv; - if (p->ctx.d3d9_device) - IDirect3DDevice9_Release(p->ctx.d3d9_device); + hwdec_devices_remove(hw->devs, &p->hwctx); + if (p->hwctx.ctx) + IDirect3DDevice9_Release((IDirect3DDevice9 *)p->hwctx.ctx); } static int create(struct gl_hwdec *hw) { GL *gl = hw->gl; - if (hw->hwctx || !gl->MPGetNativeDisplay) + if (!gl->MPGetNativeDisplay) return -1; struct priv *p = talloc_zero(hw, struct priv); hw->priv = p; - p->ctx.d3d9_device = gl->MPGetNativeDisplay("IDirect3DDevice9"); - if (!p->ctx.d3d9_device) + IDirect3DDevice9 *d3d = gl->MPGetNativeDisplay("IDirect3DDevice9"); + if (!d3d) return -1; - p->ctx.hwctx.type = HWDEC_DXVA2_COPY; - p->ctx.hwctx.d3d_ctx = &p->ctx; + MP_VERBOSE(hw, "Using libmpv supplied device %p.\n", d3d); - MP_VERBOSE(hw, "Using libmpv supplied device %p.\n", p->ctx.d3d9_device); + p->hwctx = (struct mp_hwdec_ctx){ + .type = HWDEC_DXVA2_COPY, + .driver_name = hw->driver->name, + .ctx = d3d, + }; + hwdec_devices_add(hw->devs, &p->hwctx); - hw->hwctx = &p->ctx.hwctx; hw->converted_imgfmt = 0; return 0; } diff --git a/video/out/opengl/hwdec_dxva2egl.c b/video/out/opengl/hwdec_dxva2egl.c index ed1a6e66b7..1384e2bb47 100644 --- a/video/out/opengl/hwdec_dxva2egl.c +++ b/video/out/opengl/hwdec_dxva2egl.c @@ -17,6 +17,8 @@ #include <assert.h> #include <windows.h> +#include <d3d9.h> + #include <EGL/egl.h> #include <EGL/eglext.h> @@ -25,11 +27,10 @@ #include "osdep/windows_utils.h" #include "hwdec.h" #include "video/dxva2.h" -#include "video/d3d.h" #include "video/hwdec.h" struct priv { - struct mp_d3d_ctx ctx; + struct mp_hwdec_ctx hwctx; HMODULE d3d9_dll; IDirect3D9Ex *d3d9ex; @@ -77,6 +78,8 @@ static void destroy(struct gl_hwdec *hw) destroy_textures(hw); + hwdec_devices_remove(hw->devs, &p->hwctx); + if (p->query9) IDirect3DQuery9_Release(p->query9); @@ -92,9 +95,6 @@ static void destroy(struct gl_hwdec *hw) static int create(struct gl_hwdec *hw) { - if (hw->hwctx) - return -1; - EGLDisplay egl_display = eglGetCurrentDisplay(); if (!egl_display) return -1; @@ -207,11 +207,13 @@ static int create(struct gl_hwdec *hw) hw->converted_imgfmt = IMGFMT_RGB0; - p->ctx.d3d9_device = (IDirect3DDevice9 *)p->device9ex; - p->ctx.hwctx.type = HWDEC_DXVA2; - p->ctx.hwctx.d3d_ctx = &p->ctx; + p->hwctx = (struct mp_hwdec_ctx){ + .type = HWDEC_DXVA2, + .driver_name = hw->driver->name, + .ctx = (IDirect3DDevice9 *)p->device9ex, + }; + hwdec_devices_add(hw->devs, &p->hwctx); - hw->hwctx = &p->ctx.hwctx; return 0; fail: destroy(hw); diff --git a/video/out/opengl/hwdec_dxva2gldx.c b/video/out/opengl/hwdec_dxva2gldx.c index 69be0ccd18..97f1918a2c 100644 --- a/video/out/opengl/hwdec_dxva2gldx.c +++ b/video/out/opengl/hwdec_dxva2gldx.c @@ -15,13 +15,13 @@ * License along with mpv. If not, see <http://www.gnu.org/licenses/>. */ +#include <d3d9.h> #include <assert.h> #include "common/common.h" #include "osdep/windows_utils.h" #include "hwdec.h" #include "video/hwdec.h" -#include "video/d3d.h" #include "video/dxva2.h" // for WGL_ACCESS_READ_ONLY_NV @@ -30,7 +30,7 @@ #define SHARED_SURFACE_D3DFMT D3DFMT_X8R8G8B8 #define SHARED_SURFACE_MPFMT IMGFMT_RGB0 struct priv { - struct mp_d3d_ctx ctx; + struct mp_hwdec_ctx hwctx; IDirect3DDevice9Ex *device; HANDLE device_h; @@ -74,6 +74,8 @@ static void destroy(struct gl_hwdec *hw) struct priv *p = hw->priv; destroy_objects(hw); + hwdec_devices_remove(hw->devs, &p->hwctx); + if (p->device) IDirect3DDevice9Ex_Release(p->device); } @@ -81,10 +83,8 @@ static void destroy(struct gl_hwdec *hw) static int create(struct gl_hwdec *hw) { GL *gl = hw->gl; - if (hw->hwctx || !gl->MPGetNativeDisplay || - !(gl->mpgl_caps & MPGL_CAP_DXINTEROP)) { + if (!gl->MPGetNativeDisplay || !(gl->mpgl_caps & MPGL_CAP_DXINTEROP)) return -1; - } struct priv *p = talloc_zero(hw, struct priv); hw->priv = p; @@ -100,12 +100,14 @@ static int create(struct gl_hwdec *hw) if (!p->device) return -1; IDirect3DDevice9Ex_AddRef(p->device); - p->ctx.d3d9_device = (IDirect3DDevice9 *)p->device; - p->ctx.hwctx.type = HWDEC_DXVA2; - p->ctx.hwctx.d3d_ctx = &p->ctx; + p->hwctx = (struct mp_hwdec_ctx){ + .type = HWDEC_DXVA2, + .driver_name = hw->driver->name, + .ctx = (IDirect3DDevice9 *)p->device, + }; + hwdec_devices_add(hw->devs, &p->hwctx); - hw->hwctx = &p->ctx.hwctx; hw->converted_imgfmt = SHARED_SURFACE_MPFMT; return 0; } diff --git a/video/out/opengl/hwdec_osx.c b/video/out/opengl/hwdec_osx.c index addc16f404..5aa4d3dcd4 100644 --- a/video/out/opengl/hwdec_osx.c +++ b/video/out/opengl/hwdec_osx.c @@ -43,9 +43,11 @@ struct vt_format { }; struct priv { + struct mp_hwdec_ctx hwctx; + struct mp_vt_ctx vtctx; + CVPixelBufferRef pbuf; GLuint gl_planes[MP_MAX_PLANES]; - struct mp_hwdec_ctx hwctx; }; static struct vt_format vt_formats[] = { @@ -147,9 +149,9 @@ static bool check_hwdec(struct gl_hwdec *hw) return true; } -static uint32_t get_vt_fmt(struct mp_hwdec_ctx *ctx) +static uint32_t get_vt_fmt(struct mp_vt_ctx *vtctx) { - struct gl_hwdec *hw = ctx->priv; + struct gl_hwdec *hw = vtctx->priv; struct vt_format *f = vt_get_gl_format_from_imgfmt(hw->global->opts->videotoolbox_format); return f ? f->cvpixfmt : (uint32_t)-1; @@ -167,15 +169,21 @@ static int create(struct gl_hwdec *hw) hw->priv = p; hw->converted_imgfmt = f->imgfmt; - hw->hwctx = &p->hwctx; - hw->hwctx->download_image = download_image; - hw->hwctx->type = HWDEC_VIDEOTOOLBOX; - hw->hwctx->get_vt_fmt = get_vt_fmt; hw->gl_texture_target = GL_TEXTURE_RECTANGLE; hw->gl->GenTextures(MP_MAX_PLANES, p->gl_planes); - hw->hwctx->priv = hw; + p->vtctx = (struct mp_vt_ctx){ + .priv = hw, + .get_vt_fmt = get_vt_fmt, + }; + p->hwctx = (struct mp_hwdec_ctx){ + .type = HWDEC_VIDEOTOOLBOX, + .download_image = download_image, + .ctx = &p->vtctx, + }; + hwdec_devices_add(hw->devs, &p->hwctx); + return 0; } @@ -251,6 +259,8 @@ static void destroy(struct gl_hwdec *hw) CVPixelBufferRelease(p->pbuf); gl->DeleteTextures(MP_MAX_PLANES, p->gl_planes); + + hwdec_devices_remove(hw->devs, &p->hwctx); } const struct gl_hwdec_driver gl_hwdec_videotoolbox = { diff --git a/video/out/opengl/hwdec_vaegl.c b/video/out/opengl/hwdec_vaegl.c index 6356ec4e8c..84e6e83a73 100644 --- a/video/out/opengl/hwdec_vaegl.c +++ b/video/out/opengl/hwdec_vaegl.c @@ -169,6 +169,8 @@ static void destroy(struct gl_hwdec *hw) struct priv *p = hw->priv; unref_image(hw); destroy_textures(hw); + if (p->ctx) + hwdec_devices_remove(hw->devs, &p->ctx->hwctx); va_destroy(p->ctx); } @@ -181,8 +183,6 @@ static int create(struct gl_hwdec *hw) p->current_image.buf = p->current_image.image_id = VA_INVALID_ID; p->log = hw->log; - if (hw->hwctx) - return -1; if (!eglGetCurrentContext()) return -1; @@ -229,7 +229,8 @@ static int create(struct gl_hwdec *hw) return -1; } - hw->hwctx = &p->ctx->hwctx; + p->ctx->hwctx.driver_name = hw->driver->name; + hwdec_devices_add(hw->devs, &p->ctx->hwctx); return 0; } diff --git a/video/out/opengl/hwdec_vaglx.c b/video/out/opengl/hwdec_vaglx.c index 77b1f27c51..a9c5d03af4 100644 --- a/video/out/opengl/hwdec_vaglx.c +++ b/video/out/opengl/hwdec_vaglx.c @@ -64,13 +64,13 @@ static void destroy(struct gl_hwdec *hw) { struct priv *p = hw->priv; destroy_texture(hw); + if (p->ctx) + hwdec_devices_remove(hw->devs, &p->ctx->hwctx); va_destroy(p->ctx); } static int create(struct gl_hwdec *hw) { - if (hw->hwctx) - return -1; Display *x11disp = glXGetCurrentDisplay(); if (!x11disp) return -1; @@ -126,7 +126,8 @@ static int create(struct gl_hwdec *hw) return -1; } - hw->hwctx = &p->ctx->hwctx; + p->ctx->hwctx.driver_name = hw->driver->name; + hwdec_devices_add(hw->devs, &p->ctx->hwctx); hw->converted_imgfmt = IMGFMT_RGB0; return 0; } diff --git a/video/out/opengl/hwdec_vdpau.c b/video/out/opengl/hwdec_vdpau.c index 99e5a1414a..e3b69941bf 100644 --- a/video/out/opengl/hwdec_vdpau.c +++ b/video/out/opengl/hwdec_vdpau.c @@ -92,14 +92,14 @@ static void destroy(struct gl_hwdec *hw) destroy_objects(hw); mp_vdpau_mixer_destroy(p->mixer); + if (p->ctx) + hwdec_devices_remove(hw->devs, &p->ctx->hwctx); mp_vdpau_destroy(p->ctx); } static int create(struct gl_hwdec *hw) { GL *gl = hw->gl; - if (hw->hwctx) - return -1; Display *x11disp = glXGetCurrentDisplay(); if (!x11disp) return -1; @@ -119,7 +119,8 @@ static int create(struct gl_hwdec *hw) destroy(hw); return -1; } - hw->hwctx = &p->ctx->hwctx; + p->ctx->hwctx.driver_name = hw->driver->name; + hwdec_devices_add(hw->devs, &p->ctx->hwctx); hw->converted_imgfmt = IMGFMT_RGB0; return 0; } diff --git a/video/out/vo.c b/video/out/vo.c index 3e7999a698..3390f364f7 100644 --- a/video/out/vo.c +++ b/video/out/vo.c @@ -43,6 +43,7 @@ #include "options/m_config.h" #include "common/msg.h" #include "common/global.h" +#include "video/hwdec.h" #include "video/mp_image.h" #include "sub/osd.h" #include "osdep/io.h" diff --git a/video/out/vo.h b/video/out/vo.h index f6bc270afd..f417d5b522 100644 --- a/video/out/vo.h +++ b/video/out/vo.h @@ -61,9 +61,8 @@ enum mp_voctrl { VOCTRL_SET_EQUALIZER, // struct voctrl_set_equalizer_args* VOCTRL_GET_EQUALIZER, // struct voctrl_get_equalizer_args* - /* for hardware decoding */ - VOCTRL_GET_HWDEC_INFO, // struct mp_hwdec_info** - VOCTRL_LOAD_HWDEC_API, // private to vo_opengl + /* private to vo_opengl */ + VOCTRL_LOAD_HWDEC_API, // Redraw the image previously passed to draw_image() (basically, repeat // the previous draw_image call). If this is handled, the OSD should also @@ -297,6 +296,7 @@ struct vo { struct vo_w32_state *w32; struct vo_cocoa_state *cocoa; struct vo_wayland_state *wayland; + struct mp_hwdec_devices *hwdec_devs; struct input_ctx *input_ctx; struct osd_state *osd; struct encode_lavc_context *encode_lavc_ctx; diff --git a/video/out/vo_opengl.c b/video/out/vo_opengl.c index dfef6ec500..306e893f3b 100644 --- a/video/out/vo_opengl.c +++ b/video/out/vo_opengl.c @@ -59,7 +59,6 @@ struct gl_priv { struct gl_lcms *cms; struct gl_hwdec *hwdec; - struct mp_hwdec_info hwdec_info; // Options struct gl_video_opts *renderer_opts; @@ -196,25 +195,23 @@ static int reconfig(struct vo *vo, struct mp_image_params *params) return 0; } -static void request_hwdec_api(struct gl_priv *p, const char *api_name) +static void request_hwdec_api(struct vo *vo, void *api) { + struct gl_priv *p = vo->priv; + if (p->hwdec) return; - p->hwdec = gl_hwdec_load_api(p->vo->log, p->gl, p->vo->global, api_name); + p->hwdec = gl_hwdec_load_api(p->vo->log, p->gl, p->vo->global, + vo->hwdec_devs, (intptr_t)api); gl_video_set_hwdec(p->renderer, p->hwdec); - if (p->hwdec) - p->hwdec_info.hwctx = p->hwdec->hwctx; } -static void call_request_hwdec_api(struct mp_hwdec_info *info, - const char *api_name) +static void call_request_hwdec_api(void *ctx, enum hwdec_type type) { - struct vo *vo = info->load_api_ctx; - assert(&((struct gl_priv *)vo->priv)->hwdec_info == info); // Roundabout way to run hwdec loading on the VO thread. // Redirects to request_hwdec_api(). - vo_control(vo, VOCTRL_LOAD_HWDEC_API, (void *)api_name); + vo_control(ctx, VOCTRL_LOAD_HWDEC_API, (void *)(intptr_t)type); } static void get_and_update_icc_profile(struct gl_priv *p, int *events) @@ -325,13 +322,8 @@ static int control(struct vo *vo, uint32_t request, void *data) *(struct mp_image **)data = screen; return true; } - case VOCTRL_GET_HWDEC_INFO: { - struct mp_hwdec_info **arg = data; - *arg = &p->hwdec_info; - return true; - } case VOCTRL_LOAD_HWDEC_API: - request_hwdec_api(p, data); + request_hwdec_api(vo, data); return true; case VOCTRL_SET_COMMAND_LINE: { char *arg = data; @@ -373,6 +365,8 @@ static void uninit(struct vo *vo) gl_video_uninit(p->renderer); gl_hwdec_uninit(p->hwdec); + hwdec_devices_set_loader(vo->hwdec_devs, NULL, NULL); + hwdec_devices_destroy(vo->hwdec_devs); mpgl_uninit(p->glctx); } @@ -424,17 +418,17 @@ static int preinit(struct vo *vo) gl_lcms_set_options(p->cms, p->icc_opts); get_and_update_icc_profile(p, &(int){0}); - p->hwdec_info.load_api = call_request_hwdec_api; - p->hwdec_info.load_api_ctx = vo; + vo->hwdec_devs = hwdec_devices_create(); + + hwdec_devices_set_loader(vo->hwdec_devs, call_request_hwdec_api, vo); int hwdec = vo->opts->hwdec_preload_api; if (hwdec == HWDEC_NONE) hwdec = vo->global->opts->hwdec_api; if (hwdec != HWDEC_NONE) { - p->hwdec = gl_hwdec_load_api_id(p->vo->log, p->gl, vo->global, hwdec); + p->hwdec = gl_hwdec_load_api(p->vo->log, p->gl, vo->global, + vo->hwdec_devs, hwdec); gl_video_set_hwdec(p->renderer, p->hwdec); - if (p->hwdec) - p->hwdec_info.hwctx = p->hwdec->hwctx; } return 0; diff --git a/video/out/vo_opengl_cb.c b/video/out/vo_opengl_cb.c index 40930fbcae..06e0013a96 100644 --- a/video/out/vo_opengl_cb.c +++ b/video/out/vo_opengl_cb.c @@ -89,13 +89,16 @@ struct mpv_opengl_cb_context { struct vo *active; int hwdec_api; + // --- This is only mutable while initialized=false, during which nothing + // except the OpenGL context manager is allowed to access it. + struct mp_hwdec_devices *hwdec_devs; + // --- All of these can only be accessed from the thread where the host // application's OpenGL context is current - i.e. only while the // host application is calling certain mpv_opengl_cb_* APIs. GL *gl; struct gl_video *renderer; struct gl_hwdec *hwdec; - struct mp_hwdec_info hwdec_info; // it's also semi-immutable after init }; static void update(struct vo_priv *p); @@ -180,11 +183,10 @@ int mpv_opengl_cb_init_gl(struct mpv_opengl_cb_context *ctx, const char *exts, if (!ctx->renderer) return MPV_ERROR_UNSUPPORTED; - ctx->hwdec = gl_hwdec_load_api_id(ctx->log, ctx->gl, ctx->global, - ctx->hwdec_api); + ctx->hwdec_devs = hwdec_devices_create(); + ctx->hwdec = gl_hwdec_load_api(ctx->log, ctx->gl, ctx->global, + ctx->hwdec_devs, ctx->hwdec_api); gl_video_set_hwdec(ctx->renderer, ctx->hwdec); - if (ctx->hwdec) - ctx->hwdec_info.hwctx = ctx->hwdec->hwctx; pthread_mutex_lock(&ctx->lock); // We don't know the exact caps yet - use a known superset @@ -222,6 +224,8 @@ int mpv_opengl_cb_uninit_gl(struct mpv_opengl_cb_context *ctx) ctx->renderer = NULL; gl_hwdec_uninit(ctx->hwdec); ctx->hwdec = NULL; + hwdec_devices_destroy(ctx->hwdec_devs); + ctx->hwdec_devs = NULL; talloc_free(ctx->gl); ctx->gl = NULL; talloc_free(ctx->new_opts_cfg); @@ -514,11 +518,6 @@ static int control(struct vo *vo, uint32_t request, void *data) char *arg = data; return reparse_cmdline(p, arg); } - case VOCTRL_GET_HWDEC_INFO: { - struct mp_hwdec_info **arg = data; - *arg = p->ctx ? &p->ctx->hwdec_info : NULL; - return true; - } } return VO_NOTIMPL; @@ -561,6 +560,8 @@ static int preinit(struct vo *vo) p->ctx->eq_changed = true; pthread_mutex_unlock(&p->ctx->lock); + vo->hwdec_devs = p->ctx->hwdec_devs; + return 0; } diff --git a/video/out/vo_vaapi.c b/video/out/vo_vaapi.c index 5275d4d28d..dc8aaacf9e 100644 --- a/video/out/vo_vaapi.c +++ b/video/out/vo_vaapi.c @@ -68,7 +68,6 @@ struct priv { struct vo *vo; VADisplay display; struct mp_vaapi_ctx *mpvaapi; - struct mp_hwdec_info hwdec_info; struct mp_image_params image_params; struct mp_rect src_rect; @@ -515,11 +514,6 @@ static int control(struct vo *vo, uint32_t request, void *data) struct priv *p = vo->priv; switch (request) { - case VOCTRL_GET_HWDEC_INFO: { - struct mp_hwdec_info **arg = data; - *arg = &p->hwdec_info; - return true; - } case VOCTRL_SET_EQUALIZER: { struct voctrl_set_equalizer_args *eq = data; return set_equalizer(p, eq->name, eq->value); @@ -561,6 +555,11 @@ static void uninit(struct vo *vo) free_subpicture(p, &part->image); } + if (vo->hwdec_devs) { + hwdec_devices_remove(vo->hwdec_devs, &p->mpvaapi->hwctx); + hwdec_devices_destroy(vo->hwdec_devs); + } + va_destroy(p->mpvaapi); vo_x11_uninit(vo); @@ -591,8 +590,6 @@ static int preinit(struct vo *vo) goto fail; } - p->hwdec_info.hwctx = &p->mpvaapi->hwctx; - if (va_guess_if_emulated(p->mpvaapi)) { MP_WARN(vo, "VA-API is most likely emulated via VDPAU.\n" "It's better to use VDPAU directly with: --vo=vdpau\n"); @@ -645,6 +642,10 @@ static int preinit(struct vo *vo) p->va_num_display_attrs = 0; p->mp_display_attr = talloc_zero_array(vo, int, p->va_num_display_attrs); } + + vo->hwdec_devs = hwdec_devices_create(); + hwdec_devices_add(vo->hwdec_devs, &p->mpvaapi->hwctx); + return 0; fail: diff --git a/video/out/vo_vdpau.c b/video/out/vo_vdpau.c index 1dc5dc3b36..15472b2189 100644 --- a/video/out/vo_vdpau.c +++ b/video/out/vo_vdpau.c @@ -71,7 +71,6 @@ struct vdpctx { struct vdp_functions *vdp; VdpDevice vdp_device; uint64_t preemption_counter; - struct mp_hwdec_info hwdec_info; struct m_color colorkey; @@ -1028,6 +1027,9 @@ static void uninit(struct vo *vo) { struct vdpctx *vc = vo->priv; + hwdec_devices_remove(vo->hwdec_devs, &vc->mpvdp->hwctx); + hwdec_devices_destroy(vo->hwdec_devs); + /* Destroy all vdpau objects */ mp_vdpau_mixer_destroy(vc->video_mixer); destroy_vdpau_objects(vo); @@ -1053,7 +1055,8 @@ static int preinit(struct vo *vo) return -1; } - vc->hwdec_info.hwctx = &vc->mpvdp->hwctx; + vo->hwdec_devs = hwdec_devices_create(); + hwdec_devices_add(vo->hwdec_devs, &vc->mpvdp->hwctx); vc->video_mixer = mp_vdpau_mixer_create(vc->mpvdp, vo->log); @@ -1117,11 +1120,6 @@ static int control(struct vo *vo, uint32_t request, void *data) check_preemption(vo); switch (request) { - case VOCTRL_GET_HWDEC_INFO: { - struct mp_hwdec_info **arg = data; - *arg = &vc->hwdec_info; - return true; - } case VOCTRL_GET_PANSCAN: return VO_TRUE; case VOCTRL_SET_PANSCAN: |