handle emulation_prevention_three_bytes for AVC

bug: 15917805
Change-Id: I824fe7eea807f8faba6b149c31890b7a5df87825
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 @@
 
     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 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 @@
       mNumBitsLeft(0) {
 }
 
+ABitReader::~ABitReader() {
+}
+
 void ABitReader::fillReservoir() {
     CHECK_GT(mSize, 0u);
 
@@ -99,4 +102,69 @@
     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