Bug 1195073: [webm] P2. Add WebMBufferedState::GetLastBlockOffset method. r=kinetik

MSE may input partial media segment, which could cause the WebMDemuxer and libnestegg to error upon encountering an incomplete block which can't be recovered from.
this will allow to limit read to known complete blocks.
This commit is contained in:
Jean-Yves Avenard 2015-08-19 15:22:31 +10:00
parent 5b54a2f8a4
commit b793485c9a
2 changed files with 39 additions and 6 deletions

View File

@ -192,7 +192,9 @@ void WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength,
left = std::min(left, mSkipBytes);
p += left;
mSkipBytes -= left;
} else {
}
if (!mSkipBytes) {
mBlockEndOffset = mCurrentOffset + (p - aBuffer);
mState = mNextState;
}
break;
@ -344,6 +346,13 @@ void WebMBufferedState::NotifyDataArrived(const unsigned char* aBuffer, uint32_t
i += 1;
}
}
if (mRangeParsers.IsEmpty()) {
return;
}
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
mLastBlockOffset = mRangeParsers.LastElement().mBlockEndOffset;
}
void WebMBufferedState::Reset() {
@ -398,6 +407,13 @@ int64_t WebMBufferedState::GetInitEndOffset()
return mRangeParsers[0].mInitEndOffset;
}
int64_t WebMBufferedState::GetLastBlockOffset()
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
return mLastBlockOffset;
}
bool WebMBufferedState::GetStartTime(uint64_t *aTime)
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);

View File

@ -47,9 +47,15 @@ struct WebMTimeDataOffset
struct WebMBufferedParser
{
explicit WebMBufferedParser(int64_t aOffset)
: mStartOffset(aOffset), mCurrentOffset(aOffset), mInitEndOffset(-1),
mState(READ_ELEMENT_ID), mVIntRaw(false), mClusterSyncPos(0),
mTimecodeScale(1000000), mGotTimecodeScale(false)
: mStartOffset(aOffset)
, mCurrentOffset(aOffset)
, mInitEndOffset(-1)
, mBlockEndOffset(-1)
, mState(READ_ELEMENT_ID)
, mVIntRaw(false)
, mClusterSyncPos(0)
, mTimecodeScale(1000000)
, mGotTimecodeScale(false)
{
if (mStartOffset != 0) {
mState = FIND_CLUSTER_SYNC;
@ -96,6 +102,10 @@ struct WebMBufferedParser
// Will only be set if a Segment Information has been found.
int64_t mInitEndOffset;
// End offset of the last block.
// Will only be set if a full block has been parsed.
int64_t mBlockEndOffset;
private:
enum State {
// Parser start state. Expects to begin at a valid EBML element. Move
@ -225,7 +235,10 @@ class WebMBufferedState final
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WebMBufferedState)
public:
WebMBufferedState() : mReentrantMonitor("WebMBufferedState") {
WebMBufferedState()
: mReentrantMonitor("WebMBufferedState")
, mLastBlockOffset(-1)
{
MOZ_COUNT_CTOR(WebMBufferedState);
}
@ -242,6 +255,8 @@ public:
// Returns end offset of init segment or -1 if none found.
int64_t GetInitEndOffset();
// Returns the end offset of the last complete block or -1 if none found.
int64_t GetLastBlockOffset();
// Returns start time
bool GetStartTime(uint64_t *aTime);
@ -255,12 +270,14 @@ private:
MOZ_COUNT_DTOR(WebMBufferedState);
}
// Synchronizes access to the mTimeMapping array.
// Synchronizes access to the mTimeMapping array and mLastBlockOffset.
ReentrantMonitor mReentrantMonitor;
// Sorted (by offset) map of data offsets to timecodes. Populated
// on the main thread as data is received and parsed by WebMBufferedParsers.
nsTArray<WebMTimeDataOffset> mTimeMapping;
// The last complete block parsed. -1 if not set.
int64_t mLastBlockOffset;
// Sorted (by offset) live parser instances. Main thread only.
nsTArray<WebMBufferedParser> mRangeParsers;