gecko/content/media/webm/nsWebMBufferedParser.h
Ehsan Akhgari 0fd9123eac Bug 579517 - Part 1: Automated conversion of NSPR numeric types to stdint types in Gecko; r=bsmedberg
This patch was generated by a script.  Here's the source of the script for
future reference:

function convert() {
echo "Converting $1 to $2..."
find . ! -wholename "*nsprpub*" \
       ! -wholename "*security/nss*" \
       ! -wholename "*/.hg*" \
       ! -wholename "obj-ff-dbg*" \
       ! -name nsXPCOMCID.h \
       ! -name prtypes.h \
         -type f \
      \( -iname "*.cpp" \
         -o -iname "*.h" \
         -o -iname "*.c" \
         -o -iname "*.cc" \
         -o -iname "*.idl" \
         -o -iname "*.ipdl" \
         -o -iname "*.ipdlh" \
         -o -iname "*.mm" \) | \
    xargs -n 1 sed -i -e "s/\b$1\b/$2/g"
}

convert PRInt8 int8_t
convert PRUint8 uint8_t
convert PRInt16 int16_t
convert PRUint16 uint16_t
convert PRInt32 int32_t
convert PRUint32 uint32_t
convert PRInt64 int64_t
convert PRUint64 uint64_t

convert PRIntn int
convert PRUintn unsigned

convert PRSize size_t

convert PROffset32 int32_t
convert PROffset64 int64_t

convert PRPtrdiff ptrdiff_t

convert PRFloat64 double
2012-08-22 11:56:38 -04:00

