Bug 1207441 - [mp4] Ignore invalid tracks. r=gerald, a=sylvestre
authorJean-Yves Avenard <jyavenard@mozilla.com>
Mon, 28 Sep 2015 12:32:51 +1000
changeset 296160 a3e1dc60e200004de0df58c8215736d2961c85c9
parent 296159 9d1337291612178ddbbdcb82b272fe7414fbbda8
child 296161 ab880d565bb0356017abedfae5aa4b91f0c37626
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgerald, sylvestre
bugs1207441
milestone43.0a2
Bug 1207441 - [mp4] Ignore invalid tracks. r=gerald, a=sylvestre This is designed to minimize the chance of regressions.
media/libstagefright/binding/MP4Metadata.cpp
media/libstagefright/binding/include/mp4_demuxer/MP4Metadata.h
--- a/media/libstagefright/binding/MP4Metadata.cpp
+++ b/media/libstagefright/binding/MP4Metadata.cpp
@@ -114,22 +114,24 @@ MP4Metadata::GetNumberTracks(mozilla::Tr
     sp<MetaData> metaData = mPrivate->mMetadataExtractor->getTrackMetaData(i);
 
     const char* mimeType;
     if (metaData == nullptr || !metaData->findCString(kKeyMIMEType, &mimeType)) {
       continue;
     }
     switch (aType) {
       case mozilla::TrackInfo::kAudioTrack:
-        if (!strncmp(mimeType, "audio/", 6)) {
+        if (!strncmp(mimeType, "audio/", 6) &&
+            CheckTrack(mimeType, metaData.get(), i)) {
           total++;
         }
         break;
       case mozilla::TrackInfo::kVideoTrack:
-        if (!strncmp(mimeType, "video/", 6)) {
+        if (!strncmp(mimeType, "video/", 6) &&
+            CheckTrack(mimeType, metaData.get(), i)) {
           total++;
         }
         break;
       default:
         break;
     }
   }
   return total;
@@ -151,77 +153,84 @@ MP4Metadata::GetTrackInfo(mozilla::Track
   while (i < tracks) {
     metaData = mPrivate->mMetadataExtractor->getTrackMetaData(i);
 
     if (metaData == nullptr || !metaData->findCString(kKeyMIMEType, &mimeType)) {
       continue;
     }
     switch (aType) {
       case mozilla::TrackInfo::kAudioTrack:
-        if (!strncmp(mimeType, "audio/", 6)) {
+        if (!strncmp(mimeType, "audio/", 6) &&
+            CheckTrack(mimeType, metaData.get(), i)) {
           index++;
         }
         break;
       case mozilla::TrackInfo::kVideoTrack:
-        if (!strncmp(mimeType, "video/", 6)) {
+        if (!strncmp(mimeType, "video/", 6) &&
+            CheckTrack(mimeType, metaData.get(), i)) {
           index++;
         }
         break;
       default:
         break;
     }
     if (index == aTrackNumber) {
       break;
     }
     i++;
   }
   if (index < 0) {
     return nullptr;
   }
 
-  sp<MediaSource> track = mPrivate->mMetadataExtractor->getTrack(index);
-  if (!track.get() || track->start() != OK) {
-    return nullptr;
-  }
-
-  UniquePtr<mozilla::TrackInfo> e;
+  UniquePtr<mozilla::TrackInfo> e = CheckTrack(mimeType, metaData.get(), index);
 
-  switch (aType) {
-    case mozilla::TrackInfo::kAudioTrack:
-    {
-      auto info = mozilla::MakeUnique<MP4AudioInfo>();
-      info->Update(metaData.get(), mimeType);
-      e = Move(info);
-    }
-      break;
-    case mozilla::TrackInfo::kVideoTrack:
-    {
-      auto info = mozilla::MakeUnique<MP4VideoInfo>();
-      info->Update(metaData.get(), mimeType);
-      e = Move(info);
-    }
-      break;
-    default:
-      break;
-  }
-
-  track->stop();
   if (e) {
     metaData = mPrivate->mMetadataExtractor->getMetaData();
     int64_t movieDuration;
     if (!e->mDuration &&
         metaData->findInt64(kKeyMovieDuration, &movieDuration)) {
       // No duration in track, use movie extend header box one.
       e->mDuration = movieDuration;
     }
   }
 
   return e;
 }
 
+mozilla::UniquePtr<mozilla::TrackInfo>
+MP4Metadata::CheckTrack(const char* aMimeType,
+                        stagefright::MetaData* aMetaData,
+                        int32_t aIndex) const
+{
+  sp<MediaSource> track = mPrivate->mMetadataExtractor->getTrack(aIndex);
+  if (!track.get() || track->start() != OK) {
+    return nullptr;
+  }
+
+  UniquePtr<mozilla::TrackInfo> e;
+
+  if (!strncmp(aMimeType, "audio/", 6)) {
+    auto info = mozilla::MakeUnique<MP4AudioInfo>();
+    info->Update(aMetaData, aMimeType);
+    e = Move(info);
+  } else if (!strncmp(aMimeType, "video/", 6)) {
+    auto info = mozilla::MakeUnique<MP4VideoInfo>();
+    info->Update(aMetaData, aMimeType);
+    e = Move(info);
+  }
+
+  track->stop();
+
+  if (e && e->IsValid()) {
+    return e;
+  }
+  return nullptr;
+}
+
 bool
 MP4Metadata::CanSeek() const
 {
   return mPrivate->mCanSeek;
 }
 
 void
 MP4Metadata::UpdateCrypto(const MetaData* aMetaData)
--- a/media/libstagefright/binding/include/mp4_demuxer/MP4Metadata.h
+++ b/media/libstagefright/binding/include/mp4_demuxer/MP4Metadata.h
@@ -41,16 +41,19 @@ public:
     return mCrypto;
   }
 
   bool ReadTrackIndex(FallibleTArray<Index::Indice>& aDest, mozilla::TrackID aTrackID);
 
 private:
   int32_t GetTrackNumber(mozilla::TrackID aTrackID);
   void UpdateCrypto(const stagefright::MetaData* aMetaData);
+  mozilla::UniquePtr<mozilla::TrackInfo> CheckTrack(const char* aMimeType,
+                                                    stagefright::MetaData* aMetaData,
+                                                    int32_t aIndex) const;
   nsAutoPtr<StageFrightPrivate> mPrivate;
   CryptoFile mCrypto;
   nsRefPtr<Stream> mSource;
 };
 
 } // namespace mp4_demuxer
 
 #endif // MP4METADATA_H_