diff options
author | wm4 <wm4@nowhere> | 2020-02-07 13:32:07 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2020-02-07 13:32:21 +0100 |
commit | a3bd8c3b5f84c5d48785552fc7bd2505ee839736 (patch) | |
tree | 9f6ad3cb81cd52895bbde24761f7ebe26bf3db45 /player/screenshot.c | |
parent | 3d17e19c2c5ca80f916411e7e61126cac8443baa (diff) | |
download | mpv-a3bd8c3b5f84c5d48785552fc7bd2505ee839736.tar.bz2 mpv-a3bd8c3b5f84c5d48785552fc7bd2505ee839736.tar.xz |
player: make screenshot each-frame mode more accurate
Due to asynchronicity, we generally can't guarantee that a video frame
matches up with other events such as playback time change exactly (since
decoding, presentation, and property update all happen at different
times). This is a complaint in the referenced bug report, where
screenshot filenames in each-frame screenshot did not use the correct
timestamp, and instead was lagging behind by 1 frame.
But in this case, synchronicity was already pretty much forced with wait
calls. The only problem was that the playback time was updated at a
later time, which results in the observed 1 frame lag. Fix this by
moving the place where the screenshot is triggered in this mode.
Normal screenshots may still have the old problem. There is no effort
made to guarantee the timestamps absolutely line up, same as with the
OSD. (If you want a guarantee, you need to use a video filter, such as
libavfilter's drawtext. These will obviously use the proper timestamp,
instead of going through the somewhat asynchronous property etc. system
in the player frontend.)
Fixes: #7433
Diffstat (limited to 'player/screenshot.c')
-rw-r--r-- | player/screenshot.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/player/screenshot.c b/player/screenshot.c index eccce16dd6..5651b1b7ec 100644 --- a/player/screenshot.c +++ b/player/screenshot.c @@ -53,6 +53,7 @@ typedef struct screenshot_ctx { struct mp_cmd *each_frame; int frameno; + uint64_t last_frame_count; } screenshot_ctx; void screenshot_init(struct MPContext *mpctx) @@ -529,13 +530,17 @@ static void screenshot_fin(struct mp_cmd_ctx *cmd) mp_wakeup_core(mpctx); } -void screenshot_flip(struct MPContext *mpctx) +void handle_each_frame_screenshot(struct MPContext *mpctx) { screenshot_ctx *ctx = mpctx->screenshot_ctx; if (!ctx->each_frame) return; + if (ctx->last_frame_count == mpctx->shown_vframes) + return; + ctx->last_frame_count = mpctx->shown_vframes; + struct mp_waiter wait = MP_WAITER_INITIALIZER; void *a[] = {mpctx, &wait}; run_command(mpctx, mp_cmd_clone(ctx->each_frame), NULL, screenshot_fin, a); |