Bug 1195723: P5. Add BitReader class. r?kamidphish
Extracted from the H264 codec and using the stagefright one.
MozReview-Commit-ID: ENjsDvB9MYp
new file mode 100644
--- /dev/null
+++ b/media/libstagefright/binding/BitReader.cpp
@@ -0,0 +1,104 @@
+/* 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 "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::BitReader(const uint8_t* aBuffer, size_t aLength)
+ : mBitReader(new ABitReader(aBuffer, aLength))
+ , mSize(aLength) {}
+
+BitReader::~BitReader() {}
+
+uint32_t
+BitReader::ReadBits(size_t aNum)
+{
+ MOZ_ASSERT(aNum <= 32);
+ if (mBitReader->numBitsLeft() < aNum) {
+ return 0;
+ }
+ return mBitReader->getBits(aNum);
+}
+
+// Read unsigned integer Exp-Golomb-coded.
+uint32_t
+BitReader::ReadUE()
+{
+ uint32_t i = 0;
+
+ while (ReadBit() == 0 && i < 32) {
+ i++;
+ }
+ if (i == 32) {
+ // This can happen if the data is invalid, or if it's
+ // short, since ReadBit() will return 0 when it runs
+ // off the end of the buffer.
+ NS_WARNING("Invalid H.264 data");
+ return 0;
+ }
+ uint32_t r = ReadBits(i);
+ r += (1 << i) - 1;
+ return r;
+}
+
+// Read signed integer Exp-Golomb-coded.
+int32_t
+BitReader::ReadSE()
+{
+ int32_t r = ReadUE();
+ if (r & 1) {
+ return (r+1) / 2;
+ } else {
+ return -r / 2;
+ }
+}
+
+uint64_t
+BitReader::ReadU64()
+{
+ uint64_t hi = ReadU32();
+ uint32_t lo = ReadU32();
+ return (hi << 32) | lo;
+}
+
+uint64_t
+BitReader::ReadUTF8()
+{
+ int64_t val = ReadBits(8);
+ uint32_t top = (val & 0x80) >> 1;
+
+ if ((val & 0xc0) == 0x80 || val >= 0xFE) {
+ // error.
+ return -1;
+ }
+ while (val & top) {
+ int tmp = ReadBits(8) - 128;
+ if (tmp >> 6) {
+ // error.
+ return -1;
+ }
+ val = (val << 6) + tmp;
+ top <<= 5;
+ }
+ val &= (top << 1) - 1;
+ return val;
+}
+
+size_t
+BitReader::BitCount() const
+{
+ return mSize * 8 - mBitReader->numBitsLeft();
+}
+
+} // namespace mp4_demuxer
--- a/media/libstagefright/binding/H264.cpp
+++ b/media/libstagefright/binding/H264.cpp
@@ -1,83 +1,27 @@
/* 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 "mozilla/ArrayUtils.h"
#include "mozilla/PodOperations.h"
#include "mp4_demuxer/AnnexB.h"
+#include "mp4_demuxer/BitReader.h"
#include "mp4_demuxer/ByteReader.h"
#include "mp4_demuxer/ByteWriter.h"
#include "mp4_demuxer/H264.h"
#include <media/stagefright/foundation/ABitReader.h>
#include <limits>
using namespace mozilla;
namespace mp4_demuxer
{
-class BitReader
-{
-public:
- explicit BitReader(const mozilla::MediaByteBuffer* aBuffer)
- : mBitReader(aBuffer->Elements(), aBuffer->Length())
- {
- }
-
- uint32_t ReadBits(size_t aNum)
- {
- MOZ_ASSERT(aNum <= 32);
- if (mBitReader.numBitsLeft() < aNum) {
- return 0;
- }
- return mBitReader.getBits(aNum);
- }
-
- uint32_t ReadBit()
- {
- return ReadBits(1);
- }
-
- // Read unsigned integer Exp-Golomb-coded.
- uint32_t ReadUE()
- {
- uint32_t i = 0;
-
- while (ReadBit() == 0 && i < 32) {
- i++;
- }
- if (i == 32) {
- // This can happen if the data is invalid, or if it's
- // short, since ReadBit() will return 0 when it runs
- // off the end of the buffer.
- NS_WARNING("Invalid H.264 data");
- return 0;
- }
- uint32_t r = ReadBits(i);
- r += (1 << i) - 1;
- return r;
- }
-
- // Read signed integer Exp-Golomb-coded.
- int32_t ReadSE()
- {
- int32_t r = ReadUE();
- if (r & 1) {
- return (r+1) / 2;
- } else {
- return -r / 2;
- }
- }
-
-private:
- stagefright::ABitReader mBitReader;
-};
-
SPSData::SPSData()
{
PodZero(this);
// Default values when they aren't defined as per ITU-T H.264 (2014/02).
chroma_format_idc = 1;
video_format = 5;
colour_primaries = 2;
transfer_characteristics = 2;
new file mode 100644
--- /dev/null
+++ b/media/libstagefright/binding/include/mp4_demuxer/BitReader.h
@@ -0,0 +1,45 @@
+/* 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/. */
+
+#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();
+ uint32_t ReadBits(size_t aNum);
+ uint32_t ReadBit() { return ReadBits(1); }
+ uint32_t ReadU32() { return ReadBits(32); }
+ uint64_t ReadU64();
+
+ // Read the UTF-8 sequence and convert it to its 64-bit UCS-4 encoded form.
+ // Return 0xfffffffffffffff if sequence was invalid.
+ uint64_t ReadUTF8();
+ // Read unsigned integer Exp-Golomb-coded.
+ uint32_t ReadUE();
+ // Read signed integer Exp-Golomb-coded.
+ int32_t ReadSE();
+
+ // Return the number of bits parsed so far;
+ size_t BitCount() const;
+
+private:
+ nsAutoPtr<stagefright::ABitReader> mBitReader;
+ const size_t mSize;
+};
+
+} // namespace mp4_demuxer
+
+#endif // BIT_READER_H_
\ No newline at end of file
--- a/media/libstagefright/moz.build
+++ b/media/libstagefright/moz.build
@@ -47,16 +47,17 @@ if CONFIG['OS_TARGET'] != 'Android':
'system/core/liblog/logprint.c',
]
EXPORTS.mp4_demuxer += [
'binding/include/mp4_demuxer/Adts.h',
'binding/include/mp4_demuxer/AnnexB.h',
'binding/include/mp4_demuxer/Atom.h',
'binding/include/mp4_demuxer/AtomType.h',
+ 'binding/include/mp4_demuxer/BitReader.h',
'binding/include/mp4_demuxer/BufferStream.h',
'binding/include/mp4_demuxer/ByteReader.h',
'binding/include/mp4_demuxer/ByteWriter.h',
'binding/include/mp4_demuxer/DecoderData.h',
'binding/include/mp4_demuxer/H264.h',
'binding/include/mp4_demuxer/Index.h',
'binding/include/mp4_demuxer/Interval.h',
'binding/include/mp4_demuxer/MoofParser.h',
@@ -82,16 +83,17 @@ SOURCES += [
if CONFIG['MOZ_RUST']:
EXPORTS += [
'binding/include/mp4parse.h',
]
UNIFIED_SOURCES += [
'binding/Adts.cpp',
'binding/AnnexB.cpp',
+ 'binding/BitReader.cpp',
'binding/Box.cpp',
'binding/BufferStream.cpp',
'binding/DecoderData.cpp',
'binding/H264.cpp',
'binding/Index.cpp',
'binding/MoofParser.cpp',
'binding/MP4Metadata.cpp',
'binding/ResourceStream.cpp',