--- a/dom/media/mediasource/ContainerParser.cpp
+++ b/dom/media/mediasource/ContainerParser.cpp
@@ -8,20 +8,21 @@
#include "WebMBufferedParser.h"
#include "mozilla/EndianUtils.h"
#include "mozilla/IntegerPrintfMacros.h"
#include "mozilla/ErrorResult.h"
#include "mp4_demuxer/MoofParser.h"
#include "mozilla/Logging.h"
#include "mozilla/Maybe.h"
+#include "mozilla/Result.h"
#include "MediaData.h"
#ifdef MOZ_FMP4
#include "mp4_demuxer/AtomType.h"
-#include "mp4_demuxer/ByteReader.h"
+#include "mp4_demuxer/BufferReader.h"
#include "mp4_demuxer/Stream.h"
#endif
#include "nsAutoPtr.h"
#include "SourceBufferResource.h"
#include <algorithm>
extern mozilla::LogModule* GetMediaSourceSamplesLog();
@@ -473,69 +474,74 @@ private:
eInitSegment,
eMediaSegment,
eEnd
};
AtomParser(const MediaContainerType& aType, const MediaByteBuffer* aData,
StopAt aStop = StopAt::eEnd)
{
+ mValid = Init(aType, aData, aStop).isOk();
+ }
+
+ Result<Ok, nsresult> Init(const MediaContainerType& aType, const MediaByteBuffer* aData,
+ StopAt aStop)
+ {
const MediaContainerType mType(aType); // for logging macro.
- mp4_demuxer::ByteReader reader(aData);
+ mp4_demuxer::BufferReader reader(aData);
mp4_demuxer::AtomType initAtom("moov");
mp4_demuxer::AtomType mediaAtom("moof");
mp4_demuxer::AtomType dataAtom("mdat");
// Valid top-level boxes defined in ISO/IEC 14496-12 (Table 1)
static const mp4_demuxer::AtomType validBoxes[] = {
"ftyp", "moov", // init segment
"pdin", "free", "sidx", // optional prior moov box
"styp", "moof", "mdat", // media segment
"mfra", "skip", "meta", "meco", "ssix", "prft", // others.
"pssh", // optional with encrypted EME, though ignored.
"emsg", // ISO23009-1:2014 Section 5.10.3.3
"bloc", "uuid" // boxes accepted by chrome.
};
while (reader.Remaining() >= 8) {
- uint64_t size = reader.ReadU32();
+ uint32_t tmp;
+ MOZ_TRY_VAR(tmp, reader.ReadU32());
+ uint64_t size = tmp;
const uint8_t* typec = reader.Peek(4);
- mp4_demuxer::AtomType type(reader.ReadU32());
+ MOZ_TRY_VAR(tmp, reader.ReadU32());
+ mp4_demuxer::AtomType type(tmp);
MSE_DEBUGV(AtomParser ,"Checking atom:'%c%c%c%c' @ %u",
typec[0], typec[1], typec[2], typec[3],
(uint32_t)reader.Offset() - 8);
if (std::find(std::begin(validBoxes), std::end(validBoxes), type)
== std::end(validBoxes)) {
// No valid box found, no point continuing.
mLastInvalidBox[0] = typec[0];
mLastInvalidBox[1] = typec[1];
mLastInvalidBox[2] = typec[2];
mLastInvalidBox[3] = typec[3];
mLastInvalidBox[4] = '\0';
- mValid = false;
- break;
+ return Err(NS_ERROR_FAILURE);
}
if (mInitOffset.isNothing() &&
mp4_demuxer::AtomType(type) == initAtom) {
mInitOffset = Some(reader.Offset());
}
if (mMediaOffset.isNothing() &&
mp4_demuxer::AtomType(type) == mediaAtom) {
mMediaOffset = Some(reader.Offset());
}
if (mDataOffset.isNothing() &&
mp4_demuxer::AtomType(type) == dataAtom) {
mDataOffset = Some(reader.Offset());
}
if (size == 1) {
// 64 bits size.
- if (!reader.CanReadType<uint64_t>()) {
- break;
- }
- size = reader.ReadU64();
+ MOZ_TRY_VAR(size, reader.ReadU64());
} else if (size == 0) {
// Atom extends to the end of the buffer, it can't have what we're
// looking for.
break;
}
if (reader.Remaining() < size - 8) {
// Incomplete atom.
break;
@@ -551,16 +557,18 @@ private:
if (aStop == StopAt::eMediaSegment &&
(mInitOffset || (mMediaOffset && mDataOffset))) {
// When we're looking for a media segment, if we encountered an init
// segment, it we will need to be processed first. So we can stop
// right away if we have found an init segment.
break;
}
}
+
+ return Ok();
}
bool StartWithInitSegment() const
{
return mInitOffset.isSome() &&
(mMediaOffset.isNothing() || mInitOffset.ref() < mMediaOffset.ref());
}
bool StartWithMediaSegment() const
@@ -569,17 +577,17 @@ private:
(mInitOffset.isNothing() || mMediaOffset.ref() < mInitOffset.ref());
}
bool IsValid() const { return mValid; }
const char* LastInvalidBox() const { return mLastInvalidBox; }
private:
Maybe<size_t> mInitOffset;
Maybe<size_t> mMediaOffset;
Maybe<size_t> mDataOffset;
- bool mValid = true;
+ bool mValid;
char mLastInvalidBox[5];
};
public:
MediaResult ParseStartAndEndTimestamps(MediaByteBuffer* aData,
int64_t& aStart,
int64_t& aEnd) override
{