212 lines
7.3 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#if !defined(nsWebMBufferedParser_h_)
#define nsWebMBufferedParser_h_
#include "nsISupportsImpl.h"
#include "nsTArray.h"
#include "mozilla/ReentrantMonitor.h"
class nsTimeRanges;
using mozilla::ReentrantMonitor;
// Stores a stream byte offset and the scaled timecode of the block at
// that offset. The timecode must be scaled by the stream's timecode
// scale before use.
struct nsWebMTimeDataOffset
{
nsWebMTimeDataOffset(int64_t aOffset, uint64_t aTimecode)
: mOffset(aOffset), mTimecode(aTimecode)
{}
bool operator==(int64_t aOffset) const {
return mOffset == aOffset;
}
bool operator<(int64_t aOffset) const {
return mOffset < aOffset;
}
int64_t mOffset;
uint64_t mTimecode;
};
// A simple WebM parser that produces data offset to timecode pairs as it
// consumes blocks. A new parser is created for each distinct range of data
// received and begins parsing from the first WebM cluster within that
// range. Old parsers are destroyed when their range merges with a later
// parser or an already parsed range. The parser may start at any position
// within the stream.
struct nsWebMBufferedParser
{
nsWebMBufferedParser(int64_t aOffset)
: mStartOffset(aOffset), mCurrentOffset(aOffset), mState(CLUSTER_SYNC), mClusterIDPos(0)
{}
// Steps the parser through aLength bytes of data. Always consumes
// aLength bytes. Updates mCurrentOffset before returning. Acquires
// aReentrantMonitor before using aMapping.
void Append(const unsigned char* aBuffer, uint32_t aLength,
nsTArray<nsWebMTimeDataOffset>& aMapping,
ReentrantMonitor& aReentrantMonitor);
bool operator==(int64_t aOffset) const {
return mCurrentOffset == aOffset;
}
bool operator<(int64_t aOffset) const {
return mCurrentOffset < 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
// data.
int64_t mCurrentOffset;
private:
enum State {
// Parser start state. Scans forward searching for stream sync by
// matching CLUSTER_ID with the curernt byte. The match state is stored
// in mClusterIDPos. Once this reaches sizeof(CLUSTER_ID), stream may
// have sync. The parser then advances to read the cluster size and
// timecode.
CLUSTER_SYNC,
/*
The the parser states below assume that CLUSTER_SYNC has found a valid
sync point within the data. If parsing fails in these states, the
parser returns to CLUSTER_SYNC to find a new sync point.
*/
// Read the first byte of a variable length integer. The first byte
// encodes both the variable integer's length and part of the value.
// The value read so far is stored in mVInt and the length is stored in
// mVIntLength. The number of bytes left to read is stored in
// mVIntLeft.
READ_VINT,
// Reads the remaining mVIntLeft bytes into mVInt.
READ_VINT_REST,
// Check that the next element is TIMECODE_ID. The cluster timecode is
// required to be the first element in a cluster. Advances to READ_VINT
// to read the timecode's length into mVInt.
TIMECODE_SYNC,
// mVInt holds the length of the variable length unsigned integer
// containing the cluster timecode. Read mVInt bytes into
// mClusterTimecode.
READ_CLUSTER_TIMECODE,
// Skips elements with a cluster until BLOCKGROUP_ID or SIMPLEBLOCK_ID
// is found. If BLOCKGROUP_ID is found, the parser returns to
// ANY_BLOCK_ID searching for a BLOCK_ID. Once a block or simpleblock
// is found, the current data offset is stored in mBlockOffset. If the
// current byte is the beginning of a four byte variant integer, it
// indicates the parser has reached a top-level element ID and the
// parser returns to CLUSTER_SYNC.
ANY_BLOCK_SYNC,
// Start reading a block. Blocks and simpleblocks are parsed the same
// way as the initial layouts are identical. mBlockSize is initialized
// from mVInt (holding the element size), and mBlockTimecode(Length) is
// initialized for parsing.
READ_BLOCK,
// Reads mBlockTimecodeLength bytes of data into mBlockTimecode. When
// mBlockTimecodeLength reaches 0, the timecode has been read. The sum
// of mClusterTimecode and mBlockTimecode is stored as a pair with
// mBlockOffset into the offset-to-time map.
READ_BLOCK_TIMECODE,
// Skip mSkipBytes of data before resuming parse at mNextState.
SKIP_DATA,
// Skip the content of an element. mVInt holds the element length.
SKIP_ELEMENT
};
// Current state machine action.
State mState;
// Next state machine action. SKIP_DATA and READ_VINT_REST advance to
// mNextState when the current action completes.
State mNextState;
// Match position within CLUSTER_ID. Used to find sync within arbitrary
// data.
uint32_t mClusterIDPos;
// Variable length integer read from data.
uint64_t mVInt;
// Encoding length of mVInt. This is the total number of bytes used to
// encoding mVInt's value.
uint32_t mVIntLength;
// Number of bytes of mVInt left to read. mVInt is complete once this
// reaches 0.
uint32_t mVIntLeft;
// Size of the block currently being parsed. Any unused data within the
// block is skipped once the block timecode has been parsed.
uint64_t mBlockSize;
// Cluster-level timecode.
uint64_t mClusterTimecode;
// 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.
int64_t mBlockOffset;
// Block-level timecode. This is summed with mClusterTimecode to produce
// an absolute timecode for the offset-to-time mapping.
int16_t mBlockTimecode;
// Number of bytes of mBlockTimecode left to read.
uint32_t mBlockTimecodeLength;
// Count of bytes left to skip before resuming parse at mNextState.
// Mostly used to skip block payload data after reading a block timecode.
uint32_t mSkipBytes;
};
class nsWebMBufferedState
{
NS_INLINE_DECL_REFCOUNTING(nsWebMBufferedState)
public:
nsWebMBufferedState() : mReentrantMonitor("nsWebMBufferedState") {
MOZ_COUNT_CTOR(nsWebMBufferedState);
}
~nsWebMBufferedState() {
MOZ_COUNT_DTOR(nsWebMBufferedState);
}
void NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset);
bool CalculateBufferedForRange(int64_t aStartOffset, int64_t aEndOffset,
uint64_t* aStartTime, uint64_t* aEndTime);
private:
// Synchronizes access to the mTimeMapping array.
ReentrantMonitor mReentrantMonitor;
// Sorted (by offset) map of data offsets to timecodes. Populated
// on the main thread as data is received and parsed by nsWebMBufferedParsers.
nsTArray<nsWebMTimeDataOffset> mTimeMapping;
// Sorted (by offset) live parser instances. Main thread only.
nsTArray<nsWebMBufferedParser> mRangeParsers;
};
#endif