Bug 1341483 - MP4Metadata::ReadTrackIndex() now also returns a success/error code - r?kinetik draft
authorGerald Squelart <gsquelart@mozilla.com>
Mon, 27 Feb 2017 22:16:44 +1100
changeset 498130 95890eac4fa43851a31e29cd38f80bd2255d5617
parent 498129 e957b55f953f120842d5c461520add535ea95b74
child 549096 20bf4401ae8f2283d6a420363378012d41760038
push id49123
push usergsquelart@mozilla.com
push dateTue, 14 Mar 2017 11:14:08 +0000
reviewerskinetik
bugs1341483
milestone55.0a1
Bug 1341483 - MP4Metadata::ReadTrackIndex() now also returns a success/error code - r?kinetik MozReview-Commit-ID: GO7kz1huaQl
dom/media/fmp4/MP4Demuxer.cpp
media/libstagefright/binding/MP4Metadata.cpp
media/libstagefright/binding/include/mp4_demuxer/MP4Metadata.h
media/libstagefright/gtest/TestParser.cpp
--- a/dom/media/fmp4/MP4Demuxer.cpp
+++ b/dom/media/fmp4/MP4Demuxer.cpp
@@ -204,21 +204,20 @@ MP4Demuxer::Init()
                                RESULT_DETAIL("Invalid MP4 audio track (%s)",
                                              info.Result().Description().get()));
         }
         continue;
       } else if (NS_FAILED(info.Result()) && result == NS_OK) {
         result = Move(info.Result());
       }
       FallibleTArray<mp4_demuxer::Index::Indice> indices;
-      if (!metadata.ReadTrackIndex(indices, info.Ref()->mTrackId)) {
+      MediaResult rv = metadata.ReadTrackIndex(indices, info.Ref()->mTrackId);
+      if (NS_FAILED(rv)) {
         if (result == NS_OK) {
-          result =
-            MediaResult(NS_ERROR_DOM_MEDIA_DEMUXER_ERR,
-                        RESULT_DETAIL("Invalid MP4 audio track index list"));
+          result = rv;
         }
         continue;
       }
       mAudioDemuxers[i] = new MP4TrackDemuxer(this, Move(info.Ref()), indices);
     }
   }
 
   if (videoTrackCount.Ref() != 0) {
@@ -239,21 +238,20 @@ MP4Demuxer::Init()
                                RESULT_DETAIL("Invalid MP4 video track (%s)",
                                              info.Result().Description().get()));
         }
         continue;
       } else if (NS_FAILED(info.Result()) && result == NS_OK) {
         result = Move(info.Result());
       }
       FallibleTArray<mp4_demuxer::Index::Indice> indices;
-      if (!metadata.ReadTrackIndex(indices, info.Ref()->mTrackId)) {
+      MediaResult rv = metadata.ReadTrackIndex(indices, info.Ref()->mTrackId);
+      if (NS_FAILED(rv)) {
         if (result == NS_OK) {
-          result =
-            MediaResult(NS_ERROR_DOM_MEDIA_DEMUXER_ERR,
-                        RESULT_DETAIL("Invalid MP4 video track index list"));
+          result = rv;
         }
         continue;
       }
       mVideoDemuxers[i] = new MP4TrackDemuxer(this, Move(info.Ref()), indices);
     }
   }
 
   mp4_demuxer::MP4Metadata::ResultAndCryptoFile cryptoFile =
--- a/media/libstagefright/binding/MP4Metadata.cpp
+++ b/media/libstagefright/binding/MP4Metadata.cpp
@@ -7,16 +7,17 @@
 #include "media/stagefright/MediaDefs.h"
 #include "media/stagefright/MediaSource.h"
 #include "media/stagefright/MetaData.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/CheckedInt.h"
 #include "mozilla/EndianUtils.h"
 #include "mozilla/Logging.h"
 #include "mozilla/RefPtr.h"
+#include "mozilla/SizePrintfMacros.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/UniquePtr.h"
 #include "VideoUtils.h"
 #include "mp4_demuxer/MoofParser.h"
 #include "mp4_demuxer/MP4Metadata.h"
 #include "mp4_demuxer/Stream.h"
 #include "MediaPrefs.h"
 #include "mp4parse.h"
@@ -84,17 +85,19 @@ public:
   MP4Metadata::ResultAndTrackCount
   GetNumberTracks(mozilla::TrackInfo::TrackType aType) const;
   MP4Metadata::ResultAndTrackInfo GetTrackInfo(
     mozilla::TrackInfo::TrackType aType, size_t aTrackNumber) const;
   bool CanSeek() const;
 
   MP4Metadata::ResultAndCryptoFile Crypto() const;
 
