Merge "Update state only if calls to native window are successful" into jb-mr1-dev
diff --git a/cmds/stagefright/stream.cpp b/cmds/stagefright/stream.cpp
index 8e7861e..ac88d1f 100644
--- a/cmds/stagefright/stream.cpp
+++ b/cmds/stagefright/stream.cpp
@@ -349,7 +349,10 @@
 
     size_t len = strlen(argv[1]);
     if ((!usemp4 && len >= 3 && !strcasecmp(".ts", &argv[1][len - 3])) ||
-        (usemp4 && len >= 4 && !strcasecmp(".mp4", &argv[1][len - 4]))) {
+        (usemp4 && len >= 4 &&
+         (!strcasecmp(".mp4", &argv[1][len - 4])
+            || !strcasecmp(".3gp", &argv[1][len- 4])
+            || !strcasecmp(".3g2", &argv[1][len- 4])))) {
         int fd = open(argv[1], O_RDONLY);
 
         if (fd < 0) {
diff --git a/media/libmediaplayerservice/nuplayer/mp4/Parser.cpp b/media/libmediaplayerservice/nuplayer/mp4/Parser.cpp
index b9fe819..7938fa4 100644
--- a/media/libmediaplayerservice/nuplayer/mp4/Parser.cpp
+++ b/media/libmediaplayerservice/nuplayer/mp4/Parser.cpp
@@ -271,6 +271,19 @@
             mBuffer->setRange(0, mBuffer->size());
 
             size_t maxBytesToRead = mBuffer->capacity() - mBuffer->size();
+
+            if (maxBytesToRead < needed) {
+                ALOGI("resizing buffer.");
+
+                sp<ABuffer> newBuffer =
+                    new ABuffer((mBuffer->size() + needed + 1023) & ~1023);
+                memcpy(newBuffer->data(), mBuffer->data(), mBuffer->size());
+                newBuffer->setRange(0, mBuffer->size());
+
+                mBuffer = newBuffer;
+                maxBytesToRead = mBuffer->capacity() - mBuffer->size();
+            }
+
             CHECK_GE(maxBytesToRead, needed);
 
             ssize_t n = mSource->readAt(
@@ -1023,6 +1036,11 @@
         case FOURCC('m', 'p', '4', 'v'):
             format->setString("mime", MEDIA_MIMETYPE_VIDEO_MPEG4);
             break;
+        case FOURCC('s', '2', '6', '3'):
+        case FOURCC('h', '2', '6', '3'):
+        case FOURCC('H', '2', '6', '3'):
+            format->setString("mime", MEDIA_MIMETYPE_VIDEO_H263);
+            break;
         default:
             format->setString("mime", "application/octet-stream");
             break;
@@ -1062,11 +1080,13 @@
         case FOURCC('m', 'p', '4', 'a'):
             format->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
             break;
+
         case FOURCC('s', 'a', 'm', 'r'):
             format->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
             format->setInt32("channel-count", 1);
             format->setInt32("sample-rate", 8000);
             break;
+
         case FOURCC('s', 'a', 'w', 'b'):
             format->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
             format->setInt32("channel-count", 1);
diff --git a/media/libmediaplayerservice/nuplayer/mp4/TrackFragment.cpp b/media/libmediaplayerservice/nuplayer/mp4/TrackFragment.cpp
index 12e71db..a4c31ea 100644
--- a/media/libmediaplayerservice/nuplayer/mp4/TrackFragment.cpp
+++ b/media/libmediaplayerservice/nuplayer/mp4/TrackFragment.cpp
@@ -24,6 +24,7 @@
 #include <media/stagefright/Utils.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/hexdump.h>
 
 namespace android {
 
@@ -79,6 +80,7 @@
 Parser::StaticTrackFragment::StaticTrackFragment()
     : mSampleIndex(0),
       mSampleCount(0),
+      mChunkIndex(0),
       mSampleToChunkIndex(-1),
       mSampleToChunkRemaining(0),
       mPrevChunkIndex(0xffffffff),
@@ -149,37 +151,31 @@
     mSampleInfo.mSampleDescIndex =
         U32_AT(mSampleToChunk->data() + 8 + 12 * mSampleToChunkIndex + 8);
 
-    uint32_t chunkIndex =
-        U32_AT(mSampleToChunk->data() + 8 + 12 * mSampleToChunkIndex);
-
-    CHECK_GE(chunkIndex, 1);
-    --chunkIndex;
-
-    if (chunkIndex != mPrevChunkIndex) {
-        mPrevChunkIndex = chunkIndex;
+    if (mChunkIndex != mPrevChunkIndex) {
+        mPrevChunkIndex = mChunkIndex;
 
         if (mChunkOffsets != NULL) {
             uint32_t entryCount = U32_AT(mChunkOffsets->data() + 4);
 
-            if (chunkIndex >= entryCount) {
+            if (mChunkIndex >= entryCount) {
                 mSampleIndex = mSampleCount;
                 return;
             }
 
             mNextSampleOffset =
-                U32_AT(mChunkOffsets->data() + 8 + 4 * chunkIndex);
+                U32_AT(mChunkOffsets->data() + 8 + 4 * mChunkIndex);
         } else {
             CHECK(mChunkOffsets64 != NULL);
 
             uint32_t entryCount = U32_AT(mChunkOffsets64->data() + 4);
 
-            if (chunkIndex >= entryCount) {
+            if (mChunkIndex >= entryCount) {
                 mSampleIndex = mSampleCount;
                 return;
             }
 
             mNextSampleOffset =
-                U64_AT(mChunkOffsets64->data() + 8 + 8 * chunkIndex);
+                U64_AT(mChunkOffsets64->data() + 8 + 8 * mChunkIndex);
         }
     }
 
@@ -194,14 +190,25 @@
 
     ++mSampleIndex;
     if (--mSampleToChunkRemaining == 0) {
+        ++mChunkIndex;
+
         uint32_t entryCount = U32_AT(mSampleToChunk->data() + 4);
 
-        if ((uint32_t)(mSampleToChunkIndex + 1) == entryCount) {
-            mSampleIndex = mSampleCount;  // EOS.
-            return;
+        // If this is the last entry in the sample to chunk table, we will
+        // stay on this entry.
+        if ((uint32_t)(mSampleToChunkIndex + 1) < entryCount) {
+            uint32_t nextChunkIndex =
+                U32_AT(mSampleToChunk->data() + 8 + 12 * (mSampleToChunkIndex + 1));
+
+            CHECK_GE(nextChunkIndex, 1u);
+            --nextChunkIndex;
+
+            if (mChunkIndex >= nextChunkIndex) {
+                CHECK_EQ(mChunkIndex, nextChunkIndex);
+                ++mSampleToChunkIndex;
+            }
         }
 
-        ++mSampleToChunkIndex;
         mSampleToChunkRemaining =
             U32_AT(mSampleToChunk->data() + 8 + 12 * mSampleToChunkIndex + 4);
     }
@@ -216,46 +223,13 @@
     ptr[3] = x & 0xff;
 }
 
-void Parser::StaticTrackFragment::fixSampleToChunkTableIfNecessary() {
-    if (mSampleToChunk == NULL) {
-        return;
-    }
-    uint32_t entryCount = U32_AT(mSampleToChunk->data() + 4);
-    uint32_t totalSamples = 0;
-    for (uint32_t i = 0; i < entryCount; ++i) {
-        totalSamples += U32_AT(mSampleToChunk->data() + 8 + 12 * i + 4);
-    }
-
-    if (totalSamples < mSampleCount) {
-        // Some samples are not accounted for in the sample-to-chunk
-        // data. Fabricate an extra chunk adjacent to the last one
-        // in the table with the same sample desription index.
-
-        ALOGW("Faking an extra sample-to-chunk entry for %d samples.",
-              mSampleCount - totalSamples);
-
-        uint32_t lastChunkIndex =
-            U32_AT(mSampleToChunk->data() + 8 + 12 * (entryCount - 1));
-
-        uint32_t lastSampleDescriptionIndex =
-            U32_AT(mSampleToChunk->data() + 8 + 12 * (entryCount - 1) + 8);
-
-        uint8_t *ptr = mSampleToChunk->data() + 8 + 12 * entryCount;
-
-        setU32At(ptr, lastChunkIndex + 1);
-        setU32At(ptr + 4, mSampleCount - totalSamples);
-        setU32At(ptr + 8, lastSampleDescriptionIndex);
-        setU32At(mSampleToChunk->data() + 4, entryCount + 1);
-    }
-}
-
 status_t Parser::StaticTrackFragment::signalCompletion() {
-    fixSampleToChunkTableIfNecessary();
-
     mSampleToChunkIndex = 0;
 
-    mSampleToChunkRemaining = (mSampleToChunk == NULL) ? 0 :
-        U32_AT(mSampleToChunk->data() + 8 + 12 * mSampleToChunkIndex + 4);
+    mSampleToChunkRemaining =
+        (mSampleToChunk == NULL)
+            ? 0
+            : U32_AT(mSampleToChunk->data() + 8 + 12 * mSampleToChunkIndex + 4);
 
     updateSampleInfo();
 
@@ -339,7 +313,7 @@
         return ERROR_MALFORMED;
     }
 
-    parser->copyBuffer(&mSampleToChunk, offset, size, 12 /* extra */);
+    parser->copyBuffer(&mSampleToChunk, offset, size);
 
     return OK;
 }
diff --git a/media/libmediaplayerservice/nuplayer/mp4/TrackFragment.h b/media/libmediaplayerservice/nuplayer/mp4/TrackFragment.h
index e5945ac..1498aad 100644
--- a/media/libmediaplayerservice/nuplayer/mp4/TrackFragment.h
+++ b/media/libmediaplayerservice/nuplayer/mp4/TrackFragment.h
@@ -96,6 +96,7 @@
 private:
     size_t mSampleIndex;
     size_t mSampleCount;
+    uint32_t mChunkIndex;
 
     SampleInfo mSampleInfo;
 
@@ -112,7 +113,6 @@
     uint64_t mNextSampleOffset;
 
     void updateSampleInfo();
-    void fixSampleToChunkTableIfNecessary();
 
     DISALLOW_EVIL_CONSTRUCTORS(StaticTrackFragment);
 };