diff --git a/player/audio.c b/player/audio.c index 5fcc2cbd22..2491051a54 100644 --- a/player/audio.c +++ b/player/audio.c @@ -92,6 +92,13 @@ int reinit_audio_filters(struct MPContext *mpctx) return 1; } +void reset_audio_state(struct MPContext *mpctx) +{ + if (mpctx->d_audio) + audio_reset_decoding(mpctx->d_audio); + mpctx->audio_status = mpctx->d_audio ? STATUS_SYNCING : STATUS_EOF; +} + void reinit_audio_chain(struct MPContext *mpctx) { struct MPOpts *opts = mpctx->opts; @@ -117,6 +124,7 @@ void reinit_audio_chain(struct MPContext *mpctx) mpctx->d_audio->replaygain_data = sh->audio->replaygain_data; if (!audio_init_best_codec(mpctx->d_audio, opts->audio_decoders)) goto init_error; + reset_audio_state(mpctx); } assert(mpctx->d_audio); diff --git a/player/core.h b/player/core.h index b49412164e..c24a6c1f94 100644 --- a/player/core.h +++ b/player/core.h @@ -374,6 +374,7 @@ typedef struct MPContext { } MPContext; // audio.c +void reset_audio_state(struct MPContext *mpctx); void reinit_audio_chain(struct MPContext *mpctx); int reinit_audio_filters(struct MPContext *mpctx); double playing_audio_pts(struct MPContext *mpctx); @@ -450,6 +451,7 @@ void set_osd_function(struct MPContext *mpctx, int osd_function); void set_osd_subtitle(struct MPContext *mpctx, const char *text); // playloop.c +void reset_playback_state(struct MPContext *mpctx); void pause_player(struct MPContext *mpctx); void unpause_player(struct MPContext *mpctx); void add_step_frame(struct MPContext *mpctx, int dir); @@ -481,6 +483,7 @@ struct mp_scripting { void mp_load_scripts(struct MPContext *mpctx); // sub.c +void reset_subtitle_state(struct MPContext *mpctx); void reset_subtitles(struct MPContext *mpctx, int order); void uninit_subs(struct demuxer *demuxer); void reinit_subs(struct MPContext *mpctx, int order); @@ -495,6 +498,7 @@ void build_mpv_edl_timeline(struct MPContext *mpctx); void build_cue_timeline(struct MPContext *mpctx); // video.c +void reset_video_state(struct MPContext *mpctx); int reinit_video_chain(struct MPContext *mpctx); int reinit_video_filters(struct MPContext *mpctx); int update_video(struct MPContext *mpctx, double endpts, bool reconfig_ok, diff --git a/player/loadfile.c b/player/loadfile.c index e26968000b..bcb9e900de 100644 --- a/player/loadfile.c +++ b/player/loadfile.c @@ -1251,8 +1251,6 @@ goto_reopen_demuxer: ; MP_VERBOSE(mpctx, "Starting playback...\n"); - mpctx->drop_frame_cnt = 0; - mpctx->dropped_frames = 0; mpctx->max_frames = opts->play_frames; if (mpctx->max_frames == 0) { @@ -1260,27 +1258,18 @@ goto_reopen_demuxer: ; goto terminate_playback; } - mpctx->time_frame = 0; - mpctx->drop_message_shown = 0; - mpctx->video_pts = 0; + reset_playback_state(mpctx); + mpctx->last_vo_pts = MP_NOPTS_VALUE; - mpctx->last_frame_duration = 0; - mpctx->last_seek_pts = 0; - mpctx->playback_pts = MP_NOPTS_VALUE; - mpctx->hrseek_active = false; - mpctx->hrseek_framedrop = false; - mpctx->step_frames = 0; - mpctx->backstep_active = false; - mpctx->total_avsync_change = 0; mpctx->last_chapter_seek = -2; - mpctx->playing_msg_shown = false; + mpctx->last_chapter_pts = MP_NOPTS_VALUE; + mpctx->last_chapter = -2; mpctx->paused = false; mpctx->paused_for_cache = false; - mpctx->last_chapter = -2; + mpctx->playing_msg_shown = false; + mpctx->step_frames = 0; + mpctx->backstep_active = false; mpctx->seek = (struct seek_params){ 0 }; - mpctx->video_status = mpctx->d_video ? STATUS_SYNCING : STATUS_EOF; - mpctx->audio_status = mpctx->d_audio ? STATUS_SYNCING : STATUS_EOF; - mpctx->restart_complete = false; // If there's a timeline force an absolute seek to initialize state double startpos = rel_time_to_abs(mpctx, opts->play_start); diff --git a/player/playloop.c b/player/playloop.c index cfce7aea19..60caf39389 100644 --- a/player/playloop.c +++ b/player/playloop.c @@ -146,43 +146,22 @@ void add_step_frame(struct MPContext *mpctx, int dir) } } -static void seek_reset(struct MPContext *mpctx, bool reset_ao) +// Clear some playback-related fields on file loading or after seeks. +void reset_playback_state(struct MPContext *mpctx) { - if (mpctx->d_video) { - video_reset_decoding(mpctx->d_video); - vo_seek_reset(mpctx->video_out); - } + reset_video_state(mpctx); + reset_audio_state(mpctx); + reset_subtitle_state(mpctx); - if (mpctx->d_audio) { - audio_reset_decoding(mpctx->d_audio); - if (reset_ao) - clear_audio_output_buffers(mpctx); - } - - reset_subtitles(mpctx, 0); - reset_subtitles(mpctx, 1); - - mpctx->video_pts = MP_NOPTS_VALUE; - mpctx->video_next_pts = MP_NOPTS_VALUE; - mpctx->playing_last_frame = false; - mpctx->last_frame_duration = 0; - mpctx->delay = 0; - mpctx->time_frame = 0; mpctx->hrseek_active = false; mpctx->hrseek_framedrop = false; - mpctx->total_avsync_change = 0; - mpctx->drop_frame_cnt = 0; - mpctx->dropped_frames = 0; mpctx->playback_pts = MP_NOPTS_VALUE; - mpctx->video_status = mpctx->d_video ? STATUS_SYNCING : STATUS_EOF; - mpctx->audio_status = mpctx->d_audio ? STATUS_SYNCING : STATUS_EOF; + mpctx->last_seek_pts = MP_NOPTS_VALUE; mpctx->restart_complete = false; #if HAVE_ENCODING encode_lavc_discontinuity(mpctx->encode_lavc_ctx); #endif - - mp_notify(mpctx, MPV_EVENT_SEEK, NULL); } // return -1 if seek failed (non-seekable stream?), 0 otherwise @@ -290,7 +269,10 @@ static int mp_seek(MPContext *mpctx, struct seek_params seek, } } - seek_reset(mpctx, !timeline_fallthrough); + if (!timeline_fallthrough) + clear_audio_output_buffers(mpctx); + + reset_playback_state(mpctx); if (timeline_fallthrough) { // Important if video reinit happens. @@ -305,8 +287,7 @@ static int mp_seek(MPContext *mpctx, struct seek_params seek, if (seek.type == MPSEEK_ABSOLUTE) { mpctx->video_pts = seek.amount; mpctx->last_seek_pts = seek.amount; - } else - mpctx->last_seek_pts = MP_NOPTS_VALUE; + } // The hr_seek==false case is for skipping frames with PTS before the // current timeline chapter start. It's not really known where the demuxer @@ -324,6 +305,7 @@ static int mp_seek(MPContext *mpctx, struct seek_params seek, mpctx->start_timestamp = mp_time_sec(); mpctx->sleeptime = 0; + mp_notify(mpctx, MPV_EVENT_SEEK, NULL); mp_notify(mpctx, MPV_EVENT_TICK, NULL); return 0; diff --git a/player/sub.c b/player/sub.c index 2ee928794c..1a9fdcafe7 100644 --- a/player/sub.c +++ b/player/sub.c @@ -76,6 +76,12 @@ void reset_subtitles(struct MPContext *mpctx, int order) osd_set_text(mpctx->osd, obj, NULL); } +void reset_subtitle_state(struct MPContext *mpctx) +{ + reset_subtitles(mpctx, 0); + reset_subtitles(mpctx, 1); +} + static void update_subtitle(struct MPContext *mpctx, int order) { struct MPOpts *opts = mpctx->opts; diff --git a/player/video.c b/player/video.c index dacf1200c5..713849798b 100644 --- a/player/video.c +++ b/player/video.c @@ -168,6 +168,26 @@ int reinit_video_filters(struct MPContext *mpctx) return d_video->vfilter->initialized; } +void reset_video_state(struct MPContext *mpctx) +{ + if (mpctx->d_video) + video_reset_decoding(mpctx->d_video); + if (mpctx->video_out) + vo_seek_reset(mpctx->video_out); + + mpctx->delay = 0; + mpctx->time_frame = 0; + mpctx->video_next_pts = MP_NOPTS_VALUE; + mpctx->playing_last_frame = false; + mpctx->last_frame_duration = 0; + mpctx->total_avsync_change = 0; + mpctx->drop_frame_cnt = 0; + mpctx->dropped_frames = 0; + mpctx->drop_message_shown = 0; + + mpctx->video_status = mpctx->d_video ? STATUS_SYNCING : STATUS_EOF; +} + int reinit_video_chain(struct MPContext *mpctx) { struct MPOpts *opts = mpctx->opts; @@ -223,21 +243,15 @@ int reinit_video_chain(struct MPContext *mpctx) vo_control(mpctx->video_out, mpctx->paused ? VOCTRL_PAUSE : VOCTRL_RESUME, NULL); - mpctx->video_status = STATUS_SYNCING; mpctx->sync_audio_to_video = !sh->attached_picture; - mpctx->delay = 0; - mpctx->video_next_pts = MP_NOPTS_VALUE; - mpctx->playing_last_frame = false; - mpctx->last_frame_duration = 0; mpctx->vo_pts_history_seek_ts++; // If we switch on video again, ensure audio position matches up. if (mpctx->d_audio) mpctx->audio_status = STATUS_SYNCING; - vo_seek_reset(mpctx->video_out); - reset_subtitles(mpctx, 0); - reset_subtitles(mpctx, 1); + reset_video_state(mpctx); + reset_subtitle_state(mpctx); if (opts->force_fps) { d_video->fps = opts->force_fps;