summaryrefslogtreecommitdiffstats
path: root/demux/demux_mkv.c
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 /demux/demux_mkv.c
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.
Diffstat (limited to 'demux/demux_mkv.c')
-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;