summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Dong <jdong@google.com>2012-05-15 10:43:30 -0700
committerJames Dong <jdong@google.com>2012-05-15 16:14:25 -0700
commit8c460498c028888c533ab442be12b6d4b669b965 (patch)
treef821306b7a59d4dcc9116f1948f193c78f5ad413
parent5d3d12bf58da5b48b1edb7c20b5d1edec0773f75 (diff)
downloadframeworks_av-8c460498c028888c533ab442be12b6d4b669b965.zip
frameworks_av-8c460498c028888c533ab442be12b6d4b669b965.tar.gz
frameworks_av-8c460498c028888c533ab442be12b6d4b669b965.tar.bz2
Speed up stsz box write in MPEG4Writer
With this patch, the write time for 30+ minutes recording session is reduced from 10+ seconds down to around 2-3 seconds. related-to-bug: 6435176 Change-Id: I83b705cea42d8de798e7032c770c5c7b033e267e
-rw-r--r--include/media/stagefright/MPEG4Writer.h2
-rwxr-xr-xmedia/libstagefright/MPEG4Writer.cpp48
2 files changed, 39 insertions, 11 deletions
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 @@ public:
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 @@ private:
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 @@ public:
private:
enum {
kMaxCttsOffsetTimeUs = 1000000LL, // 1 second
+ kSampleArraySize = 1000,
};
MPEG4Writer *mOwner;
@@ -96,11 +97,16 @@ private:
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 @@ MPEG4Writer::Track::~Track() {
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 @@ status_t MPEG4Writer::Track::threadEntry() {
(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::writeStssBox() {
}
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() {