Bug 1325707: P4. Fix coding style of MediaDataDemuxers. r=gerald

MozReview-Commit-ID: AV2lXwVZqLV

--HG--
extra : rebase_source : f66559f4d104516c8dfd2c9a146dfba8672dce33
This commit is contained in:
Jean-Yves Avenard 2017-02-07 09:23:34 +01:00
parent 16bf821b42
commit 71e0f46c33
12 changed files with 496 additions and 322 deletions

View File

@ -53,7 +53,8 @@ namespace adts {
// maximum compatibility always use 1 AAC frame per ADTS
// frame
// Q 16 CRC if protection absent is 0
class FrameHeader {
class FrameHeader
{
public:
uint32_t mFrameLength;
uint32_t mSampleRate;
@ -66,7 +67,8 @@ public:
bool mHaveCrc;
// Returns whether aPtr matches a valid ADTS header sync marker
static bool MatchesSync(const uint8_t* aPtr) {
static bool MatchesSync(const uint8_t* aPtr)
{
return aPtr[0] == 0xFF && (aPtr[1] & 0xF6) == 0xF0;
}
@ -81,7 +83,8 @@ public:
void Reset() { PodZero(this); }
// Returns whether the byte creates a valid sequence up to this point.
bool Parse(const uint8_t* aPtr) {
bool Parse(const uint8_t* aPtr)
{
const uint8_t* p = aPtr;
if (!MatchesSync(p)) {
@ -95,7 +98,8 @@ public:
mObjectType = ((p[2] & 0xC0) >> 6) + 1;
mSamplingIndex = (p[2] & 0x3C) >> 2;
mChannelConfig = (p[2] & 0x01) << 2 | (p[3] & 0xC0) >> 6;
mFrameLength = (p[3] & 0x03) << 11 | (p[4] & 0xFF) << 3 | (p[5] & 0xE0) >> 5;
mFrameLength =
(p[3] & 0x03) << 11 | (p[4] & 0xFF) << 3 | (p[5] & 0xE0) >> 5;
mNumAACFrames = (p[6] & 0x03) + 1;
static const int32_t SAMPLE_RATES[16] = {
@ -116,13 +120,16 @@ public:
// adts::Frame - Frame meta container used to parse and hold a frame
// header and side info.
class Frame {
class Frame
{
public:
Frame() : mOffset(0), mHeader() { }
int64_t Offset() const { return mOffset; }
size_t Length() const {
// TODO: If fields are zero'd when invalid, this check wouldn't be necessary.
size_t Length() const
{
// TODO: If fields are zero'd when invalid, this check wouldn't be
// necessary.
if (!mHeader.IsValid()) {
return 0;
}
@ -131,13 +138,13 @@ public:
}
// Returns the offset to the start of frame's raw data.
int64_t PayloadOffset() const {
return mOffset + mHeader.HeaderSize();
}
int64_t PayloadOffset() const { return mOffset + mHeader.HeaderSize(); }
// Returns the length of the frame's raw data (excluding the header) in bytes.
size_t PayloadLength() const {
// TODO: If fields are zero'd when invalid, this check wouldn't be necessary.
size_t PayloadLength() const
{
// TODO: If fields are zero'd when invalid, this check wouldn't be
// necessary.
if (!mHeader.IsValid()) {
return 0;
}
@ -146,16 +153,13 @@ public:
}
// Returns the parsed frame header.
const FrameHeader& Header() const {
return mHeader;
}
const FrameHeader& Header() const { return mHeader; }
bool IsValid() const {
return mHeader.IsValid();
}
bool IsValid() const { return mHeader.IsValid(); }
// Resets the frame header and data.
void Reset() {
void Reset()
{
mHeader.Reset();
mOffset = 0;
}
@ -187,7 +191,8 @@ private:
};
class FrameParser {
class FrameParser
{
public:
// Returns the currently parsed frame. Reset via Reset or EndFrameSession.
@ -198,7 +203,8 @@ public:
const Frame& FirstFrame() const { return mFirstFrame; }
// Resets the parser. Don't use between frames as first frame data is reset.
void Reset() {
void Reset()
{
EndFrameSession();
mFirstFrame.Reset();
}
@ -207,15 +213,17 @@ public:
// - sets PrevFrame to CurrentFrame
// - resets the CurrentFrame
// - resets ID3Header if no valid header was parsed yet
void EndFrameSession() {
void EndFrameSession()
{
mFrame.Reset();
}
// Parses contents of given ByteReader for a valid frame header and returns true
// if one was found. After returning, the variable passed to 'aBytesToSkip' holds
// the amount of bytes to be skipped (if any) in order to jump across a large
// ID3v2 tag spanning multiple buffers.
bool Parse(int64_t aOffset, uint8_t* aStart, uint8_t* aEnd) {
// Parses contents of given ByteReader for a valid frame header and returns
// true if one was found. After returning, the variable passed to
// 'aBytesToSkip' holds the amount of bytes to be skipped (if any) in order to
// jump across a large ID3v2 tag spanning multiple buffers.
bool Parse(int64_t aOffset, uint8_t* aStart, uint8_t* aEnd)
{
const bool found = mFrame.Parse(aOffset, aStart, aEnd);
if (mFrame.Length() && !mFirstFrame.Length()) {
@ -300,7 +308,8 @@ InitAudioSpecificConfig(const Frame& frame,
ADTSDemuxer::ADTSDemuxer(MediaResource* aSource)
: mSource(aSource)
{}
{
}
bool
ADTSDemuxer::InitInternal()
@ -375,13 +384,11 @@ ADTSTrackDemuxer::ADTSTrackDemuxer(MediaResource* aSource)
ADTSTrackDemuxer::~ADTSTrackDemuxer()
{
delete mParser;
mParser = nullptr;
}
bool
ADTSTrackDemuxer::Init()
{
FastSeek(media::TimeUnit());
// Read the first frame to fetch sample rate and other meta data.
RefPtr<MediaRawData> frame(GetNextFrame(FindNextFrame(true)));
@ -420,7 +427,8 @@ ADTSTrackDemuxer::Init()
mInfo->mExtendedProfile = mParser->FirstFrame().Header().mObjectType;
InitAudioSpecificConfig(mParser->FirstFrame(), mInfo->mCodecSpecificConfig);
ADTSLOG("Init mInfo={mRate=%u mChannels=%u mBitDepth=%u mDuration=%" PRId64 "}",
ADTSLOG("Init mInfo={mRate=%u mChannels=%u mBitDepth=%u mDuration=%" PRId64
"}",
mInfo->mRate, mInfo->mChannels, mInfo->mBitDepth, mInfo->mDuration);
return mSamplesPerSecond && mChannels;
@ -510,7 +518,8 @@ RefPtr<ADTSTrackDemuxer::SamplesPromise>
ADTSTrackDemuxer::GetSamples(int32_t aNumSamples)
{
ADTSLOGV("GetSamples(%d) Begin mOffset=%" PRIu64 " mNumParsedFrames=%" PRIu64
" mFrameIndex=%" PRId64 " mTotalFrameLen=%" PRIu64 " mSamplesPerFrame=%d "
" mFrameIndex=%" PRId64 " mTotalFrameLen=%" PRIu64
" mSamplesPerFrame=%d "
"mSamplesPerSecond=%d mChannels=%d",
aNumSamples, mOffset, mNumParsedFrames, mFrameIndex, mTotalFrameLen,
mSamplesPerFrame, mSamplesPerSecond, mChannels);
@ -529,7 +538,8 @@ ADTSTrackDemuxer::GetSamples(int32_t aNumSamples)
ADTSLOGV("GetSamples() End mSamples.Size()=%d aNumSamples=%d mOffset=%" PRIu64
" mNumParsedFrames=%" PRIu64 " mFrameIndex=%" PRId64
" mTotalFrameLen=%" PRIu64 " mSamplesPerFrame=%d mSamplesPerSecond=%d "
" mTotalFrameLen=%" PRIu64
" mSamplesPerFrame=%d mSamplesPerSecond=%d "
"mChannels=%d",
frames->mSamples.Length(), aNumSamples, mOffset, mNumParsedFrames,
mFrameIndex, mTotalFrameLen, mSamplesPerFrame, mSamplesPerSecond,
@ -555,7 +565,8 @@ ADTSTrackDemuxer::Reset()
}
RefPtr<ADTSTrackDemuxer::SkipAccessPointPromise>
ADTSTrackDemuxer::SkipToNextRandomAccessPoint(const media::TimeUnit& aTimeThreshold)
ADTSTrackDemuxer::SkipToNextRandomAccessPoint(
const media::TimeUnit& aTimeThreshold)
{
// Will not be called for audio-only resources.
return SkipAccessPointPromise::CreateAndReject(
@ -654,7 +665,8 @@ ADTSTrackDemuxer::FindNextFrame(bool findFirstFrame /*= false*/)
// possible to find sync marker in AAC data. If sync marker
// exists after the current frame then we've found a frame
// header.
int64_t nextFrameHeaderOffset = currentFrame.Offset() + currentFrame.Length();
int64_t nextFrameHeaderOffset =
currentFrame.Offset() + currentFrame.Length();
int32_t read = Read(buffer, nextFrameHeaderOffset, 2);
if (read != 2 || !adts::FrameHeader::MatchesSync(buffer)) {
frameHeaderOffset = currentFrame.Offset() + 1;
@ -766,7 +778,8 @@ ADTSTrackDemuxer::FrameIndexFromOffset(int64_t aOffset) const
int64_t frameIndex = 0;
if (AverageFrameLength() > 0) {
frameIndex = (aOffset - mParser->FirstFrame().Offset()) / AverageFrameLength();
frameIndex =
(aOffset - mParser->FirstFrame().Offset()) / AverageFrameLength();
}
ADTSLOGV("FrameIndexFromOffset(%" PRId64 ") -> %" PRId64, aOffset, frameIndex);
@ -781,7 +794,8 @@ ADTSTrackDemuxer::FrameIndexFromTime(const media::TimeUnit& aTime) const
frameIndex = aTime.ToSeconds() * mSamplesPerSecond / mSamplesPerFrame - 1;
}
ADTSLOGV("FrameIndexFromOffset(%fs) -> %" PRId64, aTime.ToSeconds(), frameIndex);
ADTSLOGV("FrameIndexFromOffset(%fs) -> %" PRId64,
aTime.ToSeconds(), frameIndex);
return std::max<int64_t>(0, frameIndex);
}
@ -816,7 +830,8 @@ ADTSTrackDemuxer::UpdateState(const adts::Frame& aFrame)
int32_t
ADTSTrackDemuxer::Read(uint8_t* aBuffer, int64_t aOffset, int32_t aSize)
{
ADTSLOGV("ADTSTrackDemuxer::Read(%p %" PRId64 " %d)", aBuffer, aOffset, aSize);
ADTSLOGV("ADTSTrackDemuxer::Read(%p %" PRId64 " %d)",
aBuffer, aOffset, aSize);
const int64_t streamLen = StreamLength();
if (mInfo && streamLen > 0) {

View File

@ -22,15 +22,16 @@ class FrameParser;
class ADTSTrackDemuxer;
class ADTSDemuxer : public MediaDataDemuxer {
class ADTSDemuxer : public MediaDataDemuxer
{
public:
// MediaDataDemuxer interface.
explicit ADTSDemuxer(MediaResource* aSource);
RefPtr<InitPromise> Init() override;
bool HasTrackType(TrackInfo::TrackType aType) const override;
uint32_t GetNumberTracks(TrackInfo::TrackType aType) const override;
already_AddRefed<MediaTrackDemuxer> GetTrackDemuxer(
TrackInfo::TrackType aType, uint32_t aTrackNumber) override;
already_AddRefed<MediaTrackDemuxer>
GetTrackDemuxer(TrackInfo::TrackType aType, uint32_t aTrackNumber) override;
bool IsSeekable() const override;
private:
@ -40,7 +41,8 @@ private:
RefPtr<ADTSTrackDemuxer> mTrackDemuxer;
};
class ADTSTrackDemuxer : public MediaTrackDemuxer {
class ADTSTrackDemuxer : public MediaTrackDemuxer
{
public:
explicit ADTSTrackDemuxer(MediaResource* aSource);

View File

@ -37,12 +37,11 @@ namespace mp3 {
// MP3Demuxer
MP3Demuxer::MP3Demuxer(MediaResource* aSource)
: mSource(aSource)
{}
MP3Demuxer::MP3Demuxer(MediaResource* aSource) : mSource(aSource) { }
bool
MP3Demuxer::InitInternal() {
MP3Demuxer::InitInternal()
{
if (!mTrackDemuxer) {
mTrackDemuxer = new MP3TrackDemuxer(mSource);
}
@ -50,7 +49,8 @@ MP3Demuxer::InitInternal() {
}
RefPtr<MP3Demuxer::InitPromise>
MP3Demuxer::Init() {
MP3Demuxer::Init()
{
if (!InitInternal()) {
MP3LOG("MP3Demuxer::Init() failure: waiting for data");
@ -63,17 +63,20 @@ MP3Demuxer::Init() {
}
bool
MP3Demuxer::HasTrackType(TrackInfo::TrackType aType) const {
MP3Demuxer::HasTrackType(TrackInfo::TrackType aType) const
{
return aType == TrackInfo::kAudioTrack;
}
uint32_t
MP3Demuxer::GetNumberTracks(TrackInfo::TrackType aType) const {
MP3Demuxer::GetNumberTracks(TrackInfo::TrackType aType) const
{
return aType == TrackInfo::kAudioTrack ? 1u : 0u;
}
already_AddRefed<MediaTrackDemuxer>
MP3Demuxer::GetTrackDemuxer(TrackInfo::TrackType aType, uint32_t aTrackNumber) {
MP3Demuxer::GetTrackDemuxer(TrackInfo::TrackType aType, uint32_t aTrackNumber)
{
if (!mTrackDemuxer) {
return nullptr;
}
@ -81,19 +84,22 @@ MP3Demuxer::GetTrackDemuxer(TrackInfo::TrackType aType, uint32_t aTrackNumber) {
}
bool
MP3Demuxer::IsSeekable() const {
MP3Demuxer::IsSeekable() const
{
return true;
}
void
MP3Demuxer::NotifyDataArrived() {
MP3Demuxer::NotifyDataArrived()
{
// TODO: bug 1169485.
NS_WARNING("Unimplemented function NotifyDataArrived");
MP3LOGV("NotifyDataArrived()");
}
void
MP3Demuxer::NotifyDataRemoved() {
MP3Demuxer::NotifyDataRemoved()
{
// TODO: bug 1169485.
NS_WARNING("Unimplemented function NotifyDataRemoved");
MP3LOGV("NotifyDataRemoved()");
@ -117,7 +123,8 @@ MP3TrackDemuxer::MP3TrackDemuxer(MediaResource* aSource)
}
bool
MP3TrackDemuxer::Init() {
MP3TrackDemuxer::Init()
{
Reset();
FastSeek(TimeUnit());
// Read the first frame to fetch sample rate and other meta data.
@ -151,7 +158,8 @@ MP3TrackDemuxer::Init() {
}
media::TimeUnit
MP3TrackDemuxer::SeekPosition() const {
MP3TrackDemuxer::SeekPosition() const
{
TimeUnit pos = Duration(mFrameIndex);
if (Duration() > TimeUnit()) {
pos = std::min(Duration(), pos);
@ -160,32 +168,38 @@ MP3TrackDemuxer::SeekPosition() const {
}
const FrameParser::Frame&
MP3TrackDemuxer::LastFrame() const {
MP3TrackDemuxer::LastFrame() const
{
return mParser.PrevFrame();
}
RefPtr<MediaRawData>
MP3TrackDemuxer::DemuxSample() {
MP3TrackDemuxer::DemuxSample()
{
return GetNextFrame(FindNextFrame());
}
const ID3Parser::ID3Header&
MP3TrackDemuxer::ID3Header() const {
MP3TrackDemuxer::ID3Header() const
{
return mParser.ID3Header();
}
const FrameParser::VBRHeader&
MP3TrackDemuxer::VBRInfo() const {
MP3TrackDemuxer::VBRInfo() const
{
return mParser.VBRInfo();
}
UniquePtr<TrackInfo>
MP3TrackDemuxer::GetInfo() const {
MP3TrackDemuxer::GetInfo() const
{
return mInfo->Clone();
}
RefPtr<MP3TrackDemuxer::SeekPromise>
MP3TrackDemuxer::Seek(const TimeUnit& aTime) {
MP3TrackDemuxer::Seek(const TimeUnit& aTime)
{
// Efficiently seek to the position.
FastSeek(aTime);
// Correct seek position by scanning the next frames.
@ -195,7 +209,8 @@ MP3TrackDemuxer::Seek(const TimeUnit& aTime) {
}
TimeUnit
MP3TrackDemuxer::FastSeek(const TimeUnit& aTime) {
MP3TrackDemuxer::FastSeek(const TimeUnit& aTime)
{
MP3LOG("FastSeek(%" PRId64 ") avgFrameLen=%f mNumParsedFrames=%" PRIu64
" mFrameIndex=%" PRId64 " mOffset=%" PRIu64,
aTime.ToMicroseconds(), AverageFrameLength(), mNumParsedFrames,
@ -232,7 +247,8 @@ MP3TrackDemuxer::FastSeek(const TimeUnit& aTime) {
}
TimeUnit
MP3TrackDemuxer::ScanUntil(const TimeUnit& aTime) {
MP3TrackDemuxer::ScanUntil(const TimeUnit& aTime)
{
MP3LOG("ScanUntil(%" PRId64 ") avgFrameLen=%f mNumParsedFrames=%" PRIu64
" mFrameIndex=%" PRId64 " mOffset=%" PRIu64,
aTime.ToMicroseconds(), AverageFrameLength(), mNumParsedFrames,
@ -267,10 +283,11 @@ MP3TrackDemuxer::ScanUntil(const TimeUnit& aTime) {
}
RefPtr<MP3TrackDemuxer::SamplesPromise>
MP3TrackDemuxer::GetSamples(int32_t aNumSamples) {
MP3TrackDemuxer::GetSamples(int32_t aNumSamples)
{
MP3LOGV("GetSamples(%d) Begin mOffset=%" PRIu64 " mNumParsedFrames=%" PRIu64
" mFrameIndex=%" PRId64 " mTotalFrameLen=%" PRIu64 " mSamplesPerFrame=%d "
"mSamplesPerSecond=%d mChannels=%d",
" mFrameIndex=%" PRId64 " mTotalFrameLen=%" PRIu64
" mSamplesPerFrame=%d mSamplesPerSecond=%d mChannels=%d",
aNumSamples, mOffset, mNumParsedFrames, mFrameIndex, mTotalFrameLen,
mSamplesPerFrame, mSamplesPerSecond, mChannels);
@ -306,7 +323,8 @@ MP3TrackDemuxer::GetSamples(int32_t aNumSamples) {
}
void
MP3TrackDemuxer::Reset() {
MP3TrackDemuxer::Reset()
{
MP3LOG("Reset()");
FastSeek(TimeUnit());
@ -314,19 +332,22 @@ MP3TrackDemuxer::Reset() {
}
RefPtr<MP3TrackDemuxer::SkipAccessPointPromise>
MP3TrackDemuxer::SkipToNextRandomAccessPoint(const TimeUnit& aTimeThreshold) {
MP3TrackDemuxer::SkipToNextRandomAccessPoint(const TimeUnit& aTimeThreshold)
{
// Will not be called for audio-only resources.
return SkipAccessPointPromise::CreateAndReject(
SkipFailureHolder(NS_ERROR_DOM_MEDIA_DEMUXER_ERR, 0), __func__);
}
int64_t
MP3TrackDemuxer::GetResourceOffset() const {
MP3TrackDemuxer::GetResourceOffset() const
{
return mOffset;
}
TimeIntervals
MP3TrackDemuxer::GetBuffered() {
MP3TrackDemuxer::GetBuffered()
{
AutoPinned<MediaResource> stream(mSource.GetResource());
TimeIntervals buffered;
@ -357,12 +378,14 @@ MP3TrackDemuxer::GetBuffered() {
}
int64_t
MP3TrackDemuxer::StreamLength() const {
MP3TrackDemuxer::StreamLength() const
{
return mSource.GetLength();
}
TimeUnit
MP3TrackDemuxer::Duration() const {
MP3TrackDemuxer::Duration() const
{
if (!mNumParsedFrames) {
return TimeUnit::FromMicroseconds(-1);
}
@ -386,7 +409,8 @@ MP3TrackDemuxer::Duration() const {
}
TimeUnit
MP3TrackDemuxer::Duration(int64_t aNumFrames) const {
MP3TrackDemuxer::Duration(int64_t aNumFrames) const
{
if (!mSamplesPerSecond) {
return TimeUnit::FromMicroseconds(-1);
}
@ -396,13 +420,15 @@ MP3TrackDemuxer::Duration(int64_t aNumFrames) const {
}
MediaByteRange
MP3TrackDemuxer::FindFirstFrame() {
MP3TrackDemuxer::FindFirstFrame()
{
static const int MIN_SUCCESSIVE_FRAMES = 4;
MediaByteRange candidateFrame = FindNextFrame();
int numSuccFrames = candidateFrame.Length() > 0;
MediaByteRange currentFrame = candidateFrame;
MP3LOGV("FindFirst() first candidate frame: mOffset=%" PRIu64 " Length()=%" PRIu64,
MP3LOGV("FindFirst() first candidate frame: mOffset=%" PRIu64
" Length()=%" PRIu64,
candidateFrame.mStart, candidateFrame.Length());
while (candidateFrame.Length() && numSuccFrames < MIN_SUCCESSIVE_FRAMES) {
@ -419,16 +445,17 @@ MP3TrackDemuxer::FindFirstFrame() {
if (!currentFrame.Length() || frameSeparation != 0) {
MP3LOGV("FindFirst() not enough successive frames detected, "
"rejecting candidate frame: successiveFrames=%d, last Length()=%" PRIu64
", last frameSeparation=%" PRId64, numSuccFrames, currentFrame.Length(),
frameSeparation);
"rejecting candidate frame: successiveFrames=%d, last "
"Length()=%" PRIu64 ", last frameSeparation=%" PRId64,
numSuccFrames, currentFrame.Length(), frameSeparation);
mParser.ResetFrameData();
mOffset = candidateFrame.mStart + 1;
candidateFrame = FindNextFrame();
numSuccFrames = candidateFrame.Length() > 0;
currentFrame = candidateFrame;
MP3LOGV("FindFirst() new candidate frame: mOffset=%" PRIu64 " Length()=%" PRIu64,
MP3LOGV("FindFirst() new candidate frame: mOffset=%" PRIu64
" Length()=%" PRIu64,
candidateFrame.mStart, candidateFrame.Length());
}
}
@ -443,23 +470,26 @@ MP3TrackDemuxer::FindFirstFrame() {
}
static bool
VerifyFrameConsistency(
const FrameParser::Frame& aFrame1, const FrameParser::Frame& aFrame2) {
VerifyFrameConsistency(const FrameParser::Frame& aFrame1,
const FrameParser::Frame& aFrame2)
{
const auto& h1 = aFrame1.Header();
const auto& h2 = aFrame2.Header();
return h1.IsValid() && h2.IsValid() &&
h1.Layer() == h2.Layer() &&
h1.SlotSize() == h2.SlotSize() &&
h1.SamplesPerFrame() == h2.SamplesPerFrame() &&
h1.Channels() == h2.Channels() &&
h1.SampleRate() == h2.SampleRate() &&
h1.RawVersion() == h2.RawVersion() &&
h1.RawProtection() == h2.RawProtection();
return h1.IsValid()
&& h2.IsValid()
&& h1.Layer() == h2.Layer()
&& h1.SlotSize() == h2.SlotSize()
&& h1.SamplesPerFrame() == h2.SamplesPerFrame()
&& h1.Channels() == h2.Channels()
&& h1.SampleRate() == h2.SampleRate()
&& h1.RawVersion() == h2.RawVersion()
&& h1.RawProtection() == h2.RawProtection();
}
MediaByteRange
MP3TrackDemuxer::FindNextFrame() {
MP3TrackDemuxer::FindNextFrame()
{
static const int BUFFER_SIZE = 64;
static const int MAX_SKIPPED_BYTES = 1024 * BUFFER_SIZE;
@ -477,9 +507,9 @@ MP3TrackDemuxer::FindNextFrame() {
// Check whether we've found a valid MPEG frame.
while (!foundFrame) {
if ((!mParser.FirstFrame().Length() &&
mOffset - mParser.ID3Header().Size() > MAX_SKIPPED_BYTES) ||
(read = Read(buffer, mOffset, BUFFER_SIZE)) == 0) {
if ((!mParser.FirstFrame().Length()
&& mOffset - mParser.ID3Header().Size() > MAX_SKIPPED_BYTES)
|| (read = Read(buffer, mOffset, BUFFER_SIZE)) == 0) {
MP3LOG("FindNext() EOS or exceeded MAX_SKIPPED_BYTES without a frame");
// This is not a valid MPEG audio stream or we've reached EOS, give up.
break;
@ -488,14 +518,16 @@ MP3TrackDemuxer::FindNextFrame() {
ByteReader reader(buffer, read);
uint32_t bytesToSkip = 0;
foundFrame = mParser.Parse(&reader, &bytesToSkip);
frameHeaderOffset = mOffset + reader.Offset() - FrameParser::FrameHeader::SIZE;
frameHeaderOffset =
mOffset + reader.Offset() - FrameParser::FrameHeader::SIZE;
// If we've found neither an MPEG frame header nor an ID3v2 tag,
// the reader shouldn't have any bytes remaining.
MOZ_ASSERT(foundFrame || bytesToSkip || !reader.Remaining());
if (foundFrame && mParser.FirstFrame().Length() &&
!VerifyFrameConsistency(mParser.FirstFrame(), mParser.CurrentFrame())) {
if (foundFrame && mParser.FirstFrame().Length()
&& !VerifyFrameConsistency(mParser.FirstFrame(),
mParser.CurrentFrame())) {
// We've likely hit a false-positive, ignore it and proceed with the
// search for the next valid frame.
foundFrame = false;
@ -527,7 +559,8 @@ MP3TrackDemuxer::FindNextFrame() {
}
bool
MP3TrackDemuxer::SkipNextFrame(const MediaByteRange& aRange) {
MP3TrackDemuxer::SkipNextFrame(const MediaByteRange& aRange)
{
if (!mNumParsedFrames || !aRange.Length()) {
// We can't skip the first frame, since it could contain VBR headers.
RefPtr<MediaRawData> frame(GetNextFrame(aRange));
@ -546,7 +579,8 @@ MP3TrackDemuxer::SkipNextFrame(const MediaByteRange& aRange) {
}
already_AddRefed<MediaRawData>
MP3TrackDemuxer::GetNextFrame(const MediaByteRange& aRange) {
MP3TrackDemuxer::GetNextFrame(const MediaByteRange& aRange)
{
MP3LOG("GetNext() Begin({mStart=%" PRId64 " Length()=%" PRId64 "})",
aRange.mStart, aRange.Length());
if (!aRange.Length()) {
@ -562,7 +596,8 @@ MP3TrackDemuxer::GetNextFrame(const MediaByteRange& aRange) {
return nullptr;
}
const uint32_t read = Read(frameWriter->Data(), frame->mOffset, frame->Size());
const uint32_t read =
Read(frameWriter->Data(), frame->mOffset, frame->Size());
if (read != aRange.Length()) {
MP3LOG("GetNext() Exit read=%u frame->Size()=%u", read, frame->Size());
@ -596,13 +631,15 @@ MP3TrackDemuxer::GetNextFrame(const MediaByteRange& aRange) {
}
int64_t
MP3TrackDemuxer::OffsetFromFrameIndex(int64_t aFrameIndex) const {
MP3TrackDemuxer::OffsetFromFrameIndex(int64_t aFrameIndex) const
{
int64_t offset = 0;
const auto& vbr = mParser.VBRInfo();
if (vbr.IsComplete()) {
offset = mFirstFrameOffset + aFrameIndex * vbr.NumBytes().value() /
vbr.NumAudioFrames().value();
offset = mFirstFrameOffset
+ aFrameIndex * vbr.NumBytes().value()
/ vbr.NumAudioFrames().value();
} else if (AverageFrameLength() > 0) {
offset = mFirstFrameOffset + aFrameIndex * AverageFrameLength();
}
@ -612,13 +649,15 @@ MP3TrackDemuxer::OffsetFromFrameIndex(int64_t aFrameIndex) const {
}
int64_t
MP3TrackDemuxer::FrameIndexFromOffset(int64_t aOffset) const {
MP3TrackDemuxer::FrameIndexFromOffset(int64_t aOffset) const
{
int64_t frameIndex = 0;
const auto& vbr = mParser.VBRInfo();
if (vbr.IsComplete()) {
frameIndex = static_cast<float>(aOffset - mFirstFrameOffset) /
vbr.NumBytes().value() * vbr.NumAudioFrames().value();
frameIndex = static_cast<float>(aOffset - mFirstFrameOffset)
/ vbr.NumBytes().value()
* vbr.NumAudioFrames().value();
frameIndex = std::min<int64_t>(vbr.NumAudioFrames().value(), frameIndex);
} else if (AverageFrameLength() > 0) {
frameIndex = (aOffset - mFirstFrameOffset) / AverageFrameLength();
@ -629,18 +668,21 @@ MP3TrackDemuxer::FrameIndexFromOffset(int64_t aOffset) const {
}
int64_t
MP3TrackDemuxer::FrameIndexFromTime(const media::TimeUnit& aTime) const {
MP3TrackDemuxer::FrameIndexFromTime(const media::TimeUnit& aTime) const
{
int64_t frameIndex = 0;
if (mSamplesPerSecond > 0 && mSamplesPerFrame > 0) {
frameIndex = aTime.ToSeconds() * mSamplesPerSecond / mSamplesPerFrame - 1;
}
MP3LOGV("FrameIndexFromOffset(%fs) -> %" PRId64, aTime.ToSeconds(), frameIndex);
MP3LOGV("FrameIndexFromOffset(%fs) -> %" PRId64, aTime.ToSeconds(),
frameIndex);
return std::max<int64_t>(0, frameIndex);
}
void
MP3TrackDemuxer::UpdateState(const MediaByteRange& aRange) {
MP3TrackDemuxer::UpdateState(const MediaByteRange& aRange)
{
// Prevent overflow.
if (mTotalFrameLen + aRange.Length() < mTotalFrameLen) {
// These variables have a linear dependency and are only used to derive the
@ -669,7 +711,8 @@ MP3TrackDemuxer::UpdateState(const MediaByteRange& aRange) {
}
int32_t
MP3TrackDemuxer::Read(uint8_t* aBuffer, int64_t aOffset, int32_t aSize) {
MP3TrackDemuxer::Read(uint8_t* aBuffer, int64_t aOffset, int32_t aSize)
{
MP3LOGV("MP3TrackDemuxer::Read(%p %" PRId64 " %d)", aBuffer, aOffset, aSize);
const int64_t streamLen = StreamLength();
@ -687,14 +730,15 @@ MP3TrackDemuxer::Read(uint8_t* aBuffer, int64_t aOffset, int32_t aSize) {
}
double
MP3TrackDemuxer::AverageFrameLength() const {
MP3TrackDemuxer::AverageFrameLength() const
{
if (mNumParsedFrames) {
return static_cast<double>(mTotalFrameLen) / mNumParsedFrames;
}
const auto& vbr = mParser.VBRInfo();
if (vbr.IsComplete() && vbr.NumAudioFrames().value() + 1) {
return static_cast<double>(vbr.NumBytes().value()) /
(vbr.NumAudioFrames().value() + 1);
return static_cast<double>(vbr.NumBytes().value())
/ (vbr.NumAudioFrames().value() + 1);
}
return 0.0;
}
@ -714,20 +758,23 @@ FrameParser::FrameParser()
}
void
FrameParser::Reset() {
FrameParser::Reset()
{
mID3Parser.Reset();
mFrame.Reset();
}
void
FrameParser::ResetFrameData() {
FrameParser::ResetFrameData()
{
mFrame.Reset();
mFirstFrame.Reset();
mPrevFrame.Reset();
}
void
FrameParser::EndFrameSession() {
FrameParser::EndFrameSession()
{
if (!mID3Parser.Header().IsValid()) {
// Reset ID3 tags only if we have not parsed a valid ID3 header yet.
mID3Parser.Reset();
@ -737,32 +784,38 @@ FrameParser::EndFrameSession() {
}
const FrameParser::Frame&
FrameParser::CurrentFrame() const {
FrameParser::CurrentFrame() const
{
return mFrame;
}
const FrameParser::Frame&
FrameParser::PrevFrame() const {
FrameParser::PrevFrame() const
{
return mPrevFrame;
}
const FrameParser::Frame&
FrameParser::FirstFrame() const {
FrameParser::FirstFrame() const
{
return mFirstFrame;
}
const ID3Parser::ID3Header&
FrameParser::ID3Header() const {
FrameParser::ID3Header() const
{
return mID3Parser.Header();
}
const FrameParser::VBRHeader&
FrameParser::VBRInfo() const {
FrameParser::VBRInfo() const
{
return mVBRHeader;
}
bool
FrameParser::Parse(ByteReader* aReader, uint32_t* aBytesToSkip) {
FrameParser::Parse(ByteReader* aReader, uint32_t* aBytesToSkip)
{
MOZ_ASSERT(aReader && aBytesToSkip);
*aBytesToSkip = 0;
@ -777,8 +830,9 @@ FrameParser::Parse(ByteReader* aReader, uint32_t* aBytesToSkip) {
const uint32_t skipSize = tagSize - ID3Parser::ID3Header::SIZE;
if (skipSize > aReader->Remaining()) {
// Skipping across the ID3v2 tag would take us past the end of the buffer, therefore we
// return immediately and let the calling function handle skipping the rest of the tag.
// Skipping across the ID3v2 tag would take us past the end of the
// buffer, therefore we return immediately and let the calling function
// handle skipping the rest of the tag.
MP3LOGV("ID3v2 tag detected, size=%d,"
" needing to skip %d bytes past the current buffer",
tagSize, skipSize - aReader->Remaining());
@ -788,7 +842,8 @@ FrameParser::Parse(ByteReader* aReader, uint32_t* aBytesToSkip) {
MP3LOGV("ID3v2 tag detected, size=%d", tagSize);
aReader->Read(skipSize);
} else {
// No ID3v2 tag found, rewinding reader in order to search for a MPEG frame header.
// No ID3v2 tag found, rewinding reader in order to search for a MPEG
// frame header.
aReader->Seek(prevReaderOffset);
}
}
@ -814,64 +869,76 @@ FrameParser::FrameHeader::FrameHeader()
}
uint8_t
FrameParser::FrameHeader::Sync1() const {
FrameParser::FrameHeader::Sync1() const
{
return mRaw[frame_header::SYNC1];
}
uint8_t
FrameParser::FrameHeader::Sync2() const {
FrameParser::FrameHeader::Sync2() const
{
return 0x7 & mRaw[frame_header::SYNC2_VERSION_LAYER_PROTECTION] >> 5;
}
uint8_t
FrameParser::FrameHeader::RawVersion() const {
FrameParser::FrameHeader::RawVersion() const
{
return 0x3 & mRaw[frame_header::SYNC2_VERSION_LAYER_PROTECTION] >> 3;
}
uint8_t
FrameParser::FrameHeader::RawLayer() const {
FrameParser::FrameHeader::RawLayer() const
{
return 0x3 & mRaw[frame_header::SYNC2_VERSION_LAYER_PROTECTION] >> 1;
}
uint8_t
FrameParser::FrameHeader::RawProtection() const {
FrameParser::FrameHeader::RawProtection() const
{
return 0x1 & mRaw[frame_header::SYNC2_VERSION_LAYER_PROTECTION] >> 6;
}
uint8_t
FrameParser::FrameHeader::RawBitrate() const {
FrameParser::FrameHeader::RawBitrate() const
{
return 0xF & mRaw[frame_header::BITRATE_SAMPLERATE_PADDING_PRIVATE] >> 4;
}
uint8_t
FrameParser::FrameHeader::RawSampleRate() const {
FrameParser::FrameHeader::RawSampleRate() const
{
return 0x3 & mRaw[frame_header::BITRATE_SAMPLERATE_PADDING_PRIVATE] >> 2;
}
uint8_t
FrameParser::FrameHeader::Padding() const {
FrameParser::FrameHeader::Padding() const
{
return 0x1 & mRaw[frame_header::BITRATE_SAMPLERATE_PADDING_PRIVATE] >> 1;
}
uint8_t
FrameParser::FrameHeader::Private() const {
FrameParser::FrameHeader::Private() const
{
return 0x1 & mRaw[frame_header::BITRATE_SAMPLERATE_PADDING_PRIVATE];
}
uint8_t
FrameParser::FrameHeader::RawChannelMode() const {
FrameParser::FrameHeader::RawChannelMode() const
{
return 0x3 & mRaw[frame_header::CHANNELMODE_MODEEXT_COPY_ORIG_EMPH] >> 6;
}
int32_t
FrameParser::FrameHeader::Layer() const {
FrameParser::FrameHeader::Layer() const
{
static const uint8_t LAYERS[4] = { 0, 3, 2, 1 };
return LAYERS[RawLayer()];
}
int32_t
FrameParser::FrameHeader::SampleRate() const {
FrameParser::FrameHeader::SampleRate() const
{
// Sample rates - use [version][srate]
static const uint16_t SAMPLE_RATE[4][4] = {
{ 11025, 12000, 8000, 0 }, // MPEG 2.5
@ -884,14 +951,16 @@ FrameParser::FrameHeader::SampleRate() const {
}
int32_t
FrameParser::FrameHeader::Channels() const {
FrameParser::FrameHeader::Channels() const
{
// 3 is single channel (mono), any other value is some variant of dual
// channel.
return RawChannelMode() == 3 ? 1 : 2;
}
int32_t
FrameParser::FrameHeader::SamplesPerFrame() const {
FrameParser::FrameHeader::SamplesPerFrame() const
{
// Samples per frame - use [version][layer]
static const uint16_t FRAME_SAMPLE[4][4] = {
// Layer 3 2 1 Version
@ -905,7 +974,8 @@ FrameParser::FrameHeader::SamplesPerFrame() const {
}
int32_t
FrameParser::FrameHeader::Bitrate() const {
FrameParser::FrameHeader::Bitrate() const
{
// Bitrates - use [version][layer][bitrate]
static const uint16_t BITRATE[4][4][16] = {
{ // Version 2.5
@ -938,7 +1008,8 @@ FrameParser::FrameHeader::Bitrate() const {
}
int32_t
FrameParser::FrameHeader::SlotSize() const {
FrameParser::FrameHeader::SlotSize() const
{
// Slot size (MPEG unit of measurement) - use [layer]
static const uint8_t SLOT_SIZE[4] = { 0, 1, 1, 4 }; // Rsvd, 3, 2, 1
@ -946,7 +1017,8 @@ FrameParser::FrameHeader::SlotSize() const {
}
bool
FrameParser::FrameHeader::ParseNext(uint8_t c) {
FrameParser::FrameHeader::ParseNext(uint8_t c)
{
if (!Update(c)) {
Reset();
if (!Update(c)) {
@ -957,7 +1029,8 @@ FrameParser::FrameHeader::ParseNext(uint8_t c) {
}
bool
FrameParser::FrameHeader::IsValid(int aPos) const {
FrameParser::FrameHeader::IsValid(int aPos) const
{
if (aPos >= SIZE) {
return true;
}
@ -977,17 +1050,20 @@ FrameParser::FrameHeader::IsValid(int aPos) const {
}
bool
FrameParser::FrameHeader::IsValid() const {
FrameParser::FrameHeader::IsValid() const
{
return mPos >= SIZE;
}
void
FrameParser::FrameHeader::Reset() {
FrameParser::FrameHeader::Reset()
{
mPos = 0;
}
bool
FrameParser::FrameHeader::Update(uint8_t c) {
FrameParser::FrameHeader::Update(uint8_t c)
{
if (mPos < SIZE) {
mRaw[mPos] = c;
}
@ -1007,53 +1083,62 @@ FrameParser::VBRHeader::VBRHeader()
}
FrameParser::VBRHeader::VBRHeaderType
FrameParser::VBRHeader::Type() const {
FrameParser::VBRHeader::Type() const
{
return mType;
}
const Maybe<uint32_t>&
FrameParser::VBRHeader::NumAudioFrames() const {
FrameParser::VBRHeader::NumAudioFrames() const
{
return mNumAudioFrames;
}
const Maybe<uint32_t>&
FrameParser::VBRHeader::NumBytes() const {
FrameParser::VBRHeader::NumBytes() const
{
return mNumBytes;
}
const Maybe<uint32_t>&
FrameParser::VBRHeader::Scale() const {
FrameParser::VBRHeader::Scale() const
{
return mScale;
}
bool
FrameParser::VBRHeader::IsTOCPresent() const {
FrameParser::VBRHeader::IsTOCPresent() const
{
return mTOC.size() == vbr_header::TOC_SIZE;
}
bool
FrameParser::VBRHeader::IsValid() const {
FrameParser::VBRHeader::IsValid() const
{
return mType != NONE;
}
bool
FrameParser::VBRHeader::IsComplete() const {
return IsValid() &&
mNumAudioFrames.valueOr(0) > 0 &&
mNumBytes.valueOr(0) > 0 &&
FrameParser::VBRHeader::IsComplete() const
{
return IsValid()
&& mNumAudioFrames.valueOr(0) > 0
&& mNumBytes.valueOr(0) > 0
// We don't care about the scale for any computations here.
// mScale < 101 &&
true;
// && mScale < 101
&& true;
}
int64_t
FrameParser::VBRHeader::Offset(float aDurationFac) const {
FrameParser::VBRHeader::Offset(float aDurationFac) const
{
if (!IsTOCPresent()) {
return -1;
}
// Constrain the duration percentage to [0, 99].
const float durationPer = 100.0f * std::min(0.99f, std::max(0.0f, aDurationFac));
const float durationPer =
100.0f * std::min(0.99f, std::max(0.0f, aDurationFac));
const size_t fullPer = durationPer;
const float rest = durationPer - fullPer;
@ -1068,11 +1153,13 @@ FrameParser::VBRHeader::Offset(float aDurationFac) const {
}
bool
FrameParser::VBRHeader::ParseXing(ByteReader* aReader) {
FrameParser::VBRHeader::ParseXing(ByteReader* aReader)
{
static const uint32_t XING_TAG = BigEndian::readUint32("Xing");
static const uint32_t INFO_TAG = BigEndian::readUint32("Info");
enum Flags {
enum Flags
{
NUM_FRAMES = 0x01,
NUM_BYTES = 0x02,
TOC = 0x04,
@ -1124,15 +1211,17 @@ FrameParser::VBRHeader::ParseXing(ByteReader* aReader) {
}
bool
FrameParser::VBRHeader::ParseVBRI(ByteReader* aReader) {
FrameParser::VBRHeader::ParseVBRI(ByteReader* aReader)
{
static const uint32_t TAG = BigEndian::readUint32("VBRI");
static const uint32_t OFFSET = 32 + FrameParser::FrameHeader::SIZE;
static const uint32_t FRAME_COUNT_OFFSET = OFFSET + 14;
static const uint32_t MIN_FRAME_SIZE = OFFSET + 26;
MOZ_ASSERT(aReader);
// ParseVBRI assumes that the ByteReader offset points to the beginning of a frame,
// therefore as a simple check, we look for the presence of a frame sync at that position.
// ParseVBRI assumes that the ByteReader offset points to the beginning of a
// frame, therefore as a simple check, we look for the presence of a frame
// sync at that position.
MOZ_ASSERT((aReader->PeekU16() & 0xFFE0) == 0xFFE0);
const size_t prevReaderOffset = aReader->Offset();
@ -1152,7 +1241,8 @@ FrameParser::VBRHeader::ParseVBRI(ByteReader* aReader) {
}
bool
FrameParser::VBRHeader::Parse(ByteReader* aReader) {
FrameParser::VBRHeader::Parse(ByteReader* aReader)
{
const bool rv = ParseVBRI(aReader) || ParseXing(aReader);
if (rv) {
MP3LOG("VBRHeader::Parse found valid VBR/CBR header: type=%s"
@ -1166,35 +1256,40 @@ FrameParser::VBRHeader::Parse(ByteReader* aReader) {
// FrameParser::Frame
void
FrameParser::Frame::Reset() {
FrameParser::Frame::Reset()
{
mHeader.Reset();
}
int32_t
FrameParser::Frame::Length() const {
FrameParser::Frame::Length() const
{
if (!mHeader.IsValid() || !mHeader.SampleRate()) {
return 0;
}
const float bitsPerSample = mHeader.SamplesPerFrame() / 8.0f;
const int32_t frameLen = bitsPerSample * mHeader.Bitrate() /
mHeader.SampleRate() +
mHeader.Padding() * mHeader.SlotSize();
const int32_t frameLen = bitsPerSample * mHeader.Bitrate()
/ mHeader.SampleRate()
+ mHeader.Padding() * mHeader.SlotSize();
return frameLen;
}
bool
FrameParser::Frame::ParseNext(uint8_t c) {
FrameParser::Frame::ParseNext(uint8_t c)
{
return mHeader.ParseNext(c);
}
const FrameParser::FrameHeader&
FrameParser::Frame::Header() const {
FrameParser::Frame::Header() const
{
return mHeader;
}
bool
FrameParser::ParseVBRHeader(ByteReader* aReader) {
FrameParser::ParseVBRHeader(ByteReader* aReader)
{
return mVBRHeader.Parse(aReader);
}
@ -1219,7 +1314,8 @@ static const uint8_t MAX_MAJOR_VER = 4;
} // namespace id3_header
uint32_t
ID3Parser::Parse(ByteReader* aReader) {
ID3Parser::Parse(ByteReader* aReader)
{
MOZ_ASSERT(aReader);
while (aReader->CanRead8() && !mHeader.ParseNext(aReader->ReadU8())) { }
@ -1232,12 +1328,14 @@ ID3Parser::Parse(ByteReader* aReader) {
}
void
ID3Parser::Reset() {
ID3Parser::Reset()
{
mHeader.Reset();
}
const ID3Parser::ID3Header&
ID3Parser::Header() const {
ID3Parser::Header() const
{
return mHeader;
}
@ -1249,28 +1347,33 @@ ID3Parser::ID3Header::ID3Header()
}
void
ID3Parser::ID3Header::Reset() {
ID3Parser::ID3Header::Reset()
{
mSize = 0;
mPos = 0;
}
uint8_t
ID3Parser::ID3Header::MajorVersion() const {
ID3Parser::ID3Header::MajorVersion() const
{
return mRaw[id3_header::ID_END];
}
uint8_t
ID3Parser::ID3Header::MinorVersion() const {
ID3Parser::ID3Header::MinorVersion() const
{
return mRaw[id3_header::ID_END + 1];
}
uint8_t
ID3Parser::ID3Header::Flags() const {
ID3Parser::ID3Header::Flags() const
{
return mRaw[id3_header::FLAGS_END - id3_header::FLAGS_LEN];
}
uint32_t
ID3Parser::ID3Header::Size() const {
ID3Parser::ID3Header::Size() const
{
if (!IsValid()) {
return 0;
}
@ -1278,7 +1381,8 @@ ID3Parser::ID3Header::Size() const {
}
uint8_t
ID3Parser::ID3Header::FooterSize() const {
ID3Parser::ID3Header::FooterSize() const
{
if (Flags() & (1 << 4)) {
return SIZE;
}
@ -1286,7 +1390,8 @@ ID3Parser::ID3Header::FooterSize() const {
}
bool
ID3Parser::ID3Header::ParseNext(uint8_t c) {
ID3Parser::ID3Header::ParseNext(uint8_t c)
{
if (!Update(c)) {
Reset();
if (!Update(c)) {
@ -1297,7 +1402,8 @@ ID3Parser::ID3Header::ParseNext(uint8_t c) {
}
bool
ID3Parser::ID3Header::IsValid(int aPos) const {
ID3Parser::ID3Header::IsValid(int aPos) const
{
if (aPos >= SIZE) {
return true;
}
@ -1307,8 +1413,8 @@ ID3Parser::ID3Header::IsValid(int aPos) const {
// Expecting "ID3".
return id3_header::ID[aPos] == c;
case 3:
return MajorVersion() >= id3_header::MIN_MAJOR_VER &&
MajorVersion() <= id3_header::MAX_MAJOR_VER;
return MajorVersion() >= id3_header::MIN_MAJOR_VER
&& MajorVersion() <= id3_header::MAX_MAJOR_VER;
case 4:
return MinorVersion() < 0xFF;
case 5:
@ -1321,14 +1427,16 @@ ID3Parser::ID3Header::IsValid(int aPos) const {
}
bool
ID3Parser::ID3Header::IsValid() const {
ID3Parser::ID3Header::IsValid() const
{
return mPos >= SIZE;
}
bool
ID3Parser::ID3Header::Update(uint8_t c) {
if (mPos >= id3_header::SIZE_END - id3_header::SIZE_LEN &&
mPos < id3_header::SIZE_END) {
ID3Parser::ID3Header::Update(uint8_t c)
{
if (mPos >= id3_header::SIZE_END - id3_header::SIZE_LEN
&& mPos < id3_header::SIZE_END) {
mSize <<= 7;
mSize |= c;
}

View File

@ -17,7 +17,8 @@ namespace mp3 {
class MP3TrackDemuxer;
class MP3Demuxer : public MediaDataDemuxer {
class MP3Demuxer : public MediaDataDemuxer
{
public:
// MediaDataDemuxer interface.
explicit MP3Demuxer(MediaResource* aSource);
@ -42,10 +43,12 @@ private:
// The header contains the following format (one byte per term):
// 'I' 'D' '3' MajorVersion MinorVersion Flags Size1 Size2 Size3 Size4
// For more details see http://id3.org/id3v2.3.0.
class ID3Parser {
class ID3Parser
{
public:
// Holds the ID3 header and its parsing state.
class ID3Header {
class ID3Header
{
public:
// The header size is static, see class comment.
static const int SIZE = 10;
@ -130,10 +133,12 @@ private:
// T - Copyright (0->disabled, 1->enabled)
// O - Original (0->copy, 1->original)
// HH - Emphasis (0->none, 1->50/15 ms, 2->reserved, 3->CCIT J.17)
class FrameParser {
class FrameParser
{
public:
// Holds the frame header and its parsing state.
class FrameHeader {
class FrameHeader
{
public:
// The header size is static, see class comments.
static const int SIZE = 4;
@ -200,10 +205,12 @@ public:
// VBR frames may contain Xing or VBRI headers for additional info, we use
// this class to parse them and access this info.
class VBRHeader {
class VBRHeader
{
public:
// Synchronize with vbr_header TYPE_STR on change.
enum VBRHeaderType {
enum VBRHeaderType
{
NONE = 0,
XING,
VBRI
@ -231,7 +238,8 @@ public:
// Returns whether the header is valid (type XING or VBRI).
bool IsValid() const;
// Returns whether the header is valid and contains reasonable non-zero field values.
// Returns whether the header is valid and contains reasonable non-zero
// field values.
bool IsComplete() const;
// Returns the byte offset for the given duration percentage as a factor
@ -239,9 +247,9 @@ public:
int64_t Offset(float aDurationFac) const;
// Parses contents of given ByteReader for a valid VBR header.
// The offset of the passed ByteReader needs to point to an MPEG frame begin,
// as a VBRI-style header is searched at a fixed offset relative to frame begin.
// Returns whether a valid VBR header was found in the range.
// The offset of the passed ByteReader needs to point to an MPEG frame
// begin, as a VBRI-style header is searched at a fixed offset relative to
// frame begin. Returns whether a valid VBR header was found in the range.
bool Parse(mp4_demuxer::ByteReader* aReader);
private:
@ -274,7 +282,8 @@ public:
};
// Frame meta container used to parse and hold a frame header and side info.
class Frame {
class Frame
{
public:
// Returns the length of the frame excluding the header in bytes.
int32_t Length() const;
@ -325,16 +334,16 @@ public:
// - resets ID3Header if no valid header was parsed yet
void EndFrameSession();
// Parses contents of given ByteReader for a valid frame header and returns true
// if one was found. After returning, the variable passed to 'aBytesToSkip' holds
// the amount of bytes to be skipped (if any) in order to jump across a large
// ID3v2 tag spanning multiple buffers.
// Parses contents of given ByteReader for a valid frame header and returns
// true if one was found. After returning, the variable passed to
// 'aBytesToSkip' holds the amount of bytes to be skipped (if any) in order to
// jump across a large ID3v2 tag spanning multiple buffers.
bool Parse(mp4_demuxer::ByteReader* aReader, uint32_t* aBytesToSkip);
// Parses contents of given ByteReader for a valid VBR header.
// The offset of the passed ByteReader needs to point to an MPEG frame begin,
// as a VBRI-style header is searched at a fixed offset relative to frame begin.
// Returns whether a valid VBR header was found.
// as a VBRI-style header is searched at a fixed offset relative to frame
// begin. Returns whether a valid VBR header was found.
bool ParseVBRHeader(mp4_demuxer::ByteReader* aReader);
private:
@ -353,7 +362,8 @@ private:
// The MP3 demuxer used to extract MPEG frames and side information out of
// MPEG streams.
class MP3TrackDemuxer : public MediaTrackDemuxer {
class MP3TrackDemuxer : public MediaTrackDemuxer
{
public:
// Constructor, expecting a valid media resource.
explicit MP3TrackDemuxer(MediaResource* aSource);

View File

@ -41,7 +41,8 @@ namespace flac {
#define FLAC_MAX_FRAME_SIZE (FLAC_MAX_FRAME_HEADER_SIZE \
+FLAC_MAX_BLOCKSIZE*FLAC_MAX_CHANNELS*3)
class FrameHeader {
class FrameHeader
{
public:
const AudioInfo& Info() const { return mInfo; }
@ -159,7 +160,8 @@ public:
private:
friend class Frame;
enum {
enum
{
FLAC_CHMODE_INDEPENDENT = 0,
FLAC_CHMODE_LEFT_SIDE,
FLAC_CHMODE_RIGHT_SIDE,
@ -180,7 +182,8 @@ private:
};
const int FrameHeader::FlacSampleRateTable[16] =
{ 0,
{
0,
88200, 176400, 192000,
8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000,
0, 0, 0, 0
@ -232,7 +235,8 @@ const uint8_t FrameHeader::CRC8Table[256] =
// flac::Frame - Frame meta container used to parse and hold a frame
// header and side info.
class Frame {
class Frame
{
public:
// The FLAC signature is made of 14 bits set to 1; however the 15th bit is
@ -384,7 +388,8 @@ private:
};
class FrameParser {
class FrameParser
{
public:
// Returns the currently parsed frame. Reset via EndFrameSession.
@ -563,9 +568,7 @@ private:
// FlacDemuxer
FlacDemuxer::FlacDemuxer(MediaResource* aSource)
: mSource(aSource)
{}
FlacDemuxer::FlacDemuxer(MediaResource* aSource) : mSource(aSource) { }
bool
FlacDemuxer::InitInternal()
@ -638,7 +641,8 @@ FlacTrackDemuxer::Init()
// First check if we have a valid Flac start.
char buffer[BUFFER_SIZE];
const uint8_t* ubuffer = reinterpret_cast<uint8_t*>(buffer); // only needed due to type constraints of ReadAt.
const uint8_t* ubuffer = // only needed due to type constraints of ReadAt.
reinterpret_cast<uint8_t*>(buffer);
int64_t offset = 0;
do {
@ -762,7 +766,8 @@ FlacTrackDemuxer::FastSeek(const TimeUnit& aTime)
int64_t pivot =
aTime.ToSeconds() * AverageFrameLength() + mParser->FirstFrame().Offset();
// Time in seconds where we can stop seeking and will continue using ScanUntil.
// Time in seconds where we can stop seeking and will continue using
// ScanUntil.
static const int GAP_THRESHOLD = 5;
int64_t first = mParser->FirstFrame().Offset();
int64_t last = mSource.GetLength();

View File

@ -19,7 +19,8 @@ class FrameParser;
class FlacTrackDemuxer;
class FlacDemuxer : public MediaDataDemuxer {
class FlacDemuxer : public MediaDataDemuxer
{
public:
// MediaDataDemuxer interface.
explicit FlacDemuxer(MediaResource* aSource);
@ -40,7 +41,8 @@ private:
RefPtr<FlacTrackDemuxer> mTrackDemuxer;
};
class FlacTrackDemuxer : public MediaTrackDemuxer {
class FlacTrackDemuxer : public MediaTrackDemuxer
{
public:
explicit FlacTrackDemuxer(MediaResource* aSource);
@ -71,7 +73,8 @@ private:
// Fast approximate seeking to given time.
media::TimeUnit FastSeek(const media::TimeUnit& aTime);
// Seeks by scanning the stream up to the given time for more accurate results.
// Seeks by scanning the stream up to the given time for more accurate
// results.
media::TimeUnit ScanUntil(const media::TimeUnit& aTime);
// Finds the next valid frame and return it.

View File

@ -9,22 +9,22 @@
#include <stdint.h>
#include "MP4Demuxer.h"
#include "mp4_demuxer/MoofParser.h"
#include "mp4_demuxer/MP4Metadata.h"
#include "mp4_demuxer/ResourceStream.h"
#include "mp4_demuxer/BufferStream.h"
#include "mp4_demuxer/Index.h"
#include "nsPrintfCString.h"
// Used for telemetry
#include "mozilla/Telemetry.h"
#include "mp4_demuxer/AnnexB.h"
#include "mp4_demuxer/H264.h"
#include "mp4_demuxer/MoofParser.h"
#include "mp4_demuxer/MP4Metadata.h"
#include "mp4_demuxer/ResourceStream.h"
#include "mp4_demuxer/BufferStream.h"
#include "mp4_demuxer/Index.h"
#include "nsAutoPtr.h"
#include "nsPrintfCString.h"
extern mozilla::LazyLogModule gMediaDemuxerLog;
mozilla::LogModule* GetDemuxerLog() {
mozilla::LogModule* GetDemuxerLog()
{
return gMediaDemuxerLog;
}
@ -82,12 +82,12 @@ AccumulateSPSTelemetry(const MediaByteBuffer* aExtradata)
{
mp4_demuxer::SPSData spsdata;
if (mp4_demuxer::H264::DecodeSPSFromExtraData(aExtradata, spsdata)) {
uint8_t constraints = (spsdata.constraint_set0_flag ? (1 << 0) : 0) |
(spsdata.constraint_set1_flag ? (1 << 1) : 0) |
(spsdata.constraint_set2_flag ? (1 << 2) : 0) |
(spsdata.constraint_set3_flag ? (1 << 3) : 0) |
(spsdata.constraint_set4_flag ? (1 << 4) : 0) |
(spsdata.constraint_set5_flag ? (1 << 5) : 0);
uint8_t constraints = (spsdata.constraint_set0_flag ? (1 << 0) : 0)
| (spsdata.constraint_set1_flag ? (1 << 1) : 0)
| (spsdata.constraint_set2_flag ? (1 << 2) : 0)
| (spsdata.constraint_set3_flag ? (1 << 3) : 0)
| (spsdata.constraint_set4_flag ? (1 << 4) : 0)
| (spsdata.constraint_set5_flag ? (1 << 5) : 0);
Telemetry::Accumulate(Telemetry::VIDEO_DECODED_H264_SPS_CONSTRAINT_SET_FLAG,
constraints);
@ -98,8 +98,9 @@ AccumulateSPSTelemetry(const MediaByteBuffer* aExtradata)
// Make sure level_idc represents a value between levels 1 and 5.2,
// otherwise collect 0 for unknown level.
Telemetry::Accumulate(Telemetry::VIDEO_DECODED_H264_SPS_LEVEL,
(spsdata.level_idc >= 10 && spsdata.level_idc <= 52) ?
spsdata.level_idc : 0);
(spsdata.level_idc >= 10 && spsdata.level_idc <= 52)
? spsdata.level_idc
: 0);
// max_num_ref_frames should be between 0 and 16, anything larger will
// be treated as invalid.
@ -126,13 +127,15 @@ MP4Demuxer::Init()
// Check that we have enough data to read the metadata.
if (!mp4_demuxer::MP4Metadata::HasCompleteMetadata(stream)) {
return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_DEMUXER_ERR, __func__);
return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_DEMUXER_ERR,
__func__);
}
mInitData = mp4_demuxer::MP4Metadata::Metadata(stream);
if (!mInitData) {
// OOM
return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_DEMUXER_ERR, __func__);
return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_DEMUXER_ERR,
__func__);
}
RefPtr<mp4_demuxer::BufferStream> bufferstream =
@ -140,9 +143,10 @@ MP4Demuxer::Init()
mMetadata = MakeUnique<mp4_demuxer::MP4Metadata>(bufferstream);
if (!mMetadata->GetNumberTracks(mozilla::TrackInfo::kAudioTrack) &&
!mMetadata->GetNumberTracks(mozilla::TrackInfo::kVideoTrack)) {
return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_DEMUXER_ERR, __func__);
if (!mMetadata->GetNumberTracks(mozilla::TrackInfo::kAudioTrack)
&& !mMetadata->GetNumberTracks(mozilla::TrackInfo::kVideoTrack)) {
return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_DEMUXER_ERR,
__func__);
}
return InitPromise::CreateAndResolve(NS_OK, __func__);
@ -243,16 +247,16 @@ MP4TrackDemuxer::MP4TrackDemuxer(MP4Demuxer* aParent,
VideoInfo* videoInfo = mInfo->GetAsVideoInfo();
// Collect telemetry from h264 AVCC SPS.
if (videoInfo &&
(mInfo->mMimeType.EqualsLiteral("video/mp4") ||
mInfo->mMimeType.EqualsLiteral("video/avc"))) {
if (videoInfo
&& (mInfo->mMimeType.EqualsLiteral("video/mp4")
|| mInfo->mMimeType.EqualsLiteral("video/avc"))) {
mIsH264 = true;
RefPtr<MediaByteBuffer> extraData = videoInfo->mExtraData;
mNeedSPSForTelemetry = AccumulateSPSTelemetry(extraData);
mp4_demuxer::SPSData spsdata;
if (mp4_demuxer::H264::DecodeSPSFromExtraData(extraData, spsdata) &&
spsdata.pic_width > 0 && spsdata.pic_height > 0 &&
mp4_demuxer::H264::EnsureSPSIsSane(spsdata)) {
if (mp4_demuxer::H264::DecodeSPSFromExtraData(extraData, spsdata)
&& spsdata.pic_width > 0 && spsdata.pic_height > 0
&& mp4_demuxer::H264::EnsureSPSIsSane(spsdata)) {
videoInfo->mImage.width = spsdata.pic_width;
videoInfo->mImage.height = spsdata.pic_height;
videoInfo->mDisplay.width = spsdata.display_width;
@ -299,7 +303,8 @@ MP4TrackDemuxer::Seek(const media::TimeUnit& aTime)
do {
sample = GetNextSample();
if (!sample) {
return SeekPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_END_OF_STREAM, __func__);
return SeekPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_END_OF_STREAM,
__func__);
}
if (!sample->Size()) {
// This sample can't be decoded, continue searching.
@ -313,7 +318,8 @@ MP4TrackDemuxer::Seek(const media::TimeUnit& aTime)
SetNextKeyFrameTime();
return SeekPromise::CreateAndResolve(media::TimeUnit::FromMicroseconds(seekTime), __func__);
return SeekPromise::CreateAndResolve(
media::TimeUnit::FromMicroseconds(seekTime), __func__);
}
already_AddRefed<MediaRawData>
@ -334,20 +340,20 @@ MP4TrackDemuxer::GetNextSample()
{
bool keyframe = type == mp4_demuxer::H264::FrameType::I_FRAME;
if (sample->mKeyframe != keyframe) {
NS_WARNING(nsPrintfCString("Frame incorrectly marked as %skeyframe @ pts:%lld dur:%u dts:%lld",
keyframe ? "" : "non-",
sample->mTime,
sample->mDuration,
sample->mTimecode).get());
NS_WARNING(nsPrintfCString("Frame incorrectly marked as %skeyframe "
"@ pts:%lld dur:%u dts:%lld",
keyframe ? "" : "non-", sample->mTime,
sample->mDuration, sample->mTimecode)
.get());
sample->mKeyframe = keyframe;
}
break;
}
case mp4_demuxer::H264::FrameType::INVALID:
NS_WARNING(nsPrintfCString("Invalid H264 frame @ pts:%lld dur:%u dts:%lld",
sample->mTime,
sample->mDuration,
sample->mTimecode).get());
NS_WARNING(
nsPrintfCString("Invalid H264 frame @ pts:%lld dur:%u dts:%lld",
sample->mTime, sample->mDuration, sample->mTimecode)
.get());
// We could reject the sample now, however demuxer errors are fatal.
// So we keep the invalid frame, relying on the H264 decoder to
// handle the error later.
@ -377,7 +383,8 @@ MP4TrackDemuxer::GetSamples(int32_t aNumSamples)
EnsureUpToDateIndex();
RefPtr<SamplesHolder> samples = new SamplesHolder;
if (!aNumSamples) {
return SamplesPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_DEMUXER_ERR, __func__);
return SamplesPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_DEMUXER_ERR,
__func__);
}
if (mQueuedSample) {
@ -397,7 +404,8 @@ MP4TrackDemuxer::GetSamples(int32_t aNumSamples)
}
if (samples->mSamples.IsEmpty()) {
return SamplesPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_END_OF_STREAM, __func__);
return SamplesPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_END_OF_STREAM,
__func__);
} else {
for (const auto& sample : samples->mSamples) {
// Collect telemetry from h264 Annex B SPS.
@ -408,8 +416,9 @@ MP4TrackDemuxer::GetSamples(int32_t aNumSamples)
}
}
if (mNextKeyframeTime.isNothing() ||
samples->mSamples.LastElement()->mTime >= mNextKeyframeTime.value().ToMicroseconds()) {
if (mNextKeyframeTime.isNothing()
|| samples->mSamples.LastElement()->mTime
>= mNextKeyframeTime.value().ToMicroseconds()) {
SetNextKeyFrameTime();
}
return SamplesPromise::CreateAndResolve(samples, __func__);
@ -450,7 +459,8 @@ MP4TrackDemuxer::GetNextRandomAccessPoint(media::TimeUnit* aTime)
}
RefPtr<MP4TrackDemuxer::SkipAccessPointPromise>
MP4TrackDemuxer::SkipToNextRandomAccessPoint(const media::TimeUnit& aTimeThreshold)
MP4TrackDemuxer::SkipToNextRandomAccessPoint(
const media::TimeUnit& aTimeThreshold)
{
mQueuedSample = nullptr;
// Loop until we reach the next keyframe after the threshold.

View File

@ -33,8 +33,8 @@ public:
uint32_t GetNumberTracks(TrackInfo::TrackType aType) const override;
already_AddRefed<MediaTrackDemuxer> GetTrackDemuxer(TrackInfo::TrackType aType,
uint32_t aTrackNumber) override;
already_AddRefed<MediaTrackDemuxer>
GetTrackDemuxer(TrackInfo::TrackType aType, uint32_t aTrackNumber) override;
bool IsSeekable() const override;

View File

@ -269,8 +269,8 @@ MediaSourceDecoder::NextFrameBufferedStatus()
{
MOZ_ASSERT(NS_IsMainThread());
if (!mMediaSource ||
mMediaSource->ReadyState() == dom::MediaSourceReadyState::Closed) {
if (!mMediaSource
|| mMediaSource->ReadyState() == dom::MediaSourceReadyState::Closed) {
return MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE;
}
@ -304,7 +304,8 @@ MediaSourceDecoder::CanPlayThrough()
TimeUnit duration = TimeUnit::FromSeconds(mMediaSource->Duration());
TimeUnit currentPosition = TimeUnit::FromMicroseconds(CurrentPosition());
if (duration.IsInfinite()) {
// We can't make an informed decision and just assume that it's a live stream
// We can't make an informed decision and just assume that it's a live
// stream
return true;
} else if (duration <= currentPosition) {
return true;

View File

@ -35,8 +35,8 @@ public:
uint32_t GetNumberTracks(TrackInfo::TrackType aType) const override;
already_AddRefed<MediaTrackDemuxer> GetTrackDemuxer(TrackInfo::TrackType aType,
uint32_t aTrackNumber) override;
already_AddRefed<MediaTrackDemuxer>
GetTrackDemuxer(TrackInfo::TrackType aType, uint32_t aTrackNumber) override;
bool IsSeekable() const override;
@ -105,7 +105,8 @@ public:
nsresult GetNextRandomAccessPoint(media::TimeUnit* aTime) override;
RefPtr<SkipAccessPointPromise> SkipToNextRandomAccessPoint(const media::TimeUnit& aTimeThreshold) override;
RefPtr<SkipAccessPointPromise> SkipToNextRandomAccessPoint(
const media::TimeUnit& aTimeThreshold) override;
media::TimeIntervals GetBuffered() override;
@ -119,7 +120,8 @@ public:
private:
RefPtr<SeekPromise> DoSeek(const media::TimeUnit& aTime);
RefPtr<SamplesPromise> DoGetSamples(int32_t aNumSamples);
RefPtr<SkipAccessPointPromise> DoSkipToNextRandomAccessPoint(const media::TimeUnit& aTimeThreadshold);
RefPtr<SkipAccessPointPromise> DoSkipToNextRandomAccessPoint(
const media::TimeUnit& aTimeThreadshold);
already_AddRefed<MediaRawData> GetSample(MediaResult& aError);
// Return the timestamp of the next keyframe after mLastSampleIndex.
media::TimeUnit GetNextRandomAccessPoint();

View File

@ -197,7 +197,8 @@ WAVTrackDemuxer::FmtChunkParserInit()
if (!fmtChunk) {
return false;
}
ByteReader fmtReader(fmtChunk->Data(), mHeaderParser.GiveHeader().ChunkSize());
ByteReader fmtReader(fmtChunk->Data(),
mHeaderParser.GiveHeader().ChunkSize());
mFmtParser.Parse(fmtReader);
return true;
}
@ -260,16 +261,20 @@ WAVTrackDemuxer::ListChunkParserInit(uint32_t aChunkSize)
switch (id) {
case 0x49415254: // IART
mInfo->mTags.AppendElement(MetadataTag(NS_LITERAL_CSTRING("artist"), val));
mInfo->mTags.AppendElement(
MetadataTag(NS_LITERAL_CSTRING("artist"), val));
break;
case 0x49434d54: // ICMT
mInfo->mTags.AppendElement(MetadataTag(NS_LITERAL_CSTRING("comments"), val));
mInfo->mTags.AppendElement(
MetadataTag(NS_LITERAL_CSTRING("comments"), val));
break;
case 0x49474e52: // IGNR
mInfo->mTags.AppendElement(MetadataTag(NS_LITERAL_CSTRING("genre"), val));
mInfo->mTags.AppendElement(
MetadataTag(NS_LITERAL_CSTRING("genre"), val));
break;
case 0x494e414d: // INAM
mInfo->mTags.AppendElement(MetadataTag(NS_LITERAL_CSTRING("name"), val));
mInfo->mTags.AppendElement(
MetadataTag(NS_LITERAL_CSTRING("name"), val));
break;
}
@ -430,9 +435,8 @@ WAVTrackDemuxer::Duration(int64_t aNumDataChunks) const
if (!mSamplesPerSecond || !mSamplesPerChunk) {
return TimeUnit();
}
const double usPerDataChunk = USECS_PER_S *
static_cast<double>(mSamplesPerChunk) /
mSamplesPerSecond;
const double usPerDataChunk =
USECS_PER_S * static_cast<double>(mSamplesPerChunk) / mSamplesPerSecond;
return TimeUnit::FromMicroseconds(aNumDataChunks * usPerDataChunk);
}
@ -516,9 +520,8 @@ WAVTrackDemuxer::GetNextChunk(const MediaByteRange& aRange)
return nullptr;
}
const uint32_t read = Read(chunkWriter->Data(),
datachunk->mOffset,
datachunk->Size());
const uint32_t read =
Read(chunkWriter->Data(), datachunk->mOffset, datachunk->Size());
if (read != aRange.Length()) {
return nullptr;
@ -561,9 +564,8 @@ WAVTrackDemuxer::GetFileHeader(const MediaByteRange& aRange)
return nullptr;
}
const uint32_t read = Read(headerWriter->Data(),
fileHeader->mOffset,
fileHeader->Size());
const uint32_t read =
Read(headerWriter->Data(), fileHeader->mOffset, fileHeader->Size());
if (read != aRange.Length()) {
return nullptr;
@ -757,15 +759,19 @@ HeaderParser::ChunkHeader::IsValid() const
uint32_t
HeaderParser::ChunkHeader::ChunkName() const
{
return ((mRaw[0] << 24) | (mRaw[1] << 16) |
(mRaw[2] << 8 ) | (mRaw[3]));
return ((mRaw[0] << 24)
| (mRaw[1] << 16)
| (mRaw[2] << 8 )
| (mRaw[3]));
}
uint32_t
HeaderParser::ChunkHeader::ChunkSize() const
{
return ((mRaw[7] << 24) | (mRaw[6] << 16) |
(mRaw[5] << 8 ) | (mRaw[4]));
return ((mRaw[7] << 24)
| (mRaw[6] << 16)
| (mRaw[5] << 8 )
| (mRaw[4]));
}
void
@ -831,8 +837,10 @@ FormatParser::FormatChunk::Channels() const
uint32_t
FormatParser::FormatChunk::SampleRate() const
{
return (mRaw[7] << 24) | (mRaw[6] << 16) |
(mRaw[5] << 8 ) | (mRaw[4]);
return (mRaw[7] << 24)
| (mRaw[6] << 16)
| (mRaw[5] << 8)
| (mRaw[4]);
}
uint16_t
@ -857,8 +865,8 @@ FormatParser::FormatChunk::ParseNext(uint8_t c)
bool
FormatParser::FormatChunk::IsValid() const
{
return (FrameSize() == SampleRate() * Channels() / 8) &&
(mPos >= FMT_CHUNK_MIN_SIZE);
return (FrameSize() == SampleRate() * Channels() / 8)
&& (mPos >= FMT_CHUNK_MIN_SIZE);
}
void

View File

@ -30,7 +30,8 @@ static const uint16_t DATA_CHUNK_SIZE = 768;
class WAVTrackDemuxer;
class WAVDemuxer : public MediaDataDemuxer {
class WAVDemuxer : public MediaDataDemuxer
{
public:
// MediaDataDemuxer interface.
explicit WAVDemuxer(MediaResource* aSource);
@ -49,7 +50,8 @@ private:
RefPtr<WAVTrackDemuxer> mTrackDemuxer;
};
class RIFFParser {
class RIFFParser
{
private:
class RIFFHeader;
public:
@ -60,7 +62,8 @@ public:
void Reset();
private:
class RIFFHeader {
class RIFFHeader
{
public:
RIFFHeader();
void Reset();
@ -81,7 +84,8 @@ private:
RIFFHeader mRiffHeader;
};
class HeaderParser {
class HeaderParser
{
private:
class ChunkHeader;
public:
@ -92,7 +96,8 @@ public:
void Reset();
private:
class ChunkHeader {
class ChunkHeader
{
public:
ChunkHeader();
void Reset();
@ -115,7 +120,8 @@ private:
ChunkHeader mHeader;
};
class FormatParser {
class FormatParser
{
private:
class FormatChunk;
public:
@ -126,7 +132,8 @@ public:
void Reset();
private:
class FormatChunk {
class FormatChunk
{
public:
FormatChunk();
void Reset();
@ -151,7 +158,8 @@ private:
FormatChunk mFmtChunk;
};
class DataParser {
class DataParser
{
private:
class DataChunk;
public:
@ -162,7 +170,8 @@ public:
void Reset();
private:
class DataChunk {
class DataChunk
{
public:
void Reset();
private:
@ -172,7 +181,8 @@ private:
DataChunk mChunk;
};
class WAVTrackDemuxer : public MediaTrackDemuxer {
class WAVTrackDemuxer : public MediaTrackDemuxer
{
public:
explicit WAVTrackDemuxer(MediaResourceIndex aSource);