diff --git a/video/out/drm_common.c b/video/out/drm_common.c index 9c56227b9e..084cf22768 100644 --- a/video/out/drm_common.c +++ b/video/out/drm_common.c @@ -944,6 +944,15 @@ void drm_pflip_cb(int fd, unsigned int msc, unsigned int sec, const uint64_t ust = (sec * 1000000LL) + usec; const unsigned int msc_since_last_flip = msc - vsync->msc; + if (ready && msc == vsync->msc) { + // Seems like some drivers only increment msc every other page flip when + // running in interlaced mode (I'm looking at you nouveau). Obviously we + // can't work with this, so shame the driver and bail. + mp_err(closure->log, + "Got the same msc value twice: (msc: %u, vsync->msc: %u). This shouldn't happen. Possibly broken driver/interlaced mode?\n", + msc, vsync->msc); + goto fail; + } vsync->ust = ust; vsync->msc = msc; diff --git a/video/out/drm_common.h b/video/out/drm_common.h index 6ddd0994e3..aa08312ad2 100644 --- a/video/out/drm_common.h +++ b/video/out/drm_common.h @@ -66,6 +66,7 @@ struct drm_pflip_cb_closure { struct drm_vsync_tuple *vsync; // vsync tuple of the latest page flip. drm_pflip_cb updates this struct vo_vsync_info *vsync_info; // where the drm_pflip_cb routine writes its output bool *waiting_for_flip; // drm_pflip_cb writes false here before returning + struct mp_log *log; // Needed to print error messages that shame bad drivers }; bool vt_switcher_init(struct vt_switcher *s, struct mp_log *log); diff --git a/video/out/opengl/context_drm_egl.c b/video/out/opengl/context_drm_egl.c index 736db7a4ec..3b5dac64da 100644 --- a/video/out/opengl/context_drm_egl.c +++ b/video/out/opengl/context_drm_egl.c @@ -459,6 +459,7 @@ static void queue_flip(struct ra_ctx *ctx, struct gbm_frame *frame) data->vsync = &p->vsync; data->vsync_info = &p->vsync_info; data->waiting_for_flip = &p->waiting_for_flip; + data->log = ctx->log; if (atomic_ctx) { drm_object_set_property(atomic_ctx->request, atomic_ctx->draw_plane, "FB_ID", p->fb->id); diff --git a/video/out/vo_drm.c b/video/out/vo_drm.c index be5b0c52d9..7eee6c66c1 100644 --- a/video/out/vo_drm.c +++ b/video/out/vo_drm.c @@ -489,6 +489,7 @@ static void queue_flip(struct vo *vo, struct kms_frame *frame) data->vsync = &p->vsync; data->vsync_info = &p->vsync_info; data->waiting_for_flip = &p->waiting_for_flip; + data->log = vo->log; ret = drmModePageFlip(p->kms->fd, p->kms->crtc_id, p->cur_fb->fb,