summaryrefslogtreecommitdiffstats
path: root/player
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-12-09 17:47:02 +0100
committerwm4 <wm4@nowhere>2014-12-09 17:59:04 +0100
commitfb855b86593ad2a9db71cce3aa652ace93af38b5 (patch)
treeffca8eb74c8cf58dc5e97e0fac2c519b958b7cf7 /player
parentd38bc531cc7ce9c90b74145e2be2e24cb48e501a (diff)
downloadmpv-fb855b86593ad2a9db71cce3aa652ace93af38b5.tar.bz2
mpv-fb855b86593ad2a9db71cce3aa652ace93af38b5.tar.xz
client API: expose OpenGL renderer
This adds API to libmpv that lets host applications use the mpv opengl renderer. This is a more flexible (and possibly more portable) option to foreign window embedding (via --wid). This assumes that methods like context sharing and multithreaded OpenGL rendering are infeasible, and that a way is needed to integrate it with an application that uses a single thread to render everything. Add an example that does this with QtQuick/qml. The example is relatively lazy, but still shows how relatively simple the integration is. The FBO indirection could probably be avoided, but would require more work (and would probably lead to worse QtQuick integration, because it would have to ignore transformations like rotation). Because this makes mpv directly use the host application's OpenGL context, there is no platform specific code involved in mpv, except for hw decoding interop. main.qml is derived from some Qt example. The following things are still missing: - a way to do better video timing - expose GL renderer options, allow changing them at runtime - support for color equalizer controls - support for screenshots
Diffstat (limited to 'player')
-rw-r--r--player/client.c57
-rw-r--r--player/client.h7
-rw-r--r--player/core.h2
-rw-r--r--player/video.c3
4 files changed, 69 insertions, 0 deletions
diff --git a/player/client.c b/player/client.c
index d86217106e..a46a37b10a 100644
--- a/player/client.c
+++ b/player/client.c
@@ -1511,6 +1511,8 @@ static const char *const err_table[] = {
[-MPV_ERROR_VO_INIT_FAILED] = "audio output initialization failed",
[-MPV_ERROR_NOTHING_TO_PLAY] = "the file has no audio or video data",
[-MPV_ERROR_UNKNOWN_FORMAT] = "unrecognized file format",
+ [-MPV_ERROR_UNSUPPORTED] = "not supported",
+ [-MPV_ERROR_NOT_IMPLEMENTED] = "operation not implemented",
};
const char *mpv_error_string(int error)
@@ -1567,3 +1569,58 @@ int64_t mpv_get_time_us(mpv_handle *ctx)
{
return mp_time_us();
}
+
+#include "libmpv/opengl_cb.h"
+
+#if HAVE_GL
+static mpv_opengl_cb_context *opengl_cb_get_context(mpv_handle *ctx)
+{
+ mpv_opengl_cb_context *cb = ctx->mpctx->gl_cb_ctx;
+ if (!cb) {
+ cb = mp_opengl_create(ctx->mpctx->global, ctx->mpctx->osd);
+ ctx->mpctx->gl_cb_ctx = cb;
+ }
+ return cb;
+}
+#else
+static mpv_opengl_cb_context *opengl_cb_get_context(mpv_handle *ctx)
+{
+ return NULL;
+}
+void mpv_opengl_cb_set_update_callback(mpv_opengl_cb_context *ctx,
+ mpv_opengl_cb_update_fn callback,
+ void *callback_ctx)
+{
+ return MPV_ERROR_NOT_IMPLEMENTED;
+}
+int mpv_opengl_cb_init_gl(mpv_opengl_cb_context *ctx, const char *exts,
+ mpv_opengl_cb_get_proc_address_fn get_proc_address,
+ void *get_proc_address_ctx)
+{
+ return MPV_ERROR_NOT_IMPLEMENTED;
+}
+int mpv_opengl_cb_render(mpv_opengl_cb_context *ctx, int fbo, int vp[4])
+{
+ return MPV_ERROR_NOT_IMPLEMENTED;
+}
+int mpv_opengl_cb_uninit_gl(mpv_opengl_cb_context *ctx)
+{
+ return MPV_ERROR_NOT_IMPLEMENTED;
+}
+#endif
+
+void *mpv_get_sub_api(mpv_handle *ctx, mpv_sub_api sub_api)
+{
+ if (!ctx->mpctx->initialized)
+ return NULL;
+ void *res = NULL;
+ lock_core(ctx);
+ switch (sub_api) {
+ case MPV_SUB_API_OPENGL_CB:
+ res = opengl_cb_get_context(ctx);
+ break;
+ default:;
+ }
+ unlock_core(ctx);
+ return res;
+}
diff --git a/player/client.h b/player/client.h
index a275bb9728..4e116b3bca 100644
--- a/player/client.h
+++ b/player/client.h
@@ -35,4 +35,11 @@ struct MPContext *mp_client_get_core(struct mpv_handle *ctx);
// m_option.c
void *node_get_alloc(struct mpv_node *node);
+// vo_opengl_cb.c
+struct mpv_opengl_cb_context;
+struct mpv_global;
+struct osd_state;
+struct mpv_opengl_cb_context *mp_opengl_create(struct mpv_global *g,
+ struct osd_state *osd);
+
#endif
diff --git a/player/core.h b/player/core.h
index 31a2b1eca4..344e55df19 100644
--- a/player/core.h
+++ b/player/core.h
@@ -339,6 +339,8 @@ typedef struct MPContext {
struct mp_nav_state *nav_state;
struct mp_ipc_ctx *ipc_ctx;
+
+ struct mpv_opengl_cb_context *gl_cb_ctx;
} MPContext;
// audio.c
diff --git a/player/video.c b/player/video.c
index f0829a2c8d..a14b647872 100644
--- a/player/video.c
+++ b/player/video.c
@@ -275,6 +275,9 @@ int reinit_video_chain(struct MPContext *mpctx)
goto err_out;
}
mpctx->mouse_cursor_visible = true;
+
+ vo_control(mpctx->video_out, VOCTRL_SET_LIBMPV_OPENGL_CB_CONTEXT,
+ mpctx->gl_cb_ctx);
}
update_window_title(mpctx, true);