diff options
Diffstat (limited to 'video/out')
-rw-r--r-- | video/out/gl_common.c | 17 | ||||
-rw-r--r-- | video/out/gl_common.h | 45 | ||||
-rw-r--r-- | video/out/gl_hwdec.c | 90 | ||||
-rw-r--r-- | video/out/gl_hwdec.h | 56 | ||||
-rw-r--r-- | video/out/gl_hwdec_vaglx.c | 5 | ||||
-rw-r--r-- | video/out/gl_hwdec_vda.c | 2 | ||||
-rw-r--r-- | video/out/gl_hwdec_vdpau.c | 5 | ||||
-rw-r--r-- | video/out/gl_video.c | 1 | ||||
-rw-r--r-- | video/out/vo_opengl.c | 52 |
9 files changed, 160 insertions, 113 deletions
diff --git a/video/out/gl_common.c b/video/out/gl_common.c index 4d0a3c8dd4..1f005934d4 100644 --- a/video/out/gl_common.c +++ b/video/out/gl_common.c @@ -1035,20 +1035,3 @@ void mp_log_source(struct mp_log *log, int lev, const char *src) src = next; } } - -extern const struct gl_hwdec_driver gl_hwdec_vaglx; -extern const struct gl_hwdec_driver gl_hwdec_vda; -extern const struct gl_hwdec_driver gl_hwdec_vdpau; - -const struct gl_hwdec_driver *const mpgl_hwdec_drivers[] = { -#if HAVE_VAAPI_GLX - &gl_hwdec_vaglx, -#endif -#if HAVE_VDA_GL - &gl_hwdec_vda, -#endif -#if HAVE_VDPAU_GL_X11 - &gl_hwdec_vdpau, -#endif - NULL -}; diff --git a/video/out/gl_common.h b/video/out/gl_common.h index fa1566b0fb..38d952ae1b 100644 --- a/video/out/gl_common.h +++ b/video/out/gl_common.h @@ -166,51 +166,6 @@ void mpgl_set_backend_x11(MPGLContext *ctx); void mpgl_set_backend_x11egl(MPGLContext *ctx); void mpgl_set_backend_wayland(MPGLContext *ctx); -struct mp_hwdec_info; - -struct gl_hwdec { - const struct gl_hwdec_driver *driver; - struct mp_log *log; - GL *gl; - struct mp_hwdec_info *info; - // For free use by hwdec driver - void *priv; - // hwdec backends must set this to an IMGFMT_ that has an equivalent - // internal representation in gl_video.c as the hardware texture. - // It's used to build the rendering chain, and also as screenshot format. - int converted_imgfmt; - // Normally this is GL_TEXTURE_2D, but the hwdec driver can set it to - // GL_TEXTURE_RECTANGLE. - GLenum gl_texture_target; -}; - -struct gl_hwdec_driver { - // Same name as used by mp_hwdec_info->load_api() - const char *api_name; - // 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. - // This also must set hw->converted_imgfmt. - int (*create)(struct gl_hwdec *hw); - // Prepare for rendering video. (E.g. create textures.) - // Called on initialization, and every time the video size changes. - int (*reinit)(struct gl_hwdec *hw, const struct mp_image_params *params); - // Return textures that contain the given hw_image. - // Note that the caller keeps a reference to hw_image until unmap_image - // is called, so the hwdec driver doesn't need to do that. - int (*map_image)(struct gl_hwdec *hw, struct mp_image *hw_image, - GLuint *out_textures); - // Undo map_image(). The user of map_image() calls this when the textures - // are not needed anymore. - void (*unmap_image)(struct gl_hwdec *hw); - // Return a mp_image downloaded from the GPU (optional) - struct mp_image *(*download_image)(struct gl_hwdec *hw, - struct mp_image *hw_image); - void (*destroy)(struct gl_hwdec *hw); -}; - -extern const struct gl_hwdec_driver *const mpgl_hwdec_drivers[]; - void mpgl_load_functions(GL *gl, void *(*getProcAddress)(const GLubyte *), const char *ext2, struct mp_log *log); diff --git a/video/out/gl_hwdec.c b/video/out/gl_hwdec.c new file mode 100644 index 0000000000..92f0ad095e --- /dev/null +++ b/video/out/gl_hwdec.c @@ -0,0 +1,90 @@ +/* + * This file is part of MPlayer. + * + * MPlayer is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * MPlayer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * You can alternatively redistribute this file and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + */ + +#include <stddef.h> +#include <string.h> + +#include "config.h" + +#include "common/common.h" +#include "common/msg.h" +#include "gl_hwdec.h" + +extern const struct gl_hwdec_driver gl_hwdec_vaglx; +extern const struct gl_hwdec_driver gl_hwdec_vda; +extern const struct gl_hwdec_driver gl_hwdec_vdpau; + +static const struct gl_hwdec_driver *const mpgl_hwdec_drivers[] = { +#if HAVE_VAAPI_GLX + &gl_hwdec_vaglx, +#endif +#if HAVE_VDA_GL + &gl_hwdec_vda, +#endif +#if HAVE_VDPAU_GL_X11 + &gl_hwdec_vdpau, +#endif + NULL +}; + +static struct gl_hwdec *load_hwdec_driver(struct mp_log *log, GL *gl, + const struct gl_hwdec_driver *drv, + struct mp_hwdec_info *info) +{ + struct gl_hwdec *hwdec = talloc(NULL, struct gl_hwdec); + *hwdec = (struct gl_hwdec) { + .driver = drv, + .log = mp_log_new(hwdec, log, drv->api_name), + .gl = gl, + .info = info, + .gl_texture_target = GL_TEXTURE_2D, + }; + if (hwdec->driver->create(hwdec) < 0) { + talloc_free(hwdec); + mp_err(log, "Couldn't load hwdec driver '%s'\n", drv->api_name); + return NULL; + } + return hwdec; +} + +struct gl_hwdec *gl_hwdec_load_api(struct mp_log *log, GL *gl, + const char *api_name, + struct mp_hwdec_info *info) +{ + for (int n = 0; mpgl_hwdec_drivers[n]; n++) { + const struct gl_hwdec_driver *drv = mpgl_hwdec_drivers[n]; + if (api_name && strcmp(drv->api_name, api_name) == 0) { + struct gl_hwdec *r = load_hwdec_driver(log, gl, drv, info); + if (r) + return r; + } + } + return NULL; +} + +void gl_hwdec_uninit(struct gl_hwdec *hwdec) +{ + if (hwdec) + hwdec->driver->destroy(hwdec); + talloc_free(hwdec); +} diff --git a/video/out/gl_hwdec.h b/video/out/gl_hwdec.h new file mode 100644 index 0000000000..5c70f7fd0d --- /dev/null +++ b/video/out/gl_hwdec.h @@ -0,0 +1,56 @@ +#ifndef MPGL_HWDEC_H_ +#define MPGL_HWDEC_H_ + +#include "gl_common.h" +#include "video/hwdec.h" + +struct mp_hwdec_info; + +struct gl_hwdec { + const struct gl_hwdec_driver *driver; + struct mp_log *log; + GL *gl; + struct mp_hwdec_info *info; + // For free use by hwdec driver + void *priv; + // hwdec backends must set this to an IMGFMT_ that has an equivalent + // internal representation in gl_video.c as the hardware texture. + // It's used to build the rendering chain, and also as screenshot format. + int converted_imgfmt; + // Normally this is GL_TEXTURE_2D, but the hwdec driver can set it to + // GL_TEXTURE_RECTANGLE. + GLenum gl_texture_target; +}; + +struct gl_hwdec_driver { + // Same name as used by mp_hwdec_info->load_api() + const char *api_name; + // 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. + // This also must set hw->converted_imgfmt. + int (*create)(struct gl_hwdec *hw); + // Prepare for rendering video. (E.g. create textures.) + // Called on initialization, and every time the video size changes. + int (*reinit)(struct gl_hwdec *hw, const struct mp_image_params *params); + // Return textures that contain the given hw_image. + // Note that the caller keeps a reference to hw_image until unmap_image + // is called, so the hwdec driver doesn't need to do that. + int (*map_image)(struct gl_hwdec *hw, struct mp_image *hw_image, + GLuint *out_textures); + // Undo map_image(). The user of map_image() calls this when the textures + // are not needed anymore. + void (*unmap_image)(struct gl_hwdec *hw); + // Return a mp_image downloaded from the GPU (optional) + struct mp_image *(*download_image)(struct gl_hwdec *hw, + struct mp_image *hw_image); + void (*destroy)(struct gl_hwdec *hw); +}; + +struct gl_hwdec *gl_hwdec_load_api(struct mp_log *log, GL *gl, + const char *api_name, + struct mp_hwdec_info *info); + +void gl_hwdec_uninit(struct gl_hwdec *hwdec); + +#endif diff --git a/video/out/gl_hwdec_vaglx.c b/video/out/gl_hwdec_vaglx.c index a8b3a3f8ad..3d7af74d19 100644 --- a/video/out/gl_hwdec_vaglx.c +++ b/video/out/gl_hwdec_vaglx.c @@ -24,9 +24,8 @@ #include <va/va_glx.h> #include "x11_common.h" -#include "gl_common.h" +#include "gl_hwdec.h" #include "video/vaapi.h" -#include "video/hwdec.h" struct priv { struct mp_log *log; @@ -58,6 +57,8 @@ 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) diff --git a/video/out/gl_hwdec_vda.c b/video/out/gl_hwdec_vda.c index 193204d6de..50ff2db437 100644 --- a/video/out/gl_hwdec_vda.c +++ b/video/out/gl_hwdec_vda.c @@ -23,7 +23,7 @@ #include <OpenGL/CGLIOSurface.h> #include "video/decode/dec_video.h" -#include "gl_common.h" +#include "gl_hwdec.h" struct priv { CVPixelBufferRef pbuf; diff --git a/video/out/gl_hwdec_vdpau.c b/video/out/gl_hwdec_vdpau.c index 2fa262348f..7a68ddd83f 100644 --- a/video/out/gl_hwdec_vdpau.c +++ b/video/out/gl_hwdec_vdpau.c @@ -20,9 +20,8 @@ #include <GL/glx.h> -#include "gl_common.h" +#include "gl_hwdec.h" #include "video/vdpau.h" -#include "video/hwdec.h" #include "video/vdpau_mixer.h" // This is a GL_NV_vdpau_interop specification bug, and headers (unfortunately) @@ -88,6 +87,8 @@ 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) diff --git a/video/out/gl_video.c b/video/out/gl_video.c index 65cdf90d42..d2d0c2e571 100644 --- a/video/out/gl_video.c +++ b/video/out/gl_video.c @@ -32,6 +32,7 @@ #include "misc/bstr.h" #include "gl_common.h" +#include "gl_hwdec.h" #include "gl_osd.h" #include "filter_kernels.h" #include "aspect.h" diff --git a/video/out/vo_opengl.c b/video/out/vo_opengl.c index 2499106355..7993b0a3e7 100644 --- a/video/out/vo_opengl.c +++ b/video/out/vo_opengl.c @@ -45,6 +45,7 @@ #include "sub/osd.h" #include "gl_common.h" +#include "gl_hwdec.h" #include "gl_osd.h" #include "filter_kernels.h" #include "video/memcpy_pic.h" @@ -219,43 +220,14 @@ static int reconfig(struct vo *vo, struct mp_image_params *params, int flags) return 0; } -static void load_hwdec_driver(struct gl_priv *p, - const struct gl_hwdec_driver *drv) -{ - assert(!p->hwdec); - struct gl_hwdec *hwdec = talloc(NULL, struct gl_hwdec); - *hwdec = (struct gl_hwdec) { - .driver = drv, - .log = mp_log_new(hwdec, p->vo->log, drv->api_name), - .gl = p->glctx->gl, - .info = &p->hwdec_info, - .gl_texture_target = GL_TEXTURE_2D, - }; - mpgl_lock(p->glctx); - if (hwdec->driver->create(hwdec) < 0) { - mpgl_unlock(p->glctx); - talloc_free(hwdec); - MP_ERR(p->vo, "Couldn't load hwdec driver '%s'\n", drv->api_name); - return; - } - p->hwdec = hwdec; - gl_video_set_hwdec(p->renderer, p->hwdec); - mpgl_unlock(p->glctx); -} - static void request_hwdec_api(struct gl_priv *p, const char *api_name) { - // Load at most one hwdec API if (p->hwdec) return; - for (int n = 0; mpgl_hwdec_drivers[n]; n++) { - const struct gl_hwdec_driver *drv = mpgl_hwdec_drivers[n]; - if (api_name && strcmp(drv->api_name, api_name) == 0) { - load_hwdec_driver(p, drv); - if (p->hwdec) - return; - } - } + mpgl_lock(p->glctx); + p->hwdec = gl_hwdec_load_api(p->vo->log, p->gl, api_name, &p->hwdec_info); + gl_video_set_hwdec(p->renderer, p->hwdec); + mpgl_unlock(p->glctx); } static void call_request_hwdec_api(struct mp_hwdec_info *info, @@ -268,18 +240,6 @@ static void call_request_hwdec_api(struct mp_hwdec_info *info, vo_control(vo, VOCTRL_LOAD_HWDEC_API, (void *)api_name); } -static void unload_hwdec_driver(struct gl_priv *p) -{ - if (p->hwdec) { - mpgl_lock(p->glctx); - gl_video_set_hwdec(p->renderer, NULL); - p->hwdec->driver->destroy(p->hwdec); - talloc_free(p->hwdec); - p->hwdec = NULL; - mpgl_unlock(p->glctx); - } -} - static bool update_icc_profile(struct gl_priv *p, struct mp_icc_opts *opts) { struct lut3d *lut3d = NULL; @@ -433,9 +393,9 @@ static void uninit(struct vo *vo) struct gl_priv *p = vo->priv; if (p->glctx) { - unload_hwdec_driver(p); if (p->renderer) gl_video_uninit(p->renderer); + gl_hwdec_uninit(p->hwdec); mpgl_uninit(p->glctx); } } |