summaryrefslogtreecommitdiffstats
path: root/video/out/vo_opengl.c
diff options
context:
space:
mode:
Diffstat (limited to 'video/out/vo_opengl.c')
-rw-r--r--video/out/vo_opengl.c73
1 files changed, 72 insertions, 1 deletions
diff --git a/video/out/vo_opengl.c b/video/out/vo_opengl.c
index cf1b3b3400..8572f587a4 100644
--- a/video/out/vo_opengl.c
+++ b/video/out/vo_opengl.c
@@ -48,6 +48,7 @@
#include "gl_osd.h"
#include "filter_kernels.h"
#include "video/memcpy_pic.h"
+#include "video/decode/dec_video.h"
#include "gl_video.h"
#include "gl_lcms.h"
@@ -58,6 +59,8 @@ struct gl_priv {
struct gl_video *renderer;
+ struct gl_hwdec *hwdec;
+
// Options
struct gl_video_opts *renderer_opts;
struct mp_icc_opts *icc_opts;
@@ -134,8 +137,9 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
static int query_format(struct vo *vo, uint32_t format)
{
+ struct gl_priv *p = vo->priv;
int caps = VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_FLIP;
- if (!gl_video_check_format(format))
+ if (!gl_video_check_format(p->renderer, format))
return 0;
return caps;
}
@@ -191,6 +195,68 @@ 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),
+ .mpgl = p->glctx,
+ .info = talloc_zero(hwdec, struct mp_hwdec_info),
+ };
+ 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 mp_hwdec_info *info, const char *api_name)
+{
+ struct gl_priv *p = info->load_api_ctx;
+ // 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) {
+ *info = *p->hwdec->info;
+ return;
+ }
+ }
+ }
+}
+
+static void get_hwdec_info(struct gl_priv *p, struct mp_hwdec_info *info)
+{
+ info->load_api = request_hwdec_api;
+ info->load_api_ctx = p;
+ if (p->hwdec)
+ *info = *p->hwdec->info;
+}
+
+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 reparse_cmdline(struct gl_priv *p, char *args)
{
struct m_config *cfg = NULL;
@@ -263,6 +329,10 @@ static int control(struct vo *vo, uint32_t request, void *data)
mpgl_unlock(p->glctx);
return true;
}
+ case VOCTRL_GET_HWDEC_INFO: {
+ get_hwdec_info(p, data);
+ return true;
+ }
case VOCTRL_REDRAW_FRAME:
mpgl_lock(p->glctx);
gl_video_render_frame(p->renderer);
@@ -291,6 +361,7 @@ 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);
mpgl_uninit(p->glctx);