author | Anthony Jones <ajones@mozilla.com> |
Thu, 11 Sep 2014 15:57:35 +1200 | |
changeset 204729 | 2097b83ffbab847fa200bb891fc0bd3ac98d3463 |
parent 204728 | 3331b49ff9e6063c4f2347e2a729631bbbca760a |
child 204730 | b3f02eb02208092fd717e126b1dad3592b03ac7b |
push id | 48987 |
push user | ajones@mozilla.com |
push date | Thu, 11 Sep 2014 03:58:47 +0000 |
treeherder | mozilla-inbound@2097b83ffbab [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | kinetik |
bugs | 1061079 |
milestone | 35.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/content/media/mediasource/SourceBuffer.cpp +++ b/content/media/mediasource/SourceBuffer.cpp @@ -197,17 +197,17 @@ public: private: WebMBufferedParser mParser; nsTArray<WebMTimeDataOffset> mOverlappedMapping; int64_t mOffset; }; class MP4ContainerParser : public ContainerParser { public: - MP4ContainerParser() : mTimescale(0) {} + MP4ContainerParser() {} bool IsInitSegmentPresent(const uint8_t* aData, uint32_t aLength) { ContainerParser::IsInitSegmentPresent(aData, aLength); // Each MP4 atom has a chunk size and chunk type. The root chunk in an MP4 // file is the 'ftyp' atom followed by a file type. We just check for a // vaguely valid 'ftyp' atom. @@ -229,51 +229,57 @@ public: return aData[4] == 'f' && aData[5] == 't' && aData[6] == 'y' && aData[7] == 'p'; } virtual bool ParseStartAndEndTimestamps(const uint8_t* aData, uint32_t aLength, double& aStart, double& aEnd) { - mp4_demuxer::MoofParser parser(new mp4_demuxer::BufferStream(aData, aLength), 0); - parser.mMdhd.mTimescale = mTimescale; + bool initSegment = IsInitSegmentPresent(aData, aLength); + if (initSegment) { + mStream = new mp4_demuxer::BufferStream(); + mParser = new mp4_demuxer::MoofParser(mStream, 0); + } else if (!mStream || !mParser) { + return false; + } + mStream->AppendBytes(aData, aLength); nsTArray<MediaByteRange> byteRanges; - byteRanges.AppendElement(MediaByteRange(0, aLength)); - parser.RebuildFragmentedIndex(byteRanges); + byteRanges.AppendElement(mStream->GetByteRange()); + mParser->RebuildFragmentedIndex(byteRanges); - if (IsInitSegmentPresent(aData, aLength)) { - const MediaByteRange& range = parser.mInitRange; + if (initSegment) { + const MediaByteRange& range = mParser->mInitRange; MSE_DEBUG("MP4ContainerParser(%p)::ParseStartAndEndTimestamps: Stashed init of %u bytes.", this, range.mEnd - range.mStart); mInitData.ReplaceElementsAt(0, mInitData.Length(), aData + range.mStart, range.mEnd - range.mStart); } - // Persist the timescale for when it is absent in later chunks - mTimescale = parser.mMdhd.mTimescale; + mp4_demuxer::Interval<mp4_demuxer::Microseconds> compositionRange = + mParser->GetCompositionRange(byteRanges); - mp4_demuxer::Interval<mp4_demuxer::Microseconds> compositionRange = - parser.GetCompositionRange(); + mStream->DiscardBefore(mParser->mOffset); if (compositionRange.IsNull()) { return false; } aStart = static_cast<double>(compositionRange.start) / USECS_PER_S; aEnd = static_cast<double>(compositionRange.end) / USECS_PER_S; MSE_DEBUG("MP4ContainerParser(%p)::ParseStartAndEndTimestamps: [%f, %f]", this, aStart, aEnd); return true; } - private: - uint32_t mTimescale; +private: + nsRefPtr<mp4_demuxer::BufferStream> mStream; + nsAutoPtr<mp4_demuxer::MoofParser> mParser; }; /*static*/ ContainerParser* ContainerParser::CreateForMIMEType(const nsACString& aType) { if (aType.LowerCaseEqualsLiteral("video/webm") || aType.LowerCaseEqualsLiteral("audio/webm")) { return new WebMContainerParser();