Skip to content
This repository has been archived by the owner on Aug 4, 2022. It is now read-only.

Commit

Permalink
Bug 1323081: P1. Add native BitReader class. r=gerald
Browse files Browse the repository at this point in the history
This is a rewrite from Stagefright's ABitReader. The major difference is that you give the original size in bits rather than in bytes. ABitReader always read all bits available. While under some circumstances we want to bound the buffer to a set number of bits.

MozReview-Commit-ID: hdJ7CAwOea
  • Loading branch information
Jean-Yves Avenard committed Dec 14, 2016
1 parent aa9f822 commit c6510f9
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 19 deletions.
2 changes: 1 addition & 1 deletion dom/media/flac/FlacDemuxer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class FrameHeader {
// bytes.
bool Parse(const uint8_t* aPacket)
{
mp4_demuxer::BitReader br(aPacket, FLAC_MAX_FRAME_HEADER_SIZE);
mp4_demuxer::BitReader br(aPacket, FLAC_MAX_FRAME_HEADER_SIZE * 8);

// Frame sync code.
if ((br.ReadBits(15) & 0x7fff) != 0x7ffc) {
Expand Down
76 changes: 64 additions & 12 deletions media/libstagefright/binding/BitReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,65 @@
* 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/. */

// Derived from Stagefright's ABitReader.

#include "mp4_demuxer/BitReader.h"
#include <media/stagefright/foundation/ABitReader.h>

using namespace mozilla;
using namespace stagefright;

namespace mp4_demuxer
{

BitReader::BitReader(const mozilla::MediaByteBuffer* aBuffer)
: mBitReader(new ABitReader(aBuffer->Elements(), aBuffer->Length()))
, mSize(aBuffer->Length()) {}
: BitReader(aBuffer->Elements(), aBuffer->Length() * 8)
{
}

BitReader::BitReader(const uint8_t* aBuffer, size_t aLength)
: mBitReader(new ABitReader(aBuffer, aLength))
, mSize(aLength) {}
BitReader::BitReader(const mozilla::MediaByteBuffer* aBuffer, size_t aBits)
: BitReader(aBuffer->Elements(), aBits)
{
}

BitReader::~BitReader() {}
BitReader::BitReader(const uint8_t* aBuffer, size_t aBits)
: mData(aBuffer)
, mOriginalBitSize(aBits)
, mTotalBitsLeft(aBits)
, mSize((aBits + 7) / 8)
, mReservoir(0)
, mNumBitsLeft(0)
{
}

BitReader::~BitReader() { }

uint32_t
BitReader::ReadBits(size_t aNum)
{
MOZ_ASSERT(aNum <= 32);
if (mBitReader->numBitsLeft() < aNum) {
if (mTotalBitsLeft < aNum) {
NS_ASSERTION(false, "Reading past end of buffer");
return 0;
}
return mBitReader->getBits(aNum);
uint32_t result = 0;
while (aNum > 0) {
if (mNumBitsLeft == 0) {
FillReservoir();
}

size_t m = aNum;
if (m > mNumBitsLeft) {
m = mNumBitsLeft;
}

result = (result << m) | (mReservoir >> (32 - m));
mReservoir <<= m;
mNumBitsLeft -= m;
mTotalBitsLeft -= m;

aNum -= m;
}

return result;
}

// Read unsigned integer Exp-Golomb-coded.
Expand Down Expand Up @@ -98,13 +130,33 @@ BitReader::ReadUTF8()
size_t
BitReader::BitCount() const
{
return mSize * 8 - mBitReader->numBitsLeft();
return mOriginalBitSize - mTotalBitsLeft;
}

size_t
BitReader::BitsLeft() const
{
return mBitReader->numBitsLeft();
return mTotalBitsLeft;
}

void
BitReader::FillReservoir()
{
if (mSize == 0) {
NS_ASSERTION(false, "Attempting to fill reservoir from past end of data");
return;
}

mReservoir = 0;
size_t i;
for (i = 0; mSize > 0 && i < 4; i++) {
mReservoir = (mReservoir << 8) | *mData;
mData++;
mSize--;
}

mNumBitsLeft = 8 * i;
mReservoir <<= 32 - mNumBitsLeft;
}

} // namespace mp4_demuxer
15 changes: 9 additions & 6 deletions media/libstagefright/binding/include/mp4_demuxer/BitReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,17 @@
#ifndef BIT_READER_H_
#define BIT_READER_H_

#include "nsAutoPtr.h"
#include "MediaData.h"

namespace stagefright { class ABitReader; }

namespace mp4_demuxer
{

class BitReader
{
public:
explicit BitReader(const mozilla::MediaByteBuffer* aBuffer);
BitReader(const uint8_t* aBuffer, size_t aLength);
BitReader(const mozilla::MediaByteBuffer* aBuffer, size_t aBits);
BitReader(const uint8_t* aBuffer, size_t aBits);
~BitReader();
uint32_t ReadBits(size_t aNum);
uint32_t ReadBit() { return ReadBits(1); }
Expand All @@ -38,8 +36,13 @@ class BitReader
size_t BitsLeft() const;

private:
nsAutoPtr<stagefright::ABitReader> mBitReader;
const size_t mSize;
void FillReservoir();
const uint8_t* mData;
const size_t mOriginalBitSize;
size_t mTotalBitsLeft;
size_t mSize; // Size left in bytes
uint32_t mReservoir; // Left-aligned bits
size_t mNumBitsLeft; // Number of bits left in reservoir.
};

} // namespace mp4_demuxer
Expand Down

0 comments on commit c6510f9

Please sign in to comment.