-  bool ReadTrackIndex(FallibleTArray<Index::Indice>& aDest, mozilla::TrackID aTrackID);
+  mozilla::MediaResult
+  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;
   CryptoFile mCrypto;
@@ -133,17 +136,18 @@ public:
   MP4Metadata::ResultAndTrackCount
   GetNumberTracks(mozilla::TrackInfo::TrackType aType) const;
   MP4Metadata::ResultAndTrackInfo GetTrackInfo(
     mozilla::TrackInfo::TrackType aType, size_t aTrackNumber) const;
   bool CanSeek() const;
 
   MP4Metadata::ResultAndCryptoFile Crypto() const;
 
-  bool ReadTrackIndice(mp4parse_byte_data* aIndices, mozilla::TrackID aTrackID);
+  mozilla::MediaResult
+  ReadTrackIndice(mp4parse_byte_data* aIndices, mozilla::TrackID aTrackID);
 
 private:
   void UpdateCrypto();
   Maybe<uint32_t> TrackTypeToGlobalTrackIndex(mozilla::TrackInfo::TrackType aType, size_t aTrackNumber) const;
 
   CryptoFile mCrypto;
   RefPtr<Stream> mSource;
   RustStreamAdaptor mRustSource;
@@ -455,65 +459,69 @@ MP4Metadata::Crypto() const
 
   if (mPreferRust) {
     return rustCrypto;
   }
 
   return crypto;
 }
 
-bool
-MP4Metadata::ReadTrackIndex(FallibleTArray<Index::Indice>& aDest, mozilla::TrackID aTrackID)
+mozilla::MediaResult
+MP4Metadata::ReadTrackIndex(FallibleTArray<Index::Indice>& aDest,
+                            mozilla::TrackID aTrackID)
 {
-  bool ret = mStagefright->ReadTrackIndex(aDest, aTrackID);
+  mozilla::MediaResult ret =
+    mStagefright->ReadTrackIndex(aDest, aTrackID);
 
 #ifndef RELEASE_OR_BETA
-  if (mRustTestMode && ret && mRust) {
+  if (mRustTestMode && NS_SUCCEEDED(ret) && mRust) {
     mp4parse_byte_data data = {};
-    bool rustRet = mRust->ReadTrackIndice(&data, aTrackID);
-    MOZ_DIAGNOSTIC_ASSERT(rustRet);
+    mozilla::MediaResult rustRet = mRust->ReadTrackIndice(&data, aTrackID);
+    MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rustRet));
     MOZ_DIAGNOSTIC_ASSERT(data.length == aDest.Length());
     for (uint32_t i = 0; i < data.length; i++) {
       MOZ_DIAGNOSTIC_ASSERT(data.indices[i].start_offset == aDest[i].start_offset);
       MOZ_DIAGNOSTIC_ASSERT(data.indices[i].end_offset == aDest[i].end_offset);
       MOZ_DIAGNOSTIC_ASSERT(llabs(data.indices[i].start_composition - int64_t(aDest[i].start_composition)) <= 1);
       MOZ_DIAGNOSTIC_ASSERT(llabs(data.indices[i].end_composition - int64_t(aDest[i].end_composition)) <= 1);
       MOZ_DIAGNOSTIC_ASSERT(llabs(data.indices[i].start_decode - int64_t(aDest[i].start_decode)) <= 1);
       MOZ_DIAGNOSTIC_ASSERT(data.indices[i].sync == aDest[i].sync);
     }
   }
 #endif
 
   return ret;
 }
 
