summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChong Zhang <chz@google.com>2014-07-08 20:52:31 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-07-08 17:33:57 +0000
commit718cee5f3ba7c0a055fbeced90f26296f8acb117 (patch)
treec051432b32783dd4072bc460abd9fdc008d947c1
parente8eb7a885e574858ddfe3dfd836fbe9ce62f92b8 (diff)
parent862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46c (diff)
downloadframeworks_av-718cee5f3ba7c0a055fbeced90f26296f8acb117.zip
frameworks_av-718cee5f3ba7c0a055fbeced90f26296f8acb117.tar.gz
frameworks_av-718cee5f3ba7c0a055fbeced90f26296f8acb117.tar.bz2
Merge "handle emulation_prevention_three_bytes for AVC"
-rw-r--r--include/media/stagefright/foundation/ABitReader.h22
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp4
-rw-r--r--media/libstagefright/foundation/ABitReader.cpp68
3 files changed, 89 insertions, 5 deletions
diff --git a/include/media/stagefright/foundation/ABitReader.h b/include/media/stagefright/foundation/ABitReader.h
index 5510b12..c3bf0ff 100644
--- a/include/media/stagefright/foundation/ABitReader.h
+++ b/include/media/stagefright/foundation/ABitReader.h
@@ -25,8 +25,10 @@
namespace android {
-struct ABitReader {
+class ABitReader {
+public:
ABitReader(const uint8_t *data, size_t size);
+ virtual ~ABitReader();
uint32_t getBits(size_t n);
void skipBits(size_t n);
@@ -37,18 +39,32 @@ struct ABitReader {
const uint8_t *data() const;
-private:
+protected:
const uint8_t *mData;
size_t mSize;
uint32_t mReservoir; // left-aligned bits
size_t mNumBitsLeft;
- void fillReservoir();
+ virtual void fillReservoir();
DISALLOW_EVIL_CONSTRUCTORS(ABitReader);
};
+class NALBitReader : public ABitReader {
+public:
+ NALBitReader(const uint8_t *data, size_t size);
+
+ bool atLeastNumBitsLeft(size_t n) const;
+
+private:
+ int32_t mNumZeros;
+
+ virtual void fillReservoir();
+
+ DISALLOW_EVIL_CONSTRUCTORS(NALBitReader);
+};
+
} // namespace android
#endif // A_BIT_READER_H_
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index 5abfb71..dd73cc4 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -674,9 +674,9 @@ bool NuPlayer::CCDecoder::extractFromSEI(const sp<ABuffer> &accessUnit) {
bool hasCC = false;
- ABitReader br(sei->data() + 1, sei->size() - 1);
+ NALBitReader br(sei->data() + 1, sei->size() - 1);
// sei_message()
- while (br.numBitsLeft() >= 16) { // at least 16-bit for sei_message()
+ while (br.atLeastNumBitsLeft(16)) { // at least 16-bit for sei_message()
uint32_t payload_type = 0;
size_t payload_size = 0;
uint8_t last_byte;
diff --git a/media/libstagefright/foundation/ABitReader.cpp b/media/libstagefright/foundation/ABitReader.cpp
index 5499c32..beb5cc0 100644
--- a/media/libstagefright/foundation/ABitReader.cpp
+++ b/media/libstagefright/foundation/ABitReader.cpp
@@ -27,6 +27,9 @@ ABitReader::ABitReader(const uint8_t *data, size_t size)
mNumBitsLeft(0) {
}
+ABitReader::~ABitReader() {
+}
+
void ABitReader::fillReservoir() {
CHECK_GT(mSize, 0u);
@@ -99,4 +102,69 @@ const uint8_t *ABitReader::data() const {
return mData - (mNumBitsLeft + 7) / 8;
}
+NALBitReader::NALBitReader(const uint8_t *data, size_t size)
+ : ABitReader(data, size),
+ mNumZeros(0) {
+}
+
+bool NALBitReader::atLeastNumBitsLeft(size_t n) const {
+ // check against raw size and reservoir bits first
+ size_t numBits = numBitsLeft();
+ if (n > numBits) {
+ return false;
+ }
+
+ ssize_t numBitsRemaining = n - mNumBitsLeft;
+
+ size_t size = mSize;
+ const uint8_t *data = mData;
+ int32_t numZeros = mNumZeros;
+ while (size > 0 && numBitsRemaining > 0) {
+ bool isEmulationPreventionByte = (numZeros >= 2 && *data == 3);
+
+ if (*data == 0) {
+ ++numZeros;
+ } else {
+ numZeros = 0;
+ }
+
+ if (!isEmulationPreventionByte) {
+ numBitsRemaining -= 8;
+ }
+
+ ++data;
+ --size;
+ }
+
+ return (numBitsRemaining <= 0);
+}
+
+void NALBitReader::fillReservoir() {
+ CHECK_GT(mSize, 0u);
+
+ mReservoir = 0;
+ size_t i = 0;
+ while (mSize > 0 && i < 4) {
+ bool isEmulationPreventionByte = (mNumZeros >= 2 && *mData == 3);
+
+ if (*mData == 0) {
+ ++mNumZeros;
+ } else {
+ mNumZeros = 0;
+ }
+
+ // skip emulation_prevention_three_byte
+ if (!isEmulationPreventionByte) {
+ mReservoir = (mReservoir << 8) | *mData;
+ ++i;
+ }
+
+ ++mData;
+ --mSize;
+ }
+
+ mNumBitsLeft = 8 * i;
+ mReservoir <<= 32 - mNumBitsLeft;
+}
+
} // namespace android