diff options
Diffstat (limited to 'player')
-rw-r--r-- | player/client.c | 164 | ||||
-rw-r--r-- | player/client.h | 19 | ||||
-rw-r--r-- | player/core.h | 2 | ||||
-rw-r--r-- | player/main.c | 3 | ||||
-rw-r--r-- | player/playloop.c | 1 | ||||
-rw-r--r-- | player/video.c | 1 |
6 files changed, 155 insertions, 35 deletions
diff --git a/player/client.c b/player/client.c index 1df7e659d8..45af55bee9 100644 --- a/player/client.c +++ b/player/client.c @@ -20,6 +20,7 @@ #include <fcntl.h> #include <errno.h> #include <locale.h> +#include <math.h> #include <assert.h> #include "common/common.h" @@ -46,8 +47,6 @@ #include "core.h" #include "client.h" -#include "config.h" - /* * Locking hierarchy: * @@ -74,6 +73,9 @@ struct mp_client_api { struct mp_custom_protocol *custom_protocols; int num_custom_protocols; + + struct mpv_render_context *render_context; + struct mpv_opengl_cb_context *gl_cb_ctx; }; struct observe_property { @@ -156,6 +158,16 @@ void mp_clients_destroy(struct MPContext *mpctx) if (!mpctx->clients) return; assert(mpctx->clients->num_clients == 0); + + TA_FREEP(&mpctx->clients->gl_cb_ctx); + + // The API user is supposed to call mpv_render_context_free(). It's simply + // not allowed not to do this. + if (mpctx->clients->render_context) { + MP_FATAL(mpctx, "Broken API use: mpv_render_context_free() not called.\n"); + abort(); + } + pthread_mutex_destroy(&mpctx->clients->lock); talloc_free(mpctx->clients); mpctx->clients = NULL; @@ -279,6 +291,11 @@ struct mp_log *mp_client_get_log(struct mpv_handle *ctx) return ctx->log; } +struct mpv_global *mp_client_get_global(struct mpv_handle *ctx) +{ + return ctx->mpctx->global; +} + struct MPContext *mp_client_get_core(struct mpv_handle *ctx) { return ctx->mpctx; @@ -1672,7 +1689,9 @@ int64_t mpv_get_time_us(mpv_handle *ctx) return mp_time_us(); } -// Used by vo_opengl_cb to synchronously uninitialize video. +#include "video/out/libmpv.h" + +// Used by vo_libmpv to synchronously uninitialize video. void kill_video(struct mp_client_api *client_api) { struct MPContext *mpctx = client_api->mpctx; @@ -1686,58 +1705,163 @@ void kill_video(struct mp_client_api *client_api) mp_dispatch_unlock(mpctx->dispatch); } +// Used by vo_libmpv to set the current render context. +bool mp_set_main_render_context(struct mp_client_api *client_api, + struct mpv_render_context *ctx, bool active) +{ + assert(ctx); + + pthread_mutex_lock(&client_api->lock); + bool is_set = !!client_api->render_context; + bool is_same = client_api->render_context == ctx; + // Can set if it doesn't remove another existing ctx. + bool res = is_same || !is_set; + if (res) + client_api->render_context = active ? ctx : NULL; + pthread_mutex_unlock(&client_api->lock); + return res; +} + +// Used by vo_libmpv. Relies on guarantees by mp_render_context_acquire(). +struct mpv_render_context * +mp_client_api_acquire_render_context(struct mp_client_api *ca) +{ + struct mpv_render_context *res = NULL; + pthread_mutex_lock(&ca->lock); + if (ca->render_context && mp_render_context_acquire(ca->render_context)) + res = ca->render_context; + pthread_mutex_unlock(&ca->lock); + return res; +} + +// Emulation of old opengl_cb API. + #include "libmpv/opengl_cb.h" +#include "libmpv/render_gl.h" + +struct mpv_opengl_cb_context { + struct mp_client_api *client_api; + mpv_opengl_cb_update_fn callback; + void *callback_ctx; +}; -#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; + pthread_mutex_lock(&ctx->clients->lock); + mpv_opengl_cb_context *cb = ctx->clients->gl_cb_ctx; if (!cb) { - cb = mp_opengl_create(ctx->mpctx->global, ctx->clients); - ctx->mpctx->gl_cb_ctx = cb; + cb = talloc_zero(NULL, struct mpv_opengl_cb_context); + cb->client_api = ctx->clients; + cb->client_api->gl_cb_ctx = cb; } + pthread_mutex_unlock(&ctx->clients->lock); 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) { + // This was probably supposed to be thread-safe, but we don't care. It's + // compatibility code, and if you have problems, use the new API. + if (ctx->client_api->render_context) { + mpv_render_context_set_update_callback(ctx->client_api->render_context, + callback, callback_ctx); + } + // Nasty thing: could set this even while not initialized, so we need to + // preserve it. + ctx->callback = callback; + ctx->callback_ctx = callback_ctx; } + 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; + if (ctx->client_api->render_context) + return MPV_ERROR_INVALID_PARAMETER; + + // mpv_render_context_create() only calls mp_client_get_global() on it. + mpv_handle dummy = {.mpctx = ctx->client_api->mpctx}; + + mpv_render_param params[] = { + {MPV_RENDER_PARAM_API_TYPE, MPV_RENDER_API_TYPE_OPENGL}, + {MPV_RENDER_PARAM_OPENGL_INIT_PARAMS, &(mpv_opengl_init_params){ + .get_proc_address = get_proc_address, + .get_proc_address_ctx = get_proc_address_ctx, + .extra_exts = exts, + }}, + {0} + }; + int err = mpv_render_context_create(&ctx->client_api->render_context, + &dummy, params); + if (err >= 0) { + mpv_render_context_set_update_callback(ctx->client_api->render_context, + ctx->callback, ctx->callback_ctx); + } + return err; } + int mpv_opengl_cb_draw(mpv_opengl_cb_context *ctx, int fbo, int w, int h) { - return MPV_ERROR_NOT_IMPLEMENTED; + if (!ctx->client_api->render_context) + return MPV_ERROR_INVALID_PARAMETER; + + mpv_render_param params[] = { + {MPV_RENDER_PARAM_OPENGL_FBO, &(mpv_opengl_fbo){ + .fbo = fbo, + .w = w, + .h = abs(h), + }}, + {MPV_RENDER_PARAM_FLIP_Y, &(int){h < 0}}, + {0} + }; + return mpv_render_context_render(ctx->client_api->render_context, params); } + int mpv_opengl_cb_report_flip(mpv_opengl_cb_context *ctx, int64_t time) { - return MPV_ERROR_NOT_IMPLEMENTED; + if (!ctx->client_api->render_context) + return MPV_ERROR_INVALID_PARAMETER; + + mpv_render_context_report_swap(ctx->client_api->render_context); + return 0; } + int mpv_opengl_cb_uninit_gl(mpv_opengl_cb_context *ctx) { - return MPV_ERROR_NOT_IMPLEMENTED; + if (ctx->client_api->render_context) + mpv_render_context_free(ctx->client_api->render_context); + ctx->client_api->render_context = NULL; + return 0; } + void mp_client_set_control_callback(struct mpv_opengl_cb_context *ctx, mpv_opengl_cb_control_fn callback, void *callback_ctx) { + if (ctx->client_api->render_context) { + mp_render_context_set_control_callback(ctx->client_api->render_context, + callback, callback_ctx); + } } + void mp_client_set_icc_profile(struct mpv_opengl_cb_context *ctx, bstr icc_data) { + if (!ctx->client_api->render_context) + return; + mpv_render_param param = {MPV_RENDER_PARAM_ICC_PROFILE, + &(mpv_byte_array){icc_data.start, icc_data.len}}; + mpv_render_context_set_parameter(ctx->client_api->render_context, param); } + void mp_client_set_ambient_lux(struct mpv_opengl_cb_context *ctx, int lux) { + if (!ctx->client_api->render_context) + return; + mpv_render_param param = {MPV_RENDER_PARAM_AMBIENT_LIGHT, &(int){lux}}; + mpv_render_context_set_parameter(ctx->client_api->render_context, param); } -#endif int mpv_opengl_cb_render(mpv_opengl_cb_context *ctx, int fbo, int vp[4]) { @@ -1749,16 +1873,12 @@ void *mp_get_sub_api2(mpv_handle *ctx, mpv_sub_api sub_api, bool lock) if (!ctx->mpctx->initialized) return NULL; void *res = NULL; - if (lock) - lock_core(ctx); switch (sub_api) { case MPV_SUB_API_OPENGL_CB: res = opengl_cb_get_context(ctx); break; default:; } - if (lock) - unlock_core(ctx); return res; } @@ -1767,6 +1887,8 @@ void *mpv_get_sub_api(mpv_handle *ctx, mpv_sub_api sub_api) return mp_get_sub_api2(ctx, sub_api, true); } +// stream_cb + struct mp_custom_protocol { char *protocol; void *user_data; diff --git a/player/client.h b/player/client.h index 042934cde3..58e84418a2 100644 --- a/player/client.h +++ b/player/client.h @@ -12,6 +12,7 @@ struct MPContext; struct mpv_handle; struct mp_client_api; struct mp_log; +struct mpv_global; // Includes space for \0 #define MAX_CLIENT_NAME 64 @@ -33,6 +34,7 @@ void mp_client_property_change(struct MPContext *mpctx, const char *name); struct mpv_handle *mp_new_client(struct mp_client_api *clients, const char *name); struct mp_log *mp_client_get_log(struct mpv_handle *ctx); +struct mpv_global *mp_client_get_global(struct mpv_handle *ctx); struct MPContext *mp_client_get_core(struct mpv_handle *ctx); struct MPContext *mp_client_api_get_core(struct mp_client_api *api); void *mp_get_sub_api2(mpv_handle *ctx, mpv_sub_api sub_api, bool lock); @@ -40,19 +42,22 @@ void *mp_get_sub_api2(mpv_handle *ctx, mpv_sub_api sub_api, bool lock); // m_option.c void *node_get_alloc(struct mpv_node *node); -// vo_opengl_cb.c -struct mpv_opengl_cb_context; -struct mpv_global; +// for vo_libmpv.c struct osd_state; -struct mpv_opengl_cb_context *mp_opengl_create(struct mpv_global *g, - struct mp_client_api *client_api); +struct mpv_render_context; +bool mp_set_main_render_context(struct mp_client_api *client_api, + struct mpv_render_context *ctx, bool active); +struct mpv_render_context * +mp_client_api_acquire_render_context(struct mp_client_api *ca); void kill_video(struct mp_client_api *client_api); bool mp_streamcb_lookup(struct mpv_global *g, const char *protocol, void **out_user_data, mpv_stream_cb_open_ro_fn *out_fn); -typedef int (*mpv_opengl_cb_control_fn)(void *cb_ctx, int *events, uint32_t request, void *data); - +// Legacy. +typedef int (*mpv_opengl_cb_control_fn)(void *cb_ctx, int *events, + uint32_t request, void *data); +struct mpv_opengl_cb_context; void mp_client_set_control_callback(struct mpv_opengl_cb_context *ctx, mpv_opengl_cb_control_fn callback, void *callback_ctx); diff --git a/player/core.h b/player/core.h index 27696e8f06..bfc5f662a4 100644 --- a/player/core.h +++ b/player/core.h @@ -433,8 +433,6 @@ typedef struct MPContext { struct mp_ipc_ctx *ipc_ctx; - struct mpv_opengl_cb_context *gl_cb_ctx; - pthread_mutex_t lock; // --- The following fields are protected by lock diff --git a/player/main.c b/player/main.c index 711b413735..243eae605f 100644 --- a/player/main.c +++ b/player/main.c @@ -183,9 +183,6 @@ void mp_destroy(struct MPContext *mpctx) mp_clients_destroy(mpctx); - talloc_free(mpctx->gl_cb_ctx); - mpctx->gl_cb_ctx = NULL; - osd_free(mpctx->osd); #if HAVE_COCOA diff --git a/player/playloop.c b/player/playloop.c index e77200f2d7..852fc7c199 100644 --- a/player/playloop.c +++ b/player/playloop.c @@ -891,7 +891,6 @@ int handle_force_window(struct MPContext *mpctx, bool force) .input_ctx = mpctx->input, .osd = mpctx->osd, .encode_lavc_ctx = mpctx->encode_lavc_ctx, - .opengl_cb_context = mpctx->gl_cb_ctx, .wakeup_cb = mp_wakeup_core_cb, .wakeup_ctx = mpctx, }; diff --git a/player/video.c b/player/video.c index e0919a7c5e..e03ada4863 100644 --- a/player/video.c +++ b/player/video.c @@ -222,7 +222,6 @@ void reinit_video_chain_src(struct MPContext *mpctx, struct track *track) .input_ctx = mpctx->input, .osd = mpctx->osd, .encode_lavc_ctx = mpctx->encode_lavc_ctx, - .opengl_cb_context = mpctx->gl_cb_ctx, .wakeup_cb = mp_wakeup_core_cb, .wakeup_ctx = mpctx, }; |