summaryrefslogtreecommitdiffstats
path: root/dom
diff options
context:
space:
mode:
Diffstat (limited to 'dom')
-rw-r--r--dom/media/mediasource/ContainerParser.cpp57
-rw-r--r--dom/media/mp3/MP3Demuxer.cpp5
-rw-r--r--dom/media/webaudio/AudioBuffer.cpp4
-rw-r--r--dom/media/webm/WebMBufferedParser.cpp15
-rw-r--r--dom/media/webm/WebMBufferedParser.h17
5 files changed, 54 insertions, 44 deletions
diff --git a/dom/media/mediasource/ContainerParser.cpp b/dom/media/mediasource/ContainerParser.cpp
index b4dcfde8a..9711d4fb6 100644
--- a/dom/media/mediasource/ContainerParser.cpp
+++ b/dom/media/mediasource/ContainerParser.cpp
@@ -127,58 +127,37 @@ public:
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"
- // ...
- // 0x18538067 // Segment (must be "unknown" size or contain a value large
- // enough to include the Segment Information and Tracks
- // elements that follow)
- // 0x1549a966 // -> Segment Info
- // 0x1654ae6b // -> One or more Tracks
-
- // 0x1a45dfa3 // EBML
if (aData->Length() < 4) {
return NS_ERROR_NOT_AVAILABLE;
}
- if ((*aData)[0] == 0x1a && (*aData)[1] == 0x45 && (*aData)[2] == 0xdf &&
- (*aData)[3] == 0xa3) {
- return NS_OK;
+ WebMBufferedParser parser(0);
+ nsTArray<WebMTimeDataOffset> mapping;
+ ReentrantMonitor dummy("dummy");
+ bool result = parser.Append(aData->Elements(), aData->Length(), mapping,
+ dummy);
+ if (!result) {
+ return MediaResult(NS_ERROR_FAILURE, RESULT_DETAIL("Invalid webm content"));
}
- return MediaResult(NS_ERROR_FAILURE, RESULT_DETAIL("Invalid webm content"));
+ return parser.mInitEndOffset > 0 ? NS_OK : NS_ERROR_NOT_AVAILABLE;
}
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"
- // ...
- // 0x18538067 // Segment (must be "unknown" size)
- // 0x1549a966 // -> Segment Info
- // 0x1654ae6b // -> One or more Tracks
-
- // 0x1f43b675 // Cluster
if (aData->Length() < 4) {
return NS_ERROR_NOT_AVAILABLE;
}
- if ((*aData)[0] == 0x1f && (*aData)[1] == 0x43 && (*aData)[2] == 0xb6 &&
- (*aData)[3] == 0x75) {
- return NS_OK;
- }
- // 0x1c53bb6b // Cues
- if ((*aData)[0] == 0x1c && (*aData)[1] == 0x53 && (*aData)[2] == 0xbb &&
- (*aData)[3] == 0x6b) {
- return NS_OK;
+
+ WebMBufferedParser parser(0);
+ nsTArray<WebMTimeDataOffset> mapping;
+ ReentrantMonitor dummy("dummy");
+ parser.AppendMediaSegmentOnly();
+ bool result = parser.Append(aData->Elements(), aData->Length(), mapping,
+ dummy);
+ if (!result) {
+ return MediaResult(NS_ERROR_FAILURE, RESULT_DETAIL("Invalid webm content"));
}
- return MediaResult(NS_ERROR_FAILURE, RESULT_DETAIL("Invalid webm content"));
+ return parser.GetClusterOffset() >= 0 ? NS_OK : NS_ERROR_NOT_AVAILABLE;
}
MediaResult ParseStartAndEndTimestamps(MediaByteBuffer* aData,
diff --git a/dom/media/mp3/MP3Demuxer.cpp b/dom/media/mp3/MP3Demuxer.cpp
index 5a98cabfe..ccc515afb 100644
--- a/dom/media/mp3/MP3Demuxer.cpp
+++ b/dom/media/mp3/MP3Demuxer.cpp
@@ -396,7 +396,10 @@ MP3TrackDemuxer::Duration(int64_t aNumFrames) const {
MediaByteRange
MP3TrackDemuxer::FindFirstFrame() {
- static const int MIN_SUCCESSIVE_FRAMES = 4;
+ // This check is meant to avoid invalid frames from broken streams, but
+ // small MP3 files and streams with odd header data can break this. Lowering
+ // the value to 3 seems to help significantly.
+ static const int MIN_SUCCESSIVE_FRAMES = 3;
MediaByteRange candidateFrame = FindNextFrame();
int numSuccFrames = candidateFrame.Length() > 0;
diff --git a/dom/media/webaudio/AudioBuffer.cpp b/dom/media/webaudio/AudioBuffer.cpp
index e7eba2d48..39fe8c735 100644
--- a/dom/media/webaudio/AudioBuffer.cpp
+++ b/dom/media/webaudio/AudioBuffer.cpp
@@ -254,6 +254,7 @@ void
AudioBuffer::CopyFromChannel(const Float32Array& aDestination, uint32_t aChannelNumber,
uint32_t aStartInChannel, ErrorResult& aRv)
{
+ JS::AutoCheckCannotGC nogc;
aDestination.ComputeLengthAndData();
uint32_t length = aDestination.Length();
@@ -265,7 +266,6 @@ AudioBuffer::CopyFromChannel(const Float32Array& aDestination, uint32_t aChannel
return;
}
- JS::AutoCheckCannotGC nogc;
JSObject* channelArray = mJSChannels[aChannelNumber];
const float* sourceData = nullptr;
if (channelArray) {
@@ -296,6 +296,7 @@ AudioBuffer::CopyToChannel(JSContext* aJSContext, const Float32Array& aSource,
uint32_t aChannelNumber, uint32_t aStartInChannel,
ErrorResult& aRv)
{
+ JS::AutoCheckCannotGC nogc;
aSource.ComputeLengthAndData();
uint32_t length = aSource.Length();
@@ -312,7 +313,6 @@ AudioBuffer::CopyToChannel(JSContext* aJSContext, const Float32Array& aSource,
return;
}
- JS::AutoCheckCannotGC nogc;
JSObject* channelArray = mJSChannels[aChannelNumber];
if (JS_GetTypedArrayLength(channelArray) != mLength) {
// The array's buffer was detached.
diff --git a/dom/media/webm/WebMBufferedParser.cpp b/dom/media/webm/WebMBufferedParser.cpp
index 21154ab4b..979308cf0 100644
--- a/dom/media/webm/WebMBufferedParser.cpp
+++ b/dom/media/webm/WebMBufferedParser.cpp
@@ -113,6 +113,7 @@ bool WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength,
} else {
mClusterEndOffset = -1;
}
+ mGotClusterTimecode = false;
mState = READ_ELEMENT_ID;
break;
case BLOCKGROUP_ID:
@@ -121,6 +122,11 @@ bool WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength,
case SIMPLEBLOCK_ID:
/* FALLTHROUGH */
case BLOCK_ID:
+ if (!mGotClusterTimecode) {
+ WEBM_DEBUG("The Timecode element must appear before any Block or "
+ "SimpleBlock elements in a Cluster");
+ return false;
+ }
mBlockSize = mElement.mSize.mValue;
mBlockTimecode = 0;
mBlockTimecodeLength = BLOCK_TIMECODE_LENGTH;
@@ -164,6 +170,7 @@ bool WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength,
break;
case READ_TIMECODESCALE:
if (!mGotTimecodeScale) {
+ WEBM_DEBUG("Should get the SegmentInfo first");
return false;
}
mTimecodeScale = mVInt.mValue;
@@ -171,6 +178,7 @@ bool WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength,
break;
case READ_CLUSTER_TIMECODE:
mClusterTimecode = mVInt.mValue;
+ mGotClusterTimecode = true;
mState = READ_ELEMENT_ID;
break;
case READ_BLOCK_TIMECODE:
@@ -190,6 +198,7 @@ bool WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength,
// Don't insert invalid negative timecodes.
if (mBlockTimecode >= 0 || mClusterTimecode >= uint16_t(abs(mBlockTimecode))) {
if (!mGotTimecodeScale) {
+ WEBM_DEBUG("Should get the TimecodeScale first");
return false;
}
uint64_t absTimecode = mClusterTimecode + mBlockTimecode;
@@ -266,6 +275,12 @@ WebMBufferedParser::EndSegmentOffset(int64_t aOffset)
return mBlockEndOffset;
}
+int64_t
+WebMBufferedParser::GetClusterOffset() const
+{
+ return mClusterOffset;
+}
+
// SyncOffsetComparator and TimeComparator are slightly confusing, in that
// the nsTArray they're used with (mTimeMapping) is sorted by mEndOffset and
// these comparators are used on the other fields of WebMTimeDataOffset.
diff --git a/dom/media/webm/WebMBufferedParser.h b/dom/media/webm/WebMBufferedParser.h
index bc3de4ba0..4245561fc 100644
--- a/dom/media/webm/WebMBufferedParser.h
+++ b/dom/media/webm/WebMBufferedParser.h
@@ -67,7 +67,7 @@ struct WebMBufferedParser
, mVIntLeft(0)
, mBlockSize(0)
, mClusterTimecode(0)
- , mClusterOffset(0)
+ , mClusterOffset(-1)
, mClusterEndOffset(-1)
, mBlockOffset(0)
, mBlockTimecode(0)
@@ -75,6 +75,7 @@ struct WebMBufferedParser
, mSkipBytes(0)
, mTimecodeScale(1000000)
, mGotTimecodeScale(false)
+ , mGotClusterTimecode(false)
{
if (mStartOffset != 0) {
mState = FIND_CLUSTER_SYNC;
@@ -86,6 +87,12 @@ struct WebMBufferedParser
return mTimecodeScale;
}
+ // Use this function when we would only feed media segment for the parser.
+ void AppendMediaSegmentOnly()
+ {
+ mGotTimecodeScale = true;
+ }
+
// If this parser is not expected to parse a segment info, it must be told
// the appropriate timecode scale to use from elsewhere.
void SetTimecodeScale(uint32_t aTimecodeScale) {
@@ -114,6 +121,9 @@ struct WebMBufferedParser
// This allows to determine the end of the interval containg aOffset.
int64_t EndSegmentOffset(int64_t aOffset);
+ // Return the Cluster offset, return -1 if we can't find the Cluster.
+ int64_t GetClusterOffset() const;
+
// The offset at which this parser started parsing. Used to merge
// adjacent parsers, in which case the later parser adopts the earlier
// parser's mStartOffset.
@@ -231,7 +241,7 @@ private:
// Start offset of the cluster currently being parsed. Used as the sync
// point offset for the offset-to-time mapping as each block timecode is
- // been parsed.
+ // been parsed. -1 if unknown.
int64_t mClusterOffset;
// End offset of the cluster currently being parsed. -1 if unknown.
@@ -260,6 +270,9 @@ private:
// True if we read the timecode scale from the segment info or have
// confirmed that the default value is to be used.
bool mGotTimecodeScale;
+
+ // True if we've read the cluster time code.
+ bool mGotClusterTimecode;
};
class WebMBufferedState final