Bug 1387798 - use Result as return value in BufferReader. r?kinetik draft
authorAlfredo.Yang <ayang@mozilla.com>
Fri, 13 Oct 2017 09:44:48 +0800
changeset 681371 00131d123a85706c395c05454c82952a858d60cf
parent 680633 c9049137b12f6159d525debad5cff22c75505a7e
child 681372 70cc0796f5daf988a46beac83af78503eed38e99
push id84803
push userbmo:ayang@mozilla.com
push dateTue, 17 Oct 2017 07:13:43 +0000
reviewerskinetik
bugs1387798
milestone58.0a1
Bug 1387798 - use Result as return value in BufferReader. r?kinetik MozReview-Commit-ID: uLny8ebSic
media/libstagefright/binding/MoofParser.cpp
media/libstagefright/binding/SinfParser.cpp
media/libstagefright/binding/include/mp4_demuxer/Box.h
media/libstagefright/binding/include/mp4_demuxer/BufferReader.h
media/libstagefright/binding/include/mp4_demuxer/MoofParser.h
media/libstagefright/binding/include/mp4_demuxer/SinfParser.h
--- a/media/libstagefright/binding/MoofParser.cpp
+++ b/media/libstagefright/binding/MoofParser.cpp
@@ -585,17 +585,17 @@ Moof::ParseTraf(Box& aBox, Trex& aTrex, 
   if (aTrex.mTrackId && tfhd.mTrackId != aTrex.mTrackId) {
     return;
   }
   // Now search for TRUN boxes.
   uint64_t decodeTime =
     tfdt.IsValid() ? tfdt.mBaseMediaDecodeTime : *aDecodeTime;
   for (Box box = aBox.FirstChild(); box.IsAvailable(); box = box.Next()) {
     if (box.IsType("trun")) {
-      if (ParseTrun(box, tfhd, aMvhd, aMdhd, aEdts, &decodeTime, aIsAudio)) {
+      if (ParseTrun(box, tfhd, aMvhd, aMdhd, aEdts, &decodeTime, aIsAudio).isOk()) {
         mValid = true;
       } else {
         mValid = false;
         break;
       }
     }
   }
   *aDecodeTime = decodeTime;
@@ -604,80 +604,94 @@ Moof::ParseTraf(Box& aBox, Trex& aTrex, 
 void
 Moof::FixRounding(const Moof& aMoof) {
   Microseconds gap = aMoof.mTimeRange.start - mTimeRange.end;
   if (gap > 0 && gap <= mMaxRoundingError) {
     mTimeRange.end = aMoof.mTimeRange.start;
   }
 }
 
-bool
+Result<Ok, nsresult>
 Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, Mvhd& aMvhd, Mdhd& aMdhd, Edts& aEdts, uint64_t* aDecodeTime, bool aIsAudio)
 {
   if (!aTfhd.IsValid() || !aMvhd.IsValid() || !aMdhd.IsValid() ||
       !aEdts.IsValid()) {
     LOG(Moof, "Invalid dependencies: aTfhd(%d) aMvhd(%d) aMdhd(%d) aEdts(%d)",
         aTfhd.IsValid(), aMvhd.IsValid(), aMdhd.IsValid(), !aEdts.IsValid());
-    return false;
+    return Err(NS_ERROR_FAILURE);
   }
 
   BoxReader reader(aBox);
   if (!reader->CanReadType<uint32_t>()) {
     LOG(Moof, "Incomplete Box (missing flags)");
-    return false;
+    return Err(NS_ERROR_FAILURE);
   }
-  uint32_t flags = reader->ReadU32();
+  uint32_t flags;
+  MOZ_TRY_VAR(flags, reader->ReadU32());
   uint8_t version = flags >> 24;
 
   if (!reader->CanReadType<uint32_t>()) {
     LOG(Moof, "Incomplete Box (missing sampleCount)");
-    return false;
+    return Err(NS_ERROR_FAILURE);
   }
-  uint32_t sampleCount = reader->ReadU32();
+  uint32_t sampleCount;
+  MOZ_TRY_VAR(sampleCount, reader->ReadU32());
   if (sampleCount == 0) {
-    return true;
+    return Ok();
   }
 
   size_t need =
     ((flags & 1) ? sizeof(uint32_t) : 0) +
     ((flags & 4) ? sizeof(uint32_t) : 0);
   uint16_t flag[] = { 0x100, 0x200, 0x400, 0x800, 0 };
   for (size_t i = 0; flag[i]; i++) {
     if (flags & flag[i]) {
       need += sizeof(uint32_t) * sampleCount;
     }
   }
   if (reader->Remaining() < need) {
     LOG(Moof, "Incomplete Box (have:%zu need:%zu)",
         reader->Remaining(), need);
-    return false;
+    return Err(NS_ERROR_FAILURE);
   }
 
-  uint64_t offset = aTfhd.mBaseDataOffset + (flags & 1 ? reader->ReadU32() : 0);
-  uint32_t firstSampleFlags =
-    flags & 4 ? reader->ReadU32() : aTfhd.mDefaultSampleFlags;
+  uint64_t offset = aTfhd.mBaseDataOffset;
+  if (flags & 0x01) {
+    uint32_t tmp;
+    MOZ_TRY_VAR(tmp, reader->ReadU32());
+    offset += tmp;
+  }
+  uint32_t firstSampleFlags = aTfhd.mDefaultSampleFlags;
+  if (flags & 0x04) {
+    MOZ_TRY_VAR(firstSampleFlags, reader->ReadU32());
+  }
   uint64_t decodeTime = *aDecodeTime;
   nsTArray<Interval<Microseconds>> timeRanges;
 
   if (!mIndex.SetCapacity(sampleCount, fallible)) {
     LOG(Moof, "Out of Memory");
-    return false;
+    return Err(NS_ERROR_FAILURE);
   }
 
   for (size_t i = 0; i < sampleCount; i++) {
-    uint32_t sampleDuration =
-      flags & 0x100 ? reader->ReadU32() : aTfhd.mDefaultSampleDuration;
-    uint32_t sampleSize =
-      flags & 0x200 ? reader->ReadU32() : aTfhd.mDefaultSampleSize;
-    uint32_t sampleFlags =
-      flags & 0x400 ? reader->ReadU32()
-                    : i ? aTfhd.mDefaultSampleFlags : firstSampleFlags;
+    uint32_t sampleDuration = aTfhd.mDefaultSampleDuration;
+    if (flags & 0x100) {
+      MOZ_TRY_VAR(sampleDuration, reader->ReadU32());
+    }
+    uint32_t sampleSize = aTfhd.mDefaultSampleSize;
+    if (flags & 0x200) {
+      MOZ_TRY_VAR(sampleSize, reader->ReadU32());
+    }
+    uint32_t sampleFlags = i ? aTfhd.mDefaultSampleFlags : firstSampleFlags;
+    if (flags & 0x400) {
+      MOZ_TRY_VAR(sampleFlags, reader->ReadU32());
+    }
     int32_t ctsOffset = 0;
     if (flags & 0x800) {
-      ctsOffset = reader->Read32();
+      MOZ_TRY_VAR(ctsOffset, reader->Read32());
     }
 
     if (sampleSize) {
       Sample sample;
       sample.mByteRange = MediaByteRange(offset, offset + sampleSize);
       offset += sampleSize;
 
       sample.mDecodeTime =
@@ -696,527 +710,577 @@ Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, 
       mMdatRange = mMdatRange.Span(sample.mByteRange);
     }
     decodeTime += sampleDuration;
   }
   mMaxRoundingError += aMdhd.ToMicroseconds(sampleCount);
 
   *aDecodeTime = decodeTime;
 
-  return true;
+  return Ok();
 }
 
 Tkhd::Tkhd(Box& aBox)
 {
-  if (Parse(aBox)) {
+  if (Parse(aBox).isOk()) {
     mValid = true;
   }
 }
 
-bool
+Result<Ok, nsresult>
 Tkhd::Parse(Box& aBox)
 {
   BoxReader reader(aBox);
   if (!reader->CanReadType<uint32_t>()) {
     LOG(Tkhd, "Incomplete Box (missing flags)");
-    return false;
+    return Err(NS_ERROR_FAILURE);
   }
-  uint32_t flags = reader->ReadU32();
+  uint32_t flags;
+  MOZ_TRY_VAR(flags, reader->ReadU32());
   uint8_t version = flags >> 24;
   size_t need =
     3*(version ? sizeof(int64_t) : sizeof(int32_t)) + 2*sizeof(int32_t);
   if (reader->Remaining() < need) {
     LOG(Tkhd, "Incomplete Box (have:%" PRIu64 " need:%" PRIu64 ")",
         (uint64_t)reader->Remaining(), (uint64_t)need);
-    return false;
+    return Err(NS_ERROR_FAILURE);
   }
   if (version == 0) {
-    mCreationTime = reader->ReadU32();
-    mModificationTime = reader->ReadU32();
-    mTrackId = reader->ReadU32();
-    uint32_t reserved = reader->ReadU32();
+    uint32_t creationTime, modificationTime, reserved, duration;
+    MOZ_TRY_VAR(creationTime, reader->ReadU32());
+    MOZ_TRY_VAR(modificationTime, reader->ReadU32());
+    MOZ_TRY_VAR(mTrackId, reader->ReadU32());
+    MOZ_TRY_VAR(reserved, reader->ReadU32());
+    MOZ_TRY_VAR(duration, reader->ReadU32());
+
     NS_ASSERTION(!reserved, "reserved should be 0");
-    mDuration = reader->ReadU32();
+
+    mCreationTime = creationTime;
+    mModificationTime = modificationTime;
+    mDuration = duration;
   } else if (version == 1) {
-    mCreationTime = reader->ReadU64();
-    mModificationTime = reader->ReadU64();
-    mTrackId = reader->ReadU32();
-    uint32_t reserved = reader->ReadU32();
+    uint32_t reserved;
+    MOZ_TRY_VAR(mCreationTime, reader->ReadU64());
+    MOZ_TRY_VAR(mModificationTime, reader->ReadU64());
+    MOZ_TRY_VAR(mTrackId, reader->ReadU32());
+    MOZ_TRY_VAR(reserved, reader->ReadU32());
     NS_ASSERTION(!reserved, "reserved should be 0");
-    mDuration = reader->ReadU64();
+    MOZ_TRY_VAR(mDuration, reader->ReadU64());
   }
-  return true;
+  return Ok();
 }
 
 Mvhd::Mvhd(Box& aBox)
 {
-  if (Parse(aBox)) {
+  if (Parse(aBox).isOk()) {
     mValid = true;
   }
 }
 
-bool
+Result<Ok, nsresult>
 Mvhd::Parse(Box& aBox)
 {
   BoxReader reader(aBox);
   if (!reader->CanReadType<uint32_t>()) {
     LOG(Mdhd, "Incomplete Box (missing flags)");
-    return false;
+    return Err(NS_ERROR_FAILURE);
   }
-  uint32_t flags = reader->ReadU32();
+  uint32_t flags;
+  MOZ_TRY_VAR(flags, reader->ReadU32());
   uint8_t version = flags >> 24;
   size_t need =
     3*(version ? sizeof(int64_t) : sizeof(int32_t)) + sizeof(uint32_t);
   if (reader->Remaining() < need) {
     LOG(Mvhd, "Incomplete Box (have:%" PRIu64 " need:%" PRIu64 ")",
         (uint64_t)reader->Remaining(), (uint64_t)need);
-    return false;
+    return Err(NS_ERROR_FAILURE);
   }
 
   if (version == 0) {
-    mCreationTime = reader->ReadU32();
-    mModificationTime = reader->ReadU32();
-    mTimescale = reader->ReadU32();
-    mDuration = reader->ReadU32();
+    uint32_t creationTime, modificationTime, duration;
+    MOZ_TRY_VAR(creationTime, reader->ReadU32());
+    MOZ_TRY_VAR(modificationTime, reader->ReadU32());
+    MOZ_TRY_VAR(mTimescale, reader->ReadU32());
+    MOZ_TRY_VAR(duration, reader->ReadU32());
+    mCreationTime = creationTime;
+    mModificationTime = modificationTime;
+    mDuration = duration;
   } else if (version == 1) {
-    mCreationTime = reader->ReadU64();
-    mModificationTime = reader->ReadU64();
-    mTimescale = reader->ReadU32();
-    mDuration = reader->ReadU64();
+    MOZ_TRY_VAR(mCreationTime, reader->ReadU64());
+    MOZ_TRY_VAR(mModificationTime, reader->ReadU64());
+    MOZ_TRY_VAR(mTimescale, reader->ReadU32());
+    MOZ_TRY_VAR(mDuration, reader->ReadU64());
   } else {
-    return false;
+    return Err(NS_ERROR_FAILURE);
   }
-  return true;
+    return Ok();
 }
 
 Mdhd::Mdhd(Box& aBox)
   : Mvhd(aBox)
 {
 }
 
 Trex::Trex(Box& aBox)
 {
-  if (Parse(aBox)) {
+  if (Parse(aBox).isOk()) {
     mValid = true;
   }
 }
 
-bool
+Result<Ok, nsresult>
 Trex::Parse(Box& aBox)
 {
   BoxReader reader(aBox);
   if (reader->Remaining() < 6*sizeof(uint32_t)) {
     LOG(Trex, "Incomplete Box (have:%" PRIu64 " need:%" PRIu64 ")",
         (uint64_t)reader->Remaining(), (uint64_t)6*sizeof(uint32_t));
-    return false;
+    return Err(NS_ERROR_FAILURE);
   }
-  mFlags = reader->ReadU32();
-  mTrackId = reader->ReadU32();
-  mDefaultSampleDescriptionIndex = reader->ReadU32();
-  mDefaultSampleDuration = reader->ReadU32();
-  mDefaultSampleSize = reader->ReadU32();
-  mDefaultSampleFlags = reader->ReadU32();
-  return true;
+  MOZ_TRY_VAR(mFlags, reader->ReadU32());
+  MOZ_TRY_VAR(mTrackId, reader->ReadU32());
+  MOZ_TRY_VAR(mDefaultSampleDescriptionIndex, reader->ReadU32());
+  MOZ_TRY_VAR(mDefaultSampleDuration, reader->ReadU32());
+  MOZ_TRY_VAR(mDefaultSampleSize, reader->ReadU32());
+  MOZ_TRY_VAR(mDefaultSampleFlags, reader->ReadU32());
+
+  return Ok();
 }
 
 Tfhd::Tfhd(Box& aBox, Trex& aTrex)
   : Trex(aTrex)
 {
-  if (Parse(aBox)) {
+  if (Parse(aBox).isOk()) {
     mValid = true;
   }
 }
 
-bool
+Result<Ok, nsresult>
 Tfhd::Parse(Box& aBox)
 {
   MOZ_ASSERT(aBox.IsType("tfhd"));
   MOZ_ASSERT(aBox.Parent()->IsType("traf"));
   MOZ_ASSERT(aBox.Parent()->Parent()->IsType("moof"));
 
   BoxReader reader(aBox);
   if (!reader->CanReadType<uint32_t>()) {
     LOG(Tfhd, "Incomplete Box (missing flags)");
-    return false;
+    return Err(NS_ERROR_FAILURE);
   }
-  mFlags = reader->ReadU32();
+  MOZ_TRY_VAR(mFlags, reader->ReadU32());
   size_t need = sizeof(uint32_t) /* trackid */;
   uint8_t flag[] = { 1, 2, 8, 0x10, 0x20, 0 };
   uint8_t flagSize[] = { sizeof(uint64_t), sizeof(uint32_t), sizeof(uint32_t), sizeof(uint32_t), sizeof(uint32_t) };
   for (size_t i = 0; flag[i]; i++) {
     if (mFlags & flag[i]) {
       need += flagSize[i];
     }
   }
   if (reader->Remaining() < need) {
     LOG(Tfhd, "Incomplete Box (have:%" PRIu64 " need:%" PRIu64 ")",
         (uint64_t)reader->Remaining(), (uint64_t)need);
-    return false;
+    return Err(NS_ERROR_FAILURE);
   }
-  mTrackId = reader->ReadU32();
-  mBaseDataOffset =
-    mFlags & 1 ? reader->ReadU64() : aBox.Parent()->Parent()->Offset();
-  if (mFlags & 2) {
-    mDefaultSampleDescriptionIndex = reader->ReadU32();
+  MOZ_TRY_VAR(mTrackId, reader->ReadU32());
+  mBaseDataOffset = aBox.Parent()->Parent()->Offset();
+  if (mFlags & 0x01) {
+    MOZ_TRY_VAR(mBaseDataOffset, reader->ReadU64());
   }
-  if (mFlags & 8) {
-    mDefaultSampleDuration = reader->ReadU32();
+  if (mFlags & 0x02) {
+    MOZ_TRY_VAR(mDefaultSampleDescriptionIndex, reader->ReadU32());
+  }
+  if (mFlags & 0x08) {
+    MOZ_TRY_VAR(mDefaultSampleDuration, reader->ReadU32());
   }
   if (mFlags & 0x10) {
-    mDefaultSampleSize = reader->ReadU32();
+    MOZ_TRY_VAR(mDefaultSampleSize, reader->ReadU32());
   }
   if (mFlags & 0x20) {
-    mDefaultSampleFlags = reader->ReadU32();
+    MOZ_TRY_VAR(mDefaultSampleFlags, reader->ReadU32());
   }
 
-  return true;
+  return Ok();
 }
 
 Tfdt::Tfdt(Box& aBox)
 {
-  if (Parse(aBox)) {
+  if (Parse(aBox).isOk()) {
     mValid = true;
   }
 }
 
-bool
+Result<Ok, nsresult>
 Tfdt::Parse(Box& aBox)
 {
   BoxReader reader(aBox);
   if (!reader->CanReadType<uint32_t>()) {
     LOG(Tfdt, "Incomplete Box (missing flags)");
-    return false;
+    return Err(NS_ERROR_FAILURE);
   }
-  uint32_t flags = reader->ReadU32();
+  uint32_t flags;
+  MOZ_TRY_VAR(flags, reader->ReadU32());
   uint8_t version = flags >> 24;
   size_t need = version ? sizeof(uint64_t) : sizeof(uint32_t) ;
   if (reader->Remaining() < need) {
     LOG(Tfdt, "Incomplete Box (have:%" PRIu64 " need:%" PRIu64 ")",
         (uint64_t)reader->Remaining(), (uint64_t)need);
-    return false;
+    return Err(NS_ERROR_FAILURE);
   }
   if (version == 0) {
-    mBaseMediaDecodeTime = reader->ReadU32();
+    uint32_t tmp;
+    MOZ_TRY_VAR(tmp, reader->ReadU32());
+    mBaseMediaDecodeTime = tmp;
   } else if (version == 1) {
-    mBaseMediaDecodeTime = reader->ReadU64();
+    MOZ_TRY_VAR(mBaseMediaDecodeTime, reader->ReadU64());
   }
-  return true;
+  return Ok();
 }
 
 Edts::Edts(Box& aBox)
   : mMediaStart(0)
   , mEmptyOffset(0)
 {
-  if (Parse(aBox)) {
+  if (Parse(aBox).isOk()) {
     mValid = true;
   }
 }
 
-bool
+Result<Ok, nsresult>
 Edts::Parse(Box& aBox)
 {
   Box child = aBox.FirstChild();
   if (!child.IsType("elst")) {
-    return false;
+    return Err(NS_ERROR_FAILURE);
   }
 
   BoxReader reader(child);
   if (!reader->CanReadType<uint32_t>()) {
     LOG(Edts, "Incomplete Box (missing flags)");
-    return false;
+    return Err(NS_ERROR_FAILURE);
   }
-  uint32_t flags = reader->ReadU32();
+  uint32_t flags;
+  MOZ_TRY_VAR(flags, reader->ReadU32());
   uint8_t version = flags >> 24;
   size_t need =
     sizeof(uint32_t) + 2*(version ? sizeof(int64_t) : sizeof(uint32_t));
   if (reader->Remaining() < need) {
     LOG(Edts, "Incomplete Box (have:%" PRIu64 " need:%" PRIu64 ")",
         (uint64_t)reader->Remaining(), (uint64_t)need);
-    return false;
+    return Err(NS_ERROR_FAILURE);
   }
   bool emptyEntry = false;
-  uint32_t entryCount = reader->ReadU32();
+  uint32_t entryCount;
+  MOZ_TRY_VAR(entryCount, reader->ReadU32());
   for (uint32_t i = 0; i < entryCount; i++) {
     uint64_t segment_duration;
     int64_t media_time;
     if (version == 1) {
-      segment_duration = reader->ReadU64();
-      media_time = reader->Read64();
+      MOZ_TRY_VAR(segment_duration, reader->ReadU64());
+      MOZ_TRY_VAR(media_time, reader->Read64());
     } else {
-      segment_duration = reader->ReadU32();
-      media_time = reader->Read32();
+      uint32_t tmp;
+      MOZ_TRY_VAR(tmp, reader->ReadU32());
+      segment_duration = tmp;
+      int32_t tmp2;
+      MOZ_TRY_VAR(tmp2, reader->Read32());
+      media_time = tmp2;
     }
     if (media_time == -1 && i) {
       LOG(Edts, "Multiple empty edit, not handled");
     } else if (media_time == -1) {
       mEmptyOffset = segment_duration;
       emptyEntry = true;
     } else if (i > 1 || (i > 0 && !emptyEntry)) {
       LOG(Edts, "More than one edit entry, not handled. A/V sync will be wrong");
       break;
     } else {
       mMediaStart = media_time;
     }
-    reader->ReadU32(); // media_rate_integer and media_rate_fraction
+    MOZ_TRY(reader->ReadU32()); // media_rate_integer and media_rate_fraction
   }
 
-  return true;
+  return Ok();
 }
 
 Saiz::Saiz(Box& aBox, AtomType aDefaultType)
   : mAuxInfoType(aDefaultType)
   , mAuxInfoTypeParameter(0)
 {
-  if (Parse(aBox)) {
+  if (Parse(aBox).isOk()) {
     mValid = true;
   }
 }
 
-bool
+Result<Ok, nsresult>
 Saiz::Parse(Box& aBox)
 {
   BoxReader reader(aBox);
   if (!reader->CanReadType<uint32_t>()) {
     LOG(Saiz, "Incomplete Box (missing flags)");
-    return false;
+    return Err(NS_ERROR_FAILURE);
   }
-  uint32_t flags = reader->ReadU32();
+  uint32_t flags;
+  MOZ_TRY_VAR(flags, reader->ReadU32());
   uint8_t version = flags >> 24;
   size_t need =
     ((flags & 1) ? 2*sizeof(uint32_t) : 0) + sizeof(uint8_t) + sizeof(uint32_t);
   if (reader->Remaining() < need) {
     LOG(Saiz, "Incomplete Box (have:%" PRIu64 " need:%" PRIu64 ")",
         (uint64_t)reader->Remaining(), (uint64_t)need);
-    return false;
+    return Err(NS_ERROR_FAILURE);
   }
   if (flags & 1) {
-    mAuxInfoType = reader->ReadU32();
-    mAuxInfoTypeParameter = reader->ReadU32();
+    MOZ_TRY_VAR(mAuxInfoType, reader->ReadU32());
+    MOZ_TRY_VAR(mAuxInfoTypeParameter, reader->ReadU32());
   }
-  uint8_t defaultSampleInfoSize = reader->ReadU8();
-  uint32_t count = reader->ReadU32();
+  uint8_t defaultSampleInfoSize;
+  MOZ_TRY_VAR(defaultSampleInfoSize, reader->ReadU8());
+  uint32_t count;
+  MOZ_TRY_VAR(count, reader->ReadU32());
   if (defaultSampleInfoSize) {
     if (!mSampleInfoSize.SetLength(count, fallible)) {
       LOG(Saiz, "OOM");
-      return false;
+    return Err(NS_ERROR_FAILURE);
     }
     memset(mSampleInfoSize.Elements(), defaultSampleInfoSize, mSampleInfoSize.Length());
   } else {
     if (!reader->ReadArray(mSampleInfoSize, count)) {
       LOG(Saiz, "Incomplete Box (OOM or missing count:%u)", count);
-      return false;
+    return Err(NS_ERROR_FAILURE);
     }
   }
-  return true;
+  return Ok();
 }
 
 Saio::Saio(Box& aBox, AtomType aDefaultType)
   : mAuxInfoType(aDefaultType)
   , mAuxInfoTypeParameter(0)
 {
-  if (Parse(aBox)) {
+  if (Parse(aBox).isOk()) {
     mValid = true;
   }
 }
 
-bool
+Result<Ok, nsresult>
 Saio::Parse(Box& aBox)
 {
   BoxReader reader(aBox);
   if (!reader->CanReadType<uint32_t>()) {
     LOG(Saio, "Incomplete Box (missing flags)");
-    return false;
+    return Err(NS_ERROR_FAILURE);
   }
-  uint32_t flags = reader->ReadU32();
+  uint32_t flags;
+  MOZ_TRY_VAR(flags, reader->ReadU32());
   uint8_t version = flags >> 24;
   size_t need = ((flags & 1) ? (2*sizeof(uint32_t)) : 0) + sizeof(uint32_t);
   if (reader->Remaining() < need) {
     LOG(Saio, "Incomplete Box (have:%" PRIu64 " need:%" PRIu64 ")",
         (uint64_t)reader->Remaining(), (uint64_t)need);
-    return false;
+    return Err(NS_ERROR_FAILURE);
   }
   if (flags & 1) {
-    mAuxInfoType = reader->ReadU32();
-    mAuxInfoTypeParameter = reader->ReadU32();
+    MOZ_TRY_VAR(mAuxInfoType, reader->ReadU32());
+    MOZ_TRY_VAR(mAuxInfoTypeParameter, reader->ReadU32());
   }
-  size_t count = reader->ReadU32();
+  size_t count;
+  MOZ_TRY_VAR(count, reader->ReadU32());
   need = (version ? sizeof(uint64_t) : sizeof(uint32_t)) * count;
   if (reader->Remaining() < need) {
     LOG(Saio, "Incomplete Box (have:%" PRIu64 " need:%" PRIu64 ")",
         (uint64_t)reader->Remaining(), (uint64_t)need);
-    return false;
+    return Err(NS_ERROR_FAILURE);
   }
   if (!mOffsets.SetCapacity(count, fallible)) {
     LOG(Saiz, "OOM");
-    return false;
+    return Err(NS_ERROR_FAILURE);
   }
   if (version == 0) {
+    uint32_t offset;
     for (size_t i = 0; i < count; i++) {
-      MOZ_ALWAYS_TRUE(mOffsets.AppendElement(reader->ReadU32(), fallible));
+      MOZ_TRY_VAR(offset, reader->ReadU32());
+      MOZ_ALWAYS_TRUE(mOffsets.AppendElement(offset, fallible));
     }
   } else {
+    uint64_t offset;
     for (size_t i = 0; i < count; i++) {
-      MOZ_ALWAYS_TRUE(mOffsets.AppendElement(reader->ReadU64(), fallible));
+      MOZ_TRY_VAR(offset, reader->ReadU64());
+      MOZ_ALWAYS_TRUE(mOffsets.AppendElement(offset, fallible));
     }
   }
-  return true;
+  return Ok();
 }
 
 Sbgp::Sbgp(Box& aBox)
 {
-  if (Parse(aBox)) {
+  if (Parse(aBox).isOk()) {
     mValid = true;
   }
 }
 
-bool
+Result<Ok, nsresult>
 Sbgp::Parse(Box& aBox)
 {
   BoxReader reader(aBox);
 
   if (!reader->CanReadType<uint32_t>()) {
     LOG(Sbgp, "Incomplete Box (missing flags)");
-    return false;
+    return Err(NS_ERROR_FAILURE);
   }
 
-  uint32_t flags = reader->ReadU32();
+  uint32_t flags;
+  MOZ_TRY_VAR(flags, reader->ReadU32());
   const uint8_t version = flags >> 24;
   flags = flags & 0xffffff;
 
   // Make sure we have enough bytes to read as far as the count.
   uint32_t need = (version == 1 ? sizeof(uint32_t) : 0) + sizeof(uint32_t) * 2;
   if (reader->Remaining() < need) {
     LOG(Sbgp, "Incomplete Box (have:%" PRIu64 ", need:%" PRIu64 ")",
         (uint64_t)reader->Remaining(), (uint64_t)need);
-    return false;
+    return Err(NS_ERROR_FAILURE);
   }
 
-  mGroupingType = reader->ReadU32();
+  uint32_t type;
+  MOZ_TRY_VAR(type, reader->ReadU32());
+  mGroupingType = type;
 
   if (version == 1) {
-    mGroupingTypeParam = reader->Read32();
+    MOZ_TRY_VAR(mGroupingTypeParam, reader->ReadU32());
   }
 
-  uint32_t count = reader->ReadU32();
+  uint32_t count;
+  MOZ_TRY_VAR(count, reader->ReadU32());
 
   // Make sure we can read all the entries.
   need = sizeof(uint32_t) * 2 * count;
   if (reader->Remaining() < need) {
     LOG(Sbgp, "Incomplete Box (have:%" PRIu64 ", need:%" PRIu64 "). Failed to read entries",
         (uint64_t)reader->Remaining(), (uint64_t)need);
-    return false;
+    return Err(NS_ERROR_FAILURE);
   }
 
   for (uint32_t i = 0; i < count; i++) {
-    uint32_t sampleCount = reader->ReadU32();
-    uint32_t groupDescriptionIndex = reader->ReadU32();
+    uint32_t sampleCount;
+    MOZ_TRY_VAR(sampleCount, reader->ReadU32());
+    uint32_t groupDescriptionIndex;
+    MOZ_TRY_VAR(groupDescriptionIndex, reader->ReadU32());
 
     SampleToGroupEntry entry(sampleCount, groupDescriptionIndex);
     if (!mEntries.AppendElement(entry, mozilla::fallible)) {
       LOG(Sbgp, "OOM");
-      return false;
+      return Err(NS_ERROR_FAILURE);
     }
   }
-  return true;
+  return Ok();
 }
 
 Sgpd::Sgpd(Box& aBox)
 {
-  if (Parse(aBox)) {
+  if (Parse(aBox).isOk()) {
     mValid = true;
   }
 }
 
-bool
+Result<Ok, nsresult>
 Sgpd::Parse(Box& aBox)
 {
   BoxReader reader(aBox);
 
   if (!reader->CanReadType<uint32_t>()) {
     LOG(Sgpd, "Incomplete Box (missing flags)");
-    return false;
+    return Err(NS_ERROR_FAILURE);
   }
 
-  uint32_t flags = reader->ReadU32();
+  uint32_t flags;
+  MOZ_TRY_VAR(flags, reader->ReadU32());
   const uint8_t version = flags >> 24;
   flags = flags & 0xffffff;
 
   uint32_t need = ((flags & 1) ? sizeof(uint32_t) : 0) + sizeof(uint32_t) * 2;
   if (reader->Remaining() < need) {
     LOG(Sgpd, "Incomplete Box (have:%" PRIu64 " need:%" PRIu64 ")",
         (uint64_t)reader->Remaining(), (uint64_t)need);
-    return false;
+    return Err(NS_ERROR_FAILURE);
   }
 
-  mGroupingType = reader->ReadU32();
+  uint32_t type;
+  MOZ_TRY_VAR(type, reader->ReadU32());
+  mGroupingType = type;
 
   const uint32_t entrySize = sizeof(uint32_t) + kKeyIdSize;
   uint32_t defaultLength = 0;
 
   if (version == 1) {
-    defaultLength = reader->ReadU32();
+    MOZ_TRY_VAR(defaultLength, reader->ReadU32());
     if (defaultLength < entrySize && defaultLength != 0) {
-      return false;
+      return Err(NS_ERROR_FAILURE);
     }
   }
 
-  uint32_t count = reader->ReadU32();
+  uint32_t count;
+  MOZ_TRY_VAR(count, reader->ReadU32());
 
   // Make sure we have sufficient remaining bytes to read the entries.
   need =
     count * (sizeof(uint32_t) * (version == 1 && defaultLength == 0 ? 2 : 1) +
              kKeyIdSize * sizeof(uint8_t));
   if (reader->Remaining() < need) {
     LOG(Sgpd, "Incomplete Box (have:%" PRIu64 " need:%" PRIu64 "). Failed to read entries",
         (uint64_t)reader->Remaining(), (uint64_t)need);
-    return false;
+    return Err(NS_ERROR_FAILURE);
   }
   for (uint32_t i = 0; i < count; ++i) {
     if (version == 1 && defaultLength == 0) {
-      uint32_t descriptionLength = reader->ReadU32();
+      uint32_t descriptionLength;
+      MOZ_TRY_VAR(descriptionLength, reader->ReadU32());
       if (descriptionLength < entrySize) {
-        return false;
+        return Err(NS_ERROR_FAILURE);
       }
     }
 
     CencSampleEncryptionInfoEntry entry;
-    bool valid = entry.Init(reader);
+    bool valid = entry.Init(reader).isOk();
     if (!valid) {
-      return false;
+      return Err(NS_ERROR_FAILURE);
     }
     if (!mEntries.AppendElement(entry, mozilla::fallible)) {
       LOG(Sgpd, "OOM");
-      return false;
+      return Err(NS_ERROR_FAILURE);
     }
   }
-  return true;
+  return Ok();
 }
 
-bool CencSampleEncryptionInfoEntry::Init(BoxReader& aReader)
+Result<Ok, nsresult>
+CencSampleEncryptionInfoEntry::Init(BoxReader& aReader)
 {
   // Skip a reserved byte.
-  aReader->ReadU8();
+  MOZ_TRY(aReader->ReadU8());
 
-  uint8_t possiblePatternInfo = aReader->ReadU8();
-  uint8_t flag = aReader->ReadU8();
+  uint8_t possiblePatternInfo;
+  MOZ_TRY_VAR(possiblePatternInfo, aReader->ReadU8());
+  uint8_t flag;
+  MOZ_TRY_VAR(flag, aReader->ReadU8());
 
-  mIVSize = aReader->ReadU8();
+  MOZ_TRY_VAR(mIVSize, aReader->ReadU8());
 
   // Read the key id.
+  uint8_t key;
   for (uint32_t i = 0; i < kKeyIdSize; ++i) {
-    mKeyId.AppendElement(aReader->ReadU8());
+    MOZ_TRY_VAR(key, aReader->ReadU8());
+    mKeyId.AppendElement(key);
   }
 
   mIsEncrypted = flag != 0;
 
   if (mIsEncrypted) {
     if (mIVSize != 8 && mIVSize != 16) {
-      return false;
+      return Err(NS_ERROR_FAILURE);
     }
   } else if (mIVSize != 0) {
-    return false;
+    return Err(NS_ERROR_FAILURE);
   }
 
-  return true;
+  return Ok();
 }
 
 #undef LOG
 }
--- a/media/libstagefright/binding/SinfParser.cpp
+++ b/media/libstagefright/binding/SinfParser.cpp
@@ -19,55 +19,59 @@ Sinf::Sinf(Box& aBox)
     *this = parser.GetSinf();
   }
 }
 
 SinfParser::SinfParser(Box& aBox)
 {
   for (Box box = aBox.FirstChild(); box.IsAvailable(); box = box.Next()) {
     if (box.IsType("schm")) {
-      ParseSchm(box);
+      mozilla::Unused << ParseSchm(box);
     } else if (box.IsType("schi")) {
-      ParseSchi(box);
+      mozilla::Unused << ParseSchi(box);
     }
   }
 }
 
-void
+Result<Ok, nsresult>
 SinfParser::ParseSchm(Box& aBox)
 {
   BoxReader reader(aBox);
 
   if (reader->Remaining() < 8) {
-    return;
+    return Err(NS_ERROR_FAILURE);
   }
 
-  mozilla::Unused << reader->ReadU32(); // flags -- ignore
-  mSinf.mDefaultEncryptionType = reader->ReadU32();
+  MOZ_TRY(reader->ReadU32()); // flags -- ignore
+  MOZ_TRY_VAR(mSinf.mDefaultEncryptionType, reader->ReadU32());
+  return Ok();
 }
 
-void
+Result<Ok, nsresult>
 SinfParser::ParseSchi(Box& aBox)
 {
   for (Box box = aBox.FirstChild(); box.IsAvailable(); box = box.Next()) {
-    if (box.IsType("tenc")) {
-      ParseTenc(box);
+    if (box.IsType("tenc") && ParseTenc(box).isErr()) {
+      return Err(NS_ERROR_FAILURE);
     }
   }
+  return Ok();
 }
 
-void
+Result<Ok, nsresult>
 SinfParser::ParseTenc(Box& aBox)
 {
   BoxReader reader(aBox);
 
   if (reader->Remaining() < 24) {
-    return;
+    return Err(NS_ERROR_FAILURE);
   }
 
-  mozilla::Unused << reader->ReadU32(); // flags -- ignore
+  MOZ_TRY(reader->ReadU32()); // flags -- ignore
 
-  uint32_t isEncrypted = reader->ReadU24();
-  mSinf.mDefaultIVSize = reader->ReadU8();
+  uint32_t isEncrypted;
+  MOZ_TRY_VAR(isEncrypted, reader->ReadU24());
+  MOZ_TRY_VAR(mSinf.mDefaultIVSize, reader->ReadU8());
   memcpy(mSinf.mDefaultKeyID, reader->Read(16), 16);
+  return Ok();
 }
 
 }
--- a/media/libstagefright/binding/include/mp4_demuxer/Box.h
+++ b/media/libstagefright/binding/include/mp4_demuxer/Box.h
@@ -7,17 +7,17 @@
 #ifndef BOX_H_
 #define BOX_H_
 
 #include <stdint.h>
 #include "nsTArray.h"
 #include "MediaResource.h"
 #include "mozilla/EndianUtils.h"
 #include "mp4_demuxer/AtomType.h"
-#include "mp4_demuxer/ByteReader.h"
+#include "mp4_demuxer/BufferReader.h"
 
 using namespace mozilla;
 
 namespace mp4_demuxer {
 
 class Stream;
 
 class BoxContext
@@ -70,17 +70,17 @@ private:
 class MOZ_RAII BoxReader
 {
 public:
   explicit BoxReader(Box& aBox)
     : mBuffer(aBox.Read())
     , mReader(mBuffer.Elements(), mBuffer.Length())
   {
   }
-  ByteReader* operator->() { return &mReader; }
+  BufferReader* operator->() { return &mReader; }
 
 private:
   nsTArray<uint8_t> mBuffer;
-  ByteReader mReader;
+  BufferReader mReader;
 };
 }
 
 #endif
--- a/media/libstagefright/binding/include/mp4_demuxer/BufferReader.h
+++ b/media/libstagefright/binding/include/mp4_demuxer/BufferReader.h
@@ -1,18 +1,20 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef BUFFER_READER_H_
 #define BUFFER_READER_H_
 
 #include "mozilla/EndianUtils.h"
+#include "nscore.h"
 #include "nsTArray.h"
 #include "MediaData.h"
+#include "mozilla/Result.h"
 
 namespace mp4_demuxer {
 
 class MOZ_RAII BufferReader
 {
 public:
   BufferReader() : mPtr(nullptr), mRemaining(0) {}
   BufferReader(const uint8_t* aData, size_t aSize)
@@ -37,127 +39,124 @@ public:
   {
     MOZ_ASSERT(!mPtr && !mRemaining);
     mPtr = aData.Elements();
     mRemaining = aData.Length();
     mLength = mRemaining;
   }
 
   ~BufferReader()
-  {
-  }
+  {}
 
   size_t Offset() const
   {
     return mLength - mRemaining;
   }
 
   size_t Remaining() const { return mRemaining; }
 
-  bool CanRead8() const { return mRemaining >= 1; }
-
-  uint8_t ReadU8()
+  Result<uint8_t, nsresult> ReadU8()
   {
     auto ptr = Read(1);
     if (!ptr) {
       NS_WARNING("Failed to read data");
-      return 0;
+      return mozilla::Err(NS_ERROR_FAILURE);
     }
     return *ptr;
   }
 
-  bool CanRead16() { return mRemaining >= 2; }
-
-  uint16_t ReadU16()
+  Result<uint16_t, nsresult> ReadU16()
   {
     auto ptr = Read(2);
     if (!ptr) {
       NS_WARNING("Failed to read data");
-      return 0;
+      return mozilla::Err(NS_ERROR_FAILURE);
     }
     return mozilla::BigEndian::readUint16(ptr);
   }
 
-  int16_t ReadLE16()
+  Result<int16_t, nsresult> ReadLE16()
   {
     auto ptr = Read(2);
     if (!ptr) {
       NS_WARNING("Failed to read data");
-      return 0;
+      return mozilla::Err(NS_ERROR_FAILURE);
     }
     return mozilla::LittleEndian::readInt16(ptr);
   }
 
-  uint32_t ReadU24()
+  Result<uint32_t, nsresult> ReadU24()
   {
     auto ptr = Read(3);
     if (!ptr) {
       NS_WARNING("Failed to read data");
-      return 0;
+      return mozilla::Err(NS_ERROR_FAILURE);
     }
     return ptr[0] << 16 | ptr[1] << 8 | ptr[2];
   }
 
-  uint32_t Read24()
+  Result<int32_t, nsresult> Read24()
   {
-    return (uint32_t)ReadU24();
+    auto res = ReadU24();
+    if (res.isErr()) {
+      return mozilla::Err(NS_ERROR_FAILURE);
+    }
+    return (int32_t)res.unwrap();
   }
 
-  int32_t ReadLE24()
+  Result<int32_t, nsresult> ReadLE24()
   {
     auto ptr = Read(3);
     if (!ptr) {
       NS_WARNING("Failed to read data");
-      return 0;
+      return mozilla::Err(NS_ERROR_FAILURE);
     }
     int32_t result = int32_t(ptr[2] << 16 | ptr[1] << 8 | ptr[0]);
     if (result & 0x00800000u) {
       result -= 0x1000000;
     }
     return result;
   }
 
-  bool CanRead32() { return mRemaining >= 4; }
-
-  uint32_t ReadU32()
+  Result<uint32_t, nsresult> ReadU32()
   {
     auto ptr = Read(4);
     if (!ptr) {
       NS_WARNING("Failed to read data");
-      return 0;
+      return mozilla::Err(NS_ERROR_FAILURE);
     }
     return mozilla::BigEndian::readUint32(ptr);
   }
 
-  int32_t Read32()
+  Result<int32_t, nsresult> Read32()
   {
     auto ptr = Read(4);
     if (!ptr) {
       NS_WARNING("Failed to read data");
-      return 0;
+      return mozilla::Err(NS_ERROR_FAILURE);
     }
     return mozilla::BigEndian::readInt32(ptr);
   }
 
-  uint64_t ReadU64()
+  Result<uint64_t, nsresult> ReadU64()
   {
     auto ptr = Read(8);
     if (!ptr) {
       NS_WARNING("Failed to read data");
-      return 0;
+      return mozilla::Err(NS_ERROR_FAILURE);
     }
     return mozilla::BigEndian::readUint64(ptr);
   }
 
-  int64_t Read64()
+  Result<int64_t, nsresult> Read64()
   {
     auto ptr = Read(8);
     if (!ptr) {
       NS_WARNING("Failed to read data");
-      return 0;
+      return mozilla::Err(NS_ERROR_FAILURE);
     }
     return mozilla::BigEndian::readInt64(ptr);
   }
 
   const uint8_t* Read(size_t aCount)
   {
     if (aCount > mRemaining) {
       mRemaining = 0;
--- a/media/libstagefright/binding/include/mp4_demuxer/MoofParser.h
+++ b/media/libstagefright/binding/include/mp4_demuxer/MoofParser.h
@@ -1,15 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOOF_PARSER_H_
 #define MOOF_PARSER_H_
 
+#include "mozilla/ResultExtensions.h"
 #include "mp4_demuxer/Atom.h"
 #include "mp4_demuxer/AtomType.h"
 #include "mp4_demuxer/SinfParser.h"
 #include "mp4_demuxer/Stream.h"
 #include "mp4_demuxer/Interval.h"
 #include "MediaResource.h"
 
 namespace mp4_demuxer {
@@ -40,32 +41,32 @@ public:
   }
 
   uint64_t mCreationTime;
   uint64_t mModificationTime;
   uint32_t mTimescale;
   uint64_t mDuration;
 
 protected:
-  bool Parse(Box& aBox);
+  Result<Ok, nsresult> Parse(Box& aBox);
 };
 
 class Tkhd : public Mvhd
 {
 public:
   Tkhd()
     : mTrackId(0)
   {
   }
   explicit Tkhd(Box& aBox);
 
   uint32_t mTrackId;
 
 protected:
-  bool Parse(Box& aBox);
+  Result<Ok, nsresult> Parse(Box& aBox);
 };
 
 class Mdhd : public Mvhd
 {
 public:
   Mdhd() = default;
   explicit Mdhd(Box& aBox);
 };
@@ -88,49 +89,49 @@ public:
   uint32_t mFlags;
   uint32_t mTrackId;
   uint32_t mDefaultSampleDescriptionIndex;
   uint32_t mDefaultSampleDuration;
   uint32_t mDefaultSampleSize;
   uint32_t mDefaultSampleFlags;
 
 protected:
-  bool Parse(Box& aBox);
+  Result<Ok, nsresult> Parse(Box& aBox);
 };
 
 class Tfhd : public Trex
 {
 public:
   explicit Tfhd(Trex& aTrex)
     : Trex(aTrex)
     , mBaseDataOffset(0)
   {
     mValid = aTrex.IsValid();
   }
   Tfhd(Box& aBox, Trex& aTrex);
 
   uint64_t mBaseDataOffset;
 
 protected:
-  bool Parse(Box& aBox);
+  Result<Ok, nsresult> Parse(Box& aBox);
 };
 
 class Tfdt : public Atom
 {
 public:
   Tfdt()
     : mBaseMediaDecodeTime(0)
   {
   }
   explicit Tfdt(Box& aBox);
 
   uint64_t mBaseMediaDecodeTime;
 
 protected:
-  bool Parse(Box& aBox);
+  Result<Ok, nsresult> Parse(Box& aBox);
 };
 
 class Edts : public Atom
 {
 public:
   Edts()
     : mMediaStart(0)
     , mEmptyOffset(0)
@@ -142,17 +143,17 @@ public:
     // edts is optional
     return true;
   }
 
   int64_t mMediaStart;
   int64_t mEmptyOffset;
 
 protected:
-  bool Parse(Box& aBox);
+  Result<Ok, nsresult> Parse(Box& aBox);
 };
 
 struct Sample
 {
   mozilla::MediaByteRange mByteRange;
   mozilla::MediaByteRange mCencRange;
   Microseconds mDecodeTime;
   Interval<Microseconds> mCompositionRange;
@@ -164,30 +165,30 @@ class Saiz final : public Atom
 public:
   Saiz(Box& aBox, AtomType aDefaultType);
 
   AtomType mAuxInfoType;
   uint32_t mAuxInfoTypeParameter;
   FallibleTArray<uint8_t> mSampleInfoSize;
 
 protected:
-  bool Parse(Box& aBox);
+  Result<Ok, nsresult> Parse(Box& aBox);
 };
 
 class Saio final : public Atom
 {
 public:
   Saio(Box& aBox, AtomType aDefaultType);
 
   AtomType mAuxInfoType;
   uint32_t mAuxInfoTypeParameter;
   FallibleTArray<uint64_t> mOffsets;
 
 protected:
-  bool Parse(Box& aBox);
+  Result<Ok, nsresult> Parse(Box& aBox);
 };
 
 struct SampleToGroupEntry
 {
 public:
   static const uint32_t kTrackGroupDescriptionIndexBase = 0;
   static const uint32_t kFragmentGroupDescriptionIndexBase = 0x10000;
 
@@ -206,41 +207,41 @@ class Sbgp final : public Atom // Sample
 public:
   explicit Sbgp(Box& aBox);
 
   AtomType mGroupingType;
   uint32_t mGroupingTypeParam;
   FallibleTArray<SampleToGroupEntry> mEntries;
 
 protected:
-  bool Parse(Box& aBox);
+  Result<Ok, nsresult> Parse(Box& aBox);
 };
 
 struct CencSampleEncryptionInfoEntry final
 {
 public:
   CencSampleEncryptionInfoEntry() { }
 
-  bool Init(BoxReader& aReader);
+  Result<Ok, nsresult> Init(BoxReader& aReader);
 
   bool mIsEncrypted = false;
   uint8_t mIVSize = 0;
   nsTArray<uint8_t> mKeyId;
 };
 
 class Sgpd final : public Atom // SampleGroupDescription box.
 {
 public:
   explicit Sgpd(Box& aBox);
 
   AtomType mGroupingType;
   FallibleTArray<CencSampleEncryptionInfoEntry> mEntries;
 
 protected:
-  bool Parse(Box& aBox);
+  Result<Ok, nsresult> Parse(Box& aBox);
 };
 
 class AuxInfo {
 public:
   AuxInfo(int64_t aMoofOffset, Saiz& aSaiz, Saio& aSaio);
 
 private:
   int64_t mMoofOffset;
@@ -266,17 +267,17 @@ public:
   FallibleTArray<Saiz> mSaizs;
   FallibleTArray<Saio> mSaios;
   nsTArray<nsTArray<uint8_t>> mPsshes;
 
 private:
     // aDecodeTime is updated to the end of the parsed TRAF on return.
   void ParseTraf(Box& aBox, Trex& aTrex, Mvhd& aMvhd, Mdhd& aMdhd, Edts& aEdts, Sinf& aSinf, uint64_t* aDecodeTime, bool aIsAudio);
   // aDecodeTime is updated to the end of the parsed TRUN on return.
-  bool ParseTrun(Box& aBox, Tfhd& aTfhd, Mvhd& aMvhd, Mdhd& aMdhd, Edts& aEdts, uint64_t* aDecodeTime, bool aIsAudio);
+  Result<Ok, nsresult> ParseTrun(Box& aBox, Tfhd& aTfhd, Mvhd& aMvhd, Mdhd& aMdhd, Edts& aEdts, uint64_t* aDecodeTime, bool aIsAudio);
   void ParseSaiz(Box& aBox);
   void ParseSaio(Box& aBox);
   bool ProcessCenc();
   uint64_t mMaxRoundingError;
 };
 
 class MoofParser
 {
--- a/media/libstagefright/binding/include/mp4_demuxer/SinfParser.h
+++ b/media/libstagefright/binding/include/mp4_demuxer/SinfParser.h
@@ -1,16 +1,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 
 #ifndef SINF_PARSER_H_
 #define SINF_PARSER_H_
 
+#include "mozilla/ResultExtensions.h"
 #include "mp4_demuxer/Atom.h"
 #include "mp4_demuxer/AtomType.h"
 
 namespace mp4_demuxer {
 
 class Box;
 
 class Sinf : public Atom
@@ -34,18 +35,18 @@ public:
 
 class SinfParser
 {
 public:
   explicit SinfParser(Box& aBox);
 
   Sinf& GetSinf() { return mSinf; }
 private:
-  void ParseSchm(Box& aBox);
-  void ParseSchi(Box& aBox);
-  void ParseTenc(Box& aBox);
+  Result<Ok, nsresult> ParseSchm(Box& aBox);
+  Result<Ok, nsresult> ParseSchi(Box& aBox);
+  Result<Ok, nsresult> ParseTenc(Box& aBox);
 
   Sinf mSinf;
 };
 
 }
 
 #endif // SINF_PARSER_H_