demux: disable backward demuxing if it fatally fails

We don't care much about this case, because backward playback can fail
terribly without a good way to detect it, so this was fine.

However, this froze in certain situations. Reading from a subtitle file
for which backward demuxing failed could make it get stuck in
demux_read_packet_async() in unthreaded mode. (That we don't support
backwards subtitle decoding anyway doesn't matter for this.)

So aggressively disable backward demuxing to prevent worse in these
situations. The behavior will still be awful, because the frontend is
still in backwards playback mode, but at least it won't freeze.
This commit is contained in:
wm4 2019-06-13 19:33:04 +02:00
parent 17da9071a4
commit 95c97cd66e
1 changed files with 13 additions and 0 deletions

View File

@ -416,6 +416,8 @@ static void add_packet_locked(struct sh_stream *stream, demux_packet_t *dp);
static struct demux_packet *advance_reader_head(struct demux_stream *ds);
static bool queue_seek(struct demux_internal *in, double seek_pts, int flags,
bool clear_back_state);
static void clear_reader_state(struct demux_internal *in,
bool clear_back_state);
static uint64_t get_foward_buffered_bytes(struct demux_stream *ds)
{
@ -1237,6 +1239,15 @@ void demuxer_feed_caption(struct sh_stream *stream, demux_packet_t *dp)
pthread_mutex_unlock(&in->lock);
}
static void error_on_backward_demuxing(struct demux_internal *in)
{
if (!in->back_demuxing)
return;
MP_ERR(in, "Disabling backward demuxing.\n");
in->back_demuxing = false;
clear_reader_state(in, true);
}
static void perform_backward_seek(struct demux_internal *in)
{
double target = MP_NOPTS_VALUE;
@ -1351,6 +1362,7 @@ static void find_backward_restart_pos(struct demux_stream *ds)
// The packet should have been in the searched range; maybe dts/pos
// determinism assumptions were broken.
MP_ERR(in, "Demuxer not cooperating.\n");
error_on_backward_demuxing(in);
return;
}
}
@ -1492,6 +1504,7 @@ static void back_demux_see_packets(struct demux_stream *ds)
if (!ds->global_correct_dts && !ds->global_correct_pos) {
MP_ERR(in, "Can't demux backward due to demuxer problems.\n");
error_on_backward_demuxing(in);
return;
}