player: use start timestamp for ab-looping if --ab-loop-a is absent

If --ab-loop-b is present, then ab-looping will be enabled and will
attempt to seek to the beginning of the file. This patch changes it
so it will instead seek to the start of playback, either via --start
or some equivalent, rather than always to the beginning of the file.
This commit is contained in:
Leo Izen 2017-12-03 22:19:16 -05:00
parent a6ca167794
commit ff7e294610
4 changed files with 39 additions and 7 deletions

View File

@ -543,6 +543,7 @@ void issue_refresh_seek(struct MPContext *mpctx, enum seek_precision min_prec);
double rel_time_to_abs(struct MPContext *mpctx, struct m_rel_time t);
double get_play_end_pts(struct MPContext *mpctx);
double get_play_start_pts(struct MPContext *mpctx);
double get_ab_loop_start_time(struct MPContext *mpctx);
void merge_playlist_files(struct playlist *pl);
float mp_get_cache_percent(struct MPContext *mpctx);
bool mp_get_cache_idle(struct MPContext *mpctx);

View File

@ -104,8 +104,11 @@ double get_play_end_pts(struct MPContext *mpctx)
if (cend != MP_NOPTS_VALUE && (end == MP_NOPTS_VALUE || cend < end))
end = cend;
}
// even though MP_NOPTS_VALUE is currently negative
// it doesn't necessarily have to remain that way
double ab_loop_start_time = get_ab_loop_start_time(mpctx);
if (mpctx->ab_loop_clip && opts->ab_loop[1] != MP_NOPTS_VALUE &&
opts->ab_loop[1] > opts->ab_loop[0])
(ab_loop_start_time == MP_NOPTS_VALUE || opts->ab_loop[1] > ab_loop_start_time))
{
if (end == MP_NOPTS_VALUE || end > opts->ab_loop[1])
end = opts->ab_loop[1];
@ -145,6 +148,32 @@ double get_play_start_pts(struct MPContext *mpctx)
return play_start_pts;
}
/**
* Get the time that an ab-loop seek should seek to.
* The order of priority is as follows:
* 1. --ab-loop-a, if set.
* 2. The Playback Start PTS, if set.
* 3. MP_NOPTS_VALUE.
* If unspecified, return MP_NOPTS_VALUE.
* Does not return zero unless the start time is explicitly set to zero.
*/
double get_ab_loop_start_time(struct MPContext *mpctx)
{
struct MPOpts *opts = mpctx->opts;
double ab_loop_start_time;
if (opts->ab_loop[0] != MP_NOPTS_VALUE) {
ab_loop_start_time = opts->ab_loop[0];
} else {
/*
* There is no check for MP_NOPTS_VALUE here
* because that's exactly what we want to return
* if get_play_start_pts comes up empty here.
*/
ab_loop_start_time = get_play_start_pts(mpctx);
}
return ab_loop_start_time;
}
double get_track_seek_offset(struct MPContext *mpctx, struct track *track)
{
struct MPOpts *opts = mpctx->opts;

View File

@ -356,9 +356,10 @@ void set_osd_bar_chapters(struct MPContext *mpctx, int type)
mpctx->osd_progbar.num_stops = 0;
double len = get_time_length(mpctx);
if (len > 0) {
if (opts->ab_loop[0] != MP_NOPTS_VALUE) {
double ab_loop_start_time = get_ab_loop_start_time(mpctx);
if (ab_loop_start_time != MP_NOPTS_VALUE) {
MP_TARRAY_APPEND(mpctx, mpctx->osd_progbar.stops,
mpctx->osd_progbar.num_stops, opts->ab_loop[0] / len);
mpctx->osd_progbar.num_stops, ab_loop_start_time / len);
}
if (opts->ab_loop[1] != MP_NOPTS_VALUE) {
MP_TARRAY_APPEND(mpctx, mpctx->osd_progbar.stops,

View File

@ -768,15 +768,16 @@ static void handle_loop_file(struct MPContext *mpctx)
// Assumes execute_queued_seek() happens before next audio/video is
// attempted to be decoded or filtered.
mpctx->stop_play = KEEP_PLAYING;
double start = 0;
if (opts->ab_loop[0] != MP_NOPTS_VALUE)
start = opts->ab_loop[0];
double start = get_ab_loop_start_time(mpctx);
if (start == MP_NOPTS_VALUE)
start = 0;
mark_seek(mpctx);
queue_seek(mpctx, MPSEEK_ABSOLUTE, start, MPSEEK_EXACT,
MPSEEK_FLAG_NOFLUSH);
}
if (opts->loop_file && mpctx->stop_play == AT_END_OF_FILE) {
// Do not attempt to loop-file if --ab-loop is active.
else if (opts->loop_file && mpctx->stop_play == AT_END_OF_FILE) {
mpctx->stop_play = KEEP_PLAYING;
set_osd_function(mpctx, OSD_FFW);
queue_seek(mpctx, MPSEEK_ABSOLUTE, 0, MPSEEK_DEFAULT, MPSEEK_FLAG_NOFLUSH);