Backed out changeset 3cfe2793f157 (bug 831224)
authorEd Morley <emorley@mozilla.com>
Thu, 08 Aug 2013 09:59:52 -0700
changeset 154792 7e1ba78b8ab69dbac9567cfd7dfc3c86f0cfe13f
parent 154791 3ee2edd9e015847323f2a4fd46901b8bcaef11b2
child 154793 7e8173eba3261eca8e1904c3f522dfcd6e56921b
push id2961
push userlsblakk@mozilla.com
push dateMon, 28 Oct 2013 21:59:28 +0000
treeherdermozilla-beta@73ef4f13486f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs831224
milestone26.0a1
backs out3cfe2793f157aecc562007ee91fd9bcdf6b03333
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
Backed out changeset 3cfe2793f157 (bug 831224)
content/media/omx/MP3FrameParser.cpp
content/media/omx/MP3FrameParser.h
content/media/omx/moz.build
deleted file mode 100644
--- a/content/media/omx/MP3FrameParser.cpp
+++ /dev/null
@@ -1,487 +0,0 @@
-/* -*- 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/. */
-
-#include <algorithm>
-#include "nsMemory.h"
-#include "MP3FrameParser.h"
-
-namespace mozilla {
-
-// An ID3Buffer contains data of an ID3v2 header. The supplied buffer must
-// point to an ID3 header and at least the size of ID_HEADER_LENGTH. Run the
-// Parse method to read in the header's values.
-
-class ID3Buffer
-{
-public:
-
-  enum {
-    ID3_HEADER_LENGTH = 10
-  };
-
-  ID3Buffer(const uint8_t* aBuffer, uint32_t aLength)
-  : mBuffer(aBuffer),
-    mLength(aLength),
-    mSize(0)
-  {
-    MOZ_ASSERT(mBuffer || !mLength);
-  }
-
-  nsresult Parse();
-
-  int64_t GetMP3Offset() const {
-    return ID3_HEADER_LENGTH + mSize;
-  }
-
-private:
-  const uint8_t* mBuffer;
-  uint32_t       mLength;
-  uint32_t       mSize;
-};
-
-nsresult ID3Buffer::Parse()
-{
-  NS_ENSURE_TRUE(mBuffer && mLength >= ID3_HEADER_LENGTH, NS_ERROR_INVALID_ARG);
-
-  if ((mBuffer[0] != 'I') ||
-      (mBuffer[1] != 'D') ||
-      (mBuffer[2] != '3') ||
-      (mBuffer[6] & 0x80) ||
-      (mBuffer[7] & 0x80) ||
-      (mBuffer[8] & 0x80) ||
-      (mBuffer[9] & 0x80)) {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  mSize = ((static_cast<uint32_t>(mBuffer[6])<<21) |
-           (static_cast<uint32_t>(mBuffer[7])<<14) |
-           (static_cast<uint32_t>(mBuffer[8])<<7)  |
-            static_cast<uint32_t>(mBuffer[9]));
-
-  return NS_OK;
-}
-
-// The MP3Buffer contains MP3 frame data. The supplied buffer must point
-// to a frame header. Call the method Parse to extract information from
-// the MP3 frame headers in the supplied buffer.
-
-class MP3Buffer
-{
-public:
-
-  enum {
-    MP3_HEADER_LENGTH   = 4,
-    MP3_FRAMESIZE_CONST = 144000,
-    MP3_DURATION_CONST  = 8000
-  };
-
-  MP3Buffer(const uint8_t* aBuffer, uint32_t aLength)
-  : mBuffer(aBuffer),
-    mLength(aLength),
-    mDurationUs(0),
-    mNumFrames(0),
-    mBitRateSum(0),
-    mFrameSizeSum(0),
-    mTrailing(0)
-  {
-    MOZ_ASSERT(mBuffer || !mLength);
-  }
-
-  static const uint8_t* FindNextHeader(const uint8_t* aBuffer, uint32_t aLength);
-
-  nsresult Parse();
-
-  int64_t GetDuration() const {
-    return mDurationUs;
-  }
-
-  int64_t GetNumberOfFrames() const {
-    return mNumFrames;
-  }
-
-  int64_t GetBitRateSum() const {
-    return mBitRateSum;
-  }
-
-  int64_t GetFrameSizeSum() const {
-    return mFrameSizeSum;
-  }
-
-  int64_t GetTrailing() const {
-    return mTrailing;
-  }
-
-private:
-
-  enum MP3FrameHeaderField {
-    MP3_HDR_FIELD_SYNC,
-    MP3_HDR_FIELD_VERSION,
-    MP3_HDR_FIELD_LAYER,
-    MP3_HDR_FIELD_BITRATE,
-    MP3_HDR_FIELD_SAMPLERATE,
-    MP3_HDR_FIELD_PADDING,
-    MP3_HDR_FIELDS // Must be last enumerator value
-  };
-
-  enum {
-    MP3_HDR_CONST_FRAMESYNC = 0x7ff,
-    MP3_HDR_CONST_VERSION   = 3,
-    MP3_HDR_CONST_LAYER     = 1
-  };
-
-  static uint32_t ExtractBits(uint32_t aValue, uint32_t aOffset,
-                              uint32_t aBits);
-  static uint32_t ExtractFrameHeaderField(uint32_t aHeader,
-                                          enum MP3FrameHeaderField aField);
-  static uint32_t ExtractFrameHeader(const uint8_t* aBuffer);
-  static nsresult DecodeFrameHeader(const uint8_t* aBuffer,
-                                          size_t* aFrameSize,
-                                          uint32_t* aBitRate,
-                                          uint64_t* aDuration);
-
-  static const uint16_t sBitRate[16];
-  static const uint16_t sSampleRate[4];
-
-  const uint8_t* mBuffer;
-  uint32_t       mLength;
-
-  // The duration of this parsers data in milliseconds.
-  int64_t mDurationUs;
-
-  // The number of frames in the range.
-  int64_t mNumFrames;
-
-  // The sum of all frame's bit rates.
-  int64_t mBitRateSum;
-
-  // The sum of all frame's sizes in byte.
-  int32_t mFrameSizeSum;
-
-  // The number of trailing bytes.
-  int32_t mTrailing;
-};
-
-const uint16_t MP3Buffer::sBitRate[16] = {
-  0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0
-};
-
-const uint16_t MP3Buffer::sSampleRate[4] = {
-  44100, 48000, 32000, 0
-};
-
-uint32_t MP3Buffer::ExtractBits(uint32_t aValue, uint32_t aOffset, uint32_t aBits)
-{
-  return (aValue >> aOffset) & ((0x1ul << aBits) - 1);
-}
-
-uint32_t MP3Buffer::ExtractFrameHeaderField(uint32_t aHeader, enum MP3FrameHeaderField aField)
-{
-  static const uint8_t sField[MP3_HDR_FIELDS][2] = {
-    {21, 11}, {19, 2}, {17, 2}, {12, 4}, {10, 2}, {9, 1}
-  };
-
-  MOZ_ASSERT(aField < MP3_HDR_FIELDS);
-  return ExtractBits(aHeader, sField[aField][0], sField[aField][1]);
-}
-
-uint32_t MP3Buffer::ExtractFrameHeader(const uint8_t* aBuffer)
-{
-  MOZ_ASSERT(aBuffer);
-
-  uint32_t header = (static_cast<uint32_t>(aBuffer[0])<<24) |
-                    (static_cast<uint32_t>(aBuffer[1])<<16) |
-                    (static_cast<uint32_t>(aBuffer[2])<<8)  |
-                     static_cast<uint32_t>(aBuffer[3]);
-
-  uint32_t frameSync = ExtractFrameHeaderField(header, MP3_HDR_FIELD_SYNC);
-  uint32_t version = ExtractFrameHeaderField(header, MP3_HDR_FIELD_VERSION);
-  uint32_t layer = ExtractFrameHeaderField(header, MP3_HDR_FIELD_LAYER);
-  uint32_t bitRate = sBitRate[ExtractFrameHeaderField(header, MP3_HDR_FIELD_BITRATE)];
-  uint32_t sampleRate = sSampleRate[ExtractFrameHeaderField(header, MP3_HDR_FIELD_SAMPLERATE)];
-
-  // branch-less implementation of
-  //
-  //  if (fields-are-valid)
-  //    return header;
-  //  else
-  //    return 0;
-  //
-  return (frameSync == uint32_t(MP3_HDR_CONST_FRAMESYNC)) *
-         (version == uint32_t(MP3_HDR_CONST_VERSION)) *
-         (layer == uint32_t(MP3_HDR_CONST_LAYER)) * !!bitRate * !!sampleRate * header;
-}
-
-const uint8_t* MP3Buffer::FindNextHeader(const uint8_t* aBuffer, uint32_t aLength)
-{
-  MOZ_ASSERT(aBuffer || !aLength);
-
-  // Find MP3's frame-sync marker while there are at least 4 bytes
-  // left to contain the MP3 frame header
-
-  while (aLength >= MP3_HEADER_LENGTH) {
-    if (ExtractFrameHeader(aBuffer)) {
-      break;
-    }
-    ++aBuffer;
-    --aLength;
-  }
-
-  return aBuffer;
-}
-
-nsresult MP3Buffer::DecodeFrameHeader(const uint8_t* aBuffer,
-                                      uint32_t* aFrameSize,
-                                      uint32_t* aBitRate,
-                                      uint64_t* aDuration)
-{
-  uint32_t header = ExtractFrameHeader(aBuffer);
-
-  if (!header) {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  uint32_t bitRate = sBitRate[ExtractFrameHeaderField(header, MP3_HDR_FIELD_BITRATE)];
-  uint32_t sampleRate = sSampleRate[ExtractFrameHeaderField(header, MP3_HDR_FIELD_SAMPLERATE)];
-
-  uint32_t padding = ExtractFrameHeaderField(header, MP3_HDR_FIELD_PADDING);
-  uint32_t frameSize = (uint64_t(MP3_FRAMESIZE_CONST) * bitRate) / sampleRate + padding;
-
-  MOZ_ASSERT(aBitRate);
-  *aBitRate = bitRate;
-
-  MOZ_ASSERT(aFrameSize);
-  *aFrameSize = frameSize;
-
-  MOZ_ASSERT(aDuration);
-  *aDuration = (uint64_t(MP3_DURATION_CONST) * frameSize) / bitRate;
-
-  return NS_OK;
-}
-
-nsresult MP3Buffer::Parse()
-{
-  // We walk over the newly arrived data and sum up the
-  // bit rates, sizes, durations, etc. of the contained
-  // MP3 frames.
-
-  const uint8_t* buffer = mBuffer;
-  uint32_t       length = mLength;
-
-  while (length >= MP3_HEADER_LENGTH) {
-
-    uint32_t frameSize;
-    uint32_t bitRate;
-    uint64_t duration;
-
-    nsresult rv = DecodeFrameHeader(buffer, &frameSize, &bitRate, &duration);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    mBitRateSum += bitRate;
-    mDurationUs += duration;
-    ++mNumFrames;
-
-    mFrameSizeSum += frameSize;
-
-    if (frameSize <= length) {
-      length -= frameSize;
-    } else {
-      length = 0;
-    }
-
-    buffer += frameSize;
-  }
-
-  mTrailing = length;
-
-  return NS_OK;
-}
-
-MP3FrameParser::MP3FrameParser(int64_t aLength)
-: mBufferLength(0),
-  mLock("MP3FrameParser.mLock"),
-  mDurationUs(0),
-  mBitRateSum(0),
-  mNumFrames(0),
-  mOffset(0),
-  mUnhandled(0),
-  mLength(aLength),
-  mTrailing(0),
-  mIsMP3(true)
-{ }
-
-size_t MP3FrameParser::ParseInternalBuffer(const uint8_t* aBuffer, uint32_t aLength, int64_t aOffset)
-{
-  if (mOffset != aOffset) {
-    // If we don't append, we throw away our temporary buffer.
-    mBufferLength = 0;
-    return 0;
-  }
-
-  size_t copyLength = 0;
-
-  if (mBufferLength || !mOffset) {
-
-    // We have some data in our temporary buffer and append to it, or
-    // we are at the beginning of the stream. We both cases, we append
-    // some data to our temporary buffer and try to parse it.
-    copyLength = std::min<size_t>(NS_ARRAY_LENGTH(mBuffer)-mBufferLength, aLength);
-    memcpy(mBuffer+mBufferLength, aBuffer, copyLength*sizeof(*mBuffer));
-    mBufferLength += copyLength;
-  }
-
-  if ((mBufferLength >= ID3Buffer::ID3_HEADER_LENGTH) && (mOffset < ID3Buffer::ID3_HEADER_LENGTH)) {
-
-    // There might be an ID3 header at the very beginning of the stream.
-    ID3Buffer id3Buffer(mBuffer, mBufferLength);
-    nsresult rv = id3Buffer.Parse();
-
-    if (rv == NS_OK) {
-      mOffset += id3Buffer.GetMP3Offset()-(mBufferLength-copyLength);
-      mBufferLength = 0;
-    }
-  }
-
-  if (mBufferLength >= MP3Buffer::MP3_HEADER_LENGTH) {
-
-    // Or there could be a regular frame header somewhere
-    // in the stream.
-    MP3Buffer mp3Buffer(mBuffer, mBufferLength);
-    nsresult rv = mp3Buffer.Parse();
-
-    if (rv == NS_OK) {
-      mDurationUs += mp3Buffer.GetDuration();
-      mBitRateSum += mp3Buffer.GetBitRateSum();
-      mNumFrames  += mp3Buffer.GetNumberOfFrames();
-      mOffset     += mp3Buffer.GetFrameSizeSum()-(mBufferLength-copyLength);
-      mBufferLength = 0;
-    }
-  }
-
-  if (mBufferLength) {
-    // We have not been able to successfully parse the
-    // content of the temporary buffer. If the buffer is
-    // full already, the stream does not contain MP3.
-    mOffset += copyLength;
-    mIsMP3   = (mBufferLength < NS_ARRAY_LENGTH(mBuffer));
-  } else {
-    // We parsed the temporary buffer. The parser code
-    // will update the input data.
-    copyLength = 0;
-  }
-
-  if (mOffset > mLength) {
-    mLength = mOffset;
-  }
-
-  return copyLength;
-}
-
-void MP3FrameParser::Parse(const uint8_t* aBuffer, uint32_t aLength, int64_t aOffset)
-{
-  MutexAutoLock mon(mLock);
-
-  // We first try to parse the remaining data from the last call that
-  // is stored in an internal buffer.
-  size_t bufferIncr = ParseInternalBuffer(aBuffer, aLength, aOffset);
-
-  aBuffer += bufferIncr;
-  aLength -= bufferIncr;
-  aOffset += bufferIncr;
-
-  // The number of attempts to parse the data. This should be 1 of we
-  // append to the end of the existing data.
-  int retries = 1;
-
-  if (aOffset+aLength <= mOffset) {
-    // We already processed this fragment.
-    return;
-  } else if (aOffset < mOffset) {
-    // mOffset is within the new fragment, shorten range.
-    aLength -= mOffset-aOffset;
-    aBuffer += mOffset-aOffset;
-    aOffset  = mOffset;
-  } else if (aOffset > mOffset) {
-    // Fragment comes after current position, store difference.
-    mUnhandled += aOffset-mOffset;
-
-    // We might start in the middle of a frame and have find the next
-    // frame header. As our detection heuristics might return false
-    // positives, we simply try multiple times. The current value comes
-    // from experimentation with MP3 files. If you encounter false positives
-    // and incorrectly parsed MP3 files, try incrementing this value.
-    retries = 5;
-  }
-
-  uint32_t trailing = 0;
-
-  while (retries) {
-
-    MP3Buffer mp3Buffer(aBuffer, aLength);
-    nsresult rv = mp3Buffer.Parse();
-
-    if (rv != NS_OK) {
-      --retries;
-
-      if (!retries) {
-        mIsMP3 = false;
-        return;
-      }
-
-      // We might be in the middle of a frame, find next frame header
-      const uint8_t *buffer = MP3Buffer::FindNextHeader(aBuffer+1, aLength-1);
-
-      mUnhandled += buffer-aBuffer;
-      mOffset     = aOffset + buffer-aBuffer;
-      aLength    -= buffer-aBuffer;
-      aBuffer     = buffer;
-    } else {
-      mDurationUs += mp3Buffer.GetDuration();
-      mBitRateSum += mp3Buffer.GetBitRateSum();
-      mNumFrames  += mp3Buffer.GetNumberOfFrames();
-      mOffset     += mp3Buffer.GetFrameSizeSum();
-
-      trailing = mp3Buffer.GetTrailing();
-      retries = 0;
-    }
-  }
-
-  if (trailing) {
-    // Store trailing bytes in temporary buffer.
-    MOZ_ASSERT(trailing < (NS_ARRAY_LENGTH(mBuffer)*sizeof(*mBuffer)));
-    memcpy(mBuffer, aBuffer+(aLength-trailing), trailing);
-    mBufferLength = trailing;
-  }
-
-  if (mOffset > mLength) {
-    mLength = mOffset;
-  }
-}
-
-void MP3FrameParser::NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset)
-{
-  Parse(reinterpret_cast<const uint8_t*>(aBuffer), aLength, aOffset);
-}
-
-int64_t MP3FrameParser::GetDuration()
-{
-  MutexAutoLock mon(mLock);
-
-  if (!mNumFrames) {
-    return -1; // Not a single frame decoded yet
-  }
-
-  // Compute the duration of the unhandled fragments from
-  // the average bitrate.
-  int64_t avgBitRate = mBitRateSum / mNumFrames;
-  NS_ENSURE_TRUE(avgBitRate > 0, mDurationUs);
-
-  MOZ_ASSERT(mLength >= mOffset);
-  int64_t unhandled = mUnhandled + (mLength-mOffset);
-
-  return mDurationUs + (uint64_t(MP3Buffer::MP3_DURATION_CONST) * unhandled) / avgBitRate;
-}
-
-}
deleted file mode 100644
--- a/content/media/omx/MP3FrameParser.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* -*- 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/. */
-
-#include <stdint.h>
-#include "mozilla/Mutex.h"
-
-namespace mozilla {
-
-// A description of the MP3 format and its extensions is available at
-//
-//  http://www.codeproject.com/Articles/8295/MPEG-Audio-Frame-Header
-//
-// The data in MP3 streams is split into small frames, with each frame
-// containing a fixed number of samples. The duration of a frame depends
-// on the frame's bit rate and sample rate. Both values can vary among
-// frames, so it is necessary to examine each individual frame of an MP3
-// stream to calculate the stream's overall duration.
-//
-// The MP3 frame parser extracts information from an MP3 data stream. It
-// accepts a range of frames of an MP3 stream as input, and parses all
-// frames for their duration. Callers can query the stream's overall
-// duration from the parser.
-//
-// Call the methods NotifyDataArrived or Parse to add new data. If you added
-// information for a certain stream position, you cannot go back to previous
-// positions. The parser will simply ignore the input. If you skip stream
-// positions, the duration of the related MP3 frames will be estimated from
-// the stream's average.
-//
-// The method GetDuration returns calculated duration of the stream, including
-// estimates for skipped ranges.
-//
-// All public methods are thread-safe.
-
-class MP3FrameParser
-{
-public:
-  MP3FrameParser(int64_t aLength=-1);
-
-  bool IsMP3() {
-    MutexAutoLock mon(mLock);
-    return mIsMP3;
-  }
-
-  void Parse(const uint8_t* aBuffer, uint32_t aLength, int64_t aOffset);
-
-  void NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset);
-
-  int64_t GetDuration();
-
-private:
-  size_t ParseInternalBuffer(const uint8_t* aBuffer, uint32_t aLength, int64_t aOffset);
-
-  uint8_t  mBuffer[10];
-  uint32_t mBufferLength;
-
-  // A low-contention lock for protecting the parser results
-  Mutex mLock;
-
-  // All fields below are protected by mLock
-  uint64_t mDurationUs;
-  uint64_t mBitRateSum;
-  uint64_t mNumFrames;
-  int64_t  mOffset;
-  int64_t  mUnhandled;
-  int64_t  mLength;
-  uint32_t mTrailing;
-
-  // Contains the state of the MP3 detection
-  bool mIsMP3;
-};
-
-}
--- a/content/media/omx/moz.build
+++ b/content/media/omx/moz.build
@@ -9,13 +9,12 @@ MODULE = 'content'
 EXPORTS += [
     'MediaOmxDecoder.h',
     'MediaOmxReader.h',
 ]
 
 CPP_SOURCES += [
     'MediaOmxDecoder.cpp',
     'MediaOmxReader.cpp',
-    'MP3FrameParser.cpp',
     'OmxDecoder.cpp',
     'OMXCodecProxy.cpp',
 ]