summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--old-makefile1
-rw-r--r--video/out/gl_common.c17
-rw-r--r--video/out/gl_common.h45
-rw-r--r--video/out/gl_hwdec.c90
-rw-r--r--video/out/gl_hwdec.h56
-rw-r--r--video/out/gl_hwdec_vaglx.c5
-rw-r--r--video/out/gl_hwdec_vda.c2
-rw-r--r--video/out/gl_hwdec_vdpau.c5
-rw-r--r--video/out/gl_video.c1
-rw-r--r--video/out/vo_opengl.c52
-rw-r--r--wscript_build.py1
11 files changed, 162 insertions, 113 deletions
diff --git a/old-makefile b/old-makefile
index 7408b3c089..764df273a7 100644
--- a/old-makefile
+++ b/old-makefile
@@ -63,6 +63,7 @@ SOURCES-$(SDL2) += audio/out/ao_sdl.c video/out/vo_sdl.c
SOURCES-$(GL) += video/out/gl_common.c video/out/gl_osd.c \
video/out/vo_opengl.c video/out/gl_lcms.c \
video/out/gl_video.c video/out/dither.c \
+ video/out/gl_hwdec.c \
video/out/vo_opengl_old.c \
video/out/pnm_loader.c
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);
}
}
diff --git a/wscript_build.py b/wscript_build.py
index 169f9f5059..428c626f2b 100644
--- a/wscript_build.py
+++ b/wscript_build.py
@@ -336,6 +336,7 @@ def build(ctx):
( "video/out/filter_kernels.c" ),
( "video/out/gl_cocoa.c", "gl-cocoa" ),
( "video/out/gl_common.c", "gl" ),
+ ( "video/out/gl_hwdec.c", "gl" ),
( "video/out/gl_hwdec_vaglx.c", "vaapi-glx" ),
( "video/out/gl_hwdec_vda.c", "vda-gl" ),
( "video/out/gl_hwdec_vdpau.c", "vdpau-gl-x11" ),