1
mirror of https://github.com/mpv-player/mpv synced 2024-10-22 08:51:57 +02:00

demux_mkv: use new EBML parser for file header

This commit is contained in:
Uoti Urpala 2010-01-25 02:43:27 +02:00
parent 5f631d1c08
commit 8b0726b28a
3 changed files with 29 additions and 79 deletions

View File

@ -2018,16 +2018,40 @@ static int demux_mkv_open(demuxer_t *demuxer)
stream_t *s = demuxer->stream;
mkv_demuxer_t *mkv_d;
mkv_track_t *track;
int i, version, cont = 0;
char *str;
int i, cont = 0;
stream_seek(s, s->start_pos);
str = ebml_read_header(s, &version);
if (str == NULL || strcmp(str, "matroska") || version > 2) {
if (ebml_read_id(s, NULL) != EBML_ID_EBML)
return 0;
struct ebml_ebml ebml_master = {};
struct ebml_parse_ctx parse_ctx = { .no_error_messages = true };
if (ebml_read_element(s, &parse_ctx, &ebml_master, &ebml_ebml_desc) < 0)
return 0;
if (ebml_master.doc_type.len != 8 || strncmp(ebml_master.doc_type.start,
"matroska", 8)) {
mp_msg(MSGT_DEMUX, MSGL_DBG2, "[mkv] no head found\n");
talloc_free(parse_ctx.talloc_ctx);
return 0;
}
free(str);
if (ebml_master.doc_type_read_version > 2) {
mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] This looks like a Matroska file, "
"but we don't support format version %"PRIu64"\n",
ebml_master.doc_type_read_version);
talloc_free(parse_ctx.talloc_ctx);
return 0;
}
if ((ebml_master.n_ebml_read_version
&& ebml_master.ebml_read_version != EBML_VERSION)
|| (ebml_master.n_ebml_max_size_length
&& ebml_master.ebml_max_size_length > 8)
|| (ebml_master.n_ebml_max_id_length
&& ebml_master.ebml_max_id_length != 4)) {
mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] This looks like a Matroska file, "
"but the header has bad parameters\n");
talloc_free(parse_ctx.talloc_ctx);
return 0;
}
talloc_free(parse_ctx.talloc_ctx);
mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] Found the head...\n");

View File

@ -285,79 +285,6 @@ uint32_t ebml_read_master(stream_t *s, uint64_t *length)
}
/*
* Read an EBML header.
*/
char *ebml_read_header(stream_t *s, int *version)
{
uint64_t length, l, num;
uint32_t id;
char *str = NULL;
if (ebml_read_master(s, &length) != EBML_ID_EBML)
return 0;
if (version)
*version = 1;
while (length > 0) {
id = ebml_read_id(s, NULL);
if (id == EBML_ID_INVALID)
return NULL;
length -= 2;
switch (id) {
/* is our read version uptodate? */
case EBML_ID_EBMLREADVERSION:
num = ebml_read_uint(s, &l);
if (num != EBML_VERSION)
return NULL;
break;
/* we only handle 8 byte lengths at max */
case EBML_ID_EBMLMAXSIZELENGTH:
num = ebml_read_uint(s, &l);
if (num != sizeof(uint64_t))
return NULL;
break;
/* we handle 4 byte IDs at max */
case EBML_ID_EBMLMAXIDLENGTH:
num = ebml_read_uint(s, &l);
if (num != sizeof(uint32_t))
return NULL;
break;
case EBML_ID_DOCTYPE:
str = ebml_read_ascii(s, &l);
if (str == NULL)
return NULL;
break;
case EBML_ID_DOCTYPEREADVERSION:
num = ebml_read_uint(s, &l);
if (num == EBML_UINT_INVALID)
return NULL;
if (version)
*version = num;
break;
/* we ignore these two, they don't tell us anything we care about */
case EBML_ID_VOID:
case EBML_ID_EBMLVERSION:
case EBML_ID_DOCTYPEVERSION:
default:
if (ebml_read_skip(s, &l))
return NULL;
break;
}
length -= l;
}
return str;
}
#define EVALARGS(F, ...) F(__VA_ARGS__)
#define E(str, N, type) const struct ebml_elem_desc ebml_ ## N ## _desc = { str, type };

View File

@ -109,7 +109,6 @@ char *ebml_read_ascii (stream_t *s, uint64_t *length);
char *ebml_read_utf8 (stream_t *s, uint64_t *length);
int ebml_read_skip (stream_t *s, uint64_t *length);
uint32_t ebml_read_master (stream_t *s, uint64_t *length);
char *ebml_read_header (stream_t *s, int *version);
int ebml_read_element(struct stream *s, struct ebml_parse_ctx *ctx,
void *target, const struct ebml_elem_desc *desc);