diff options
Diffstat (limited to 'player')
-rw-r--r-- | player/command.c | 42 | ||||
-rw-r--r-- | player/command.h | 2 | ||||
-rw-r--r-- | player/core.h | 2 | ||||
-rw-r--r-- | player/misc.c | 6 | ||||
-rw-r--r-- | player/playloop.c | 28 |
5 files changed, 38 insertions, 42 deletions
diff --git a/player/command.c b/player/command.c index f941e864dc..99538cebcf 100644 --- a/player/command.c +++ b/player/command.c @@ -75,8 +75,6 @@ struct command_ctx { double last_seek_pts; double marked_pts; - double prev_pts; - char **warned_deprecated; int num_warned_deprecated; @@ -220,7 +218,7 @@ static void mp_hook_add(struct MPContext *mpctx, char *client, char *name, } // Call before a seek, in order to allow revert-seek to undo the seek. -static void mark_seek(struct MPContext *mpctx) +void mark_seek(struct MPContext *mpctx) { struct command_ctx *cmd = mpctx->command_ctx; double now = mp_time_sec(); @@ -3301,9 +3299,11 @@ static int mp_property_ab_loop(void *ctx, struct m_property *prop, } int r = mp_property_generic_option(mpctx, prop, action, arg); if (r > 0 && action == M_PROPERTY_SET) { + mpctx->ab_loop_clip = mpctx->playback_pts < opts->ab_loop[1]; if (strcmp(prop->name, "ab-loop-b") == 0) { - struct command_ctx *cctx = mpctx->command_ctx; - cctx->prev_pts = opts->ab_loop[0]; + if (opts->ab_loop[1] != MP_NOPTS_VALUE && + mpctx->playback_pts <= opts->ab_loop[1]) + mpctx->ab_loop_clip = true; } // Update if visible set_osd_bar_chapters(mpctx, OSD_BAR_SEEK); @@ -5375,7 +5375,6 @@ void command_init(struct MPContext *mpctx) mpctx->command_ctx = talloc(NULL, struct command_ctx); *mpctx->command_ctx = (struct command_ctx){ .last_seek_pts = MP_NOPTS_VALUE, - .prev_pts = MP_NOPTS_VALUE, }; } @@ -5388,8 +5387,6 @@ static void command_event(struct MPContext *mpctx, int event, void *arg) ctx->marked_pts = MP_NOPTS_VALUE; } - if (event == MPV_EVENT_SEEK) - ctx->prev_pts = MP_NOPTS_VALUE; if (event == MPV_EVENT_IDLE) ctx->is_idle = true; if (event == MPV_EVENT_START_FILE) @@ -5400,35 +5397,6 @@ static void command_event(struct MPContext *mpctx, int event, void *arg) } } -void handle_ab_loop(struct MPContext *mpctx) -{ - struct command_ctx *ctx = mpctx->command_ctx; - struct MPOpts *opts = mpctx->opts; - - if (opts->pause) - return; - - double now = mpctx->restart_complete ? mpctx->playback_pts : MP_NOPTS_VALUE; - if (now != MP_NOPTS_VALUE && (opts->ab_loop[0] != MP_NOPTS_VALUE || - opts->ab_loop[1] != MP_NOPTS_VALUE)) - { - double start = opts->ab_loop[0]; - if (start == MP_NOPTS_VALUE) - start = 0; - double end = opts->ab_loop[1]; - if (end == MP_NOPTS_VALUE) - end = INFINITY; - if (ctx->prev_pts >= start && ctx->prev_pts < end && - (now >= end || mpctx->stop_play == AT_END_OF_FILE)) - { - mark_seek(mpctx); - queue_seek(mpctx, MPSEEK_ABSOLUTE, start, - MPSEEK_EXACT, MPSEEK_FLAG_DELAY); - } - } - ctx->prev_pts = now; -} - void handle_command_updates(struct MPContext *mpctx) { struct command_ctx *ctx = mpctx->command_ctx; diff --git a/player/command.h b/player/command.h index a233319ad7..9ffa5c1340 100644 --- a/player/command.h +++ b/player/command.h @@ -57,6 +57,6 @@ enum { bool mp_hook_test_completion(struct MPContext *mpctx, char *type); void mp_hook_run(struct MPContext *mpctx, char *client, char *type); -void handle_ab_loop(struct MPContext *mpctx); +void mark_seek(struct MPContext *mpctx); #endif /* MPLAYER_COMMAND_H */ diff --git a/player/core.h b/player/core.h index 94bfe4aada..25eb8b71a8 100644 --- a/player/core.h +++ b/player/core.h @@ -82,6 +82,7 @@ enum seek_precision { enum seek_flags { MPSEEK_FLAG_DELAY = 1 << 0, // give player chance to coalesce multiple seeks + MPSEEK_FLAG_NOFLUSH = 1 << 1, // keeping remaining data for seamless loops }; enum video_sync { @@ -326,6 +327,7 @@ typedef struct MPContext { bool hrseek_lastframe; // drop everything until last frame reached bool hrseek_backstep; // go to frame before seek target double hrseek_pts; + bool ab_loop_clip; // clip to the "b" part of an A-B loop if available // AV sync: the next frame should be shown when the audio out has this // much (in seconds) buffered data left. Increased when more data is // written to the ao, decreased when moving to the next video frame. diff --git a/player/misc.c b/player/misc.c index a9174c41a9..bd65fb9d5b 100644 --- a/player/misc.c +++ b/player/misc.c @@ -90,6 +90,12 @@ double get_play_end_pts(struct MPContext *mpctx) if (cend != MP_NOPTS_VALUE && (end == MP_NOPTS_VALUE || cend < end)) end = cend; } + if (mpctx->ab_loop_clip && opts->ab_loop[1] != MP_NOPTS_VALUE && + opts->ab_loop[1] > opts->ab_loop[0]) + { + if (end == MP_NOPTS_VALUE || end > opts->ab_loop[1]) + end = opts->ab_loop[1]; + } return end; } diff --git a/player/playloop.c b/player/playloop.c index abba107dc5..ed4f57dd5c 100644 --- a/player/playloop.c +++ b/player/playloop.c @@ -172,6 +172,7 @@ void reset_playback_state(struct MPContext *mpctx) mpctx->last_seek_pts = MP_NOPTS_VALUE; mpctx->cache_wait_time = 0; mpctx->step_frames = 0; + mpctx->ab_loop_clip = true; mpctx->restart_complete = false; #if HAVE_ENCODING @@ -272,7 +273,9 @@ static void mp_seek(MPContext *mpctx, struct seek_params seek) } } - clear_audio_output_buffers(mpctx); + if (!(seek.flags & MPSEEK_FLAG_NOFLUSH)) + clear_audio_output_buffers(mpctx); + reset_playback_state(mpctx); /* Use the target time as "current position" for further relative @@ -301,6 +304,8 @@ static void mp_seek(MPContext *mpctx, struct seek_params seek) mpctx->audio_allow_second_chance_seek = !hr_seek && !(demux_flags & SEEK_FORWARD); + + mpctx->ab_loop_clip = mpctx->last_seek_pts < opts->ab_loop[1]; } // This combines consecutive seek requests. @@ -697,10 +702,25 @@ static void handle_sstep(struct MPContext *mpctx) static void handle_loop_file(struct MPContext *mpctx) { struct MPOpts *opts = mpctx->opts; + + if (mpctx->stop_play == AT_END_OF_FILE && + (opts->ab_loop[0] != MP_NOPTS_VALUE || opts->ab_loop[1] != MP_NOPTS_VALUE)) + { + // 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]; + 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) { mpctx->stop_play = KEEP_PLAYING; set_osd_function(mpctx, OSD_FFW); - queue_seek(mpctx, MPSEEK_ABSOLUTE, 0, MPSEEK_DEFAULT, 0); + queue_seek(mpctx, MPSEEK_ABSOLUTE, 0, MPSEEK_DEFAULT, MPSEEK_FLAG_NOFLUSH); if (opts->loop_file > 0) opts->loop_file--; } @@ -894,6 +914,7 @@ static void handle_playback_restart(struct MPContext *mpctx) mpctx->hrseek_active = false; mpctx->restart_complete = true; mpctx->audio_allow_second_chance_seek = false; + handle_playback_time(mpctx); mp_notify(mpctx, MPV_EVENT_PLAYBACK_RESTART, NULL); if (!mpctx->playing_msg_shown) { if (opts->playing_msg && opts->playing_msg[0]) { @@ -913,6 +934,7 @@ static void handle_playback_restart(struct MPContext *mpctx) } mpctx->playing_msg_shown = true; mpctx->sleeptime = 0; + mpctx->ab_loop_clip = mpctx->playback_pts < opts->ab_loop[1]; MP_VERBOSE(mpctx, "playback restart complete\n"); } } @@ -1013,8 +1035,6 @@ void run_playloop(struct MPContext *mpctx) handle_loop_file(mpctx); - handle_ab_loop(mpctx); - handle_keep_open(mpctx); handle_sstep(mpctx); |