mirror of
https://github.com/mpv-player/mpv
synced 2025-03-19 01:47:38 +00:00
demux: fix assertion when switching tracks during backward playback
Someone who rams a knife into his own hand just to see what happens is normally put in a psychiatric ward. But in software, this is acceptable behavior. Programs are not supposed to crash just because a user did something unreasonably dumb. Switching tracks during backward playback is such a thing. It triggered an assertion because the newly enabled stream was not properly initialized for backward playback. Fix this, and make it actually work (mostly; it still takes a "while" until playback recovers fully). This actually makes some aspects of initialization slightly cleaner.
This commit is contained in:
parent
60a0db39aa
commit
b9250569cd
@ -787,8 +787,8 @@ static void ds_clear_reader_state(struct demux_stream *ds,
|
||||
ds->back_restart_pos = -1;
|
||||
ds->back_restart_dts = MP_NOPTS_VALUE;
|
||||
ds->back_restart_eof = false;
|
||||
ds->back_restart_next = false;
|
||||
ds->back_restarting = false;
|
||||
ds->back_restart_next = ds->in->back_demuxing;
|
||||
ds->back_restarting = ds->in->back_demuxing && ds->eager;
|
||||
ds->back_seek_pos = MP_NOPTS_VALUE;
|
||||
ds->back_resume_pos = -1;
|
||||
ds->back_resume_dts = MP_NOPTS_VALUE;
|
||||
@ -821,8 +821,6 @@ static void update_stream_selection_state(struct demux_internal *in,
|
||||
ds->eof = false;
|
||||
ds->refreshing = false;
|
||||
|
||||
ds_clear_reader_state(ds, true);
|
||||
|
||||
// We still have to go over the whole stream list to update ds->eager for
|
||||
// other streams too, because they depend on other stream's selections.
|
||||
|
||||
@ -862,6 +860,8 @@ static void update_stream_selection_state(struct demux_internal *in,
|
||||
if (!any_streams)
|
||||
in->blocked = false;
|
||||
|
||||
ds_clear_reader_state(ds, true);
|
||||
|
||||
// Make sure any stream reselection or addition is reflected in the seek
|
||||
// ranges, and also get rid of data that is not needed anymore (or
|
||||
// rather, which can't be kept consistent). This has to happen after we've
|
||||
@ -1511,8 +1511,10 @@ resume_earlier:
|
||||
}
|
||||
}
|
||||
|
||||
ds->back_seek_pos -= in->opts->back_seek_size;
|
||||
in->need_back_seek = true;
|
||||
if (ds->back_seek_pos != MP_NOPTS_VALUE) {
|
||||
ds->back_seek_pos -= in->opts->back_seek_size;
|
||||
in->need_back_seek = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Process that one or multiple packets were added.
|
||||
@ -3347,14 +3349,14 @@ static bool queue_seek(struct demux_internal *in, double seek_pts, int flags,
|
||||
}
|
||||
}
|
||||
|
||||
clear_reader_state(in, clear_back_state);
|
||||
|
||||
in->eof = false;
|
||||
in->last_eof = false;
|
||||
in->idle = true;
|
||||
in->reading = false;
|
||||
in->back_demuxing = set_backwards;
|
||||
|
||||
clear_reader_state(in, clear_back_state);
|
||||
|
||||
if (cache_target) {
|
||||
execute_cache_seek(in, cache_target, seek_pts, flags);
|
||||
} else {
|
||||
@ -3368,22 +3370,15 @@ static bool queue_seek(struct demux_internal *in, double seek_pts, int flags,
|
||||
for (int n = 0; n < in->num_streams; n++) {
|
||||
struct demux_stream *ds = in->streams[n]->ds;
|
||||
|
||||
if (in->back_demuxing && clear_back_state) {
|
||||
// Process possibly cached packets.
|
||||
if (in->back_demuxing) {
|
||||
ds->back_seek_pos = seek_pts;
|
||||
ds->back_restarting = ds->eager;
|
||||
ds->back_restart_next = true;
|
||||
back_demux_see_packets(in->streams[n]->ds);
|
||||
}
|
||||
|
||||
wakeup_ds(ds);
|
||||
}
|
||||
|
||||
if (in->back_demuxing) {
|
||||
// Process possibly cached packets. Separate from the loop above, since
|
||||
// all flags must be set on all streams before this function is called.
|
||||
for (int n = 0; n < in->num_streams; n++)
|
||||
back_demux_see_packets(in->streams[n]->ds);
|
||||
}
|
||||
|
||||
if (!in->threading && in->seeking)
|
||||
execute_seek(in);
|
||||
|
||||
@ -3488,14 +3483,19 @@ void demuxer_select_track(struct demuxer *demuxer, struct sh_stream *stream,
|
||||
struct demux_internal *in = demuxer->in;
|
||||
struct demux_stream *ds = stream->ds;
|
||||
pthread_mutex_lock(&in->lock);
|
||||
ref_pts = MP_ADD_PTS(ref_pts, -in->ts_offset);
|
||||
// don't flush buffers if stream is already selected / unselected
|
||||
if (ds->selected != selected) {
|
||||
MP_VERBOSE(in, "%sselect track %d\n", selected ? "" : "de", stream->index);
|
||||
ds->selected = selected;
|
||||
update_stream_selection_state(in, ds);
|
||||
in->tracks_switched = true;
|
||||
if (ds->selected && !in->after_seek)
|
||||
initiate_refresh_seek(in, ds, MP_ADD_PTS(ref_pts, -in->ts_offset));
|
||||
if (ds->selected) {
|
||||
if (in->back_demuxing)
|
||||
ds->back_seek_pos = ref_pts;
|
||||
if (!in->after_seek)
|
||||
initiate_refresh_seek(in, ds, ref_pts);
|
||||
}
|
||||
if (in->threading) {
|
||||
pthread_cond_signal(&in->wakeup);
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user