summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Zern <jzern@google.com>2010-05-25 18:20:59 +0000
committerReinhard Tartler <siretart@tauware.de>2010-05-25 18:20:59 +0000
commit9d3bb3501de9c9221c90a5ef22ba899e29fbd231 (patch)
tree7a6ebdff0eb1d11dab5a1e2d2f21c2589b9c9023
parent0b374e40b1df87d21c6870e998849dd51027c637 (diff)
matroskadec: Support webm doctype
Patch by James Zern <jzern at google> backport r23245 by conrad Originally committed as revision 23313 to svn://svn.ffmpeg.org/ffmpeg/branches/0.6
-rw-r--r--Changelog1
-rw-r--r--doc/general.texi1
-rw-r--r--libavformat/avformat.h2
-rw-r--r--libavformat/matroskadec.c29
4 files changed, 24 insertions, 9 deletions
diff --git a/Changelog b/Changelog
index 09587f8670..76f6a89a3f 100644
--- a/Changelog
+++ b/Changelog
@@ -78,6 +78,7 @@ version 0.6:
- faster AAC decoding
- faster H.264 decoding
- low overhead Ogg muxing
+- WebM support in Matroska demuxer
diff --git a/doc/general.texi b/doc/general.texi
index 1bfde02bc2..bb199f6501 100644
--- a/doc/general.texi
+++ b/doc/general.texi
@@ -234,6 +234,7 @@ library:
@item VC-1 test bitstream @tab X @tab X
@item WAV @tab X @tab X
@item WavPack @tab @tab X
+@item WebM @tab @tab X
@item Wing Commander III movie @tab @tab X
@tab Multimedia format used in Origin's Wing Commander III computer game.
@item Westwood Studios audio @tab @tab X
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 3b77b2d121..48c5061d49 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -22,7 +22,7 @@
#define AVFORMAT_AVFORMAT_H
#define LIBAVFORMAT_VERSION_MAJOR 52
-#define LIBAVFORMAT_VERSION_MINOR 63
+#define LIBAVFORMAT_VERSION_MINOR 64
#define LIBAVFORMAT_VERSION_MICRO 0
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index 90356d818b..df7edac131 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -505,6 +505,8 @@ static EbmlSyntax matroska_clusters[] = {
{ 0 }
};
+static const char *matroska_doctypes[] = { "matroska", "webm" };
+
/*
* Return: Whether we reached the end of a level in the hierarchy or not.
*/
@@ -823,8 +825,7 @@ static void ebml_free(EbmlSyntax *syntax, void *data)
static int matroska_probe(AVProbeData *p)
{
uint64_t total = 0;
- int len_mask = 0x80, size = 1, n = 1;
- static const char probe_data[] = "matroska";
+ int len_mask = 0x80, size = 1, n = 1, i;
/* EBML header? */
if (AV_RB32(p->buf) != EBML_ID_HEADER)
@@ -846,13 +847,16 @@ static int matroska_probe(AVProbeData *p)
if (p->buf_size < 4 + size + total)
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
* availability of that array of characters inside the header.
* Not fully fool-proof, but good enough. */
- for (n = 4+size; n <= 4+size+total-(sizeof(probe_data)-1); n++)
- if (!memcmp(p->buf+n, probe_data, sizeof(probe_data)-1))
- return AVPROBE_SCORE_MAX;
+ for (i = 0; i < FF_ARRAY_ELEMS(matroska_doctypes); i++) {
+ int probelen = strlen(matroska_doctypes[i]);
+ 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;
}
@@ -1139,14 +1143,23 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
/* First read the EBML header. */
if (ebml_parse(matroska, ebml_syntax, &ebml)
|| ebml.version > EBML_VERSION || ebml.max_size > sizeof(uint64_t)
- || ebml.id_length > sizeof(uint32_t) || strcmp(ebml.doctype, "matroska")
- || ebml.doctype_version > 2) {
+ || ebml.id_length > sizeof(uint32_t) || ebml.doctype_version > 2) {
av_log(matroska->ctx, AV_LOG_ERROR,
"EBML header using unsupported features\n"
"(EBML version %"PRIu64", doctype %s, doc version %"PRIu64")\n",
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;
}
+ av_metadata_set2(&s->metadata, "doctype", ebml.doctype, 0);
ebml_free(ebml_syntax, &ebml);
/* The next thing is a segment. */