summaryrefslogtreecommitdiffstats
path: root/demux
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2019-06-13 19:33:04 +0200
committerwm4 <wm4@nowhere>2019-09-19 20:37:05 +0200
commit95c97cd66e2fd2e79565d1ef563a19ad6d96b071 (patch)
tree8b329bb78ccafa52ebd9814fb612965baa8a33eb /demux
parent17da9071a4a524139e2ef945ed6cde17dd08c99c (diff)
downloadmpv-95c97cd66e2fd2e79565d1ef563a19ad6d96b071.tar.bz2
mpv-95c97cd66e2fd2e79565d1ef563a19ad6d96b071.tar.xz
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.
Diffstat (limited to 'demux')
-rw-r--r--demux/demux.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/demux/demux.c b/demux/demux.c
index b9101a3054..5c7cfcbd55 100644
--- a/demux/demux.c
+++ b/demux/demux.c
@@ -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;
}