summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2019-05-27 01:46:34 +0200
committerwm4 <wm4@nowhere>2019-09-19 20:37:05 +0200
commitc7269e4e84f4d0a0709a560acbfe2fa3b02a5527 (patch)
tree696322ad37985d511a2c9f82561a751e9923797d
parent878d4ea2ee22cc8d11652aee0fe144ca3f6ae131 (diff)
downloadmpv-c7269e4e84f4d0a0709a560acbfe2fa3b02a5527.tar.bz2
mpv-c7269e4e84f4d0a0709a560acbfe2fa3b02a5527.tar.xz
player: fix --loop with backward playback
Obviously should seek back to the end of the file when it loops. Also remove some minor code duplication around start times. This isn't the correct solution by the way. Rather than hoping we know a reasonable start/end time, this stuff should instruct the demuxer to seek to the exact location. It'll work with 99% of all normal files, but add an appropriate comment (that basically says the function is bullshit) to get_start_time() anyway.
-rw-r--r--player/core.h1
-rw-r--r--player/loadfile.c2
-rw-r--r--player/misc.c10
-rw-r--r--player/playloop.c16
4 files changed, 19 insertions, 10 deletions
diff --git a/player/core.h b/player/core.h
index c0b3e3d8e0..bf4b62fa56 100644
--- a/player/core.h
+++ b/player/core.h
@@ -589,6 +589,7 @@ void add_step_frame(struct MPContext *mpctx, int dir);
void queue_seek(struct MPContext *mpctx, enum seek_type type, double amount,
enum seek_precision exact, int flags);
double get_time_length(struct MPContext *mpctx);
+double get_start_time(struct MPContext *mpctx, int dir);
double get_current_time(struct MPContext *mpctx);
double get_playback_time(struct MPContext *mpctx);
int get_percent_pos(struct MPContext *mpctx);
diff --git a/player/loadfile.c b/player/loadfile.c
index e1e0c2c794..c730d2e8f8 100644
--- a/player/loadfile.c
+++ b/player/loadfile.c
@@ -1555,7 +1555,7 @@ static void play_current_file(struct MPContext *mpctx)
// Backward playback -> start from end by default.
if (play_start_pts == MP_NOPTS_VALUE && opts->play_dir < 0)
- play_start_pts = MPMAX(mpctx->demuxer->duration, 0);
+ play_start_pts = get_start_time(mpctx, -1);
if (play_start_pts != MP_NOPTS_VALUE) {
queue_seek(mpctx, MPSEEK_ABSOLUTE, play_start_pts, MPSEEK_DEFAULT, 0);
diff --git a/player/misc.c b/player/misc.c
index a39c8df82b..b9a280f2cc 100644
--- a/player/misc.c
+++ b/player/misc.c
@@ -107,14 +107,8 @@ double get_play_start_pts(struct MPContext *mpctx)
{
struct MPOpts *opts = mpctx->opts;
double res = rel_time_to_abs(mpctx, opts->play_start);
- if (res == MP_NOPTS_VALUE) {
- res = 0;
- if (!opts->rebase_start_time && mpctx->demuxer)
- res = mpctx->demuxer->start_time;
- // Backward playback -> start from end by default.
- if (mpctx->play_dir < 0 && mpctx->demuxer)
- res = MPMAX(mpctx->demuxer->duration, 0);
- }
+ if (res == MP_NOPTS_VALUE)
+ res = get_start_time(mpctx, mpctx->play_dir);
return res;
}
diff --git a/player/playloop.c b/player/playloop.c
index 4067e13459..30c1bbb5d6 100644
--- a/player/playloop.c
+++ b/player/playloop.c
@@ -488,6 +488,20 @@ double get_time_length(struct MPContext *mpctx)
return demuxer && demuxer->duration >= 0 ? demuxer->duration : MP_NOPTS_VALUE;
}
+// Return approximate PTS of first frame played. This can be completely wrong
+// for a number of reasons in a number of situations.
+double get_start_time(struct MPContext *mpctx, int dir)
+{
+ double res = 0;
+ if (mpctx->demuxer) {
+ if (!mpctx->opts->rebase_start_time)
+ res += mpctx->demuxer->start_time;
+ if (dir < 0)
+ res += MPMAX(mpctx->demuxer->duration, 0);
+ }
+ return res;
+}
+
double get_current_time(struct MPContext *mpctx)
{
struct demuxer *demuxer = mpctx->demuxer;
@@ -827,7 +841,7 @@ static void handle_loop_file(struct MPContext *mpctx)
} else if (opts->loop_file) {
if (opts->loop_file > 0)
opts->loop_file--;
- target = 0;
+ target = get_start_time(mpctx, mpctx->play_dir);
}
if (target != MP_NOPTS_VALUE) {