diff options
Diffstat (limited to 'video/out/vo_libmpv.c')
-rw-r--r-- | video/out/vo_libmpv.c | 168 |
1 files changed, 87 insertions, 81 deletions
diff --git a/video/out/vo_libmpv.c b/video/out/vo_libmpv.c index d07ab4c4eb..7974eed3f7 100644 --- a/video/out/vo_libmpv.c +++ b/video/out/vo_libmpv.c @@ -1,13 +1,11 @@ +#include <assert.h> +#include <limits.h> +#include <math.h> +#include <stdatomic.h> +#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <math.h> -#include <stdbool.h> -#include <limits.h> -#include <pthread.h> -#include <assert.h> - -#include "config.h" #include "mpv_talloc.h" #include "common/common.h" @@ -21,7 +19,7 @@ #include "vo.h" #include "video/mp_image.h" #include "sub/osd.h" -#include "osdep/atomic.h" +#include "osdep/threads.h" #include "osdep/timer.h" #include "common/global.h" @@ -29,6 +27,10 @@ #include "libmpv.h" +#if HAVE_MACOS_COCOA_CB +#include "osdep/mac/app_bridge.h" +#endif + /* * mpv_render_context is managed by the host application - the host application * can access it any time, even if the VO is destroyed (or not created yet). @@ -67,20 +69,20 @@ struct mpv_render_context { bool advanced_control; struct dr_helper *dr; // NULL if advanced_control disabled - pthread_mutex_t control_lock; + mp_mutex control_lock; // --- Protected by control_lock mp_render_cb_control_fn control_cb; void *control_cb_ctx; - pthread_mutex_t update_lock; - pthread_cond_t update_cond; // paired with update_lock + mp_mutex update_lock; + mp_cond update_cond; // paired with update_lock // --- Protected by update_lock mpv_render_update_fn update_cb; void *update_cb_ctx; - pthread_mutex_t lock; - pthread_cond_t video_wait; // paired with lock + mp_mutex lock; + mp_cond video_wait; // paired with lock // --- Protected by lock struct vo_frame *next_frame; // next frame to draw @@ -117,12 +119,12 @@ const struct render_backend_fns *render_backends[] = { static void update(struct mpv_render_context *ctx) { - pthread_mutex_lock(&ctx->update_lock); + mp_mutex_lock(&ctx->update_lock); if (ctx->update_cb) ctx->update_cb(ctx->update_cb_ctx); - pthread_cond_broadcast(&ctx->update_cond); - pthread_mutex_unlock(&ctx->update_lock); + mp_cond_broadcast(&ctx->update_cond); + mp_mutex_unlock(&ctx->update_lock); } void *get_mpv_render_param(mpv_render_param *params, mpv_render_param_type type, @@ -137,7 +139,7 @@ void *get_mpv_render_param(mpv_render_param *params, mpv_render_param_type type, static void forget_frames(struct mpv_render_context *ctx, bool all) { - pthread_cond_broadcast(&ctx->video_wait); + mp_cond_broadcast(&ctx->video_wait); if (all) { talloc_free(ctx->cur_frame); ctx->cur_frame = NULL; @@ -152,22 +154,22 @@ static void dispatch_wakeup(void *ptr) } static struct mp_image *render_get_image(void *ptr, int imgfmt, int w, int h, - int stride_align) + int stride_align, int flags) { struct mpv_render_context *ctx = ptr; - return ctx->renderer->fns->get_image(ctx->renderer, imgfmt, w, h, stride_align); + return ctx->renderer->fns->get_image(ctx->renderer, imgfmt, w, h, stride_align, flags); } int mpv_render_context_create(mpv_render_context **res, mpv_handle *mpv, mpv_render_param *params) { mpv_render_context *ctx = talloc_zero(NULL, mpv_render_context); - pthread_mutex_init(&ctx->control_lock, NULL); - pthread_mutex_init(&ctx->lock, NULL); - pthread_mutex_init(&ctx->update_lock, NULL); - pthread_cond_init(&ctx->update_cond, NULL); - pthread_cond_init(&ctx->video_wait, NULL); + mp_mutex_init(&ctx->control_lock); + mp_mutex_init(&ctx->lock); + mp_mutex_init(&ctx->update_lock); + mp_cond_init(&ctx->update_cond); + mp_cond_init(&ctx->video_wait); ctx->global = mp_client_get_global(mpv); ctx->client_api = ctx->global->client_api; @@ -229,22 +231,22 @@ void mpv_render_context_set_update_callback(mpv_render_context *ctx, mpv_render_update_fn callback, void *callback_ctx) { - pthread_mutex_lock(&ctx->update_lock); + mp_mutex_lock(&ctx->update_lock); ctx->update_cb = callback; ctx->update_cb_ctx = callback_ctx; if (ctx->update_cb) ctx->update_cb(ctx->update_cb_ctx); - pthread_mutex_unlock(&ctx->update_lock); + mp_mutex_unlock(&ctx->update_lock); } void mp_render_context_set_control_callback(mpv_render_context *ctx, mp_render_cb_control_fn callback, void *callback_ctx) { - pthread_mutex_lock(&ctx->control_lock); + mp_mutex_lock(&ctx->control_lock); ctx->control_cb = callback; ctx->control_cb_ctx = callback_ctx; - pthread_mutex_unlock(&ctx->control_lock); + mp_mutex_unlock(&ctx->control_lock); } void mpv_render_context_free(mpv_render_context *ctx) @@ -284,13 +286,13 @@ void mpv_render_context_free(mpv_render_context *ctx) } } - pthread_mutex_lock(&ctx->lock); + mp_mutex_lock(&ctx->lock); // Barrier - guarantee uninit() has left the lock region. It will access ctx // until the lock has been released, so we must not proceed with destruction // before we can acquire the lock. (The opposite, uninit() acquiring the // lock, can not happen anymore at this point - we've waited for VO uninit, // and prevented that new VOs can be created.) - pthread_mutex_unlock(&ctx->lock); + mp_mutex_unlock(&ctx->lock); assert(!atomic_load(&ctx->in_use)); assert(!ctx->vo); @@ -313,11 +315,11 @@ void mpv_render_context_free(mpv_render_context *ctx) talloc_free(ctx->dr); talloc_free(ctx->dispatch); - pthread_cond_destroy(&ctx->update_cond); - pthread_cond_destroy(&ctx->video_wait); - pthread_mutex_destroy(&ctx->update_lock); - pthread_mutex_destroy(&ctx->lock); - pthread_mutex_destroy(&ctx->control_lock); + mp_cond_destroy(&ctx->update_cond); + mp_cond_destroy(&ctx->video_wait); + mp_mutex_destroy(&ctx->update_lock); + mp_mutex_destroy(&ctx->lock); + mp_mutex_destroy(&ctx->control_lock); talloc_free(ctx); } @@ -333,7 +335,7 @@ bool mp_render_context_acquire(mpv_render_context *ctx) int mpv_render_context_render(mpv_render_context *ctx, mpv_render_param *params) { - pthread_mutex_lock(&ctx->lock); + mp_mutex_lock(&ctx->lock); int do_render = !GET_MPV_RENDER_PARAM(params, MPV_RENDER_PARAM_SKIP_RENDERING, int, 0); @@ -343,7 +345,7 @@ int mpv_render_context_render(mpv_render_context *ctx, mpv_render_param *params) int err = ctx->renderer->fns->get_target_size(ctx->renderer, params, &vp_w, &vp_h); if (err < 0) { - pthread_mutex_unlock(&ctx->lock); + mp_mutex_unlock(&ctx->lock); return err; } @@ -387,7 +389,7 @@ int mpv_render_context_render(mpv_render_context *ctx, mpv_render_param *params) ctx->next_frame = NULL; if (!(frame->redraw || !frame->current)) wait_present_count += 1; - pthread_cond_broadcast(&ctx->video_wait); + mp_cond_broadcast(&ctx->video_wait); talloc_free(ctx->cur_frame); ctx->cur_frame = vo_frame_ref(frame); } else { @@ -400,7 +402,7 @@ int mpv_render_context_render(mpv_render_context *ctx, mpv_render_param *params) if (!frame) frame = &dummy; - pthread_mutex_unlock(&ctx->lock); + mp_mutex_unlock(&ctx->lock); MP_STATS(ctx, "glcb-render"); @@ -415,10 +417,10 @@ int mpv_render_context_render(mpv_render_context *ctx, mpv_render_param *params) if (GET_MPV_RENDER_PARAM(params, MPV_RENDER_PARAM_BLOCK_FOR_TARGET_TIME, int, 1)) { - pthread_mutex_lock(&ctx->lock); + mp_mutex_lock(&ctx->lock); while (wait_present_count > ctx->present_count) - pthread_cond_wait(&ctx->video_wait, &ctx->lock); - pthread_mutex_unlock(&ctx->lock); + mp_cond_wait(&ctx->video_wait, &ctx->lock); + mp_mutex_unlock(&ctx->lock); } return err; @@ -428,10 +430,10 @@ void mpv_render_context_report_swap(mpv_render_context *ctx) { MP_STATS(ctx, "glcb-reportflip"); - pthread_mutex_lock(&ctx->lock); + mp_mutex_lock(&ctx->lock); ctx->flip_count += 1; - pthread_cond_broadcast(&ctx->video_wait); - pthread_mutex_unlock(&ctx->lock); + mp_cond_broadcast(&ctx->video_wait); + mp_mutex_unlock(&ctx->lock); } uint64_t mpv_render_context_update(mpv_render_context *ctx) @@ -440,10 +442,10 @@ uint64_t mpv_render_context_update(mpv_render_context *ctx) mp_dispatch_queue_process(ctx->dispatch, 0); - pthread_mutex_lock(&ctx->lock); + mp_mutex_lock(&ctx->lock); if (ctx->next_frame) res |= MPV_RENDER_UPDATE_FRAME; - pthread_mutex_unlock(&ctx->lock); + mp_mutex_unlock(&ctx->lock); return res; } @@ -457,7 +459,7 @@ int mpv_render_context_get_info(mpv_render_context *ctx, mpv_render_param param) { int res = MPV_ERROR_NOT_IMPLEMENTED; - pthread_mutex_lock(&ctx->lock); + mp_mutex_lock(&ctx->lock); switch (param.type) { case MPV_RENDER_PARAM_NEXT_FRAME_INFO: { @@ -479,7 +481,7 @@ int mpv_render_context_get_info(mpv_render_context *ctx, default:; } - pthread_mutex_unlock(&ctx->lock); + mp_mutex_unlock(&ctx->lock); return res; } @@ -488,12 +490,12 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) struct vo_priv *p = vo->priv; struct mpv_render_context *ctx = p->ctx; - pthread_mutex_lock(&ctx->lock); + mp_mutex_lock(&ctx->lock); assert(!ctx->next_frame); ctx->next_frame = vo_frame_ref(frame); ctx->expected_flip_count = ctx->flip_count + 1; ctx->redrawing = frame->redraw || !frame->current; - pthread_mutex_unlock(&ctx->lock); + mp_mutex_unlock(&ctx->lock); update(ctx); } @@ -502,13 +504,13 @@ static void flip_page(struct vo *vo) { struct vo_priv *p = vo->priv; struct mpv_render_context *ctx = p->ctx; - struct timespec ts = mp_rel_time_to_timespec(0.2); + int64_t until = mp_time_ns() + MP_TIME_MS_TO_NS(200); - pthread_mutex_lock(&ctx->lock); + mp_mutex_lock(&ctx->lock); // Wait until frame was rendered while (ctx->next_frame) { - if (pthread_cond_timedwait(&ctx->video_wait, &ctx->lock, &ts)) { + if (mp_cond_timedwait_until(&ctx->video_wait, &ctx->lock, until)) { if (ctx->next_frame) { MP_VERBOSE(vo, "mpv_render_context_render() not being called " "or stuck.\n"); @@ -519,7 +521,7 @@ static void flip_page(struct vo *vo) // Unblock mpv_render_context_render(). ctx->present_count += 1; - pthread_cond_broadcast(&ctx->video_wait); + mp_cond_broadcast(&ctx->video_wait); if (ctx->redrawing) goto done; // do not block for redrawing @@ -530,7 +532,7 @@ static void flip_page(struct vo *vo) // Assume the user calls it consistently _if_ it's called at all. if (!ctx->flip_count) break; - if (pthread_cond_timedwait(&ctx->video_wait, &ctx->lock, &ts)) { + if (mp_cond_timedwait_until(&ctx->video_wait, &ctx->lock, until)) { MP_VERBOSE(vo, "mpv_render_report_swap() not being called.\n"); goto done; } @@ -544,11 +546,11 @@ done: ctx->cur_frame = ctx->next_frame; ctx->next_frame = NULL; ctx->present_count += 2; - pthread_cond_signal(&ctx->video_wait); + mp_cond_signal(&ctx->video_wait); vo_increment_drop_count(vo, 1); } - pthread_mutex_unlock(&ctx->lock); + mp_mutex_unlock(&ctx->lock); } static int query_format(struct vo *vo, int format) @@ -557,10 +559,10 @@ static int query_format(struct vo *vo, int format) struct mpv_render_context *ctx = p->ctx; bool ok = false; - pthread_mutex_lock(&ctx->lock); + mp_mutex_lock(&ctx->lock); if (format >= IMGFMT_START && format < IMGFMT_END) ok = ctx->imgfmt_supported[format - IMGFMT_START]; - pthread_mutex_unlock(&ctx->lock); + mp_mutex_unlock(&ctx->lock); return ok; } @@ -574,9 +576,9 @@ static void run_control_on_render_thread(void *p) switch (request) { case VOCTRL_SCREENSHOT: { - pthread_mutex_lock(&ctx->lock); + mp_mutex_lock(&ctx->lock); struct vo_frame *frame = vo_frame_ref(ctx->cur_frame); - pthread_mutex_unlock(&ctx->lock); + mp_mutex_unlock(&ctx->lock); if (frame && ctx->renderer->fns->screenshot) ctx->renderer->fns->screenshot(ctx->renderer, frame, data); talloc_free(frame); @@ -601,28 +603,25 @@ static int control(struct vo *vo, uint32_t request, void *data) switch (request) { case VOCTRL_RESET: - pthread_mutex_lock(&ctx->lock); + mp_mutex_lock(&ctx->lock); forget_frames(ctx, false); ctx->need_reset = true; - pthread_mutex_unlock(&ctx->lock); + mp_mutex_unlock(&ctx->lock); vo->want_redraw = true; return VO_TRUE; case VOCTRL_PAUSE: vo->want_redraw = true; return VO_TRUE; - case VOCTRL_SET_EQUALIZER: - vo->want_redraw = true; - return VO_TRUE; case VOCTRL_SET_PANSCAN: - pthread_mutex_lock(&ctx->lock); + mp_mutex_lock(&ctx->lock); ctx->need_resize = true; - pthread_mutex_unlock(&ctx->lock); + mp_mutex_unlock(&ctx->lock); vo->want_redraw = true; return VO_TRUE; case VOCTRL_UPDATE_RENDER_OPTS: - pthread_mutex_lock(&ctx->lock); + mp_mutex_lock(&ctx->lock); ctx->need_update_external = true; - pthread_mutex_unlock(&ctx->lock); + mp_mutex_unlock(&ctx->lock); vo->want_redraw = true; return VO_TRUE; } @@ -641,26 +640,26 @@ static int control(struct vo *vo, uint32_t request, void *data) } int r = VO_NOTIMPL; - pthread_mutex_lock(&ctx->control_lock); + mp_mutex_lock(&ctx->control_lock); if (ctx->control_cb) { int events = 0; r = p->ctx->control_cb(vo, p->ctx->control_cb_ctx, &events, request, data); vo_event(vo, events); } - pthread_mutex_unlock(&ctx->control_lock); + mp_mutex_unlock(&ctx->control_lock); return r; } static struct mp_image *get_image(struct vo *vo, int imgfmt, int w, int h, - int stride_align) + int stride_align, int flags) { struct vo_priv *p = vo->priv; struct mpv_render_context *ctx = p->ctx; if (ctx->dr) - return dr_helper_get_image(ctx->dr, imgfmt, w, h, stride_align); + return dr_helper_get_image(ctx->dr, imgfmt, w, h, stride_align, flags); return NULL; } @@ -670,12 +669,12 @@ static int reconfig(struct vo *vo, struct mp_image_params *params) struct vo_priv *p = vo->priv; struct mpv_render_context *ctx = p->ctx; - pthread_mutex_lock(&ctx->lock); + mp_mutex_lock(&ctx->lock); forget_frames(ctx, true); ctx->img_params = *params; ctx->need_reconfig = true; ctx->need_resize = true; - pthread_mutex_unlock(&ctx->lock); + mp_mutex_unlock(&ctx->lock); control(vo, VOCTRL_RECONFIG, NULL); @@ -689,7 +688,7 @@ static void uninit(struct vo *vo) control(vo, VOCTRL_UNINIT, NULL); - pthread_mutex_lock(&ctx->lock); + mp_mutex_lock(&ctx->lock); forget_frames(ctx, true); ctx->img_params = (struct mp_image_params){0}; @@ -705,11 +704,18 @@ static void uninit(struct vo *vo) assert(prev_in_use); // obviously must have been set mp_dispatch_interrupt(ctx->dispatch); - pthread_mutex_unlock(&ctx->lock); + mp_mutex_unlock(&ctx->lock); } static int preinit(struct vo *vo) { +#if HAVE_MACOS_COCOA_CB + cocoa_init_cocoa_cb(); +#else + if (vo->probing) + return -1; +#endif + struct vo_priv *p = vo->priv; struct mpv_render_context *ctx = @@ -722,11 +728,11 @@ static int preinit(struct vo *vo) return -1; } - pthread_mutex_lock(&ctx->lock); + mp_mutex_lock(&ctx->lock); ctx->vo = vo; ctx->need_resize = true; ctx->need_update_external = true; - pthread_mutex_unlock(&ctx->lock); + mp_mutex_unlock(&ctx->lock); vo->hwdec_devs = ctx->hwdec_devs; control(vo, VOCTRL_PREINIT, NULL); |