summaryrefslogtreecommitdiffstats
path: root/mplayer.c
diff options
context:
space:
mode:
authorUoti Urpala <uau@mplayer2.org>2012-03-16 08:04:24 +0200
committerUoti Urpala <uau@mplayer2.org>2012-03-20 14:51:32 +0200
commitfd50478659e56db84e8564434702cdc8291ac854 (patch)
treecf4a3fc55aebb69bb9d59df1eb7154b80368b71d /mplayer.c
parentec58e5a3848f82681839eaa15d2c6912d92e74ed (diff)
downloadmpv-fd50478659e56db84e8564434702cdc8291ac854.tar.bz2
mpv-fd50478659e56db84e8564434702cdc8291ac854.tar.xz
core: improve sub and audio start after timeline part switch
When switching to a timeline part from another file, decoders were reinitialized after doing the demuxer-level seek. This is necessary for audio because some decoders read from the demuxer stream during initialization and the previous stream position before seek could have been at EOF. However, this initialization sequence could lose first subtitles or first part of audio. The problem for subtitles was that the seek itself or audio initialization could already have buffered subtitle packets from the new position, and the way subtitles are reinitialized flushes packet buffers. Thus early subtitles could be lost (even if they were demuxed - unfortunately demuxers may not know about still active subtitles earlier in the file, but that's another issue). Fix this by moving subtitle and video reinitialization before the demuxer seek; they don't have the problems which prevent that for audio. Audio initialization can already decode and buffer some output. However, the seek_reset() call done last would then throw away this buffered output. Work around this by adding an extra flag to seek_reset().
Diffstat (limited to 'mplayer.c')
-rw-r--r--mplayer.c36
1 files changed, 21 insertions, 15 deletions
diff --git a/mplayer.c b/mplayer.c
index 7ca2d0303f..3803dffe79 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -3030,14 +3030,7 @@ void add_step_frame(struct MPContext *mpctx)
unpause_player(mpctx);
}
-static void reinit_decoders(struct MPContext *mpctx)
-{
- reinit_video_chain(mpctx);
- reinit_audio_chain(mpctx);
- mp_property_do("sub", M_PROPERTY_SET, &(int){mpctx->global_sub_pos}, mpctx);
-}
-
-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->sh_video) {
current_module = "seek_video_reset";
@@ -3059,7 +3052,7 @@ static void seek_reset(struct MPContext *mpctx, bool reset_ao)
update_teletext(mpctx->sh_video, mpctx->demuxer, 1);
}
- if (mpctx->sh_audio) {
+ if (mpctx->sh_audio && reset_ac) {
current_module = "seek_audio_reset";
resync_audio_stream(mpctx->sh_audio);
if (reset_ao)
@@ -3168,13 +3161,19 @@ static int seek(MPContext *mpctx, struct seek_params seek,
if (demuxer_amount == -1) {
mpctx->stop_play = AT_END_OF_FILE;
// Clear audio from current position
- if (mpctx->sh_audio) {
+ if (mpctx->sh_audio && !timeline_fallthrough) {
ao_reset(mpctx->ao);
mpctx->sh_audio->a_buffer_len = 0;
}
return -1;
}
}
+ if (need_reset) {
+ reinit_video_chain(mpctx);
+ mp_property_do("sub", M_PROPERTY_SET, &(int){mpctx->global_sub_pos},
+ mpctx);
+ }
+
int demuxer_style = 0;
switch (seek.type) {
case MPSEEK_FACTOR:
@@ -3191,12 +3190,19 @@ static int seek(MPContext *mpctx, struct seek_params seek,
demuxer_amount -= opts->hr_seek_demuxer_offset;
int seekresult = demux_seek(mpctx->demuxer, demuxer_amount, audio_delay,
demuxer_style);
- if (need_reset)
- reinit_decoders(mpctx);
- if (seekresult == 0)
+ if (seekresult == 0) {
+ if (need_reset) {
+ reinit_audio_chain(mpctx);
+ seek_reset(mpctx, !timeline_fallthrough, false);
+ }
return -1;
+ }
- 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);
/* Use the target time as "current position" for further relative
* seeks etc until a new video frame has been decoded */
@@ -3384,7 +3390,7 @@ int seek_chapter(struct MPContext *mpctx, int chapter, double *seek_pts)
int res = demuxer_seek_chapter(mpctx->demuxer, chapter, seek_pts);
if (res >= 0) {
if (*seek_pts == -1)
- seek_reset(mpctx, true);
+ seek_reset(mpctx, true, true);
else {
mpctx->last_chapter_seek = res;
mpctx->last_chapter_pts = *seek_pts;