Merge "Fix ringbuffer handling" into lmp-dev
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
index 863b908..fb27dca 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
@@ -137,6 +137,7 @@
     mOutputDelayRingBuffer = new short[mOutputDelayRingBufferSize];
     mOutputDelayRingBufferWritePos = 0;
     mOutputDelayRingBufferReadPos = 0;
+    mOutputDelayRingBufferFilled = 0;
 
     if (mAACDecoder == NULL) {
         ALOGE("AAC decoder is null. TODO: Can not call aacDecoder_SetParam in the following code");
@@ -411,6 +412,10 @@
     if (numSamples == 0) {
         return true;
     }
+    if (outputDelayRingBufferSpaceLeft() < numSamples) {
+        ALOGE("RING BUFFER WOULD OVERFLOW");
+        return false;
+    }
     if (mOutputDelayRingBufferWritePos + numSamples <= mOutputDelayRingBufferSize
             && (mOutputDelayRingBufferReadPos <= mOutputDelayRingBufferWritePos
                     || mOutputDelayRingBufferReadPos > mOutputDelayRingBufferWritePos + numSamples)) {
@@ -422,10 +427,6 @@
         if (mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferSize) {
             mOutputDelayRingBufferWritePos -= mOutputDelayRingBufferSize;
         }
-        if (mOutputDelayRingBufferWritePos == mOutputDelayRingBufferReadPos) {
-            ALOGE("RING BUFFER OVERFLOW");
-            return false;
-        }
     } else {
         ALOGV("slow SoftAAC2::outputDelayRingBufferPutSamples()");
 
@@ -435,16 +436,19 @@
             if (mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferSize) {
                 mOutputDelayRingBufferWritePos -= mOutputDelayRingBufferSize;
             }
-            if (mOutputDelayRingBufferWritePos == mOutputDelayRingBufferReadPos) {
-                ALOGE("RING BUFFER OVERFLOW");
-                return false;
-            }
         }
     }
+    mOutputDelayRingBufferFilled += numSamples;
     return true;
 }
 
 int32_t SoftAAC2::outputDelayRingBufferGetSamples(INT_PCM *samples, int32_t numSamples) {
+
+    if (numSamples > mOutputDelayRingBufferFilled) {
+        ALOGE("RING BUFFER WOULD UNDERRUN");
+        return -1;
+    }
+
     if (mOutputDelayRingBufferReadPos + numSamples <= mOutputDelayRingBufferSize
             && (mOutputDelayRingBufferWritePos < mOutputDelayRingBufferReadPos
                     || mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferReadPos + numSamples)) {
@@ -463,10 +467,6 @@
         ALOGV("slow SoftAAC2::outputDelayRingBufferGetSamples()");
 
         for (int32_t i = 0; i < numSamples; i++) {
-            if (mOutputDelayRingBufferWritePos == mOutputDelayRingBufferReadPos) {
-                ALOGE("RING BUFFER UNDERRUN");
-                return -1;
-            }
             if (samples != 0) {
                 samples[i] = mOutputDelayRingBuffer[mOutputDelayRingBufferReadPos];
             }
@@ -476,22 +476,15 @@
             }
         }
     }
+    mOutputDelayRingBufferFilled -= numSamples;
     return numSamples;
 }
 
 int32_t SoftAAC2::outputDelayRingBufferSamplesAvailable() {
-    int32_t available = mOutputDelayRingBufferWritePos - mOutputDelayRingBufferReadPos;
-    if (available < 0) {
-        available += mOutputDelayRingBufferSize;
-    }
-    if (available < 0) {
-        ALOGE("FATAL RING BUFFER ERROR");
-        return 0;
-    }
-    return available;
+    return mOutputDelayRingBufferFilled;
 }
 
-int32_t SoftAAC2::outputDelayRingBufferSamplesLeft() {
+int32_t SoftAAC2::outputDelayRingBufferSpaceLeft() {
     return mOutputDelayRingBufferSize - outputDelayRingBufferSamplesAvailable();
 }
 
@@ -658,7 +651,7 @@
 
             AAC_DECODER_ERROR decoderErr;
             do {
-                if (outputDelayRingBufferSamplesLeft() <
+                if (outputDelayRingBufferSpaceLeft() <
                         (mStreamInfo->frameSize * mStreamInfo->numChannels)) {
                     ALOGV("skipping decode: not enough space left in ringbuffer");
                     break;
@@ -1032,6 +1025,7 @@
     mOutputDelayCompensated = 0;
     mOutputDelayRingBufferWritePos = 0;
     mOutputDelayRingBufferReadPos = 0;
+    mOutputDelayRingBufferFilled = 0;
     mEndOfInput = false;
     mEndOfOutput = false;
     mBufferTimestamps.clear();
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.h b/media/libstagefright/codecs/aacdec/SoftAAC2.h
index 9fcb598..c3e4459 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.h
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.h
@@ -85,10 +85,11 @@
     short *mOutputDelayRingBuffer;
     int32_t mOutputDelayRingBufferWritePos;
     int32_t mOutputDelayRingBufferReadPos;
+    int32_t mOutputDelayRingBufferFilled;
     bool outputDelayRingBufferPutSamples(INT_PCM *samples, int numSamples);
     int32_t outputDelayRingBufferGetSamples(INT_PCM *samples, int numSamples);
     int32_t outputDelayRingBufferSamplesAvailable();
-    int32_t outputDelayRingBufferSamplesLeft();
+    int32_t outputDelayRingBufferSpaceLeft();
 
     DISALLOW_EVIL_CONSTRUCTORS(SoftAAC2);
 };