summaryrefslogtreecommitdiffstats
path: root/video/out
diff options
context:
space:
mode:
Diffstat (limited to 'video/out')
-rw-r--r--video/out/opengl/hwdec.c29
-rw-r--r--video/out/opengl/hwdec.h12
-rw-r--r--video/out/opengl/hwdec_d3d11egl.c18
-rw-r--r--video/out/opengl/hwdec_dxva2.c27
-rw-r--r--video/out/opengl/hwdec_dxva2egl.c20
-rw-r--r--video/out/opengl/hwdec_dxva2gldx.c20
-rw-r--r--video/out/opengl/hwdec_osx.c26
-rw-r--r--video/out/opengl/hwdec_vaegl.c7
-rw-r--r--video/out/opengl/hwdec_vaglx.c7
-rw-r--r--video/out/opengl/hwdec_vdpau.c7
-rw-r--r--video/out/vo.c1
-rw-r--r--video/out/vo.h6
-rw-r--r--video/out/vo_opengl.c36
-rw-r--r--video/out/vo_opengl_cb.c21
-rw-r--r--video/out/vo_vaapi.c17
-rw-r--r--video/out/vo_vdpau.c12
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: