mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1195073: [webm] P6. Calculate cluster's end offset if its size is known in advance. r=kinetik.
This allows to detect the end of a webm media segment without having to wait for the start of a new one. Also record where an init segment (EBML) starts as this will be required by the WebM ContainerParser.
This commit is contained in:
parent
98864bb30c
commit
be2837a7a6
@ -34,6 +34,7 @@ void WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength,
|
||||
nsTArray<WebMTimeDataOffset>& aMapping,
|
||||
ReentrantMonitor& aReentrantMonitor)
|
||||
{
|
||||
static const uint32_t EBML_ID = 0x1a45dfa3;
|
||||
static const uint32_t SEGMENT_ID = 0x18538067;
|
||||
static const uint32_t SEGINFO_ID = 0x1549a966;
|
||||
static const uint32_t TRACKS_ID = 0x1654AE6B;
|
||||
@ -102,6 +103,12 @@ void WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength,
|
||||
case CLUSTER_ID:
|
||||
mClusterOffset = mCurrentOffset + (p - aBuffer) -
|
||||
(mElement.mID.mLength + mElement.mSize.mLength);
|
||||
// Handle "unknown" length;
|
||||
if (mElement.mSize.mValue + 1 != uint64_t(1) << (mElement.mSize.mLength * 7)) {
|
||||
mClusterEndOffset = mClusterOffset + mElement.mID.mLength + mElement.mSize.mLength + mElement.mSize.mValue;
|
||||
} else {
|
||||
mClusterEndOffset = -1;
|
||||
}
|
||||
mState = READ_ELEMENT_ID;
|
||||
break;
|
||||
case SIMPLEBLOCK_ID:
|
||||
@ -119,6 +126,10 @@ void WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength,
|
||||
mSkipBytes = mElement.mSize.mValue;
|
||||
mState = CHECK_INIT_FOUND;
|
||||
break;
|
||||
case EBML_ID:
|
||||
mLastInitStartOffset = mCurrentOffset + (p - aBuffer) -
|
||||
(mElement.mID.mLength + mElement.mSize.mLength);
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
mSkipBytes = mElement.mSize.mValue;
|
||||
mState = SKIP_DATA;
|
||||
@ -172,7 +183,8 @@ void WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength,
|
||||
MOZ_ASSERT(mGotTimecodeScale);
|
||||
uint64_t absTimecode = mClusterTimecode + mBlockTimecode;
|
||||
absTimecode *= mTimecodeScale;
|
||||
WebMTimeDataOffset entry(endOffset, absTimecode, mClusterOffset);
|
||||
WebMTimeDataOffset entry(endOffset, absTimecode, mLastInitStartOffset,
|
||||
mClusterOffset, mClusterEndOffset);
|
||||
aMapping.InsertElementAt(idx, entry);
|
||||
}
|
||||
}
|
||||
@ -220,6 +232,16 @@ void WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength,
|
||||
mCurrentOffset += aLength;
|
||||
}
|
||||
|
||||
int64_t
|
||||
WebMBufferedParser::EndSegmentOffset(int64_t aOffset)
|
||||
{
|
||||
if (mLastInitStartOffset > aOffset || mClusterOffset > aOffset) {
|
||||
return std::min(mLastInitStartOffset >= 0 ? mLastInitStartOffset : INT64_MAX,
|
||||
mClusterOffset >= 0 ? mClusterOffset : INT64_MAX);
|
||||
}
|
||||
return mBlockEndOffset;
|
||||
}
|
||||
|
||||
// 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.
|
||||
|
@ -17,8 +17,14 @@ namespace mozilla {
|
||||
// that offset.
|
||||
struct WebMTimeDataOffset
|
||||
{
|
||||
WebMTimeDataOffset(int64_t aEndOffset, uint64_t aTimecode, int64_t aSyncOffset)
|
||||
: mEndOffset(aEndOffset), mSyncOffset(aSyncOffset), mTimecode(aTimecode)
|
||||
WebMTimeDataOffset(int64_t aEndOffset, uint64_t aTimecode,
|
||||
int64_t aInitOffset, int64_t aSyncOffset,
|
||||
int64_t aClusterEndOffset)
|
||||
: mEndOffset(aEndOffset)
|
||||
, mInitOffset(aInitOffset)
|
||||
, mSyncOffset(aSyncOffset)
|
||||
, mClusterEndOffset(aClusterEndOffset)
|
||||
, mTimecode(aTimecode)
|
||||
{}
|
||||
|
||||
bool operator==(int64_t aEndOffset) const {
|
||||
@ -34,7 +40,9 @@ struct WebMTimeDataOffset
|
||||
}
|
||||
|
||||
int64_t mEndOffset;
|
||||
int64_t mInitOffset;
|
||||
int64_t mSyncOffset;
|
||||
int64_t mClusterEndOffset;
|
||||
uint64_t mTimecode;
|
||||
};
|
||||
|
||||
@ -53,7 +61,9 @@ struct WebMBufferedParser
|
||||
, mBlockEndOffset(-1)
|
||||
, mState(READ_ELEMENT_ID)
|
||||
, mVIntRaw(false)
|
||||
, mLastInitStartOffset(-1)
|
||||
, mClusterSyncPos(0)
|
||||
, mClusterEndOffset(-1)
|
||||
, mTimecodeScale(1000000)
|
||||
, mGotTimecodeScale(false)
|
||||
{
|
||||
@ -89,21 +99,26 @@ struct WebMBufferedParser
|
||||
return mCurrentOffset < aOffset;
|
||||
}
|
||||
|
||||
// Returns the start offset of the init (EBML) or media segment (Cluster)
|
||||
// following the aOffset position. If none were found, returns mBlockEndOffset.
|
||||
// This allows to determine the end of the interval containg aOffset.
|
||||
int64_t EndSegmentOffset(int64_t aOffset);
|
||||
|
||||
// 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.
|
||||
int64_t mStartOffset;
|
||||
|
||||
// Current offset with the stream. Updated in chunks as Append() consumes
|
||||
// Current offset within the stream. Updated in chunks as Append() consumes
|
||||
// data.
|
||||
int64_t mCurrentOffset;
|
||||
|
||||
// Tracks element's end offset. This indicates the end of the init segment.
|
||||
// Will only be set if a Segment Information has been found.
|
||||
// Tracks element's end offset. This indicates the end of the first init
|
||||
// segment. 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.
|
||||
// End offset of the last block parsed.
|
||||
// Will only be set if a complete block has been parsed.
|
||||
int64_t mBlockEndOffset;
|
||||
|
||||
private:
|
||||
@ -185,6 +200,10 @@ private:
|
||||
|
||||
bool mVIntRaw;
|
||||
|
||||
// EBML start offset. This indicates the start of the last init segment
|
||||
// parsed. Will only be set if an EBML element has been found.
|
||||
int64_t mLastInitStartOffset;
|
||||
|
||||
// Current match position within CLUSTER_SYNC_ID. Used to find sync
|
||||
// within arbitrary data.
|
||||
uint32_t mClusterSyncPos;
|
||||
@ -205,6 +224,9 @@ private:
|
||||
// been parsed.
|
||||
int64_t mClusterOffset;
|
||||
|
||||
// End offset of the cluster currently being parsed. -1 if unknown.
|
||||
int64_t mClusterEndOffset;
|
||||
|
||||
// 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.
|
||||
|
Loading…
Reference in New Issue
Block a user