Merge "Squashed commit of the following:"
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 9e7f1c7..07a5a82 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -984,7 +984,14 @@
             (const uint8_t *)mBuffer->data() + mBuffer->range_offset();
 
         size_t nal_size = parseNALSize(src);
-        CHECK(mBuffer->range_length() >= mNALLengthSize + nal_size);
+        if (mBuffer->range_length() < mNALLengthSize + nal_size) {
+            LOGE("incomplete NAL unit.");
+
+            mBuffer->release();
+            mBuffer = NULL;
+
+            return ERROR_MALFORMED;
+        }
 
         MediaBuffer *clone = mBuffer->clone();
         clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size);
@@ -1023,7 +1030,13 @@
             CHECK(srcOffset + mNALLengthSize <= size);
             size_t nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
             srcOffset += mNALLengthSize;
-            CHECK(srcOffset + nalLength <= size);
+
+            if (srcOffset + nalLength > size) {
+                mBuffer->release();
+                mBuffer = NULL;
+
+                return ERROR_MALFORMED;
+            }
 
             if (nalLength == 0) {
                 continue;
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index d8bd25d..c4d3b5d 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -1786,6 +1786,21 @@
 void OMXCodec::fillOutputBuffers() {
     CHECK_EQ(mState, EXECUTING);
 
+    // This is a workaround for some decoders not properly reporting
+    // end-of-output-stream. If we own all input buffers and also own
+    // all output buffers and we already signalled end-of-input-stream,
+    // the end-of-output-stream is implied.
+    if (mSignalledEOS
+            && countBuffersWeOwn(mPortBuffers[kPortIndexInput])
+                == mPortBuffers[kPortIndexInput].size()
+            && countBuffersWeOwn(mPortBuffers[kPortIndexOutput])
+                == mPortBuffers[kPortIndexOutput].size()) {
+        mNoMoreOutputData = true;
+        mBufferFilled.signal();
+
+        return;
+    }
+
     Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
     for (size_t i = 0; i < buffers->size(); ++i) {
         fillOutputBuffer(&buffers->editItemAt(i));
@@ -1833,6 +1848,8 @@
 
         mNoMoreOutputData = false;
 
+        CODEC_LOGV("calling emptyBuffer with codec specific data");
+
         status_t err = mOMX->emptyBuffer(
                 mNode, info->mBuffer, 0, size,
                 OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_CODECCONFIG,
diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp
index 4aec0e9..2de96d4 100644
--- a/media/libstagefright/SampleTable.cpp
+++ b/media/libstagefright/SampleTable.cpp
@@ -291,7 +291,7 @@
 
 status_t SampleTable::getChunkForSample(
         uint32_t sample_index,
-        uint32_t *chunk_index, 
+        uint32_t *chunk_index,
         uint32_t *chunk_relative_sample_index,
         uint32_t *desc_index) {
     *chunk_index = 0;
@@ -469,7 +469,7 @@
     for (uint32_t i = 0; i < mNumSampleSizes; ++i) {
         size_t sample_size;
         status_t err = getSampleSize(i, &sample_size);
-        
+
         if (err != OK) {
             return err;
         }
@@ -502,7 +502,7 @@
 
             return OK;
         }
-        
+
         *time += delta * n;
         cur_sample += n;
     }
@@ -510,6 +510,10 @@
     return ERROR_OUT_OF_RANGE;
 }
 
+uint32_t abs_difference(uint32_t time1, uint32_t time2) {
+    return time1 > time2 ? time1 - time2 : time2 - time1;
+}
+
 status_t SampleTable::findClosestSample(
         uint32_t req_time, uint32_t *sample_index, uint32_t flags) {
     Mutex::Autolock autoLock(mLock);
@@ -523,7 +527,16 @@
         if (req_time < time + n * delta) {
             int j = (req_time - time) / delta;
 
-            *sample_index = cur_sample + j;
+            uint32_t time1 = time + j * delta;
+            uint32_t time2 = time1 + delta;
+
+            if (i+1 == mTimeToSampleCount
+                    || (abs_difference(req_time, time1)
+                        < abs_difference(req_time, time2))) {
+                *sample_index = cur_sample + j;
+            } else {
+                *sample_index = cur_sample + j + 1;
+            }
 
             if (flags & kSyncSample_Flag) {
                 return findClosestSyncSample(*sample_index, sample_index);
@@ -554,8 +567,9 @@
     uint32_t right = mNumSyncSamples;
     while (left < right) {
         uint32_t mid = (left + right) / 2;
+
         if (mDataSource->readAt(
-                    mSyncSampleOffset + 8 + (mid - 1) * 4, &x, 4) != 4) {
+                    mSyncSampleOffset + 8 + mid * 4, &x, 4) != 4) {
             return ERROR_IO;
         }