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.c54
1 files changed, 51 insertions, 3 deletions
diff --git a/video/out/vo.c b/video/out/vo.c
index f195568eaa..8e63be75e6 100644
--- a/video/out/vo.c
+++ b/video/out/vo.c
@@ -134,6 +134,8 @@ struct vo_internal {
int64_t nominal_vsync_interval;
+ bool external_renderloop_drive;
+
int64_t vsync_interval;
int64_t *vsync_samples;
int num_vsync_samples;
@@ -788,11 +790,12 @@ static void wait_until(struct vo *vo, int64_t target)
pthread_mutex_unlock(&in->lock);
}
-static bool render_frame(struct vo *vo)
+bool vo_render_frame_external(struct vo *vo)
{
struct vo_internal *in = vo->in;
struct vo_frame *frame = NULL;
bool got_frame = false;
+ bool flipped = false;
update_display_fps(vo);
@@ -854,6 +857,7 @@ static bool render_frame(struct vo *vo)
if (in->dropped_frame) {
in->drop_count += 1;
} else {
+ flipped = true;
in->rendering = true;
in->hasframe_rendered = true;
int64_t prev_drop_count = vo->in->drop_count;
@@ -904,6 +908,8 @@ static bool render_frame(struct vo *vo)
done:
talloc_free(frame);
pthread_mutex_unlock(&in->lock);
+ if (in->external_renderloop_drive)
+ return flipped;
return got_frame || (in->frame_queued && in->frame_queued->display_synced);
}
@@ -946,6 +952,44 @@ static void do_redraw(struct vo *vo)
talloc_free(frame);
}
+static void drop_unrendered_frame(struct vo *vo)
+{
+ struct vo_internal *in = vo->in;
+
+ pthread_mutex_lock(&in->lock);
+
+ if (!in->frame_queued)
+ goto end;
+
+ if ((in->frame_queued->pts + in->frame_queued->duration) > mp_time_us())
+ goto end;
+
+ MP_VERBOSE(vo, "Dropping unrendered frame (pts %li)\n", in->frame_queued->pts);
+
+ talloc_free(in->frame_queued);
+ in->frame_queued = NULL;
+ in->hasframe = false;
+ pthread_cond_broadcast(&in->wakeup);
+ wakeup_core(vo);
+
+end:
+ pthread_mutex_unlock(&in->lock);
+}
+
+void vo_enable_external_renderloop(struct vo *vo)
+{
+ struct vo_internal *in = vo->in;
+ MP_VERBOSE(vo, "Enabling event driven renderloop!\n");
+ in->external_renderloop_drive = true;
+}
+
+void vo_disable_external_renderloop(struct vo *vo)
+{
+ struct vo_internal *in = vo->in;
+ MP_VERBOSE(vo, "Disabling event driven renderloop!\n");
+ in->external_renderloop_drive = false;
+}
+
static void *vo_thread(void *ptr)
{
struct vo *vo = ptr;
@@ -967,7 +1011,11 @@ static void *vo_thread(void *ptr)
if (in->terminate)
break;
vo->driver->control(vo, VOCTRL_CHECK_EVENTS, NULL);
- bool working = render_frame(vo);
+ bool working = false;
+ if (!in->external_renderloop_drive || !in->hasframe_rendered)
+ working = vo_render_frame_external(vo);
+ else
+ drop_unrendered_frame(vo);
int64_t now = mp_time_us();
int64_t wait_until = now + (working ? 0 : (int64_t)1e9);
@@ -980,7 +1028,7 @@ static void *vo_thread(void *ptr)
wakeup_core(vo);
}
}
- if (vo->want_redraw && !in->want_redraw) {
+ if (vo->want_redraw) {
vo->want_redraw = false;
in->want_redraw = true;
wakeup_core(vo);