Commit 89970543 authored by conrad's avatar conrad

matroskadec: Support webm doctype

Patch by James Zern <jzern at google>

git-svn-id: file:///var/local/repositories/ffmpeg/trunk@23245 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b
parent de300a55
...@@ -71,6 +71,7 @@ version <next>: ...@@ -71,6 +71,7 @@ version <next>:
- spectral extension support in the E-AC-3 decoder - spectral extension support in the E-AC-3 decoder
- unsharp video filter - unsharp video filter
- RTP hinting in the mov/3gp/mp4 muxer - RTP hinting in the mov/3gp/mp4 muxer
- WebM support in Matroska demuxer
......
...@@ -234,6 +234,7 @@ library: ...@@ -234,6 +234,7 @@ library:
@item VC-1 test bitstream @tab X @tab X @item VC-1 test bitstream @tab X @tab X
@item WAV @tab X @tab X @item WAV @tab X @tab X
@item WavPack @tab @tab X @item WavPack @tab @tab X
@item WebM @tab @tab X
@item Wing Commander III movie @tab @tab X @item Wing Commander III movie @tab @tab X
@tab Multimedia format used in Origin's Wing Commander III computer game. @tab Multimedia format used in Origin's Wing Commander III computer game.
@item Westwood Studios audio @tab @tab X @item Westwood Studios audio @tab @tab X
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#define AVFORMAT_AVFORMAT_H #define AVFORMAT_AVFORMAT_H
#define LIBAVFORMAT_VERSION_MAJOR 52 #define LIBAVFORMAT_VERSION_MAJOR 52
#define LIBAVFORMAT_VERSION_MINOR 63 #define LIBAVFORMAT_VERSION_MINOR 64
#define LIBAVFORMAT_VERSION_MICRO 0 #define LIBAVFORMAT_VERSION_MICRO 0
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
......
...@@ -505,6 +505,8 @@ static EbmlSyntax matroska_clusters[] = { ...@@ -505,6 +505,8 @@ static EbmlSyntax matroska_clusters[] = {
{ 0 } { 0 }
}; };
static const char *matroska_doctypes[] = { "matroska", "webm" };
/* /*
* Return: Whether we reached the end of a level in the hierarchy or not. * Return: Whether we reached the end of a level in the hierarchy or not.
*/ */
...@@ -825,8 +827,7 @@ static void ebml_free(EbmlSyntax *syntax, void *data) ...@@ -825,8 +827,7 @@ static void ebml_free(EbmlSyntax *syntax, void *data)
static int matroska_probe(AVProbeData *p) static int matroska_probe(AVProbeData *p)
{ {
uint64_t total = 0; uint64_t total = 0;
int len_mask = 0x80, size = 1, n = 1; int len_mask = 0x80, size = 1, n = 1, i;
static const char probe_data[] = "matroska";
/* EBML header? */ /* EBML header? */
if (AV_RB32(p->buf) != EBML_ID_HEADER) if (AV_RB32(p->buf) != EBML_ID_HEADER)
...@@ -848,13 +849,16 @@ static int matroska_probe(AVProbeData *p) ...@@ -848,13 +849,16 @@ static int matroska_probe(AVProbeData *p)
if (p->buf_size < 4 + size + total) if (p->buf_size < 4 + size + total)
return 0; return 0;
/* The header must contain the document type 'matroska'. For now, /* The header should contain a known document type. For now,
* we don't parse the whole header but simply check for the * we don't parse the whole header but simply check for the
* availability of that array of characters inside the header. * availability of that array of characters inside the header.
* Not fully fool-proof, but good enough. */ * Not fully fool-proof, but good enough. */
for (n = 4+size; n <= 4+size+total-(sizeof(probe_data)-1); n++) for (i = 0; i < FF_ARRAY_ELEMS(matroska_doctypes); i++) {
if (!memcmp(p->buf+n, probe_data, sizeof(probe_data)-1)) int probelen = strlen(matroska_doctypes[i]);
return AVPROBE_SCORE_MAX; for (n = 4+size; n <= 4+size+total-probelen; n++)
if (!memcmp(p->buf+n, matroska_doctypes[i], probelen))
return AVPROBE_SCORE_MAX;
}
return 0; return 0;
} }
...@@ -1141,14 +1145,23 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap) ...@@ -1141,14 +1145,23 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
/* First read the EBML header. */ /* First read the EBML header. */
if (ebml_parse(matroska, ebml_syntax, &ebml) if (ebml_parse(matroska, ebml_syntax, &ebml)
|| ebml.version > EBML_VERSION || ebml.max_size > sizeof(uint64_t) || ebml.version > EBML_VERSION || ebml.max_size > sizeof(uint64_t)
|| ebml.id_length > sizeof(uint32_t) || strcmp(ebml.doctype, "matroska") || ebml.id_length > sizeof(uint32_t) || ebml.doctype_version > 2) {
|| ebml.doctype_version > 2) {
av_log(matroska->ctx, AV_LOG_ERROR, av_log(matroska->ctx, AV_LOG_ERROR,
"EBML header using unsupported features\n" "EBML header using unsupported features\n"
"(EBML version %"PRIu64", doctype %s, doc version %"PRIu64")\n", "(EBML version %"PRIu64", doctype %s, doc version %"PRIu64")\n",
ebml.version, ebml.doctype, ebml.doctype_version); ebml.version, ebml.doctype, ebml.doctype_version);
ebml_free(ebml_syntax, &ebml);
return AVERROR_PATCHWELCOME;
}
for (i = 0; i < FF_ARRAY_ELEMS(matroska_doctypes); i++)
if (!strcmp(ebml.doctype, matroska_doctypes[i]))
break;
if (i >= FF_ARRAY_ELEMS(matroska_doctypes)) {
av_log(s, AV_LOG_ERROR, "Unknown EBML doctype '%s'\n", ebml.doctype);
ebml_free(ebml_syntax, &ebml);
return AVERROR_PATCHWELCOME; return AVERROR_PATCHWELCOME;
} }
av_metadata_set2(&s->metadata, "doctype", ebml.doctype, 0);
ebml_free(ebml_syntax, &ebml); ebml_free(ebml_syntax, &ebml);
/* The next thing is a segment. */ /* The next thing is a segment. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment