summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-05-12 22:30:45 +0200
committerwm4 <wm4@nowhere>2015-05-12 22:30:45 +0200
commit434343d634177f4ca1d245d22107b905fbec0b74 (patch)
treeec54f03990c2354dff11a618ba47be60b0ba994f /video
parent6b7155c05bafa2e3bdf4c4aa0f6372745dc59a1d (diff)
downloadmpv-434343d634177f4ca1d245d22107b905fbec0b74.tar.bz2
mpv-434343d634177f4ca1d245d22107b905fbec0b74.tar.xz
vo: use pthread_cond_timedwait() for video timing
Will be used to make video waiting interruptible with Cocoa (see the following commit). One worry was that this could cause hangs if the system clock jumps backwards. Normally we don't support such behavior, because it's almost impossible to handle it reasonably. E.g. we would have to change the default clock type for condition variables, which in turn would require a custom function for creating condition variables, or so. If the OS even supports different clocks. But it turns out that this is no issue, because other events seem to wakeup the wait call anyway, and mpv internal absolute times use a monotonic clock.
Diffstat (limited to 'video')
-rw-r--r--video/out/vo.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/video/out/vo.c b/video/out/vo.c
index 9f6e44a744..edde793cbf 100644
--- a/video/out/vo.c
+++ b/video/out/vo.c
@@ -561,6 +561,22 @@ void vo_wait_frame(struct vo *vo)
pthread_mutex_unlock(&in->lock);
}
+// Wait until realtime is >= ts
+// called without lock
+static void wait_until(struct vo *vo, int64_t target)
+{
+ struct vo_internal *in = vo->in;
+ struct timespec ts = mp_time_us_to_timespec(target);
+ while (1) {
+ int64_t now = mp_time_us();
+ if (target <= now)
+ break;
+ pthread_mutex_lock(&in->lock);
+ pthread_cond_timedwait(&in->wakeup, &in->lock, &ts);
+ pthread_mutex_unlock(&in->lock);
+ }
+}
+
// needs lock
static int64_t prev_sync(struct vo *vo, int64_t ts)
{
@@ -672,12 +688,7 @@ static bool render_frame(struct vo *vo)
vo->driver->draw_image(vo, img);
}
- while (1) {
- int64_t now = mp_time_us();
- if (target <= now)
- break;
- mp_sleep_us(target - now);
- }
+ wait_until(vo, target);
bool drop = false;
if (vo->driver->flip_page_timed)