summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-01-22 15:32:23 +0100
committerwm4 <wm4@nowhere>2015-01-22 15:32:23 +0100
commitaae9af348e62d5feba6547855003df0d954cb3ae (patch)
treedd0d28655c65e1f814bec3ef537ea377a941b9b7 /video
parent29cf62d20133b32e1514a315b4f7e013ed9cb768 (diff)
downloadmpv-aae9af348e62d5feba6547855003df0d954cb3ae.tar.bz2
mpv-aae9af348e62d5feba6547855003df0d954cb3ae.tar.xz
video: have a generic context struct for hwdec backends
Before this commit, each hw backend had their own specific struct types for context, and some, like VDA, had none at all. Add a context struct (mp_hwdec_ctx) that provides a somewhat generic way to pass the hwdec context around. Some things get slightly better, some slightly more verbose. mp_hwdec_info is still around; it's still needed, but is reduced to its role of handling delayed loading of the hwdec backend.
Diffstat (limited to 'video')
-rw-r--r--video/decode/vaapi.c8
-rw-r--r--video/decode/vdpau.c6
-rw-r--r--video/filter/vf_vavpp.c4
-rw-r--r--video/filter/vf_vdpaupp.c4
-rw-r--r--video/hwdec.h18
-rw-r--r--video/out/gl_hwdec.c7
-rw-r--r--video/out/gl_hwdec.h5
-rw-r--r--video/out/gl_hwdec_vaglx.c6
-rw-r--r--video/out/gl_hwdec_vdpau.c6
-rw-r--r--video/out/vo_opengl.c4
-rw-r--r--video/out/vo_opengl_cb.c5
-rw-r--r--video/out/vo_vaapi.c2
-rw-r--r--video/out/vo_vdpau.c2
-rw-r--r--video/vaapi.c4
-rw-r--r--video/vaapi.h2
-rw-r--r--video/vdpau.c4
-rw-r--r--video/vdpau.h3
17 files changed, 56 insertions, 34 deletions
diff --git a/video/decode/vaapi.c b/video/decode/vaapi.c
index de26ac2955..82de0a667e 100644
--- a/video/decode/vaapi.c
+++ b/video/decode/vaapi.c
@@ -408,20 +408,18 @@ static int init_with_vactx(struct lavc_ctx *ctx, struct mp_vaapi_ctx *vactx)
static int init(struct lavc_ctx *ctx)
{
- if (!ctx->hwdec_info->vaapi_ctx)
- return -1;
- return init_with_vactx(ctx, ctx->hwdec_info->vaapi_ctx);
+ return init_with_vactx(ctx, ctx->hwdec_info->hwctx->vaapi_ctx);
}
static int probe(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info,
const char *decoder)
{
hwdec_request_api(info, "vaapi");
- if (!info || !info->vaapi_ctx)
+ if (!info || !info->hwctx || !info->hwctx->vaapi_ctx)
return HWDEC_ERR_NO_CTX;
if (!hwdec_check_codec_support(decoder, profiles))
return HWDEC_ERR_NO_CODEC;
- if (va_guess_if_emulated(info->vaapi_ctx))
+ if (va_guess_if_emulated(info->hwctx->vaapi_ctx))
return HWDEC_ERR_EMULATED;
return 0;
}
diff --git a/video/decode/vdpau.c b/video/decode/vdpau.c
index f144176520..92ea401750 100644
--- a/video/decode/vdpau.c
+++ b/video/decode/vdpau.c
@@ -153,7 +153,7 @@ static int init(struct lavc_ctx *ctx)
struct priv *p = talloc_ptrtype(NULL, p);
*p = (struct priv) {
.log = mp_log_new(p, ctx->log, "vdpau"),
- .mpvdp = ctx->hwdec_info->vdpau_ctx,
+ .mpvdp = ctx->hwdec_info->hwctx->vdpau_ctx,
};
ctx->hwdec_priv = p;
@@ -185,11 +185,11 @@ static int probe(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info,
const char *decoder)
{
hwdec_request_api(info, "vdpau");
- if (!info || !info->vdpau_ctx)
+ if (!info || !info->hwctx || !info->hwctx->vdpau_ctx)
return HWDEC_ERR_NO_CTX;
if (!hwdec_check_codec_support(decoder, profiles))
return HWDEC_ERR_NO_CODEC;
- if (mp_vdpau_guess_if_emulated(info->vdpau_ctx))
+ if (mp_vdpau_guess_if_emulated(info->hwctx->vdpau_ctx))
return HWDEC_ERR_EMULATED;
return 0;
}
diff --git a/video/filter/vf_vavpp.c b/video/filter/vf_vavpp.c
index ec39772865..4e39affd41 100644
--- a/video/filter/vf_vavpp.c
+++ b/video/filter/vf_vavpp.c
@@ -391,8 +391,10 @@ static int vf_open(vf_instance_t *vf)
vf->control = control;
struct vf_priv_s *p = vf->priv;
+ if (!vf->hwdec)
+ return false;
hwdec_request_api(vf->hwdec, "vaapi");
- p->va = vf->hwdec ? vf->hwdec->vaapi_ctx : NULL;
+ p->va = vf->hwdec->hwctx ? vf->hwdec->hwctx->vaapi_ctx : NULL;
if (!p->va || !p->va->display)
return false;
p->display = p->va->display;
diff --git a/video/filter/vf_vdpaupp.c b/video/filter/vf_vdpaupp.c
index 05cabf7998..4db6ab9186 100644
--- a/video/filter/vf_vdpaupp.c
+++ b/video/filter/vf_vdpaupp.c
@@ -222,8 +222,10 @@ static int vf_open(vf_instance_t *vf)
vf->control = control;
vf->uninit = uninit;
+ if (!vf->hwdec)
+ return 0;
hwdec_request_api(vf->hwdec, "vdpau");
- p->ctx = vf->hwdec ? vf->hwdec->vdpau_ctx : NULL;
+ p->ctx = vf->hwdec->hwctx ? vf->hwdec->hwctx->vdpau_ctx : NULL;
if (!p->ctx)
return 0;
diff --git a/video/hwdec.h b/video/hwdec.h
index ca18340ae1..149cd81bae 100644
--- a/video/hwdec.h
+++ b/video/hwdec.h
@@ -1,14 +1,26 @@
#ifndef MP_HWDEC_H_
#define MP_HWDEC_H_
+struct mp_image_pool;
+
+struct mp_hwdec_ctx {
+ void *priv; // for free use by hwdec implementation
+
+ // API-specific, not needed by all backends.
+ struct mp_vdpau_ctx *vdpau_ctx;
+ struct mp_vaapi_ctx *vaapi_ctx;
+};
+
// Used to communicate hardware decoder API handles from VO to video decoder.
// The VO can set the context pointer for supported APIs.
struct mp_hwdec_info {
- struct mp_vdpau_ctx *vdpau_ctx;
- struct mp_vaapi_ctx *vaapi_ctx;
+ // (Since currently only 1 hwdec API is loaded at a time, this pointer
+ // simply maps to the loaded one.)
+ struct mp_hwdec_ctx *hwctx;
+
// Can be used to lazily load a requested API.
// api_name is e.g. "vdpau" (like the fields above, without "_ctx")
- // Can be NULL, is idempotent, caller checks _ctx fields for success/access.
+ // Can be NULL, is idempotent, caller checks hwctx fields for success/access.
// Due to threading, the callback is the only code that is allowed to
// change fields in this struct after initialization.
void (*load_api)(struct mp_hwdec_info *info, const char *api_name);
diff --git a/video/out/gl_hwdec.c b/video/out/gl_hwdec.c
index 3bab1c1e9c..7b8adb4fc4 100644
--- a/video/out/gl_hwdec.c
+++ b/video/out/gl_hwdec.c
@@ -49,7 +49,6 @@ static const struct gl_hwdec_driver *const mpgl_hwdec_drivers[] = {
static struct gl_hwdec *load_hwdec_driver(struct mp_log *log, GL *gl,
const struct gl_hwdec_driver *drv,
- struct mp_hwdec_info *info,
bool is_auto)
{
struct gl_hwdec *hwdec = talloc(NULL, struct gl_hwdec);
@@ -57,7 +56,6 @@ static struct gl_hwdec *load_hwdec_driver(struct mp_log *log, GL *gl,
.driver = drv,
.log = mp_log_new(hwdec, log, drv->api_name),
.gl = gl,
- .info = info,
.gl_texture_target = GL_TEXTURE_2D,
.reject_emulated = is_auto,
};
@@ -70,14 +68,13 @@ static struct gl_hwdec *load_hwdec_driver(struct mp_log *log, GL *gl,
}
struct gl_hwdec *gl_hwdec_load_api(struct mp_log *log, GL *gl,
- const char *api_name,
- struct mp_hwdec_info *info)
+ const char *api_name)
{
bool is_auto = api_name && strcmp(api_name, "auto") == 0;
for (int n = 0; mpgl_hwdec_drivers[n]; n++) {
const struct gl_hwdec_driver *drv = mpgl_hwdec_drivers[n];
if (is_auto || (api_name && strcmp(drv->api_name, api_name) == 0)) {
- struct gl_hwdec *r = load_hwdec_driver(log, gl, drv, info, is_auto);
+ struct gl_hwdec *r = load_hwdec_driver(log, gl, drv, is_auto);
if (r)
return r;
}
diff --git a/video/out/gl_hwdec.h b/video/out/gl_hwdec.h
index ea10ac08f8..8d2f563d5e 100644
--- a/video/out/gl_hwdec.h
+++ b/video/out/gl_hwdec.h
@@ -10,7 +10,7 @@ struct gl_hwdec {
const struct gl_hwdec_driver *driver;
struct mp_log *log;
GL *gl;
- struct mp_hwdec_info *info;
+ struct mp_hwdec_ctx *hwctx;
// For free use by hwdec driver
void *priv;
// For working around the vdpau vs. vaapi mess.
@@ -50,8 +50,7 @@ struct gl_hwdec_driver {
};
struct gl_hwdec *gl_hwdec_load_api(struct mp_log *log, GL *gl,
- const char *api_name,
- struct mp_hwdec_info *info);
+ const char *api_name);
void gl_hwdec_uninit(struct gl_hwdec *hwdec);
diff --git a/video/out/gl_hwdec_vaglx.c b/video/out/gl_hwdec_vaglx.c
index 555e61aec3..f9dc42911d 100644
--- a/video/out/gl_hwdec_vaglx.c
+++ b/video/out/gl_hwdec_vaglx.c
@@ -58,13 +58,11 @@ static void destroy(struct gl_hwdec *hw)
struct priv *p = hw->priv;
destroy_texture(hw);
va_destroy(p->ctx);
-
- hw->info->vaapi_ctx = NULL;
}
static int create(struct gl_hwdec *hw)
{
- if (hw->info->vaapi_ctx)
+ if (hw->hwctx)
return -1;
Display *x11disp = glXGetCurrentDisplay();
if (!x11disp)
@@ -84,7 +82,7 @@ static int create(struct gl_hwdec *hw)
destroy(hw);
return -1;
}
- hw->info->vaapi_ctx = p->ctx;
+ hw->hwctx = &p->ctx->hwctx;
hw->converted_imgfmt = IMGFMT_RGB0;
return 0;
}
diff --git a/video/out/gl_hwdec_vdpau.c b/video/out/gl_hwdec_vdpau.c
index c59d97bc1b..49f8e7c7b5 100644
--- a/video/out/gl_hwdec_vdpau.c
+++ b/video/out/gl_hwdec_vdpau.c
@@ -87,14 +87,12 @@ static void destroy(struct gl_hwdec *hw)
destroy_objects(hw);
mp_vdpau_mixer_destroy(p->mixer);
mp_vdpau_destroy(p->ctx);
-
- hw->info->vdpau_ctx = NULL;
}
static int create(struct gl_hwdec *hw)
{
GL *gl = hw->gl;
- if (hw->info->vdpau_ctx)
+ if (hw->hwctx)
return -1;
Display *x11disp = glXGetCurrentDisplay();
if (!x11disp)
@@ -115,7 +113,7 @@ static int create(struct gl_hwdec *hw)
destroy(hw);
return -1;
}
- hw->info->vdpau_ctx = p->ctx;
+ hw->hwctx = &p->ctx->hwctx;
hw->converted_imgfmt = IMGFMT_RGB0;
return 0;
}
diff --git a/video/out/vo_opengl.c b/video/out/vo_opengl.c
index bfb1adbec8..058b305c2f 100644
--- a/video/out/vo_opengl.c
+++ b/video/out/vo_opengl.c
@@ -224,8 +224,10 @@ static void request_hwdec_api(struct gl_priv *p, const char *api_name)
if (p->hwdec)
return;
mpgl_lock(p->glctx);
- p->hwdec = gl_hwdec_load_api(p->vo->log, p->gl, api_name, &p->hwdec_info);
+ p->hwdec = gl_hwdec_load_api(p->vo->log, p->gl, api_name);
gl_video_set_hwdec(p->renderer, p->hwdec);
+ if (p->hwdec)
+ p->hwdec_info.hwctx = p->hwdec->hwctx;
mpgl_unlock(p->glctx);
}
diff --git a/video/out/vo_opengl_cb.c b/video/out/vo_opengl_cb.c
index 3d5c16d8f2..1a2e44f718 100644
--- a/video/out/vo_opengl_cb.c
+++ b/video/out/vo_opengl_cb.c
@@ -227,9 +227,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(ctx->log, ctx->gl, ctx->hwapi, &ctx->hwdec_info);
+ ctx->hwdec = gl_hwdec_load_api(ctx->log, ctx->gl, ctx->hwapi);
gl_video_set_hwdec(ctx->renderer, ctx->hwdec);
-
+ if (ctx->hwdec)
+ ctx->hwdec_info.hwctx = ctx->hwdec->hwctx;
pthread_mutex_lock(&ctx->lock);
ctx->eq = *gl_video_eq_ptr(ctx->renderer);
diff --git a/video/out/vo_vaapi.c b/video/out/vo_vaapi.c
index 21e604f235..cf07787a48 100644
--- a/video/out/vo_vaapi.c
+++ b/video/out/vo_vaapi.c
@@ -609,7 +609,7 @@ static int preinit(struct vo *vo)
goto fail;
}
- p->hwdec_info.vaapi_ctx = p->mpvaapi;
+ 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"
diff --git a/video/out/vo_vdpau.c b/video/out/vo_vdpau.c
index 640e16e1a8..a022946c1b 100644
--- a/video/out/vo_vdpau.c
+++ b/video/out/vo_vdpau.c
@@ -988,7 +988,7 @@ static int preinit(struct vo *vo)
return -1;
}
- vc->hwdec_info.vdpau_ctx = vc->mpvdp;
+ vc->hwdec_info.hwctx = &vc->mpvdp->hwctx;
vc->video_mixer = mp_vdpau_mixer_create(vc->mpvdp, vo->log);
diff --git a/video/vaapi.c b/video/vaapi.c
index e7cd7591a1..13e78f0f31 100644
--- a/video/vaapi.c
+++ b/video/vaapi.c
@@ -122,6 +122,10 @@ struct mp_vaapi_ctx *va_initialize(VADisplay *display, struct mp_log *plog)
*res = (struct mp_vaapi_ctx) {
.log = talloc_steal(res, log),
.display = display,
+ .hwctx = {
+ .priv = res,
+ .vaapi_ctx = res,
+ },
};
mpthread_mutex_init_recursive(&res->lock);
diff --git a/video/vaapi.h b/video/vaapi.h
index 8a6ba766e5..98e21d579b 100644
--- a/video/vaapi.h
+++ b/video/vaapi.h
@@ -72,11 +72,13 @@
(const char[]){(fcc), (fcc) >> 8u, (fcc) >> 16u, (fcc) >> 24u, 0}
#include "mp_image.h"
+#include "hwdec.h"
struct mp_image_pool;
struct mp_log;
struct mp_vaapi_ctx {
+ struct mp_hwdec_ctx hwctx;
struct mp_log *log;
VADisplay display;
struct va_image_formats *image_formats;
diff --git a/video/vdpau.c b/video/vdpau.c
index 650f181907..3f7488470c 100644
--- a/video/vdpau.c
+++ b/video/vdpau.c
@@ -302,6 +302,10 @@ struct mp_vdpau_ctx *mp_vdpau_create_device_x11(struct mp_log *log, Display *x11
.log = log,
.x11 = x11,
.preemption_counter = 1,
+ .hwctx = {
+ .priv = ctx,
+ .vdpau_ctx = ctx,
+ },
};
mpthread_mutex_init_recursive(&ctx->preempt_lock);
pthread_mutex_init(&ctx->pool_lock, NULL);
diff --git a/video/vdpau.h b/video/vdpau.h
index f1c29fd50d..0af00f098b 100644
--- a/video/vdpau.h
+++ b/video/vdpau.h
@@ -10,6 +10,7 @@
#include <vdpau/vdpau_x11.h>
#include "common/msg.h"
+#include "hwdec.h"
#define CHECK_VDP_ERROR(ctx, message) \
do { \
@@ -40,6 +41,8 @@ struct mp_vdpau_ctx {
struct mp_log *log;
Display *x11;
+ struct mp_hwdec_ctx hwctx;
+
// These are mostly immutable, except on preemption. We don't really care
// to synchronize the preemption case fully correctly, because it's an
// extremely obscure corner case, and basically a vdpau API design bug.