commit 6715852d4487a4b3176c70f34358f5894954bbe2 Author: Eugen Sawin esawin@mozilla.com Date: Wed Aug 3 15:34:30 2016 +0200
Bug 1291543 - [1.1] Accept partial information from VBR headers. r=jya
This fixes our bug 20160. --- dom/media/MP3Demuxer.cpp | 16 ++++++++++------ dom/media/MP3Demuxer.h | 5 ++++- 2 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/dom/media/MP3Demuxer.cpp b/dom/media/MP3Demuxer.cpp index 88a20dcb..773f996 100644 --- a/dom/media/MP3Demuxer.cpp +++ b/dom/media/MP3Demuxer.cpp @@ -347,7 +347,7 @@ MP3TrackDemuxer::Duration() const {
int64_t numFrames = 0; const auto numAudioFrames = mParser.VBRInfo().NumAudioFrames(); - if (mParser.VBRInfo().IsValid()) { + if (mParser.VBRInfo().IsValid() && numAudioFrames.valueOr(0) + 1 > 1) { // VBR headers don't include the VBR header frame. numFrames = numAudioFrames.value() + 1; } else { @@ -513,7 +513,6 @@ MP3TrackDemuxer::GetNextFrame(const MediaByteRange& aRange) {
if (mNumParsedFrames == 1) { // First frame parsed, let's read VBR info if available. - // TODO: read info that helps with seeking (bug 1163667). ByteReader reader(frame->Data(), frame->Size()); mParser.ParseVBRHeader(&reader); reader.DiscardRemaining(); @@ -534,7 +533,7 @@ MP3TrackDemuxer::OffsetFromFrameIndex(int64_t aFrameIndex) const { int64_t offset = 0; const auto& vbr = mParser.VBRInfo();
- if (vbr.IsValid()) { + if (vbr.IsComplete()) { offset = mFirstFrameOffset + aFrameIndex * vbr.NumBytes().value() / vbr.NumAudioFrames().value(); } else if (AverageFrameLength() > 0) { @@ -550,7 +549,7 @@ MP3TrackDemuxer::FrameIndexFromOffset(int64_t aOffset) const { int64_t frameIndex = 0; const auto& vbr = mParser.VBRInfo();
- if (vbr.IsValid()) { + if (vbr.IsComplete()) { frameIndex = static_cast<float>(aOffset - mFirstFrameOffset) / vbr.NumBytes().value() * vbr.NumAudioFrames().value(); frameIndex = std::min<int64_t>(vbr.NumAudioFrames().value(), frameIndex); @@ -626,7 +625,7 @@ MP3TrackDemuxer::AverageFrameLength() const { return static_cast<double>(mTotalFrameLen) / mNumParsedFrames; } const auto& vbr = mParser.VBRInfo(); - if (vbr.IsValid() && vbr.NumAudioFrames().value() + 1) { + if (vbr.IsComplete() && vbr.NumAudioFrames().value() + 1) { return static_cast<double>(vbr.NumBytes().value()) / (vbr.NumAudioFrames().value() + 1); } @@ -964,7 +963,12 @@ FrameParser::VBRHeader::IsTOCPresent() const {
bool FrameParser::VBRHeader::IsValid() const { - return mType != NONE && + return mType != NONE; +} + +bool +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. diff --git a/dom/media/MP3Demuxer.h b/dom/media/MP3Demuxer.h index d98cb73..54e380a 100644 --- a/dom/media/MP3Demuxer.h +++ b/dom/media/MP3Demuxer.h @@ -232,9 +232,12 @@ public: // Returns true iff Xing/Info TOC (table of contents) is present. bool IsTOCPresent() const;
- // Returns whether the header is valid (containing reasonable field values). + // 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. + bool IsComplete() const; + // Returns the byte offset for the given duration percentage as a factor // (0: begin, 1.0: end). int64_t Offset(float aDurationFac) const;