Bug 1093567 - Don't loop forever looking for mp4 tracks. r=ajones.
authorRalph Giles <giles@mozilla.com>
Mon, 17 Nov 2014 16:20:00 -0800
changeset 216562 d24d7dfddb48b88bcf3c3379c2f426990f2275fc
parent 216561 7c4360f398ffaf8455f179c56f5103cd9f1fd39e
child 216563 5d895a54de81cfd46cc1b5986311333fbadaa7df
push idunknown
push userunknown
push dateunknown
reviewersajones
bugs1093567
milestone36.0a1
Bug 1093567 - Don't loop forever looking for mp4 tracks. r=ajones. We were ignoring I/O errors from parseChunk(). We must break instead of returning early so mInitCheck gets set correctly.
dom/media/MediaCache.cpp
media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp
--- a/dom/media/MediaCache.cpp
+++ b/dom/media/MediaCache.cpp
@@ -1664,16 +1664,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
@@ -459,16 +459,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");