Bug 1050083 - Changes to WebM buffered range handling. r=cajbir

Include the frame duration in the range end.  Also handle (ignore) invalid
negative timestamps when parsing.  Include cluster offset in time/data
offset record.  Cluster offset will be used when calculating discard/resync
points in MSE.
This commit is contained in:
Matthew Gregan 2014-08-11 14:05:09 +12:00
parent 8a37d5542f
commit 8a0f131967
2 changed files with 24 additions and 11 deletions

View File

@ -32,8 +32,8 @@ VIntLength(unsigned char aFirstByte, uint32_t* aMask)
}
void WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength,
nsTArray<WebMTimeDataOffset>& aMapping,
ReentrantMonitor& aReentrantMonitor)
nsTArray<WebMTimeDataOffset>& aMapping,
ReentrantMonitor& aReentrantMonitor)
{
static const unsigned char CLUSTER_ID[] = { 0x1f, 0x43, 0xb6, 0x75 };
static const unsigned char TIMECODE_ID = 0xe7;
@ -60,6 +60,7 @@ void WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength,
// and return to CLUSTER_SYNC.
if (mClusterIDPos == sizeof(CLUSTER_ID)) {
mClusterIDPos = 0;
mClusterOffset = mCurrentOffset + (p - aBuffer) - 1;
mState = READ_VINT;
mNextState = TIMECODE_SYNC;
}
@ -140,9 +141,14 @@ void WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength,
{
ReentrantMonitorAutoEnter mon(aReentrantMonitor);
uint32_t idx = aMapping.IndexOfFirstElementGt(mBlockOffset);
if (idx == 0 || !(aMapping[idx-1] == mBlockOffset)) {
WebMTimeDataOffset entry(mBlockOffset, mClusterTimecode + mBlockTimecode);
aMapping.InsertElementAt(idx, entry);
if (idx == 0 || !(aMapping[idx - 1] == mBlockOffset)) {
// Don't insert invalid negative timecodes.
if (mBlockOffset > 0 || mClusterTimecode > uint16_t(abs(mBlockOffset))) {
WebMTimeDataOffset entry(mBlockOffset,
mClusterTimecode + mBlockTimecode,
mClusterOffset);
aMapping.InsertElementAt(idx, entry);
}
}
}
@ -177,18 +183,18 @@ void WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength,
}
bool WebMBufferedState::CalculateBufferedForRange(int64_t aStartOffset, int64_t aEndOffset,
uint64_t* aStartTime, uint64_t* aEndTime)
uint64_t* aStartTime, uint64_t* aEndTime)
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
// Find the first WebMTimeDataOffset at or after aStartOffset.
uint32_t start = mTimeMapping.IndexOfFirstElementGt(aStartOffset-1);
uint32_t start = mTimeMapping.IndexOfFirstElementGt(aStartOffset - 1);
if (start == mTimeMapping.Length()) {
return false;
}
// Find the first WebMTimeDataOffset at or before aEndOffset.
uint32_t end = mTimeMapping.IndexOfFirstElementGt(aEndOffset-1);
uint32_t end = mTimeMapping.IndexOfFirstElementGt(aEndOffset - 1);
if (end > 0) {
end -= 1;
}
@ -216,13 +222,14 @@ bool WebMBufferedState::CalculateBufferedForRange(int64_t aStartOffset, int64_t
*aStartTime = mTimeMapping[start].mTimecode;
*aEndTime = mTimeMapping[end].mTimecode;
*aEndTime += mTimeMapping[end].mTimecode - mTimeMapping[end - 1].mTimecode;
return true;
}
bool WebMBufferedState::GetOffsetForTime(uint64_t aTime, int64_t* aOffset)
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
WebMTimeDataOffset result(0,0);
WebMTimeDataOffset result(0, 0, 0);
for (uint32_t i = 0; i < mTimeMapping.Length(); ++i) {
WebMTimeDataOffset o = mTimeMapping[i];

View File

@ -21,8 +21,8 @@ class TimeRanges;
// scale before use.
struct WebMTimeDataOffset
{
WebMTimeDataOffset(int64_t aOffset, uint64_t aTimecode)
: mOffset(aOffset), mTimecode(aTimecode)
WebMTimeDataOffset(int64_t aOffset, uint64_t aTimecode, int64_t aSyncOffset)
: mOffset(aOffset), mTimecode(aTimecode), mSyncOffset(aSyncOffset)
{}
bool operator==(int64_t aOffset) const {
@ -35,6 +35,7 @@ struct WebMTimeDataOffset
int64_t mOffset;
uint64_t mTimecode;
int64_t mSyncOffset;
};
// A simple WebM parser that produces data offset to timecode pairs as it
@ -165,6 +166,11 @@ private:
// Cluster-level timecode.
uint64_t mClusterTimecode;
// 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.
int64_t mClusterOffset;
// Start offset of the block currently being parsed. Used as the byte
// offset for the offset-to-time mapping once the block timecode has been
// parsed.