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.
This commit is contained in:
wm4 2019-05-27 01:46:34 +02:00
parent 878d4ea2ee
commit c7269e4e84
4 changed files with 19 additions and 10 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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) {