summaryrefslogtreecommitdiffstats
path: root/demux/demux_mkv.c
diff options
context:
space:
mode:
Diffstat (limited to 'demux/demux_mkv.c')
-rw-r--r--demux/demux_mkv.c35
1 files changed, 26 insertions, 9 deletions
diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c
index c33fab3a2d..65c3559f55 100644
--- a/demux/demux_mkv.c
+++ b/demux/demux_mkv.c
@@ -214,6 +214,8 @@ typedef struct mkv_demuxer {
// Packets to return.
struct demux_packet **packets;
int num_packets;
+
+ bool probably_webm_dash_init;
} mkv_demuxer_t;
#define OPT_BASE_STRUCT struct demux_mkv_opts
@@ -1945,6 +1947,7 @@ static void probe_x264_garbage(demuxer_t *demuxer)
static int read_ebml_header(demuxer_t *demuxer)
{
+ mkv_demuxer_t *mkv_d = demuxer->priv;
stream_t *s = demuxer->stream;
if (ebml_read_id(s) != EBML_ID_EBML)
@@ -1953,15 +1956,22 @@ static int read_ebml_header(demuxer_t *demuxer)
struct ebml_parse_ctx parse_ctx = { demuxer->log, .no_error_messages = true };
if (ebml_read_element(s, &parse_ctx, &ebml_master, &ebml_ebml_desc) < 0)
return 0;
+ bool is_matroska = false, is_webm = false;
if (!ebml_master.doc_type) {
MP_VERBOSE(demuxer, "File has EBML header but no doctype. "
"Assuming \"matroska\".\n");
- } else if (strcmp(ebml_master.doc_type, "matroska") != 0
- && strcmp(ebml_master.doc_type, "webm") != 0) {
+ is_matroska = true;
+ } else if (strcmp(ebml_master.doc_type, "matroska") == 0) {
+ is_matroska = true;
+ } else if (strcmp(ebml_master.doc_type, "webm") == 0) {
+ is_webm = true;
+ }
+ if (!is_matroska && !is_webm) {
MP_TRACE(demuxer, "no head found\n");
talloc_free(parse_ctx.talloc_ctx);
return 0;
}
+ mkv_d->probably_webm_dash_init &= is_webm;
if (ebml_master.doc_type_read_version > 2) {
MP_WARN(demuxer, "This looks like a Matroska file, "
"but we don't support format version %"PRIu64"\n",
@@ -2029,6 +2039,15 @@ static int demux_mkv_open(demuxer_t *demuxer, enum demux_check check)
int64_t start_pos;
int64_t end_pos;
+ mkv_d = talloc_zero(demuxer, struct mkv_demuxer);
+ demuxer->priv = mkv_d;
+ mkv_d->tc_scale = 1000000;
+ mkv_d->a_skip_preroll = 1;
+ mkv_d->skip_to_timecode = INT64_MIN;
+
+ if (demuxer->params)
+ mkv_d->probably_webm_dash_init = demuxer->params->init_fragment.len > 0;
+
bstr start = stream_peek(s, 4);
uint32_t start_id = 0;
for (int n = 0; n < start.len; n++)
@@ -2043,13 +2062,8 @@ static int demux_mkv_open(demuxer_t *demuxer, enum demux_check check)
if (!read_mkv_segment_header(demuxer, &end_pos))
return -1;
- mkv_d = talloc_zero(demuxer, struct mkv_demuxer);
- demuxer->priv = mkv_d;
- mkv_d->tc_scale = 1000000;
mkv_d->segment_start = stream_tell(s);
mkv_d->segment_end = end_pos;
- mkv_d->a_skip_preroll = 1;
- mkv_d->skip_to_timecode = INT64_MIN;
mp_read_option_raw(demuxer->global, "index", &m_option_type_choice,
&mkv_d->index_mode);
@@ -2065,7 +2079,8 @@ static int demux_mkv_open(demuxer_t *demuxer, enum demux_check check)
stream_peek(s, 4); // make sure we can always seek back
uint32_t id = ebml_read_id(s);
if (s->eof) {
- MP_WARN(demuxer, "Unexpected end of file (no clusters found)\n");
+ if (!mkv_d->probably_webm_dash_init)
+ MP_WARN(demuxer, "Unexpected end of file (no clusters found)\n");
break;
}
if (id == MATROSKA_ID_CLUSTER) {
@@ -2091,7 +2106,9 @@ static int demux_mkv_open(demuxer_t *demuxer, enum demux_check check)
// Warn against incomplete files and skip headers outside of range.
if (elem->pos >= end) {
elem->parsed = true; // don't bother if file is incomplete
- if (!mkv_d->eof_warning) {
+ if (!mkv_d->eof_warning && !(mkv_d->probably_webm_dash_init &&
+ elem->pos == end))
+ {
MP_WARN(demuxer, "SeekHead position beyond "
"end of file - incomplete file?\n");
mkv_d->eof_warning = true;