diff options
-rw-r--r-- | player/command.c | 23 | ||||
-rw-r--r-- | player/core.h | 1 | ||||
-rw-r--r-- | player/playloop.c | 21 |
3 files changed, 28 insertions, 17 deletions
diff --git a/player/command.c b/player/command.c index 25b9a90e4a..3e6a4da9f1 100644 --- a/player/command.c +++ b/player/command.c @@ -2595,25 +2595,14 @@ static int mp_property_vf_fps(void *ctx, struct m_property *prop, MPContext *mpctx = ctx; if (!mpctx->d_video) return M_PROPERTY_UNAVAILABLE; - double next_pts = mpctx->vo_pts_history_pts[0]; - if (mpctx->vo_pts_history_seek[0] != mpctx->vo_pts_history_seek_ts) + double durations[10]; + int num = get_past_frame_durations(mpctx, durations, MP_ARRAY_SIZE(durations)); + if (num < MP_ARRAY_SIZE(durations)) return M_PROPERTY_UNAVAILABLE; - if (next_pts == MP_NOPTS_VALUE) - return M_PROPERTY_UNAVAILABLE; - int num_samples = 10; - assert(num_samples + 1 <= MAX_NUM_VO_PTS); double duration = 0; - for (int n = 1; n < 1 + num_samples; n++) { - double frame_pts = mpctx->vo_pts_history_pts[n]; - // Discontinuity -> refuse to return a value. - if (mpctx->vo_pts_history_seek[n] != mpctx->vo_pts_history_seek_ts) - return M_PROPERTY_UNAVAILABLE; - if (frame_pts == MP_NOPTS_VALUE) - return M_PROPERTY_UNAVAILABLE; - duration += next_pts - frame_pts; - next_pts = frame_pts; - } - return m_property_double_ro(action, arg, num_samples / duration); + for (int n = 0; n < num; n++) + duration += durations[n]; + return m_property_double_ro(action, arg, num / duration); } /// Video aspect (RO) diff --git a/player/core.h b/player/core.h index 64fd4ec1a5..2ae6a4ae65 100644 --- a/player/core.h +++ b/player/core.h @@ -466,6 +466,7 @@ void mp_idle(struct MPContext *mpctx); void idle_loop(struct MPContext *mpctx); void handle_force_window(struct MPContext *mpctx, bool reconfig); void add_frame_pts(struct MPContext *mpctx, double pts); +int get_past_frame_durations(struct MPContext *mpctx, double *fd, int num); void seek_to_last_frame(struct MPContext *mpctx); // scripting.c diff --git a/player/playloop.c b/player/playloop.c index c9d74c2950..4f42b17e97 100644 --- a/player/playloop.c +++ b/player/playloop.c @@ -691,6 +691,27 @@ void add_frame_pts(struct MPContext *mpctx, double pts) mpctx->vo_pts_history_pts[0] = pts; } +// Return the last (at most num) frame duration in fd[]. Return the number of +// entries written to fd[] (range [0, num]). fd[0] is the most recent frame. +int get_past_frame_durations(struct MPContext *mpctx, double *fd, int num) +{ + double next_pts = mpctx->vo_pts_history_pts[0]; + if (mpctx->vo_pts_history_seek[0] != mpctx->vo_pts_history_seek_ts || + next_pts == MP_NOPTS_VALUE) + return 0; + int num_ret = 0; + for (int n = 1; n < MAX_NUM_VO_PTS && num_ret < num; n++) { + double frame_pts = mpctx->vo_pts_history_pts[n]; + // Discontinuity -> refuse to return a value. + if (mpctx->vo_pts_history_seek[n] != mpctx->vo_pts_history_seek_ts || + next_pts <= frame_pts || frame_pts == MP_NOPTS_VALUE) + break; + fd[num_ret++] = next_pts - frame_pts; + next_pts = frame_pts; + } + return num_ret; +} + static double find_previous_pts(struct MPContext *mpctx, double pts) { for (int n = 0; n < MAX_NUM_VO_PTS - 1; n++) { |