summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-09-08 05:09:16 +0200
committerwm4 <wm4@nowhere>2013-09-08 07:47:26 +0200
commit7dbed3f0191caf891ee60a6ebf513944e3a36914 (patch)
treec4a737fc1f68f559cae6559403f29577a55148b3
parentecd2d90190176b963b99b1cf6b248ad04f3f2c34 (diff)
downloadmpv-7dbed3f0191caf891ee60a6ebf513944e3a36914.tar.bz2
mpv-7dbed3f0191caf891ee60a6ebf513944e3a36914.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 9fc1c6f0bb..e4f40ba212 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
@@ -2266,7 +2269,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 "
@@ -2313,7 +2319,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;
@@ -2594,7 +2600,10 @@ static void demux_mkv_seek(demuxer_t *demuxer, float rel_seek_secs,
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;