Bug 1093567 - Don't loop forever looking for mp4 tracks. r=ajones, a=lsblakk
authorRalph Giles <giles@mozilla.com>
Mon, 17 Nov 2014 16:20:00 -0800
changeset 234015 4e51a5678a9be5a0e5b6872f7557bfd188001fb0
parent 234014 fcc41d2a915832092041005e1291ba993b2dce89
child 234016 aeb38e969a422f461dd88e4730ab7001e0db924f
push id4187
push userbhearsum@mozilla.com
push dateFri, 28 Nov 2014 15:29:12 +0000
treeherdermozilla-beta@f23cc6a30c11 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersajones, lsblakk
bugs1093567
milestone35.0a2
Bug 1093567 - Don't loop forever looking for mp4 tracks. r=ajones, a=lsblakk We were ignoring I/O errors from parseChunk().
content/media/MediaCache.cpp
media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp
--- a/content/media/MediaCache.cpp
+++ b/content/media/MediaCache.cpp
@@ -1661,16 +1661,17 @@ MediaCache::NoteSeek(MediaCacheStream* a
     // Any played block that is entirely after the start of the seeked-over
     // range must be converted.
     int32_t blockIndex =
       (aStream->mStreamOffset + BLOCK_SIZE - 1)/BLOCK_SIZE;
     int32_t endIndex =
       std::min<int64_t>((aOldOffset + BLOCK_SIZE - 1)/BLOCK_SIZE,
              aStream->mBlocks.Length());
     while (blockIndex < endIndex) {
+      MOZ_ASSERT(endIndex > 0);
       int32_t cacheBlockIndex = aStream->mBlocks[endIndex - 1];
       if (cacheBlockIndex >= 0) {
         BlockOwner* bo = GetBlockOwner(cacheBlockIndex, aStream);
         NS_ASSERTION(bo, "Stream doesn't own its blocks?");
         if (bo->mClass == PLAYED_BLOCK) {
           aStream->mPlayedBlocks.RemoveBlock(cacheBlockIndex);
           bo->mClass = READAHEAD_BLOCK;
           // Adding this as the first block is sure to be OK since
--- a/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp
@@ -454,16 +454,24 @@ status_t MPEG4Extractor::readMetaData() 
     if (mInitCheck != NO_INIT) {
         return mInitCheck;
     }
 
     off64_t offset = 0;
     status_t err;
     while (!mFirstTrack) {
         err = parseChunk(&offset, 0);
+        // The parseChunk function returns UNKNOWN_ERROR to skip
+        // some boxes we don't want to handle. Filter that error
+        // code but return others so e.g. I/O errors propagate.
+        if (err != OK && err != (status_t) UNKNOWN_ERROR) {
+          ALOGW("Error %d parsing chuck at offset %lld looking for first track",
+              err, (long long)offset);
+          break;
+        }
     }
 
     if (mInitCheck == OK) {
         if (mHasVideo) {
             mFileMetaData->setCString(
                     kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG4);
         } else {
             mFileMetaData->setCString(kKeyMIMEType, "audio/mp4");