summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-03-06 15:06:59 +0100
committerwm4 <wm4@nowhere>2015-03-06 15:06:59 +0100
commit12dcc5eaacdabb5ac56846ee81e9595857f4553e (patch)
treef2b75b5d877081b988017f426cb72529407fef53
parent4ff29f33b0d86888a02524df5d6085c4bc29477e (diff)
downloadmpv-12dcc5eaacdabb5ac56846ee81e9595857f4553e.tar.bz2
mpv-12dcc5eaacdabb5ac56846ee81e9595857f4553e.tar.xz
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.
-rw-r--r--demux/demux_mkv.c30
1 files changed, 16 insertions, 14 deletions
diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c
index d19d50aab1..f46203111b 100644
--- a/demux/demux_mkv.c
+++ b/demux/demux_mkv.c
@@ -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;