diff --git a/libavdevice/x11grab.c b/libavdevice/x11grab.c
index 0e7b6ae..63d2490 100644
--- a/libavdevice/x11grab.c
+++ b/libavdevice/x11grab.c
@@ -319,7 +319,7 @@ x11grab_read_header(AVFormatContext *s1)
     x11grab->frame_size = x11grab->width * x11grab->height * image->bits_per_pixel/8;
     x11grab->dpy = dpy;
     x11grab->time_base  = av_inv_q(x11grab->framerate);
-    x11grab->time_frame = av_gettime() / av_q2d(x11grab->time_base);
+    x11grab->time_frame = av_gettime();
     x11grab->x_off = x_off;
     x11grab->y_off = y_off;
     x11grab->image = image;
@@ -478,26 +478,28 @@ x11grab_read_packet(AVFormatContext *s1, AVPacket *pkt)
     Window root;
     int follow_mouse = s->follow_mouse;
 
-    int64_t curtime, delay;
-    struct timespec ts;
-
-    /* Calculate the time of the next frame */
-    s->time_frame += INT64_C(1000000);
+    int64_t curtime, delay, frame_dur;
 
     /* wait based on the frame rate */
-    for(;;) {
-        curtime = av_gettime();
-        delay = s->time_frame * av_q2d(s->time_base) - curtime;
-        if (delay <= 0) {
-            if (delay < INT64_C(-1000000) * av_q2d(s->time_base)) {
-                s->time_frame += INT64_C(1000000);
-            }
-            break;
-        }
-        ts.tv_sec = delay / 1000000;
-        ts.tv_nsec = (delay % 1000000) * 1000;
-        nanosleep(&ts, NULL);
-    }
+	curtime = av_gettime();
+	frame_dur = INT64_C(1000000) * av_q2d(s->time_base);
+	for (delay = s->time_frame - curtime; delay < -frame_dur; delay += frame_dur) {
+		s->time_frame += frame_dur;
+		av_log(s1, AV_LOG_DEBUG, "X11Grab: Frame skipped\n");
+	}
+	if (delay > 0) {
+		if (s1->flags & AVFMT_FLAG_NONBLOCK) {
+			return AVERROR(EAGAIN);
+		} else {
+			struct timespec ts;
+			ts.tv_sec = delay / 1000000;
+			ts.tv_nsec = (delay % 1000000) * 1000;
+			nanosleep(&ts, NULL);
+		}
+	}
+
+	/* Calculate the time of the next frame */
+	s->time_frame += frame_dur;
 
     av_init_packet(pkt);
     pkt->data = image->data;
