diff options
Diffstat (limited to 'video/out/vo.c')
-rw-r--r-- | video/out/vo.c | 51 |
1 files changed, 36 insertions, 15 deletions
diff --git a/video/out/vo.c b/video/out/vo.c index aa92d349e5..139b840c23 100644 --- a/video/out/vo.c +++ b/video/out/vo.c @@ -297,12 +297,17 @@ autoprobe: return NULL; } +static void terminate_vo(void *p) +{ + struct vo *vo = p; + struct vo_internal *in = vo->in; + in->terminate = true; +} + void vo_destroy(struct vo *vo) { struct vo_internal *in = vo->in; - mp_dispatch_lock(in->dispatch); - vo->in->terminate = true; - mp_dispatch_unlock(in->dispatch); + mp_dispatch_run(in->dispatch, terminate_vo, vo); pthread_join(vo->in->thread, NULL); dealloc_vo(vo); } @@ -339,9 +344,7 @@ static void check_estimated_display_fps(struct vo *vo) struct vo_internal *in = vo->in; bool use_estimated = false; - if (in->num_total_vsync_samples >= MAX_VSYNC_SAMPLES * 2 && - fabs((in->nominal_vsync_interval - in->estimated_vsync_interval)) - >= 0.01 * in->nominal_vsync_interval && + if (in->num_total_vsync_samples >= MAX_VSYNC_SAMPLES / 2 && in->estimated_vsync_interval <= 1e6 / 20.0 && in->estimated_vsync_interval >= 1e6 / 99.0) { @@ -358,12 +361,11 @@ static void check_estimated_display_fps(struct vo *vo) } if (use_estimated == (in->vsync_interval == in->nominal_vsync_interval)) { if (use_estimated) { - MP_WARN(vo, "Reported display FPS seems incorrect.\n" - "Assuming a value closer to %.3f Hz.\n", - 1e6 / in->estimated_vsync_interval); + MP_VERBOSE(vo, "adjusting display FPS to a value closer to %.3f Hz\n", + 1e6 / in->estimated_vsync_interval); } else { - MP_WARN(vo, "Switching back to assuming %.3f Hz.\n", - 1e6 / in->nominal_vsync_interval); + MP_VERBOSE(vo, "switching back to assuming display fps = %.3f Hz\n", + 1e6 / in->nominal_vsync_interval); } } in->vsync_interval = use_estimated ? (int64_t)in->estimated_vsync_interval @@ -537,20 +539,39 @@ static void run_control(void *p) { void **pp = p; struct vo *vo = pp[0]; - uint32_t request = *(int *)pp[1]; + int request = (intptr_t)pp[1]; void *data = pp[2]; int ret = vo->driver->control(vo, request, data); - *(int *)pp[3] = ret; + if (pp[3]) + *(int *)pp[3] = ret; } -int vo_control(struct vo *vo, uint32_t request, void *data) +int vo_control(struct vo *vo, int request, void *data) { int ret; - void *p[] = {vo, &request, data, &ret}; + void *p[] = {vo, (void *)(intptr_t)request, data, &ret}; mp_dispatch_run(vo->in->dispatch, run_control, p); return ret; } +// Run vo_control() without waiting for a reply. +// (Only works for some VOCTRLs.) +void vo_control_async(struct vo *vo, int request, void *data) +{ + void *p[4] = {vo, (void *)(intptr_t)request, NULL, NULL}; + void **d = talloc_memdup(NULL, p, sizeof(p)); + + switch (request) { + case VOCTRL_UPDATE_PLAYBACK_STATE: + d[2] = ta_xdup_ptrtype(d, (struct voctrl_playback_state *)data); + break; + default: + abort(); // requires explicit support + } + + mp_dispatch_enqueue_autofree(vo->in->dispatch, run_control, d); +} + // must be called locked static void forget_frames(struct vo *vo) { |