matroskadec: Support webm doctype
authorJames Zern <jzern@google.com>
Sat, 22 May 2010 01:41:32 +0000 (01:41 +0000)
committerDavid Conrad <lessen42@gmail.com>
Sat, 22 May 2010 01:41:32 +0000 (01:41 +0000)
Patch by James Zern <jzern at google>

Originally committed as revision 23245 to svn://svn.ffmpeg.org/ffmpeg/trunk

Changelog
doc/general.texi
libavformat/avformat.h
libavformat/matroskadec.c

index b5c5782..c3ea45b 100644 (file)
--- a/Changelog
+++ b/Changelog
@@ -71,6 +71,7 @@ version <next>:
 - spectral extension support in the E-AC-3 decoder
 - unsharp video filter
 - RTP hinting in the mov/3gp/mp4 muxer
 - spectral extension support in the E-AC-3 decoder
 - unsharp video filter
 - RTP hinting in the mov/3gp/mp4 muxer
+- WebM support in Matroska demuxer
 
 
 
 
 
 
index 1bfde02..bb199f6 100644 (file)
@@ -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 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
 @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
index 88cabc5..91d6911 100644 (file)
@@ -22,7 +22,7 @@
 #define AVFORMAT_AVFORMAT_H
 
 #define LIBAVFORMAT_VERSION_MAJOR 52
 #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, \
 #define LIBAVFORMAT_VERSION_MICRO  0
 
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
index 1bde1af..e5d34d7 100644 (file)
@@ -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)
 static int matroska_probe(AVProbeData *p)
 {
     uint64_t total = 0;
 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)
 
     /* EBML header? */
     if (AV_RB32(p->buf) != EBML_ID_HEADER)
@@ -848,13 +849,16 @@ static int matroska_probe(AVProbeData *p)
     if (p->buf_size < 4 + size + total)
       return 0;
 
     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. */
      * 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;
 }
 
     return 0;
 }
@@ -1141,14 +1145,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)
     /* 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);
         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;
     }
         return AVERROR_PATCHWELCOME;
     }
+    av_metadata_set2(&s->metadata, "doctype", ebml.doctype, 0);
     ebml_free(ebml_syntax, &ebml);
 
     /* The next thing is a segment. */
     ebml_free(ebml_syntax, &ebml);
 
     /* The next thing is a segment. */