Bug 1314533: [MSE] P1. Change member prototype. r?gerald
MozReview-Commit-ID: L8H4oDoTm2b
--- a/dom/media/mediasource/ContainerParser.cpp
+++ b/dom/media/mediasource/ContainerParser.cpp
@@ -33,38 +33,38 @@ namespace mozilla {
ContainerParser::ContainerParser(const nsACString& aType)
: mHasInitData(false)
, mType(aType)
{
}
ContainerParser::~ContainerParser() = default;
-bool
+MediaResult
ContainerParser::IsInitSegmentPresent(MediaByteBuffer* aData)
{
MSE_DEBUG(ContainerParser, "aLength=%u [%x%x%x%x]",
aData->Length(),
aData->Length() > 0 ? (*aData)[0] : 0,
aData->Length() > 1 ? (*aData)[1] : 0,
aData->Length() > 2 ? (*aData)[2] : 0,
aData->Length() > 3 ? (*aData)[3] : 0);
- return false;
+ return NS_ERROR_NOT_AVAILABLE;
}
-bool
+MediaResult
ContainerParser::IsMediaSegmentPresent(MediaByteBuffer* aData)
{
MSE_DEBUG(ContainerParser, "aLength=%u [%x%x%x%x]",
aData->Length(),
aData->Length() > 0 ? (*aData)[0] : 0,
aData->Length() > 1 ? (*aData)[1] : 0,
aData->Length() > 2 ? (*aData)[2] : 0,
aData->Length() > 3 ? (*aData)[3] : 0);
- return false;
+ return NS_ERROR_NOT_AVAILABLE;
}
bool
ContainerParser::ParseStartAndEndTimestamps(MediaByteBuffer* aData,
int64_t& aStart, int64_t& aEnd)
{
return false;
}
@@ -118,17 +118,17 @@ public:
: ContainerParser(aType)
, mParser(0)
, mOffset(0)
{}
static const unsigned NS_PER_USEC = 1000;
static const unsigned USEC_PER_SEC = 1000000;
- bool IsInitSegmentPresent(MediaByteBuffer* aData) override
+ MediaResult IsInitSegmentPresent(MediaByteBuffer* aData) override
{
ContainerParser::IsInitSegmentPresent(aData);
// XXX: This is overly primitive, needs to collect data as it's appended
// to the SB and handle, rather than assuming everything is present in a
// single aData segment.
// 0x1a45dfa3 // EBML
// ...
// DocType == "webm"
@@ -138,22 +138,22 @@ public:
// elements that follow)
// 0x1549a966 // -> Segment Info
// 0x1654ae6b // -> One or more Tracks
// 0x1a45dfa3 // EBML
if (aData->Length() >= 4 &&
(*aData)[0] == 0x1a && (*aData)[1] == 0x45 && (*aData)[2] == 0xdf &&
(*aData)[3] == 0xa3) {
- return true;
+ return NS_OK;
}
- return false;
+ return NS_ERROR_NOT_AVAILABLE;
}
- bool IsMediaSegmentPresent(MediaByteBuffer* aData) override
+ MediaResult IsMediaSegmentPresent(MediaByteBuffer* aData) override
{
ContainerParser::IsMediaSegmentPresent(aData);
// XXX: This is overly primitive, needs to collect data as it's appended
// to the SB and handle, rather than assuming everything is present in a
// single aData segment.
// 0x1a45dfa3 // EBML
// ...
// DocType == "webm"
@@ -161,33 +161,34 @@ public:
// 0x18538067 // Segment (must be "unknown" size)
// 0x1549a966 // -> Segment Info
// 0x1654ae6b // -> One or more Tracks
// 0x1f43b675 // Cluster
if (aData->Length() >= 4 &&
(*aData)[0] == 0x1f && (*aData)[1] == 0x43 && (*aData)[2] == 0xb6 &&
(*aData)[3] == 0x75) {
- return true;
+ return NS_OK;
}
// 0x1c53bb6b // Cues
if (aData->Length() >= 4 &&
(*aData)[0] == 0x1c && (*aData)[1] == 0x53 && (*aData)[2] == 0xbb &&
(*aData)[3] == 0x6b) {
- return true;
+ return NS_OK;
}
- return false;
+ return NS_ERROR_NOT_AVAILABLE;
}
bool ParseStartAndEndTimestamps(MediaByteBuffer* aData,
int64_t& aStart, int64_t& aEnd) override
{
- bool initSegment = IsInitSegmentPresent(aData);
+ bool initSegment = NS_SUCCEEDED(IsInitSegmentPresent(aData));
- if (mLastMapping && (initSegment || IsMediaSegmentPresent(aData))) {
+ if (mLastMapping &&
+ (initSegment || NS_SUCCEEDED(IsMediaSegmentPresent(aData)))) {
// The last data contained a complete cluster but we can only detect it
// now that a new one is starting.
// We use mOffset as end position to ensure that any blocks not reported
// by WebMBufferParser are properly skipped.
mCompleteMediaSegmentRange = MediaByteRange(mLastMapping.ref().mSyncOffset,
mOffset);
mLastMapping.reset();
MSE_DEBUG(WebMContainerParser, "New cluster found at start, ending previous one");
@@ -332,30 +333,30 @@ private:
#ifdef MOZ_FMP4
class MP4ContainerParser : public ContainerParser {
public:
explicit MP4ContainerParser(const nsACString& aType)
: ContainerParser(aType)
{}
- bool IsInitSegmentPresent(MediaByteBuffer* aData) override
+ MediaResult IsInitSegmentPresent(MediaByteBuffer* aData) override
{
ContainerParser::IsInitSegmentPresent(aData);
// Each MP4 atom has a chunk size and chunk type. The root chunk in an MP4
// file is the 'ftyp' atom followed by a file type. We just check for a
// vaguely valid 'ftyp' atom.
AtomParser parser(mType, aData);
- return parser.StartWithInitSegment();
+ return parser.StartWithInitSegment() ? NS_OK : NS_ERROR_NOT_AVAILABLE;
}
- bool IsMediaSegmentPresent(MediaByteBuffer* aData) override
+ MediaResult IsMediaSegmentPresent(MediaByteBuffer* aData) override
{
AtomParser parser(mType, aData);
- return parser.StartWithMediaSegment();
+ return parser.StartWithMediaSegment() ? NS_OK : NS_ERROR_NOT_AVAILABLE;
}
private:
class AtomParser {
public:
AtomParser(const nsACString& aType, const MediaByteBuffer* aData)
{
const nsCString mType(aType); // for logging macro.
@@ -415,17 +416,17 @@ private:
Maybe<size_t> mInitOffset;
Maybe<size_t> mMediaOffset;
};
public:
bool ParseStartAndEndTimestamps(MediaByteBuffer* aData,
int64_t& aStart, int64_t& aEnd) override
{
- bool initSegment = IsInitSegmentPresent(aData);
+ bool initSegment = NS_SUCCEEDED(IsInitSegmentPresent(aData));
if (initSegment) {
mResource = new SourceBufferResource(NS_LITERAL_CSTRING("video/mp4"));
mStream = new MP4Stream(mResource);
// We use a timestampOffset of 0 for ContainerParser, and require
// consumers of ParseStartAndEndTimestamps to add their timestamp offset
// manually. This allows the ContainerParser to be shared across different
// timestampOffsets.
mParser = new mp4_demuxer::MoofParser(mStream, 0, /* aIsAudio = */ false);
@@ -549,56 +550,56 @@ public:
// Return successfully parsed data.
header.header_length = header_length;
header.frame_length = header_length + data_length;
header.aac_frames = frames;
header.have_crc = have_crc;
return true;
}
- bool IsInitSegmentPresent(MediaByteBuffer* aData) override
+ MediaResult IsInitSegmentPresent(MediaByteBuffer* aData) override
{
// Call superclass for logging.
ContainerParser::IsInitSegmentPresent(aData);
Header header;
if (!Parse(aData, header)) {
- return false;
+ return NS_ERROR_NOT_AVAILABLE;
}
MSE_DEBUGV(ADTSContainerParser, "%llu byte frame %d aac frames%s",
(unsigned long long)header.frame_length, (int)header.aac_frames,
header.have_crc ? " crc" : "");
- return true;
+ return NS_OK;
}
- bool IsMediaSegmentPresent(MediaByteBuffer* aData) override
+ MediaResult IsMediaSegmentPresent(MediaByteBuffer* aData) override
{
// Call superclass for logging.
ContainerParser::IsMediaSegmentPresent(aData);
// Make sure we have a header so we know how long the frame is.
// NB this assumes the media segment buffer starts with an
// initialization segment. Since every frame has an ADTS header
// this is a normal place to divide packets, but we can re-parse
// mInitData if we need to handle separate media segments.
Header header;
if (!Parse(aData, header)) {
- return false;
+ return NS_ERROR_NOT_AVAILABLE;
}
// We're supposed to return true as long as aData contains the
// start of a media segment, whether or not it's complete. So
// return true if we have any data beyond the header.
if (aData->Length() <= header.header_length) {
- return false;
+ return NS_ERROR_NOT_AVAILABLE;
}
// We should have at least a partial frame.
- return true;
+ return NS_OK;
}
bool ParseStartAndEndTimestamps(MediaByteBuffer* aData,
int64_t& aStart, int64_t& aEnd) override
{
// ADTS header.
Header header;
if (!Parse(aData, header)) {
--- a/dom/media/mediasource/ContainerParser.h
+++ b/dom/media/mediasource/ContainerParser.h
@@ -5,36 +5,43 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MOZILLA_CONTAINERPARSER_H_
#define MOZILLA_CONTAINERPARSER_H_
#include "mozilla/RefPtr.h"
#include "nsString.h"
#include "MediaResource.h"
+#include "MediaResult.h"
namespace mozilla {
class MediaByteBuffer;
class SourceBufferResource;
class ContainerParser {
public:
explicit ContainerParser(const nsACString& aType);
virtual ~ContainerParser();
// Return true if aData starts with an initialization segment.
// The base implementation exists only for debug logging and is expected
// to be called first from the overriding implementation.
- virtual bool IsInitSegmentPresent(MediaByteBuffer* aData);
+ // Return NS_OK if segment is present, NS_ERROR_NOT_AVAILABLE if no sufficient
+ // data is currently available to make a determination. Any other value
+ // indicates an error.
+ virtual MediaResult IsInitSegmentPresent(MediaByteBuffer* aData);
// Return true if aData starts with a media segment.
// The base implementation exists only for debug logging and is expected
// to be called first from the overriding implementation.
- virtual bool IsMediaSegmentPresent(MediaByteBuffer* aData);
+ // Return NS_OK if segment is present, NS_ERROR_NOT_AVAILABLE if no sufficient
+ // data is currently available to make a determination. Any other value
+ // indicates an error.
+ virtual MediaResult IsMediaSegmentPresent(MediaByteBuffer* aData);
// Parse aData to extract the start and end frame times from the media
// segment. aData may not start on a parser sync boundary. Return true
// if aStart and aEnd have been updated.
virtual bool ParseStartAndEndTimestamps(MediaByteBuffer* aData,
int64_t& aStart, int64_t& aEnd);
// Compare aLhs and rHs, considering any error that may exist in the
--- a/dom/media/mediasource/TrackBuffersManager.cpp
+++ b/dom/media/mediasource/TrackBuffersManager.cpp
@@ -631,25 +631,25 @@ TrackBuffersManager::SegmentParserLoop()
// ignored from the start of the input buffer.
// We do not remove bytes from our input buffer. Instead we enforce that
// our ContainerParser is able to skip over all data that is supposed to be
// ignored.
// 4. If the append state equals WAITING_FOR_SEGMENT, then run the following
// steps:
if (mSourceBufferAttributes->GetAppendState() == AppendState::WAITING_FOR_SEGMENT) {
- if (mParser->IsInitSegmentPresent(mInputBuffer)) {
+ if (NS_SUCCEEDED(mParser->IsInitSegmentPresent(mInputBuffer))) {
SetAppendState(AppendState::PARSING_INIT_SEGMENT);
if (mFirstInitializationSegmentReceived) {
// This is a new initialization segment. Obsolete the old one.
RecreateParser(false);
}
continue;
}
- if (mParser->IsMediaSegmentPresent(mInputBuffer)) {
+ if (NS_SUCCEEDED(mParser->IsMediaSegmentPresent(mInputBuffer))) {
SetAppendState(AppendState::PARSING_MEDIA_SEGMENT);
mNewMediaSegmentStarted = true;
continue;
}
// We have neither an init segment nor a media segment, this is either
// invalid data or not enough data to detect a segment type.
MSE_DEBUG("Found invalid or incomplete data.");
NeedMoreData();
--- a/dom/media/mediasource/gtest/TestContainerParser.cpp
+++ b/dom/media/mediasource/gtest/TestContainerParser.cpp
@@ -42,43 +42,43 @@ TEST(ContainerParser, ADTSHeader) {
parser = ContainerParser::CreateForMIMEType(NS_LITERAL_CSTRING("audio/aac"));
ASSERT_NE(parser, nullptr);
// Audio data should have no gaps.
EXPECT_EQ(parser->GetRoundingError(), 0);
// Test a valid header.
RefPtr<MediaByteBuffer> header = make_adts_header();
- EXPECT_TRUE(parser->IsInitSegmentPresent(header));
+ EXPECT_TRUE(NS_SUCCEEDED(parser->IsInitSegmentPresent(header)));
// Test variations.
uint8_t save = header->ElementAt(1);
for (uint8_t i = 1; i < 3; ++i) {
// Set non-zero layer.
header->ReplaceElementAt(1, (header->ElementAt(1) & 0xf9) | (i << 1));
- EXPECT_FALSE(parser->IsInitSegmentPresent(header))
+ EXPECT_FALSE(NS_SUCCEEDED(parser->IsInitSegmentPresent(header)))
<< "Accepted non-zero layer in header.";
}
header->ReplaceElementAt(1, save);
save = header->ElementAt(2);
header->ReplaceElementAt(2, (header->ElementAt(2) & 0x3b) | (15 << 2));
- EXPECT_FALSE(parser->IsInitSegmentPresent(header))
+ EXPECT_FALSE(NS_SUCCEEDED(parser->IsInitSegmentPresent(header)))
<< "Accepted explicit frequency in header.";
header->ReplaceElementAt(2, save);
// Test a short header.
header->SetLength(6);
- EXPECT_FALSE(parser->IsInitSegmentPresent(header))
+ EXPECT_FALSE(NS_SUCCEEDED(parser->IsInitSegmentPresent(header)))
<< "Accepted too-short header.";
- EXPECT_FALSE(parser->IsMediaSegmentPresent(header))
+ EXPECT_FALSE(NS_SUCCEEDED(parser->IsMediaSegmentPresent(header)))
<< "Found media segment when there was just a partial header.";
// Test parse results.
header = make_adts_header();
- EXPECT_FALSE(parser->IsMediaSegmentPresent(header))
+ EXPECT_FALSE(NS_SUCCEEDED(parser->IsMediaSegmentPresent(header)))
<< "Found media segment when there was just a header.";
int64_t start = 0;
int64_t end = 0;
EXPECT_FALSE(parser->ParseStartAndEndTimestamps(header, start, end));
EXPECT_TRUE(parser->HasInitData());
EXPECT_TRUE(parser->HasCompleteInitData());
MediaByteBuffer* init = parser->InitData();