summaryrefslogtreecommitdiffstats
path: root/video/out/vo.c
diff options
context:
space:
mode:
Diffstat (limited to 'video/out/vo.c')
-rw-r--r--video/out/vo.c51
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)
{