summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--player/playloop.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/player/playloop.c b/player/playloop.c
index bcdbd6e991..cf7a7eea48 100644
--- a/player/playloop.c
+++ b/player/playloop.c
@@ -168,14 +168,14 @@ void add_step_frame(struct MPContext *mpctx, int dir)
}
}
-static void seek_reset(struct MPContext *mpctx, bool reset_ao)
+static void seek_reset(struct MPContext *mpctx, bool reset_ao, bool reset_ac)
{
if (mpctx->d_video) {
video_reset_decoding(mpctx->d_video);
vo_seek_reset(mpctx->video_out);
}
- if (mpctx->d_audio) {
+ if (mpctx->d_audio && reset_ac) {
audio_reset_decoding(mpctx->d_audio);
if (reset_ao)
clear_audio_output_buffers(mpctx);
@@ -204,9 +204,6 @@ static void seek_reset(struct MPContext *mpctx, bool reset_ao)
}
// return -1 if seek failed (non-seekable stream?), 0 otherwise
-// timeline_fallthrough: true if used to explicitly switch timeline - in this
-// case, don't drop buffered AO audio data, so that
-// timeline segment transition is seemless
static int mp_seek(MPContext *mpctx, struct seek_params seek,
bool timeline_fallthrough)
{
@@ -253,6 +250,9 @@ static int mp_seek(MPContext *mpctx, struct seek_params seek,
seek.amount += get_current_time(mpctx);
}
+ /* At least the liba52 decoder wants to read from the input stream
+ * during initialization, so reinit must be done after the demux_seek()
+ * call that clears possible stream EOF. */
bool need_reset = false;
double demuxer_amount = seek.amount;
if (mpctx->timeline) {
@@ -271,7 +271,6 @@ static int mp_seek(MPContext *mpctx, struct seek_params seek,
}
if (need_reset) {
reinit_video_chain(mpctx);
- reinit_audio_chain(mpctx);
reinit_subs(mpctx, 0);
reinit_subs(mpctx, 1);
}
@@ -296,8 +295,10 @@ static int mp_seek(MPContext *mpctx, struct seek_params seek,
demuxer_amount -= hr_seek_offset;
int seekresult = demux_seek(mpctx->demuxer, demuxer_amount, demuxer_style);
if (seekresult == 0) {
- if (need_reset)
- seek_reset(mpctx, !timeline_fallthrough);
+ if (need_reset) {
+ reinit_audio_chain(mpctx);
+ seek_reset(mpctx, !timeline_fallthrough, false);
+ }
return -1;
}
@@ -315,7 +316,11 @@ static int mp_seek(MPContext *mpctx, struct seek_params seek,
}
}
- seek_reset(mpctx, !timeline_fallthrough);
+ if (need_reset)
+ reinit_audio_chain(mpctx);
+ /* If we just reinitialized audio it doesn't need to be reset,
+ * and resetting could lose audio some decoders produce during init. */
+ seek_reset(mpctx, !timeline_fallthrough, !need_reset);
if (timeline_fallthrough) {
// Important if video reinit happens.
@@ -571,7 +576,7 @@ bool mp_seek_chapter(struct MPContext *mpctx, int chapter)
if (res >= 0) {
if (pts == -1) {
// for DVD/BD - seek happened via stream layer
- seek_reset(mpctx, true);
+ seek_reset(mpctx, true, true);
mpctx->seek = (struct seek_params){0};
return true;
}