1
0
mirror of https://github.com/mpv-player/mpv synced 2025-04-01 14:50:07 +00:00

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.
This commit is contained in:
wm4 2013-09-08 05:09:16 +02:00
parent 7f398f833e
commit 222b8c6e02

View File

@ -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;