OSDN Git Service

The length information of the chunks making up vorbis codec specific info
authorAndreas Huber <andih@google.com>
Wed, 14 Nov 2012 23:24:53 +0000 (15:24 -0800)
committerAndreas Huber <andih@google.com>
Thu, 15 Nov 2012 17:47:02 +0000 (09:47 -0800)
are "Xiph-style-lacing encoded" instead of individual bytes.

Change-Id: Ic1274a5bd8f082197bae6831da04002762a920c5
related-to-bug: 7401329

media/libstagefright/codecs/on2/dec/SoftVPX.cpp
media/libstagefright/matroska/MatroskaExtractor.cpp

index bf9ab3a..a400b4c 100644 (file)
@@ -66,7 +66,7 @@ void SoftVPX::initPorts() {
     def.eDir = OMX_DirInput;
     def.nBufferCountMin = kNumBuffers;
     def.nBufferCountActual = def.nBufferCountMin;
-    def.nBufferSize = 256 * 1024;
+    def.nBufferSize = 768 * 1024;
     def.bEnabled = OMX_TRUE;
     def.bPopulated = OMX_FALSE;
     def.eDomain = OMX_PortDomainVideo;
index 8f7d12b..7fc7037 100644 (file)
@@ -758,31 +758,69 @@ static void addESDSFromCodecPrivate(
     esds = NULL;
 }
 
-void addVorbisCodecInfo(
+status_t addVorbisCodecInfo(
         const sp<MetaData> &meta,
         const void *_codecPrivate, size_t codecPrivateSize) {
-    // printf("vorbis private data follows:\n");
     // hexdump(_codecPrivate, codecPrivateSize);
 
-    CHECK(codecPrivateSize >= 3);
+    if (codecPrivateSize < 1) {
+        return ERROR_MALFORMED;
+    }
 
     const uint8_t *codecPrivate = (const uint8_t *)_codecPrivate;
-    CHECK(codecPrivate[0] == 0x02);
 
-    size_t len1 = codecPrivate[1];
-    size_t len2 = codecPrivate[2];
+    if (codecPrivate[0] != 0x02) {
+        return ERROR_MALFORMED;
+    }
 
-    CHECK(codecPrivateSize > 3 + len1 + len2);
+    // codecInfo starts with two lengths, len1 and len2, that are
+    // "Xiph-style-lacing encoded"...
 
-    CHECK(codecPrivate[3] == 0x01);
-    meta->setData(kKeyVorbisInfo, 0, &codecPrivate[3], len1);
+    size_t offset = 1;
+    size_t len1 = 0;
+    while (offset < codecPrivateSize && codecPrivate[offset] == 0xff) {
+        len1 += 0xff;
+        ++offset;
+    }
+    if (offset >= codecPrivateSize) {
+        return ERROR_MALFORMED;
+    }
+    len1 += codecPrivate[offset++];
 
-    CHECK(codecPrivate[len1 + 3] == 0x03);
+    size_t len2 = 0;
+    while (offset < codecPrivateSize && codecPrivate[offset] == 0xff) {
+        len2 += 0xff;
+        ++offset;
+    }
+    if (offset >= codecPrivateSize) {
+        return ERROR_MALFORMED;
+    }
+    len2 += codecPrivate[offset++];
+
+    if (codecPrivateSize < offset + len1 + len2) {
+        return ERROR_MALFORMED;
+    }
+
+    if (codecPrivate[offset] != 0x01) {
+        return ERROR_MALFORMED;
+    }
+    meta->setData(kKeyVorbisInfo, 0, &codecPrivate[offset], len1);
+
+    offset += len1;
+    if (codecPrivate[offset] != 0x03) {
+        return ERROR_MALFORMED;
+    }
+
+    offset += len2;
+    if (codecPrivate[offset] != 0x05) {
+        return ERROR_MALFORMED;
+    }
 
-    CHECK(codecPrivate[len1 + len2 + 3] == 0x05);
     meta->setData(
-            kKeyVorbisBooks, 0, &codecPrivate[len1 + len2 + 3],
-            codecPrivateSize - len1 - len2 - 3);
+            kKeyVorbisBooks, 0, &codecPrivate[offset],
+            codecPrivateSize - offset);
+
+    return OK;
 }
 
 void MatroskaExtractor::addTracks() {
@@ -809,6 +847,8 @@ void MatroskaExtractor::addTracks() {
 
         sp<MetaData> meta = new MetaData;
 
+        status_t err = OK;
+
         switch (track->GetType()) {
             case VIDEO_TRACK:
             {
@@ -855,7 +895,8 @@ void MatroskaExtractor::addTracks() {
                 } else if (!strcmp("A_VORBIS", codecID)) {
                     meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_VORBIS);
 
-                    addVorbisCodecInfo(meta, codecPrivate, codecPrivateSize);
+                    err = addVorbisCodecInfo(
+                            meta, codecPrivate, codecPrivateSize);
                 } else if (!strcmp("A_MPEG/L3", codecID)) {
                     meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
                 } else {
@@ -872,6 +913,11 @@ void MatroskaExtractor::addTracks() {
                 continue;
         }
 
+        if (err != OK) {
+            ALOGE("skipping track, codec specific data was malformed.");
+            continue;
+        }
+
         long long durationNs = mSegment->GetDuration();
         meta->setInt64(kKeyDuration, (durationNs + 500) / 1000);