mirror of https://github.com/mpv-player/mpv
demux_mkv: fix issues with unseekable streams
A user reported a webm stream that couldn't be played. The issue was that this stream 1. was on an unseekable HTTP connection, and 2. had a SeekHead element (wtf?). The code reading the SeekHead marked the element as unreadable too early: although you can't seek in the stream, reading the header elements after the SeekHead read them anyway. Marking them as unreadable only after the normal header reading fixes this. (The way the failing stream was setup was pretty retarded: inserting these SeekHead elements makes absolutely no sense for a stream that cannot be seeked.) Fixes #1656.
This commit is contained in:
parent
4ff29f33b0
commit
12dcc5eaac
|
@ -1035,9 +1035,6 @@ static int demux_mkv_read_seekhead(demuxer_t *demuxer)
|
|||
struct ebml_seek_head seekhead = {0};
|
||||
struct ebml_parse_ctx parse_ctx = {demuxer->log};
|
||||
|
||||
int64_t end = 0;
|
||||
stream_control(s, STREAM_CTRL_GET_SIZE, &end);
|
||||
|
||||
MP_VERBOSE(demuxer, "/---- [ parsing seek head ] ---------\n");
|
||||
if (ebml_read_element(s, &parse_ctx, &seekhead, &ebml_seek_head_desc) < 0) {
|
||||
res = -1;
|
||||
|
@ -1052,16 +1049,7 @@ static int demux_mkv_read_seekhead(demuxer_t *demuxer)
|
|||
uint64_t pos = seek->seek_position + mkv_d->segment_start;
|
||||
MP_DBG(demuxer, "Element 0x%x at %"PRIu64".\n",
|
||||
(unsigned)seek->seek_id, pos);
|
||||
struct header_elem *elem = get_header_element(demuxer, seek->seek_id, pos);
|
||||
// Warn against incomplete files.
|
||||
if (elem && pos >= end) {
|
||||
elem->parsed = true; // don't bother
|
||||
if (!mkv_d->eof_warning) {
|
||||
MP_WARN(demuxer, "SeekHead position beyond "
|
||||
"end of file - incomplete file?\n");
|
||||
mkv_d->eof_warning = true;
|
||||
}
|
||||
}
|
||||
get_header_element(demuxer, seek->seek_id, pos);
|
||||
}
|
||||
out:
|
||||
MP_VERBOSE(demuxer, "\\---- [ parsing seek head ] ---------\n");
|
||||
|
@ -1809,12 +1797,26 @@ static int demux_mkv_open(demuxer_t *demuxer, enum demux_check check)
|
|||
return -1;
|
||||
}
|
||||
|
||||
int64_t end = 0;
|
||||
stream_control(s, STREAM_CTRL_GET_SIZE, &end);
|
||||
|
||||
// Read headers that come after the first cluster (i.e. require seeking).
|
||||
// Note: reading might increase ->num_headers.
|
||||
// Likewise, ->headers might be reallocated.
|
||||
for (int n = 0; n < mkv_d->num_headers; n++) {
|
||||
struct header_elem *elem = &mkv_d->headers[n];
|
||||
if (elem->id == MATROSKA_ID_CUES && !elem->parsed) {
|
||||
if (elem->parsed)
|
||||
continue;
|
||||
// Warn against incomplete files.
|
||||
if (elem->pos >= end) {
|
||||
elem->parsed = true; // don't bother if file is incomplete
|
||||
if (!mkv_d->eof_warning) {
|
||||
MP_WARN(demuxer, "SeekHead position beyond "
|
||||
"end of file - incomplete file?\n");
|
||||
mkv_d->eof_warning = true;
|
||||
}
|
||||
}
|
||||
if (elem->id == MATROSKA_ID_CUES) {
|
||||
// Read cues when they are needed, to avoid seeking on opening.
|
||||
MP_VERBOSE(demuxer, "Deferring reading cues.\n");
|
||||
continue;
|
||||
|
|
Loading…
Reference in New Issue