--- 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/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
{