Bug 1343437 - MP4Demuxer::Init resolves with a MediaResult - r?jya draft
authorGerald Squelart <gsquelart@mozilla.com>
Mon, 27 Feb 2017 10:10:28 +1100
changeset 560822 cd9b965cf3ccd98cfc376ba4b1b8b787a41eab02
parent 560821 bad4713ab14340a7227ca7fbddb4668966807320
child 560823 89af89ab5687d285531d7e180880a68bfdbdb661
push id53551
push usergsquelart@mozilla.com
push dateTue, 11 Apr 2017 23:47:44 +0000
reviewersjya
bugs1343437
milestone55.0a1
Bug 1343437 - MP4Demuxer::Init resolves with a MediaResult - r?jya If MP4Demuxer::Init detects some recoverable error (e.g., invalid tracks when others may still be usable), it will eventually Resolve the promise with the first warning. Later on, errors/warnings from the MP4Metadata parser will also be handled, to provide even better diagnostics. MozReview-Commit-ID: E9Rly9dhXW3
dom/media/fmp4/MP4Demuxer.cpp
--- a/dom/media/fmp4/MP4Demuxer.cpp
+++ b/dom/media/fmp4/MP4Demuxer.cpp
@@ -119,16 +119,19 @@ MP4Demuxer::MP4Demuxer(MediaResource* aR
 {
 }
 
 RefPtr<MP4Demuxer::InitPromise>
 MP4Demuxer::Init()
 {
   AutoPinned<mp4_demuxer::ResourceStream> stream(mStream);
 
+  // 'result' will capture the first warning, if any.
+  MediaResult result{NS_OK};
+
   RefPtr<MediaByteBuffer> initData = mp4_demuxer::MP4Metadata::Metadata(stream);
   if (!initData) {
     return InitPromise::CreateAndReject(
       MediaResult(NS_ERROR_DOM_MEDIA_DEMUXER_ERR,
                   RESULT_DETAIL("Invalid MP4 metadata or OOM")),
       __func__);
   }
 
@@ -146,52 +149,74 @@ MP4Demuxer::Init()
       __func__);
   }
 
   if (audioTrackCount != 0) {
     mAudioDemuxers.SetLength(audioTrackCount);
     for (size_t i = 0; i < audioTrackCount; i++) {
       UniquePtr<TrackInfo> info =
         metadata.GetTrackInfo(TrackInfo::kAudioTrack, i);
-      if (info) {
-        UniquePtr<mp4_demuxer::IndiceWrapper> indices =
-          metadata.GetTrackIndice(info->mTrackId);
-        if (indices) {
-          mAudioDemuxers[i] = new MP4TrackDemuxer(this, Move(info), *indices.get());
+      if (!info) {
+        if (result == NS_OK) {
+          result = MediaResult(NS_ERROR_DOM_MEDIA_DEMUXER_ERR,
+                               RESULT_DETAIL("Invalid MP4 audio track"));
         }
+        continue;
       }
+      UniquePtr<mp4_demuxer::IndiceWrapper> indices =
+        metadata.GetTrackIndice(info->mTrackId);
+      if (!indices) {
+        if (result == NS_OK) {
+          result =
+            MediaResult(NS_ERROR_DOM_MEDIA_DEMUXER_ERR,
+                        RESULT_DETAIL("Invalid MP4 audio track index list"));
+        }
+        continue;
+      }
+      mAudioDemuxers[i] = new MP4TrackDemuxer(this, Move(info), *indices.get());
     }
   }
 
   if (videoTrackCount != 0) {
     mVideoDemuxers.SetLength(videoTrackCount);
     for (size_t i = 0; i < videoTrackCount; i++) {
       UniquePtr<TrackInfo> info =
         metadata.GetTrackInfo(TrackInfo::kVideoTrack, i);
-      if (info) {
-        UniquePtr<mp4_demuxer::IndiceWrapper> indices =
-          metadata.GetTrackIndice(info->mTrackId);
-        if (indices) {
-          mVideoDemuxers[i] = new MP4TrackDemuxer(this, Move(info), *indices.get());
+      if (!info) {
+        if (result == NS_OK) {
+          result = MediaResult(NS_ERROR_DOM_MEDIA_DEMUXER_ERR,
+                               RESULT_DETAIL("Invalid MP4 video track"));
         }
+        continue;
       }
+      UniquePtr<mp4_demuxer::IndiceWrapper> indices =
+        metadata.GetTrackIndice(info->mTrackId);
+      if (!indices) {
+        if (result == NS_OK) {
+          result =
+            MediaResult(NS_ERROR_DOM_MEDIA_DEMUXER_ERR,
+                        RESULT_DETAIL("Invalid MP4 video track index list"));
+        }
+        continue;
+      }
+      mVideoDemuxers[i] = new MP4TrackDemuxer(this, Move(info), *indices.get());
     }
   }
 
   const mp4_demuxer::CryptoFile& cryptoFile = metadata.Crypto();
   if (cryptoFile.valid) {
     const nsTArray<mp4_demuxer::PsshInfo>& psshs = cryptoFile.pssh;
     for (uint32_t i = 0; i < psshs.Length(); i++) {
       mCryptoInitData.AppendElements(psshs[i].data);
     }
   }
 
   mIsSeekable = metadata.CanSeek();
 
-  return InitPromise::CreateAndResolve(NS_OK, __func__);
+  return InitPromise::CreateAndResolve(result, __func__);
 }
 
 bool
 MP4Demuxer::HasTrackType(TrackInfo::TrackType aType) const
 {
   return GetNumberTracks(aType) != 0;
 }