-static inline bool
+static inline mozilla::MediaResult
 ConvertIndex(FallibleTArray<Index::Indice>& aDest,
              const nsTArray<stagefright::MediaSource::Indice>& aIndex,
              int64_t aMediaTime)
 {
   if (!aDest.SetCapacity(aIndex.Length(), mozilla::fallible)) {
-    return false;
+    return MediaResult{NS_ERROR_OUT_OF_MEMORY,
+                       RESULT_DETAIL("Could not resize to %" PRIuSIZE " indices",
+                                     aIndex.Length())};
   }
   for (size_t i = 0; i < aIndex.Length(); i++) {
     Index::Indice indice;
     const stagefright::MediaSource::Indice& s_indice = aIndex[i];
     indice.start_offset = s_indice.start_offset;
     indice.end_offset = s_indice.end_offset;
     indice.start_composition = s_indice.start_composition - aMediaTime;
     indice.end_composition = s_indice.end_composition - aMediaTime;
     indice.start_decode = s_indice.start_decode;
     indice.sync = s_indice.sync;
     // FIXME: Make this infallible after bug 968520 is done.
     MOZ_ALWAYS_TRUE(aDest.AppendElement(indice, mozilla::fallible));
     MOZ_LOG(sLog, LogLevel::Debug, ("s_o: %" PRIu64 ", e_o: %" PRIu64 ", s_c: %" PRIu64 ", e_c: %" PRIu64 ", s_d: %" PRIu64 ", sync: %d\n",
                                     indice.start_offset, indice.end_offset, indice.start_composition, indice.end_composition,
                                     indice.start_decode, indice.sync));
   }
-  return true;
+  return NS_OK;
 }
 
 MP4MetadataStagefright::MP4MetadataStagefright(Stream* aSource)
   : mSource(aSource)
   , mMetadataExtractor(new MPEG4Extractor(new DataSourceAdapter(mSource)))
   , mCanSeek(mMetadataExtractor->flags() & MediaExtractor::CAN_SEEK)
 {
   sp<MetaData> metaData = mMetadataExtractor->getMetaData();
@@ -676,36 +684,39 @@ MP4MetadataStagefright::UpdateCrypto(con
   // There's no point in checking that the type matches anything because it
   // isn't set consistently in the MPEG4Extractor.
   if (!aMetaData->findData(kKeyPssh, &type, &data, &size)) {
     return;
   }
   mCrypto.Update(reinterpret_cast<const uint8_t*>(data), size);
 }
 
-bool
-MP4MetadataStagefright::ReadTrackIndex(FallibleTArray<Index::Indice>& aDest, mozilla::TrackID aTrackID)
+mozilla::MediaResult
+MP4MetadataStagefright::ReadTrackIndex(FallibleTArray<Index::Indice>& aDest,
+                                       mozilla::TrackID aTrackID)
 {
   size_t numTracks = mMetadataExtractor->countTracks();
   int32_t trackNumber = GetTrackNumber(aTrackID);
   if (trackNumber < 0) {
-    return false;
+    return MediaResult(NS_ERROR_DOM_MEDIA_METADATA_ERR,
+                       RESULT_DETAIL("Cannot find track id %d",
+                                     int(aTrackID)));
   }
   sp<MediaSource> track = mMetadataExtractor->getTrack(trackNumber);
   if (!track.get()) {
-    return false;
+    return MediaResult(NS_ERROR_DOM_MEDIA_METADATA_ERR,
+                       RESULT_DETAIL("Cannot access track id %d",
+                                     int(aTrackID)));
   }
   sp<MetaData> metadata = mMetadataExtractor->getTrackMetaData(trackNumber);
   int64_t mediaTime;
   if (!metadata->findInt64(kKeyMediaTime, &mediaTime)) {
     mediaTime = 0;
   }
-  bool rv = ConvertIndex(aDest, track->exportIndex(), mediaTime);
-
-  return rv;
+  return ConvertIndex(aDest, track->exportIndex(), mediaTime);
 }
 
 int32_t
 MP4MetadataStagefright::GetTrackNumber(mozilla::TrackID aTrackID)
 {
   size_t numTracks = mMetadataExtractor->countTracks();
   for (size_t i = 0; i < numTracks; i++) {
     sp<MetaData> metaData = mMetadataExtractor->getTrackMetaData(i);
@@ -990,35 +1001,39 @@ MP4MetadataRust::CanSeek() const
 }
 
 MP4Metadata::ResultAndCryptoFile
 MP4MetadataRust::Crypto() const
 {
   return {NS_OK, &mCrypto};
 }
 
-bool
+mozilla::MediaResult
 MP4MetadataRust::ReadTrackIndice(mp4parse_byte_data* aIndices, mozilla::TrackID aTrackID)
 {
   uint8_t fragmented = false;
   auto rv = mp4parse_is_fragmented(mRustParser.get(), aTrackID, &fragmented);
   if (rv != MP4PARSE_OK) {
-    return false;
+    return MediaResult(NS_ERROR_DOM_MEDIA_METADATA_ERR,
+                       RESULT_DETAIL("Cannot parse whether track id %d is fragmented",
+                                     int(aTrackID)));
   }
 
   if (fragmented) {
-    return true;
+    return NS_OK;
   }
 
   rv = mp4parse_get_indice_table(mRustParser.get(), aTrackID, aIndices);
   if (rv != MP4PARSE_OK) {
-    return false;
+    return MediaResult(NS_ERROR_DOM_MEDIA_METADATA_ERR,
+                       RESULT_DETAIL("Cannot parse index table in track id %d",
+                                     int(aTrackID)));
   }
 
-  return true;
+  return NS_OK;
 }
 
 /*static*/ MP4Metadata::ResultAndByteBuffer
 MP4MetadataRust::Metadata(Stream* aSource)
 {
   MOZ_ASSERT(false, "Not yet implemented");
   return {NS_ERROR_NOT_IMPLEMENTED, nullptr};
 }
--- a/media/libstagefright/binding/include/mp4_demuxer/MP4Metadata.h
+++ b/media/libstagefright/binding/include/mp4_demuxer/MP4Metadata.h
@@ -60,17 +60,19 @@ public:
   ResultAndTrackInfo GetTrackInfo(mozilla::TrackInfo::TrackType aType,
                                   size_t aTrackNumber) const;
 
   bool CanSeek() const;
 
   using ResultAndCryptoFile = ResultAndType<const CryptoFile*>;
   ResultAndCryptoFile Crypto() const;
 
-  bool ReadTrackIndex(FallibleTArray<Index::Indice>& aDest, mozilla::TrackID aTrackID);
+  mozilla::MediaResult
+  ReadTrackIndex(FallibleTArray<Index::Indice>& aDest,
+                 mozilla::TrackID aTrackID);
 
 private:
   UniquePtr<MP4MetadataStagefright> mStagefright;
   UniquePtr<MP4MetadataRust> mRust;
   mutable bool mPreferRust;
   mutable bool mReportedAudioTrackTelemetry;
   mutable bool mReportedVideoTrackTelemetry;
 #ifndef RELEASE_OR_BETA
--- a/media/libstagefright/gtest/TestParser.cpp
+++ b/media/libstagefright/gtest/TestParser.cpp
@@ -235,17 +235,18 @@ TEST(stagefright_MPEG4Metadata, test_cas
       const VideoInfo* videoInfo = trackInfo.Ref()->GetAsVideoInfo();
       ASSERT_TRUE(!!videoInfo);
       EXPECT_TRUE(videoInfo->IsValid());
       EXPECT_TRUE(videoInfo->IsVideo());
       EXPECT_EQ(testFiles[test].mVideoDuration, videoInfo->mDuration);
       EXPECT_EQ(testFiles[test].mWidth, videoInfo->mDisplay.width);
       EXPECT_EQ(testFiles[test].mHeight, videoInfo->mDisplay.height);
       FallibleTArray<mp4_demuxer::Index::Indice> indices;
-      EXPECT_TRUE(metadata.ReadTrackIndex(indices, videoInfo->mTrackId));
+      EXPECT_TRUE(
+        NS_SUCCEEDED(metadata.ReadTrackIndex(indices, videoInfo->mTrackId)));
       for (const mp4_demuxer::Index::Indice& indice : indices) {
         EXPECT_TRUE(indice.start_offset <= indice.end_offset);
         EXPECT_TRUE(indice.start_composition <= indice.end_composition);
       }
     }
     trackInfo = metadata.GetTrackInfo(TrackInfo::kAudioTrack, 0);
     if (testFiles[test].mNumberAudioTracks == 0) {
       EXPECT_TRUE(!trackInfo.Ref());
@@ -253,17 +254,18 @@ TEST(stagefright_MPEG4Metadata, test_cas
       ASSERT_TRUE(!!trackInfo.Ref());
       const AudioInfo* audioInfo = trackInfo.Ref()->GetAsAudioInfo();
       ASSERT_TRUE(!!audioInfo);
       EXPECT_TRUE(audioInfo->IsValid());
       EXPECT_TRUE(audioInfo->IsAudio());
       EXPECT_EQ(testFiles[test].mAudioDuration, audioInfo->mDuration);
       EXPECT_EQ(testFiles[test].mAudioProfile, audioInfo->mProfile);
       FallibleTArray<mp4_demuxer::Index::Indice> indices;
-      EXPECT_TRUE(metadata.ReadTrackIndex(indices, audioInfo->mTrackId));
+      EXPECT_TRUE(
+        NS_SUCCEEDED(metadata.ReadTrackIndex(indices, audioInfo->mTrackId)));
       for (const mp4_demuxer::Index::Indice& indice : indices) {
         EXPECT_TRUE(indice.start_offset <= indice.end_offset);
         EXPECT_TRUE(indice.start_composition <= indice.end_composition);
       }
     }
     EXPECT_FALSE(metadata.GetTrackInfo(TrackInfo::kTextTrack, 0).Ref());
     // We can see anywhere in any MPEG4.
     EXPECT_TRUE(metadata.CanSeek());