From aae9af348e62d5feba6547855003df0d954cb3ae Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 22 Jan 2015 15:32:23 +0100 Subject: 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. --- video/decode/vaapi.c | 8 +++----- video/decode/vdpau.c | 6 +++--- video/filter/vf_vavpp.c | 4 +++- video/filter/vf_vdpaupp.c | 4 +++- video/hwdec.h | 18 +++++++++++++++--- video/out/gl_hwdec.c | 7 ++----- video/out/gl_hwdec.h | 5 ++--- video/out/gl_hwdec_vaglx.c | 6 ++---- video/out/gl_hwdec_vdpau.c | 6 ++---- video/out/vo_opengl.c | 4 +++- video/out/vo_opengl_cb.c | 5 +++-- video/out/vo_vaapi.c | 2 +- video/out/vo_vdpau.c | 2 +- video/vaapi.c | 4 ++++ video/vaapi.h | 2 ++ video/vdpau.c | 4 ++++ video/vdpau.h | 3 +++ 17 files changed, 56 insertions(+), 34 deletions(-) (limited to 'video') 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 #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. -- cgit v1.2.3