summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-09-08 05:09:16 +0200
committerwm4 <wm4@nowhere>2013-09-08 05:09:16 +0200
commit222b8c6e0291c791391c572d273d4708bcd3b34f (patch)
tree8f7c036c0a9117a73559f9e4928d775e4e53dfd6
parent7f398f833e51dd68e175fbc7585fc29e5dc80f6b (diff)
downloadmpv-222b8c6e0291c791391c572d273d4708bcd3b34f.tar.bz2
mpv-222b8c6e0291c791391c572d273d4708bcd3b34f.tar.xz
demux_mkv: don't overflow packet queue when doing sub-preroll
Consider the cluster used for prerolling contains an insane amount of subtitle packets. Then the demuxer packet queue would be full of subtitle packets, and demux.c would refuse to read any further packets - including video and audio packets, resulting in EOF. Since everything involving Matroska and subtitles is 100% insane, this can actually happen. Fix this by putting a limit on the number of subtitle packets read by preroll, and throw away any further packets if the limit is exceeded. If this happens, the preroll mechanism will stop working, but the player's operation is unaffected otherwise.
-rw-r--r--demux/demux_mkv.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c
index 3e902c0ea3..a391dde5a6 100644
--- a/demux/demux_mkv.c
+++ b/demux/demux_mkv.c
@@ -188,7 +188,7 @@ typedef struct mkv_demuxer {
uint64_t skip_to_timecode;
int v_skip_to_keyframe, a_skip_to_keyframe;
- bool subtitle_preroll;
+ int subtitle_preroll;
} mkv_demuxer_t;
#define REALHEADER_SIZE 16
@@ -196,6 +196,9 @@ typedef struct mkv_demuxer {
#define RAPROPERTIES4_SIZE 56
#define RAPROPERTIES5_SIZE 70
+// Maximum number of subtitle packets that are accepted for pre-roll.
+#define NUM_SUB_PREROLL_PACKETS 100
+
/**
* \brief ensures there is space for at least one additional element
* \param array array to grow
@@ -2269,7 +2272,10 @@ static int handle_block(demuxer_t *demuxer, struct block_info *block_info)
if (mkv_d->v_skip_to_keyframe)
use_this_block = 0;
} else if (track->type == MATROSKA_TRACK_SUBTITLE) {
- use_this_block |= mkv_d->subtitle_preroll;
+ if (!use_this_block && mkv_d->subtitle_preroll) {
+ mkv_d->subtitle_preroll--;
+ use_this_block = 1;
+ }
if (use_this_block) {
if (laces > 1) {
mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] Subtitles use Matroska "
@@ -2316,7 +2322,7 @@ static int handle_block(demuxer_t *demuxer, struct block_info *block_info)
if (stream->type == STREAM_VIDEO) {
mkv_d->v_skip_to_keyframe = 0;
mkv_d->skip_to_timecode = 0;
- mkv_d->subtitle_preroll = false;
+ mkv_d->subtitle_preroll = 0;
} else if (stream->type == STREAM_AUDIO)
mkv_d->a_skip_to_keyframe = 0;
@@ -2596,7 +2602,10 @@ static void demux_mkv_seek(demuxer_t *demuxer, float rel_seek_secs, int flags)
a_tnum = track->tnum;
}
}
- mkv_d->subtitle_preroll = (flags & SEEK_SUBPREROLL) && st_active[STREAM_SUB];
+ mkv_d->subtitle_preroll = 0;
+ if ((flags & SEEK_SUBPREROLL) && st_active[STREAM_SUB] &&
+ st_active[STREAM_VIDEO])
+ mkv_d->subtitle_preroll = NUM_SUB_PREROLL_PACKETS;
if (!(flags & (SEEK_BACKWARD | SEEK_FORWARD))) {
if (flags & SEEK_ABSOLUTE || rel_seek_secs < 0)
flags |= SEEK_BACKWARD;