am e9f4e016: am 50a9908f: Merge "Speed up stsz box write in MPEG4Writer" into jb-dev

* commit 'e9f4e016145f9bd1f2d133425dde6440d2f4c27e':
  Speed up stsz box write in MPEG4Writer
diff --git a/include/media/stagefright/MPEG4Writer.h b/include/media/stagefright/MPEG4Writer.h
index 0409b30..cd4e129 100644
--- a/include/media/stagefright/MPEG4Writer.h
+++ b/include/media/stagefright/MPEG4Writer.h
@@ -50,6 +50,7 @@
     void writeCString(const char *s);
     void writeFourcc(const char *fourcc);
     void write(const void *data, size_t size);
+    inline size_t write(const void *ptr, size_t size, size_t nmemb);
     void endBox();
     uint32_t interleaveDuration() const { return mInterleaveDurationUs; }
     status_t setInterleaveDuration(uint32_t duration);
@@ -168,7 +169,6 @@
     off64_t addSample_l(MediaBuffer *buffer);
     off64_t addLengthPrefixedSample_l(MediaBuffer *buffer);
 
-    inline size_t write(const void *ptr, size_t size, size_t nmemb);
     bool exceedsFileSizeLimit();
     bool use32BitFileOffset() const;
     bool exceedsFileDurationLimit();
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 7ebbe1d..85fbcdf 100755
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -72,6 +72,7 @@
 private:
     enum {
         kMaxCttsOffsetTimeUs = 1000000LL,  // 1 second
+        kSampleArraySize = 1000,
     };
 
     MPEG4Writer *mOwner;
@@ -96,11 +97,16 @@
 
     pthread_t mThread;
 
-    // mNumSamples is used to track how many samples in mSampleSizes List.
-    // This is to reduce the cost associated with mSampleSizes.size() call,
-    // since it is O(n). Ideally, the fix should be in List class.
-    size_t              mNumSamples;
-    List<size_t>        mSampleSizes;
+    /*
+     * mNumSamples is used to track the total number of samples in
+     * mSampleSizes List.
+     *
+     * A linked list of fixed sized array is used here to reduce the time
+     * to write out stsz box.
+     */
+    uint32_t            mNumSamples;
+    uint32_t*           mCurrentSampleSizeArr;
+    List<uint32_t *>    mSampleSizes;
     bool                mSamplesHaveSameSize;
 
     List<MediaBuffer *> mChunkSamples;
@@ -1263,6 +1269,12 @@
         free(mCodecSpecificData);
         mCodecSpecificData = NULL;
     }
+
+    while (!mSampleSizes.empty()) {
+        List<uint32_t *>::iterator it = mSampleSizes.begin();
+        delete[] (*it);
+        mSampleSizes.erase(it);
+    }
 }
 
 void MPEG4Writer::Track::initTrackingProgressStatus(MetaData *params) {
@@ -2038,7 +2050,14 @@
                 (lastTimestampUs * mTimeScale + 500000LL) / 1000000LL);
         CHECK_GE(currDurationTicks, 0ll);
 
-        mSampleSizes.push_back(sampleSize);
+        if ((mNumSamples % kSampleArraySize) == 0) {
+            uint32_t *arr = new uint32_t[kSampleArraySize];
+            CHECK(arr != NULL);
+            mSampleSizes.push_back(arr);
+            mCurrentSampleSizeArr = arr;
+        }
+
+        mCurrentSampleSizeArr[mNumSamples % kSampleArraySize] = htonl(sampleSize);
         ++mNumSamples;
         if (mNumSamples > 2) {
 
@@ -2788,22 +2807,31 @@
 }
 
 void MPEG4Writer::Track::writeStszBox() {
+    ALOGD("writeStszBox for %s track", isAudio()? "Audio": "Video");
     mOwner->beginBox("stsz");
     mOwner->writeInt32(0);  // version=0, flags=0
     if (mSamplesHaveSameSize) {
-        List<size_t>::iterator it = mSampleSizes.begin();
-        mOwner->writeInt32(*it);  // default sample size
+        List<uint32_t *>::iterator it = mSampleSizes.begin();
+        mOwner->writeInt32((*it)[0]);  // default sample size
     } else {
         mOwner->writeInt32(0);
     }
     mOwner->writeInt32(mNumSamples);
+    uint32_t nSamples = mNumSamples;
     if (!mSamplesHaveSameSize) {
-        for (List<size_t>::iterator it = mSampleSizes.begin();
+        for (List<uint32_t *>::iterator it = mSampleSizes.begin();
             it != mSampleSizes.end(); ++it) {
-            mOwner->writeInt32(*it);
+            if (nSamples >= kSampleArraySize) {
+                mOwner->write(*it, 4, kSampleArraySize);
+                nSamples -= kSampleArraySize;
+            } else {
+                mOwner->write(*it, 4, nSamples);
+                break;
+            }
         }
     }
     mOwner->endBox();  // stsz
+    ALOGD("writeStszBox: X");
 }
 
 void MPEG4Writer::Track::writeStscBox() {